mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-05-22 17:49:41 +00:00
91 lines
3.3 KiB
Rust
91 lines
3.3 KiB
Rust
|
|
//! Criterion microbenchmarks for client/wallet cryptographic primitives.
|
||
|
|
//!
|
||
|
|
//! Measures:
|
||
|
|
//! - `KeyChain::new_os_random` (mnemonic → SSK → NSK/VSK + public keys)
|
||
|
|
//! - `KeyChain::new_mnemonic` (same, but mnemonic exposed)
|
||
|
|
//! - `SharedSecretKey::new` (Diffie-Hellman shared key derivation, the per-recipient cost)
|
||
|
|
//! - `EncryptionScheme::encrypt` / `decrypt` (Account note encryption)
|
||
|
|
|
||
|
|
use std::time::Duration;
|
||
|
|
|
||
|
|
use criterion::{Criterion, criterion_group, criterion_main};
|
||
|
|
use key_protocol::key_management::KeyChain;
|
||
|
|
use nssa_core::{
|
||
|
|
Commitment, EncryptionScheme, SharedSecretKey,
|
||
|
|
account::{Account, AccountId},
|
||
|
|
encryption::{EphemeralPublicKey, EphemeralSecretKey},
|
||
|
|
program::PrivateAccountKind,
|
||
|
|
};
|
||
|
|
use rand::{RngCore as _, rngs::OsRng};
|
||
|
|
|
||
|
|
fn bench_keychain(c: &mut Criterion) {
|
||
|
|
let mut g = c.benchmark_group("keychain");
|
||
|
|
g.sample_size(50).noise_threshold(0.05);
|
||
|
|
g.bench_function("new_os_random", |b| b.iter(KeyChain::new_os_random));
|
||
|
|
g.bench_function("new_mnemonic", |b| {
|
||
|
|
b.iter(|| {
|
||
|
|
let (_kc, _mnemonic) = KeyChain::new_mnemonic("");
|
||
|
|
});
|
||
|
|
});
|
||
|
|
g.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
fn bench_shared_secret_key(c: &mut Criterion) {
|
||
|
|
// One-time setup: recipient's viewing public key (sender side bench).
|
||
|
|
let recipient_kc = KeyChain::new_os_random();
|
||
|
|
let vpk = recipient_kc.viewing_public_key;
|
||
|
|
|
||
|
|
let mut g = c.benchmark_group("shared_secret_key");
|
||
|
|
g.sample_size(50).noise_threshold(0.05);
|
||
|
|
g.bench_function("sender_dh", |b| {
|
||
|
|
b.iter(|| {
|
||
|
|
let mut bytes = [0_u8; 32];
|
||
|
|
OsRng.fill_bytes(&mut bytes);
|
||
|
|
let esk: EphemeralSecretKey = bytes;
|
||
|
|
let _epk = EphemeralPublicKey::from(&esk);
|
||
|
|
SharedSecretKey::new(esk, &vpk)
|
||
|
|
});
|
||
|
|
});
|
||
|
|
g.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
fn bench_encryption(c: &mut Criterion) {
|
||
|
|
// One-time setup: a fixed Account/Commitment and a SharedSecretKey to bench
|
||
|
|
// encrypt/decrypt over a representative note. ESK gen is excluded from the
|
||
|
|
// measured loop (covered by the SharedSecretKey bench above).
|
||
|
|
let recipient_kc = KeyChain::new_os_random();
|
||
|
|
let vpk = recipient_kc.viewing_public_key;
|
||
|
|
let account = Account::default();
|
||
|
|
let account_id = AccountId::new([7; 32]);
|
||
|
|
let commitment = Commitment::new(&account_id, &account);
|
||
|
|
let shared = {
|
||
|
|
let mut bytes = [0_u8; 32];
|
||
|
|
OsRng.fill_bytes(&mut bytes);
|
||
|
|
let esk: EphemeralSecretKey = bytes;
|
||
|
|
SharedSecretKey::new(esk, &vpk)
|
||
|
|
};
|
||
|
|
let kind = PrivateAccountKind::Regular(0_u128);
|
||
|
|
let output_index: u32 = 0;
|
||
|
|
|
||
|
|
let mut g = c.benchmark_group("encryption");
|
||
|
|
g.sample_size(50).noise_threshold(0.05);
|
||
|
|
g.bench_function("encrypt", |b| {
|
||
|
|
b.iter(|| EncryptionScheme::encrypt(&account, &kind, &shared, &commitment, output_index));
|
||
|
|
});
|
||
|
|
// One ciphertext for the decrypt bench (encrypt is deterministic given inputs).
|
||
|
|
let ct = EncryptionScheme::encrypt(&account, &kind, &shared, &commitment, output_index);
|
||
|
|
g.bench_function("decrypt", |b| {
|
||
|
|
b.iter(|| EncryptionScheme::decrypt(&ct, &shared, &commitment, output_index));
|
||
|
|
});
|
||
|
|
g.finish();
|
||
|
|
}
|
||
|
|
|
||
|
|
criterion_group! {
|
||
|
|
name = benches;
|
||
|
|
config = Criterion::default()
|
||
|
|
.warm_up_time(Duration::from_secs(2))
|
||
|
|
.measurement_time(Duration::from_secs(10));
|
||
|
|
targets = bench_keychain, bench_shared_secret_key, bench_encryption
|
||
|
|
}
|
||
|
|
criterion_main!(benches);
|