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
8 changes: 4 additions & 4 deletions src/modular.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ mod tests {
#[test]
fn test_reducing_r2_wide() {
// Divide the value ONE^2 by R, which should equal ONE
let (hi, lo) = Modulus2::ONE.square().split();
let (lo, hi) = Modulus2::ONE.square().split();
assert_eq!(
montgomery_reduction::<{ Modulus2::LIMBS }>(
&(lo, hi),
Expand Down Expand Up @@ -157,9 +157,9 @@ mod tests {

// Computing xR mod modulus without Montgomery reduction
let (lo, hi) = x.split_mul(&Modulus2::ONE);
let c = hi.concat(&lo);
let red = c.rem_vartime(&NonZero::new(U256::ZERO.concat(&Modulus2::MODULUS)).unwrap());
let (hi, lo) = red.split();
let c = lo.concat(&hi);
let red = c.rem_vartime(&NonZero::new(Modulus2::MODULUS.0.concat(&U256::ZERO)).unwrap());
let (lo, hi) = red.split();
assert_eq!(hi, Uint::ZERO);

assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions src/modular/monty_form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ impl<const LIMBS: usize> MontyParams<LIMBS> {
// `R^2 mod modulus`, used to convert integers to Montgomery form.
let r2 = one
.square()
.rem(&NonZero(Uint::<LIMBS>::ZERO.concat(&modulus.0)))
.rem(&NonZero(modulus.0.concat(&Uint::ZERO)))
.split()
.1;
.0;

// The modular inverse should always exist, because it was ensured odd above, which also ensures it's non-zero
let inv_mod = modulus
Expand Down
45 changes: 21 additions & 24 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,49 +467,46 @@ pub trait CheckedSub<Rhs = Self>: Sized {
fn checked_sub(&self, rhs: &Rhs) -> CtOption<Self>;
}

/// Concatenate two numbers into a "wide" double-width value, using the `lo`
/// value as the least significant value.
/// Concatenate two numbers into a "wide" double-width value, using the `hi` value as the most
/// significant portion of the resulting value.
pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
/// Concatenated output: twice the width of `Self`.
type Output: Integer;

/// Concatenate the two halves, with `self` as most significant and `lo`
/// as the least significant.
fn concat(&self, lo: &Self) -> Self::Output {
self.concat_mixed(lo)
/// Concatenate the two halves, with `self` as least significant and `hi` as the least
/// significant.
fn concat(&self, hi: &Self) -> Self::Output {
self.concat_mixed(hi)
}
}

/// Concatenate two numbers into a "wide" combined-width value, using the `lo`
/// value as the least significant value.
pub trait ConcatMixed<Lo: ?Sized = Self> {
/// Concatenated output: combination of `Lo` and `Self`.
/// Concatenate two numbers into a "wide" combined-width value, using the `hi` value as the most
/// significant value.
pub trait ConcatMixed<Hi: ?Sized = Self> {
/// Concatenated output: combination of `Self` and `Hi`.
type MixedOutput: Integer;

/// Concatenate the two values, with `self` as most significant and `lo`
/// as the least significant.
fn concat_mixed(&self, lo: &Lo) -> Self::MixedOutput;
/// Concatenate the two values, with `self` as least significant and `hi` as the most
/// significant.
fn concat_mixed(&self, hi: &Hi) -> Self::MixedOutput;
}

/// Split a number in half, returning the most significant half followed by
/// the least significant.
/// Split a number in half, returning the least significant half followed by the most significant.
pub trait Split: SplitMixed<Self::Output, Self::Output> {
/// Split output: high/low components of the value.
/// Split output: low/high components of the value.
type Output;

/// Split this number in half, returning its high and low components
/// respectively.
/// Split this number in half, returning its low and high components respectively.
fn split(&self) -> (Self::Output, Self::Output) {
self.split_mixed()
}
}

/// Split a number into parts, returning the most significant part followed by
/// the least significant.
pub trait SplitMixed<Hi, Lo> {
/// Split this number into parts, returning its high and low components
/// respectively.
fn split_mixed(&self) -> (Hi, Lo);
/// Split a number into parts, returning the least significant part followed by the most
/// significant.
pub trait SplitMixed<Lo, Hi> {
/// Split this number into parts, returning its low and high components respectively.
fn split_mixed(&self) -> (Lo, Hi);
}

/// Encoding support.
Expand Down
10 changes: 5 additions & 5 deletions src/uint/concat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,21 @@ mod tests {
let hi = U64::from_u64(0x0011223344556677);
let lo = U64::from_u64(0x8899aabbccddeeff);
assert_eq!(
hi.concat(&lo),
lo.concat(&hi),
U128::from_be_hex("00112233445566778899aabbccddeeff")
);
}

#[test]
fn concat_mixed() {
let a = U64::from_u64(0x0011223344556677);
let b = U128::from_u128(0x8899aabbccddeeff_8899aabbccddeeff);
let hi = U64::from_u64(0x0011223344556677);
let lo = U128::from_u128(0x8899aabbccddeeff_8899aabbccddeeff);
assert_eq!(
a.concat_mixed(&b),
lo.concat_mixed(&hi),
U192::from_be_hex("00112233445566778899aabbccddeeff8899aabbccddeeff")
);
assert_eq!(
b.concat_mixed(&a),
hi.concat_mixed(&lo),
U192::from_be_hex("8899aabbccddeeff8899aabbccddeeff0011223344556677")
);
}
Expand Down
8 changes: 4 additions & 4 deletions src/uint/from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,19 @@ impl<const LIMBS: usize> From<Limb> for Uint<LIMBS> {

impl<const L: usize, const H: usize, const LIMBS: usize> From<(Uint<L>, Uint<H>)> for Uint<LIMBS>
where
Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
Uint<L>: ConcatMixed<Uint<H>, MixedOutput = Uint<LIMBS>>,
{
fn from(nums: (Uint<L>, Uint<H>)) -> Uint<LIMBS> {
nums.1.concat_mixed(&nums.0)
nums.0.concat_mixed(&nums.1)
}
}

impl<const L: usize, const H: usize, const LIMBS: usize> From<&(Uint<L>, Uint<H>)> for Uint<LIMBS>
where
Uint<H>: ConcatMixed<Uint<L>, MixedOutput = Uint<LIMBS>>,
Uint<L>: ConcatMixed<Uint<H>, MixedOutput = Uint<LIMBS>>,
{
fn from(nums: &(Uint<L>, Uint<H>)) -> Uint<LIMBS> {
nums.1.concat_mixed(&nums.0)
nums.0.concat_mixed(&nums.1)
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/uint/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ macro_rules! impl_uint_concat_split_mixed {
{
type MixedOutput = $name;

fn concat_mixed(&self, lo: &Uint<{ U64::LIMBS * $size }>) -> Self::MixedOutput {
$crate::uint::concat::concat_mixed(lo, self)
fn concat_mixed(&self, hi: &Uint<{ U64::LIMBS * $size }>) -> Self::MixedOutput {
$crate::uint::concat::concat_mixed(self, hi)
}
}

Expand Down Expand Up @@ -107,16 +107,16 @@ macro_rules! impl_uint_concat_split_even {
{
type MixedOutput = $name;

fn concat_mixed(&self, lo: &Uint<{ <$name>::LIMBS / 2 }>) -> Self::MixedOutput {
$crate::uint::concat::concat_mixed(lo, self)
fn concat_mixed(&self, hi: &Uint<{ <$name>::LIMBS / 2 }>) -> Self::MixedOutput {
$crate::uint::concat::concat_mixed(self, hi)
}
}

impl Uint<{ <$name>::LIMBS / 2 }> {
/// Concatenate the two values, with `self` as most significant and `rhs`
/// as the least significant.
pub const fn concat(&self, lo: &Uint<{ <$name>::LIMBS / 2 }>) -> $name {
$crate::uint::concat::concat_mixed(lo, self)
pub const fn concat(&self, hi: &Uint<{ <$name>::LIMBS / 2 }>) -> $name {
$crate::uint::concat::concat_mixed(self, hi)
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/uint/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,15 @@ mod tests {
#[test]
fn square() {
let n = U64::from_u64(0xffff_ffff_ffff_ffff);
let (hi, lo) = n.square().split();
let (lo, hi) = n.square().split();
assert_eq!(lo, U64::from_u64(1));
assert_eq!(hi, U64::from_u64(0xffff_ffff_ffff_fffe));
}

#[test]
fn square_larger() {
let n = U256::MAX;
let (hi, lo) = n.square().split();
let (lo, hi) = n.square().split();
assert_eq!(lo, U256::ONE);
assert_eq!(hi, U256::MAX.wrapping_sub(&U256::ONE));
}
Expand Down
11 changes: 5 additions & 6 deletions src/uint/split.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::{Limb, Uint};

/// Split this number in half, returning its high and low components
/// respectively.
/// Split this number in half, returning its low and high components respectively.
#[inline]
pub(crate) const fn split_mixed<const L: usize, const H: usize, const O: usize>(
n: &Uint<O>,
) -> (Uint<H>, Uint<L>) {
) -> (Uint<L>, Uint<H>) {
let top = L + H;
let top = if top < O { top } else { O };
let mut lo = [Limb::ZERO; L];
Expand All @@ -21,7 +20,7 @@ pub(crate) const fn split_mixed<const L: usize, const H: usize, const O: usize>(
i += 1;
}

(Uint { limbs: hi }, Uint { limbs: lo })
(Uint { limbs: lo }, Uint { limbs: hi })
}

#[cfg(test)]
Expand All @@ -30,8 +29,8 @@ mod tests {

#[test]
fn split() {
let (hi, lo) = U128::from_be_hex("00112233445566778899aabbccddeeff").split();
assert_eq!(hi, U64::from_u64(0x0011223344556677));
let (lo, hi) = U128::from_be_hex("00112233445566778899aabbccddeeff").split();
assert_eq!(lo, U64::from_u64(0x8899aabbccddeeff));
assert_eq!(hi, U64::from_u64(0x0011223344556677));
}
}