Skip to content

Commit

Permalink
k256: impl ReduceNonZero<U512> for Scalar
Browse files Browse the repository at this point in the history
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
  • Loading branch information
tarcieri committed Dec 3, 2021
1 parent 0583d87 commit 69929df
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 31 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion k256/Cargo.toml
Expand Up @@ -19,7 +19,7 @@ rust-version = "1.56"

[dependencies]
cfg-if = "1.0"
elliptic-curve = { version = "0.11", default-features = false, features = ["hazmat", "sec1"] }
elliptic-curve = { version = "0.11.3", default-features = false, features = ["hazmat", "sec1"] }
sec1 = { version = "0.2", default-features = false }

# optional dependencies
Expand Down
49 changes: 28 additions & 21 deletions k256/src/arithmetic/scalar.rs
Expand Up @@ -12,7 +12,7 @@ use elliptic_curve::{
bigint::{nlimbs, prelude::*, Limb, LimbUInt, U256, U512},
generic_array::arr,
group::ff::{Field, PrimeField},
ops::Reduce,
ops::{Reduce, ReduceNonZero},
rand_core::{CryptoRng, RngCore},
subtle::{
Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
Expand Down Expand Up @@ -581,6 +581,12 @@ impl Reduce<U512> for Scalar {
}
}

impl ReduceNonZero<U512> for Scalar {
fn from_uint_reduced_nonzero(w: U512) -> Self {
WideScalar(w).reduce_nonzero()
}
}

#[cfg(feature = "bits")]
#[cfg_attr(docsrs, doc(cfg(feature = "bits")))]
impl From<&Scalar> for ScalarBits {
Expand Down Expand Up @@ -628,7 +634,10 @@ mod tests {
use super::Scalar;
use crate::arithmetic::dev::{biguint_to_bytes, bytes_to_biguint};
use elliptic_curve::{
bigint::U512,
ff::{Field, PrimeField},
generic_array::GenericArray,
ops::Reduce,
IsHigh,
};
use num_bigint::{BigUint, ToBigUint};
Expand Down Expand Up @@ -745,15 +754,14 @@ mod tests {
assert_eq!((a - &a).is_zero().unwrap_u8(), 1);
}

// TODO(tarcieri): test reduce impls
// #[test]
// fn from_wide_bytes_reduced() {
// let m = Scalar::modulus_as_biguint();
// let b = [0xffu8; 64];
// let s = Scalar::from_wide_bytes_reduced(&b);
// let s_bu = s.to_biguint().unwrap();
// assert!(s_bu < m);
// }
#[test]
fn from_wide_bytes_reduced() {
let m = Scalar::modulus_as_biguint();
let b = [0xffu8; 64];
let s = <Scalar as Reduce<U512>>::from_be_bytes_reduced(GenericArray::clone_from_slice(&b));
let s_bu = s.to_biguint().unwrap();
assert!(s_bu < m);
}

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

// TODO(tarcieri): test reduce impls
// #[test]
// fn fuzzy_from_wide_bytes_reduced(bytes_hi in any::<[u8; 32]>(), bytes_lo in any::<[u8; 32]>()) {
// let m = Scalar::modulus_as_biguint();
// let mut bytes = [0u8; 64];
// bytes[0..32].clone_from_slice(&bytes_hi);
// bytes[32..64].clone_from_slice(&bytes_lo);
// let s = Scalar::from_wide_bytes_reduced(&bytes);
// let s_bu = s.to_biguint().unwrap();
// assert!(s_bu < m);
// }
#[test]
fn fuzzy_from_wide_bytes_reduced(bytes_hi in any::<[u8; 32]>(), bytes_lo in any::<[u8; 32]>()) {
let m = Scalar::modulus_as_biguint();
let mut bytes = [0u8; 64];
bytes[0..32].clone_from_slice(&bytes_hi);
bytes[32..64].clone_from_slice(&bytes_lo);
let s = <Scalar as Reduce<U512>>::from_be_bytes_reduced(GenericArray::clone_from_slice(&bytes));
let s_bu = s.to_biguint().unwrap();
assert!(s_bu < m);
}
}
}
10 changes: 3 additions & 7 deletions k256/src/arithmetic/scalar/wide64.rs
@@ -1,10 +1,9 @@
//! Wide scalar (64-bit limbs)

use super::{Scalar, MODULUS};
use crate::{NonZeroScalar, ORDER};
use crate::ORDER;
use elliptic_curve::{
bigint::{Limb, U256, U512},
group::ff::Field,
subtle::{Choice, ConditionallySelectable},
};

Expand Down Expand Up @@ -212,11 +211,8 @@ impl WideScalar {
self.reduce_impl(false)
}

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

Expand Down

0 comments on commit 69929df

Please sign in to comment.