MessageSession

Struct MessageSession 

Source
pub struct MessageSession { /* private fields */ }
Expand description

MessageSession manages the cryptographic state for secure message exchange between two parties using post-quantum cryptographic algorithms.

Each session contains:

  • A KEM keypair for key encapsulation mechanism
  • A digital signature keypair for signing messages
  • A shared secret established with the other party
  • A verifier for validating messages from the other party
  • A nonce for preventing replay attacks

Implementations§

Source§

impl MessageSession

Source

pub fn to_bytes(&self) -> Result<Vec<u8>, CryptoError>

Serializes the session to a byte array

§Returns
  • Result<Vec<u8>, CryptoError>: The serialized session or an error
§Security Note

The serialized data contains sensitive cryptographic material including private keys. It should be stored securely and only deserialized in a trusted environment.

Source

pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError>

Deserializes a session from a byte array

§Arguments
  • bytes - The serialized session bytes
§Returns
  • Result<Self, CryptoError>: The deserialized session or an error
§Errors

Returns an error if the byte array is not the correct length or format

Source

pub fn new_initiator( my_keypair: KEMPair, my_signer: SignerPair, base_nonce: [u8; 24], target_pubkey: &[u8; 1568], target_verifier: &[u8; 1793], ) -> Result<(Self, [u8; 1568]), CryptoError>

Creates a new session as the initiator

§Arguments
  • my_keypair - Your own KEM keypair
  • my_signer - Your own signer pair
  • base_nonce - Base nonce (0..16 session id, 16..24 counter)
  • target_pubkey - KEM public key of the target
  • target_verifier - Falcon verifier containing the public key of the target
§Returns
  • Result<(Self, [u8; PQCLEAN_MLKEM1024_CLEAN_CRYPTO_CIPHERTEXTBYTES]), CryptoError>: The session and ciphertext for the responder, or an error
Examples found in repository?
examples/full_exchange.rs (lines 17-23)
6fn main() {
7    let alice_kem = KEMPair::create();
8    let alice_signer = SignerPair::create();
9
10    let bob_kem = KEMPair::create();
11    let bob_signer = SignerPair::create();
12
13    // Create a base nonce with a new session id, and a counter of
14    let base_nonce = create_nonce(&gen_session_id(), 0);
15
16    // Lets create the message session for Alice first
17    let (mut alice_session, ciphertext) = MessageSession::new_initiator(
18        alice_kem,
19        alice_signer.clone(),
20        base_nonce,
21        &bob_kem.to_bytes().unwrap().0,    // Bob's public KEM key
22        &bob_signer.to_bytes().unwrap().0, // Bob's public signer key
23    )
24    .unwrap();
25
26    // Now for Bob it would look like this
27    let mut bob_session = MessageSession::new_responder(
28        bob_kem,
29        bob_signer.clone(),
30        base_nonce,
31        &ciphertext,
32        &alice_signer.to_bytes().unwrap().0, // Alice's public signer key
33    )
34    .unwrap();
35
36    // Now both sessions contain a shared secret they use to encrypt and decrypt messages
37    // and a nonce that is incremented with each message sent or received.
38
39    // Alice creates a mesasge and prepares to send it to Bob
40    let message = b"Hello, Bob! This is a secret message.";
41    let encrypted_message = alice_session.craft_message(message).unwrap();
42
43    // Bob decrypts and verifies Alice's message
44    let raw_message = bob_session.validate_message(&encrypted_message).unwrap();
45
46    // Both message and raw_message are equal, let's print them out to illustrate
47    let message_str = String::from_utf8_lossy(message);
48    let raw_message_str = String::from_utf8_lossy(&raw_message);
49
50    println!("[1] Alice's message: {}", message_str);
51    println!("[2] Bob's decrypted message: {}", raw_message_str);
52
53    // Bob crafts a reply message to Alice
54    let reply = b"Hello, Alice! I received your message safely.";
55    let encrypted_reply = bob_session.craft_message(reply).unwrap();
56
57    // Alice decrypts and verifies Bob's reply
58    let raw_reply = alice_session.validate_message(&encrypted_reply).unwrap();
59
60    // Both reply and raw_reply are equal, let's print them again
61    let reply_str = String::from_utf8_lossy(reply);
62    let raw_reply_str = String::from_utf8_lossy(&raw_reply);
63
64    println!("[3] Bob's reply: {}", reply_str);
65    println!("[4] Alice's decrypted reply: {}", raw_reply_str);
66}
Source

pub fn new_responder( my_keypair: KEMPair, my_signer: SignerPair, base_nonce: [u8; 24], ciphertext_bytes: &[u8; 1568], sender_verifier: &[u8; 1793], ) -> Result<Self, CryptoError>

Creates a new session as the responder

§Arguments
  • my_keypair - Your own KEM keypair
  • my_signer - Your own signer pair
  • base_nonce - Base nonce (0..16 session id, 16..24 counter)
  • ciphertext_bytes - KEM ciphertext sent by the initiator
  • sender_verifier - Falcon verifier containing the public key of the initiator
§Returns
  • Result<Self, CryptoError>: The session or an error
Examples found in repository?
examples/full_exchange.rs (lines 27-33)
6fn main() {
7    let alice_kem = KEMPair::create();
8    let alice_signer = SignerPair::create();
9
10    let bob_kem = KEMPair::create();
11    let bob_signer = SignerPair::create();
12
13    // Create a base nonce with a new session id, and a counter of
14    let base_nonce = create_nonce(&gen_session_id(), 0);
15
16    // Lets create the message session for Alice first
17    let (mut alice_session, ciphertext) = MessageSession::new_initiator(
18        alice_kem,
19        alice_signer.clone(),
20        base_nonce,
21        &bob_kem.to_bytes().unwrap().0,    // Bob's public KEM key
22        &bob_signer.to_bytes().unwrap().0, // Bob's public signer key
23    )
24    .unwrap();
25
26    // Now for Bob it would look like this
27    let mut bob_session = MessageSession::new_responder(
28        bob_kem,
29        bob_signer.clone(),
30        base_nonce,
31        &ciphertext,
32        &alice_signer.to_bytes().unwrap().0, // Alice's public signer key
33    )
34    .unwrap();
35
36    // Now both sessions contain a shared secret they use to encrypt and decrypt messages
37    // and a nonce that is incremented with each message sent or received.
38
39    // Alice creates a mesasge and prepares to send it to Bob
40    let message = b"Hello, Bob! This is a secret message.";
41    let encrypted_message = alice_session.craft_message(message).unwrap();
42
43    // Bob decrypts and verifies Alice's message
44    let raw_message = bob_session.validate_message(&encrypted_message).unwrap();
45
46    // Both message and raw_message are equal, let's print them out to illustrate
47    let message_str = String::from_utf8_lossy(message);
48    let raw_message_str = String::from_utf8_lossy(&raw_message);
49
50    println!("[1] Alice's message: {}", message_str);
51    println!("[2] Bob's decrypted message: {}", raw_message_str);
52
53    // Bob crafts a reply message to Alice
54    let reply = b"Hello, Alice! I received your message safely.";
55    let encrypted_reply = bob_session.craft_message(reply).unwrap();
56
57    // Alice decrypts and verifies Bob's reply
58    let raw_reply = alice_session.validate_message(&encrypted_reply).unwrap();
59
60    // Both reply and raw_reply are equal, let's print them again
61    let reply_str = String::from_utf8_lossy(reply);
62    let raw_reply_str = String::from_utf8_lossy(&raw_reply);
63
64    println!("[3] Bob's reply: {}", reply_str);
65    println!("[4] Alice's decrypted reply: {}", raw_reply_str);
66}
Source

pub fn craft_message(&mut self, message: &[u8]) -> Result<Vec<u8>, CryptoError>

Creates a signed and encrypted message for the other party

§Arguments
  • message - The plaintext message to encrypt
§Returns
  • Result<Vec<u8>, CryptoError>: The encrypted message or an error
§Security Note

This method automatically increments the nonce counter to ensure uniqueness for each message.

Examples found in repository?
examples/full_exchange.rs (line 41)
6fn main() {
7    let alice_kem = KEMPair::create();
8    let alice_signer = SignerPair::create();
9
10    let bob_kem = KEMPair::create();
11    let bob_signer = SignerPair::create();
12
13    // Create a base nonce with a new session id, and a counter of
14    let base_nonce = create_nonce(&gen_session_id(), 0);
15
16    // Lets create the message session for Alice first
17    let (mut alice_session, ciphertext) = MessageSession::new_initiator(
18        alice_kem,
19        alice_signer.clone(),
20        base_nonce,
21        &bob_kem.to_bytes().unwrap().0,    // Bob's public KEM key
22        &bob_signer.to_bytes().unwrap().0, // Bob's public signer key
23    )
24    .unwrap();
25
26    // Now for Bob it would look like this
27    let mut bob_session = MessageSession::new_responder(
28        bob_kem,
29        bob_signer.clone(),
30        base_nonce,
31        &ciphertext,
32        &alice_signer.to_bytes().unwrap().0, // Alice's public signer key
33    )
34    .unwrap();
35
36    // Now both sessions contain a shared secret they use to encrypt and decrypt messages
37    // and a nonce that is incremented with each message sent or received.
38
39    // Alice creates a mesasge and prepares to send it to Bob
40    let message = b"Hello, Bob! This is a secret message.";
41    let encrypted_message = alice_session.craft_message(message).unwrap();
42
43    // Bob decrypts and verifies Alice's message
44    let raw_message = bob_session.validate_message(&encrypted_message).unwrap();
45
46    // Both message and raw_message are equal, let's print them out to illustrate
47    let message_str = String::from_utf8_lossy(message);
48    let raw_message_str = String::from_utf8_lossy(&raw_message);
49
50    println!("[1] Alice's message: {}", message_str);
51    println!("[2] Bob's decrypted message: {}", raw_message_str);
52
53    // Bob crafts a reply message to Alice
54    let reply = b"Hello, Alice! I received your message safely.";
55    let encrypted_reply = bob_session.craft_message(reply).unwrap();
56
57    // Alice decrypts and verifies Bob's reply
58    let raw_reply = alice_session.validate_message(&encrypted_reply).unwrap();
59
60    // Both reply and raw_reply are equal, let's print them again
61    let reply_str = String::from_utf8_lossy(reply);
62    let raw_reply_str = String::from_utf8_lossy(&raw_reply);
63
64    println!("[3] Bob's reply: {}", reply_str);
65    println!("[4] Alice's decrypted reply: {}", raw_reply_str);
66}
Source

pub fn validate_message( &mut self, ciphertext: &[u8], ) -> Result<Vec<u8>, CryptoError>

Decrypts and validates a message from the other party

§Arguments
  • ciphertext - The encrypted message
§Returns
  • Result<Vec<u8>, CryptoError>: The decrypted and validated message or an error
§Security Note

This method automatically increments the nonce counter to match the sender’s nonce. If the nonces are out of sync, validation will fail.

Examples found in repository?
examples/full_exchange.rs (line 44)
6fn main() {
7    let alice_kem = KEMPair::create();
8    let alice_signer = SignerPair::create();
9
10    let bob_kem = KEMPair::create();
11    let bob_signer = SignerPair::create();
12
13    // Create a base nonce with a new session id, and a counter of
14    let base_nonce = create_nonce(&gen_session_id(), 0);
15
16    // Lets create the message session for Alice first
17    let (mut alice_session, ciphertext) = MessageSession::new_initiator(
18        alice_kem,
19        alice_signer.clone(),
20        base_nonce,
21        &bob_kem.to_bytes().unwrap().0,    // Bob's public KEM key
22        &bob_signer.to_bytes().unwrap().0, // Bob's public signer key
23    )
24    .unwrap();
25
26    // Now for Bob it would look like this
27    let mut bob_session = MessageSession::new_responder(
28        bob_kem,
29        bob_signer.clone(),
30        base_nonce,
31        &ciphertext,
32        &alice_signer.to_bytes().unwrap().0, // Alice's public signer key
33    )
34    .unwrap();
35
36    // Now both sessions contain a shared secret they use to encrypt and decrypt messages
37    // and a nonce that is incremented with each message sent or received.
38
39    // Alice creates a mesasge and prepares to send it to Bob
40    let message = b"Hello, Bob! This is a secret message.";
41    let encrypted_message = alice_session.craft_message(message).unwrap();
42
43    // Bob decrypts and verifies Alice's message
44    let raw_message = bob_session.validate_message(&encrypted_message).unwrap();
45
46    // Both message and raw_message are equal, let's print them out to illustrate
47    let message_str = String::from_utf8_lossy(message);
48    let raw_message_str = String::from_utf8_lossy(&raw_message);
49
50    println!("[1] Alice's message: {}", message_str);
51    println!("[2] Bob's decrypted message: {}", raw_message_str);
52
53    // Bob crafts a reply message to Alice
54    let reply = b"Hello, Alice! I received your message safely.";
55    let encrypted_reply = bob_session.craft_message(reply).unwrap();
56
57    // Alice decrypts and verifies Bob's reply
58    let raw_reply = alice_session.validate_message(&encrypted_reply).unwrap();
59
60    // Both reply and raw_reply are equal, let's print them again
61    let reply_str = String::from_utf8_lossy(reply);
62    let raw_reply_str = String::from_utf8_lossy(&raw_reply);
63
64    println!("[3] Bob's reply: {}", reply_str);
65    println!("[4] Alice's decrypted reply: {}", raw_reply_str);
66}
Source

pub fn get_counter(&self) -> u64

Gets the current nonce counter value

§Returns
  • u64: The current nonce counter value

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V