Skip to content

Commit f6ac4b0

Browse files
authored
elliptic-curve: add ReduceNonZero trait (#827)
Adds a trait similar to `Reduce`, but where the output of the reduction is ensured to be non-zero. Also impls `Reduce` and `ReduceNonZero` for `NonZeroScalar`. This means that end users need only concern themselves with `Reduce` as they can use `NonZeroScalar::<C>::from_uint_reduced` instead of the more cumbersome `Scalar::<C>::from_uint_reduced_non_zero`. Related: RustCrypto/elliptic-curves#432
1 parent afe0b79 commit f6ac4b0

File tree

2 files changed

+37
-1
lines changed

2 files changed

+37
-1
lines changed

elliptic-curve/src/ops.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,13 @@ pub trait Reduce<UInt: Integer + ArrayEncoding>: Sized {
4040
Self::from_uint_reduced(UInt::from_le_byte_array(bytes))
4141
}
4242
}
43+
44+
/// Modular reduction to a non-zero output.
45+
///
46+
/// This trait is primarily intended for use by curve implementations.
47+
///
48+
/// End users can use the `Reduce` impl on `NonZeroScalar` instead.
49+
pub trait ReduceNonZero<UInt: Integer + ArrayEncoding>: Sized {
50+
/// Perform a modular reduction, returning a field element.
51+
fn from_uint_reduced_non_zero(n: UInt) -> Self;
52+
}

elliptic-curve/src/scalar/non_zero.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{
44
bigint::Encoding as _,
55
hex,
6-
ops::Invert,
6+
ops::{Invert, Reduce, ReduceNonZero},
77
rand_core::{CryptoRng, RngCore},
88
Curve, Error, FieldBytes, IsHigh, Result, Scalar, ScalarArithmetic, ScalarCore, SecretKey,
99
};
@@ -12,6 +12,7 @@ use core::{
1212
ops::{Deref, Neg},
1313
str,
1414
};
15+
use crypto_bigint::{ArrayEncoding, Integer};
1516
use ff::{Field, PrimeField};
1617
use generic_array::GenericArray;
1718
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
@@ -198,6 +199,31 @@ where
198199
}
199200
}
200201

202+
/// Note: implementation is the same as `ReduceNonZero`
203+
impl<C, I> Reduce<I> for NonZeroScalar<C>
204+
where
205+
C: Curve + ScalarArithmetic,
206+
I: Integer + ArrayEncoding,
207+
Scalar<C>: ReduceNonZero<I>,
208+
{
209+
fn from_uint_reduced(n: I) -> Self {
210+
Self::from_uint_reduced_non_zero(n)
211+
}
212+
}
213+
214+
impl<C, I> ReduceNonZero<I> for NonZeroScalar<C>
215+
where
216+
C: Curve + ScalarArithmetic,
217+
I: Integer + ArrayEncoding,
218+
Scalar<C>: ReduceNonZero<I>,
219+
{
220+
fn from_uint_reduced_non_zero(n: I) -> Self {
221+
let scalar = Scalar::<C>::from_uint_reduced_non_zero(n);
222+
debug_assert!(!bool::from(scalar.is_zero()));
223+
Self::new(scalar).unwrap()
224+
}
225+
}
226+
201227
impl<C> TryFrom<&[u8]> for NonZeroScalar<C>
202228
where
203229
C: Curve + ScalarArithmetic,

0 commit comments

Comments
 (0)