mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-25 11:25:21 +00:00
Sign announcements (#267)
* wip * announcements WIP * works * restore mainnet
This commit is contained in:
@@ -11,7 +11,8 @@ import com.bitchat.android.util.*
|
||||
@Parcelize
|
||||
data class IdentityAnnouncement(
|
||||
val nickname: String,
|
||||
val publicKey: ByteArray // FIXED: Made non-nullable to match iOS and AnnouncementPacket
|
||||
val noisePublicKey: ByteArray, // Noise static public key (Curve25519.KeyAgreement)
|
||||
val signingPublicKey: ByteArray // Ed25519 public key for signing
|
||||
) : Parcelable {
|
||||
|
||||
/**
|
||||
@@ -19,7 +20,8 @@ data class IdentityAnnouncement(
|
||||
*/
|
||||
private enum class TLVType(val value: UByte) {
|
||||
NICKNAME(0x01u),
|
||||
NOISE_PUBLIC_KEY(0x02u);
|
||||
NOISE_PUBLIC_KEY(0x02u),
|
||||
SIGNING_PUBLIC_KEY(0x03u); // NEW: Ed25519 signing public key
|
||||
|
||||
companion object {
|
||||
fun fromValue(value: UByte): TLVType? {
|
||||
@@ -35,7 +37,7 @@ data class IdentityAnnouncement(
|
||||
val nicknameData = nickname.toByteArray(Charsets.UTF_8)
|
||||
|
||||
// Check size limits
|
||||
if (nicknameData.size > 255 || publicKey.size > 255) {
|
||||
if (nicknameData.size > 255 || noisePublicKey.size > 255 || signingPublicKey.size > 255) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -46,10 +48,15 @@ data class IdentityAnnouncement(
|
||||
result.add(nicknameData.size.toByte())
|
||||
result.addAll(nicknameData.toList())
|
||||
|
||||
// TLV for public key
|
||||
// TLV for noise public key
|
||||
result.add(TLVType.NOISE_PUBLIC_KEY.value.toByte())
|
||||
result.add(publicKey.size.toByte())
|
||||
result.addAll(publicKey.toList())
|
||||
result.add(noisePublicKey.size.toByte())
|
||||
result.addAll(noisePublicKey.toList())
|
||||
|
||||
// TLV for signing public key
|
||||
result.add(TLVType.SIGNING_PUBLIC_KEY.value.toByte())
|
||||
result.add(signingPublicKey.size.toByte())
|
||||
result.addAll(signingPublicKey.toList())
|
||||
|
||||
return result.toByteArray()
|
||||
}
|
||||
@@ -64,12 +71,13 @@ data class IdentityAnnouncement(
|
||||
|
||||
var offset = 0
|
||||
var nickname: String? = null
|
||||
var publicKey: ByteArray? = null
|
||||
var noisePublicKey: ByteArray? = null
|
||||
var signingPublicKey: ByteArray? = null
|
||||
|
||||
while (offset + 2 <= dataCopy.size) {
|
||||
// Read TLV type
|
||||
val typeValue = dataCopy[offset].toUByte()
|
||||
val type = TLVType.fromValue(typeValue) ?: return null
|
||||
val type = TLVType.fromValue(typeValue)
|
||||
offset += 1
|
||||
|
||||
// Read TLV length
|
||||
@@ -83,19 +91,27 @@ data class IdentityAnnouncement(
|
||||
val value = dataCopy.sliceArray(offset until offset + length)
|
||||
offset += length
|
||||
|
||||
// Process known TLV types, skip unknown ones for forward compatibility
|
||||
when (type) {
|
||||
TLVType.NICKNAME -> {
|
||||
nickname = String(value, Charsets.UTF_8)
|
||||
}
|
||||
TLVType.NOISE_PUBLIC_KEY -> {
|
||||
publicKey = value
|
||||
noisePublicKey = value
|
||||
}
|
||||
TLVType.SIGNING_PUBLIC_KEY -> {
|
||||
signingPublicKey = value
|
||||
}
|
||||
null -> {
|
||||
// Unknown TLV; skip (tolerant decoder for forward compatibility)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Both fields are required
|
||||
return if (nickname != null && publicKey != null) {
|
||||
IdentityAnnouncement(nickname, publicKey)
|
||||
// All three fields are required
|
||||
return if (nickname != null && noisePublicKey != null && signingPublicKey != null) {
|
||||
IdentityAnnouncement(nickname, noisePublicKey, signingPublicKey)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -110,18 +126,20 @@ data class IdentityAnnouncement(
|
||||
other as IdentityAnnouncement
|
||||
|
||||
if (nickname != other.nickname) return false
|
||||
if (!publicKey.contentEquals(other.publicKey)) return false
|
||||
if (!noisePublicKey.contentEquals(other.noisePublicKey)) return false
|
||||
if (!signingPublicKey.contentEquals(other.signingPublicKey)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = nickname.hashCode()
|
||||
result = 31 * result + publicKey.contentHashCode()
|
||||
result = 31 * result + noisePublicKey.contentHashCode()
|
||||
result = 31 * result + signingPublicKey.contentHashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "IdentityAnnouncement(nickname='$nickname', publicKey=${publicKey.joinToString("") { "%02x".format(it) }.take(16)}...)"
|
||||
return "IdentityAnnouncement(nickname='$nickname', noisePublicKey=${noisePublicKey.joinToString("") { "%02x".format(it) }.take(16)}..., signingPublicKey=${signingPublicKey.joinToString("") { "%02x".format(it) }.take(16)}...)"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user