Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion elliptic-curve/src/arithmetic.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Elliptic curve arithmetic traits.

use crate::{
ops::{LinearCombination, MulByGenerator, ShrAssign},
ops::{LinearCombination, MulByGenerator, Reduce, ShrAssign},
point::{AffineXCoordinate, AffineYIsOdd},
scalar::FromUintUnchecked,
scalar::IsHigh,
Expand Down Expand Up @@ -72,6 +72,7 @@ pub trait CurveArithmetic: Curve {
+ Into<Self::Uint>
+ IsHigh
+ PartialOrd
+ Reduce<Self::Uint, Bytes = FieldBytes<Self>>
+ ShrAssign<usize>
+ ff::Field
+ ff::PrimeField<Repr = FieldBytes<Self>>;
Expand Down
6 changes: 6 additions & 0 deletions elliptic-curve/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,12 +325,18 @@ impl<'a> Product<&'a Scalar> for Scalar {
}

impl Reduce<U256> for Scalar {
type Bytes = FieldBytes;

fn reduce(w: U256) -> Self {
let (r, underflow) = w.sbb(&MockCurve::ORDER, Limb::ZERO);
let underflow = Choice::from((underflow.0 >> (Limb::BITS - 1)) as u8);
let reduced = U256::conditional_select(&w, &r, !underflow);
Self(ScalarPrimitive::new(reduced).unwrap())
}

fn reduce_bytes(_: &FieldBytes) -> Self {
todo!()
}
}

impl From<u64> for Scalar {
Expand Down
3 changes: 2 additions & 1 deletion elliptic-curve/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ extern crate alloc;
#[cfg(feature = "std")]
extern crate std;

pub mod ops;
pub mod point;
pub mod scalar;

Expand All @@ -82,6 +81,8 @@ pub mod dev;
pub mod ecdh;
#[cfg(feature = "hash2curve")]
pub mod hash2curve;
#[cfg(feature = "arithmetic")]
pub mod ops;
#[cfg(feature = "sec1")]
pub mod sec1;
#[cfg(feature = "arithmetic")]
Expand Down
17 changes: 11 additions & 6 deletions elliptic-curve/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
pub use core::ops::{Add, AddAssign, Mul, Neg, Shr, ShrAssign, Sub, SubAssign};

use crypto_bigint::Integer;

#[cfg(feature = "arithmetic")]
use {group::Group, subtle::CtOption};

/// Perform an inversion on a field element (i.e. base field element or scalar)
Expand All @@ -16,7 +14,6 @@ pub trait Invert {
fn invert(&self) -> Self::Output;
}

#[cfg(feature = "arithmetic")]
impl<F: ff::Field> Invert for F {
type Output = CtOption<F>;

Expand All @@ -31,7 +28,6 @@ impl<F: ff::Field> Invert for F {
/// linear combinations (e.g. Shamir's Trick), or otherwise provides a default
/// non-optimized implementation.
// TODO(tarcieri): replace this with a trait from the `group` crate? (see zkcrypto/group#25)
#[cfg(feature = "arithmetic")]
pub trait LinearCombination: Group {
/// Calculates `x * k + y * l`.
fn lincomb(x: &Self, k: &Self::Scalar, y: &Self, l: &Self::Scalar) -> Self {
Expand All @@ -43,7 +39,6 @@ pub trait LinearCombination: Group {
///
/// May use optimizations (e.g. precomputed tables) when available.
// TODO(tarcieri): replace this with `Group::mul_by_generator``? (see zkcrypto/group#44)
#[cfg(feature = "arithmetic")]
pub trait MulByGenerator: Group {
/// Multiply by the generator of the prime-order subgroup.
#[must_use]
Expand All @@ -54,8 +49,14 @@ pub trait MulByGenerator: Group {

/// Modular reduction.
pub trait Reduce<Uint: Integer>: Sized {
/// Bytes used as input to [`Reduce::reduce_bytes`].
type Bytes: AsRef<[u8]>;

/// Perform a modular reduction, returning a field element.
fn reduce(n: Uint) -> Self;

/// Interpret the given bytes as an integer and perform a modular reduction.
fn reduce_bytes(bytes: &Self::Bytes) -> Self;
}

/// Modular reduction to a non-zero output.
Expand All @@ -65,7 +66,11 @@ pub trait Reduce<Uint: Integer>: Sized {
///
/// End users should use the [`Reduce`] impl on
/// [`NonZeroScalar`][`crate::NonZeroScalar`] instead.
pub trait ReduceNonZero<Uint: Integer>: Sized {
pub trait ReduceNonZero<Uint: Integer>: Reduce<Uint> + Sized {
/// Perform a modular reduction, returning a field element.
fn reduce_nonzero(n: Uint) -> Self;

/// Interpret the given bytes as an integer and perform a modular reduction
/// to a non-zero output.
fn reduce_nonzero_bytes(bytes: &Self::Bytes) -> Self;
}
16 changes: 14 additions & 2 deletions elliptic-curve/src/scalar/nonzero.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,24 +249,36 @@ impl<C, I> Reduce<I> for NonZeroScalar<C>
where
C: CurveArithmetic,
I: Integer + ArrayEncoding,
Scalar<C>: ReduceNonZero<I>,
Scalar<C>: Reduce<I, Bytes = FieldBytes<C>> + ReduceNonZero<I>,
{
type Bytes = FieldBytes<C>;

fn reduce(n: I) -> Self {
Self::reduce_nonzero(n)
}

fn reduce_bytes(bytes: &FieldBytes<C>) -> Self {
Self::reduce_nonzero_bytes(bytes)
}
}

impl<C, I> ReduceNonZero<I> for NonZeroScalar<C>
where
C: CurveArithmetic,
I: Integer + ArrayEncoding,
Scalar<C>: ReduceNonZero<I>,
Scalar<C>: Reduce<I, Bytes = FieldBytes<C>> + ReduceNonZero<I>,
{
fn reduce_nonzero(n: I) -> Self {
let scalar = Scalar::<C>::reduce_nonzero(n);
debug_assert!(!bool::from(scalar.is_zero()));
Self::new(scalar).unwrap()
}

fn reduce_nonzero_bytes(bytes: &FieldBytes<C>) -> Self {
let scalar = Scalar::<C>::reduce_nonzero_bytes(bytes);
debug_assert!(!bool::from(scalar.is_zero()));
Self::new(scalar).unwrap()
}
}

impl<C> TryFrom<&[u8]> for NonZeroScalar<C>
Expand Down
8 changes: 6 additions & 2 deletions elliptic-curve/src/scalar/primitive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@

use crate::{
bigint::{prelude::*, Limb, NonZero},
ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign},
scalar::FromUintUnchecked,
scalar::IsHigh,
Curve, Error, FieldBytes, Result,
};
use base16ct::HexDisplay;
use core::{cmp::Ordering, fmt, str};
use core::{
cmp::Ordering,
fmt,
ops::{Add, AddAssign, Neg, ShrAssign, Sub, SubAssign},
str,
};
use generic_array::GenericArray;
use rand_core::CryptoRngCore;
use subtle::{
Expand Down