aws-lc-rs-testing/benches/agreement_benchmark.rs (43 lines of code) (raw):
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC
use aws_lc_rs::{test, test_file};
use criterion::{criterion_group, criterion_main, Criterion};
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum Curve {
X25519,
P256,
P384,
}
impl From<&str> for Curve {
fn from(value: &str) -> Self {
match value {
"X25519" => Curve::X25519,
"P-256" => Curve::P256,
"P-384" => Curve::P384,
_ => panic!("Unrecognized curve: '{value}'"),
}
}
}
pub struct AgreementConfig {
curve: Curve,
peer_pub: Vec<u8>,
private: Vec<u8>,
}
impl AgreementConfig {
fn new(curve: &str, peer_pub: &[u8], private: &[u8]) -> Self {
AgreementConfig {
curve: Curve::from(curve),
peer_pub: Vec::from(peer_pub),
private: Vec::from(private),
}
}
}
macro_rules! benchmark_agreement {
( $pkg:ident ) => {
paste::item! {
mod [<$pkg _benchmarks>] {
use $pkg::{agreement, test};
use crate::{AgreementConfig, Curve};
use agreement::{
agree_ephemeral, Algorithm, EphemeralPrivateKey, UnparsedPublicKey, ECDH_P256, ECDH_P384,
X25519,
};
fn algorithm(config: &AgreementConfig) -> &'static Algorithm {
match config.curve {
Curve::X25519 => &X25519,
Curve::P256 => &ECDH_P256,
Curve::P384 => &ECDH_P384,
}
}
pub fn private_key(config: &AgreementConfig) -> EphemeralPrivateKey {
let rng = test::rand::FixedSliceRandom {
bytes: &config.private,
};
EphemeralPrivateKey::generate(algorithm(config), &rng).unwrap()
}
pub fn peer_public_key(config: &AgreementConfig) -> UnparsedPublicKey<Vec<u8>> {
UnparsedPublicKey::new(algorithm(config), config.peer_pub.clone())
}
pub fn agreement(
private_key: EphemeralPrivateKey,
peer_public_key: &UnparsedPublicKey<Vec<u8>>,
) {
agree_ephemeral(private_key, peer_public_key, (), |val| Ok(Vec::from(val))).unwrap();
}
}
}
};
}
benchmark_agreement!(aws_lc_rs);
#[cfg(feature = "ring-benchmarks")]
benchmark_agreement!(ring);
fn test_agree_ephemeral(c: &mut Criterion, config: &AgreementConfig) {
let bench_group_name = format!("Agreement-{:?}", config.curve);
let mut group = c.benchmark_group(bench_group_name);
let aws_peer_public_key = aws_lc_rs_benchmarks::peer_public_key(config);
group.bench_function("AWS-LC", |b| {
b.iter(|| {
let private_key = aws_lc_rs_benchmarks::private_key(config);
aws_lc_rs_benchmarks::agreement(private_key, &aws_peer_public_key);
});
});
#[cfg(feature = "ring-benchmarks")]
{
let ring_peer_public_key = ring_benchmarks::peer_public_key(config);
group.bench_function("Ring", |b| {
b.iter(|| {
let private_key = ring_benchmarks::private_key(config);
ring_benchmarks::agreement(private_key, &ring_peer_public_key);
});
});
}
}
fn test_agreement(c: &mut Criterion) {
test::run(
test_file!("data/agreement_benchmarks.txt"),
|_section, test_case| {
let config = AgreementConfig::new(
test_case.consume_string("Curve").as_str(),
test_case.consume_bytes("PeerQ").as_slice(),
test_case.consume_bytes("D").as_slice(),
);
test_agree_ephemeral(c, &config);
Ok(())
},
);
}
criterion_group!(benches, test_agreement);
criterion_main!(benches);