Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add traits to connect integers and residue represenations #431

Merged
merged 6 commits into from
Dec 20, 2023
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
23 changes: 22 additions & 1 deletion src/modular/boxed_monty_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use super::{
reduction::{montgomery_reduction_boxed, montgomery_reduction_boxed_mut},
Retrieve,
};
use crate::{BoxedUint, ConstantTimeSelect, Integer, Limb, NonZero, Word};
use crate::{BoxedUint, ConstantTimeSelect, Integer, Limb, Monty, NonZero, Word};
use subtle::CtOption;

#[cfg(feature = "std")]
Expand Down Expand Up @@ -251,6 +251,27 @@ impl Retrieve for BoxedMontyForm {
}
}

impl Monty for BoxedMontyForm {
type Integer = BoxedUint;
type Params = BoxedMontyParams;

fn new_params(modulus: Self::Integer) -> CtOption<Self::Params> {
BoxedMontyParams::new(modulus)
}

fn new(value: Self::Integer, params: Self::Params) -> Self {
BoxedMontyForm::new(value, params)
}

fn zero(params: Self::Params) -> Self {
BoxedMontyForm::zero(params)
}

fn one(params: Self::Params) -> Self {
BoxedMontyForm::one(params)
}
}

/// Convert the given integer into the Montgomery domain.
#[inline]
fn convert_to_montgomery(integer: &mut BoxedUint, params: &BoxedMontyParams) {
Expand Down
10 changes: 8 additions & 2 deletions src/modular/boxed_monty_form/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

use super::{BoxedMontyForm, BoxedMontyParams};
use crate::{
modular::reduction::montgomery_reduction_boxed_mut, traits::Square, uint::mul::mul_limbs,
BoxedUint, Limb, Word, Zero,
modular::reduction::montgomery_reduction_boxed_mut, uint::mul::mul_limbs, BoxedUint, Limb,
Square, SquareAssign, Word, Zero,
};
use core::{
borrow::Borrow,
Expand Down Expand Up @@ -94,6 +94,12 @@ impl Square for BoxedMontyForm {
}
}

impl SquareAssign for BoxedMontyForm {
fn square_assign(&mut self) {
MontgomeryMultiplier::from(self.params.borrow()).square_assign(&mut self.montgomery_form);
}
}

impl<'a> From<&'a BoxedMontyParams> for MontgomeryMultiplier<'a> {
fn from(params: &'a BoxedMontyParams) -> MontgomeryMultiplier<'a> {
MontgomeryMultiplier::new(&params.modulus, params.mod_neg_inv)
Expand Down
23 changes: 22 additions & 1 deletion src/modular/monty_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use super::{
reduction::montgomery_reduction,
Retrieve,
};
use crate::{Limb, NonZero, Uint, Word, Zero};
use crate::{Limb, Monty, NonZero, Uint, Word, Zero};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};

/// Parameters to efficiently go to/from the Montgomery form for an odd modulus provided at runtime.
Expand Down Expand Up @@ -208,6 +208,27 @@ impl<const LIMBS: usize> Retrieve for MontyForm<LIMBS> {
}
}

impl<const LIMBS: usize> Monty for MontyForm<LIMBS> {
type Integer = Uint<LIMBS>;
type Params = MontyParams<LIMBS>;

fn new_params(modulus: Self::Integer) -> CtOption<Self::Params> {
MontyParams::new(&modulus)
}

fn new(value: Self::Integer, params: Self::Params) -> Self {
MontyForm::new(&value, params)
}

fn zero(params: Self::Params) -> Self {
MontyForm::zero(params)
}

fn one(params: Self::Params) -> Self {
MontyForm::one(params)
}
}

impl<const LIMBS: usize, P: ConstMontyParams<LIMBS>> From<&ConstMontyForm<P, LIMBS>>
for MontyForm<LIMBS>
{
Expand Down
8 changes: 7 additions & 1 deletion src/modular/monty_form/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use super::MontyForm;
use crate::{
modular::mul::{mul_montgomery_form, square_montgomery_form},
traits::Square,
Square, SquareAssign,
};
use core::ops::{Mul, MulAssign};

Expand Down Expand Up @@ -82,3 +82,9 @@ impl<const LIMBS: usize> Square for MontyForm<LIMBS> {
MontyForm::square(self)
}
}

impl<const LIMBS: usize> SquareAssign for MontyForm<LIMBS> {
fn square_assign(&mut self) {
*self = self.square()
}
}
73 changes: 63 additions & 10 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub(crate) use sealed::PrecomputeInverterWithAdjuster;
use crate::{Limb, NonZero};
use core::fmt::Debug;
use core::ops::{
Add, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign, Mul, Not,
Rem, Shl, ShlAssign, Shr, ShrAssign, Sub,
Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
Mul, MulAssign, Neg, Not, Rem, Shl, ShlAssign, Shr, ShrAssign, Sub, SubAssign,
};
use subtle::{
Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
Expand Down Expand Up @@ -141,6 +141,10 @@ pub trait Integer:
+ WrappingShr
+ Zero
{
/// The corresponding Montgomery representation,
/// optimized for the performance of modular operations at the price of a conversion overhead.
type Monty: Monty<Integer = Self>;

/// The value `1`.
fn one() -> Self;

Expand Down Expand Up @@ -425,14 +429,16 @@ pub trait Encoding: Sized {
}

/// Support for optimized squaring
pub trait Square: Sized
where
for<'a> &'a Self: Mul<&'a Self, Output = Self>,
{
/// Computes the same as `self.mul(self)`, but may be more efficient.
fn square(&self) -> Self {
self * self
}
pub trait Square {
/// Computes the same as `self * self`, but may be more efficient.
fn square(&self) -> Self;
}

/// Support for optimized squaring in-place
pub trait SquareAssign {
/// Computes the same as `self * self`, but may be more efficient.
/// Writes the result in `self`.
fn square_assign(&mut self);
}

/// Constant-time exponentiation.
Expand Down Expand Up @@ -513,3 +519,50 @@ pub trait WideningMul<Rhs = Self>: Sized {
/// Perform widening multiplication.
fn widening_mul(&self, rhs: Rhs) -> Self::Output;
}

/// A representation of an integer optimized for the performance of modular operations.
pub trait Monty:
'static
+ Clone
+ Debug
+ Eq
+ Sized
+ Send
+ Sync
+ Add<Output = Self>
+ for<'a> Add<&'a Self, Output = Self>
+ AddAssign
+ for<'a> AddAssign<&'a Self>
+ Sub<Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ SubAssign
+ for<'a> SubAssign<&'a Self>
+ Mul<Output = Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ MulAssign
+ for<'a> MulAssign<&'a Self>
+ Neg<Output = Self>
+ PowBoundedExp<Self::Integer>
+ Square
+ SquareAssign
{
/// The original integer type.
type Integer: Integer<Monty = Self>;

/// The precomputed data needed for this representation.
type Params: Clone;

/// Create the precomputed data for Montgomery representation of integers modulo `modulus`.
///
/// `modulus` must be odd, otherwise returns `None`.
fn new_params(modulus: Self::Integer) -> CtOption<Self::Params>;
tarcieri marked this conversation as resolved.
Show resolved Hide resolved

/// Convert the value into the representation using precomputed data.
fn new(value: Self::Integer, params: Self::Params) -> Self;

/// Returns zero in this representation.
fn zero(params: Self::Params) -> Self;

/// Returns one in this representation.
fn one(params: Self::Params) -> Self;
}
7 changes: 5 additions & 2 deletions src/uint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ pub(crate) mod boxed;
mod rand;

use crate::{
modular::BernsteinYangInverter, Bounded, ConstCtOption, Constants, Encoding, FixedInteger,
Integer, Limb, NonZero, PrecomputeInverter, PrecomputeInverterWithAdjuster, Word, ZeroConstant,
modular::{BernsteinYangInverter, MontyForm},
Bounded, ConstCtOption, Constants, Encoding, FixedInteger, Integer, Limb, NonZero,
PrecomputeInverter, PrecomputeInverterWithAdjuster, Word, ZeroConstant,
};
use core::fmt;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
Expand Down Expand Up @@ -235,6 +236,8 @@ impl<const LIMBS: usize> FixedInteger for Uint<LIMBS> {
}

impl<const LIMBS: usize> Integer for Uint<LIMBS> {
type Monty = MontyForm<LIMBS>;

fn one() -> Self {
Self::ONE
}
Expand Down
4 changes: 3 additions & 1 deletion src/uint/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ mod sub_mod;
#[cfg(feature = "rand_core")]
mod rand;

use crate::{Integer, Limb, NonZero, Word, Zero};
use crate::{modular::BoxedMontyForm, Integer, Limb, NonZero, Word, Zero};
use alloc::{boxed::Box, vec, vec::Vec};
use core::fmt;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
Expand Down Expand Up @@ -284,6 +284,8 @@ impl Default for BoxedUint {
}

impl Integer for BoxedUint {
type Monty = BoxedMontyForm;

fn one() -> Self {
Self::one()
}
Expand Down