Skip to content

Commit

Permalink
Merge branch 'master' into merge-dense-mle
Browse files Browse the repository at this point in the history
  • Loading branch information
mmagician committed Jun 19, 2024
2 parents 4ecd7a8 + 8183072 commit 06dfcf7
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 5 deletions.
33 changes: 28 additions & 5 deletions ff/src/biginteger/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,34 @@ pub fn sbb_for_sub_with_borrow(a: &mut u64, b: u64, borrow: u8) -> u8 {
}
}

#[inline(always)]
#[doc(hidden)]
pub const fn widening_mul(a: u64, b: u64) -> u128 {
#[cfg(not(target_family = "wasm"))]
{
a as u128 * b as u128
}
#[cfg(target_family = "wasm")]
{
let a_lo = a as u32 as u64;
let a_hi = a >> 32;
let b_lo = b as u32 as u64;
let b_hi = b >> 32;

let lolo = (a_lo * b_lo) as u128;
let lohi = ((a_lo * b_hi) as u128) << 32;
let hilo = ((a_hi * b_lo) as u128) << 32;
let hihi = ((a_hi * b_hi) as u128) << 64;
(lolo | hihi) + (lohi + hilo)
}
}

/// Calculate a + b * c, returning the lower 64 bits of the result and setting
/// `carry` to the upper 64 bits.
#[inline(always)]
#[doc(hidden)]
pub fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (a as u128) + (b as u128 * c as u128);
let tmp = (a as u128) + widening_mul(b, c);
*carry = (tmp >> 64) as u64;
tmp as u64
}
Expand All @@ -97,21 +119,22 @@ pub fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
#[inline(always)]
#[doc(hidden)]
pub fn mac_discard(a: u64, b: u64, c: u64, carry: &mut u64) {
let tmp = (a as u128) + (b as u128 * c as u128);
let tmp = (a as u128) + widening_mul(b, c);
*carry = (tmp >> 64) as u64;
}

macro_rules! mac_with_carry {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128 * $c as u128) + ($carry as u128);
let tmp =
($a as u128) + $crate::biginteger::arithmetic::widening_mul($b, $c) + ($carry as u128);
$carry = (tmp >> 64) as u64;
tmp as u64
}};
}

macro_rules! mac {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128 * $c as u128);
let tmp = ($a as u128) + $crate::biginteger::arithmetic::widening_mul($b, $c);
$carry = (tmp >> 64) as u64;
tmp as u64
}};
Expand All @@ -122,7 +145,7 @@ macro_rules! mac {
#[inline(always)]
#[doc(hidden)]
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (a as u128) + (b as u128 * c as u128) + (*carry as u128);
let tmp = (a as u128) + widening_mul(b, c) + (*carry as u128);
*carry = (tmp >> 64) as u64;
tmp as u64
}
Expand Down
2 changes: 2 additions & 0 deletions ff/src/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ pub trait Field:
}
Some(res)
}

fn mul_by_base_prime_field(&self, elem: &Self::BasePrimeField) -> Self;
}

// Given a vector of field elements {v_i}, compute the vector {v_i^(-1)}
Expand Down
8 changes: 8 additions & 0 deletions ff/src/fields/models/cubic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,14 @@ impl<P: CubicExtConfig> Field for CubicExtField<P> {

P::mul_base_field_by_frob_coeff(&mut self.c1, &mut self.c2, power);
}

fn mul_by_base_prime_field(&self, elem: &Self::BasePrimeField) -> Self {
let mut result = *self;
result.c0 = result.c0.mul_by_base_prime_field(elem);
result.c1 = result.c1.mul_by_base_prime_field(elem);
result.c2 = result.c2.mul_by_base_prime_field(elem);
result
}
}

/// `CubicExtField` elements are ordered lexicographically.
Expand Down
6 changes: 6 additions & 0 deletions ff/src/fields/models/fp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,12 @@ impl<P: FpConfig<N>, const N: usize> Field for Fp<P, N> {
QuadraticNonResidue
}
}

/// Fp is already a "BasePrimeField", so it's just mul by self
#[inline]
fn mul_by_base_prime_field(&self, elem: &Self::BasePrimeField) -> Self {
*self * elem
}
}

impl<P: FpConfig<N>, const N: usize> PrimeField for Fp<P, N> {
Expand Down
7 changes: 7 additions & 0 deletions ff/src/fields/models/quadratic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,13 @@ impl<P: QuadExtConfig> Field for QuadExtField<P> {
self
})
}

fn mul_by_base_prime_field(&self, elem: &Self::BasePrimeField) -> Self {
let mut result = *self;
result.c0 = result.c0.mul_by_base_prime_field(elem);
result.c1 = result.c1.mul_by_base_prime_field(elem);
result
}
}

/// `QuadExtField` elements are ordered lexicographically.
Expand Down
21 changes: 21 additions & 0 deletions test-templates/src/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,27 @@ macro_rules! __test_field {
}
}
}


#[test]
fn test_mul_by_base_field_elem() {
use ark_std::UniformRand;
let rng = &mut test_rng();

for _ in 0..ITERATIONS {
let a = vec![<<$field as Field>::BasePrimeField>::rand(rng); <$field>::extension_degree() as usize];
let b = <<$field as Field>::BasePrimeField>::rand(rng);

let mut a = <$field>::from_base_prime_field_elems(a).unwrap();
let computed = a.mul_by_base_prime_field(&b);

let embedded_b = <$field as Field>::from_base_prime_field(b);

let naive = a*embedded_b;

assert_eq!(computed, naive);
}
}
};
($field: ty; fft) => {
$crate::__test_field!($field);
Expand Down

0 comments on commit 06dfcf7

Please sign in to comment.