diff --git a/Cargo.lock b/Cargo.lock index e97d8c242a..8a76d1e996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,21 +206,21 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.15.0" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5932a7d9d28b0d2ea34c6b3779d35e3dd6f6345317c34e73438c4f1f29144151" +checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" dependencies = [ "aws-lc-sys", + "untrusted 0.7.1", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.33.0" +version = "0.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1826f2e4cfc2cd19ee53c42fbf68e2f81ec21108e0b7ecf6a71cf062137360fc" +checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" dependencies = [ - "bindgen", "cc", "cmake", "dunce", @@ -629,26 +629,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" -[[package]] -name = "bindgen" -version = "0.72.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" -dependencies = [ - "bitflags", - "cexpr", - "clang-sys", - "itertools 0.13.0", - "log", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn", -] - [[package]] name = "bit-set" version = "0.8.0" @@ -776,15 +756,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - [[package]] name = "cfg-if" version = "1.0.4" @@ -872,17 +843,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading", -] - [[package]] name = "clap" version = "4.5.51" @@ -1201,6 +1161,7 @@ version = "0.0.64" dependencies = [ "anyhow", "arbitrary", + "aws-lc-rs", "blake3", "blst", "bytes", @@ -3102,16 +3063,6 @@ dependencies = [ "cc", ] -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link 0.2.1", -] - [[package]] name = "libm" version = "0.2.15" @@ -3681,16 +3632,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn", -] - [[package]] name = "primeorder" version = "0.13.6" @@ -4145,7 +4086,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.16", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -4296,7 +4237,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ "ring", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -4308,7 +4249,7 @@ dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -4366,7 +4307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ "ring", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -5290,6 +5231,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" diff --git a/Cargo.toml b/Cargo.toml index 5f4d0b35f9..8964da6e6a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -66,6 +66,7 @@ anyhow = { version = "1.0.99", default-features = false } arbitrary = "1.4.1" async-lock = "3.4.0" aws-config = "1.8.10" +aws-lc-rs = "1.15.2" aws-sdk-ec2 = "1.187.0" axum = "0.8.1" blake3 = { version = "1.8.2", default-features = false } diff --git a/cryptography/Cargo.toml b/cryptography/Cargo.toml index 6875c0c5a3..a6a53b19f9 100644 --- a/cryptography/Cargo.toml +++ b/cryptography/Cargo.toml @@ -36,6 +36,10 @@ thiserror.workspace = true x25519-dalek = { workspace = true, features = ["zeroize"] } zeroize = { workspace = true, features = ["zeroize_derive"] } +[target.'cfg(any(target_arch = "x86_64", target_arch = "aarch64"))'.dependencies] +# aws-lc-rs provides optimized P-256 verification on x86_64 and aarch64. +aws-lc-rs.workspace = true + [target.'cfg(target_arch = "wasm32")'.dependencies.getrandom] # Enable "js" feature when WASM is target version = "0.2.15" diff --git a/cryptography/src/secp256r1/common.rs b/cryptography/src/secp256r1/common.rs index 8502e649df..b13233f34f 100644 --- a/cryptography/src/secp256r1/common.rs +++ b/cryptography/src/secp256r1/common.rs @@ -159,6 +159,14 @@ impl PublicKeyInner { pub fn from_private_key(private_key: &PrivateKeyInner) -> Self { Self::new(private_key.key.verifying_key().to_owned()) } + + /// aws-lc-rs can decompress keys, but since we already have the key parsed + /// in memory, extracting the uncompressed form directly is faster. + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] + pub fn to_uncompressed(&self) -> [u8; 65] { + let encoded = self.key.to_encoded_point(false); + encoded.as_bytes().try_into().unwrap() + } } impl Write for PublicKeyInner { diff --git a/cryptography/src/secp256r1/standard.rs b/cryptography/src/secp256r1/standard.rs index b0804731ef..8b312dede8 100644 --- a/cryptography/src/secp256r1/standard.rs +++ b/cryptography/src/secp256r1/standard.rs @@ -9,6 +9,8 @@ use super::common::{ impl_private_key_wrapper, impl_public_key_wrapper, PrivateKeyInner, PublicKeyInner, CURVE_NAME, PRIVATE_KEY_LENGTH, PUBLIC_KEY_LENGTH, }; +#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] +use aws_lc_rs::signature::{UnparsedPublicKey, ECDSA_P256_SHA256_FIXED}; use bytes::{Buf, BufMut}; use commonware_codec::{Error as CodecError, FixedSize, Read, ReadExt, Write}; use commonware_utils::{hex, union_unique, Array, Span}; @@ -17,10 +19,9 @@ use core::{ hash::{Hash, Hasher}, ops::Deref, }; -use p256::{ - ecdsa::signature::{Signer, Verifier}, - elliptic_curve::scalar::IsHigh, -}; +#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] +use p256::ecdsa::signature::Verifier; +use p256::{ecdsa::signature::Signer, elliptic_curve::scalar::IsHigh}; const SIGNATURE_LENGTH: usize = 64; // R || S @@ -77,6 +78,7 @@ impl crate::Verifier for PublicKey { } impl PublicKey { + #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))] #[inline(always)] fn verify_inner(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Signature) -> bool { let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| { @@ -84,6 +86,17 @@ impl PublicKey { }); self.0.key.verify(&payload, &sig.signature).is_ok() } + + #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))] + #[inline(always)] + fn verify_inner(&self, namespace: Option<&[u8]>, msg: &[u8], sig: &Signature) -> bool { + let payload = namespace.map_or(Cow::Borrowed(msg), |namespace| { + Cow::Owned(union_unique(namespace, msg)) + }); + let uncompressed = self.0.to_uncompressed(); + let public_key = UnparsedPublicKey::new(&ECDSA_P256_SHA256_FIXED, &uncompressed); + public_key.verify(&payload, &sig.raw).is_ok() + } } /// Secp256r1 Signature.