Skip to content

Commit

Permalink
Add Field::sum_of_products method
Browse files Browse the repository at this point in the history
Closes #79.
  • Loading branch information
str4d committed Apr 26, 2022
1 parent dcd0219 commit f8aae72
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub use bitvec::view::BitViewSized;

#[cfg(feature = "bits")]
use bitvec::{array::BitArray, order::Lsb0};
use core::array;
use core::fmt;
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
use rand_core::RngCore;
Expand Down Expand Up @@ -124,6 +125,20 @@ pub trait Field:

res
}

/// Returns `c = a.zip(b).fold(0, |acc, (a_i, b_i)| acc + a_i * b_i)`.
///
/// This computes the "dot product" or "inner product" `a ⋅ b`.
///
/// The provided implementation of this trait method uses the direct calculation given
/// above. Implementations of `Field` should override this to use more efficient
/// methods that take advantage of their internal representation, such as interleaving
/// or sharing modular reductions.
fn sum_of_products<const T: usize>(a: [Self; T], b: [Self; T]) -> Self {
array::IntoIter::new(a)
.zip(array::IntoIter::new(b))
.fold(Self::zero(), |acc, (a_i, b_i)| acc + a_i * b_i)
}
}

/// This represents an element of a prime field.
Expand Down
24 changes: 24 additions & 0 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ mod fermat {
struct Fermat65537Field([u64; 1]);
}

#[test]
fn sum_of_products() {
use std::convert::TryInto;

use ff::{Field, PrimeField};

let one = Bls381K12Scalar::one();

// [1, 2, 3, 4]
let values: Vec<_> = (0..4)
.scan(one, |acc, _| {
let ret = *acc;
*acc += &one;
Some(ret)
})
.collect();
let values: [_; 4] = values.try_into().unwrap();

assert_eq!(
Bls381K12Scalar::sum_of_products(values, values),
Bls381K12Scalar::from_str_vartime("30").unwrap()
);
}

#[test]
fn batch_inversion() {
use ff::{BatchInverter, Field};
Expand Down

0 comments on commit f8aae72

Please sign in to comment.