Skip to content

Commit

Permalink
Squashed 'ff/' changes from 1eddf54c..9b9a8d9c
Browse files Browse the repository at this point in the history
REVERT: 1eddf54c Merge pull request privacy-scaling-explorations#94 from zkcrypto/trait-constants
REVERT: 6bf93ee5 Use associated constants of type `Self` in `Field` and `PrimeField`
REVERT: 9a844a72 Merge pull request privacy-scaling-explorations#93 from zkcrypto/field-trait-changes
REVERT: cc08c5ee Document that `Field::{sqrt, sqrt_alt}` provided impls use `sqrt_ratio`
REVERT: 58741b76 Add `ff::Field::{sqrt_ratio, sqrt_alt}`
REVERT: a35b5eb5 Merge pull request privacy-scaling-explorations#92 from zkcrypto/release-0.12.1
REVERT: b97576cf Add `ff::Field::pow`
REVERT: b98ca7f7 Release 0.12.1
REVERT: 7653f345 Merge pull request privacy-scaling-explorations#88 from GaloisInc/checked_shr
REVERT: 732b862b add test case
REVERT: 22bc4997 Update ff_derive/src/lib.rs
REVERT: 9ea208df Merge pull request privacy-scaling-explorations#83 from eqlabs/allow_clippy_on_mont_reduce
REVERT: bb379984 Use `checked_shr` instead of `>>` in `Field::random`
REVERT: 6a1c1e90 chore(derive): allow too_many_args at mont_reduce

git-subtree-dir: ff
git-subtree-split: 9b9a8d9c363ecbf7bb4c79998aaed32c1f8ce027
  • Loading branch information
jonathanpwang committed Nov 9, 2022
1 parent 0852b2e commit 2d7eb8e
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 290 deletions.
28 changes: 2 additions & 26 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,16 @@ and this library adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `ff::Field::{ZERO, ONE}`
- `ff::Field::pow`
- `ff::Field::{sqrt_ratio, sqrt_alt}`
- `ff::PrimeField::{MULTIPLICATIVE_GENERATOR, ROOT_OF_UNITY}`
- `ff::helpers`:
- `sqrt_tonelli_shanks`
- `sqrt_ratio_generic`

### Changed
- `ff::Field::sqrt` is now a provided method that uses the `Field::sqrt_ratio`
method. Implementors of the `Field` trait can choose to implement
`Field::sqrt_ratio` and use the provided `ff::Field::sqrt` method, especially
if it is more efficient in practice, or they can keep their own implementation
of `Field::sqrt` and implement `Field::sqrt_ratio` in terms of that
implementation using the `ff::helpers::sqrt_ratio_generic` helper function.

### Removed
- `ff::Field::{zero, one}` (use `ff::Field::{ZERO, ONE}` instead).
- `ff::PrimeField::{multiplicative_generator, root_of_unity}` (use
`ff::PrimeField::{MULTIPLICATIVE_GENERATOR, ROOT_OF_UNITY}` instead).

## [0.12.1] - 2022-10-28
### Fixed
- `ff_derive` previously generated a `Field::random` implementation that would
overflow for fields that needed a full 64-bit spare limb.

## [0.12.0] - 2022-05-04

### Changed

- MSRV is now 1.56.0.
- Bumped `bitvec` to 1.0.

## [0.11.1] - 2022-05-04

### Fixed
- `ff_derive` procedural macro can now be invoked within regular macros.
- Previously, `ff_derive`'s procedural macro would generate implementations of
Expand Down
7 changes: 2 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ff"
version = "0.12.1"
version = "0.12.0"
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <thestr4d@gmail.com>",
Expand All @@ -16,13 +16,10 @@ edition = "2021"
[dependencies]
bitvec = { version = "1", default-features = false, optional = true }
byteorder = { version = "1", default-features = false, optional = true }
ff_derive = { version = "0.12.1", path = "ff_derive", optional = true }
ff_derive = { version = "0.12", path = "ff_derive", optional = true }
rand_core = { version = "0.6", default-features = false }
subtle = { version = "2.2.1", default-features = false, features = ["i128"] }

[dev-dependencies]
rand = "0.8"

[features]
default = ["bits", "std"]
alloc = []
Expand Down
2 changes: 1 addition & 1 deletion ff_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ff_derive"
version = "0.12.1"
version = "0.12.0"
authors = [
"Sean Bowe <ewillbefull@gmail.com>",
"Jack Grigg <thestr4d@gmail.com>",
Expand Down
55 changes: 32 additions & 23 deletions ff_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,8 @@ fn validate_struct(ast: &syn::DeriveInput, limbs: usize) -> Option<proc_macro2::
syn::Expr::Group(expr_group) => match &*expr_group.expr {
syn::Expr::Lit(expr_lit) => Some(&expr_lit.lit),
_ => None,
},
_ => None,
}
_ => None
};
let lit_int = match match expr_lit {
Some(syn::Lit::Int(lit_int)) => Some(lit_int),
Expand Down Expand Up @@ -519,7 +519,7 @@ fn prime_field_constants_and_sqrt(
} else if (modulus % BigUint::from_str("16").unwrap()) == BigUint::from_str("1").unwrap() {
// Addition chain for (t - 1) // 2
let t_minus_1_over_2 = if t == BigUint::one() {
quote!( #name::ONE )
quote!( #name::one() )
} else {
pow_fixed::generate(&quote! {self}, (&t - BigUint::one()) >> 1)
};
Expand Down Expand Up @@ -547,7 +547,7 @@ fn prime_field_constants_and_sqrt(
let mut j_less_than_v: ::ff::derive::subtle::Choice = 1.into();

for j in 2..max_v {
let tmp_is_one = tmp.ct_eq(&#name::ONE);
let tmp_is_one = tmp.ct_eq(&#name::one());
let squared = #name::conditional_select(&tmp, &z, tmp_is_one).square();
tmp = #name::conditional_select(&squared, &tmp, tmp_is_one);
let new_z = #name::conditional_select(&z, &squared, tmp_is_one);
Expand All @@ -557,7 +557,7 @@ fn prime_field_constants_and_sqrt(
}

let result = x * &z;
x = #name::conditional_select(&result, &x, b.ct_eq(&#name::ONE));
x = #name::conditional_select(&result, &x, b.ct_eq(&#name::one()));
z = z.square();
b *= &z;
v = k;
Expand Down Expand Up @@ -841,6 +841,7 @@ fn prime_field_impl(
/// field.
fn inv_impl(
a: proc_macro2::TokenStream,
name: &syn::Ident,
modulus: &BigUint,
) -> proc_macro2::TokenStream {
// Addition chain for p - 2
Expand All @@ -859,13 +860,13 @@ fn prime_field_impl(
#mod_minus_2
};

::ff::derive::subtle::CtOption::new(inv, !#a.is_zero())
::ff::derive::subtle::CtOption::new(inv, !#a.ct_eq(&#name::zero()))
}
}

let squaring_impl = sqr_impl(quote! {self}, limbs);
let multiply_impl = mul_impl(quote! {self}, quote! {other}, limbs);
let invert_impl = inv_impl(quote! {self}, modulus);
let invert_impl = inv_impl(quote! {self}, name, modulus);
let montgomery_impl = mont_impl(limbs);

// self.0[0].ct_eq(&other.0[0]) & self.0[1].ct_eq(&other.0[1]) & ...
Expand Down Expand Up @@ -933,7 +934,7 @@ fn prime_field_impl(
impl ::core::default::Default for #name {
fn default() -> #name {
use ::ff::Field;
#name::ZERO
#name::zero()
}
}

Expand Down Expand Up @@ -1206,19 +1207,20 @@ fn prime_field_impl(

const CAPACITY: u32 = Self::NUM_BITS - 1;

const MULTIPLICATIVE_GENERATOR: Self = GENERATOR;
fn multiplicative_generator() -> Self {
GENERATOR
}

const S: u32 = S;

const ROOT_OF_UNITY: Self = ROOT_OF_UNITY;
fn root_of_unity() -> Self {
ROOT_OF_UNITY
}
}

#prime_field_bits_impl

impl ::ff::Field for #name {
const ZERO: Self = #name([0; #limbs]);
const ONE: Self = R;

/// Computes a uniformly random element using rejection sampling.
fn random(mut rng: impl ::ff::derive::rand_core::RngCore) -> Self {
loop {
Expand All @@ -1231,18 +1233,30 @@ fn prime_field_impl(
};

// Mask away the unused most-significant bits.
// Note: In some edge cases, `REPR_SHAVE_BITS` could be 64, in which case
// `0xfff... >> REPR_SHAVE_BITS` overflows. So use `checked_shr` instead.
// This is always sufficient because we will have at most one spare limb
// to accommodate values of up to twice the modulus.
tmp.0.as_mut()[#top_limb_index] &= 0xffffffffffffffffu64.checked_shr(REPR_SHAVE_BITS).unwrap_or(0);
tmp.0.as_mut()[#top_limb_index] &= 0xffffffffffffffff >> REPR_SHAVE_BITS;

if tmp.is_valid() {
return tmp
}
}
}

#[inline]
fn zero() -> Self {
#name([0; #limbs])
}

#[inline]
fn one() -> Self {
R
}

#[inline]
fn is_zero(&self) -> ::ff::derive::subtle::Choice {
use ::ff::derive::subtle::ConstantTimeEq;
self.ct_eq(&Self::zero())
}

#[inline]
fn is_zero_vartime(&self) -> bool {
self.0.iter().all(|&e| e == 0)
Expand Down Expand Up @@ -1277,10 +1291,6 @@ fn prime_field_impl(
#squaring_impl
}

fn sqrt_ratio(num: &Self, div: &Self) -> (::ff::derive::subtle::Choice, Self) {
::ff::helpers::sqrt_ratio_generic(num, div)
}

fn sqrt(&self) -> ::ff::derive::subtle::CtOption<Self> {
#sqrt_impl
}
Expand Down Expand Up @@ -1342,7 +1352,6 @@ fn prime_field_impl(
}
}

#[allow(clippy::too_many_arguments)]
#[inline(always)]
fn mont_reduce(
&mut self,
Expand Down
18 changes: 9 additions & 9 deletions src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,19 @@ where
I: IntoIterator<Item = &'a mut F>,
{
fn batch_invert(self) -> F {
let mut acc = F::ONE;
let mut acc = F::one();
let iter = self.into_iter();
let mut tmp = alloc::vec::Vec::with_capacity(iter.size_hint().0);
for p in iter {
let q = *p;
tmp.push((acc, p));
acc = F::conditional_select(&(acc * q), &acc, q.is_zero());
acc = F::conditional_select(&(acc * q), &acc, q.ct_eq(&F::zero()));
}
acc = acc.invert().unwrap();
let allinv = acc;

for (tmp, p) in tmp.into_iter().rev() {
let skip = p.is_zero();
let skip = p.ct_eq(&F::zero());

let tmp = tmp * acc;
acc = F::conditional_select(&(acc * *p), &acc, skip);
Expand Down Expand Up @@ -74,17 +74,17 @@ impl BatchInverter {
{
assert_eq!(elements.len(), scratch_space.len());

let mut acc = F::ONE;
let mut acc = F::one();
for (p, scratch) in elements.iter().zip(scratch_space.iter_mut()) {
*scratch = acc;
acc = F::conditional_select(&(acc * *p), &acc, p.is_zero());
acc = F::conditional_select(&(acc * *p), &acc, p.ct_eq(&F::zero()));
}
acc = acc.invert().unwrap();
let allinv = acc;

for (p, scratch) in elements.iter_mut().zip(scratch_space.iter()).rev() {
let tmp = *scratch * acc;
let skip = p.is_zero();
let skip = p.ct_eq(&F::zero());
acc = F::conditional_select(&(acc * *p), &acc, skip);
*p = F::conditional_select(&tmp, &p, skip);
}
Expand All @@ -109,19 +109,19 @@ impl BatchInverter {
TE: Fn(&mut T) -> &mut F,
TS: Fn(&mut T) -> &mut F,
{
let mut acc = F::ONE;
let mut acc = F::one();
for item in items.iter_mut() {
*(scratch_space)(item) = acc;
let p = (element)(item);
acc = F::conditional_select(&(acc * *p), &acc, p.is_zero());
acc = F::conditional_select(&(acc * *p), &acc, p.ct_eq(&F::zero()));
}
acc = acc.invert().unwrap();
let allinv = acc;

for item in items.iter_mut().rev() {
let tmp = *(scratch_space)(item) * acc;
let p = (element)(item);
let skip = p.is_zero();
let skip = p.ct_eq(&F::zero());
acc = F::conditional_select(&(acc * *p), &acc, skip);
*p = F::conditional_select(&tmp, &p, skip);
}
Expand Down
Loading

0 comments on commit 2d7eb8e

Please sign in to comment.