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
59 changes: 35 additions & 24 deletions src/uint/concat.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
use crate::{Concat, ConcatMixed, Limb, Uint};

impl<T> Concat for T
where
T: ConcatMixed<T>,
{
type Output = Self::MixedOutput;
}
impl<const L: usize> Uint<L> {
/// Concatenate the two values, with `self` as least significant and `hi` as the most
/// significant.
pub const fn concat<const O: usize>(&self, hi: &Self) -> Uint<O>
where
Self: Concat<Output = Uint<O>>,
{
Uint::concat_mixed(self, hi)
}

/// Concatenate the two values, with `lo` as least significant and `hi`
/// as the most significant.
#[inline]
pub(crate) const fn concat_mixed<const L: usize, const H: usize, const O: usize>(
lo: &Uint<L>,
hi: &Uint<H>,
) -> Uint<O> {
let top = L + H;
let top = if top < O { top } else { O };
let mut limbs = [Limb::ZERO; O];
let mut i = 0;
/// Concatenate the two values, with `lo` as least significant and `hi`
/// as the most significant.
#[inline]
pub const fn concat_mixed<const H: usize, const O: usize>(lo: &Uint<L>, hi: &Uint<H>) -> Uint<O>
where
Self: ConcatMixed<Uint<H>, MixedOutput = Uint<O>>,
{
let top = L + H;
let top = if top < O { top } else { O };
let mut limbs = [Limb::ZERO; O];
let mut i = 0;

while i < top {
if i < L {
limbs[i] = lo.limbs[i];
} else {
limbs[i] = hi.limbs[i - L];
while i < top {
if i < L {
limbs[i] = lo.limbs[i];
} else {
limbs[i] = hi.limbs[i - L];
}
i += 1;
}
i += 1;

Uint { limbs }
}
}

Uint { limbs }
impl<T> Concat for T
where
T: ConcatMixed<T>,
{
type Output = Self::MixedOutput;
}

#[cfg(test)]
Expand Down
12 changes: 2 additions & 10 deletions src/uint/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ macro_rules! impl_uint_concat_split_mixed {
type MixedOutput = $name;

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

Expand Down Expand Up @@ -113,15 +113,7 @@ macro_rules! impl_uint_concat_split_even {
type MixedOutput = $name;

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 least significant and `hi` as the most
/// significant.
pub const fn concat(&self, hi: &Uint<{ <$name>::LIMBS / 2 }>) -> $name {
$crate::uint::concat::concat_mixed(self, hi)
Uint::concat_mixed(self, hi)
}
}

Expand Down
15 changes: 7 additions & 8 deletions src/uint/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

// TODO(tarcieri): use Karatsuba for better performance

use super::concat::concat_mixed;
use crate::{
Checked, CheckedMul, Concat, ConcatMixed, Limb, Uint, WideningMul, Wrapping, WrappingMul, Zero,
};
Expand Down Expand Up @@ -61,10 +60,10 @@ impl<const LIMBS: usize> Uint<LIMBS> {
rhs: &Uint<RHS_LIMBS>,
) -> Uint<WIDE_LIMBS>
where
Uint<RHS_LIMBS>: ConcatMixed<Self, MixedOutput = Uint<WIDE_LIMBS>>,
Self: ConcatMixed<Uint<RHS_LIMBS>, MixedOutput = Uint<WIDE_LIMBS>>,
{
let (lo, hi) = self.split_mul(rhs);
concat_mixed(&lo, &hi)
Uint::concat_mixed(&lo, &hi)
}

/// Compute "wide" multiplication as a 2-tuple containing the `(lo, hi)` components of the product, whose sizes
Expand Down Expand Up @@ -172,7 +171,7 @@ where
/// Square self, returning a concatenated "wide" result.
pub const fn square(&self) -> Uint<WIDE_LIMBS> {
let (lo, hi) = self.square_wide();
concat_mixed(&lo, &hi)
lo.concat(&hi)
}
}

Expand Down Expand Up @@ -244,9 +243,9 @@ impl<const LIMBS: usize> MulAssign<&Checked<Uint<LIMBS>>> for Checked<Uint<LIMBS
impl<const LIMBS: usize, const RHS_LIMBS: usize, const WIDE_LIMBS: usize>
WideningMul<Uint<RHS_LIMBS>> for Uint<LIMBS>
where
Uint<RHS_LIMBS>: ConcatMixed<Self, MixedOutput = Uint<WIDE_LIMBS>>,
Self: ConcatMixed<Uint<RHS_LIMBS>, MixedOutput = Uint<WIDE_LIMBS>>,
{
type Output = <Uint<RHS_LIMBS> as ConcatMixed<Self>>::MixedOutput;
type Output = <Self as ConcatMixed<Uint<RHS_LIMBS>>>::MixedOutput;

#[inline]
fn widening_mul(&self, rhs: Uint<RHS_LIMBS>) -> Self::Output {
Expand All @@ -257,9 +256,9 @@ where
impl<const LIMBS: usize, const RHS_LIMBS: usize, const WIDE_LIMBS: usize>
WideningMul<&Uint<RHS_LIMBS>> for Uint<LIMBS>
where
Uint<RHS_LIMBS>: ConcatMixed<Self, MixedOutput = Uint<WIDE_LIMBS>>,
Self: ConcatMixed<Uint<RHS_LIMBS>, MixedOutput = Uint<WIDE_LIMBS>>,
{
type Output = <Uint<RHS_LIMBS> as ConcatMixed<Self>>::MixedOutput;
type Output = <Self as ConcatMixed<Uint<RHS_LIMBS>>>::MixedOutput;

#[inline]
fn widening_mul(&self, rhs: &Uint<RHS_LIMBS>) -> Self::Output {
Expand Down