mod binary;
use crate::Zero;
pub trait AddInline<Rhs>: Sized {
fn add_inline(&self, rhs: Rhs) -> Self;
#[inline(always)]
fn add_assign_inline(&mut self, rhs: Rhs) {
*self = self.add_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn add(&self, rhs: Rhs) -> Self {
self.add_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn add_assign(&mut self, rhs: Rhs) {
self.add_assign_inline(rhs)
}
}
pub trait AddFullInline<Rhs>: Sized {
type High;
fn add_full_inline(&self, rhs: Rhs) -> (Self, Self::High);
#[inline(always)]
fn add_full_assign_inline(&mut self, rhs: Rhs) -> Self::High {
let (lo, hi) = self.add_full_inline(rhs);
*self = lo;
hi
}
#[cfg_attr(feature = "inline", inline(always))]
fn add_full(&self, rhs: Rhs) -> (Self, Self::High) {
self.add_full_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn add_full_assign(&mut self, rhs: Rhs) -> Self::High {
self.add_full_assign_inline(rhs)
}
}
pub trait NegInline: Sized {
fn neg_inline(&self) -> Self;
#[inline(always)]
fn neg_assign_inline(&mut self) {
*self = self.neg_inline()
}
#[cfg_attr(feature = "inline", inline(always))]
fn neg(&self) -> Self {
self.neg_inline()
}
#[cfg_attr(feature = "inline", inline(always))]
fn neg_assign(&mut self) {
self.neg_assign_inline()
}
}
pub trait SubInline<Rhs>: Sized {
fn sub_inline(&self, rhs: Rhs) -> Self;
#[inline(always)]
fn sub_assign_inline(&mut self, rhs: Rhs) {
*self = self.sub_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn sub(&self, rhs: Rhs) -> Self {
self.sub_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn sub_assign(&mut self, rhs: Rhs) {
self.sub_assign_inline(rhs)
}
}
pub trait SubFullInline<Rhs>: Sized {
type High;
fn sub_full_inline(&self, rhs: Rhs) -> (Self, Self::High);
#[inline(always)]
fn sub_full_assign_inline(&mut self, rhs: Rhs) -> Self::High {
let (lo, hi) = self.sub_full_inline(rhs);
*self = lo;
hi
}
#[cfg_attr(feature = "inline", inline(always))]
fn sub_full(&self, rhs: Rhs) -> (Self, Self::High) {
self.sub_full_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn sub_full_assign(&mut self, rhs: Rhs) -> Self::High {
self.sub_full_assign_inline(rhs)
}
}
pub trait SubFromInline<Rhs> {
fn sub_from_assign_inline(&mut self, rhs: Rhs);
#[cfg_attr(feature = "inline", inline(always))]
fn sub_from_assign(&mut self, rhs: Rhs) {
self.sub_from_assign_inline(rhs)
}
}
pub trait SubFromFullInline<Rhs> {
type High;
fn sub_from_full_assign_inline(&mut self, rhs: Rhs) -> Self::High;
#[cfg_attr(feature = "inline", inline(always))]
fn sub_from_full_assign(&mut self, rhs: Rhs) -> Self::High {
self.sub_from_full_assign_inline(rhs)
}
}
pub trait SquareInline: Sized {
fn square_inline(&self) -> Self;
#[inline(always)]
fn square_assign_inline(&mut self) {
*self = self.square_inline()
}
#[cfg_attr(feature = "inline", inline(always))]
fn square(&self) -> Self {
self.square_inline()
}
#[cfg_attr(feature = "inline", inline(always))]
fn square_assign(&mut self) {
self.square_assign_inline()
}
}
pub trait SquareFullInline: Sized {
fn square_full_inline(&self) -> (Self, Self);
#[inline(always)]
fn square_full_assign_inline(&mut self) -> Self {
let (lo, hi) = self.square_full_inline();
*self = lo;
hi
}
#[cfg_attr(feature = "inline", inline(always))]
fn square_full(&self) -> (Self, Self) {
self.square_full_inline()
}
#[cfg_attr(feature = "inline", inline(always))]
fn square_full_assign(&mut self) -> Self {
self.square_full_assign_inline()
}
}
pub trait MulInline<Rhs>: Sized {
fn mul_inline(&self, rhs: Rhs) -> Self;
#[inline(always)]
fn mul_assign_inline(&mut self, rhs: Rhs) {
*self = self.mul_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn mul(&self, rhs: Rhs) -> Self {
self.mul_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn mul_assign(&mut self, rhs: Rhs) {
self.mul_assign_inline(rhs)
}
}
pub trait MulFullInline<Rhs>: Sized {
type High;
fn mul_full_inline(&self, rhs: Rhs) -> (Self, Self::High);
#[inline(always)]
fn mul_full_assign_inline(&mut self, rhs: Rhs) -> Self::High {
let (lo, hi) = self.mul_full_inline(rhs);
*self = lo;
hi
}
#[cfg_attr(feature = "inline", inline(always))]
fn mul_full(&self, rhs: Rhs) -> (Self, Self::High) {
self.mul_full_inline(rhs)
}
#[cfg_attr(feature = "inline", inline(always))]
fn mul_full_assign(&self, rhs: Rhs) -> (Self, Self::High) {
self.mul_full_inline(rhs)
}
}
pub trait DivRem<Rhs> {
type Quotient;
type Remainder;
fn div_rem(&self, rhs: Rhs) -> Option<(Self::Quotient, Self::Remainder)>;
}
pub trait InvMod: Sized {
fn inv_mod(&self, modulus: &Self) -> Option<Self>;
}
pub trait GCD: Sized {
fn gcd(a: &Self, b: &Self) -> Self;
fn gcd_extended(a: &Self, b: &Self) -> (Self, Self, Self, bool);
}
#[allow(clippy::declare_interior_mutable_const)]
pub trait MontgomeryParameters: 'static + Send + Sync + Sized {
type UInt;
const MODULUS: Self::UInt;
const M64: u64;
const R1: Self::UInt;
const R2: Self::UInt;
const R3: Self::UInt;
}
pub trait Montgomery: Zero {
fn to_montgomery<M: MontgomeryParameters<UInt = Self>>(&self) -> Self {
#[allow(clippy::borrow_interior_mutable_const)]
self.mul_redc::<M>(&M::R2)
}
fn from_montgomery<M: MontgomeryParameters<UInt = Self>>(&self) -> Self {
Self::redc_inline::<M>(self, &Self::zero())
}
fn reduce_1_inline<M: MontgomeryParameters<UInt = Self>>(&self) -> Self;
fn reduce_1<M: MontgomeryParameters<UInt = Self>>(&self) -> Self {
Self::reduce_1_inline::<M>(self)
}
fn redc_inline<M: MontgomeryParameters<UInt = Self>>(lo: &Self, hi: &Self) -> Self;
fn square_redc_inline<M: MontgomeryParameters<UInt = Self>>(&self) -> Self;
fn mul_redc_inline<M: MontgomeryParameters<UInt = Self>>(&self, rhs: &Self) -> Self;
fn inv_redc<M: MontgomeryParameters<UInt = Self>>(&self) -> Option<Self>;
fn redc<M: MontgomeryParameters<UInt = Self>>(lo: &Self, hi: &Self) -> Self {
Self::redc_inline::<M>(lo, hi)
}
fn square_redc<M: MontgomeryParameters<UInt = Self>>(&self) -> Self {
self.square_redc_inline::<M>()
}
fn mul_redc<M: MontgomeryParameters<UInt = Self>>(&self, rhs: &Self) -> Self {
self.mul_redc_inline::<M>(rhs)
}
fn mul_mod<M: MontgomeryParameters<UInt = Self>>(&self, rhs: &Self) -> Self {
#[allow(clippy::borrow_interior_mutable_const)]
let mont = Self::mul_redc_inline::<M>(self, &M::R2);
Self::mul_redc_inline::<M>(&mont, rhs)
}
}
#[allow(unreachable_pub)]
pub use binary::{Binary, BinaryAssignRef, BinaryOps};
pub trait BinaryRing: Binary {}