
commonMain.org.ton.api.adnl.AdnlPacketContents.kt Maven / Gradle / Ivy
package org.ton.api.adnl
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.ton.api.SignedTlObject
import org.ton.api.adnl.message.AdnlMessage
import org.ton.api.pk.PrivateKey
import org.ton.api.pub.PublicKey
import org.ton.tl.*
import kotlin.random.Random
// total packet length:
// for full packet:
// 32 (dst) + 64 (encryption overhead) + 4 (magic) + 36 (pubkey) + 4 + M (sum of messages) +
// + A1 + A2 + 8 + 8 + 4 + 4 + 4 + 4 + 68 (signature) + 16 (r1) + 16 (r2) =
// = 272 + M + A1 + A2
// for channel:
// 32 (channel id) + 32 (encryption overhead) + 4 (magic) + 4 + M (sum of messages) +
// + A1 + A2 + 8 + 8 + 4 + 4 + 16(r1) + 16(r2) = 128 + M + A1 + A2
@Serializable
public data class AdnlPacketContents(
val rand1: ByteArray,
val flags: Int,
val from: PublicKey?,
@SerialName("from_short")
val fromShort: AdnlIdShort?,
val message: AdnlMessage?,
val messages: Collection?,
val address: AdnlAddressList?,
@SerialName("priority_address")
val priorityAddress: AdnlAddressList?,
val seqno: Long?,
@SerialName("confirm_seqno")
val confirmSeqno: Long?,
@SerialName("recv_addr_list_version")
val recvAddrListVersion: Int?,
@SerialName("recv_priority_addr_list_version")
val recvPriorityAddrListVersion: Int?,
@SerialName("reinit_date")
val reinitDate: Int?,
@SerialName("dst_reinit_date")
val dstReinitDate: Int?,
override val signature: ByteArray?,
val rand2: ByteArray
) : SignedTlObject {
public constructor(
rand1: ByteArray = Random.Default.nextBytes(if (Random.nextBoolean()) 7 else 15),
from: PublicKey? = null,
from_short: AdnlIdShort? = null,
message: AdnlMessage? = null,
messages: Collection? = null,
address: AdnlAddressList? = null,
priority_address: AdnlAddressList? = null,
seqno: Long? = null,
confirm_seqno: Long? = null,
recv_addr_list_version: Int? = null,
recv_priority_addr_list_version: Int? = null,
reinit_date: Int? = null,
dst_reinit_date: Int? = null,
signature: ByteArray? = null,
rand2: ByteArray = Random.Default.nextBytes(if (Random.nextBoolean()) 7 else 15)
) : this(
rand1 = rand1,
flags = flags(
from != null,
from_short != null,
message != null,
messages != null,
address != null,
priority_address != null,
seqno != null,
confirm_seqno != null,
recv_addr_list_version != null,
recv_priority_addr_list_version != null,
reinit_date != null,
signature != null
),
from,
from_short,
message,
messages,
address,
priority_address,
seqno,
confirm_seqno,
recv_addr_list_version,
recv_priority_addr_list_version,
reinit_date,
dst_reinit_date,
signature,
rand2
)
init {
if (message != null && messages != null) {
throw IllegalArgumentException("both fields `message` and `messages` set")
}
if (from != null && fromShort != null && from.toAdnlIdShort() != fromShort) {
throw IllegalArgumentException("`from` and `from_short` mismatch")
}
// if (address != null && address.addrs.isEmpty()) {
// throw IllegalArgumentException("`address` contains empty list")
// }
if (priorityAddress != null && priorityAddress.addrs.isEmpty()) {
throw IllegalArgumentException("`priority_address` contains empty list")
}
}
public fun messages(): Collection = message?.let { listOf(it) } ?: messages ?: emptyList()
override fun signed(privateKey: PrivateKey): AdnlPacketContents {
val encoded = tlCodec().encodeToByteArray(
AdnlPacketContents(
rand1 = rand1,
from = from,
from_short = fromShort,
message = message,
messages = messages,
address = address,
priority_address = priorityAddress,
seqno = seqno,
confirm_seqno = confirmSeqno,
recv_addr_list_version = recvAddrListVersion,
recv_priority_addr_list_version = recvPriorityAddrListVersion,
reinit_date = reinitDate,
dst_reinit_date = dstReinitDate,
signature = null,
rand2 = rand2
)
)
val signature = privateKey.sign(encoded)
return AdnlPacketContents(
rand1 = rand1,
from = from,
from_short = fromShort,
message = message,
messages = messages,
address = address,
priority_address = priorityAddress,
seqno = seqno,
confirm_seqno = confirmSeqno,
recv_addr_list_version = recvAddrListVersion,
recv_priority_addr_list_version = recvPriorityAddrListVersion,
reinit_date = reinitDate,
dst_reinit_date = dstReinitDate,
signature = signature,
rand2 = rand2
)
}
override fun verify(publicKey: PublicKey): Boolean {
val encoded = tlCodec().encodeToByteArray(
AdnlPacketContents(
rand1 = rand1,
from = from,
from_short = fromShort,
message = message,
messages = messages,
address = address,
priority_address = priorityAddress,
seqno = seqno,
confirm_seqno = confirmSeqno,
recv_addr_list_version = recvAddrListVersion,
recv_priority_addr_list_version = recvPriorityAddrListVersion,
reinit_date = reinitDate,
dst_reinit_date = dstReinitDate,
signature = null,
rand2 = rand2
)
)
return publicKey.verify(encoded, signature)
}
override fun tlCodec(): TlCodec = AdnlPacketContentsTlConstructor
public companion object : TlCodec by AdnlPacketContentsTlConstructor {
public fun flags(
from: Boolean = false,
from_short: Boolean = false,
message: Boolean = false,
messages: Boolean = false,
address: Boolean = false,
priority_address: Boolean = false,
seqno: Boolean = false,
confirm_seqno: Boolean = false,
recv_addr_list_version: Boolean = false,
recv_priority_addr_list_version: Boolean = false,
reinit_date: Boolean = false,
signature: Boolean = false
): Int {
var flags = 0
if (from) flags = flags or 1
if (from_short) flags = flags or 2
if (message) flags = flags or 4
if (messages) flags = flags or 8
if (address) flags = flags or 16
if (priority_address) flags = flags or 32
if (seqno) flags = flags or 64
if (confirm_seqno) flags = flags or 128
if (recv_addr_list_version) flags = flags or 256
if (recv_priority_addr_list_version) flags = flags or 512
if (reinit_date) flags = flags or 1024
if (signature) flags = flags or 2048
return flags
}
}
}
private object AdnlPacketContentsTlConstructor : TlConstructor(
schema = "adnl.packetContents" +
" rand1:bytes" +
" flags:#" +
" from:flags.0?PublicKey" +
" from_short:flags.1?adnl.id.short" +
" message:flags.2?adnl.Message" +
" messages:flags.3?(vector adnl.Message)" +
" address:flags.4?adnl.addressList" +
" priority_address:flags.5?adnl.addressList" +
" seqno:flags.6?long" +
" confirm_seqno:flags.7?long" +
" recv_addr_list_version:flags.8?int" +
" recv_priority_addr_list_version:flags.9?int" +
" reinit_date:flags.10?int" +
" dst_reinit_date:flags.10?int" +
" signature:flags.11?bytes" +
" rand2:bytes" +
" = adnl.PacketContents",
id = -784151159
) {
override fun decode(reader: TlReader): AdnlPacketContents {
val rand1 = reader.readBytes()
val flags = reader.readInt()
val from = reader.readNullable(flags, 0) { read(PublicKey) }
val from_short = reader.readNullable(flags, 1) { read(AdnlIdShort) }
val message = reader.readNullable(flags, 2) { read(AdnlMessage) }
val messages = reader.readNullable(flags, 3) { readCollection { read(AdnlMessage) } }
val address = reader.readNullable(flags, 4) { read(AdnlAddressList) }
val priority_address = reader.readNullable(flags, 5) { read(AdnlAddressList) }
val seqno = reader.readNullable(flags, 6) { readLong() }
val confirm_seqno = reader.readNullable(flags, 7) { readLong() }
val recv_addr_list_version = reader.readNullable(flags, 8) { readInt() }
val recv_priority_addr_list_version = reader.readNullable(flags, 9) { readInt() }
val reinit_date = reader.readNullable(flags, 10) { readInt() }
val dst_reinit_date = reader.readNullable(flags, 10) { readInt() }
val signature = reader.readNullable(flags, 11) { readBytes() }
val rand2 = reader.readBytes()
return AdnlPacketContents(
rand1,
flags,
from,
from_short,
message,
messages,
address,
priority_address,
seqno,
confirm_seqno,
recv_addr_list_version,
recv_priority_addr_list_version,
reinit_date,
dst_reinit_date,
signature,
rand2
)
}
override fun encode(writer: TlWriter, value: AdnlPacketContents) {
writer.writeBytes(value.rand1)
writer.writeInt(value.flags)
val flags = value.flags
writer.writeNullable(flags, 0, value.from) { write(PublicKey, it) }
writer.writeNullable(flags, 1, value.fromShort) { write(AdnlIdShort, it) }
writer.writeNullable(flags, 2, value.message) { write(AdnlMessage, it) }
writer.writeNullable(flags, 3, value.messages) { list ->
writeCollection(list) { element ->
write(AdnlMessage, element)
}
}
writer.writeNullable(flags, 4, value.address) { write(AdnlAddressList, it) }
writer.writeNullable(flags, 5, value.priorityAddress) { write(AdnlAddressList, it) }
writer.writeNullable(flags, 6, value.seqno) { writeLong(it) }
writer.writeNullable(flags, 7, value.confirmSeqno) { writeLong(it) }
writer.writeNullable(flags, 8, value.recvAddrListVersion) { writeInt(it) }
writer.writeNullable(flags, 9, value.recvPriorityAddrListVersion) { writeInt(it) }
writer.writeNullable(flags, 10, value.reinitDate) { writeInt(it) }
writer.writeNullable(flags, 10, value.dstReinitDate) { writeInt(it) }
writer.writeNullable(flags, 11, value.signature) { writeBytes(it) }
writer.writeBytes(value.rand2)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy