pub fn packet_counter(salt: &[u8; 16], pkt_seq_no: u32) -> [u8; 16]crypto only.Expand description
Compute the 128-bit AES-CTR initial counter for one data packet.
This follows the reference SRT construction (libsrt haicrypt/hcrypt.h,
hcrypt_SetCtrIV), which is what real SRT peers use on the wire:
memset(iv, 0, 16); // all 16 bytes zeroed
memcpy(&iv[10], &pki, 4); // 32-bit packet index at bytes [10..14]
iv[0..14] ^= salt[0..14]; // XOR MSB(112, Salt) across the top 14 bytes
// iv[14..16] = per-packet AES-block counter, starts 0
//
// byte: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// +-----------------------+-----------+-----+
// | 0s | pki | ctr |
// +-----------------------+-----------+-----+On the draft’s IV = (MSB(112, Salt) << 2) XOR PktSeqNo (§6.2.2/§6.3.2):
the << 2 is a known artifact/typo of the draft text — the reference
implementation does no left shift. Implementing the << 2 literally
produces a keystream no real SRT peer can decrypt, so this function follows
hcrypt_SetCtrIV (which is equivalent to §6.1.2’s field layout: packet index
in bits [47:16], block counter in [15:0]). See the module doc’s
“conflicting IV formula” note.
The low 16 bits (counter[14..16]) are the per-packet AES-block counter,
left at 0 here — a standard 128-bit big-endian CTR increments the whole
counter per block, which only touches these low bits as long as a single
packet’s payload stays under 2^16 AES blocks (1 MiB); every SRT payload
(bounded by a UDP datagram) is far smaller.
pkt_seq_no is the data packet’s 31-bit Packet Sequence Number
(draft-sharabayko-srt-01 §3.1); bit 31 (the F header bit) is never part
of it.