Skip to main content

full_exchange/
full_exchange.rs

1use pq_msg::{
2    exchange::{pair::KEMPair, prekey::SignedPrekey},
3    messaging::{MessageSession, create_nonce, gen_session_id},
4    signatures::keypair::{SignerPair, ViewOperations},
5};
6
7fn main() {
8    let alice_signer = SignerPair::create();
9    let mut bob_signer = SignerPair::create();
10
11    // Bob creates a one-time prekey and signs its public part, which he shares with Alice
12    let bob_prekey = KEMPair::create();
13    let bob_signed_prekey = SignedPrekey::new(&mut bob_signer, &bob_prekey).unwrap();
14
15    // Create a base nonce with a new session id, and a counter of 0
16    let base_nonce = create_nonce(&gen_session_id(), 0);
17
18    // Lets create the message session for Alice first. This checks that the prekey
19    // was signed by Bob.
20    let (mut alice_session, ciphertext) = MessageSession::new_initiator(
21        alice_signer.clone(),
22        base_nonce,
23        &bob_signed_prekey,
24        bob_signer.pub_key_bytes(), // Bob's public signer key
25    )
26    .unwrap();
27
28    // Now for Bob it would look like this
29    let mut bob_session = MessageSession::new_responder(
30        &bob_prekey,
31        bob_signer.clone(),
32        base_nonce,
33        &ciphertext,
34        alice_signer.pub_key_bytes(), // Alice's public signer key
35    )
36    .unwrap();
37
38    // The prekey was one-time, so Bob deletes it now (dropping it wipes it from memory)
39    drop(bob_prekey);
40
41    // Both sessions now hold one chain key per direction, derived from the shared secret.
42    // Every message gets its own key, and the chain moves forward after each one.
43
44    // Alice creates a message and prepares to send it to Bob
45    let message = b"Hello, Bob! This is a secret message.";
46    let encrypted_message = alice_session.craft_message(message).unwrap();
47
48    // Bob decrypts and verifies Alice's message
49    let raw_message = bob_session.validate_message(&encrypted_message).unwrap();
50
51    // Both message and raw_message are equal, let's print them out to illustrate
52    let message_str = String::from_utf8_lossy(message);
53    let raw_message_str = String::from_utf8_lossy(&raw_message);
54
55    println!("[1] Alice's message: {}", message_str);
56    println!("[2] Bob's decrypted message: {}", raw_message_str);
57
58    // Bob crafts a reply message to Alice
59    let reply = b"Hello, Alice! I received your message safely.";
60    let encrypted_reply = bob_session.craft_message(reply).unwrap();
61
62    // Alice decrypts and verifies Bob's reply
63    let raw_reply = alice_session.validate_message(&encrypted_reply).unwrap();
64
65    // Both reply and raw_reply are equal, let's print them again
66    let reply_str = String::from_utf8_lossy(reply);
67    let raw_reply_str = String::from_utf8_lossy(&raw_reply);
68
69    println!("[3] Bob's reply: {}", reply_str);
70    println!("[4] Alice's decrypted reply: {}", raw_reply_str);
71}