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)
}
}