Skip to content

Commit 6fc0838

Browse files
committed
Add WideningMul trait
Adds a trait for performing widening multiplication, with an output whose size is equal to the sum of the inputs.
1 parent 33e3eb5 commit 6fc0838

3 files changed

Lines changed: 76 additions & 4 deletions

File tree

src/traits.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ pub trait CheckedSub<Rhs = Self>: Sized {
272272
/// value as the least significant value.
273273
pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
274274
/// Concatenated output: twice the width of `Self`.
275-
type Output;
275+
type Output: Integer;
276276

277277
/// Concatenate the two halves, with `self` as most significant and `lo`
278278
/// as the least significant.
@@ -285,7 +285,7 @@ pub trait Concat: ConcatMixed<Self, MixedOutput = Self::Output> {
285285
/// value as the least significant value.
286286
pub trait ConcatMixed<Lo: ?Sized = Self> {
287287
/// Concatenated output: combination of `Lo` and `Self`.
288-
type MixedOutput;
288+
type MixedOutput: Integer;
289289

290290
/// Concatenate the two values, with `self` as most significant and `lo`
291291
/// as the least significant.
@@ -416,3 +416,12 @@ pub trait Invert: Sized {
416416
/// Computes the inverse.
417417
fn invert(&self) -> Self::Output;
418418
}
419+
420+
/// Widening multiply: returns a value with a number of limbs equal to the sum of the inputs.
421+
pub trait WideningMul<Rhs = Self>: Sized {
422+
/// Output of the widening multiplication.
423+
type Output: Integer;
424+
425+
/// Perform widening multiplication.
426+
fn widening_mul(&self, rhs: Rhs) -> Self::Output;
427+
}

src/uint/boxed/mul.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! [`BoxedUint`] multiplication operations.
22
3-
use crate::{uint::mul::mul_limbs, BoxedUint, CheckedMul, Limb, Wrapping, Zero};
3+
use crate::{uint::mul::mul_limbs, BoxedUint, CheckedMul, Limb, WideningMul, Wrapping, Zero};
44
use core::ops::{Mul, MulAssign};
55
use subtle::{Choice, CtOption};
66

@@ -26,6 +26,14 @@ impl BoxedUint {
2626
}
2727
}
2828

29+
impl CheckedMul<BoxedUint> for BoxedUint {
30+
type Output = Self;
31+
32+
fn checked_mul(&self, rhs: BoxedUint) -> CtOption<Self> {
33+
self.checked_mul(&rhs)
34+
}
35+
}
36+
2937
impl CheckedMul<&BoxedUint> for BoxedUint {
3038
type Output = Self;
3139

@@ -43,6 +51,24 @@ impl CheckedMul<&BoxedUint> for BoxedUint {
4351
}
4452
}
4553

54+
impl WideningMul for BoxedUint {
55+
type Output = Self;
56+
57+
#[inline]
58+
fn widening_mul(&self, rhs: BoxedUint) -> Self {
59+
self.mul(&rhs)
60+
}
61+
}
62+
63+
impl WideningMul<&BoxedUint> for BoxedUint {
64+
type Output = Self;
65+
66+
#[inline]
67+
fn widening_mul(&self, rhs: &BoxedUint) -> Self {
68+
self.mul(&rhs)
69+
}
70+
}
71+
4672
impl Mul<Wrapping<BoxedUint>> for Wrapping<BoxedUint> {
4773
type Output = Self;
4874

src/uint/mul.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
33
// TODO(tarcieri): use Karatsuba for better performance
44

5-
use crate::{Checked, CheckedMul, Concat, ConcatMixed, Limb, Uint, WideWord, Word, Wrapping, Zero};
5+
use crate::{
6+
Checked, CheckedMul, Concat, ConcatMixed, Limb, Uint, WideWord, WideningMul, Word, Wrapping,
7+
Zero,
8+
};
69
use core::ops::{Mul, MulAssign};
710
use subtle::CtOption;
811

@@ -165,15 +168,49 @@ impl<const LIMBS: usize> Uint<LIMBS> {
165168
}
166169
}
167170

171+
impl<const LIMBS: usize, const HLIMBS: usize> CheckedMul<Uint<HLIMBS>> for Uint<LIMBS> {
172+
type Output = Self;
173+
174+
#[inline]
175+
fn checked_mul(&self, rhs: Uint<HLIMBS>) -> CtOption<Self> {
176+
self.checked_mul(&rhs)
177+
}
178+
}
179+
168180
impl<const LIMBS: usize, const HLIMBS: usize> CheckedMul<&Uint<HLIMBS>> for Uint<LIMBS> {
169181
type Output = Self;
170182

183+
#[inline]
171184
fn checked_mul(&self, rhs: &Uint<HLIMBS>) -> CtOption<Self> {
172185
let (lo, hi) = self.mul_wide(rhs);
173186
CtOption::new(lo, hi.is_zero())
174187
}
175188
}
176189

190+
impl<const LIMBS: usize, const HLIMBS: usize> WideningMul<Uint<HLIMBS>> for Uint<LIMBS>
191+
where
192+
Uint<HLIMBS>: ConcatMixed<Self>,
193+
{
194+
type Output = <Uint<HLIMBS> as ConcatMixed<Self>>::MixedOutput;
195+
196+
#[inline]
197+
fn widening_mul(&self, rhs: Uint<HLIMBS>) -> Self::Output {
198+
self.mul(&rhs)
199+
}
200+
}
201+
202+
impl<const LIMBS: usize, const HLIMBS: usize> WideningMul<&Uint<HLIMBS>> for Uint<LIMBS>
203+
where
204+
Uint<HLIMBS>: ConcatMixed<Self>,
205+
{
206+
type Output = <Uint<HLIMBS> as ConcatMixed<Self>>::MixedOutput;
207+
208+
#[inline]
209+
fn widening_mul(&self, rhs: &Uint<HLIMBS>) -> Self::Output {
210+
self.mul(rhs)
211+
}
212+
}
213+
177214
impl<const LIMBS: usize, const HLIMBS: usize> Mul<Wrapping<Uint<HLIMBS>>>
178215
for Wrapping<Uint<LIMBS>>
179216
{

0 commit comments

Comments
 (0)