signal_protocol
Types
Whether this party initiates (Alice) or responds (Bob) in the DR handshake.
pub type DrRole {
Alice
Bob
}
Constructors
-
Alice -
Bob
Opaque Double Ratchet session state (~5.3 KB).
pub type DrSession {
DrSession(state: BitArray)
}
Constructors
-
DrSession(state: BitArray)
Identity key pair (Ed25519). public_key is 32 bytes; private_key is
64 bytes (libsodium’s secret-key encoding: seed ++ derived pub).
pub type IdentityKeyPair {
IdentityKeyPair(public_key: BitArray, private_key: BitArray)
}
Constructors
-
IdentityKeyPair(public_key: BitArray, private_key: BitArray)
A parsed PreKeySignalMessage. inner_message is the serialized inner
SignalMessage and is fed to dr_decrypt_message after the recipient
has initialized their Double Ratchet from the recovered X3DH secret.
pub type PksmMessage {
PksmMessage(
registration_id: Int,
base_key: BitArray,
identity_key: BitArray,
one_time_pre_key_id: option.Option(Int),
signed_pre_key_id: Int,
inner_message: BitArray,
)
}
Constructors
-
PksmMessage( registration_id: Int, base_key: BitArray, identity_key: BitArray, one_time_pre_key_id: option.Option(Int), signed_pre_key_id: Int, inner_message: BitArray, )
One-time pre-key. private_key must be stored: the DH half is needed to
complete X3DH on the responder side.
pub type PreKey {
PreKey(
key_id: Int,
public_key: BitArray,
private_key: BitArray,
)
}
Constructors
-
PreKey(key_id: Int, public_key: BitArray, private_key: BitArray)
Pre-key bundle: the public material a party publishes so others can
start sessions with them asynchronously. Serialized by encode_bundle
to exactly what the NIF consumes:
identity_key(32) || signed_pre_key(32) || signature(64) [|| one_time_pre_key(32)]
Key ids and the registration id are not part of this binary – they travel in the PreKeySignalMessage of the first message.
pub type PreKeyBundle {
PreKeyBundle(
identity_key: BitArray,
signed_pre_key: BitArray,
signature: BitArray,
one_time_pre_key: option.Option(BitArray),
)
}
Constructors
-
PreKeyBundle( identity_key: BitArray, signed_pre_key: BitArray, signature: BitArray, one_time_pre_key: option.Option(BitArray), )
Information Alice must include in her first PreKeySignalMessage so Bob can identify which of his prekeys to consume and recover the X3DH shared secret.
pub type PreKeyInfo {
PreKeyInfo(
registration_id: Int,
one_time_pre_key_id: option.Option(Int),
signed_pre_key_id: Int,
alice_ephemeral_pub: BitArray,
)
}
Constructors
-
PreKeyInfo( registration_id: Int, one_time_pre_key_id: option.Option(Int), signed_pre_key_id: Int, alice_ephemeral_pub: BitArray, )
Signed pre-key: an X25519 keypair whose public half carries an Ed25519 signature made with the identity private key.
pub type SignedPreKey {
SignedPreKey(
key_id: Int,
public_key: BitArray,
private_key: BitArray,
signature: BitArray,
)
}
Constructors
-
SignedPreKey( key_id: Int, public_key: BitArray, private_key: BitArray, signature: BitArray, )
Values
pub fn decode_bundle(
wire: BitArray,
) -> Result(PreKeyBundle, String)
Parses a pre-key bundle from its wire form. Accepts exactly 128 bytes (no one-time pre-key) or 160 bytes (with one).
pub fn dr_decrypt_message(
session: DrSession,
ciphertext: BitArray,
) -> Result(#(BitArray, DrSession), String)
Decrypt a Double Ratchet ciphertext. Returns the plaintext and the advanced session state.
pub fn dr_encrypt_message(
session: DrSession,
message: BitArray,
) -> Result(#(BitArray, DrSession), String)
Encrypt a message under the Double Ratchet. Returns the ciphertext and the advanced session state.
pub fn dr_encrypt_prekey(
session: DrSession,
message: BitArray,
info: PreKeyInfo,
) -> Result(#(BitArray, DrSession), String)
Encrypt Alice’s first message and wrap it in a PreKeySignalMessage so Bob can recover the X3DH shared secret before decrypting.
pub fn encode_bundle(bundle: PreKeyBundle) -> BitArray
Serializes a pre-key bundle to the NIF wire form: identity_key(32) || signed_pre_key(32) || signature(64) [|| one_time_pre_key(32)]
pub fn generate_identity_key_pair() -> Result(
IdentityKeyPair,
String,
)
Generates a new identity key pair.
pub fn generate_pre_key(key_id: Int) -> Result(PreKey, String)
Generates a new pre-key with the given ID.
pub fn generate_signed_pre_key(
identity_key: BitArray,
key_id: Int,
) -> Result(SignedPreKey, String)
Generates a new signed pre-key with the given ID, signed by the identity key.
pub fn init_double_ratchet(
shared_secret: BitArray,
local_identity_pub: BitArray,
remote_identity_pub: BitArray,
self_identity_priv: BitArray,
role: DrRole,
) -> Result(DrSession, String)
Initialize a Double Ratchet session.
shared_secret must be 96 bytes (typically the X3DH output).
local_identity_pub and remote_identity_pub are 32-byte Ed25519 pubs;
both are stored in DR state and folded into every message MAC (Signal
spec: HMAC scope is sender_id || receiver_id || version || message).
- Alice:
self_identity_privmay be empty (she uses a fresh ephemeral for DH). - Bob:
self_identity_privis his 64-byte Ed25519 secret, used as the initial DH ratchet pair. Bob’s encrypt fails until he receives Alice’s first message.
pub fn pksm_decode(wire: BitArray) -> Result(PksmMessage, String)
Decode a PreKeySignalMessage wire envelope.
pub fn process_pre_key_bundle(
local_identity_priv: BitArray,
bundle: PreKeyBundle,
) -> Result(#(BitArray, BitArray), String)
Performs X3DH key agreement against a remote pre-key bundle.
Returns #(shared_secret, ephemeral_pub) where the 96-byte shared secret
(32B DR root key || two 32B per-direction DR-HE header-key seeds) is fed
straight into init_double_ratchet.
pub fn process_pre_key_bundle_bob(
identity_priv: BitArray,
signed_pre_key_priv: BitArray,
one_time_pre_key_priv: BitArray,
remote_identity_pub: BitArray,
remote_ephemeral_pub: BitArray,
) -> Result(BitArray, String)
Bob’s side of X3DH. Returns the same 96-byte shared secret Alice
derives from process_pre_key_bundle (32B root key || two 32B
per-direction DR-HE header-key seeds).
Pass an empty BitArray for one_time_pre_key_priv when no OPK is
being used.