//! SAKE conformance tests use crate::{ Signer, ed25519::PrivateKey, handshake::sake::{ Ack, Context, Syn, SynAck, Version, dial_end, dial_start, listen_end, listen_start, }, }; use commonware_codec::{Encode, conformance::CodecConformance}; use commonware_conformance::{Conformance, conformance_tests}; use commonware_math::algebra::Random; use commonware_utils::TestRng; use rand::RngExt as _; /// Runs a full handshake for `version`, logging every message and the summary of the resulting /// transcript. fn exchange(seed: u64, version: Version) -> Vec { let mut rng = TestRng::new(seed); let mut log = Vec::new(); // Namespaces of 128 bytes or more reach the multi-byte packet lengths where transcript // framings differ, and a nonzero high byte pins the timestamp byte order. The listener's clock // runs ahead of the dialer's, so each message carries its sender's own timestamp. let mut namespace = vec![0u8; rng.random_range(0..=300)]; rng.fill(&mut namespace[..]); let dialer_time = rng.random_range(1u64 << 56..1 << 63); let listener_time = dialer_time + rng.random_range(1..1000); let dialer_key = PrivateKey::random(&mut rng); let listener_key = PrivateKey::random(&mut rng); let (dialer_state, dialer_greeting) = dial_start( &mut rng, Context::new( &namespace, dialer_time, listener_time..listener_time + 1, dialer_key.clone(), listener_key.public_key(), version, ), ); log.extend(dialer_greeting.encode()); let (listener_state, listener_greeting_ack) = listen_start( &mut rng, Context::new( &namespace, listener_time, dialer_time..dialer_time + 1, listener_key, dialer_key.public_key(), version, ), dialer_greeting, ) .unwrap(); log.extend(listener_greeting_ack.encode()); let (dialer_ack, dialer_transcript) = dial_end(dialer_state, listener_greeting_ack).unwrap(); log.extend(dialer_ack.encode()); let listener_transcript = listen_end(listener_state, dialer_ack).unwrap(); let summary = dialer_transcript.summarize(); assert_eq!(summary, listener_transcript.summarize()); log.extend(summary.encode()); log } struct SakeV0; impl Conformance for SakeV0 { async fn commit(seed: u64) -> Vec { exchange(seed, Version::V0) } } struct SakeV1; impl Conformance for SakeV1 { async fn commit(seed: u64) -> Vec { exchange(seed, Version::V1) } } conformance_tests! { SakeV0 => 4096, SakeV1 => 4096, CodecConformance>, CodecConformance>, CodecConformance, }