Skip to content

Commit

Permalink
Merge pull request #97 from zkcrypto/field-sum-prod
Browse files Browse the repository at this point in the history
Add `core::iter::{Sum, Product}` bounds on `Field`
  • Loading branch information
str4d authored Nov 19, 2022
2 parents 1eddf54 + 3c7ceee commit c070ffb
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this library adheres to Rust's notion of
- `ff::Field::{ZERO, ONE}`
- `ff::Field::pow`
- `ff::Field::{sqrt_ratio, sqrt_alt}`
- `core::iter::{Sum, Product}` bounds on `ff::Field`
- `ff::PrimeField::{MULTIPLICATIVE_GENERATOR, ROOT_OF_UNITY}`
- `ff::helpers`:
- `sqrt_tonelli_shanks`
Expand Down
21 changes: 17 additions & 4 deletions ff_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,10 +839,7 @@ fn prime_field_impl(

/// Generates an implementation of multiplicative inversion within the target prime
/// field.
fn inv_impl(
a: proc_macro2::TokenStream,
modulus: &BigUint,
) -> proc_macro2::TokenStream {
fn inv_impl(a: proc_macro2::TokenStream, modulus: &BigUint) -> proc_macro2::TokenStream {
// Addition chain for p - 2
let mod_minus_2 = pow_fixed::generate(&a, modulus - BigUint::from(2u64));

Expand Down Expand Up @@ -1155,6 +1152,22 @@ fn prime_field_impl(
}
}

impl<T: ::core::borrow::Borrow<#name>> ::core::iter::Sum<T> for #name {
fn sum<I: Iterator<Item = T>>(iter: I) -> Self {
use ::ff::Field;

iter.fold(Self::ZERO, |acc, item| acc + item.borrow())
}
}

impl<T: ::core::borrow::Borrow<#name>> ::core::iter::Product<T> for #name {
fn product<I: Iterator<Item = T>>(iter: I) -> Self {
use ::ff::Field;

iter.fold(Self::ONE, |acc, item| acc * item.borrow())
}
}

impl ::ff::PrimeField for #name {
type Repr = #repr;

Expand Down
15 changes: 11 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,11 @@ pub use bitvec::view::BitViewSized;

#[cfg(feature = "bits")]
use bitvec::{array::BitArray, order::Lsb0};

use core::fmt;
use core::iter::{Product, Sum};
use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};

use rand_core::RngCore;
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};

Expand All @@ -47,19 +50,23 @@ pub trait Field:
+ 'static
+ ConditionallySelectable
+ ConstantTimeEq
+ Neg<Output = Self>
+ Add<Output = Self>
+ Sub<Output = Self>
+ Mul<Output = Self>
+ Neg<Output = Self>
+ Sum
+ Product
+ for<'a> Add<&'a Self, Output = Self>
+ for<'a> Mul<&'a Self, Output = Self>
+ for<'a> Sub<&'a Self, Output = Self>
+ MulAssign
+ for<'a> Mul<&'a Self, Output = Self>
+ for<'a> Sum<&'a Self>
+ for<'a> Product<&'a Self>
+ AddAssign
+ SubAssign
+ for<'a> MulAssign<&'a Self>
+ MulAssign
+ for<'a> AddAssign<&'a Self>
+ for<'a> SubAssign<&'a Self>
+ for<'a> MulAssign<&'a Self>
{
/// The zero element of the field, the additive identity.
const ZERO: Self;
Expand Down

0 comments on commit c070ffb

Please sign in to comment.