mirror of
https://github.com/logos-storage/rust-poseidon-bn254-pure.git
synced 2026-02-10 11:13:28 +00:00
conversion to decimal string; mulAdd
This commit is contained in:
parent
1786565415
commit
92881234bf
@ -100,7 +100,7 @@ impl<const N: usize> BigInt<N> {
|
||||
buf
|
||||
}
|
||||
|
||||
pub fn from_be_bytes(buf : &[u8; 4*N]) -> BigInt<N> {
|
||||
pub fn from_be_bytes(buf: &[u8; 4*N]) -> BigInt<N> {
|
||||
let mut ws: [u32; N] = [0; N];
|
||||
for i in 0..N {
|
||||
let k = 4*i;
|
||||
@ -113,8 +113,38 @@ impl<const N: usize> BigInt<N> {
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
// decimal printing
|
||||
|
||||
pub fn truncate1(big : &BigInt<{N+1}>) -> BigInt<N> {
|
||||
pub fn divmod_small(big: &BigInt<N>, modulus: u32) -> (BigInt<N> , u32) {
|
||||
let u64_modulus: u64 = modulus as u64;
|
||||
let mut carry: u32 = 0;
|
||||
let mut qs: [u32; N] = [0; N];
|
||||
for i in 0..N {
|
||||
let x: u64 = ((carry as u64) << 32) + (big.0[N-1-i] as u64);
|
||||
qs[N-1-i] = (x / u64_modulus) as u32;
|
||||
carry = (x % u64_modulus) as u32;
|
||||
}
|
||||
(BigInt(qs), carry)
|
||||
}
|
||||
|
||||
pub fn to_decimal_string(input: &BigInt<N>) -> String {
|
||||
let mut digits: Vec<u8> = Vec::new();
|
||||
let mut big: BigInt<N> = input.clone();
|
||||
while( !BigInt::is_zero(&big) ) {
|
||||
let (q,r) = BigInt::divmod_small(&big, 10);
|
||||
digits.push( 48 + (r as u8) );
|
||||
big = q;
|
||||
}
|
||||
if digits.len() == 0 {
|
||||
digits.push( 48 );
|
||||
}
|
||||
digits.reverse();
|
||||
str::from_utf8(&digits).unwrap().to_string()
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
pub fn truncate1(big: &BigInt<{N+1}>) -> BigInt<N> {
|
||||
// let small: [u32; N] = &big.limbs[0..N];
|
||||
let mut small: [u32; N] = [0; N];
|
||||
for i in 0..N { small[i] = big.0[i]; }
|
||||
@ -343,6 +373,66 @@ impl<const N: usize> BigInt<N> {
|
||||
BigInt::multiply(big1,big2)
|
||||
}
|
||||
|
||||
// x*y + z
|
||||
#[inline(always)]
|
||||
pub fn mulAdd(big1: &BigInt<N>, big2: &BigInt<N>, big3: &BigInt<N>) -> BigInt<{N+N}> {
|
||||
// first compute the product
|
||||
let mut product : [u32; N+N] = [0; N+N];
|
||||
let mut state : [u32; N] = [0; N];
|
||||
for j in 0..N {
|
||||
let (scaled,carry) = BigInt::scaleAdd( big2.0[j], &big1, &BigInt(state) );
|
||||
product[j] = scaled.0[0];
|
||||
for i in 1..N { state[i-1] = scaled.0[i] }
|
||||
state[N-1] = carry;
|
||||
}
|
||||
for i in 0..N {
|
||||
product[i+N] = state[i]
|
||||
}
|
||||
|
||||
// then add the third number
|
||||
let mut carry: bool = false;
|
||||
for i in 0..N {
|
||||
let (z,c) = addCarry32( product[i] , big3.0[i] , carry );
|
||||
carry = c;
|
||||
product[i] = z;
|
||||
}
|
||||
// continue carrying
|
||||
for i in N..(N+N) {
|
||||
let (z,c) = addCarry32( product[i] , 0 , carry );
|
||||
carry = c;
|
||||
product[i] = z;
|
||||
}
|
||||
|
||||
BigInt(product)
|
||||
}
|
||||
|
||||
// x*y + (z << 256)
|
||||
#[inline(always)]
|
||||
pub fn mulAddShifted(big1: &BigInt<N>, big2: &BigInt<N>, big3: &BigInt<N>) -> BigInt<{N+N}> {
|
||||
// first compute the product
|
||||
let mut product : [u32; N+N] = [0; N+N];
|
||||
let mut state : [u32; N] = [0; N];
|
||||
for j in 0..N {
|
||||
let (scaled,carry) = BigInt::scaleAdd( big2.0[j], &big1, &BigInt(state) );
|
||||
product[j] = scaled.0[0];
|
||||
for i in 1..N { state[i-1] = scaled.0[i] }
|
||||
state[N-1] = carry;
|
||||
}
|
||||
for i in 0..N {
|
||||
product[i+N] = state[i]
|
||||
}
|
||||
|
||||
// then add the third number, shifted
|
||||
let mut carry: bool = false;
|
||||
for i in 0..N {
|
||||
let (z,c) = addCarry32( product[i+N] , big3.0[i] , carry );
|
||||
carry = c;
|
||||
product[i+N] = z;
|
||||
}
|
||||
|
||||
BigInt(product)
|
||||
}
|
||||
|
||||
// TODO: optimize this?!
|
||||
pub fn sqr_naive(big: &BigInt<N>) -> BigInt<{N+N}> {
|
||||
BigInt::multiply(big,big)
|
||||
|
||||
@ -93,6 +93,10 @@ impl Felt {
|
||||
Felt(Mont::convert_to_big(&mont))
|
||||
}
|
||||
|
||||
pub fn to_decimal_string(input: &Felt) -> String {
|
||||
BigInt::to_decimal_string(&input.0)
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
pub fn zero() -> Felt {
|
||||
|
||||
@ -43,6 +43,9 @@ impl Mont {
|
||||
BigInt::is_lt_prime(&mont.0)
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
// to/from bytes
|
||||
|
||||
// note: this exports the Montgomery representation!
|
||||
pub fn to_le_bytes(mont: &Mont) -> [u8; 32] {
|
||||
BigInt::to_le_bytes(&mont.0)
|
||||
@ -65,6 +68,10 @@ impl Mont {
|
||||
Mont(big)
|
||||
}
|
||||
|
||||
pub fn to_decimal_string(input: &Mont) -> String {
|
||||
BigInt::to_decimal_string(&Mont::convert_to_big(&input))
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
#[inline(always)]
|
||||
@ -109,6 +116,9 @@ impl Mont {
|
||||
Mont::add(&mont, &mont)
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
// reduction and multiplication
|
||||
|
||||
// the Montgomery reduction algorithm
|
||||
// <https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#Montgomery_arithmetic_on_multiprecision_integers>
|
||||
fn redc_safe(input: BigInt<16>) -> Big {
|
||||
@ -188,6 +198,15 @@ impl Mont {
|
||||
Mont(Mont::redc(large))
|
||||
}
|
||||
|
||||
// x*y + z
|
||||
pub fn mulAdd(mont1: &Mont, mont2: &Mont, mont3: &Mont) -> Mont {
|
||||
let large = BigInt::mulAddShifted(&mont1.0, &mont2.0, &mont3.0);
|
||||
Mont(Mont::redc(large))
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
// conversions
|
||||
|
||||
// this does conversion from the standard representation
|
||||
// we assume the input is in the range `[0..p-1]`
|
||||
pub fn unsafe_convert_from_big(input: &Big) -> Mont {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user