diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 38d11b129..d2446723e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -134,3 +134,79 @@ jobs: - name: 🏃🏻‍♀️ Test run: CC=emcc AR=emar wasm-pack test --node --features wasm + + build: + strategy: + fail-fast: false + matrix: + bits: [32, 64] + os: + - macos-latest + - ubuntu-latest + - windows-latest + exclude: + - bits: 32 + os: "macos-latest" + # FIXME: Linking isn't working here yet for hacl #42 + - bits: 32 + os: "windows-latest" + + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash + + steps: + - uses: actions/checkout@v4 + + - run: echo "RUST_TARGET_FLAG=" > $GITHUB_ENV + if: ${{ matrix.bits == 64 }} + + - name: ⚙️ Setup Ubuntu x86 + if: ${{ matrix.bits == 32 && matrix.os == 'ubuntu-latest' }} + run: | + rustup target add i686-unknown-linux-gnu + sudo apt-get update + sudo apt-get install -y gcc-multilib g++-multilib + + - name: ⚙️ Setup Ubuntu x64 + if: ${{ matrix.bits == 64 && matrix.os == 'ubuntu-latest' }} + run: | + rustup target add aarch64-unknown-linux-gnu + + - name: ⚙️ Setup macOS + if: ${{ matrix.os == 'macos-latest' }} + run: | + rustup target add aarch64-apple-darwin + + # Set up 32 bit systems + + - name: 🛠️ Config Windows x86 + run: echo "RUST_TARGET_FLAG=--target=i686-pc-windows-msvc" > $GITHUB_ENV + if: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }} + + - name: 🛠️ Config Linux x86 + run: | + echo "RUST_TARGET_FLAG=--target=i686-unknown-linux-gnu" > $GITHUB_ENV + if: ${{ matrix.bits == 32 && matrix.os == 'ubuntu-latest' }} + + # Set up windows + + - name: ⚙️ Setup Windows x86 + if: ${{ matrix.bits == 32 && matrix.os == 'windows-latest' }} + shell: pwsh + run: | + echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + vcpkg install openssl:x86-windows-static-md + + - name: ⚙️ Setup Windows x64 + if: ${{ matrix.bits == 64 && matrix.os == 'windows-latest' }} + shell: pwsh + run: | + echo "VCPKG_ROOT=$env:VCPKG_INSTALLATION_ROOT" | Out-File -FilePath $env:GITHUB_ENV -Append + vcpkg install openssl:x64-windows-static-md + + # Benchmarks ... + + - name: 🏃🏻‍♀️ Benchmarks + run: cargo bench --verbose $RUST_TARGET_FLAG -p benchmarks \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index efc9a3499..8cca7e8d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,11 @@ [workspace] -members = ["sys/hacl", "sys/libjade", "sys/platform", "sys/pqclean"] +members = [ + "sys/hacl", + "sys/libjade", + "sys/platform", + "sys/pqclean", + "benchmarks", +] [workspace.package] version = "0.0.2-pre.1" @@ -55,51 +61,9 @@ serde_json = { version = "1.0" } serde = { version = "1.0", features = ["derive"] } hex = "0.4" -# Benchmarking "RustCrypto" -chacha20poly1305 = "0.10" -sha2 = "0.10" -x25519-dalek-ng = "1.1" -sha3 = "0.10" -# Benchmarking "Ring" -ring = "0.17" - [target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3" -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -criterion = "0.5" -# libcrux-pqclean = { version = "0.0.2-pre.1", path = "sys/pqclean" } - -# Benchmarking "OpenSSL" -# XXX: We don't do this for Windows or wasm right now. -# x86 is usally a cross compilation where this won't work either. -[target.'cfg(all(not(windows), not(target_arch = "wasm32"), not(target_arch = "x86")))'.dev-dependencies] -openssl = "0.10" - -[[bench]] -name = "sha2" -harness = false - -[[bench]] -name = "sha3" -harness = false - -[[bench]] -name = "x25519" -harness = false - -[[bench]] -name = "aead" -harness = false - -[[bench]] -name = "hpke" -harness = false - -[[bench]] -name = "drbg" -harness = false - [features] hacspec = [] # TODO: #7 Use specs instead of efficient implementations rand = [] diff --git a/benchmarks/Cargo.toml b/benchmarks/Cargo.toml new file mode 100644 index 000000000..f82543943 --- /dev/null +++ b/benchmarks/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "benchmarks" +version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +edition.workspace = true +repository.workspace = true +readme.workspace = true + +[dependencies] + +[dev-dependencies] +libcrux = { path = "../", features = ["rand"] } +rand = { version = "0.8" } +rand_core = { version = "0.6" } +# Benchmarking "RustCrypto" +chacha20poly1305 = "0.10" +sha2 = "0.10" +x25519-dalek-ng = "1.1" +sha3 = "0.10" +p256 = { version = "0.13", features = ["ecdh"] } +# Benchmarking "Ring" +ring = "0.17" + +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +criterion = "0.5" +# libcrux-pqclean = { version = "0.0.2-pre.1", path = "sys/pqclean" } + +# Benchmarking "OpenSSL" +# XXX: We don't do this for Windows or wasm right now. +# x86 is usally a cross compilation where this won't work either. +[target.'cfg(all(not(windows), not(target_arch = "wasm32"), not(target_arch = "x86")))'.dev-dependencies] +openssl = "0.10" + +[[bench]] +name = "sha2" +harness = false + +[[bench]] +name = "sha3" +harness = false + +[[bench]] +name = "x25519" +harness = false + +[[bench]] +name = "p256" +harness = false + +[[bench]] +name = "aead" +harness = false + +[[bench]] +name = "hpke" +harness = false + +[[bench]] +name = "drbg" +harness = false diff --git a/benches/Readme.md b/benchmarks/benches/Readme.md similarity index 100% rename from benches/Readme.md rename to benchmarks/benches/Readme.md diff --git a/benches/aead.rs b/benchmarks/benches/aead.rs similarity index 100% rename from benches/aead.rs rename to benchmarks/benches/aead.rs diff --git a/benches/drbg.rs b/benchmarks/benches/drbg.rs similarity index 100% rename from benches/drbg.rs rename to benchmarks/benches/drbg.rs diff --git a/benches/hpke.rs b/benchmarks/benches/hpke.rs similarity index 100% rename from benches/hpke.rs rename to benchmarks/benches/hpke.rs diff --git a/benchmarks/benches/p256.rs b/benchmarks/benches/p256.rs new file mode 100644 index 000000000..a562bebd2 --- /dev/null +++ b/benchmarks/benches/p256.rs @@ -0,0 +1,121 @@ +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; +use libcrux::ecdh; + +mod util; +use rand_core::OsRng; + +fn derive(c: &mut Criterion) { + // Comparing libcrux performance for different payload sizes and other implementations. + let mut group = c.benchmark_group("P256 derive"); + + group.bench_function("libcrux", |b| { + b.iter_batched( + || { + let (_, pk1) = ecdh::key_gen(ecdh::Algorithm::P256, &mut OsRng).unwrap(); + let (sk2, _) = ecdh::key_gen(ecdh::Algorithm::P256, &mut OsRng).unwrap(); + (pk1, sk2) + }, + |(pk1, sk2)| { + let _zz = ecdh::derive(ecdh::Algorithm::P256, &pk1, &sk2).unwrap(); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("Ring", |b| { + use ring::{agreement, rand::SystemRandom}; + + b.iter_batched( + || { + let rng = SystemRandom::new(); + let sk1 = + agreement::EphemeralPrivateKey::generate(&agreement::ECDH_P256, &rng).unwrap(); + let pk1 = sk1.compute_public_key().unwrap(); + let sk2 = + agreement::EphemeralPrivateKey::generate(&agreement::ECDH_P256, &rng).unwrap(); + + (pk1, sk2) + }, + |(pk1, sk2)| { + let _zz: Result, ring::error::Unspecified> = agreement::agree_ephemeral( + sk2, + &agreement::UnparsedPublicKey::new(&agreement::ECDH_P256, pk1), + |k| Ok(k.to_vec()), + ) + .unwrap(); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("RustCrypto", |b| { + use p256::{ecdh::EphemeralSecret, PublicKey}; + + b.iter_batched( + || { + let sk1 = EphemeralSecret::random(&mut OsRng); + let pk1 = PublicKey::from(&sk1); + let sk2 = EphemeralSecret::random(&mut OsRng); + (pk1, sk2) + }, + |(pk1, sk2)| { + let _zz = sk2.diffie_hellman(&pk1); + }, + BatchSize::SmallInput, + ) + }); +} + +fn secret_to_public(c: &mut Criterion) { + // Comparing libcrux performance for different payload sizes and other implementations. + let mut group = c.benchmark_group("P256 secret to public"); + + group.bench_function("libcrux", |b| { + b.iter_batched( + || { + let (sk, _) = ecdh::key_gen(ecdh::Algorithm::P256, &mut OsRng).unwrap(); + sk + }, + |sk| { + let _pk = ecdh::secret_to_public(ecdh::Algorithm::P256, &sk).unwrap(); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("Ring", |b| { + use ring::{agreement, rand::SystemRandom}; + + b.iter_batched( + || { + let rng = SystemRandom::new(); + let sk = + agreement::EphemeralPrivateKey::generate(&agreement::ECDH_P256, &rng).unwrap(); + + sk + }, + |sk| { + let _pk = sk.compute_public_key().unwrap(); + }, + BatchSize::SmallInput, + ) + }); + + group.bench_function("RustCrypto", |b| { + use p256::{ecdh::EphemeralSecret, PublicKey}; + + b.iter_batched( + || { + let sk = EphemeralSecret::random(&mut OsRng); + sk + }, + |sk| { + let _pk = PublicKey::from(&sk); + }, + BatchSize::SmallInput, + ) + }); +} + +criterion_group!(benches, derive, secret_to_public); +criterion_main!(benches); diff --git a/benches/sha2.rs b/benchmarks/benches/sha2.rs similarity index 100% rename from benches/sha2.rs rename to benchmarks/benches/sha2.rs diff --git a/benches/sha3.rs b/benchmarks/benches/sha3.rs similarity index 100% rename from benches/sha3.rs rename to benchmarks/benches/sha3.rs diff --git a/benches/util.rs b/benchmarks/benches/util.rs similarity index 100% rename from benches/util.rs rename to benchmarks/benches/util.rs diff --git a/benches/x25519.rs b/benchmarks/benches/x25519.rs similarity index 97% rename from benches/x25519.rs rename to benchmarks/benches/x25519.rs index bfcff330e..0bcf91a38 100644 --- a/benches/x25519.rs +++ b/benchmarks/benches/x25519.rs @@ -17,7 +17,7 @@ fn derive(c: &mut Criterion) { (pk1, sk2) }, |(pk1, sk2)| { - let _zz = ecdh::derive(ecdh::Algorithm::X25519, &sk2, &pk1).unwrap(); + let _zz = ecdh::derive(ecdh::Algorithm::X25519, &pk1, &sk2).unwrap(); }, BatchSize::SmallInput, ) @@ -38,10 +38,9 @@ fn derive(c: &mut Criterion) { (pk1, sk2) }, |(pk1, sk2)| { - let _zz = agreement::agree_ephemeral( + let _zz: Result, ring::error::Unspecified> = agreement::agree_ephemeral( sk2, &agreement::UnparsedPublicKey::new(&agreement::X25519, pk1), - ring::error::Unspecified, |k| Ok(k.to_vec()), ) .unwrap(); diff --git a/benchmarks/src/lib.rs b/benchmarks/src/lib.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/benchmarks/src/lib.rs @@ -0,0 +1 @@ +