113 lines
3.7 KiB
Kotlin
113 lines
3.7 KiB
Kotlin
/*
|
|
* Copyright 2017 Christian Basler
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package ch.dissem.bitmessage.entity.payload
|
|
|
|
import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_EXTRA_BYTES
|
|
import ch.dissem.bitmessage.InternalContext.Companion.NETWORK_NONCE_TRIALS_PER_BYTE
|
|
import ch.dissem.bitmessage.utils.Singleton.cryptography
|
|
import java.io.OutputStream
|
|
import java.nio.ByteBuffer
|
|
import java.util.*
|
|
|
|
/**
|
|
* Public keys for signing and encryption, the answer to a 'getpubkey' request.
|
|
*/
|
|
abstract class Pubkey protected constructor(version: Long) : ObjectPayload(version) {
|
|
|
|
override val type: ObjectType = ObjectType.PUBKEY
|
|
|
|
abstract val signingKey: ByteArray
|
|
|
|
abstract val encryptionKey: ByteArray
|
|
|
|
abstract val behaviorBitfield: Int
|
|
|
|
val ripe: ByteArray by lazy { cryptography().ripemd160(cryptography().sha512(signingKey, encryptionKey)) }
|
|
|
|
open val nonceTrialsPerByte: Long = NETWORK_NONCE_TRIALS_PER_BYTE
|
|
|
|
open val extraBytes: Long = NETWORK_EXTRA_BYTES
|
|
|
|
open fun writeUnencrypted(out: OutputStream) {
|
|
write(out)
|
|
}
|
|
|
|
open fun writeUnencrypted(buffer: ByteBuffer) {
|
|
write(buffer)
|
|
}
|
|
|
|
/**
|
|
* Bits 0 through 29 are yet undefined
|
|
*/
|
|
enum class Feature constructor(bitNumber: Int) {
|
|
/**
|
|
* Receiving node expects that the RIPE hash encoded in their address preceedes the encrypted message data of msg
|
|
* messages bound for them.
|
|
*/
|
|
INCLUDE_DESTINATION(30),
|
|
/**
|
|
* If true, the receiving node does send acknowledgements (rather than dropping them).
|
|
*/
|
|
DOES_ACK(31);
|
|
|
|
// The Bitmessage Protocol Specification starts counting at the most significant bit,
|
|
// thus the slightly awkward calculation.
|
|
// https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features
|
|
private val bit: Int = 1 shl 31 - bitNumber
|
|
|
|
fun isActive(bitfield: Int): Boolean {
|
|
return bitfield and bit != 0
|
|
}
|
|
|
|
companion object {
|
|
@JvmStatic fun bitfield(vararg features: Feature): Int {
|
|
var bits = 0
|
|
for (feature in features) {
|
|
bits = bits or feature.bit
|
|
}
|
|
return bits
|
|
}
|
|
|
|
@JvmStatic fun features(bitfield: Int): Array<Feature> {
|
|
val features = ArrayList<Feature>(Feature.values().size)
|
|
for (feature in Feature.values()) {
|
|
if (bitfield and feature.bit != 0) {
|
|
features.add(feature)
|
|
}
|
|
}
|
|
return features.toTypedArray()
|
|
}
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
@JvmField val LATEST_VERSION: Long = 4
|
|
|
|
fun getRipe(publicSigningKey: ByteArray, publicEncryptionKey: ByteArray): ByteArray {
|
|
return cryptography().ripemd160(cryptography().sha512(publicSigningKey, publicEncryptionKey))
|
|
}
|
|
|
|
fun add0x04(key: ByteArray): ByteArray {
|
|
if (key.size == 65) return key
|
|
val result = ByteArray(65)
|
|
result[0] = 4
|
|
System.arraycopy(key, 0, result, 1, 64)
|
|
return result
|
|
}
|
|
}
|
|
}
|