prekey_server/
prekey_server.rs1use std::collections::HashMap;
5
6use pq_msg::{
7 exchange::{
8 pair::KEMPair,
9 prekey::{PrekeyId, SignedPrekey},
10 },
11 messaging::{MessageSession, create_nonce, gen_session_id},
12 server::PrekeyServer,
13 signatures::keypair::{SignerPair, ViewOperations},
14};
15
16fn main() {
17 let mut server = PrekeyServer::new();
18
19 let mut bob_signer = SignerPair::create();
21 let bob_last_resort = KEMPair::create();
22 let bob_last_resort_signed = SignedPrekey::new(&mut bob_signer, &bob_last_resort).unwrap();
23
24 let mut bob_one_time: HashMap<PrekeyId, KEMPair> = HashMap::new();
25 let mut published = Vec::new();
26 for _ in 0..3 {
27 let prekey = KEMPair::create();
28 let signed = SignedPrekey::new(&mut bob_signer, &prekey).unwrap();
29 bob_one_time.insert(signed.id(), prekey);
30 published.push(signed);
31 }
32 server
33 .publish(
34 "bob",
35 *bob_signer.pub_key_bytes(),
36 bob_last_resort_signed.clone(),
37 published,
38 )
39 .unwrap();
40 println!(
41 "Bob published 3 one-time prekeys and a last-resort prekey ({} one-time left)",
42 server.one_time_remaining(&"bob")
43 );
44
45 let alice_signer = SignerPair::create();
47 let bundle = server.fetch(&"bob").unwrap();
48
49 assert_eq!(&bundle.identity, bob_signer.pub_key_bytes());
52
53 let base_nonce = create_nonce(&gen_session_id(), 0);
54 let (mut alice_session, ciphertext) = MessageSession::new_initiator(
55 alice_signer.clone(),
56 base_nonce,
57 &bundle.prekey,
58 &bundle.identity,
59 )
60 .unwrap();
61
62 let prekey_id = bundle.prekey.id();
64
65 let mut bob_session = if let Some(prekey) = bob_one_time.remove(&prekey_id) {
67 MessageSession::new_responder(
70 &prekey,
71 bob_signer.clone(),
72 base_nonce,
73 &ciphertext,
74 alice_signer.pub_key_bytes(),
75 )
76 .unwrap()
77 } else if prekey_id == bob_last_resort_signed.id() {
78 MessageSession::new_responder(
80 &bob_last_resort,
81 bob_signer.clone(),
82 base_nonce,
83 &ciphertext,
84 alice_signer.pub_key_bytes(),
85 )
86 .unwrap()
87 } else {
88 panic!("unknown prekey");
89 };
90 println!(
91 "Session set up; Bob has {} one-time prekey secrets left on his device",
92 bob_one_time.len()
93 );
94
95 let encrypted = alice_session.craft_message(b"Hi Bob!").unwrap();
97 let message = bob_session.validate_message(&encrypted).unwrap();
98 println!("Bob received: {}", String::from_utf8_lossy(&message));
99
100 let encrypted = bob_session.craft_message(b"Hi Alice!").unwrap();
101 let reply = alice_session.validate_message(&encrypted).unwrap();
102 println!("Alice received: {}", String::from_utf8_lossy(&reply));
103}