From dc0c56e24582233b6b62932e6bfddac6afb27e63 Mon Sep 17 00:00:00 2001 From: Franziskus Kiefer Date: Tue, 18 Jun 2024 11:19:52 +0200 Subject: [PATCH] wip; no chrono and encaps example --- benchmarks/benches/sha2.rs | 2 +- libcrux-psq/benches/psq.rs | 16 +- libcrux-psq/examples/encaps.rs | 17 ++ libcrux-psq/examples/sizes.rs | 11 +- libcrux-psq/flamegraph.svg | 491 +++++++++++++++++++++++++++++++++ libcrux-psq/src/psq.rs | 52 ++-- 6 files changed, 552 insertions(+), 37 deletions(-) create mode 100644 libcrux-psq/examples/encaps.rs create mode 100644 libcrux-psq/flamegraph.svg diff --git a/benchmarks/benches/sha2.rs b/benchmarks/benches/sha2.rs index 297dee805..d9f82577e 100644 --- a/benchmarks/benches/sha2.rs +++ b/benchmarks/benches/sha2.rs @@ -10,7 +10,7 @@ macro_rules! impl_comp { ($fun:ident, $libcrux:expr, $ring:expr, $rust_crypto:ty, $openssl:expr) => { // Comparing libcrux performance for different payload sizes and other implementations. fn $fun(c: &mut Criterion) { - const PAYLOAD_SIZES: [usize; 1] = [1024 * 1024 * 10]; + const PAYLOAD_SIZES: [usize; 5] = [100, 1024, 2048, 4096, 8192]; let mut group = c.benchmark_group(stringify!($fun).replace("_", " ")); diff --git a/libcrux-psq/benches/psq.rs b/libcrux-psq/benches/psq.rs index 616d57672..a25a8b343 100644 --- a/libcrux-psq/benches/psq.rs +++ b/libcrux-psq/benches/psq.rs @@ -175,7 +175,7 @@ pub fn comparisons_psq_send(c: &mut Criterion) { |(_sk, pk)| { let _ = pk.send_psk( b"bench context", - chrono::Duration::hours(1), + Duration::from_secs(3600), &mut thread_rng(), ); }, @@ -189,7 +189,7 @@ pub fn comparisons_psq_send(c: &mut Criterion) { |(_sk, pk)| { let _ = pk.send_psk( b"bench context", - chrono::Duration::hours(1), + Duration::from_secs(3600), &mut thread_rng(), ); }, @@ -206,7 +206,7 @@ pub fn comparisons_psq_send(c: &mut Criterion) { |(_sk, pk)| { let _ = pk.send_psk( b"bench context", - chrono::Duration::hours(1), + Duration::from_secs(3600), &mut thread_rng(), ); }, @@ -223,7 +223,7 @@ pub fn comparisons_psq_send(c: &mut Criterion) { |(_sk, pk)| { let _ = pk.send_psk( b"bench context", - chrono::Duration::hours(1), + Duration::from_secs(3600), &mut thread_rng(), ); }, @@ -245,7 +245,7 @@ pub fn comparisons_psq_receive(c: &mut Criterion) { .unwrap(); let (_psk, message) = pk - .send_psk(b"bench context", chrono::Duration::hours(1), &mut rng) + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) .unwrap(); (pk, sk, message) }, @@ -264,7 +264,7 @@ pub fn comparisons_psq_receive(c: &mut Criterion) { .unwrap(); let (_psk, message) = pk - .send_psk(b"bench context", chrono::Duration::hours(1), &mut rng) + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) .unwrap(); (pk, sk, message) }, @@ -285,7 +285,7 @@ pub fn comparisons_psq_receive(c: &mut Criterion) { .unwrap(); let (_psk, message) = pk - .send_psk(b"bench context", chrono::Duration::hours(1), &mut rng) + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) .unwrap(); (pk, sk, message) }, @@ -306,7 +306,7 @@ pub fn comparisons_psq_receive(c: &mut Criterion) { .unwrap(); let (_psk, message) = pk - .send_psk(b"bench context", chrono::Duration::hours(1), &mut rng) + .send_psk(b"bench context", Duration::from_secs(3600), &mut rng) .unwrap(); (pk, sk, message) }, diff --git a/libcrux-psq/examples/encaps.rs b/libcrux-psq/examples/encaps.rs new file mode 100644 index 000000000..6c26ca3d3 --- /dev/null +++ b/libcrux-psq/examples/encaps.rs @@ -0,0 +1,17 @@ +use std::time::Duration; + +use libcrux_psq::{generate_key_pair, Algorithm}; +use rand::thread_rng; + +fn main() { + let mut rng = thread_rng(); + let mlkem_keypair = generate_key_pair(Algorithm::MlKem768, &mut rng).unwrap(); + + for _ in 0..100_000 { + let _ = core::hint::black_box(mlkem_keypair.1.send_psk( + b"size context", + Duration::from_secs(3600), + &mut rng, + )); + } +} diff --git a/libcrux-psq/examples/sizes.rs b/libcrux-psq/examples/sizes.rs index 2d5d75a7d..b2fbf2e7d 100644 --- a/libcrux-psq/examples/sizes.rs +++ b/libcrux-psq/examples/sizes.rs @@ -1,4 +1,5 @@ -use chrono::Duration; +use std::time::Duration; + use libcrux_psq::*; use rand::{self, thread_rng}; @@ -11,19 +12,19 @@ fn main() { let mlkem_message = mlkem_keypair .1 - .send_psk(b"size context", Duration::hours(1), &mut rng) + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) .unwrap(); let x25519_message = x25519_keypair .1 - .send_psk(b"size context", Duration::hours(1), &mut rng) + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) .unwrap(); let xwing_message = xwing_keypair .1 - .send_psk(b"size context", Duration::hours(1), &mut rng) + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) .unwrap(); let classic_mceliece_message = classic_mceliece_keypair .1 - .send_psk(b"size context", Duration::hours(1), &mut rng) + .send_psk(b"size context", Duration::from_secs(3600), &mut rng) .unwrap(); println!("ML-KEM-768:"); diff --git a/libcrux-psq/flamegraph.svg b/libcrux-psq/flamegraph.svg new file mode 100644 index 000000000..9a50187c4 --- /dev/null +++ b/libcrux-psq/flamegraph.svg @@ -0,0 +1,491 @@ +Flame Graph Reset ZoomSearch encaps`DYLD-STUB$$memcpy (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_finish (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_last (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_nblocks (6 samples, 0.22%)encaps`sha256_update (1,169 samples, 42.65%)encaps`sha256_updatelibsystem_c.dylib`__memcpy_chk (2 samples, 0.07%)encaps`Hacl_HMAC_compute_sha2_256 (1,184 samples, 43.20%)encaps`Hacl_HMAC_compute_sha2_256libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)encaps`Hacl_Hash_SHA2_sha256_update_nblocks (1 samples, 0.04%)libsystem_c.dylib`DYLD-STUB$$mkdtempat_np (1 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)encaps`Hacl_HKDF_expand_sha2_256 (1,193 samples, 43.52%)encaps`Hacl_HKDF_expand_sha2_256libsystem_pthread.dylib`___chkstk_darwin (4 samples, 0.15%)encaps`Hacl_Hash_SHA2_sha256_finish (1 samples, 0.04%)encaps`sha256_update (91 samples, 3.32%)enc..libsystem_c.dylib`__memcpy_chk (1 samples, 0.04%)encaps`Hacl_HMAC_compute_sha2_256 (94 samples, 3.43%)enc..libsystem_platform.dylib`_platform_memmove (1 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_malloc (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_realloc (1 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (1 samples, 0.04%)libsystem_malloc.dylib`szone_realloc (2 samples, 0.07%)libsystem_malloc.dylib`szone_malloc_should_clear (1 samples, 0.04%)libsystem_malloc.dylib`small_malloc_should_clear (1 samples, 0.04%)libsystem_malloc.dylib`_malloc_zone_realloc (8 samples, 0.29%)libsystem_platform.dylib`_platform_memmove (3 samples, 0.11%)libsystem_malloc.dylib`default_zone_realloc (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_realloc (1 samples, 0.04%)encaps`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (11 samples, 0.40%)encaps`alloc::raw_vec::finish_grow (11 samples, 0.40%)libsystem_malloc.dylib`_realloc (11 samples, 0.40%)libsystem_malloc.dylib`szone_size (1 samples, 0.04%)libsystem_malloc.dylib`tiny_size (1 samples, 0.04%)libsystem_malloc.dylib`small_malloc_should_clear (2 samples, 0.07%)encaps`libcrux_kem::Ct::encode (4 samples, 0.15%)libsystem_malloc.dylib`szone_malloc_should_clear (2 samples, 0.07%)libsystem_malloc.dylib`small_malloc_should_clear (2 samples, 0.07%)libsystem_malloc.dylib`small_malloc_from_free_list (1 samples, 0.04%)libsystem_malloc.dylib`small_free_list_remove_ptr_no_clear (1 samples, 0.04%)encaps`<rand_chacha::chacha::ChaCha12Core as rand_core::block::BlockRngCore>::generate (12 samples, 0.44%)encaps`DYLD-STUB$$memcpy (1 samples, 0.04%)encaps`libcrux_ml_kem::ind_cpa::encrypt (1,058 samples, 38.60%)encaps`libcrux_ml_kem::ind_cpa::encryptlibsystem_platform.dylib`_platform_memmove (31 samples, 1.13%)encaps`libcrux_ml_kem::mlkem768::encapsulate (1,365 samples, 49.80%)encaps`libcrux_ml_kem::mlkem768::encapsulatelibsystem_platform.dylib`_platform_memset (21 samples, 0.77%)encaps`libcrux_kem::PublicKey::encapsulate (1,380 samples, 50.35%)encaps`libcrux_kem::PublicKey::encapsulatelibsystem_platform.dylib`_platform_memmove (2 samples, 0.07%)encaps`libcrux_kem::Ss::encode (1 samples, 0.04%)encaps`libcrux_ml_kem::mlkem768::encapsulate (2 samples, 0.07%)libsystem_c.dylib`clock_gettime (5 samples, 0.18%)libsystem_c.dylib`gettimeofday (5 samples, 0.18%)libsystem_kernel.dylib`mach_absolute_time (5 samples, 0.18%)libsystem_malloc.dylib`_malloc_zone_malloc (2 samples, 0.07%)libsystem_malloc.dylib`_nanov2_free (2 samples, 0.07%)libsystem_malloc.dylib`_szone_free (1 samples, 0.04%)libsystem_malloc.dylib`free_small (1 samples, 0.04%)libsystem_malloc.dylib`nanov2_calloc (1 samples, 0.04%)libsystem_platform.dylib`__bzero (1 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (7 samples, 0.26%)libsystem_platform.dylib`_platform_memset (4 samples, 0.15%)encaps`encaps::main (2,716 samples, 99.09%)encaps`encaps::mainlibsystem_pthread.dylib`___chkstk_darwin (2 samples, 0.07%)libsystem_malloc.dylib`_free (1 samples, 0.04%)dyld`start (2,740 samples, 99.96%)dyld`startencaps`main (2,740 samples, 99.96%)encaps`mainencaps`std::sys_common::backtrace::__rust_begin_short_backtrace (2,740 samples, 99.96%)encaps`std::sys_common::backtrace::__rust_begin_short_backtracelibsystem_platform.dylib`_platform_memmove (23 samples, 0.84%)all (2,741 samples, 100%)libsystem_kernel.dylib`__exit (1 samples, 0.04%) \ No newline at end of file diff --git a/libcrux-psq/src/psq.rs b/libcrux-psq/src/psq.rs index 4b4abee7d..7f9444b47 100644 --- a/libcrux-psq/src/psq.rs +++ b/libcrux-psq/src/psq.rs @@ -3,7 +3,8 @@ //! This crate implements a post-quantum (PQ) pre-shared key (PSK) establishment //! protocol. -use chrono::{DateTime, Duration, Utc}; +use std::time::{Duration, Instant, SystemTime}; + use classic_mceliece_rust::{decapsulate_boxed, encapsulate_boxed}; use libcrux_hmac::hmac; use rand::{CryptoRng, Rng}; @@ -236,10 +237,13 @@ impl PublicKey<'_> { .try_into() .expect("should receive the correct number of bytes from HKDF"); - let now = Utc::now(); - let ts = now.timestamp_millis(); + let now = SystemTime::now(); + let ts = now + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_millis(); let mut mac_input = ts.to_be_bytes().to_vec(); - mac_input.extend_from_slice(&psk_ttl.num_milliseconds().to_be_bytes()); + mac_input.extend_from_slice(&psk_ttl.as_millis().to_be_bytes()); let mac: Mac = hmac( libcrux_hmac::Algorithm::Sha256, @@ -276,16 +280,10 @@ impl PrivateKey<'_> { mac, } = message; - let received_ts = if let Some(time) = DateTime::from_timestamp(*ts, 0) { - time - } else { - return Err(Error::DerivationError); - }; - - let now = Utc::now(); - if now.signed_duration_since(received_ts) >= *psk_ttl { - return Err(Error::DerivationError); - } + // let now = Instant::now(); + // if now.duration_since(received_ts) >= *psk_ttl { + // return Err(Error::DerivationError); + // } let ik = enc.decapsulate(&self).map_err(|_| Error::DerivationError)?; @@ -310,7 +308,7 @@ impl PrivateKey<'_> { .map_err(|_| Error::DerivationError)?; let mut mac_input = (*ts).to_be_bytes().to_vec(); - mac_input.extend_from_slice(&psk_ttl.num_milliseconds().to_be_bytes()); + mac_input.extend_from_slice(&psk_ttl.as_millis().to_be_bytes()); let recomputed_mac: Mac = hmac( libcrux_hmac::Algorithm::Sha256, @@ -336,7 +334,7 @@ impl PrivateKey<'_> { } pub struct PskMessage { enc: Ciphertext, - ts: i64, + ts: u128, psk_ttl: Duration, mac: Mac, } @@ -347,9 +345,9 @@ impl PskMessage { } pub fn size(&self) -> usize { self.ct_size() - + self.mac.len() - + self.ts.to_be_bytes().len() - + self.psk_ttl.num_milliseconds().to_be_bytes().len() + + MAC_LENGTH // self.mac.len() + + 8 // self.ts.to_be_bytes().len() + + 8 // self.psk_ttl.num_milliseconds().to_be_bytes().len() } } #[cfg(test)] @@ -362,7 +360,9 @@ mod tests { let (sk, pk) = generate_key_pair(Algorithm::X25519, &mut rng).unwrap(); eprintln!("Size of pk: {}", std::mem::size_of::()); let sctx = b"test context"; - let (psk_initiator, message) = pk.send_psk(sctx, Duration::hours(2), &mut rng).unwrap(); + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); assert_eq!(psk_initiator, psk_responder); @@ -373,7 +373,9 @@ mod tests { let mut rng = rand::thread_rng(); let (sk, pk) = generate_key_pair(Algorithm::MlKem768, &mut rng).unwrap(); let sctx = b"test context"; - let (psk_initiator, message) = pk.send_psk(sctx, Duration::hours(2), &mut rng).unwrap(); + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); assert_eq!(psk_initiator, psk_responder); @@ -384,7 +386,9 @@ mod tests { let mut rng = rand::thread_rng(); let (sk, pk) = generate_key_pair(Algorithm::XWingKemDraft02, &mut rng).unwrap(); let sctx = b"test context"; - let (psk_initiator, message) = pk.send_psk(sctx, Duration::hours(2), &mut rng).unwrap(); + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); assert_eq!(psk_initiator, psk_responder); @@ -395,7 +399,9 @@ mod tests { let mut rng = rand::thread_rng(); let (sk, pk) = generate_key_pair(Algorithm::ClassicMcEliece, &mut rng).unwrap(); let sctx = b"test context"; - let (psk_initiator, message) = pk.send_psk(sctx, Duration::hours(2), &mut rng).unwrap(); + let (psk_initiator, message) = pk + .send_psk(sctx, Duration::from_secs(2 * 3600), &mut rng) + .unwrap(); let psk_responder = sk.receive_psk(&pk, &message, sctx).unwrap(); assert_eq!(psk_initiator, psk_responder);