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 71 72 73 74 75 76 77
//! Properties of a big number
use crate::digit::Digit;
pub mod impls;
pub trait IsBigInt {
/// segment type, typically primitive integer type like u64, u32
type Dig: Digit + PartialEq;
/// segment length in byte
const DIG_BYTE_LEN: usize = Self::Dig::BYTE_LEN;
/// number of segments
const DIG_LEN: usize;
/// segment length in bit
const DIG_BIT_LEN: usize = Self::DIG_BYTE_LEN << 3;
/// segment bit length mask, for example, if segment is u8 type, its bit length is 8, mask is 0b111 = (1 << 3) - 1
const DIG_BIT_LEN_MSK: usize = Self::DIG_BIT_LEN - 1;
/// segment bit length shift amount. uf segment is u8, this value is 3 since 1 << 3 = 8
const DIG_BIT_LEN_SHT: usize = Self::DIG_BIT_LEN.trailing_zeros() as usize;
/// segment byte length mask, u8 segment has 1 byte length, so mask is 0
const DIG_BYTE_LEN_MSK: usize = Self::DIG_BYTE_LEN - 1;
/// segment byte length mask, u8 segment has 1 byte length, so mask is 0
const DIG_BYTE_LEN_SHT: usize = Self::DIG_BYTE_LEN.trailing_zeros() as usize;
/// big integer length in byte
const BYTE_LEN: usize = Self::DIG_LEN * Self::DIG_BYTE_LEN;
/// big integer length in bit
const BIT_LEN: usize = Self::BYTE_LEN << 3;
const ONE: Self;
const ZERO: Self;
/// number of leading zeros in bit
fn bit_nlz(&self) -> usize;
/// big uint length in segment, excluding leading zeros
fn seg_len(&self) -> usize;
/// big uint length in bit, excluding leading zeros
fn bit_len(&self) -> usize;
/// get the idx-th bit of big integer
fn bit(&self, idx: usize) -> bool;
/// check if this biguint is negative, i.e. the MSB is 0
fn is_negative(&self) -> bool;
/// check if self is zero
fn is_zero(&self) -> bool;
/// check is self is odd
fn is_odd(&self) -> bool;
/// get a reference of slice of digs for this bigint
fn as_slice(&self) -> &[Self::Dig; Self::DIG_LEN];
fn from_slice(arr: &[Self::Dig; Self::DIG_LEN]) -> Self;
fn to_array(self) -> [Self::Dig; Self::DIG_LEN];
fn from_array(arr: [Self::Dig; Self::DIG_LEN]) -> Self;
fn as_bytes(&self) -> &[u8]
where
[(); Self::BYTE_LEN]:
;
fn set_bit(self, idx: usize, bit: bool) -> Self;
#[cfg(feature = "rand")]
fn rand(rng: &mut impl rand_core::CryptoRngCore) -> Self
where
[(); Self::DIG_LEN]: ,
Self: Sized
{
let mut out = [Self::Dig::ZERO; Self::DIG_LEN];
out.iter_mut().for_each(|x| *x = Self::Dig::rand(rng));
Self::from_array(out)
}
}