diff --git a/Cargo.lock b/Cargo.lock index ced2b26a1..533511165 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,7 +215,7 @@ checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.3.0", + "cpufeatures", "rand_core 0.10.0", ] @@ -309,15 +309,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" version = "0.3.0" @@ -516,9 +507,9 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.14.0-rc.29" +version = "0.14.0-rc.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84043d573efd4ac9d2d125817979a379204bf7e328b25a4a30487e8d100e618" +checksum = "7d7a0bfd012613a7bcfe02cbfccf2b846e9ef9e1bccb641c48d461253cfb034d" dependencies = [ "base16ct", "crypto-bigint", @@ -775,7 +766,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", + "cpufeatures", ] [[package]] @@ -1210,9 +1201,9 @@ dependencies = [ [[package]] name = "rustcrypto-ff" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5db129183b2c139d7d87d08be57cba626c715789db17aec65c8866bfd767d1f" +checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" dependencies = [ "bitvec", "rand_core 0.10.0", @@ -1237,9 +1228,9 @@ dependencies = [ [[package]] name = "rustcrypto-group" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c4b1463f274a3ff6fb2f44da43e576cb9424367bd96f185ead87b52fe00523" +checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" dependencies = [ "rand_core 0.10.0", "rustcrypto-ff", @@ -1381,12 +1372,12 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-rc.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest", ] diff --git a/bignp256/Cargo.toml b/bignp256/Cargo.toml index 2b78e90f0..399417324 100644 --- a/bignp256/Cargo.toml +++ b/bignp256/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", features = ["sec1"] } # optional dependencies belt-block = { version = "0.2.0-rc.3", optional = true } @@ -38,7 +38,7 @@ signature = { version = "3.0.0-rc.10", optional = true } [dev-dependencies] criterion = "0.7" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] } hex-literal = "1" primeorder = { version = "0.14.0-rc.8", features = ["dev"] } proptest = "1" diff --git a/bp256/Cargo.toml b/bp256/Cargo.toml index 5edf4575a..9b949d76b 100644 --- a/bp256/Cargo.toml +++ b/bp256/Cargo.toml @@ -14,7 +14,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa = { version = "0.17.0-rc.16", optional = true, default-features = false, features = ["der"] } @@ -24,7 +24,7 @@ sha2 = { version = "0.11", optional = true, default-features = false } [dev-dependencies] criterion = "0.7" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] } [features] default = ["pkcs8", "std"] diff --git a/bp384/Cargo.toml b/bp384/Cargo.toml index df5de52c3..6fe5840ac 100644 --- a/bp384/Cargo.toml +++ b/bp384/Cargo.toml @@ -14,7 +14,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa = { version = "0.17.0-rc.16", optional = true, default-features = false, features = ["der"] } @@ -24,7 +24,7 @@ sha2 = { version = "0.11", optional = true, default-features = false } [dev-dependencies] criterion = "0.7" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] } [features] default = ["pkcs8", "std"] diff --git a/ed448-goldilocks/Cargo.toml b/ed448-goldilocks/Cargo.toml index b03d5906e..76a9d6bb5 100644 --- a/ed448-goldilocks/Cargo.toml +++ b/ed448-goldilocks/Cargo.toml @@ -16,7 +16,7 @@ This crate also includes signing and verifying of Ed448 signatures. """ [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", features = ["arithmetic", "pkcs8"] } +elliptic-curve = { version = "0.14.0-rc.30", features = ["arithmetic", "pkcs8"] } hash2curve = "0.14.0-rc.11" rand_core = { version = "0.10", default-features = false } sha3 = { version = "0.11", default-features = false } diff --git a/hash2curve/Cargo.toml b/hash2curve/Cargo.toml index 8c8a73237..cb597e0e9 100644 --- a/hash2curve/Cargo.toml +++ b/hash2curve/Cargo.toml @@ -15,7 +15,7 @@ rust-version = "1.85" [dependencies] digest = { version = "0.11" } -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["arithmetic"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["arithmetic"] } [dev-dependencies] hex-literal = "1" diff --git a/k256/Cargo.toml b/k256/Cargo.toml index 8179581ca..56ad8e98a 100644 --- a/k256/Cargo.toml +++ b/k256/Cargo.toml @@ -20,7 +20,7 @@ rust-version = "1.85" [dependencies] cpubits = "0.1" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } hash2curve = { version = "0.14.0-rc.11", optional = true } # optional dependencies diff --git a/k256/src/arithmetic/field.rs b/k256/src/arithmetic/field.rs index 0f073527a..e11cf5c17 100644 --- a/k256/src/arithmetic/field.rs +++ b/k256/src/arithmetic/field.rs @@ -28,14 +28,13 @@ use core::{ }; use elliptic_curve::{ Generate, - bigint::{Odd, U256, modular::Retrieve}, + bigint::{ArrayEncoding, Odd, U256, modular::Retrieve}, ff::{self, Field, PrimeField}, ops::Invert, rand_core::{TryCryptoRng, TryRng}, subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption}, zeroize::DefaultIsZeroes, }; - #[cfg(test)] use num_bigint::{BigUint, ToBigUint}; @@ -319,6 +318,10 @@ impl PrimeField for FieldElement { self.to_bytes() } + fn to_le_repr(&self) -> Self::Repr { + self.0.normalize().to_u256().to_le_byte_array() + } + fn is_odd(&self) -> Choice { self.is_odd() } diff --git a/k256/src/arithmetic/projective.rs b/k256/src/arithmetic/projective.rs index b58a5eb3d..775367b84 100644 --- a/k256/src/arithmetic/projective.rs +++ b/k256/src/arithmetic/projective.rs @@ -24,7 +24,7 @@ use elliptic_curve::{ }; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use {alloc::vec::Vec, elliptic_curve::group::WnafGroup}; #[rustfmt::skip] const ENDOMORPHISM_BETA: FieldElement = FieldElement::from_bytes_unchecked(&[ @@ -524,6 +524,15 @@ impl PrimeCurve for ProjectivePoint { impl PrimeGroup for ProjectivePoint {} +#[cfg(feature = "alloc")] +impl WnafGroup for ProjectivePoint { + fn recommended_wnaf_for_num_scalars(_num_scalars: usize) -> usize { + // TODO(tarcieri): provide a way for individual curves to configure this + // Returns a number between 2 and 22, inclusive. + 4 // This seems to be a common starting point? + } +} + // // `core::ops` trait impls // diff --git a/k256/src/arithmetic/scalar.rs b/k256/src/arithmetic/scalar.rs index 1c92f81bf..df5ce6c98 100644 --- a/k256/src/arithmetic/scalar.rs +++ b/k256/src/arithmetic/scalar.rs @@ -310,6 +310,10 @@ impl PrimeField for Scalar { self.to_bytes() } + fn to_le_repr(&self) -> Self::Repr { + self.0.to_le_byte_array() + } + fn is_odd(&self) -> Choice { self.0.is_odd().into() } diff --git a/p192/Cargo.toml b/p192/Cargo.toml index 9b0477b47..86292e2f7 100644 --- a/p192/Cargo.toml +++ b/p192/Cargo.toml @@ -17,7 +17,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa-core = { version = "0.17.0-rc.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] } diff --git a/p224/Cargo.toml b/p224/Cargo.toml index da8ae519d..49afc9cd3 100644 --- a/p224/Cargo.toml +++ b/p224/Cargo.toml @@ -17,7 +17,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa-core = { version = "0.17.0-rc.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] } diff --git a/p256/Cargo.toml b/p256/Cargo.toml index c2001dfb3..69428ed04 100644 --- a/p256/Cargo.toml +++ b/p256/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa-core = { version = "0.17.0-rc.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] } diff --git a/p256/src/arithmetic/scalar.rs b/p256/src/arithmetic/scalar.rs index 8a5965104..01dbf7ca5 100644 --- a/p256/src/arithmetic/scalar.rs +++ b/p256/src/arithmetic/scalar.rs @@ -305,6 +305,10 @@ impl PrimeField for Scalar { self.to_bytes() } + fn to_le_repr(&self) -> FieldBytes { + self.0.to_le_byte_array() + } + fn is_odd(&self) -> Choice { self.0.is_odd().into() } diff --git a/p256/tests/projective.rs b/p256/tests/projective.rs index 5be8291eb..24e1cae16 100644 --- a/p256/tests/projective.rs +++ b/p256/tests/projective.rs @@ -18,6 +18,9 @@ use p256::{ use primeorder::test_projective_arithmetic; use proptest::{prelude::any, prop_compose, proptest}; +#[cfg(feature = "alloc")] +use elliptic_curve::point::AffineCoordinates; + test_projective_arithmetic!( AffinePoint, ProjectivePoint, @@ -32,6 +35,21 @@ fn projective_identity_to_bytes() { assert_eq!([0; 33], ProjectivePoint::IDENTITY.to_bytes().as_slice()); } +#[cfg(feature = "alloc")] +#[test] +fn wnaf() { + for (k, coords) in ADD_TEST_VECTORS.iter().enumerate() { + let scalar = Scalar::from(k as u64 + 1); + let mut wnaf = ProjectivePoint::wnaf(); + let mut wnaf_base = wnaf.base(ProjectivePoint::GENERATOR, 1); + let p = wnaf_base.scalar(&scalar).to_affine(); + + let (x, y) = (p.x(), p.y()); + assert_eq!(x.0, coords.0); + assert_eq!(y.0, coords.1); + } +} + prop_compose! { fn non_identity()(bytes in any::<[u8; 32]>()) -> NonIdentity { NonIdentity::mul_by_generator(&NonZeroScalar::reduce_nonzero(&FieldBytes::from(bytes))) diff --git a/p384/Cargo.toml b/p384/Cargo.toml index 7f2ac9efa..039892cb7 100644 --- a/p384/Cargo.toml +++ b/p384/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa-core = { version = "0.17.0-rc.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] } diff --git a/p521/Cargo.toml b/p521/Cargo.toml index 374026df3..6318aecd7 100644 --- a/p521/Cargo.toml +++ b/p521/Cargo.toml @@ -18,7 +18,7 @@ rust-version = "1.85" [dependencies] base16ct = "1" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } # optional dependencies ecdsa-core = { version = "0.17.0-rc.16", package = "ecdsa", optional = true, default-features = false, features = ["der"] } diff --git a/p521/src/arithmetic/field.rs b/p521/src/arithmetic/field.rs index 47f78a176..3db5ae880 100644 --- a/p521/src/arithmetic/field.rs +++ b/p521/src/arithmetic/field.rs @@ -560,6 +560,13 @@ impl PrimeField for FieldElement { self.to_bytes() } + #[inline] + fn to_le_repr(&self) -> FieldBytes { + let mut ret = [0u8; 66]; + fiat_p521_to_bytes(&mut ret, &self.0); // natively little-endian + ret.into() + } + #[inline] fn is_odd(&self) -> Choice { self.is_odd() diff --git a/primefield/Cargo.toml b/primefield/Cargo.toml index 4f1ebee66..91724170a 100644 --- a/primefield/Cargo.toml +++ b/primefield/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.85" [dependencies] bigint = { version = "0.7.1", package = "crypto-bigint", default-features = false, features = ["rand_core", "hybrid-array", "subtle"] } common = { package = "crypto-common", version = "0.2", features = ["rand_core"] } -ff = { version = "0.14.0-rc.0", package = "rustcrypto-ff", default-features = false } +ff = { version = "0.14.0-rc.1", package = "rustcrypto-ff", default-features = false } subtle = { version = "2.6", default-features = false, features = ["const-generics"] } rand_core = { version = "0.10", default-features = false } zeroize = { version = "1.7", default-features = false } diff --git a/primefield/src/macros.rs b/primefield/src/macros.rs index 7677a346c..9b895b62d 100644 --- a/primefield/src/macros.rs +++ b/primefield/src/macros.rs @@ -346,6 +346,11 @@ macro_rules! monty_field_element { self.0.to_repr() } + #[inline] + fn to_le_repr(&self) -> Self::Repr { + self.0.to_le_repr() + } + #[inline] fn is_odd(&self) -> $crate::subtle::Choice { self.0.is_odd() diff --git a/primefield/src/monty.rs b/primefield/src/monty.rs index 6d3b0bb7d..d1c91823c 100644 --- a/primefield/src/monty.rs +++ b/primefield/src/monty.rs @@ -475,6 +475,17 @@ where self.to_bytes() } + fn to_le_repr(&self) -> Self::Repr { + match MOD::BYTE_ORDER { + ByteOrder::BigEndian => { + let mut bytes = self.to_bytes(); + bytes.reverse(); + bytes + } + ByteOrder::LittleEndian => self.to_bytes(), + } + } + fn is_odd(&self) -> Choice { self.is_odd() } diff --git a/primeorder/Cargo.toml b/primeorder/Cargo.toml index f9a04ec0f..f07b5f3a3 100644 --- a/primeorder/Cargo.toml +++ b/primeorder/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["arithmetic", "sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["arithmetic", "sec1"] } # optional dependencies serdect = { version = "0.4", optional = true, default-features = false } diff --git a/primeorder/src/projective.rs b/primeorder/src/projective.rs index 2e402b983..0fc940c07 100644 --- a/primeorder/src/projective.rs +++ b/primeorder/src/projective.rs @@ -31,7 +31,10 @@ use elliptic_curve::{ }; #[cfg(feature = "alloc")] -use alloc::vec::Vec; +use { + alloc::vec::Vec, + elliptic_curve::group::{Wnaf, WnafGroup}, +}; #[cfg(feature = "serde")] use serdect::serde::{Deserialize, Serialize, de, ser}; @@ -116,6 +119,15 @@ where lincomb(array::from_mut(&mut k), array::from_mut(&mut pc)) } + + /// Obtain a wNAF context for this group. + #[cfg(feature = "alloc")] + pub fn wnaf() -> Wnaf<(), Vec, Vec> + where + FieldBytes: Copy, + { + Wnaf::new() + } } impl ConditionallySelectable for ProjectivePoint @@ -601,6 +613,19 @@ where } } +#[cfg(feature = "alloc")] +impl WnafGroup for ProjectivePoint +where + C: PrimeCurveParams, + FieldBytes: Copy, +{ + fn recommended_wnaf_for_num_scalars(_num_scalars: usize) -> usize { + // TODO(tarcieri): provide a way for individual curves to configure this + // Returns a number between 2 and 22, inclusive. + 4 // This seems to be a common starting point? + } +} + // // `core::ops` trait impls // diff --git a/sm2/Cargo.toml b/sm2/Cargo.toml index 5faa76254..8cc448c34 100644 --- a/sm2/Cargo.toml +++ b/sm2/Cargo.toml @@ -18,7 +18,7 @@ edition = "2024" rust-version = "1.85" [dependencies] -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] } fiat-crypto = { version = "0.3", default-features = false } rand_core = { version = "0.10", default-features = false } @@ -33,7 +33,7 @@ sm3 = { version = "0.5", optional = true, default-features = false } [dev-dependencies] criterion = "0.7" -elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] } +elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] } hex-literal = "1" proptest = "1"