CiphertextMessageCodec
KSecureMessage ciphertext wire format, version 1. The output goes into EncryptedEnvelope.payload. Framing only: no cryptography happens here and the ratchet bytes are carried unchanged. Full specification: docs/wire-format.md.
RatchetMessage: version=0x01 | type=0x01 | length:u32 | ratchet bytes
PreKeyMessage: version=0x01 | type=0x02 (initiation v1) or 0x03 (initiation v2)
| signedPreKeyId:u32
| flag:u8 (0x00 absent, 0x01 present) | [oneTimePreKeyId:u32]
| identityKey[64] | ephemeralKey[64] | length:u32 | ratchet bytesTypes 0x02 and 0x03 share one layout and differ only in the session initiation version (SessionInitiationVersion). The type byte itself is not authenticated, but the initiation version selects the associated data the first ratchet message is authenticated with (docs/session-lifecycle.md): a relay that rewrites 0x03 to 0x02 or back makes decryption fail, and a v1 message never creates a session (S1).
Integers are unsigned 32-bit big-endian. Prekey IDs must have the high bit clear. Decoding treats input as untrusted: anything that is not exactly one well-formed message is rejected with a ProtocolException, never partially accepted. Encoding is deterministic.
Properties
Upper bound for a complete encoded message.
Upper bound for the opaque ratchet bytes (Kodium header plus ciphertext).
PreKeyMessage with SessionInitiationVersion.V2 (S1).