Skip to content

Commit

Permalink
Merge branch 'main' into feat/multilinear_sumcheck
Browse files Browse the repository at this point in the history
  • Loading branch information
diegokingston authored Mar 6, 2024
2 parents b513a20 + ea74b0a commit 9c3dde1
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 30 deletions.
6 changes: 1 addition & 5 deletions crypto/src/hash/monolith/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ fn random_field_element(shake: &mut Shake128Reader) -> u32 {
}

pub fn dot_product(u: &[u32], v: &[u32]) -> u32 {
u.iter()
.zip(v)
.map(|(x, y)| F::mul(x, y))
.reduce(|a, b| F::add(&a, &b))
.unwrap()
Mersenne31Field::sum(u.iter().zip(v).map(|(x, y)| F::mul(x, y)))
}

pub fn get_random_y_i(
Expand Down
26 changes: 19 additions & 7 deletions math/src/field/fields/mersenne31/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ impl Mersenne31Field {
*n
}
}

#[inline]
pub fn sum<I: Iterator<Item = <Self as IsField>::BaseType>>(
iter: I,
) -> <Self as IsField>::BaseType {
// Delayed reduction
Self::from_u64(iter.map(|x| (x as u64)).sum::<u64>())
}
}

pub const MERSENNE_31_PRIME_FIELD_ORDER: u32 = (1 << 31) - 1;
Expand Down Expand Up @@ -63,12 +71,7 @@ impl IsField for Mersenne31Field {
/// Returns the multiplication of `a` and `b`.
// Note: for powers of 2 we can perform bit shifting this would involve overriding the trait implementation
fn mul(a: &u32, b: &u32) -> u32 {
let prod = u64::from(*a) * u64::from(*b);
let prod_lo = (prod as u32) & ((1 << 31) - 1);
let prod_hi = (prod >> 31) as u32;
//assert prod_hi and prod_lo 31 bit clear
debug_assert!((prod_lo >> 31) == 0 && (prod_hi >> 31) == 0);
Self::add(&prod_lo, &prod_hi)
Self::from_u64(u64::from(*a) * u64::from(*b))
}

fn sub(a: &u32, b: &u32) -> u32 {
Expand Down Expand Up @@ -201,14 +204,23 @@ impl Display for FieldElement<Mersenne31Field> {
#[cfg(test)]
mod tests {
use super::*;

type F = Mersenne31Field;

#[test]
fn from_hex_for_b_is_11() {
assert_eq!(F::from_hex("B").unwrap(), 11);
}

#[test]
fn sum_delayed_reduction() {
let up_to = u32::pow(2, 23);
let pow = u64::pow(2, 60);

let iter = (0..up_to).map(F::weak_reduce).map(|e| F::pow(&e, pow));

assert_eq!(F::from_u64(1314320703), F::sum(iter));
}

#[test]
fn from_hex_for_0x1_a_is_26() {
assert_eq!(F::from_hex("0x1a").unwrap(), 26);
Expand Down
30 changes: 12 additions & 18 deletions math/src/unsigned_integer/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,12 @@ impl<const NUM_LIMBS: usize> ShrAssign<usize> for UnsignedInteger<NUM_LIMBS> {
impl<const NUM_LIMBS: usize> BitAnd for UnsignedInteger<NUM_LIMBS> {
type Output = Self;

#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
let Self { mut limbs } = self;

for (a_i, b_i) in limbs.iter_mut().zip(rhs.limbs.iter()) {
*a_i &= b_i;
}
Self { limbs }
let mut result = self;
result &= rhs;
result
}
}

Expand All @@ -345,14 +343,12 @@ impl<const NUM_LIMBS: usize> BitAndAssign for UnsignedInteger<NUM_LIMBS> {
impl<const NUM_LIMBS: usize> BitOr for UnsignedInteger<NUM_LIMBS> {
type Output = Self;

#[inline(always)]
fn bitor(self, rhs: Self) -> Self::Output {
let Self { mut limbs } = self;

for (a_i, b_i) in limbs.iter_mut().zip(rhs.limbs.iter()) {
*a_i |= b_i;
}
Self { limbs }
let mut result = self;
result |= rhs;
result
}
}

Expand All @@ -369,14 +365,12 @@ impl<const NUM_LIMBS: usize> BitOrAssign for UnsignedInteger<NUM_LIMBS> {
impl<const NUM_LIMBS: usize> BitXor for UnsignedInteger<NUM_LIMBS> {
type Output = Self;

#[inline(always)]
fn bitxor(self, rhs: Self) -> Self::Output {
let Self { mut limbs } = self;

for (a_i, b_i) in limbs.iter_mut().zip(rhs.limbs.iter()) {
*a_i ^= b_i;
}
Self { limbs }
let mut result = self;
result ^= rhs;
result
}
}

Expand Down

0 comments on commit 9c3dde1

Please sign in to comment.