use crate::{FromBits, FromBytes, ToBits, ToBytes, rand::Uniform};
use num_bigint::BigUint;
use std::fmt::{Debug, Display};
mod bigint_256;
pub use bigint_256::*;
mod bigint_384;
pub use bigint_384::*;
#[cfg(test)]
mod tests;
pub trait BigInteger:
ToBits
+ FromBits
+ ToBytes
+ FromBytes
+ Copy
+ Clone
+ Debug
+ Default
+ Display
+ Eq
+ Ord
+ Send
+ Sized
+ Sync
+ 'static
+ Uniform
+ AsMut<[u64]>
+ AsRef<[u64]>
+ From<u64>
{
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 to_biguint(&self) -> BigUint;
fn find_wnaf(&self) -> Vec<i64>;
}
pub mod arithmetic {
#[inline(always)]
pub fn adc(a: &mut u64, b: u64, carry: u64) -> u64 {
let tmp = u128::from(*a) + u128::from(b) + u128::from(carry);
*a = tmp as u64;
(tmp >> 64) as u64
}
#[inline(always)]
pub fn sbb(a: &mut u64, b: u64, borrow: u64) -> u64 {
let tmp = (1u128 << 64) + u128::from(*a) - u128::from(b) - u128::from(borrow);
let carry = u64::from(tmp >> 64 == 0);
*a = tmp as u64;
carry
}
#[inline(always)]
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (u128::from(a)) + u128::from(b) * u128::from(c) + u128::from(*carry);
*carry = (tmp >> 64) as u64;
tmp as u64
}
#[inline(always)]
pub fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (u128::from(a)) + u128::from(b) * u128::from(c);
*carry = (tmp >> 64) as u64;
tmp as u64
}
#[inline(always)]
pub fn mac_discard(a: u64, b: u64, c: u64, carry: &mut u64) {
let tmp = (u128::from(a)) + u128::from(b) * u128::from(c);
*carry = (tmp >> 64) as u64;
}
}