KodiumProtocolEngine
ProtocolEngine backed by Kodium's X3DH and Double Ratchet.
Key encoding: private keys are Kodium's raw 32-byte secret, public keys are Kodium's 64-byte unified key (X25519 encryption key followed by Ed25519 signing key).
Every operation imports the ratchet from SecureSession.state, works on a throwaway Kodium session and exports it again. Kodium mutates its session even when decryption fails, so a failed call must never produce a new state; the caller's stored session stays valid.
Kodium's X3DH neither verifies the signed prekey signature nor defines associated data. This engine verifies the signature before key agreement. Sessions it creates use session initiation version 2 (S1): the associated data of every ratchet message is the canonical initiation transcript (SessionInitiationId.v2Transcript) with both device addresses, both identity keys, the whole ephemeral key and both prekey IDs. Sessions created before S1 keep their version 1 associated data initiatorIdentityKey || responderIdentityKey.
Functions
Creates the responder side of a session from the first message, sent by remote to localAddress, and decrypts it. Only a SessionInitiationVersion.V2 message is accepted: its transcript, built from both addresses and every header field, is the associated data, so a changed address or header field fails decryption and nothing is created. A SessionInitiationVersion.V1 message throws ProtocolException.InvalidMessage. The caller looks up signedPreKey and oneTimePreKey by the IDs in message. It must delete SessionAcceptanceResult.consumedOneTimePreKeyId once the result is persisted.
Creates the device authentication key pair (docs/server-authentication.md). Separate from the messaging identity: it only authenticates the device to the server, see ServerRequestAuthentication.
Creates an offline last-device recovery key (docs/last-device-recovery.md). Separate from the messaging identity and from every device authentication key; the application keeps it offline.
Decrypts message on an existing session of the device whose public identity key is localIdentityKey. A PreKeyMessage is accepted too; the initiator may send several before it sees a reply. It must have the session's initiation version, belong to the initiation that created session (see sessionInfo), and the local device must be the session's responder with the message's identity key as initiator; otherwise ProtocolException.InvalidMessage is thrown.
Verifies remoteBundle and starts a session as initiator from localAddress to the bundle's address, always with session initiation version 2 (S1): the associated data binds both addresses and every initiation header field (docs/session-lifecycle.md). The session stays pending: encrypt returns PreKeyMessages until the first message from the remote side is decrypted.
Describes session without changing it. Throws ProtocolException.InvalidSessionState for an unreadable state.
The remote identity key session was established with, or null if that cannot be told apart from the local one: exactly one of the session's two identity keys must equal localIdentityKey, and the other one is returned. Never returns the local key. Used to pin a session created before identity pinning (S1, finding F9).