Skip to content

Commit f7f1752

Browse files
committed
Add HasResidueRepr and ResidueRepr traits to connect integers and residue representations
1 parent cc3f984 commit f7f1752

File tree

5 files changed

+89
-4
lines changed

5 files changed

+89
-4
lines changed

src/modular/boxed_residue.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use super::{
1212
reduction::{montgomery_reduction_boxed, montgomery_reduction_boxed_mut},
1313
Retrieve,
1414
};
15-
use crate::{BoxedUint, Integer, Limb, NonZero, Word};
15+
use crate::{BoxedUint, Integer, Limb, NonZero, ResidueRepr, Word};
1616
use subtle::CtOption;
1717

1818
#[cfg(feature = "std")]
@@ -240,6 +240,27 @@ impl Retrieve for BoxedResidue {
240240
}
241241
}
242242

243+
impl ResidueRepr for BoxedResidue {
244+
type Raw = BoxedUint;
245+
type Precomputed = BoxedResidueParams;
246+
247+
fn new_precomputed(modulus: Self::Raw) -> CtOption<Self::Precomputed> {
248+
BoxedResidueParams::new(modulus)
249+
}
250+
251+
fn new(value: Self::Raw, precomputed: Self::Precomputed) -> Self {
252+
BoxedResidue::new(value, precomputed)
253+
}
254+
255+
fn zero(precomputed: Self::Precomputed) -> Self {
256+
BoxedResidue::zero(precomputed)
257+
}
258+
259+
fn one(precomputed: Self::Precomputed) -> Self {
260+
BoxedResidue::one(precomputed)
261+
}
262+
}
263+
243264
/// Convert the given integer into the Montgomery domain.
244265
#[inline]
245266
fn convert_to_montgomery(integer: &mut BoxedUint, residue_params: &BoxedResidueParams) {

src/modular/dyn_residue.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use super::{
1313
residue::{Residue, ResidueParams},
1414
Retrieve,
1515
};
16-
use crate::{Limb, NonZero, Uint, Word, Zero};
16+
use crate::{Limb, NonZero, ResidueRepr, Uint, Word, Zero};
1717
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};
1818

1919
/// Parameters to efficiently go to/from the Montgomery form for an odd modulus provided at runtime.
@@ -208,6 +208,27 @@ impl<const LIMBS: usize> Retrieve for DynResidue<LIMBS> {
208208
}
209209
}
210210

211+
impl<const LIMBS: usize> ResidueRepr for DynResidue<LIMBS> {
212+
type Raw = Uint<LIMBS>;
213+
type Precomputed = DynResidueParams<LIMBS>;
214+
215+
fn new_precomputed(modulus: Self::Raw) -> CtOption<Self::Precomputed> {
216+
DynResidueParams::new(&modulus)
217+
}
218+
219+
fn new(value: Self::Raw, precomputed: Self::Precomputed) -> Self {
220+
DynResidue::new(&value, precomputed)
221+
}
222+
223+
fn zero(precomputed: Self::Precomputed) -> Self {
224+
DynResidue::zero(precomputed)
225+
}
226+
227+
fn one(precomputed: Self::Precomputed) -> Self {
228+
DynResidue::one(precomputed)
229+
}
230+
}
231+
211232
impl<const LIMBS: usize, P: ResidueParams<LIMBS>> From<&Residue<P, LIMBS>> for DynResidue<LIMBS> {
212233
fn from(residue: &Residue<P, LIMBS>) -> Self {
213234
Self {

src/traits.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,3 +433,33 @@ pub trait WideningMul<Rhs = Self>: Sized {
433433
/// Perform widening multiplication.
434434
fn widening_mul(&self, rhs: Rhs) -> Self::Output;
435435
}
436+
437+
/// This integer has a representation optimized for the performance of modular operations.
438+
pub trait HasResidueRepr {
439+
/// The representation type.
440+
type Residue: ResidueRepr<Raw = Self>;
441+
}
442+
443+
/// A representation of an integer optimized for the performance of modular operations.
444+
pub trait ResidueRepr {
445+
/// The original integer type.
446+
type Raw: HasResidueRepr<Residue = Self>;
447+
448+
/// The precomputed data needed for this representation.
449+
type Precomputed: Clone;
450+
451+
/// Create the precomputed data.
452+
///
453+
/// Can return `None` if `modulus` is not valid for the representation;
454+
/// see the documentation of the specific type for the requirements.
455+
fn new_precomputed(modulus: Self::Raw) -> CtOption<Self::Precomputed>;
456+
457+
/// Convert the value into the representation using precomputed data.
458+
fn new(value: Self::Raw, precomputed: Self::Precomputed) -> Self;
459+
460+
/// Returns zero in this representation.
461+
fn zero(precomputed: Self::Precomputed) -> Self;
462+
463+
/// Returns one in this representation.
464+
fn one(precomputed: Self::Precomputed) -> Self;
465+
}

src/uint.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ pub(crate) mod boxed;
3838
#[cfg(feature = "rand_core")]
3939
mod rand;
4040

41-
use crate::{Bounded, Constants, Encoding, FixedInteger, Integer, Limb, Word, ZeroConstant};
41+
use crate::{
42+
modular::DynResidue, Bounded, Constants, Encoding, FixedInteger, HasResidueRepr, Integer, Limb,
43+
Word, ZeroConstant,
44+
};
4245
use core::fmt;
4346
use subtle::{Choice, ConditionallySelectable};
4447

@@ -249,6 +252,10 @@ impl<const LIMBS: usize> Integer for Uint<LIMBS> {
249252
}
250253
}
251254

255+
impl<const LIMBS: usize> HasResidueRepr for Uint<LIMBS> {
256+
type Residue = DynResidue<LIMBS>;
257+
}
258+
252259
impl<const LIMBS: usize> ZeroConstant for Uint<LIMBS> {
253260
const ZERO: Self = Self::ZERO;
254261
}

src/uint/boxed.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ mod neg_mod;
2424
#[cfg(feature = "rand_core")]
2525
mod rand;
2626

27-
use crate::{Integer, Limb, NonZero, Uint, Word, Zero, U128, U64};
27+
use crate::{
28+
modular::BoxedResidue, HasResidueRepr, Integer, Limb, NonZero, Uint, Word, Zero, U128, U64,
29+
};
2830
use alloc::{boxed::Box, vec, vec::Vec};
2931
use core::{fmt, mem};
3032
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
@@ -403,6 +405,10 @@ impl Zero for BoxedUint {
403405
}
404406
}
405407

408+
impl HasResidueRepr for BoxedUint {
409+
type Residue = BoxedResidue;
410+
}
411+
406412
#[cfg(feature = "zeroize")]
407413
impl Zeroize for BoxedUint {
408414
fn zeroize(&mut self) {

0 commit comments

Comments
 (0)