use crate::{
bytes::{FromBytes, ToBytes},
fields::{BitIteratorBE, BitIteratorLE},
UniformRand,
};
use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, SerializationError};
use ark_std::rand::{
distributions::{Distribution, Standard},
Rng,
};
use ark_std::{
convert::TryFrom,
fmt::{Debug, Display},
io::{Read, Result as IoResult, Write},
vec::Vec,
};
use num_bigint::BigUint;
use zeroize::Zeroize;
#[macro_use]
pub mod arithmetic;
#[macro_use]
mod macros;
pub fn signed_mod_reduction(n: u64, modulus: u64) -> i64 {
let t = (n % modulus) as i64;
if t as u64 >= (modulus / 2) {
t - (modulus as i64)
} else {
t
}
}
bigint_impl!(BigInteger64, 1);
bigint_impl!(BigInteger128, 2);
bigint_impl!(BigInteger256, 4);
bigint_impl!(BigInteger320, 5);
bigint_impl!(BigInteger384, 6);
bigint_impl!(BigInteger448, 7);
bigint_impl!(BigInteger768, 12);
bigint_impl!(BigInteger832, 13);
#[cfg(test)]
mod tests;
pub trait BigInteger:
ToBytes
+ FromBytes
+ CanonicalSerialize
+ CanonicalDeserialize
+ Copy
+ Clone
+ Debug
+ Default
+ Display
+ Eq
+ Ord
+ Send
+ Sized
+ Sync
+ 'static
+ UniformRand
+ Zeroize
+ AsMut<[u64]>
+ AsRef<[u64]>
+ From<u64>
+ TryFrom<BigUint>
+ Into<BigUint>
{
const NUM_LIMBS: usize;
fn add_nocarry(&mut self, other: &Self) -> bool;
fn sub_noborrow(&mut self, other: &Self) -> bool;
fn mul2(&mut self);
fn muln(&mut self, amt: u32);
fn div2(&mut self);
fn divn(&mut self, amt: u32);
fn is_odd(&self) -> bool;
fn is_even(&self) -> bool;
fn is_zero(&self) -> bool;
fn num_bits(&self) -> u32;
fn get_bit(&self, i: usize) -> bool;
fn from_bits_be(bits: &[bool]) -> Self;
fn from_bits_le(bits: &[bool]) -> Self;
fn to_bits_be(&self) -> Vec<bool> {
BitIteratorBE::new(self).collect::<Vec<_>>()
}
fn to_bits_le(&self) -> Vec<bool> {
BitIteratorLE::new(self).collect::<Vec<_>>()
}
fn to_bytes_be(&self) -> Vec<u8>;
fn to_bytes_le(&self) -> Vec<u8>;
fn find_wnaf(&self, w: usize) -> Option<Vec<i64>> {
if w >= 2 && w < 64 {
let mut res = vec![];
let mut e = *self;
while !e.is_zero() {
let z: i64;
if e.is_odd() {
z = signed_mod_reduction(e.as_ref()[0], 1 << w);
if z >= 0 {
e.sub_noborrow(&Self::from(z as u64));
} else {
e.add_nocarry(&Self::from((-z) as u64));
}
} else {
z = 0;
}
res.push(z);
e.div2();
}
Some(res)
} else {
None
}
}
fn write_le<W: Write>(&self, writer: &mut W) -> IoResult<()> {
self.write(writer)
}
fn read_le<R: Read>(&mut self, reader: &mut R) -> IoResult<()> {
*self = Self::read(reader)?;
Ok(())
}
}