From 6832d78cf67552b3644583a249c236bf39ab0cb0 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Tue, 13 Aug 2024 17:08:57 +0200 Subject: [PATCH 1/4] Separate parameter set benchmarks --- libcrux-ml-dsa/Cargo.toml | 10 ++- .../benches/{manual.rs => bench_utils.rs} | 62 +++++++++---------- libcrux-ml-dsa/benches/manual44.rs | 15 +++++ libcrux-ml-dsa/benches/manual65.rs | 15 +++++ libcrux-ml-dsa/benches/manual87.rs | 15 +++++ 5 files changed, 83 insertions(+), 34 deletions(-) rename libcrux-ml-dsa/benches/{manual.rs => bench_utils.rs} (70%) create mode 100644 libcrux-ml-dsa/benches/manual44.rs create mode 100644 libcrux-ml-dsa/benches/manual65.rs create mode 100644 libcrux-ml-dsa/benches/manual87.rs diff --git a/libcrux-ml-dsa/Cargo.toml b/libcrux-ml-dsa/Cargo.toml index 5127e1020..5408a697b 100644 --- a/libcrux-ml-dsa/Cargo.toml +++ b/libcrux-ml-dsa/Cargo.toml @@ -29,7 +29,15 @@ simd128 = [] simd256 = [] [[bench]] -name = "manual" +name = "manual44" +harness = false + +[[bench]] +name = "manual65" +harness = false + +[[bench]] +name = "manual87" harness = false [[bench]] diff --git a/libcrux-ml-dsa/benches/manual.rs b/libcrux-ml-dsa/benches/bench_utils.rs similarity index 70% rename from libcrux-ml-dsa/benches/manual.rs rename to libcrux-ml-dsa/benches/bench_utils.rs index af4b36b43..604bb0364 100644 --- a/libcrux-ml-dsa/benches/manual.rs +++ b/libcrux-ml-dsa/benches/bench_utils.rs @@ -1,21 +1,15 @@ -use std::time::{Duration, Instant}; - -use libcrux_ml_dsa::{ - ml_dsa_44::{self, MLDSA44KeyPair, MLDSA44Signature}, - ml_dsa_65::{self, MLDSA65KeyPair, MLDSA65Signature}, - ml_dsa_87::{self, MLDSA87KeyPair, MLDSA87Signature}, - KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, -}; -use rand::{rngs::OsRng, RngCore}; - -fn random_array() -> [u8; L] { - let mut rng = OsRng; +use rand::RngCore; + +#[allow(unused)] +pub(crate) fn random_array() -> [u8; L] { + let mut rng = rand::rngs::OsRng; let mut seed = [0; L]; rng.try_fill_bytes(&mut seed).unwrap(); seed } -fn print_time(label: &str, d: Duration) { +#[allow(unused)] +pub(crate) fn print_time(label: &str, d: std::time::Duration) { let micros = d.as_micros(); let time = if micros < (1_000 * ITERATIONS as u128) { format!("{} μs", micros / ITERATIONS as u128) @@ -39,34 +33,38 @@ fn print_time(label: &str, d: Duration) { println!("{label}:{space}{time}"); } -const ITERATIONS: usize = 100_000; -const WARMUP_ITERATIONS: usize = 1_000; +#[allow(unused)] +pub(crate) const ITERATIONS: usize = 100_000; +#[allow(unused)] +pub(crate) const WARMUP_ITERATIONS: usize = 1_000; // A benchmarking macro to avoid copying memory and skewing the results. +#[macro_export] macro_rules! bench { ($label:literal, $variant:literal, $input:expr, $setup:expr, $routine:expr) => {{ - let mut time = Duration::ZERO; + let mut time = std::time::Duration::ZERO; // Warmup - for _ in 0..WARMUP_ITERATIONS { + for _ in 0..bench_utils::WARMUP_ITERATIONS { let input = $setup($input); $routine(input); } // Benchmark - for _ in 0..ITERATIONS { + for _ in 0..bench_utils::ITERATIONS { let input = $setup($input); - let start = Instant::now(); + let start = std::time::Instant::now(); core::hint::black_box($routine(input)); - let end = Instant::now(); + let end = std::time::Instant::now(); time += end.duration_since(start); } - print_time(concat!($label, " ", $variant), time); + bench_utils::print_time(concat!($label, " ", $variant), time); }}; } +#[macro_export] macro_rules! bench_group { ($variant:literal, $mod:ident, $keypair_t:ident, $signature_t:ident) => {{ bench!( @@ -74,7 +72,7 @@ macro_rules! bench_group { $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = random_array(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); key_generation_seed }, |key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE]| { @@ -86,9 +84,9 @@ macro_rules! bench_group { $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = random_array(); - let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = random_array(); - let message = random_array::<1023>(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); + let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = bench_utils::random_array(); + let message = bench_utils::random_array::<1023>(); let keypair = $mod::generate_key_pair(key_generation_seed); (keypair, message, signing_randomness) @@ -105,9 +103,9 @@ macro_rules! bench_group { $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = random_array(); - let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = random_array(); - let message = random_array::<1023>(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); + let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = bench_utils::random_array(); + let message = bench_utils::random_array::<1023>(); let keypair = $mod::generate_key_pair(key_generation_seed); let signature = $mod::sign(&keypair.signing_key, &message, signing_randomness); (keypair, message, signature) @@ -121,8 +119,6 @@ macro_rules! bench_group { }}; } -fn main() { - bench_group!("44", ml_dsa_44, MLDSA44KeyPair, MLDSA44Signature); - bench_group!("65", ml_dsa_65, MLDSA65KeyPair, MLDSA65Signature); - bench_group!("87", ml_dsa_87, MLDSA87KeyPair, MLDSA87Signature); -} + + + diff --git a/libcrux-ml-dsa/benches/manual44.rs b/libcrux-ml-dsa/benches/manual44.rs new file mode 100644 index 000000000..9efe13d9b --- /dev/null +++ b/libcrux-ml-dsa/benches/manual44.rs @@ -0,0 +1,15 @@ + + +use libcrux_ml_dsa::{ + ml_dsa_44::{self, MLDSA44KeyPair, MLDSA44Signature}, + KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, +}; + + +#[path = "./bench_utils.rs"] +#[macro_use] +mod bench_utils; + +fn main() { + bench_group!("44", ml_dsa_44, MLDSA44KeyPair, MLDSA44Signature); +} diff --git a/libcrux-ml-dsa/benches/manual65.rs b/libcrux-ml-dsa/benches/manual65.rs new file mode 100644 index 000000000..437a7b19f --- /dev/null +++ b/libcrux-ml-dsa/benches/manual65.rs @@ -0,0 +1,15 @@ + + +use libcrux_ml_dsa::{ + ml_dsa_65::{self, MLDSA65KeyPair, MLDSA65Signature}, + KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, +}; + + +#[path = "./bench_utils.rs"] +#[macro_use] +mod bench_utils; + +fn main() { + bench_group!("65", ml_dsa_65, MLDSA65KeyPair, MLDSA65Signature); +} diff --git a/libcrux-ml-dsa/benches/manual87.rs b/libcrux-ml-dsa/benches/manual87.rs new file mode 100644 index 000000000..d16bbf008 --- /dev/null +++ b/libcrux-ml-dsa/benches/manual87.rs @@ -0,0 +1,15 @@ + + +use libcrux_ml_dsa::{ + ml_dsa_87::{self, MLDSA87KeyPair, MLDSA87Signature}, + KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, +}; + + +#[path = "./bench_utils.rs"] +#[macro_use] +mod bench_utils; + +fn main() { + bench_group!("87", ml_dsa_87, MLDSA87KeyPair, MLDSA87Signature); +} From e19a7609844a9aae74d3c961e16cfb5a6e9bcd77 Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Wed, 14 Aug 2024 08:44:36 +0200 Subject: [PATCH 2/4] Benchmark pqclean --- libcrux-ml-dsa/benches/bench_utils.rs | 62 ++++++++++++++++++++++----- libcrux-ml-dsa/benches/manual44.rs | 6 +-- libcrux-ml-dsa/benches/manual65.rs | 6 +-- libcrux-ml-dsa/benches/manual87.rs | 6 +-- 4 files changed, 61 insertions(+), 19 deletions(-) diff --git a/libcrux-ml-dsa/benches/bench_utils.rs b/libcrux-ml-dsa/benches/bench_utils.rs index 604bb0364..21d756ee8 100644 --- a/libcrux-ml-dsa/benches/bench_utils.rs +++ b/libcrux-ml-dsa/benches/bench_utils.rs @@ -65,26 +65,29 @@ macro_rules! bench { } #[macro_export] -macro_rules! bench_group { +macro_rules! bench_group_libcrux { ($variant:literal, $mod:ident, $keypair_t:ident, $signature_t:ident) => {{ bench!( - "KeyGen", + "(libcrux) KeyGen", $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = + bench_utils::random_array(); key_generation_seed }, |key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE]| { $mod::generate_key_pair(key_generation_seed) } ); + bench!( - "Sign", + "(libcrux) Sign", $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = + bench_utils::random_array(); let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = bench_utils::random_array(); let message = bench_utils::random_array::<1023>(); let keypair = $mod::generate_key_pair(key_generation_seed); @@ -99,11 +102,12 @@ macro_rules! bench_group { ); bench!( - "Verify", + "(libcrux) Verify", $variant, (), |()| { - let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = bench_utils::random_array(); + let key_generation_seed: [u8; KEY_GENERATION_RANDOMNESS_SIZE] = + bench_utils::random_array(); let signing_randomness: [u8; SIGNING_RANDOMNESS_SIZE] = bench_utils::random_array(); let message = bench_utils::random_array::<1023>(); let keypair = $mod::generate_key_pair(key_generation_seed); @@ -119,6 +123,44 @@ macro_rules! bench_group { }}; } - - - +#[macro_export] +macro_rules! bench_group_pqclean { + ($variant:literal, $mod:ident) => {{ + bench!("(pqclean) KeyGen", $variant, (), |()| {}, |()| { + pqcrypto_dilithium::$mod::keypair() + }); + bench!( + "(pqclean) Sign", + $variant, + (), + |()| { + let (_, sk) = pqcrypto_dilithium::$mod::keypair(); + let message = bench_utils::random_array::<1023>(); + (sk, message) + }, + |(sk, message): (pqcrypto_dilithium::$mod::SecretKey, [u8; 1023])| { + let _ = pqcrypto_dilithium::$mod::detached_sign(&message, &sk); + } + ); + bench!( + "(pqclean) Verify", + $variant, + (), + |()| { + let (vk, sk) = pqcrypto_dilithium::$mod::keypair(); + let message = bench_utils::random_array::<1023>(); + let signature = pqcrypto_dilithium::$mod::detached_sign(&message, &sk); + (vk, message, signature) + }, + |(vk, message, signature): ( + pqcrypto_dilithium::$mod::PublicKey, + [u8; 1023], + pqcrypto_dilithium::$mod::DetachedSignature + )| { + let _ = + pqcrypto_dilithium::$mod::verify_detached_signature(&signature, &message, &vk) + .unwrap(); + } + ); + }}; +} diff --git a/libcrux-ml-dsa/benches/manual44.rs b/libcrux-ml-dsa/benches/manual44.rs index 9efe13d9b..1719c7478 100644 --- a/libcrux-ml-dsa/benches/manual44.rs +++ b/libcrux-ml-dsa/benches/manual44.rs @@ -1,15 +1,15 @@ - - use libcrux_ml_dsa::{ ml_dsa_44::{self, MLDSA44KeyPair, MLDSA44Signature}, KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, }; +use pqcrypto_dilithium; #[path = "./bench_utils.rs"] #[macro_use] mod bench_utils; fn main() { - bench_group!("44", ml_dsa_44, MLDSA44KeyPair, MLDSA44Signature); + bench_group_libcrux!("44", ml_dsa_44, MLDSA44KeyPair, MLDSA44Signature); + bench_group_pqclean!("44", dilithium2); } diff --git a/libcrux-ml-dsa/benches/manual65.rs b/libcrux-ml-dsa/benches/manual65.rs index 437a7b19f..d65168b3a 100644 --- a/libcrux-ml-dsa/benches/manual65.rs +++ b/libcrux-ml-dsa/benches/manual65.rs @@ -1,15 +1,15 @@ - - use libcrux_ml_dsa::{ ml_dsa_65::{self, MLDSA65KeyPair, MLDSA65Signature}, KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, }; +use pqcrypto_dilithium; #[path = "./bench_utils.rs"] #[macro_use] mod bench_utils; fn main() { - bench_group!("65", ml_dsa_65, MLDSA65KeyPair, MLDSA65Signature); + bench_group_libcrux!("65", ml_dsa_65, MLDSA65KeyPair, MLDSA65Signature); + bench_group_pqclean!("65", dilithium3); } diff --git a/libcrux-ml-dsa/benches/manual87.rs b/libcrux-ml-dsa/benches/manual87.rs index d16bbf008..76a4989f6 100644 --- a/libcrux-ml-dsa/benches/manual87.rs +++ b/libcrux-ml-dsa/benches/manual87.rs @@ -1,15 +1,15 @@ - - use libcrux_ml_dsa::{ ml_dsa_87::{self, MLDSA87KeyPair, MLDSA87Signature}, KEY_GENERATION_RANDOMNESS_SIZE, SIGNING_RANDOMNESS_SIZE, }; +use pqcrypto_dilithium; #[path = "./bench_utils.rs"] #[macro_use] mod bench_utils; fn main() { - bench_group!("87", ml_dsa_87, MLDSA87KeyPair, MLDSA87Signature); + bench_group_libcrux!("87", ml_dsa_87, MLDSA87KeyPair, MLDSA87Signature); + bench_group_pqclean!("87", dilithium5); } From 7af24bf2d8b83b90b6f4805047c24fe39b5709bd Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Wed, 14 Aug 2024 09:08:32 +0200 Subject: [PATCH 3/4] More meaningful constants --- libcrux-ml-dsa/benches/bench_utils.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libcrux-ml-dsa/benches/bench_utils.rs b/libcrux-ml-dsa/benches/bench_utils.rs index 21d756ee8..cc1b663eb 100644 --- a/libcrux-ml-dsa/benches/bench_utils.rs +++ b/libcrux-ml-dsa/benches/bench_utils.rs @@ -11,17 +11,17 @@ pub(crate) fn random_array() -> [u8; L] { #[allow(unused)] pub(crate) fn print_time(label: &str, d: std::time::Duration) { let micros = d.as_micros(); - let time = if micros < (1_000 * ITERATIONS as u128) { + let time = if micros < MILLI_PER_ITERATION_THRESHOLD { format!("{} μs", micros / ITERATIONS as u128) - } else if micros < (1_000_000 * ITERATIONS as u128) { + } else if micros < SECOND_PER_ITERATION_THRESHOLD { format!( "{:.2} ms", - (micros as f64 / (1_000_f64 * ITERATIONS as f64)) + (micros as f64 / (MICROS_PER_MILLI * ITERATIONS as f64)) ) } else { format!( "{:.2}s", - (micros as f64 / (1_000_000_f64 * ITERATIONS as f64)) + (micros as f64 / (MICROS_PER_SECOND * ITERATIONS as f64)) ) }; let space = if label.len() < 6 { @@ -33,11 +33,15 @@ pub(crate) fn print_time(label: &str, d: std::time::Duration) { println!("{label}:{space}{time}"); } -#[allow(unused)] pub(crate) const ITERATIONS: usize = 100_000; #[allow(unused)] pub(crate) const WARMUP_ITERATIONS: usize = 1_000; +pub(crate) const MICROS_PER_MILLI: f64 = 1_000.0; +pub(crate) const MICROS_PER_SECOND: f64 = 1_000_000.0; +pub(crate) const MILLI_PER_ITERATION_THRESHOLD: u128 = 1_000 * ITERATIONS as u128; +pub(crate) const SECOND_PER_ITERATION_THRESHOLD: u128 = 1_000_000 * ITERATIONS as u128; + // A benchmarking macro to avoid copying memory and skewing the results. #[macro_export] macro_rules! bench { From af83d1d71082ffb8930e89eeba18666f76fcf95f Mon Sep 17 00:00:00 2001 From: Jonas Schneider-Bensch Date: Wed, 14 Aug 2024 11:24:15 +0200 Subject: [PATCH 4/4] Remove unnecessary attributes --- libcrux-ml-dsa/benches/manual44.rs | 2 -- libcrux-ml-dsa/benches/manual65.rs | 2 -- libcrux-ml-dsa/benches/manual87.rs | 2 -- 3 files changed, 6 deletions(-) diff --git a/libcrux-ml-dsa/benches/manual44.rs b/libcrux-ml-dsa/benches/manual44.rs index 1719c7478..050296e14 100644 --- a/libcrux-ml-dsa/benches/manual44.rs +++ b/libcrux-ml-dsa/benches/manual44.rs @@ -5,8 +5,6 @@ use libcrux_ml_dsa::{ use pqcrypto_dilithium; -#[path = "./bench_utils.rs"] -#[macro_use] mod bench_utils; fn main() { diff --git a/libcrux-ml-dsa/benches/manual65.rs b/libcrux-ml-dsa/benches/manual65.rs index d65168b3a..18c6598dc 100644 --- a/libcrux-ml-dsa/benches/manual65.rs +++ b/libcrux-ml-dsa/benches/manual65.rs @@ -5,8 +5,6 @@ use libcrux_ml_dsa::{ use pqcrypto_dilithium; -#[path = "./bench_utils.rs"] -#[macro_use] mod bench_utils; fn main() { diff --git a/libcrux-ml-dsa/benches/manual87.rs b/libcrux-ml-dsa/benches/manual87.rs index 76a4989f6..4daf07f24 100644 --- a/libcrux-ml-dsa/benches/manual87.rs +++ b/libcrux-ml-dsa/benches/manual87.rs @@ -5,8 +5,6 @@ use libcrux_ml_dsa::{ use pqcrypto_dilithium; -#[path = "./bench_utils.rs"] -#[macro_use] mod bench_utils; fn main() {