use crate::{Limb, NonZero};
use core::fmt::Debug;
use core::ops::{Div, Rem};
use subtle::{
Choice, ConditionallySelectable, ConstantTimeEq, ConstantTimeGreater, ConstantTimeLess,
};
#[cfg(feature = "rand")]
use rand_core::{CryptoRng, RngCore};
pub trait Integer:
'static
+ AsRef<[Limb]>
+ Copy
+ ConditionallySelectable
+ ConstantTimeEq
+ ConstantTimeGreater
+ ConstantTimeLess
+ Debug
+ Default
+ Div<NonZero<Self>, Output = Self>
+ Encoding
+ Eq
+ From<u64>
+ Ord
+ Rem<NonZero<Self>, Output = Self>
+ Send
+ Sized
+ Sync
{
const ZERO: Self;
const ONE: Self;
const MAX: Self;
fn is_zero(&self) -> Choice {
self.ct_eq(&Self::ZERO)
}
fn is_odd(&self) -> Choice;
fn is_even(&self) -> Choice {
!self.is_odd()
}
}
#[cfg(feature = "rand")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub trait Random: Sized {
fn random(rng: impl CryptoRng + RngCore) -> Self;
}
#[cfg(feature = "rand")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub trait RandomMod: Sized {
fn random_mod(rng: impl CryptoRng + RngCore, modulus: &Self) -> Self;
}
pub trait AddMod<Rhs = Self> {
type Output;
fn add_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
}
pub trait SubMod<Rhs = Self> {
type Output;
fn sub_mod(&self, rhs: &Rhs, p: &Self) -> Self::Output;
}
pub trait NegMod {
type Output;
#[must_use]
fn neg_mod(&self, p: &Self) -> Self::Output;
}
pub trait MulMod<Rhs = Self> {
type Output;
fn mul_mod(&self, rhs: &Rhs, p: &Self, p_inv: Limb) -> Self::Output;
}
pub trait Concat<Rhs = Self> {
type Output;
fn concat(&self, rhs: &Self) -> Self::Output;
}
pub trait Split<Rhs = Self> {
type Output;
fn split(&self) -> (Self::Output, Self::Output);
}
pub trait Encoding: Sized {
const BIT_SIZE: usize;
const BYTE_SIZE: usize;
type Repr: AsRef<[u8]> + AsMut<[u8]> + Copy + Clone + Sized;
fn from_be_bytes(bytes: Self::Repr) -> Self;
fn from_le_bytes(bytes: Self::Repr) -> Self;
fn to_be_bytes(&self) -> Self::Repr;
fn to_le_bytes(&self) -> Self::Repr;
}