Skip to content

Commit 2af0212

Browse files
committed
k256: impl ReduceNonZero<U512> for Scalar
Provides an impl of the `ReduceNonZero` trait added in #827, which provides a reduction from a 512-bit (64-byte) input, i.e. a "wide" reduction from an integer twice the size of the curve's order, to a `Scalar` which is guaranteed to be non-zero. Based on @fjarri's work in #432
1 parent 0583d87 commit 2af0212

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

Cargo.lock

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

k256/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ rust-version = "1.56"
1919

2020
[dependencies]
2121
cfg-if = "1.0"
22-
elliptic-curve = { version = "0.11", default-features = false, features = ["hazmat", "sec1"] }
22+
elliptic-curve = { version = "0.11.3", default-features = false, features = ["hazmat", "sec1"] }
2323
sec1 = { version = "0.2", default-features = false }
2424

2525
# optional dependencies

k256/src/arithmetic/scalar.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use elliptic_curve::{
1212
bigint::{nlimbs, prelude::*, Limb, LimbUInt, U256, U512},
1313
generic_array::arr,
1414
group::ff::{Field, PrimeField},
15-
ops::Reduce,
15+
ops::{Reduce, ReduceNonZero},
1616
rand_core::{CryptoRng, RngCore},
1717
subtle::{
1818
Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
@@ -581,6 +581,12 @@ impl Reduce<U512> for Scalar {
581581
}
582582
}
583583

584+
impl ReduceNonZero<U512> for Scalar {
585+
fn from_uint_reduced_nonzero(w: U512) -> Self {
586+
WideScalar(w).reduce_nonzero()
587+
}
588+
}
589+
584590
#[cfg(feature = "bits")]
585591
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
586592
impl From<&Scalar> for ScalarBits {
@@ -628,7 +634,10 @@ mod tests {
628634
use super::Scalar;
629635
use crate::arithmetic::dev::{biguint_to_bytes, bytes_to_biguint};
630636
use elliptic_curve::{
637+
bigint::U512,
631638
ff::{Field, PrimeField},
639+
generic_array::GenericArray,
640+
ops::Reduce,
632641
IsHigh,
633642
};
634643
use num_bigint::{BigUint, ToBigUint};
@@ -745,15 +754,14 @@ mod tests {
745754
assert_eq!((a - &a).is_zero().unwrap_u8(), 1);
746755
}
747756

748-
// TODO(tarcieri): test reduce impls
749-
// #[test]
750-
// fn from_wide_bytes_reduced() {
751-
// let m = Scalar::modulus_as_biguint();
752-
// let b = [0xffu8; 64];
753-
// let s = Scalar::from_wide_bytes_reduced(&b);
754-
// let s_bu = s.to_biguint().unwrap();
755-
// assert!(s_bu < m);
756-
// }
757+
#[test]
758+
fn from_wide_bytes_reduced() {
759+
let m = Scalar::modulus_as_biguint();
760+
let b = [0xffu8; 64];
761+
let s = <Scalar as Reduce<U512>>::from_be_bytes_reduced(GenericArray::clone_from_slice(&b));
762+
let s_bu = s.to_biguint().unwrap();
763+
assert!(s_bu < m);
764+
}
757765

758766
prop_compose! {
759767
fn scalar()(bytes in any::<[u8; 32]>()) -> Scalar {
@@ -854,16 +862,15 @@ mod tests {
854862
assert_eq!((&inv_bi * &a_bi) % &m, 1.to_biguint().unwrap());
855863
}
856864

857-
// TODO(tarcieri): test reduce impls
858-
// #[test]
859-
// fn fuzzy_from_wide_bytes_reduced(bytes_hi in any::<[u8; 32]>(), bytes_lo in any::<[u8; 32]>()) {
860-
// let m = Scalar::modulus_as_biguint();
861-
// let mut bytes = [0u8; 64];
862-
// bytes[0..32].clone_from_slice(&bytes_hi);
863-
// bytes[32..64].clone_from_slice(&bytes_lo);
864-
// let s = Scalar::from_wide_bytes_reduced(&bytes);
865-
// let s_bu = s.to_biguint().unwrap();
866-
// assert!(s_bu < m);
867-
// }
865+
#[test]
866+
fn fuzzy_from_wide_bytes_reduced(bytes_hi in any::<[u8; 32]>(), bytes_lo in any::<[u8; 32]>()) {
867+
let m = Scalar::modulus_as_biguint();
868+
let mut bytes = [0u8; 64];
869+
bytes[0..32].clone_from_slice(&bytes_hi);
870+
bytes[32..64].clone_from_slice(&bytes_lo);
871+
let s = <Scalar as Reduce<U512>>::from_be_bytes_reduced(GenericArray::clone_from_slice(&bytes));
872+
let s_bu = s.to_biguint().unwrap();
873+
assert!(s_bu < m);
874+
}
868875
}
869876
}

k256/src/arithmetic/scalar/wide32.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -404,11 +404,8 @@ impl WideScalar {
404404
self.reduce_impl(false)
405405
}
406406

407-
// TODO(tarcieri): use this
408-
#[allow(dead_code)]
409-
pub(super) fn reduce_nonzero(&self) -> NonZeroScalar {
410-
let s = self.reduce_impl(true);
411-
NonZeroScalar::new(s + Scalar::one()).unwrap()
407+
pub(super) fn reduce_nonzero(&self) -> Scalar {
408+
self.reduce_impl(true) + Scalar::ONE
412409
}
413410
}
414411

k256/src/arithmetic/scalar/wide64.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
//! Wide scalar (64-bit limbs)
22
33
use super::{Scalar, MODULUS};
4-
use crate::{NonZeroScalar, ORDER};
4+
use crate::ORDER;
55
use elliptic_curve::{
66
bigint::{Limb, U256, U512},
7-
group::ff::Field,
87
subtle::{Choice, ConditionallySelectable},
98
};
109

@@ -212,11 +211,8 @@ impl WideScalar {
212211
self.reduce_impl(false)
213212
}
214213

215-
// TODO(tarcieri): use this
216-
#[allow(dead_code)]
217-
pub(super) fn reduce_nonzero(&self) -> NonZeroScalar {
218-
let s = self.reduce_impl(true);
219-
NonZeroScalar::new(s + Scalar::one()).unwrap()
214+
pub(super) fn reduce_nonzero(&self) -> Scalar {
215+
self.reduce_impl(true) + Scalar::ONE
220216
}
221217
}
222218

0 commit comments

Comments
 (0)