benchmarks: move crypto benchmarks to criterion (#271)

This commit is contained in:
Noah Kennedy 2022-06-24 13:56:14 -05:00 committed by GitHub
parent 8f603fced6
commit 2fffe3c763
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 646 additions and 396 deletions

416
Cargo.lock generated
View File

@ -2,6 +2,15 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aead"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877"
dependencies = [
"generic-array",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
@ -44,7 +53,10 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
name = "boringtun"
version = "0.4.0"
dependencies = [
"aead",
"base64",
"chacha20poly1305",
"criterion",
"hex",
"ip_network",
"ip_network_table",
@ -65,7 +77,7 @@ name = "boringtun-cli"
version = "0.1.0"
dependencies = [
"boringtun",
"clap",
"clap 3.1.6",
"daemonize",
"tracing",
"tracing-appender",
@ -78,6 +90,18 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
[[package]]
name = "bstr"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
dependencies = [
"lazy_static",
"memchr",
"regex-automata",
"serde",
]
[[package]]
name = "bumpalo"
version = "3.9.1"
@ -96,6 +120,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cast"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
dependencies = [
"rustc_version",
]
[[package]]
name = "cc"
version = "1.0.72"
@ -114,6 +147,51 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chacha20"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
"zeroize",
]
[[package]]
name = "chacha20poly1305"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a"
dependencies = [
"aead",
"chacha20",
"cipher",
"poly1305",
"zeroize",
]
[[package]]
name = "cipher"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7"
dependencies = [
"generic-array",
]
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"bitflags",
"textwrap 0.11.0",
"unicode-width",
]
[[package]]
name = "clap"
version = "3.1.6"
@ -126,7 +204,7 @@ dependencies = [
"os_str_bytes",
"strsim",
"termcolor",
"textwrap",
"textwrap 0.15.0",
]
[[package]]
@ -139,6 +217,51 @@ dependencies = [
"memchr",
]
[[package]]
name = "cpufeatures"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b"
dependencies = [
"libc",
]
[[package]]
name = "criterion"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
dependencies = [
"atty",
"cast",
"clap 2.34.0",
"criterion-plot",
"csv",
"itertools",
"lazy_static",
"num-traits",
"oorandom",
"plotters",
"rayon",
"regex",
"serde",
"serde_cbor",
"serde_derive",
"serde_json",
"tinytemplate",
"walkdir",
]
[[package]]
name = "criterion-plot"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
dependencies = [
"cast",
"itertools",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.2"
@ -149,6 +272,31 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
dependencies = [
"cfg-if",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
dependencies = [
"autocfg",
"cfg-if",
"crossbeam-utils",
"memoffset",
"once_cell",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.7"
@ -159,6 +307,28 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "csv"
version = "1.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
dependencies = [
"bstr",
"csv-core",
"itoa 0.4.8",
"ryu",
"serde",
]
[[package]]
name = "csv-core"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
dependencies = [
"memchr",
]
[[package]]
name = "curve25519-dalek"
version = "3.2.1"
@ -191,6 +361,12 @@ dependencies = [
"generic-array",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "generic-array"
version = "0.14.5"
@ -212,6 +388,12 @@ dependencies = [
"wasi",
]
[[package]]
name = "half"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
name = "hashbrown"
version = "0.11.2"
@ -265,6 +447,21 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d"
[[package]]
name = "itertools"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
[[package]]
name = "itoa"
version = "1.0.1"
@ -358,6 +555,25 @@ dependencies = [
"memoffset",
]
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "num_threads"
version = "0.1.3"
@ -373,6 +589,18 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5"
[[package]]
name = "oorandom"
version = "11.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
[[package]]
name = "opaque-debug"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "os_str_bytes"
version = "6.0.0"
@ -411,6 +639,45 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c"
[[package]]
name = "plotters"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
dependencies = [
"num-traits",
"plotters-backend",
"plotters-svg",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "plotters-backend"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
[[package]]
name = "plotters-svg"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
dependencies = [
"plotters-backend",
]
[[package]]
name = "poly1305"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede"
dependencies = [
"cpufeatures",
"opaque-debug",
"universal-hash",
]
[[package]]
name = "proc-macro2"
version = "1.0.36"
@ -438,6 +705,30 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rayon"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
dependencies = [
"autocfg",
"crossbeam-deque",
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-utils",
"num_cpus",
]
[[package]]
name = "redox_syscall"
version = "0.2.10"
@ -447,6 +738,27 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex"
version = "1.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1"
dependencies = [
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
[[package]]
name = "ring"
version = "0.16.20"
@ -462,6 +774,21 @@ dependencies = [
"winapi",
]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "same-file"
version = "1.0.6"
@ -477,6 +804,50 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a41d061efea015927ac527063765e73601444cdc344ba855bc7bd44578b25e1c"
[[package]]
name = "serde"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
[[package]]
name = "serde_cbor"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half",
"serde",
]
[[package]]
name = "serde_derive"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
dependencies = [
"itoa 1.0.1",
"ryu",
"serde",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
@ -542,6 +913,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "textwrap"
version = "0.15.0"
@ -583,11 +963,21 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "004cbc98f30fa233c61a38bc77e96a9106e65c88f2d3bef182ae952027e5753d"
dependencies = [
"itoa",
"itoa 1.0.1",
"libc",
"num_threads",
]
[[package]]
name = "tinytemplate"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "tracing"
version = "0.1.31"
@ -663,12 +1053,28 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "universal-hash"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05"
dependencies = [
"generic-array",
"subtle",
]
[[package]]
name = "untrusted"
version = "0.7.1"
@ -870,9 +1276,9 @@ dependencies = [
[[package]]
name = "zeroize_derive"
version = "1.3.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81e8f13fef10b63c06356d65d416b070798ddabcadc10d3ece0c5be9b3c7eddb"
checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17"
dependencies = [
"proc-macro2",
"quote",

View File

@ -3,4 +3,8 @@ members = ["boringtun", "boringtun-cli"]
[profile.release]
lto = true # Enable full link-time optimization.
codegen-units = 1 # Use only 1 codegen-unit to enable full optimizations.
codegen-units = 1 # Use only 1 codegen-unit to enable full optimizations.
[profile.bench]
lto = true # Enable full link-time optimization.
codegen-units = 1 # Use only 1 codegen-unit to enable full optimizations.

View File

@ -51,16 +51,6 @@ Testing this project has a few requirements:
- `sudo`: required to create tunnels. When you run `cargo test` you'll be prompted for your password.
- Docker: you can install it [here](https://www.docker.com/get-started). If you are on Ubuntu/Debian you can run `apt-get install docker.io`.
### Benchmarking
To benchmark this project you can run this command:
```
cargo +nightly bench
```
This command depends on the unstable `test` feature of the Rust compiler. As a result, you'll need to use the `nightly` channel of Rust when you run it.
## Supported platforms
Target triple |Binary|Library| |

View File

@ -23,6 +23,9 @@ rand_core = "0.5.1"
[dev-dependencies]
tracing-subscriber = "0.3"
criterion = { version = "0.3.5", features = ["html_reports"] }
chacha20poly1305 = "0.9.0"
aead = "0.4.3"
[target.'cfg(target_os="android")'.dependencies]
jni = "0.19.0"
@ -30,6 +33,6 @@ jni = "0.19.0"
[target.'cfg(target_os="macos")'.dependencies]
nix = "0.23.1"
[[example]]
name = "benchmarks"
path = "src/benchmarks_example.rs"
[[bench]]
name = "crypto_benches"
harness = false

View File

@ -0,0 +1,23 @@
use boringtun::crypto::Blake2s;
use criterion::{BenchmarkId, Criterion, Throughput};
pub fn bench_blake2s(c: &mut Criterion) {
let mut group = c.benchmark_group("blake2s");
group.sample_size(1000);
for size in [128, 1024] {
group.throughput(Throughput::Bytes(size as u64));
group.bench_with_input(BenchmarkId::from_parameter(size), &size, |b, _| {
let buf_in = vec![0u8; size];
b.iter(|| {
Blake2s::new_hash().hash(&buf_in).finalize();
buf_in.len()
});
});
}
group.finish();
}

View File

@ -0,0 +1,99 @@
use aead::{AeadInPlace, NewAead};
use criterion::{BenchmarkId, Criterion, Throughput};
use rand_core::{OsRng, RngCore};
use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};
fn chacha20poly1305_ring(key_bytes: &[u8], buf: &mut [u8]) {
let len = buf.len();
let n = len - 16;
let key = LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, &key_bytes).unwrap());
let tag = key
.seal_in_place_separate_tag(
Nonce::assume_unique_for_key([0u8; 12]),
Aad::from(&[]),
&mut buf[..n],
)
.unwrap();
buf[n..].copy_from_slice(tag.as_ref())
}
fn chacha20poly1305_non_ring(key_bytes: &[u8], buf: &mut [u8]) {
let len = buf.len();
let n = len - 16;
let aead = chacha20poly1305::ChaCha20Poly1305::new_from_slice(key_bytes).unwrap();
let nonce = chacha20poly1305::Nonce::default();
let tag = aead
.encrypt_in_place_detached(&nonce, &[], &mut buf[..n])
.unwrap();
buf[n..].copy_from_slice(tag.as_ref());
}
pub fn bench_chacha20poly1305(c: &mut Criterion) {
let mut group = c.benchmark_group("chacha20poly1305");
group.sample_size(1000);
for size in [128, 192, 1400, 8192] {
group.throughput(Throughput::Bytes(size as u64));
group.bench_with_input(
BenchmarkId::new("chacha20poly1305_ring", size),
&size,
|b, i| {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];
let mut rng = OsRng::default();
rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);
b.iter(|| chacha20poly1305_ring(&key, &mut buf));
},
);
group.bench_with_input(
BenchmarkId::new("chacha20poly1305_non_ring", size),
&size,
|b, i| {
let mut key = [0; 32];
let mut buf = vec![0; i + 16];
let mut rng = OsRng::default();
rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf);
b.iter(|| chacha20poly1305_non_ring(&key, &mut buf));
},
);
group.bench_with_input(
BenchmarkId::new("chacha20poly1305_custom", size),
&size,
|b, _| {
let mut key = [0; 32];
let mut buf_in = vec![0u8; size];
let mut buf_out = vec![0u8; size + 16];
let mut rng = OsRng::default();
rng.fill_bytes(&mut key);
rng.fill_bytes(&mut buf_in);
let aead = boringtun::crypto::ChaCha20Poly1305::new_aead(&key);
b.iter(|| aead.seal_wg(0, &[], &buf_in, &mut buf_out) - 16)
},
);
}
group.finish();
}

View File

@ -0,0 +1,18 @@
use blake2s_benching::bench_blake2s;
use chacha20poly1305_benching::bench_chacha20poly1305;
use x25519_public_key_benching::bench_x25519_public_key;
use x25519_shared_key_benching::bench_x25519_shared_key;
mod blake2s_benching;
mod chacha20poly1305_benching;
mod x25519_public_key_benching;
mod x25519_shared_key_benching;
criterion::criterion_group!(
crypto_benches,
bench_chacha20poly1305,
bench_blake2s,
bench_x25519_shared_key,
bench_x25519_public_key
);
criterion::criterion_main!(crypto_benches);

View File

@ -0,0 +1,30 @@
use criterion::Criterion;
use rand_core::OsRng;
pub fn bench_x25519_public_key(c: &mut Criterion) {
let mut group = c.benchmark_group("x25519_public_key");
group.sample_size(1000);
group.bench_function("x25519_public_key_dalek", |b| {
b.iter(|| {
let secret_key = x25519_dalek::StaticSecret::new(OsRng);
let public_key = x25519_dalek::PublicKey::from(&secret_key);
(secret_key, public_key)
});
});
group.bench_function("x25519_public_key_ring", |b| {
let rng = ring::rand::SystemRandom::new();
b.iter(|| {
let my_private_key =
ring::agreement::EphemeralPrivateKey::generate(&ring::agreement::X25519, &rng)
.unwrap();
my_private_key.compute_public_key().unwrap()
});
});
group.finish();
}

View File

@ -0,0 +1,52 @@
use criterion::{BatchSize, Criterion};
use rand_core::OsRng;
pub fn bench_x25519_shared_key(c: &mut Criterion) {
let mut group = c.benchmark_group("x25519_shared_key");
group.sample_size(1000);
group.bench_function("x25519_shared_key_dalek", |b| {
let public_key = x25519_dalek::PublicKey::from(&x25519_dalek::StaticSecret::new(OsRng));
b.iter_batched(
|| x25519_dalek::StaticSecret::new(OsRng),
|secret_key| secret_key.diffie_hellman(&public_key),
BatchSize::SmallInput,
);
});
group.bench_function("x25519_shared_key_ring", |b| {
let rng = ring::rand::SystemRandom::new();
let peer_public_key = {
let peer_private_key =
ring::agreement::EphemeralPrivateKey::generate(&ring::agreement::X25519, &rng)
.unwrap();
peer_private_key.compute_public_key().unwrap()
};
let peer_public_key_alg = &ring::agreement::X25519;
let my_public_key =
ring::agreement::UnparsedPublicKey::new(peer_public_key_alg, &peer_public_key);
b.iter_batched(
|| {
ring::agreement::EphemeralPrivateKey::generate(&ring::agreement::X25519, &rng)
.unwrap()
},
|my_private_key| {
ring::agreement::agree_ephemeral(
my_private_key,
&my_public_key,
ring::error::Unspecified,
|_key_material| Ok(()),
)
.unwrap()
},
BatchSize::SmallInput,
);
});
group.finish();
}

View File

@ -1,98 +0,0 @@
// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
#![feature(test)]
extern crate test;
#[cfg(test)]
mod tests {
use boringtun::crypto::Blake2s;
use boringtun::crypto::ChaCha20Poly1305;
use rand_core::OsRng;
use test::{black_box, Bencher};
use x25519_dalek::{PublicKey, StaticSecret};
#[bench]
fn bench_x25519_public_key(b: &mut Bencher) {
let secret_key = StaticSecret::new(OsRng);
b.iter(|| {
black_box(PublicKey::from(&secret_key));
});
}
#[bench]
fn bench_x25519_shared_key(b: &mut Bencher) {
let secret_key = StaticSecret::new(OsRng);
let public_key = PublicKey::from(&StaticSecret::new(OsRng));
b.iter(|| black_box(secret_key.diffie_hellman(&public_key)));
}
#[bench]
fn bench_blake2s_hash_128b(b: &mut Bencher) {
let data = [0_u8; 128];
b.iter(|| black_box(Blake2s::new_hash().hash(&data).finalize()));
}
#[bench]
fn bench_blake2s_hash_1024b(b: &mut Bencher) {
let data = [0_u8; 1024];
b.iter(|| black_box(Blake2s::new_hash().hash(&data).finalize()));
}
#[bench]
fn bench_chacha20poly1305_seal_192b(b: &mut Bencher) {
let pc = ChaCha20Poly1305::new_aead(&[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
]);
let pt = [0_u8; 192];
let mut ct = [0_u8; 192 + 16];
b.iter(|| {
black_box(pc.seal_wg(0, &[], &pt, &mut ct));
});
}
#[bench]
fn bench_chacha20poly1305_open_192b(b: &mut Bencher) {
let pc = ChaCha20Poly1305::new_aead(&[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
]);
let mut pt = [0_u8; 192];
let mut ct = [0_u8; 192 + 16];
pc.seal_wg(0, &[], &pt, &mut ct);
b.iter(|| {
black_box(pc.open_wg(0, &[], &ct, &mut pt).unwrap());
});
}
#[bench]
fn bench_chacha20poly1305_seal_512b(b: &mut Bencher) {
let pc = ChaCha20Poly1305::new_aead(&[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
]);
let pt = [0_u8; 512];
let mut ct = [0_u8; 512 + 16];
b.iter(|| {
black_box(pc.seal_wg(0, &[], &pt, &mut ct));
});
}
#[bench]
fn bench_chacha20poly1305_seal_8192b(b: &mut Bencher) {
let pc = ChaCha20Poly1305::new_aead(&[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
]);
let pt = [0_u8; 8192];
let mut ct = [0_u8; 8192 + 16];
b.iter(|| {
black_box(pc.seal_wg(0, &[], &pt, &mut ct));
});
}
}

View File

@ -1,21 +0,0 @@
// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
mod crypto;
mod ffi;
mod noise;
mod serialization;
use ffi::benchmark::do_benchmark;
use std::io::prelude::Write;
fn main() {
let mut i = 0;
while let Some(benchmark_name) = do_benchmark(true, i) {
print!("{}", benchmark_name);
std::io::stdout().flush().unwrap();
let benchmark_result = do_benchmark(false, i).unwrap();
println!("{}", benchmark_result);
i += 1;
}
println!("Done");
}

View File

@ -4,9 +4,9 @@
//! Optimized cryptographic primitives for the WireGuard protocol.
mod blake2s;
mod chacha20poly1305;
mod chacha20poly1305_custom;
pub use blake2s::{constant_time_mac_check, Blake2s};
pub use chacha20poly1305::ChaCha20Poly1305;
pub use chacha20poly1305_custom::ChaCha20Poly1305;
pub use ring::rand::SystemRandom;

View File

@ -1,238 +0,0 @@
// Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
// SPDX-License-Identifier: BSD-3-Clause
/// This module implements benchmarking code for use with the FFI bindings
use crate::crypto::{Blake2s, ChaCha20Poly1305};
use rand_core::OsRng;
use ring::aead::{Aad, LessSafeKey, Nonce, UnboundKey, CHACHA20_POLY1305};
use ring::{agreement, rand};
use x25519_dalek::{PublicKey, StaticSecret};
use std::time::Instant;
const ITR_DURATION: u64 = 1;
const ITRS: u64 = 3;
// Format f64 with US locale decimal separators
// We don't care about speed or efficiency here
// Assumes that f64 in this context is always smaller than u64::MAX and larger than 0
fn format_float(number: f64) -> String {
let fract = number.fract();
let mut integer = number.trunc() as u64;
let mut formatted = format!("{:.2}", fract);
if integer == 0 {
// Return with the leading 0
return formatted;
}
// Strip the 0
formatted = formatted[1..].to_string();
loop {
let remainder = integer % 1000;
integer /= 1000;
if integer == 0 {
let mut new_str = format!("{:}", remainder);
new_str.push_str(&formatted);
formatted = new_str;
break;
}
let mut new_str = format!(",{:03}", remainder);
new_str.push_str(&formatted);
formatted = new_str;
}
formatted
}
fn run_bench(test_func: &mut dyn FnMut() -> usize) -> f64 {
let mut best_time = std::f64::MAX;
// Take the best result out of ITRS runs
for _ in 0..ITRS {
let start_time = Instant::now();
let mut total_itr = 0;
loop {
for _ in 0..300 {
total_itr += test_func();
}
// Check time every 300 iterations
let time_since_started = Instant::now().duration_since(start_time);
if time_since_started.as_secs() >= ITR_DURATION {
// Stop the benchmark after ITR_DURATION
let total_time = time_since_started.as_secs() as f64
+ f64::from(time_since_started.subsec_nanos()) * 1e-9;
best_time = best_time.min((total_itr as f64) / total_time);
break;
}
}
}
best_time
}
fn bench_x25519_shared_key(name: bool, _: usize) -> String {
if name {
return "X25519 Shared Key: ".to_string();
}
let secret_key = StaticSecret::new(OsRng);
let public_key = PublicKey::from(&StaticSecret::new(OsRng));
let result = run_bench(&mut move || {
let _ = secret_key.diffie_hellman(&public_key);
1
});
format!("{} ops/sec", format_float(result))
}
fn bench_x25519_public_key(name: bool, _: usize) -> String {
if name {
return "X25519 Public Key: ".to_string();
}
let secret_key = StaticSecret::new(OsRng);
let result = run_bench(&mut move || {
let _ = PublicKey::from(&secret_key);
1
});
format!("{} ops/sec", format_float(result))
}
fn bench_blake2s(name: bool, n: usize) -> String {
if name {
return format!("Blake2s {}B: ", n);
}
let buf_in = vec![0u8; n];
let result = run_bench(&mut move || {
Blake2s::new_hash().hash(&buf_in).finalize();
buf_in.len()
});
format!("{} MiB/s", format_float(result / (1024. * 1024.)))
}
fn bench_chacha20poly1305_ring(name: bool, n: usize) -> String {
if name {
return format!("(Ring) AEAD Seal {}B: ", n);
}
let key = LessSafeKey::new(UnboundKey::new(&CHACHA20_POLY1305, &[0x0fu8; 32]).unwrap());
let mut buf_in = vec![0u8; n + 16];
let result = run_bench(&mut move || {
let tag_len = CHACHA20_POLY1305.tag_len();
let buf_len = buf_in.len();
key.seal_in_place_separate_tag(
Nonce::assume_unique_for_key([0u8; 12]),
Aad::from(&[]),
&mut buf_in[..buf_len - tag_len],
)
.map(|tag| {
buf_in[buf_len - tag_len..].copy_from_slice(tag.as_ref());
buf_len
})
.unwrap()
});
format!("{} MiB/s", format_float(result / (1024. * 1024.)))
}
fn bench_chacha20poly1305(name: bool, n: usize) -> String {
if name {
return format!("AEAD Seal {}B: ", n);
}
let aead = ChaCha20Poly1305::new_aead(&[0u8; 32]);
let buf_in = vec![0u8; n];
let mut buf_out = vec![0u8; n + 16];
let result = run_bench(&mut move || aead.seal_wg(0, &[], &buf_in, &mut buf_out) - 16);
format!("{} MiB/s", format_float(result / (1024. * 1024.)))
}
fn bench_x25519_shared_key_ring(name: bool, _: usize) -> String {
if name {
return "(Ring) X25519 Shared Key: ".to_string();
}
let rng = rand::SystemRandom::new();
let peer_public_key = {
let peer_private_key =
agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng).unwrap();
peer_private_key.compute_public_key().unwrap()
};
let peer_public_key_alg = &agreement::X25519;
let result = run_bench(&mut move || {
let my_private_key =
agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng).unwrap();
let my_public_key =
agreement::UnparsedPublicKey::new(peer_public_key_alg, &peer_public_key);
agreement::agree_ephemeral(
my_private_key,
&my_public_key,
ring::error::Unspecified,
|_key_material| Ok(()),
)
.unwrap();
1
});
format!("{} ops/sec", format_float(result))
}
fn bench_x25519_public_key_ring(name: bool, _: usize) -> String {
if name {
return "(Ring) X25519 Public Key: ".to_string();
}
let rng = rand::SystemRandom::new();
let result = run_bench(&mut move || {
let my_private_key =
agreement::EphemeralPrivateKey::generate(&agreement::X25519, &rng).unwrap();
my_private_key.compute_public_key().unwrap();
1
});
format!("{} ops/sec", format_float(result))
}
type BenchFnc = fn(bool, usize) -> String;
pub fn do_benchmark(name: bool, idx: usize) -> Option<String> {
let benchmarks: Vec<(BenchFnc, usize)> = vec![
(bench_x25519_public_key, 0),
(bench_x25519_shared_key, 0),
(bench_x25519_public_key_ring, 0),
(bench_x25519_shared_key_ring, 0),
(bench_blake2s, 128),
(bench_blake2s, 1024),
(bench_chacha20poly1305, 128),
(bench_chacha20poly1305, 192),
(bench_chacha20poly1305, 1400),
(bench_chacha20poly1305, 8192),
(bench_chacha20poly1305_ring, 128),
(bench_chacha20poly1305_ring, 192),
(bench_chacha20poly1305_ring, 1400),
(bench_chacha20poly1305_ring, 8192),
];
if idx >= benchmarks.len() {
return None;
}
let fnc = benchmarks[idx].0;
let param = benchmarks[idx].1;
Some(fnc(name, param))
}

View File

@ -6,8 +6,6 @@
#![allow(clippy::missing_safety_doc)]
/// C bindings for the BoringTun library
pub mod benchmark;
use self::benchmark::do_benchmark;
use super::noise::{Tunn, TunnResult};
use base64::{decode, encode};
use hex::encode as encode_hex;
@ -17,7 +15,6 @@ use x25519_dalek::{PublicKey, StaticSecret};
use crate::serialization::KeyBytes;
use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::c_char;
use std::panic;
use std::ptr;
@ -322,16 +319,3 @@ pub unsafe extern "C" fn wireguard_stats(tunnel: *mut Tunn) -> stats {
reserved: [0u8; 56],
}
}
/// Performs an internal benchmark, and returns its result as a C-string.
#[no_mangle]
pub extern "C" fn benchmark(name: i32, idx: u32) -> *const c_char {
if let Some(s) = do_benchmark(name != 0, idx as usize) {
let s = CString::new(s).unwrap();
let v = s.as_ptr();
mem::forget(s); // This is a memory leak, but we assume it is rarely used anyway
v
} else {
ptr::null()
}
}

View File

@ -87,5 +87,3 @@ struct wireguard_result wireguard_force_handshake(struct wireguard_tunnel *tunne
uint32_t dst_size);
struct stats wireguard_stats(struct wireguard_tunnel *tunnel);
const uint8_t *benchmark(int32_t name, uint32_t idx);