Skip to main content

bench/
bench.rs

1// SPDX-License-Identifier: MIT
2//
3// Rivide Post-Quantum Cryptography Library
4// Copyright (C) 2026 Moh. Ananda Firmansyah Putra
5//
6// Permission is hereby granted, free of charge, to any person obtaining a copy
7// of this software and associated documentation files (the "Software"), to deal
8// in the Software without restriction, including without limitation the rights
9// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10// copies of the Software, and to permit persons to whom the Software is
11// furnished to do so, subject to the following conditions:
12//
13// The above copyright notice and this permission notice shall be included in all
14// copies or substantial portions of the Software.
15
16//! Rust performance benchmark example executable.
17
18use rivide::crypto::{AesGcm, Sha3};
19use rivide::dsa::{MlDsa65, MlDsa87};
20use rivide::kem::{MlKem1024, MlKem768};
21use rivide::utils::{get_cpu_features, version};
22use std::time::Instant;
23
24fn benchmark<F: FnMut()>(name: &str, mut f: F, iterations: usize) {
25    for _ in 0..50 {
26        f();
27    }
28
29    let start = Instant::now();
30    for _ in 0..iterations {
31        f();
32    }
33    let duration = start.elapsed();
34    let duration_sec = duration.as_secs_f64();
35    let ops_per_sec = iterations as f64 / duration_sec;
36    let us_per_op = (duration_sec / iterations as f64) * 1_000_000.0;
37
38    println!(
39        "  {:<28} : {:>9.2} ops/sec ({:>7.2} us/op)",
40        name, ops_per_sec, us_per_op
41    );
42}
43
44fn main() {
45    println!(
46        "Rivide Rust Post-Quantum Cryptography Benchmark Suite v{}\n",
47        version()
48    );
49    let cpu = get_cpu_features();
50    println!(
51        "Hardware Acceleration : AVX2: {}, AES-NI: {}, NEON: {}, ARM-CE: {}\n",
52        if cpu.has_avx2 { "YES" } else { "NO" },
53        if cpu.has_aesni { "YES" } else { "NO" },
54        if cpu.has_neon { "YES" } else { "NO" },
55        if cpu.has_arm_ce { "YES" } else { "NO" },
56    );
57
58    let iters = 1000;
59
60    println!("NIST FIPS 203 ML-KEM Benchmarks:");
61    let kem768_kp = MlKem768::keypair().unwrap();
62    let kem768_enc = MlKem768::encapsulate(&kem768_kp.public_key).unwrap();
63    benchmark(
64        "ML-KEM-768 KeyGen",
65        || {
66            let _ = MlKem768::keypair();
67        },
68        iters,
69    );
70    benchmark(
71        "ML-KEM-768 Encaps",
72        || {
73            let _ = MlKem768::encapsulate(&kem768_kp.public_key);
74        },
75        iters,
76    );
77    benchmark(
78        "ML-KEM-768 Decaps",
79        || {
80            let _ = MlKem768::decapsulate(&kem768_enc.ciphertext, &kem768_kp.secret_key);
81        },
82        iters,
83    );
84
85    println!();
86    let kem1024_kp = MlKem1024::keypair().unwrap();
87    let kem1024_enc = MlKem1024::encapsulate(&kem1024_kp.public_key).unwrap();
88    benchmark(
89        "ML-KEM-1024 KeyGen",
90        || {
91            let _ = MlKem1024::keypair();
92        },
93        iters,
94    );
95    benchmark(
96        "ML-KEM-1024 Encaps",
97        || {
98            let _ = MlKem1024::encapsulate(&kem1024_kp.public_key);
99        },
100        iters,
101    );
102    benchmark(
103        "ML-KEM-1024 Decaps",
104        || {
105            let _ = MlKem1024::decapsulate(&kem1024_enc.ciphertext, &kem1024_kp.secret_key);
106        },
107        iters,
108    );
109
110    println!("\nNIST FIPS 204 ML-DSA Benchmarks:");
111    let dsa65_kp = MlDsa65::keypair().unwrap();
112    let sample_msg = b"Quantum-safe payload for Rust digital signature benchmarking.";
113    let dsa65_sig = MlDsa65::sign(sample_msg, &dsa65_kp.secret_key).unwrap();
114    benchmark(
115        "ML-DSA-65 KeyGen",
116        || {
117            let _ = MlDsa65::keypair();
118        },
119        iters,
120    );
121    benchmark(
122        "ML-DSA-65 Sign",
123        || {
124            let _ = MlDsa65::sign(sample_msg, &dsa65_kp.secret_key);
125        },
126        iters,
127    );
128    benchmark(
129        "ML-DSA-65 Verify",
130        || {
131            let _ = MlDsa65::verify(&dsa65_sig, sample_msg, &dsa65_kp.public_key);
132        },
133        iters,
134    );
135
136    println!();
137    let dsa87_kp = MlDsa87::keypair().unwrap();
138    let dsa87_sig = MlDsa87::sign(sample_msg, &dsa87_kp.secret_key).unwrap();
139    benchmark(
140        "ML-DSA-87 KeyGen",
141        || {
142            let _ = MlDsa87::keypair();
143        },
144        iters,
145    );
146    benchmark(
147        "ML-DSA-87 Sign",
148        || {
149            let _ = MlDsa87::sign(sample_msg, &dsa87_kp.secret_key);
150        },
151        iters,
152    );
153    benchmark(
154        "ML-DSA-87 Verify",
155        || {
156            let _ = MlDsa87::verify(&dsa87_sig, sample_msg, &dsa87_kp.public_key);
157        },
158        iters,
159    );
160
161    println!("\nSymmetric Primitives Benchmarks:");
162    let payload_4kb = vec![0x42u8; 4096];
163    let key32 = [0x01u8; 32];
164    let iv12 = [0x02u8; 12];
165    let enc_res = AesGcm::encrypt_256(&key32, &iv12, &payload_4kb, None).unwrap();
166
167    benchmark(
168        "SHA3-256 (4 KB)",
169        || {
170            let _ = Sha3::sha3_256(&payload_4kb);
171        },
172        iters,
173    );
174    benchmark(
175        "SHAKE-256 (4 KB -> 32B)",
176        || {
177            let _ = Sha3::shake256(&payload_4kb, 32);
178        },
179        iters,
180    );
181    benchmark(
182        "AES-256-GCM Encrypt (4 KB)",
183        || {
184            let _ = AesGcm::encrypt_256(&key32, &iv12, &payload_4kb, None);
185        },
186        iters,
187    );
188    benchmark(
189        "AES-256-GCM Decrypt (4 KB)",
190        || {
191            let _ = AesGcm::decrypt_256(&key32, &iv12, &enc_res.ciphertext, &enc_res.tag, None);
192        },
193        iters,
194    );
195
196    println!("\n[SUCCESS] Rust Benchmark Suite Execution Complete.");
197}