use std::hint::black_box;
use std::sync::OnceLock;
use std::time::Instant;
use cryptography::public_key::ec_edwards::ed25519 as ed25519_curve;
use cryptography::vt::{
p256, BigUint, Cocks, Dsa, EcElGamal, Ecdh, Ecdsa, Ecies, Ed25519, EdwardsDh, EdwardsElGamal,
ElGamal, MlDsa, MlDsaParameterSet, MlKem, MlKemParameterSet, NtruEes1087Ep2, NtruEes401Ep1,
NtruEes1087Ep1, NtruEes1171Ep1, NtruEes1499Ep1, NtruEes443Ep1, NtruEes449Ep1, NtruEes541Ep1,
NtruEes677Ep1,
NtruHps509, NtruHps677, NtruHps821, NtruHrss701, Paillier, Rabin, Rsa, RsaOaep, RsaPss,
SchmidtSamoa, X25519, X448,
};
use cryptography::{Csprng, CtrDrbgAes256, Sha256};
const MSG: [u8; 32] = [0x42; 32];
const EC_MSG: [u8; 16] = [0x24; 16];
const OAEP_LABEL: &[u8] = b"pilot-pk-oaep";
const OAEP_SEED: [u8; 32] = [0x11; 32];
const PSS_SALT: [u8; 32] = [0x22; 32];
fn ms_per_op(elapsed: std::time::Duration, n: usize) -> f64 {
elapsed.as_secs_f64() * 1000.0 / n as f64
}
fn pk_iters(base: usize) -> usize {
static SCALE_PERCENT: OnceLock<usize> = OnceLock::new();
let scale = *SCALE_PERCENT.get_or_init(|| {
std::env::var("PILOT_PK_ITERS_PERCENT")
.ok()
.and_then(|s| s.parse::<usize>().ok())
.map(|v| v.clamp(1, 100))
.unwrap_or(25)
});
base.saturating_mul(scale).div_ceil(100).max(1)
}
fn main() {
let op = std::env::args().nth(1).unwrap_or_else(|| {
eprintln!("usage: pilot_pk <operation>");
std::process::exit(1);
});
let mut rng = CtrDrbgAes256::new(&[0x5a; 48]);
let ms: f64 = match op.to_ascii_lowercase().as_str() {
"ecdsa_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(Ecdsa::generate(p256(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ecdsa_sign" => {
let (_, priv_key) = Ecdsa::generate(p256(), &mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.sign_message_bytes::<Sha256>(&MSG).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ecdsa_verify" => {
let (pub_key, priv_key) = Ecdsa::generate(p256(), &mut rng);
let sig = priv_key.sign_message_bytes::<Sha256>(&MSG).unwrap();
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.verify_message_bytes::<Sha256>(&MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"ecdh_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(Ecdh::generate(p256(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ecdh_agree" => {
let (pub_a, _) = Ecdh::generate(p256(), &mut rng);
let (_, priv_b) = Ecdh::generate(p256(), &mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_b.agree_x_coordinate(&pub_a).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ecdh_serialize" => {
let (pub_key, _) = Ecdh::generate(p256(), &mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.to_wire_bytes());
}
ms_per_op(t0.elapsed(), n)
}
"ecies_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(Ecies::generate(p256(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ecies_encrypt" => {
let (pub_key, _) = Ecies::generate(p256(), &mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ecies_decrypt" => {
let (pub_key, priv_key) = Ecies::generate(p256(), &mut rng);
let ct = pub_key.encrypt(&MSG, &mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ec_elgamal_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(EcElGamal::generate(p256(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ec_elgamal_encrypt" => {
let (pub_key, _) = EcElGamal::generate(p256(), &mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&EC_MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ec_elgamal_decrypt" => {
let (pub_key, priv_key) = EcElGamal::generate(p256(), &mut rng);
let ct = pub_key.encrypt(&EC_MSG, &mut rng).unwrap();
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct));
}
ms_per_op(t0.elapsed(), n)
}
"ed25519_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(Ed25519::generate(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ed25519_sign" => {
let (_, priv_key) = Ed25519::generate(&mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.sign_message_bytes(&MSG));
}
ms_per_op(t0.elapsed(), n)
}
"ed25519_verify" => {
let (pub_key, priv_key) = Ed25519::generate(&mut rng);
let sig = priv_key.sign_message_bytes(&MSG);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.verify_message_bytes(&MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"edwards_dh_agree" => {
let (pub_a, _) = EdwardsDh::generate(ed25519_curve(), &mut rng);
let (_, priv_b) = EdwardsDh::generate(ed25519_curve(), &mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_b.agree_compressed_point(&pub_a).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"edwards_dh_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(EdwardsDh::generate(ed25519_curve(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"edwards_dh_serialize" => {
let (pub_key, _) = EdwardsDh::generate(ed25519_curve(), &mut rng);
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.to_wire_bytes());
}
ms_per_op(t0.elapsed(), n)
}
"edwards_elgamal_keygen" => {
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(EdwardsElGamal::generate(ed25519_curve(), &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"edwards_elgamal_encrypt" => {
let (pub_key, _) = EdwardsElGamal::generate(ed25519_curve(), &mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt_int(7, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"edwards_elgamal_decrypt" => {
let (pub_key, priv_key) = EdwardsElGamal::generate(ed25519_curve(), &mut rng);
let ct = pub_key.encrypt_int(7, &mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt_int(&ct, 32).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"dsa_keygen_1024" => {
let n = pk_iters(10);
let t0 = Instant::now();
for _ in 0..n {
black_box(Dsa::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"dsa_sign_1024" => {
let (_, priv_key) = Dsa::generate(&mut rng, 1024).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.sign_message_bytes::<Sha256>(&MSG).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"dsa_verify_1024" => {
let (pub_key, priv_key) = Dsa::generate(&mut rng, 1024).unwrap();
let sig = priv_key.sign_message_bytes::<Sha256>(&MSG).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.verify_message_bytes::<Sha256>(&MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"elgamal_keygen_1024" => {
let n = pk_iters(5);
let t0 = Instant::now();
for _ in 0..n {
black_box(ElGamal::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"elgamal_encrypt_1024" => {
let (pub_key, _) = ElGamal::generate(&mut rng, 1024).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"elgamal_decrypt_1024" => {
let (pub_key, priv_key) = ElGamal::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG, &mut rng).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct));
}
ms_per_op(t0.elapsed(), n)
}
"paillier_keygen_1024" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(Paillier::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"paillier_encrypt_1024" => {
let (pub_key, _) = Paillier::generate(&mut rng, 1024).unwrap();
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"paillier_decrypt_1024" => {
let (pub_key, priv_key) = Paillier::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG, &mut rng).unwrap();
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct));
}
ms_per_op(t0.elapsed(), n)
}
"paillier_rerandomize_1024" => {
let (pub_key, _) = Paillier::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG, &mut rng).unwrap();
let n = pk_iters(50);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.rerandomize(&ct, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"paillier_add_1024" => {
let (pub_key, priv_key) = Paillier::generate(&mut rng, 1024).unwrap();
let ct_a = pub_key.encrypt(&MSG, &mut rng).unwrap();
let ct_b = pub_key.encrypt(&[0x01], &mut rng).unwrap();
let n = pk_iters(2000);
let mut combined = pub_key.add_ciphertexts(&ct_a, &ct_b).unwrap();
let t0 = Instant::now();
for _ in 0..n {
combined = black_box(pub_key.add_ciphertexts(&ct_a, &ct_b).unwrap());
}
let combined_plaintext = priv_key.decrypt(&combined);
let expected = BigUint::from_be_bytes(&MSG).add_ref(&BigUint::from_u64(1));
assert_eq!(combined_plaintext, expected.to_be_bytes());
ms_per_op(t0.elapsed(), n)
}
"cocks_keygen_1024" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(Cocks::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"cocks_encrypt_1024" => {
let (pub_key, _) = Cocks::generate(&mut rng, 1024).unwrap();
let n = pk_iters(300);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"cocks_decrypt_1024" => {
let (pub_key, priv_key) = Cocks::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG).unwrap();
let n = pk_iters(1500);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct));
}
ms_per_op(t0.elapsed(), n)
}
"rabin_keygen_1024" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(Rabin::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rabin_encrypt_1024" => {
let (pub_key, _) = Rabin::generate(&mut rng, 1024).unwrap();
let n = pk_iters(5000);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rabin_decrypt_1024" => {
let (pub_key, priv_key) = Rabin::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG).unwrap();
let n = pk_iters(200);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"schmidt_samoa_keygen_1024" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(SchmidtSamoa::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"schmidt_samoa_encrypt_1024" => {
let (pub_key, _) = SchmidtSamoa::generate(&mut rng, 1024).unwrap();
let n = pk_iters(300);
let t0 = Instant::now();
for _ in 0..n {
black_box(pub_key.encrypt(&MSG).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"schmidt_samoa_decrypt_1024" => {
let (pub_key, priv_key) = SchmidtSamoa::generate(&mut rng, 1024).unwrap();
let ct = pub_key.encrypt(&MSG).unwrap();
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_key.decrypt(&ct));
}
ms_per_op(t0.elapsed(), n)
}
"rsa_keygen_1024" => {
let n = pk_iters(10);
let t0 = Instant::now();
for _ in 0..n {
black_box(Rsa::generate(&mut rng, 1024).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_encrypt_1024" => {
let (pub_key, _) = Rsa::generate(&mut rng, 1024).unwrap();
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(
RsaOaep::<Sha256>::encrypt(&pub_key, OAEP_LABEL, &MSG, &OAEP_SEED).unwrap(),
);
}
ms_per_op(t0.elapsed(), n)
}
"rsa_decrypt_1024" => {
let (pub_key, priv_key) = Rsa::generate(&mut rng, 1024).unwrap();
let ct = RsaOaep::<Sha256>::encrypt(&pub_key, OAEP_LABEL, &MSG, &OAEP_SEED).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaOaep::<Sha256>::decrypt(&priv_key, OAEP_LABEL, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_sign_1024" => {
let (_, priv_key) = Rsa::generate(&mut rng, 1024).unwrap();
let n = pk_iters(100);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaPss::<Sha256>::sign(&priv_key, &MSG, &PSS_SALT).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_verify_1024" => {
let (pub_key, priv_key) = Rsa::generate(&mut rng, 1024).unwrap();
let sig = RsaPss::<Sha256>::sign(&priv_key, &MSG, &PSS_SALT).unwrap();
let n = pk_iters(1000);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaPss::<Sha256>::verify(&pub_key, &MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"rsa_keygen_2048" => {
let n = pk_iters(3);
let t0 = Instant::now();
for _ in 0..n {
black_box(Rsa::generate(&mut rng, 2048).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_encrypt_2048" => {
let (pub_key, _) = Rsa::generate(&mut rng, 2048).unwrap();
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(
RsaOaep::<Sha256>::encrypt(&pub_key, OAEP_LABEL, &MSG, &OAEP_SEED).unwrap(),
);
}
ms_per_op(t0.elapsed(), n)
}
"rsa_decrypt_2048" => {
let (pub_key, priv_key) = Rsa::generate(&mut rng, 2048).unwrap();
let ct = RsaOaep::<Sha256>::encrypt(&pub_key, OAEP_LABEL, &MSG, &OAEP_SEED).unwrap();
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaOaep::<Sha256>::decrypt(&priv_key, OAEP_LABEL, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_sign_2048" => {
let (_, priv_key) = Rsa::generate(&mut rng, 2048).unwrap();
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaPss::<Sha256>::sign(&priv_key, &MSG, &PSS_SALT).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"rsa_verify_2048" => {
let (pub_key, priv_key) = Rsa::generate(&mut rng, 2048).unwrap();
let sig = RsaPss::<Sha256>::sign(&priv_key, &MSG, &PSS_SALT).unwrap();
let n = pk_iters(200);
let t0 = Instant::now();
for _ in 0..n {
black_box(RsaPss::<Sha256>::verify(&pub_key, &MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"mlkem512_keygen" => {
let n = pk_iters(200);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::keygen(MlKemParameterSet::MlKem512, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem512_encaps" => {
let (pk, _) = MlKem::keygen(MlKemParameterSet::MlKem512, &mut rng).unwrap();
let n = pk_iters(200);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::encaps(&pk, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem512_decaps" => {
let (pk, sk) = MlKem::keygen(MlKemParameterSet::MlKem512, &mut rng).unwrap();
let (ct, _) = MlKem::encaps(&pk, &mut rng).unwrap();
let n = pk_iters(200);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::decaps(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem768_keygen" => {
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::keygen(MlKemParameterSet::MlKem768, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem768_encaps" => {
let (pk, _) = MlKem::keygen(MlKemParameterSet::MlKem768, &mut rng).unwrap();
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::encaps(&pk, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem768_decaps" => {
let (pk, sk) = MlKem::keygen(MlKemParameterSet::MlKem768, &mut rng).unwrap();
let (ct, _) = MlKem::encaps(&pk, &mut rng).unwrap();
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::decaps(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem1024_keygen" => {
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::keygen(MlKemParameterSet::MlKem1024, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem1024_encaps" => {
let (pk, _) = MlKem::keygen(MlKemParameterSet::MlKem1024, &mut rng).unwrap();
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::encaps(&pk, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mlkem1024_decaps" => {
let (pk, sk) = MlKem::keygen(MlKemParameterSet::MlKem1024, &mut rng).unwrap();
let (ct, _) = MlKem::encaps(&pk, &mut rng).unwrap();
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlKem::decaps(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa44_keygen" => {
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::keygen(MlDsaParameterSet::MlDsa44, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa44_sign" => {
let (_, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa44, &mut rng).unwrap();
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::sign(&sk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa44_verify" => {
let (pk, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa44, &mut rng).unwrap();
let sig = MlDsa::sign(&sk, &MSG, &mut rng).unwrap();
let n = pk_iters(120);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::verify(&pk, &MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"mldsa65_keygen" => {
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::keygen(MlDsaParameterSet::MlDsa65, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa65_sign" => {
let (_, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa65, &mut rng).unwrap();
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::sign(&sk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa65_verify" => {
let (pk, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa65, &mut rng).unwrap();
let sig = MlDsa::sign(&sk, &MSG, &mut rng).unwrap();
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::verify(&pk, &MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"mldsa87_keygen" => {
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::keygen(MlDsaParameterSet::MlDsa87, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa87_sign" => {
let (_, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa87, &mut rng).unwrap();
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::sign(&sk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"mldsa87_verify" => {
let (pk, sk) = MlDsa::keygen(MlDsaParameterSet::MlDsa87, &mut rng).unwrap();
let sig = MlDsa::sign(&sk, &MSG, &mut rng).unwrap();
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(MlDsa::verify(&pk, &MSG, &sig));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps509_keygen" => {
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps509::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps509_encaps" => {
let (pk, _) = NtruHps509::keygen(&mut rng);
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps509::encaps(&pk, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps509_decaps" => {
let (pk, sk) = NtruHps509::keygen(&mut rng);
let (ct, _) = NtruHps509::encaps(&pk, &mut rng);
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps509::decaps(&sk, &ct));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps677_keygen" => {
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps677::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps677_encaps" => {
let (pk, _) = NtruHps677::keygen(&mut rng);
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps677::encaps(&pk, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps677_decaps" => {
let (pk, sk) = NtruHps677::keygen(&mut rng);
let (ct, _) = NtruHps677::encaps(&pk, &mut rng);
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps677::decaps(&sk, &ct));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps821_keygen" => {
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps821::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps821_encaps" => {
let (pk, _) = NtruHps821::keygen(&mut rng);
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps821::encaps(&pk, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhps821_decaps" => {
let (pk, sk) = NtruHps821::keygen(&mut rng);
let (ct, _) = NtruHps821::encaps(&pk, &mut rng);
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHps821::decaps(&sk, &ct));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhrss701_keygen" => {
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHrss701::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhrss701_encaps" => {
let (pk, _) = NtruHrss701::keygen(&mut rng);
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHrss701::encaps(&pk, &mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruhrss701_decaps" => {
let (pk, sk) = NtruHrss701::keygen(&mut rng);
let (ct, _) = NtruHrss701::encaps(&pk, &mut rng);
let n = pk_iters(60);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruHrss701::decaps(&sk, &ct));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees401ep1_keygen" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes401Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees401ep1_encrypt" => {
let (pk, _) = NtruEes401Ep1::keygen(&mut rng);
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes401Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees401ep1_decrypt" => {
let (pk, sk) = NtruEes401Ep1::keygen(&mut rng);
let ct = NtruEes401Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes401Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees443ep1_keygen" => {
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes443Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees443ep1_encrypt" => {
let (pk, _) = NtruEes443Ep1::keygen(&mut rng);
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes443Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees443ep1_decrypt" => {
let (pk, sk) = NtruEes443Ep1::keygen(&mut rng);
let ct = NtruEes443Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(80);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes443Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees449ep1_keygen" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes449Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees449ep1_encrypt" => {
let (pk, _) = NtruEes449Ep1::keygen(&mut rng);
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes449Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees449ep1_decrypt" => {
let (pk, sk) = NtruEes449Ep1::keygen(&mut rng);
let ct = NtruEes449Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes449Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees541ep1_keygen" => {
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes541Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees541ep1_encrypt" => {
let (pk, _) = NtruEes541Ep1::keygen(&mut rng);
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes541Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees541ep1_decrypt" => {
let (pk, sk) = NtruEes541Ep1::keygen(&mut rng);
let ct = NtruEes541Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(40);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes541Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees677ep1_keygen" => {
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes677Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees677ep1_encrypt" => {
let (pk, _) = NtruEes677Ep1::keygen(&mut rng);
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes677Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees677ep1_decrypt" => {
let (pk, sk) = NtruEes677Ep1::keygen(&mut rng);
let ct = NtruEes677Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes677Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep1_keygen" => {
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep1_encrypt" => {
let (pk, _) = NtruEes1087Ep1::keygen(&mut rng);
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep1_decrypt" => {
let (pk, sk) = NtruEes1087Ep1::keygen(&mut rng);
let ct = NtruEes1087Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(30);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep2_keygen" => {
let n = pk_iters(10);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep2::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep2_encrypt" => {
let (pk, _) = NtruEes1087Ep2::keygen(&mut rng);
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep2::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1087ep2_decrypt" => {
let (pk, sk) = NtruEes1087Ep2::keygen(&mut rng);
let ct = NtruEes1087Ep2::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(20);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1087Ep2::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1171ep1_keygen" => {
let n = pk_iters(8);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1171Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1171ep1_encrypt" => {
let (pk, _) = NtruEes1171Ep1::keygen(&mut rng);
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1171Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1171ep1_decrypt" => {
let (pk, sk) = NtruEes1171Ep1::keygen(&mut rng);
let ct = NtruEes1171Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1171Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1499ep1_keygen" => {
let n = pk_iters(8);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1499Ep1::keygen(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1499ep1_encrypt" => {
let (pk, _) = NtruEes1499Ep1::keygen(&mut rng);
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1499Ep1::encrypt(&pk, &MSG, &mut rng).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"ntruees1499ep1_decrypt" => {
let (pk, sk) = NtruEes1499Ep1::keygen(&mut rng);
let ct = NtruEes1499Ep1::encrypt(&pk, &MSG, &mut rng).unwrap();
let n = pk_iters(15);
let t0 = Instant::now();
for _ in 0..n {
black_box(NtruEes1499Ep1::decrypt(&sk, &ct).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"x25519_keygen" => {
let n = pk_iters(2000);
let t0 = Instant::now();
for _ in 0..n {
black_box(X25519::generate(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"x25519_agree" => {
let (pub_a, _) = X25519::generate(&mut rng);
let (_, priv_b) = X25519::generate(&mut rng);
let n = pk_iters(2000);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_b.agree(&pub_a).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"x25519_scalar_mult_base" => {
let mut secret = [0u8; 32];
rng.fill_bytes(&mut secret);
let n = pk_iters(2000);
let t0 = Instant::now();
for _ in 0..n {
black_box(X25519::scalar_mult_base(&secret));
}
ms_per_op(t0.elapsed(), n)
}
"x25519_scalar_mult" => {
let mut secret = [0u8; 32];
rng.fill_bytes(&mut secret);
let mut u = [0u8; 32];
u[0] = 9;
let n = pk_iters(2000);
let t0 = Instant::now();
for _ in 0..n {
black_box(X25519::scalar_mult(&secret, &u));
}
ms_per_op(t0.elapsed(), n)
}
"x448_keygen" => {
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(X448::generate(&mut rng));
}
ms_per_op(t0.elapsed(), n)
}
"x448_agree" => {
let (pub_a, _) = X448::generate(&mut rng);
let (_, priv_b) = X448::generate(&mut rng);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(priv_b.agree(&pub_a).unwrap());
}
ms_per_op(t0.elapsed(), n)
}
"x448_scalar_mult_base" => {
let mut secret = [0u8; 56];
rng.fill_bytes(&mut secret);
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(X448::scalar_mult_base(&secret));
}
ms_per_op(t0.elapsed(), n)
}
"x448_scalar_mult" => {
let mut secret = [0u8; 56];
rng.fill_bytes(&mut secret);
let mut u = [0u8; 56];
u[0] = 5;
let n = pk_iters(500);
let t0 = Instant::now();
for _ in 0..n {
black_box(X448::scalar_mult(&secret, &u));
}
ms_per_op(t0.elapsed(), n)
}
_ => {
eprintln!("unknown operation: {}", op);
std::process::exit(1);
}
};
println!("{:.6}", ms);
}