11 releases
Uses new Rust 2024
| 0.1.146 | Jan 28, 2026 |
|---|---|
| 0.1.145 | Jan 28, 2026 |
| 0.1.141 | Dec 18, 2025 |
#1166 in Cryptography
115KB
2K
SLoC
libsignal-dezire
A pure Rust implementation of the Signal Protocol, providing end-to-end encryption for messaging applications.
Features
- VXEdDSA - Verifiable XEdDSA signatures with VRF output
- X3DH - Extended Triple Diffie-Hellman key agreement
- Double Ratchet - Session encryption with forward secrecy
- FFI/JNI - C and Android bindings included
Installation
[dependencies]
libsignal-dezire = "0.1.143"
Quick Start
Key Exchange (X3DH)
use libsignal_dezire::x3dh::{x3dh_initiator, x3dh_responder, PreKeyBundle};
use libsignal_dezire::vxeddsa::{gen_keypair, vxeddsa_sign};
use libsignal_dezire::utils::encode_public_key;
// Bob publishes a prekey bundle
let bob_identity = gen_keypair();
let bob_spk = gen_keypair();
let encoded_spk = encode_public_key(&bob_spk.public);
let sig = vxeddsa_sign(&bob_identity.secret, &encoded_spk).unwrap();
let bundle = PreKeyBundle {
identity_key: bob_identity.public,
signed_prekey: SignedPreKey { id: 1, public_key: bob_spk.public, signature: sig.signature },
one_time_prekey: None,
};
// Alice initiates
let alice_identity = gen_keypair();
let result = x3dh_initiator(&alice_identity.secret, &bundle).unwrap();
// result.shared_secret, result.ephemeral_public
// Bob responds
let bob_sk = x3dh_responder(
&bob_identity.secret,
&bob_spk.secret,
None,
&alice_identity.public,
&result.ephemeral_public,
).unwrap();
assert_eq!(result.shared_secret, bob_sk);
Session Encryption (Double Ratchet)
use libsignal_dezire::ratchet::{init_sender_state, init_receiver_state, encrypt, decrypt};
// Initialize from X3DH shared secret
let mut alice = init_sender_state(shared_secret, bob_dh_public).unwrap();
let mut bob = init_receiver_state(shared_secret, bob_keypair);
// Encrypt
let (header, ciphertext) = encrypt(&mut alice, b"Hello Bob!", b"").unwrap();
// Decrypt
let plaintext = decrypt(&mut bob, &header, &ciphertext, b"").unwrap();
Associated Data
Construct AD for AEAD when sending the initial message:
use libsignal_dezire::utils::encode_public_key;
let ad = [
encode_public_key(&alice_identity_public),
encode_public_key(&bob_identity_public),
].concat(); // 66 bytes
FFI
For C/iOS integration, include libsignal-dezire.h. For Android, use the JNI bindings.
#include "libsignal-dezire.h"
X3DHInitOutput output;
x3dh_initiator_ffi(identity_private, &bundle, &output);
Security
- ✅ Security Audited
- ✅ Constant-time operations
- ✅ Memory zeroization via
zeroizecrate - ✅ Low-order point rejection
License
AGPL-v3 - see LICENSE
Dependencies
~3–16MB
~159K SLoC