#crypto #cryptography #x3dh

xxxdh

Pure Rust X3DH key exchange protocol implementation

12 releases (6 breaking)

Uses new Rust 2021

0.7.2 Apr 21, 2022
0.7.1 Mar 25, 2022
0.6.3 Feb 7, 2022
0.5.0 Dec 23, 2021

#825 in Cryptography

23 downloads per month

MIT license

24KB
496 lines

TestStatus Crate API

XXXDH

Implementation of the Extended Triple Diffie-Hellman key exchange protocol written in Rust.

Implementation is close to the Signal Spec, but Ristretto point Curve25519 used as a curve for the default implementation. Though underlying algorithms could be changed fairly easily.

Usage

//! Basic example.

use cryptimitives::{aead, kdf::sha256, key::x25519_ristretto};
use cryptraits::{convert::ToVec, key::KeyPair, signature::Sign};
use rand_core::OsRng;
use xxxdh::{
    inmem, IdentityKeyStorage, OnetimeKeyStorage, PreKeyStorage, Protocol, SignatureStorage,
};

fn main() {
    // Instantiate Alice protocol.

    let alice_identity = x25519_ristretto::KeyPair::generate_with(OsRng);
    let alice_prekey = x25519_ristretto::KeyPair::generate_with(OsRng);
    let alice_signature = alice_identity.sign(&alice_prekey.to_public().to_vec());
    let mut alice_protocol = Protocol::<
        x25519_ristretto::SecretKey,
        x25519_ristretto::EphemeralSecretKey,
        x25519_ristretto::Signature,
        inmem::Storage<_, _>,
        sha256::Kdf,
        aead::aes_gcm::Aes256Gcm,
    >::new(alice_identity, alice_prekey, alice_signature, None);

    // Instantiate Bob protocol.

    let onetime_keypair = x25519_ristretto::KeyPair::generate_with(OsRng);

    let bob_identity = x25519_ristretto::KeyPair::generate_with(OsRng);
    let bob_prekey = x25519_ristretto::KeyPair::generate_with(OsRng);
    let bob_signature = bob_identity.sign(&bob_prekey.to_public().to_vec());
    let mut bob_protocol = Protocol::<
        x25519_ristretto::SecretKey,
        x25519_ristretto::EphemeralSecretKey,
        x25519_ristretto::Signature,
        inmem::Storage<_, _>,
        sha256::Kdf,
        aead::aes_gcm::Aes256Gcm,
    >::new(
        bob_identity,
        bob_prekey,
        bob_signature,
        Some(vec![onetime_keypair]),
    );

    // Derive shared secret for Alice and prepare message for Bob.

    let bob_identity = bob_protocol.storage.get_identity_key_pair().to_public();
    let bob_prekey = bob_protocol.storage.get_prekey_pair().to_public();
    let bob_signature = bob_protocol
        .storage
        .get_signature(&bob_prekey)
        .unwrap()
        .unwrap();
    let onetime_key = bob_protocol.storage.provide_ontime_key().unwrap().unwrap();

    let (alice_identity, alice_ephemeral_key, bob_onetime_key, alice_sk, nonce, ciphertext) =
        alice_protocol
            .prepare_init_msg(&bob_identity, &bob_prekey, bob_signature, onetime_key)
            .unwrap();

    // Derive shared secret for Bob using Alice credentials.

    let bob_sk = bob_protocol
        .derive_shared_secret(
            &alice_identity,
            &alice_ephemeral_key,
            &bob_onetime_key,
            &nonce,
            &ciphertext,
        )
        .unwrap();

    println!("Alice shared secret: {:?}", alice_sk);
    println!("Bob shared secret: {:?}", bob_sk);
}

Dependencies

~7MB
~129K SLoC