Signal Protocol wire format implementation.
Based on the official Signal Protocol specification and libsignal-protocol-java.
Wire format:
- SignalMessage: version_byte || protobuf || mac(8 bytes)
- PreKeySignalMessage: version_byte || protobuf
Key format:
- Public keys are serialized as: 0x05 || 32-byte-key (33 bytes total)
Version byte format:
(current_version << 4) | current_version
- For version 3: 0x33
Summary
Functions
Decrypts ciphertext using AES-256-CBC and validates PKCS7 padding.
Deserializes a public key, removing the type prefix.
Encodes an unsigned integer as a varint.
Encrypts plaintext using AES-256-CBC with PKCS7 padding.
Returns the message type atom for the given serialized message.
Parses a serialized PreKeySignalMessage.
Parses a serialized SignalMessage.
Serializes a PreKeySignalMessage.
Serializes a public key with the DJB type prefix (0x05).
Serializes a SignalMessage (whisper message).
Verifies the Signal MAC over version_and_proto.
Verifies a Signal MAC with compatibility fallbacks used by production WA clients.
Functions
@spec decrypt_aes_cbc(binary(), binary(), binary()) :: {:ok, binary()} | {:error, :invalid_ciphertext | :invalid_padding | :decrypt_failed}
Decrypts ciphertext using AES-256-CBC and validates PKCS7 padding.
Deserializes a public key, removing the type prefix.
Encodes an unsigned integer as a varint.
Encrypts plaintext using AES-256-CBC with PKCS7 padding.
This is the encryption used inside Signal messages (not AES-GCM!).
Returns the message type atom for the given serialized message.
Parses a serialized PreKeySignalMessage.
Returns map keys:
:version_byte:registration_id:prekey_id:signed_prekey_id:base_key:identity_key:message(inner SignalMessage bytes)
Parses a serialized SignalMessage.
Returns map keys:
:version_byte:version_and_proto(used for MAC verification):mac:ratchet_key(32 bytes):counter:previous_counter:ciphertext
Serializes a PreKeySignalMessage.
Args:
- registration_id: sender's registration ID
- prekey_id: one-time prekey ID (optional)
- signed_prekey_id: signed prekey ID
- base_key: ephemeral public key from X3DH
- identity_key: sender's identity public key
- signal_message: already-serialized SignalMessage bytes
Returns the serialized prekey message bytes.
Serializes a public key with the DJB type prefix (0x05).
Serializes a SignalMessage (whisper message).
Args:
- ratchet_key: 32-byte sender's current ratchet public key
- counter: message counter
- previous_counter: previous chain's counter
- ciphertext: AES-CBC encrypted message
- mac_key: key for HMAC
- sender_identity: sender's identity public key
- receiver_identity: receiver's identity public key
Returns the serialized message bytes.
Verifies the Signal MAC over version_and_proto.
Verifies a Signal MAC with compatibility fallbacks used by production WA clients.
Returns {:ok, strategy} when a check matches, or :error otherwise.