11use ark_std:: vec:: Vec ;
22
3+ /// Make 4 u64 multiplications, instead of 1 u128
4+ /// It's faster than __multi3 in wasm
5+ /// https://github.com/rust-lang/compiler-builtins/blob/4797774cd72e453e30785cfee684aaf68e16e03e/src/int/mul.rs#L108
6+ /// https://github.com/zkBob/fawkes-crypto/pull/15
7+ #[ cfg( target_family = "wasm" ) ]
8+ #[ inline( always) ]
9+ pub fn u64_mul_u64 ( x : u64 , y : u64 ) -> u128 {
10+ let x_low = ( x as u32 ) as u64 ;
11+ let x_high = x >> 32 ;
12+ let y_low = ( y as u32 ) as u64 ;
13+ let y_high = y >> 32 ;
14+
15+ let z_low = x_low * y_low;
16+ let z_high = x_high * y_high;
17+ let z = u128:: from ( x_low * y_high) + u128:: from ( x_high * y_low) ;
18+
19+ ( u128:: from ( z_high) << 64 ) + ( z << 32 ) + u128:: from ( z_low)
20+ }
21+
22+ #[ cfg( not( target_family = "wasm" ) ) ]
23+ #[ inline( always) ]
24+ pub fn u64_mul_u64 ( x : u64 , y : u64 ) -> u128 {
25+ u128:: from ( x) * u128:: from ( y)
26+ }
27+
328/// Calculate a + b + carry, returning the sum and modifying the
429/// carry value.
530macro_rules! adc {
@@ -15,6 +40,19 @@ macro_rules! adc {
1540/// Calculate a + (b * c) + carry, returning the least significant digit
1641/// and setting carry to the most significant digit.
1742macro_rules! mac_with_carry {
43+ ( $a: expr, $b: expr, $c: expr, & mut $carry: expr$( , ) ?) => { {
44+ let tmp = ( $a as u128 ) + crate :: biginteger:: arithmetic:: u64_mul_u64( $b, $c) + ( $carry as u128 ) ;
45+ // let tmp = ($a as u128) + ($b as u128 * $c as u128) + ($carry as u128);
46+
47+ $carry = ( tmp >> 64 ) as u64 ;
48+
49+ tmp as u64
50+ } } ;
51+ }
52+
53+ /// Calculate a + (b * c) + carry, returning the least significant digit
54+ /// and setting carry to the most significant digit.
55+ macro_rules! const_mac_with_carry {
1856 ( $a: expr, $b: expr, $c: expr, & mut $carry: expr$( , ) ?) => { {
1957 let tmp = ( $a as u128 ) + ( $b as u128 * $c as u128 ) + ( $carry as u128 ) ;
2058
@@ -38,7 +76,8 @@ macro_rules! sbb {
3876
3977#[ inline( always) ]
4078pub ( crate ) fn mac ( a : u64 , b : u64 , c : u64 , carry : & mut u64 ) -> u64 {
41- let tmp = ( u128:: from ( a) ) + u128:: from ( b) * u128:: from ( c) ;
79+ let tmp = ( u128:: from ( a) ) + u64_mul_u64 ( b, c) ;
80+ // let tmp = (u128::from(a)) + u128::from(b) * u128::from(c);
4281
4382 * carry = ( tmp >> 64 ) as u64 ;
4483
@@ -47,7 +86,8 @@ pub(crate) fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
4786
4887#[ inline( always) ]
4988pub ( crate ) fn mac_discard ( a : u64 , b : u64 , c : u64 , carry : & mut u64 ) {
50- let tmp = ( u128:: from ( a) ) + u128:: from ( b) * u128:: from ( c) ;
89+ let tmp = ( u128:: from ( a) ) + u64_mul_u64 ( b, c) ;
90+ // let tmp = (u128::from(a)) + u128::from(b) * u128::from(c);
5191
5292 * carry = ( tmp >> 64 ) as u64 ;
5393}
0 commit comments