Skip to content

Commit c8fa260

Browse files
authored
Preliminary wNAF support (#1714)
RustCrypto/group#12 included a workaround that allows curves with a big endian `PrimeField::Repr` to be used for wNAF, by defining a separate `PrimeField::to_le_repr` method which is always guaranteed to be little endian. This may not be the permanent solution to this problem which gets upstreamed, but it unblocks work for now. This commit adds the relevant impls of `to_le_repr`, along with initial `WnafGroup` impls to `ProjectivePoint` in `k256` and `primeorder` (currently hardcoded to a fixed constant of `4` for now to unblock additional work). This also adds a `ProjectivePoint::wnaf` static method to obtain a wNAF context for that particular curve group, feature-gated on `alloc`. Finally, it adds a smoke test to `p256` which checks it against our scalar multiplication test vectors, however it does not check any other curves yet and probably should.
1 parent b557dee commit c8fa260

File tree

24 files changed

+119
-42
lines changed

24 files changed

+119
-42
lines changed

Cargo.lock

Lines changed: 11 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bignp256/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ edition = "2024"
1818
rust-version = "1.85"
1919

2020
[dependencies]
21-
elliptic-curve = { version = "0.14.0-rc.29", features = ["sec1"] }
21+
elliptic-curve = { version = "0.14.0-rc.30", features = ["sec1"] }
2222

2323
# optional dependencies
2424
belt-block = { version = "0.2.0-rc.3", optional = true }
@@ -38,7 +38,7 @@ signature = { version = "3.0.0-rc.10", optional = true }
3838

3939
[dev-dependencies]
4040
criterion = "0.7"
41-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] }
41+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] }
4242
hex-literal = "1"
4343
primeorder = { version = "0.14.0-rc.8", features = ["dev"] }
4444
proptest = "1"

bp256/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ edition = "2024"
1414
rust-version = "1.85"
1515

1616
[dependencies]
17-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] }
17+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] }
1818

1919
# optional dependencies
2020
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 }
2424

2525
[dev-dependencies]
2626
criterion = "0.7"
27-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] }
27+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] }
2828

2929
[features]
3030
default = ["pkcs8", "std"]

bp384/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ edition = "2024"
1414
rust-version = "1.85"
1515

1616
[dependencies]
17-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] }
17+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] }
1818

1919
# optional dependencies
2020
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 }
2424

2525
[dev-dependencies]
2626
criterion = "0.7"
27-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["dev"] }
27+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["dev"] }
2828

2929
[features]
3030
default = ["pkcs8", "std"]

ed448-goldilocks/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ This crate also includes signing and verifying of Ed448 signatures.
1616
"""
1717

1818
[dependencies]
19-
elliptic-curve = { version = "0.14.0-rc.29", features = ["arithmetic", "pkcs8"] }
19+
elliptic-curve = { version = "0.14.0-rc.30", features = ["arithmetic", "pkcs8"] }
2020
hash2curve = "0.14.0-rc.11"
2121
rand_core = { version = "0.10", default-features = false }
2222
sha3 = { version = "0.11", default-features = false }

hash2curve/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ rust-version = "1.85"
1515

1616
[dependencies]
1717
digest = { version = "0.11" }
18-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["arithmetic"] }
18+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["arithmetic"] }
1919

2020
[dev-dependencies]
2121
hex-literal = "1"

k256/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ rust-version = "1.85"
2020

2121
[dependencies]
2222
cpubits = "0.1"
23-
elliptic-curve = { version = "0.14.0-rc.29", default-features = false, features = ["sec1"] }
23+
elliptic-curve = { version = "0.14.0-rc.30", default-features = false, features = ["sec1"] }
2424
hash2curve = { version = "0.14.0-rc.11", optional = true }
2525

2626
# optional dependencies

k256/src/arithmetic/field.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@ use core::{
2828
};
2929
use elliptic_curve::{
3030
Generate,
31-
bigint::{Odd, U256, modular::Retrieve},
31+
bigint::{ArrayEncoding, Odd, U256, modular::Retrieve},
3232
ff::{self, Field, PrimeField},
3333
ops::Invert,
3434
rand_core::{TryCryptoRng, TryRng},
3535
subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption},
3636
zeroize::DefaultIsZeroes,
3737
};
38-
3938
#[cfg(test)]
4039
use num_bigint::{BigUint, ToBigUint};
4140

@@ -319,6 +318,10 @@ impl PrimeField for FieldElement {
319318
self.to_bytes()
320319
}
321320

321+
fn to_le_repr(&self) -> Self::Repr {
322+
self.0.normalize().to_u256().to_le_byte_array()
323+
}
324+
322325
fn is_odd(&self) -> Choice {
323326
self.is_odd()
324327
}

k256/src/arithmetic/projective.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use elliptic_curve::{
2424
};
2525

2626
#[cfg(feature = "alloc")]
27-
use alloc::vec::Vec;
27+
use {alloc::vec::Vec, elliptic_curve::group::WnafGroup};
2828

2929
#[rustfmt::skip]
3030
const ENDOMORPHISM_BETA: FieldElement = FieldElement::from_bytes_unchecked(&[
@@ -524,6 +524,15 @@ impl PrimeCurve for ProjectivePoint {
524524

525525
impl PrimeGroup for ProjectivePoint {}
526526

527+
#[cfg(feature = "alloc")]
528+
impl WnafGroup for ProjectivePoint {
529+
fn recommended_wnaf_for_num_scalars(_num_scalars: usize) -> usize {
530+
// TODO(tarcieri): provide a way for individual curves to configure this
531+
// Returns a number between 2 and 22, inclusive.
532+
4 // This seems to be a common starting point?
533+
}
534+
}
535+
527536
//
528537
// `core::ops` trait impls
529538
//

k256/src/arithmetic/scalar.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,10 @@ impl PrimeField for Scalar {
310310
self.to_bytes()
311311
}
312312

313+
fn to_le_repr(&self) -> Self::Repr {
314+
self.0.to_le_byte_array()
315+
}
316+
313317
fn is_odd(&self) -> Choice {
314318
self.0.is_odd().into()
315319
}

0 commit comments

Comments
 (0)