1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
use core::ops::{Add, Sub, Shr, Shl, Rem, Mul};
use crate::{BigUInt, property::IsBigInt};
pub mod impls;
pub mod slice;
/// perform arithmetic rhs % self, which is symmetic Rem
pub trait WrapAround<Rhs = Self> {
fn wrap(self, rhs: Rhs) -> Self;
}
/// This trait requires bigint to implement methods for multiplication.
///
/// Due to restrictions on rust type system, it's difficult for us to express something like
///
/// ```text,ignore
/// Self: Mul<Output = impl BigUIntProperties<DIG_LEN == 2 * <Self as BigUIntProperties>::DIG_LEN> && Dig == <Self as BigUIntProperties>::Dig>
/// ```
///
/// So instead of implementing a multiplication that returns one biguint with twice of self's length, we return
/// two biguints representing the higher digs and lower digs seperatly.
///
/// This trait requires biguint to implement this kind of multiplication, and to use the return convinently,
/// we should also implement a mod method to convert two biguints into one by modding one biguint, which is useful
/// when we are dealing with biguint mul-mod or exp-mod arithmetics.
pub trait BigIntOpsExt
where
Self:
BigIntOps +
Mul<Self, Output = [Self; 2]> + Mul<Self::Dig, Output = (Self, Self::Dig)> +
WrapAround<[Self; 2]> +
PartialEq<[Self; 2]> + PartialOrd<[Self; 2]>
{ }
/// This trait requires bigint to at least implement add, sub, shl, shr, mod and order
pub trait BigIntOps
where
Self:
Sized + Copy +
IsBigInt +
Add<Output = (Self, Self::Dig)> + Add<Self::Dig, Output = (Self, Self::Dig)> +
Sub<Output = (Self, Self::Dig)> + Sub<Self::Dig, Output = (Self, Self::Dig)> +
Shr<usize, Output = Self> +
Shl<usize, Output = Self> +
Rem<Output = Self> +
Ord + Eq
{ }
impl<T: Copy, const LEN: usize> BigIntOps for BigUInt<T, LEN>
where
Self:
IsBigInt +
Add<Output = (Self, Self::Dig)> + Add<Self::Dig, Output = (Self, Self::Dig)> +
Sub<Output = (Self, Self::Dig)> + Sub<Self::Dig, Output = (Self, Self::Dig)> +
Shr<usize, Output = Self> +
Shr<usize, Output = Self> +
Shl<usize, Output = Self> +
Rem<Output = Self> +
Ord + Eq,
{ }
impl<T: Copy, const LEN: usize> BigIntOpsExt for BigUInt<T, LEN>
where
Self:
BigIntOps +
Mul<Output = [Self; 2]> + Mul<Self::Dig, Output = (Self, Self::Dig)> +
WrapAround<[Self; 2]> +
PartialEq<[Self; 2]> + PartialOrd<[Self; 2]>
{ }