Skip to content

Commit

Permalink
perf: add optional support for keccak-asm (#466)
Browse files Browse the repository at this point in the history
* perf: add optional support for keccak-asm

* fmt

* fix: unmiri

* chore: add bench

* chore: clippy

* chore: re-enable bench

* chore: clippy

* chore: re-exclude tests

* chore: simpler casts
  • Loading branch information
DaniPopes authored Dec 27, 2023
1 parent 6dd9112 commit 79dc9bc
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 25 deletions.
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ authors = ["Alloy Contributors"]
license = "MIT OR Apache-2.0"
homepage = "https://github.com/alloy-rs/core"
repository = "https://github.com/alloy-rs/core"
exclude = ["benches/", "tests/"]
exclude = ["tests"]

[workspace.metadata.docs.rs]
all-features = true
Expand Down Expand Up @@ -46,6 +46,9 @@ strum = { version = "0.25", features = ["derive"] }
num_enum = "0.7"
thiserror = "1.0"

keccak-asm = { version = "0.1.0", default-features = false }
tiny-keccak = "2.0"

# misc
alloy-rlp = { version = "0.3", default-features = false }
alloy-rlp-derive = { version = "0.3", default-features = false }
Expand All @@ -65,6 +68,5 @@ proptest-derive = "0.4"
rand = { version = "0.8", default-features = false }
ruint = { version = "1.11.1", default-features = false, features = ["alloc"] }
ruint-macro = { version = "1", default-features = false }
tiny-keccak = "2.0"
winnow = { version = "0.5.19", default-features = false, features = ["alloc"] }
postgres-types = "0.2.6"
7 changes: 5 additions & 2 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ hex.workspace = true
itoa.workspace = true
ruint.workspace = true
tiny-keccak = { workspace = true, features = ["keccak"] }
keccak-asm = { workspace = true, optional = true }

# macros
derive_more.workspace = true
Expand Down Expand Up @@ -65,13 +66,15 @@ std = [
"hex/std",
"ruint/std",
"alloy-rlp?/std",
"keccak-asm?/std",
"proptest?/std",
"rand?/std",
"serde?/std",
]
postgres = ["dep:postgres-types", "std", "ruint/postgres"]
tiny-keccak = []
native-keccak = []
asm-keccak = ["dep:keccak-asm"]
getrandom = ["dep:getrandom"]
rand = ["dep:rand", "getrandom", "ruint/rand"]
rlp = ["dep:alloy-rlp", "ruint/alloy-rlp"]
Expand All @@ -93,7 +96,7 @@ arbitrary = [
hex-compat = ["hex/hex"]

[[bench]]
name = "address"
path = "benches/address.rs"
name = "primitives"
path = "benches/primitives.rs"
harness = false
required-features = ["rand"]
18 changes: 0 additions & 18 deletions crates/primitives/benches/address.rs

This file was deleted.

28 changes: 28 additions & 0 deletions crates/primitives/benches/primitives.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use alloy_primitives::{keccak256, Address, B256};
use criterion::{criterion_group, criterion_main, Criterion};
use std::hint::black_box;

fn primitives(c: &mut Criterion) {
let mut g = c.benchmark_group("primitives");
g.bench_function("address/checksum", |b| {
let address = Address::random();
let out = &mut [0u8; 42];
b.iter(|| {
let x = address.to_checksum_raw(black_box(out), None);
black_box(x);
})
});
g.bench_function("keccak256/32", |b| {
let mut out = B256::random();
b.iter(|| {
for _ in 0..10 {
out = keccak256(out);
}
black_box(&out);
});
});
g.finish();
}

criterion_group!(benches, primitives);
criterion_main!(benches);
4 changes: 4 additions & 0 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ pub use {
tiny_keccak::{self, Hasher, Keccak},
};

#[cfg(feature = "asm-keccak")]
#[doc(no_inline)]
pub use keccak_asm::{self, digest, Keccak256};

/// Re-export of [`ruint::uint!`] for convenience. Note that users of this macro
/// must also add [`ruint`] to their `Cargo.toml` as a dependency.
#[doc(inline)]
Expand Down
13 changes: 10 additions & 3 deletions crates/primitives/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub fn keccak256<T: AsRef<[u8]>>(bytes: T) -> B256 {
let mut output = MaybeUninit::<B256>::uninit();

cfg_if::cfg_if! {
if #[cfg(all(feature = "native-keccak", not(feature = "tiny-keccak")))] {
if #[cfg(all(feature = "native-keccak", not(feature = "tiny-keccak"), not(miri)))] {
#[link(wasm_import_module = "vm_hooks")]
extern "C" {
/// When targeting VMs with native keccak hooks, the `native-keccak` feature
Expand All @@ -83,14 +83,21 @@ pub fn keccak256<T: AsRef<[u8]>>(bytes: T) -> B256 {
}

// SAFETY: The output is 32-bytes, and the input comes from a slice.
unsafe { native_keccak256(bytes.as_ptr(), bytes.len(), output.as_mut_ptr().cast()) };
unsafe { native_keccak256(bytes.as_ptr(), bytes.len(), output.as_mut_ptr().cast::<u8>()) };
} else if #[cfg(all(feature = "asm-keccak", not(miri)))] {
use keccak_asm::{digest::Digest, Keccak256};

let mut hasher = Keccak256::new();
hasher.update(bytes);
// SAFETY: Never reads from `output`.
hasher.finalize_into(unsafe { (&mut (*output.as_mut_ptr()).0).into() });
} else {
use tiny_keccak::{Hasher, Keccak};

let mut hasher = Keccak::v256();
hasher.update(bytes);
// SAFETY: Never reads from `output`.
hasher.finalize(unsafe { (*output.as_mut_ptr()).as_mut_slice() });
hasher.finalize(unsafe { &mut (*output.as_mut_ptr()).0 });
}
}

Expand Down

0 comments on commit 79dc9bc

Please sign in to comment.