Browse Source

Upgrade to work with latest `ark-ff` (#90)

Co-authored-by: Sun <huachuang20@gmail.com>
Co-authored-by: Pratyush Mishra <pratyushmishra@berkeley.edu>
master
Weikeng Chen 2 years ago
committed by GitHub
parent
commit
b7874406ec
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 426 additions and 388 deletions
  1. +14
    -4
      .github/workflows/ci.yml
  2. +17
    -1
      Cargo.toml
  3. +1
    -1
      benches/bench.rs
  4. +63
    -63
      src/bits/boolean.rs
  5. +14
    -14
      src/bits/uint.rs
  6. +8
    -8
      src/bits/uint8.rs
  7. +22
    -22
      src/fields/cubic_extension.rs
  8. +8
    -8
      src/fields/fp/cmp.rs
  9. +19
    -19
      src/fields/fp/mod.rs
  10. +17
    -15
      src/fields/fp12.rs
  11. +3
    -3
      src/fields/fp2.rs
  12. +4
    -3
      src/fields/fp3.rs
  13. +5
    -4
      src/fields/fp4.rs
  14. +5
    -4
      src/fields/fp6_2over3.rs
  15. +13
    -12
      src/fields/fp6_3over2.rs
  16. +1
    -1
      src/fields/mod.rs
  17. +38
    -36
      src/fields/nonnative/allocated_field_var.rs
  18. +12
    -12
      src/fields/nonnative/allocated_mul_result.rs
  19. +11
    -11
      src/fields/nonnative/field_var.rs
  20. +2
    -2
      src/fields/nonnative/mod.rs
  21. +1
    -1
      src/fields/nonnative/mul_result.rs
  22. +7
    -7
      src/fields/nonnative/params.rs
  23. +28
    -24
      src/fields/nonnative/reduce.rs
  24. +22
    -22
      src/fields/quadratic_extension.rs
  25. +5
    -5
      src/groups/curves/short_weierstrass/bls12/mod.rs
  26. +17
    -17
      src/groups/curves/short_weierstrass/mnt4/mod.rs
  27. +17
    -17
      src/groups/curves/short_weierstrass/mnt6/mod.rs
  28. +9
    -9
      src/groups/curves/short_weierstrass/mod.rs
  29. +6
    -6
      src/groups/curves/twisted_edwards/mod.rs
  30. +6
    -6
      src/pairing/bls12/mod.rs
  31. +2
    -2
      src/pairing/mnt4/mod.rs
  32. +2
    -2
      src/pairing/mnt6/mod.rs
  33. +1
    -1
      src/poly/domain/mod.rs
  34. +1
    -1
      src/poly/evaluations/univariate/lagrange_interpolator.rs
  35. +1
    -1
      src/poly/evaluations/univariate/mod.rs
  36. +24
    -24
      tests/arithmetic_tests.rs

+ 14
- 4
.github/workflows/ci.yml

@ -176,10 +176,20 @@ jobs:
- name: Patch cargo.toml - name: Patch cargo.toml
run: | run: |
if ! grep -q "\[patch.crates-io\]" Cargo.toml ; then
echo "[patch.crates-io]" >> Cargo.toml
if grep -q "\[patch.crates-io\]" Cargo.toml ; then
MATCH=$(awk '/\[patch.crates-io\]/{ print NR; exit }' Cargo.toml);
sed -i "$MATCH,\$d" Cargo.toml
fi fi
echo "ark-r1cs-std = { path = 'r1cs-std' }" >> Cargo.toml
{
echo "[patch.crates-io]"
echo "ark-std = { git = 'https://github.com/arkworks-rs/std' }"
echo "ark-ec = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-ff = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-poly = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-serialize = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-algebra-test-templates = { git = 'https://github.com/arkworks-rs/algebra' }"
echo "ark-r1cs-std = { path = 'r1cs-std' }"
} >> Cargo.toml
- name: Test on ${{ matrix.curve }} - name: Test on ${{ matrix.curve }}
run: "cd ${{ matrix.curve }} && cargo test --features 'r1cs'" run: "cd ${{ matrix.curve }} && cargo test --features 'r1cs'"

+ 17
- 1
Cargo.toml

@ -50,4 +50,20 @@ parallel = [ "std", "ark-ff/parallel", "ark-std/parallel"]
[[bench]] [[bench]]
name = "nonnative-bench" name = "nonnative-bench"
path = "benches/bench.rs" path = "benches/bench.rs"
harness = false
harness = false
# To be removed in the new release.
[patch.crates-io]
ark-std = { git = "https://github.com/arkworks-rs/std" }
ark-ec = { git = "https://github.com/arkworks-rs/algebra" }
ark-ff = { git = "https://github.com/arkworks-rs/algebra" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra" }
ark-serialize = { git = "https://github.com/arkworks-rs/algebra" }
ark-test-curves = { git = "https://github.com/arkworks-rs/algebra" }
ark-bls12-381 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-bls12-377 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-mnt4-298 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-mnt4-753 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-mnt6-298 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-mnt6-753 = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }
ark-pallas = { git = "https://github.com/sunhuachuang/curves", branch = "upgrade-ff" }

+ 1
- 1
benches/bench.rs

@ -19,7 +19,7 @@ fn get_density(cs: &ConstraintSystemRef) -> us
let matrices = cs_bak.to_matrices().unwrap(); let matrices = cs_bak.to_matrices().unwrap();
matrices.a_num_non_zero + matrices.b_num_non_zero + matrices.c_num_non_zero matrices.a_num_non_zero + matrices.b_num_non_zero + matrices.c_num_non_zero
}
},
} }
} }

+ 63
- 63
src/bits/boolean.rs

@ -1,4 +1,4 @@
use ark_ff::{BitIteratorBE, Field, FpParameters, PrimeField};
use ark_ff::{BitIteratorBE, Field, PrimeField};
use crate::{fields::fp::FpVar, prelude::*, Assignment, ToConstraintFieldGadget, Vec}; use crate::{fields::fp::FpVar, prelude::*, Assignment, ToConstraintFieldGadget, Vec};
use ark_relations::r1cs::{ use ark_relations::r1cs::{
@ -396,7 +396,7 @@ impl Boolean {
// a XOR (NOT b) = NOT(a XOR b) // a XOR (NOT b) = NOT(a XOR b)
(is @ &Is(_), not @ &Not(_)) | (not @ &Not(_), is @ &Is(_)) => { (is @ &Is(_), not @ &Not(_)) | (not @ &Not(_), is @ &Is(_)) => {
Ok(is.xor(&not.not())?.not()) Ok(is.xor(&not.not())?.not())
}
},
// a XOR b = (NOT a) XOR (NOT b) // a XOR b = (NOT a) XOR (NOT b)
(&Is(ref a), &Is(ref b)) | (&Not(ref a), &Not(ref b)) => Ok(Is(a.xor(b)?)), (&Is(ref a), &Is(ref b)) | (&Not(ref a), &Not(ref b)) => Ok(Is(a.xor(b)?)),
} }
@ -438,7 +438,7 @@ impl Boolean {
// a OR b = NOT ((NOT a) AND (NOT b)) // a OR b = NOT ((NOT a) AND (NOT b))
(a @ &Is(_), b @ &Not(_)) | (b @ &Not(_), a @ &Is(_)) | (b @ &Not(_), a @ &Not(_)) => { (a @ &Is(_), b @ &Not(_)) | (b @ &Not(_), a @ &Is(_)) | (b @ &Not(_), a @ &Not(_)) => {
Ok(a.not().and(&b.not())?.not()) Ok(a.not().and(&b.not())?.not())
}
},
(&Is(ref a), &Is(ref b)) => a.or(b).map(From::from), (&Is(ref a), &Is(ref b)) => a.or(b).map(From::from),
} }
} }
@ -604,7 +604,7 @@ impl Boolean {
Is(_) | Not(_) => { Is(_) | Not(_) => {
r.cs() r.cs()
.enforce_constraint(r.lc(), lc!() + Variable::One, lc!() + Variable::One) .enforce_constraint(r.lc(), lc!() + Variable::One, lc!() + Variable::One)
}
},
} }
} }
@ -651,7 +651,7 @@ impl Boolean {
// If the number of bits is less than the size of the field, // If the number of bits is less than the size of the field,
// then we do not need to enforce that the element is less than // then we do not need to enforce that the element is less than
// the modulus. // the modulus.
if bits.len() >= F::Params::MODULUS_BITS as usize {
if bits.len() >= F::MODULUS_BIT_SIZE as usize {
Self::enforce_in_field_le(bits)?; Self::enforce_in_field_le(bits)?;
} }
Ok(crate::fields::fp::AllocatedFp::new(value, variable, cs.clone()).into()) Ok(crate::fields::fp::AllocatedFp::new(value, variable, cs.clone()).into())
@ -946,7 +946,7 @@ impl CondSelectGadget for Boolean {
)?; )?;
Ok(result) Ok(result)
}
},
}, },
} }
} }
@ -1247,30 +1247,30 @@ mod test {
(OpType::AllocatedTrue, OpType::False, Boolean::Is(_)) => (), (OpType::AllocatedTrue, OpType::False, Boolean::Is(_)) => (),
(OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Not(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedFalse, OpType::True, Boolean::Not(_)) => (), (OpType::AllocatedFalse, OpType::True, Boolean::Not(_)) => (),
(OpType::AllocatedFalse, OpType::False, Boolean::Is(_)) => (), (OpType::AllocatedFalse, OpType::False, Boolean::Is(_)) => (),
(OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { (OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::AllocatedFalse, OpType::AllocatedFalse,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
@ -1278,18 +1278,18 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::True, Boolean::Is(_)) => (), (OpType::NegatedAllocatedTrue, OpType::True, Boolean::Is(_)) => (),
(OpType::NegatedAllocatedTrue, OpType::False, Boolean::Not(_)) => (), (OpType::NegatedAllocatedTrue, OpType::False, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Not(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
@ -1297,7 +1297,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
@ -1305,14 +1305,14 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::NegatedAllocatedFalse, OpType::True, Boolean::Is(_)) => (), (OpType::NegatedAllocatedFalse, OpType::True, Boolean::Is(_)) => (),
(OpType::NegatedAllocatedFalse, OpType::False, Boolean::Not(_)) => (), (OpType::NegatedAllocatedFalse, OpType::False, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::AllocatedFalse, OpType::AllocatedFalse,
@ -1320,7 +1320,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
@ -1328,7 +1328,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
@ -1336,7 +1336,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
_ => unreachable!(), _ => unreachable!(),
} }
@ -1409,85 +1409,85 @@ mod test {
(OpType::AllocatedTrue, OpType::False, Boolean::Is(_)) => (), (OpType::AllocatedTrue, OpType::False, Boolean::Is(_)) => (),
(OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Not(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::True, Boolean::Constant(true)) => (), (OpType::AllocatedFalse, OpType::True, Boolean::Constant(true)) => (),
(OpType::AllocatedFalse, OpType::False, Boolean::Is(_)) => (), (OpType::AllocatedFalse, OpType::False, Boolean::Is(_)) => (),
(OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => { (OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::AllocatedFalse, OpType::AllocatedFalse,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::True, Boolean::Constant(true)) => (), (OpType::NegatedAllocatedTrue, OpType::True, Boolean::Constant(true)) => (),
(OpType::NegatedAllocatedTrue, OpType::False, Boolean::Not(_)) => (), (OpType::NegatedAllocatedTrue, OpType::False, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedFalse, OpType::True, Boolean::Constant(true)) => (), (OpType::NegatedAllocatedFalse, OpType::True, Boolean::Constant(true)) => (),
(OpType::NegatedAllocatedFalse, OpType::False, Boolean::Not(_)) => (), (OpType::NegatedAllocatedFalse, OpType::False, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Not(ref v)) => { (OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Not(ref v)) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::AllocatedFalse, OpType::AllocatedFalse,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
Boolean::Not(ref v), Boolean::Not(ref v),
) => { ) => {
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
_ => panic!( _ => panic!(
"this should never be encountered, in case: (a = {:?}, b = {:?}, c = {:?})", "this should never be encountered, in case: (a = {:?}, b = {:?}, c = {:?})",
@ -1531,49 +1531,49 @@ mod test {
(OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedTrue, OpType::NegatedAllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::AllocatedFalse, OpType::True, Boolean::Is(_)) => (), (OpType::AllocatedFalse, OpType::True, Boolean::Is(_)) => (),
(OpType::AllocatedFalse, OpType::False, Boolean::Constant(false)) => (), (OpType::AllocatedFalse, OpType::False, Boolean::Constant(false)) => (),
(OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::NegatedAllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::AllocatedFalse, OpType::NegatedAllocatedFalse, Boolean::Is(ref v)) => { (OpType::AllocatedFalse, OpType::NegatedAllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::True, Boolean::Not(_)) => (), (OpType::NegatedAllocatedTrue, OpType::True, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedTrue, OpType::False, Boolean::Constant(false)) => (), (OpType::NegatedAllocatedTrue, OpType::False, Boolean::Constant(false)) => (),
(OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::NegatedAllocatedTrue, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
@ -1581,7 +1581,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
@ -1589,18 +1589,18 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
(OpType::NegatedAllocatedFalse, OpType::True, Boolean::Not(_)) => (), (OpType::NegatedAllocatedFalse, OpType::True, Boolean::Not(_)) => (),
(OpType::NegatedAllocatedFalse, OpType::False, Boolean::Constant(false)) => (), (OpType::NegatedAllocatedFalse, OpType::False, Boolean::Constant(false)) => (),
(OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => { (OpType::NegatedAllocatedFalse, OpType::AllocatedTrue, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
(OpType::NegatedAllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => { (OpType::NegatedAllocatedFalse, OpType::AllocatedFalse, Boolean::Is(ref v)) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedTrue, OpType::NegatedAllocatedTrue,
@ -1608,7 +1608,7 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::zero());
assert_eq!(v.value(), Ok(false)); assert_eq!(v.value(), Ok(false));
}
},
( (
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
OpType::NegatedAllocatedFalse, OpType::NegatedAllocatedFalse,
@ -1616,14 +1616,14 @@ mod test {
) => { ) => {
assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one()); assert_eq!(cs.assigned_value(v.variable()).unwrap(), Fr::one());
assert_eq!(v.value(), Ok(true)); assert_eq!(v.value(), Ok(true));
}
},
_ => { _ => {
panic!( panic!(
"unexpected behavior at {:?} AND {:?}", "unexpected behavior at {:?} AND {:?}",
first_operand, second_operand first_operand, second_operand
); );
}
},
} }
} }
} }
@ -1642,9 +1642,9 @@ mod test {
let cs = ConstraintSystem::<Fr>::new_ref(); let cs = ConstraintSystem::<Fr>::new_ref();
let native_bits: Vec<_> = BitIteratorLE::new(r.into_repr()).collect();
let native_bits: Vec<_> = BitIteratorLE::new(r.into_bigint()).collect();
let bits = Vec::new_witness(cs.clone(), || Ok(native_bits))?; let bits = Vec::new_witness(cs.clone(), || Ok(native_bits))?;
Boolean::enforce_smaller_or_equal_than_le(&bits, s.into_repr())?;
Boolean::enforce_smaller_or_equal_than_le(&bits, s.into_bigint())?;
assert!(cs.is_satisfied().unwrap()); assert!(cs.is_satisfied().unwrap());
} }
@ -1658,11 +1658,11 @@ mod test {
let s2 = r.double(); let s2 = r.double();
let cs = ConstraintSystem::<Fr>::new_ref(); let cs = ConstraintSystem::<Fr>::new_ref();
let native_bits: Vec<_> = BitIteratorLE::new(r.into_repr()).collect();
let native_bits: Vec<_> = BitIteratorLE::new(r.into_bigint()).collect();
let bits = Vec::new_witness(cs.clone(), || Ok(native_bits))?; let bits = Vec::new_witness(cs.clone(), || Ok(native_bits))?;
Boolean::enforce_smaller_or_equal_than_le(&bits, s.into_repr())?;
Boolean::enforce_smaller_or_equal_than_le(&bits, s.into_bigint())?;
if r < s2 { if r < s2 {
Boolean::enforce_smaller_or_equal_than_le(&bits, s2.into_repr())?;
Boolean::enforce_smaller_or_equal_than_le(&bits, s2.into_bigint())?;
} }
assert!(cs.is_satisfied().unwrap()); assert!(cs.is_satisfied().unwrap());
@ -1693,7 +1693,7 @@ mod test {
let cs = ConstraintSystem::<Fr>::new_ref(); let cs = ConstraintSystem::<Fr>::new_ref();
let mut bits = vec![]; let mut bits = vec![];
for b in BitIteratorBE::new(r.into_repr()).skip(1) {
for b in BitIteratorBE::new(r.into_bigint()).skip(1) {
bits.push(Boolean::new_witness(cs.clone(), || Ok(b))?); bits.push(Boolean::new_witness(cs.clone(), || Ok(b))?);
} }
bits.reverse(); bits.reverse();
@ -1796,7 +1796,7 @@ mod test {
for &mode in modes.iter() { for &mode in modes.iter() {
for _ in 0..1000 { for _ in 0..1000 {
let f = Fr::rand(rng); let f = Fr::rand(rng);
let bits = BitIteratorLE::new(f.into_repr()).collect::<Vec<_>>();
let bits = BitIteratorLE::new(f.into_bigint()).collect::<Vec<_>>();
let bits: Vec<_> = let bits: Vec<_> =
AllocVar::new_variable(cs.clone(), || Ok(bits.as_slice()), mode)?; AllocVar::new_variable(cs.clone(), || Ok(bits.as_slice()), mode)?;
let f = AllocVar::new_variable(cs.clone(), || Ok(f), mode)?; let f = AllocVar::new_variable(cs.clone(), || Ok(f), mode)?;
@ -1806,7 +1806,7 @@ mod test {
for _ in 0..1000 { for _ in 0..1000 {
let f = Fr::from(u64::rand(rng)); let f = Fr::from(u64::rand(rng));
let bits = BitIteratorLE::new(f.into_repr()).collect::<Vec<_>>();
let bits = BitIteratorLE::new(f.into_bigint()).collect::<Vec<_>>();
let bits: Vec<_> = let bits: Vec<_> =
AllocVar::new_variable(cs.clone(), || Ok(bits.as_slice()), mode)?; AllocVar::new_variable(cs.clone(), || Ok(bits.as_slice()), mode)?;
let f = AllocVar::new_variable(cs.clone(), || Ok(f), mode)?; let f = AllocVar::new_variable(cs.clone(), || Ok(f), mode)?;

+ 14
- 14
src/bits/uint.rs

@ -6,7 +6,7 @@ macro_rules! make_uint {
#[doc = $native_doc_name] #[doc = $native_doc_name]
#[doc = " type."] #[doc = " type."]
pub mod $mod_name { pub mod $mod_name {
use ark_ff::{Field, FpParameters, One, PrimeField, Zero};
use ark_ff::{Field, One, PrimeField, Zero};
use core::borrow::Borrow; use core::borrow::Borrow;
use core::convert::TryFrom; use core::convert::TryFrom;
use num_bigint::BigUint; use num_bigint::BigUint;
@ -103,17 +103,17 @@ macro_rules! make_uint {
match *b { match *b {
Boolean::Constant(b) => { Boolean::Constant(b) => {
value.as_mut().map(|v| *v |= $native::from(b)); value.as_mut().map(|v| *v |= $native::from(b));
}
},
Boolean::Is(ref b) => match b.value() { Boolean::Is(ref b) => match b.value() {
Ok(b) => { Ok(b) => {
value.as_mut().map(|v| *v |= $native::from(b)); value.as_mut().map(|v| *v |= $native::from(b));
}
},
Err(_) => value = None, Err(_) => value = None,
}, },
Boolean::Not(ref b) => match b.value() { Boolean::Not(ref b) => match b.value() {
Ok(b) => { Ok(b) => {
value.as_mut().map(|v| *v |= $native::from(!b)); value.as_mut().map(|v| *v |= $native::from(!b));
}
},
Err(_) => value = None, Err(_) => value = None,
}, },
} }
@ -171,13 +171,13 @@ macro_rules! make_uint {
{ {
// Make some arbitrary bounds for ourselves to avoid overflows // Make some arbitrary bounds for ourselves to avoid overflows
// in the scalar field // in the scalar field
assert!(F::Params::MODULUS_BITS >= 2 * $size);
assert!(F::MODULUS_BIT_SIZE >= 2 * $size);
// Support up to 128 // Support up to 128
assert!($size <= 128); assert!($size <= 128);
assert!(operands.len() >= 1); assert!(operands.len() >= 1);
assert!($size * operands.len() <= F::Params::MODULUS_BITS as usize);
assert!($size * operands.len() <= F::MODULUS_BIT_SIZE as usize);
if operands.len() == 1 { if operands.len() == 1 {
return Ok(operands[0].clone()); return Ok(operands[0].clone());
@ -202,13 +202,13 @@ macro_rules! make_uint {
match op.value { match op.value {
Some(val) => { Some(val) => {
result_value.as_mut().map(|v| *v += BigUint::from(val)); result_value.as_mut().map(|v| *v += BigUint::from(val));
}
},
None => { None => {
// If any of our operands have unknown value, we won't // If any of our operands have unknown value, we won't
// know the value of the result // know the value of the result
result_value = None; result_value = None;
}
},
} }
// Iterate over each bit_gadget of the operand and add the operand to // Iterate over each bit_gadget of the operand and add the operand to
@ -221,18 +221,18 @@ macro_rules! make_uint {
// Add coeff * bit_gadget // Add coeff * bit_gadget
lc += (coeff, bit.variable()); lc += (coeff, bit.variable());
}
},
Boolean::Not(ref bit) => { Boolean::Not(ref bit) => {
all_constants = false; all_constants = false;
// Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget // Add coeff * (1 - bit_gadget) = coeff * ONE - coeff * bit_gadget
lc = lc + (coeff, Variable::One) - (coeff, bit.variable()); lc = lc + (coeff, Variable::One) - (coeff, bit.variable());
}
},
Boolean::Constant(bit) => { Boolean::Constant(bit) => {
if bit { if bit {
lc += (coeff, Variable::One); lc += (coeff, Variable::One);
} }
}
},
} }
coeff.double_in_place(); coeff.double_in_place();
@ -407,7 +407,7 @@ macro_rules! make_uint {
match bit { match bit {
&Boolean::Constant(bit) => { &Boolean::Constant(bit) => {
assert_eq!(bit, ((b.value()? >> i) & 1 == 1)); assert_eq!(bit, ((b.value()? >> i) & 1 == 1));
}
},
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -416,8 +416,8 @@ macro_rules! make_uint {
for x in v.iter().zip(expected_to_be_same.iter()) { for x in v.iter().zip(expected_to_be_same.iter()) {
match x { match x {
(&Boolean::Constant(true), &Boolean::Constant(true)) => {}
(&Boolean::Constant(false), &Boolean::Constant(false)) => {}
(&Boolean::Constant(true), &Boolean::Constant(true)) => {},
(&Boolean::Constant(false), &Boolean::Constant(false)) => {},
_ => unreachable!(), _ => unreachable!(),
} }
} }

+ 8
- 8
src/bits/uint8.rs

@ -1,4 +1,4 @@
use ark_ff::{Field, FpParameters, PrimeField, ToConstraintField};
use ark_ff::{Field, PrimeField, ToConstraintField};
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};
@ -152,7 +152,7 @@ impl UInt8 {
let values_len = values.len(); let values_len = values.len();
let field_elements: Vec<F> = ToConstraintField::<F>::to_field_elements(values).unwrap(); let field_elements: Vec<F> = ToConstraintField::<F>::to_field_elements(values).unwrap();
let max_size = 8 * (F::Params::CAPACITY / 8) as usize;
let max_size = 8 * ((F::MODULUS_BIT_SIZE - 1) / 8) as usize;
let mut allocated_bits = Vec::new(); let mut allocated_bits = Vec::new();
for field_element in field_elements.into_iter() { for field_element in field_elements.into_iter() {
let fe = AllocatedFp::new_input(cs.clone(), || Ok(field_element))?; let fe = AllocatedFp::new_input(cs.clone(), || Ok(field_element))?;
@ -335,7 +335,7 @@ impl AllocVar for UInt8 {
} }
} }
/// Parses the `Vec<UInt8<ConstraintF>>` in fixed-sized `ConstraintF::Params::CAPACITY` chunks and
/// Parses the `Vec<UInt8<ConstraintF>>` in fixed-sized `ConstraintF::MODULUS_BIT_SIZE - 1` chunks and
/// converts each chunk, which is assumed to be little-endian, to its `FpVar<ConstraintF>` /// converts each chunk, which is assumed to be little-endian, to its `FpVar<ConstraintF>`
/// representation. /// representation.
/// This is the gadget counterpart to the `[u8]` implementation of /// This is the gadget counterpart to the `[u8]` implementation of
@ -343,7 +343,7 @@ impl AllocVar for UInt8 {
impl<ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for [UInt8<ConstraintF>] { impl<ConstraintF: PrimeField> ToConstraintFieldGadget<ConstraintF> for [UInt8<ConstraintF>] {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_constraint_field(&self) -> Result<Vec<FpVar<ConstraintF>>, SynthesisError> { fn to_constraint_field(&self) -> Result<Vec<FpVar<ConstraintF>>, SynthesisError> {
let max_size = (ConstraintF::Params::CAPACITY / 8) as usize;
let max_size = ((ConstraintF::MODULUS_BIT_SIZE - 1) / 8) as usize;
self.chunks(max_size) self.chunks(max_size)
.map(|chunk| Boolean::le_bits_to_fp_var(chunk.to_bits_le()?.as_slice())) .map(|chunk| Boolean::le_bits_to_fp_var(chunk.to_bits_le()?.as_slice()))
.collect::<Result<Vec<_>, SynthesisError>>() .collect::<Result<Vec<_>, SynthesisError>>()
@ -363,7 +363,7 @@ mod test {
use crate::fields::fp::FpVar; use crate::fields::fp::FpVar;
use crate::prelude::AllocationMode::{Constant, Input, Witness}; use crate::prelude::AllocationMode::{Constant, Input, Witness};
use crate::{prelude::*, ToConstraintFieldGadget, Vec}; use crate::{prelude::*, ToConstraintFieldGadget, Vec};
use ark_ff::{FpParameters, PrimeField, ToConstraintField};
use ark_ff::{PrimeField, ToConstraintField};
use ark_relations::r1cs::{ConstraintSystem, SynthesisError}; use ark_relations::r1cs::{ConstraintSystem, SynthesisError};
use ark_std::rand::distributions::Uniform; use ark_std::rand::distributions::Uniform;
use ark_std::rand::Rng; use ark_std::rand::Rng;
@ -426,8 +426,8 @@ mod test {
for x in v.iter().zip(expected_to_be_same.iter()) { for x in v.iter().zip(expected_to_be_same.iter()) {
match x { match x {
(&Boolean::Constant(true), &Boolean::Constant(true)) => {}
(&Boolean::Constant(false), &Boolean::Constant(false)) => {}
(&Boolean::Constant(true), &Boolean::Constant(true)) => {},
(&Boolean::Constant(false), &Boolean::Constant(false)) => {},
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -475,7 +475,7 @@ mod test {
#[test] #[test]
fn test_uint8_to_constraint_field() -> Result<(), SynthesisError> { fn test_uint8_to_constraint_field() -> Result<(), SynthesisError> {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
let max_size = (<Fr as PrimeField>::Params::CAPACITY / 8) as usize;
let max_size = ((<Fr as PrimeField>::MODULUS_BIT_SIZE - 1) / 8) as usize;
let modes = [Input, Witness, Constant]; let modes = [Input, Witness, Constant];
for mode in &modes { for mode in &modes {

+ 22
- 22
src/fields/cubic_extension.rs

@ -1,6 +1,6 @@
use ark_ff::{ use ark_ff::{
fields::{CubicExtField, CubicExtParameters, Field},
Zero,
fields::{CubicExtField, Field},
CubicExtConfig, Zero,
}; };
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};
use core::{borrow::Borrow, marker::PhantomData}; use core::{borrow::Borrow, marker::PhantomData};
@ -16,7 +16,7 @@ use crate::{
#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Debug(bound = "BF: core::fmt::Debug"), Clone(bound = "BF: Clone"))] #[derivative(Debug(bound = "BF: core::fmt::Debug"), Clone(bound = "BF: Clone"))]
#[must_use] #[must_use]
pub struct CubicExtVar<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarParams<BF>>
pub struct CubicExtVar<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarConfig<BF>>
where where
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
{ {
@ -32,8 +32,8 @@ where
/// This trait describes parameters that are used to implement arithmetic for /// This trait describes parameters that are used to implement arithmetic for
/// `CubicExtVar`. /// `CubicExtVar`.
pub trait CubicExtVarParams<BF: FieldVar<Self::BaseField, Self::BasePrimeField>>:
CubicExtParameters
pub trait CubicExtVarConfig<BF: FieldVar<Self::BaseField, Self::BasePrimeField>>:
CubicExtConfig
where where
for<'a> &'a BF: FieldOpsBounds<'a, Self::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, Self::BaseField, BF>,
{ {
@ -43,7 +43,7 @@ where
fn mul_base_field_vars_by_frob_coeff(c1: &mut BF, c2: &mut BF, power: usize); fn mul_base_field_vars_by_frob_coeff(c1: &mut BF, c2: &mut BF, power: usize);
} }
impl<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarParams<BF>> CubicExtVar<BF, P>
impl<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarConfig<BF>> CubicExtVar<BF, P>
where where
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
{ {
@ -86,7 +86,7 @@ impl R1CSVar for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
type Value = CubicExtField<P>; type Value = CubicExtField<P>;
@ -107,7 +107,7 @@ impl From> for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
fn from(other: Boolean<P::BasePrimeField>) -> Self { fn from(other: Boolean<P::BasePrimeField>) -> Self {
let c0 = BF::from(other); let c0 = BF::from(other);
@ -121,14 +121,14 @@ impl<'a, BF, P> FieldOpsBounds<'a, CubicExtField

, CubicExtVar> for Cub

where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
} }
impl<'a, BF, P> FieldOpsBounds<'a, CubicExtField<P>, CubicExtVar<BF, P>> for &'a CubicExtVar<BF, P> impl<'a, BF, P> FieldOpsBounds<'a, CubicExtField<P>, CubicExtVar<BF, P>> for &'a CubicExtVar<BF, P>
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
} }
@ -136,7 +136,7 @@ impl FieldVar, P::BasePrimeField> for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
fn constant(other: CubicExtField<P>) -> Self { fn constant(other: CubicExtField<P>) -> Self {
let c0 = BF::constant(other.c0); let c0 = BF::constant(other.c0);
@ -301,7 +301,7 @@ impl_bounded_ops!(
|this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| { |this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| {
this + CubicExtVar::constant(other) this + CubicExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarConfig<BF>),
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
); );
impl_bounded_ops!( impl_bounded_ops!(
@ -320,7 +320,7 @@ impl_bounded_ops!(
|this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| { |this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| {
this - CubicExtVar::constant(other) this - CubicExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarConfig<BF>),
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
); );
impl_bounded_ops!( impl_bounded_ops!(
@ -357,7 +357,7 @@ impl_bounded_ops!(
|this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| { |this: &'a CubicExtVar<BF, P>, other: CubicExtField<P>| {
this * CubicExtVar::constant(other) this * CubicExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: CubicExtVarConfig<BF>),
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
); );
@ -365,7 +365,7 @@ impl EqGadget for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn is_eq(&self, other: &Self) -> Result<Boolean<P::BasePrimeField>, SynthesisError> { fn is_eq(&self, other: &Self) -> Result<Boolean<P::BasePrimeField>, SynthesisError> {
@ -406,7 +406,7 @@ impl ToBitsGadget for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_bits_le(&self) -> Result<Vec<Boolean<P::BasePrimeField>>, SynthesisError> { fn to_bits_le(&self) -> Result<Vec<Boolean<P::BasePrimeField>>, SynthesisError> {
@ -433,7 +433,7 @@ impl ToBytesGadget for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> { fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
@ -463,7 +463,7 @@ impl ToConstraintFieldGadget for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
BF: ToConstraintFieldGadget<P::BasePrimeField>, BF: ToConstraintFieldGadget<P::BasePrimeField>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
@ -482,7 +482,7 @@ impl CondSelectGadget for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
#[inline] #[inline]
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
@ -503,7 +503,7 @@ where
BF: FieldVar<P::BaseField, P::BasePrimeField> BF: FieldVar<P::BaseField, P::BasePrimeField>
+ TwoBitLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>, + TwoBitLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
type TableConstant = CubicExtField<P>; type TableConstant = CubicExtField<P>;
@ -527,7 +527,7 @@ where
BF: FieldVar<P::BaseField, P::BasePrimeField> BF: FieldVar<P::BaseField, P::BasePrimeField>
+ ThreeBitCondNegLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>, + ThreeBitCondNegLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
type TableConstant = CubicExtField<P>; type TableConstant = CubicExtField<P>;
@ -551,7 +551,7 @@ impl AllocVar, P::BasePrimeField> for CubicExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: CubicExtVarParams<BF>,
P: CubicExtVarConfig<BF>,
{ {
fn new_variable<T: Borrow<CubicExtField<P>>>( fn new_variable<T: Borrow<CubicExtField<P>>>(
cs: impl Into<Namespace<P::BasePrimeField>>, cs: impl Into<Namespace<P::BasePrimeField>>,

+ 8
- 8
src/fields/fp/cmp.rs

@ -106,7 +106,7 @@ impl FpVar {
// self <= (p-1)/2, which implies self < p. // self <= (p-1)/2, which implies self < p.
let _ = Boolean::enforce_smaller_or_equal_than_le( let _ = Boolean::enforce_smaller_or_equal_than_le(
&self.to_non_unique_bits_le()?, &self.to_non_unique_bits_le()?,
F::modulus_minus_one_div_two(),
F::MODULUS_MINUS_ONE_DIV_TWO,
)?; )?;
Ok(()) Ok(())
} }
@ -165,7 +165,7 @@ mod test {
fn test_cmp() { fn test_cmp() {
let mut rng = ark_std::test_rng(); let mut rng = ark_std::test_rng();
fn rand_in_range<R: Rng>(rng: &mut R) -> Fr { fn rand_in_range<R: Rng>(rng: &mut R) -> Fr {
let pminusonedivtwo: Fr = Fr::modulus_minus_one_div_two().into();
let pminusonedivtwo: Fr = Fr::MODULUS_MINUS_ONE_DIV_TWO.into();
let mut r; let mut r;
loop { loop {
r = Fr::rand(rng); r = Fr::rand(rng);
@ -186,12 +186,12 @@ mod test {
Ordering::Less => { Ordering::Less => {
a_var.enforce_cmp(&b_var, Ordering::Less, false).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Less, false).unwrap();
a_var.enforce_cmp(&b_var, Ordering::Less, true).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Less, true).unwrap();
}
},
Ordering::Greater => { Ordering::Greater => {
a_var.enforce_cmp(&b_var, Ordering::Greater, false).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Greater, false).unwrap();
a_var.enforce_cmp(&b_var, Ordering::Greater, true).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Greater, true).unwrap();
}
_ => {}
},
_ => {},
} }
if i == 0 { if i == 0 {
@ -212,12 +212,12 @@ mod test {
Ordering::Less => { Ordering::Less => {
a_var.enforce_cmp(&b_var, Ordering::Less, false).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Less, false).unwrap();
a_var.enforce_cmp(&b_var, Ordering::Less, true).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Less, true).unwrap();
}
},
Ordering::Greater => { Ordering::Greater => {
a_var.enforce_cmp(&b_var, Ordering::Greater, false).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Greater, false).unwrap();
a_var.enforce_cmp(&b_var, Ordering::Greater, true).unwrap(); a_var.enforce_cmp(&b_var, Ordering::Greater, true).unwrap();
}
_ => {}
},
_ => {},
} }
assert!(!cs.is_satisfied().unwrap()); assert!(!cs.is_satisfied().unwrap());

+ 19
- 19
src/fields/fp/mod.rs

@ -1,4 +1,4 @@
use ark_ff::{BigInteger, FpParameters, PrimeField};
use ark_ff::{BigInteger, PrimeField};
use ark_relations::r1cs::{ use ark_relations::r1cs::{
ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable, ConstraintSystemRef, LinearCombination, Namespace, SynthesisError, Variable,
}; };
@ -468,15 +468,15 @@ impl ToBitsGadget for AllocatedFp {
use ark_ff::BitIteratorBE; use ark_ff::BitIteratorBE;
let mut bits = if let Some(value) = self.value { let mut bits = if let Some(value) = self.value {
let field_char = BitIteratorBE::new(F::characteristic()); let field_char = BitIteratorBE::new(F::characteristic());
let bits: Vec<_> = BitIteratorBE::new(value.into_repr())
let bits: Vec<_> = BitIteratorBE::new(value.into_bigint())
.zip(field_char) .zip(field_char)
.skip_while(|(_, c)| !c) .skip_while(|(_, c)| !c)
.map(|(b, _)| Some(b)) .map(|(b, _)| Some(b))
.collect(); .collect();
assert_eq!(bits.len(), F::Params::MODULUS_BITS as usize);
assert_eq!(bits.len(), F::MODULUS_BIT_SIZE as usize);
bits bits
} else { } else {
vec![None; F::Params::MODULUS_BITS as usize]
vec![None; F::MODULUS_BIT_SIZE as usize]
}; };
// Convert to little-endian // Convert to little-endian
@ -573,7 +573,7 @@ impl CondSelectGadget for AllocatedFp {
)?; )?;
Ok(result) Ok(result)
}
},
} }
} }
} }
@ -717,13 +717,13 @@ impl FieldVar for FpVar {
(Constant(_), Constant(_), Constant(_)) => Ok(()), (Constant(_), Constant(_), Constant(_)) => Ok(()),
(Constant(_), Constant(_), _) | (Constant(_), Var(_), _) | (Var(_), Constant(_), _) => { (Constant(_), Constant(_), _) | (Constant(_), Var(_), _) | (Var(_), Constant(_), _) => {
result.enforce_equal(&(self * other)) result.enforce_equal(&(self * other))
} // this multiplication should be free
}, // this multiplication should be free
(Var(v1), Var(v2), Var(v3)) => v1.mul_equals(v2, v3), (Var(v1), Var(v2), Var(v3)) => v1.mul_equals(v2, v3),
(Var(v1), Var(v2), Constant(f)) => { (Var(v1), Var(v2), Constant(f)) => {
let cs = v1.cs.clone(); let cs = v1.cs.clone();
let v3 = AllocatedFp::new_constant(cs, f).unwrap(); let v3 = AllocatedFp::new_constant(cs, f).unwrap();
v1.mul_equals(v2, &v3) v1.mul_equals(v2, &v3)
}
},
} }
} }
@ -737,12 +737,12 @@ impl FieldVar for FpVar {
let cs = r.cs.clone(); let cs = r.cs.clone();
let v = AllocatedFp::new_witness(cs, || Ok(f))?; let v = AllocatedFp::new_witness(cs, || Ok(f))?;
v.square_equals(&r) v.square_equals(&r)
}
},
(Var(v), Constant(f)) => { (Var(v), Constant(f)) => {
let cs = v.cs.clone(); let cs = v.cs.clone();
let r = AllocatedFp::new_witness(cs, || Ok(f))?; let r = AllocatedFp::new_witness(cs, || Ok(f))?;
v.square_equals(&r) v.square_equals(&r)
}
},
(Var(v1), Var(v2)) => v1.square_equals(v2), (Var(v1), Var(v2)) => v1.square_equals(v2),
} }
} }
@ -763,7 +763,7 @@ impl FieldVar for FpVar {
let mut f = *f; let mut f = *f;
f.frobenius_map(power); f.frobenius_map(power);
Ok(FpVar::Constant(f)) Ok(FpVar::Constant(f))
}
},
} }
} }
@ -850,7 +850,7 @@ impl EqGadget for FpVar {
let cs = v.cs.clone(); let cs = v.cs.clone();
let c = AllocatedFp::new_constant(cs, c)?; let c = AllocatedFp::new_constant(cs, c)?;
c.is_eq(v) c.is_eq(v)
}
},
(Self::Var(v1), Self::Var(v2)) => v1.is_eq(v2), (Self::Var(v1), Self::Var(v2)) => v1.is_eq(v2),
} }
} }
@ -867,7 +867,7 @@ impl EqGadget for FpVar {
let cs = v.cs.clone(); let cs = v.cs.clone();
let c = AllocatedFp::new_constant(cs, c)?; let c = AllocatedFp::new_constant(cs, c)?;
c.conditional_enforce_equal(v, should_enforce) c.conditional_enforce_equal(v, should_enforce)
}
},
(Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_equal(v2, should_enforce), (Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_equal(v2, should_enforce),
} }
} }
@ -884,7 +884,7 @@ impl EqGadget for FpVar {
let cs = v.cs.clone(); let cs = v.cs.clone();
let c = AllocatedFp::new_constant(cs, c)?; let c = AllocatedFp::new_constant(cs, c)?;
c.conditional_enforce_not_equal(v, should_enforce) c.conditional_enforce_not_equal(v, should_enforce)
}
},
(Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_not_equal(v2, should_enforce), (Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_not_equal(v2, should_enforce),
} }
} }
@ -903,8 +903,8 @@ impl ToBitsGadget for FpVar {
fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> { fn to_non_unique_bits_le(&self) -> Result<Vec<Boolean<F>>, SynthesisError> {
use ark_ff::BitIteratorLE; use ark_ff::BitIteratorLE;
match self { match self {
Self::Constant(c) => Ok(BitIteratorLE::new(&c.into_repr())
.take((F::Params::MODULUS_BITS) as usize)
Self::Constant(c) => Ok(BitIteratorLE::new(&c.into_bigint())
.take((F::MODULUS_BIT_SIZE) as usize)
.map(Boolean::constant) .map(Boolean::constant)
.collect::<Vec<_>>()), .collect::<Vec<_>>()),
Self::Var(v) => v.to_non_unique_bits_le(), Self::Var(v) => v.to_non_unique_bits_le(),
@ -956,7 +956,7 @@ impl CondSelectGadget for FpVar {
let not = AllocatedFp::from(cond.not()); let not = AllocatedFp::from(cond.not());
// cond * t + (1 - cond) * f // cond * t + (1 - cond) * f
Ok(is.mul_constant(*t).add(&not.mul_constant(*f)).into()) Ok(is.mul_constant(*t).add(&not.mul_constant(*f)).into())
}
},
(..) => { (..) => {
let cs = cond.cs(); let cs = cond.cs();
let true_value = match true_value { let true_value = match true_value {
@ -968,9 +968,9 @@ impl CondSelectGadget for FpVar {
Self::Var(v) => v.clone(), Self::Var(v) => v.clone(),
}; };
cond.select(&true_value, &false_value).map(Self::Var) cond.select(&true_value, &false_value).map(Self::Var)
}
},
} }
}
},
} }
} }
} }
@ -1049,7 +1049,7 @@ impl<'a, F: PrimeField> Sum<&'a FpVar> for FpVar {
FpVar::Constant(c) => { FpVar::Constant(c) => {
sum_constants += c; sum_constants += c;
None None
}
},
FpVar::Var(v) => Some(v), FpVar::Var(v) => Some(v),
}))); })));

+ 17
- 15
src/fields/fp12.rs

@ -1,31 +1,33 @@
use crate::fields::{fp2::Fp2Var, fp6_3over2::Fp6Var, quadratic_extension::*, FieldVar}; use crate::fields::{fp2::Fp2Var, fp6_3over2::Fp6Var, quadratic_extension::*, FieldVar};
use ark_ff::fields::{fp12_2over3over2::*, fp6_3over2::Fp6Parameters, Field, QuadExtParameters};
use ark_ff::fields::{fp12_2over3over2::*, Field};
use ark_ff::fp6_3over2::Fp6Config;
use ark_ff::QuadExtConfig;
use ark_relations::r1cs::SynthesisError; use ark_relations::r1cs::SynthesisError;
/// A degree-12 extension field constructed as the tower of a /// A degree-12 extension field constructed as the tower of a
/// quadratic extension over a cubic extension over a quadratic extension field. /// quadratic extension over a cubic extension over a quadratic extension field.
/// This is the R1CS equivalent of `ark_ff::fp12_2over3over2::Fp12<P>`. /// This is the R1CS equivalent of `ark_ff::fp12_2over3over2::Fp12<P>`.
pub type Fp12Var<P> = QuadExtVar<Fp6Var<<P as Fp12Parameters>::Fp6Params>, Fp12ParamsWrapper<P>>;
pub type Fp12Var<P> = QuadExtVar<Fp6Var<<P as Fp12Config>::Fp6Config>, Fp12ConfigWrapper<P>>;
type Fp2Params<P> = <<P as Fp12Parameters>::Fp6Params as Fp6Parameters>::Fp2Params;
type Fp2Config<P> = <<P as Fp12Config>::Fp6Config as Fp6Config>::Fp2Config;
impl<P: Fp12Parameters> QuadExtVarParams<Fp6Var<P::Fp6Params>> for Fp12ParamsWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp6Var<P::Fp6Params>, power: usize) {
impl<P: Fp12Config> QuadExtVarConfig<Fp6Var<P::Fp6Config>> for Fp12ConfigWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp6Var<P::Fp6Config>, power: usize) {
fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
fe.c2 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c2 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
} }
} }
impl<P: Fp12Parameters> Fp12Var<P> {
impl<P: Fp12Config> Fp12Var<P> {
/// Multiplies by a sparse element of the form `(c0 = (c0, c1, 0), c1 = (0, /// Multiplies by a sparse element of the form `(c0 = (c0, c1, 0), c1 = (0,
/// d1, 0))`. /// d1, 0))`.
#[inline] #[inline]
pub fn mul_by_014( pub fn mul_by_014(
&self, &self,
c0: &Fp2Var<Fp2Params<P>>,
c1: &Fp2Var<Fp2Params<P>>,
d1: &Fp2Var<Fp2Params<P>>,
c0: &Fp2Var<Fp2Config<P>>,
c1: &Fp2Var<Fp2Config<P>>,
d1: &Fp2Var<Fp2Config<P>>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
let v0 = self.c0.mul_by_c0_c1_0(&c0, &c1)?; let v0 = self.c0.mul_by_c0_c1_0(&c0, &c1)?;
let v1 = self.c1.mul_by_0_c1_0(&d1)?; let v1 = self.c1.mul_by_0_c1_0(&d1)?;
@ -40,9 +42,9 @@ impl Fp12Var

{

#[inline] #[inline]
pub fn mul_by_034( pub fn mul_by_034(
&self, &self,
c0: &Fp2Var<Fp2Params<P>>,
d0: &Fp2Var<Fp2Params<P>>,
d1: &Fp2Var<Fp2Params<P>>,
c0: &Fp2Var<Fp2Config<P>>,
d0: &Fp2Var<Fp2Config<P>>,
d1: &Fp2Var<Fp2Config<P>>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
let a0 = &self.c0.c0 * c0; let a0 = &self.c0.c0 * c0;
let a1 = &self.c0.c1 * c0; let a1 = &self.c0.c1 * c0;
@ -62,7 +64,7 @@ impl Fp12Var

{

/// Squares `self` when `self` is in the cyclotomic subgroup. /// Squares `self` when `self` is in the cyclotomic subgroup.
pub fn cyclotomic_square(&self) -> Result<Self, SynthesisError> { pub fn cyclotomic_square(&self) -> Result<Self, SynthesisError> {
if characteristic_square_mod_6_is_one(Fp12::<P>::characteristic()) { if characteristic_square_mod_6_is_one(Fp12::<P>::characteristic()) {
let fp2_nr = <P::Fp6Params as Fp6Parameters>::NONRESIDUE;
let fp2_nr = <P::Fp6Config as Fp6Config>::NONRESIDUE;
let z0 = &self.c0.c0; let z0 = &self.c0.c0;
let z4 = &self.c0.c1; let z4 = &self.c0.c1;
@ -143,12 +145,12 @@ impl Fp12Var

{

&self, &self,
exponent: impl AsRef<[u64]>, exponent: impl AsRef<[u64]>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
use ark_ff::biginteger::arithmetic::find_wnaf;
use ark_ff::biginteger::arithmetic::find_naf;
let mut res = Self::one(); let mut res = Self::one();
let self_inverse = self.unitary_inverse()?; let self_inverse = self.unitary_inverse()?;
let mut found_nonzero = false; let mut found_nonzero = false;
let naf = find_wnaf(exponent.as_ref());
let naf = find_naf(exponent.as_ref());
for &value in naf.iter().rev() { for &value in naf.iter().rev() {
if found_nonzero { if found_nonzero {

+ 3
- 3
src/fields/fp2.rs

@ -1,11 +1,11 @@
use crate::fields::{fp::FpVar, quadratic_extension::*}; use crate::fields::{fp::FpVar, quadratic_extension::*};
use ark_ff::fields::{Fp2Parameters, Fp2ParamsWrapper, QuadExtParameters};
use ark_ff::fields::{Fp2Config, Fp2ConfigWrapper, QuadExtConfig};
/// A quadratic extension field constructed over a prime field. /// A quadratic extension field constructed over a prime field.
/// This is the R1CS equivalent of `ark_ff::Fp2<P>`. /// This is the R1CS equivalent of `ark_ff::Fp2<P>`.
pub type Fp2Var<P> = QuadExtVar<FpVar<<P as Fp2Parameters>::Fp>, Fp2ParamsWrapper<P>>;
pub type Fp2Var<P> = QuadExtVar<FpVar<<P as Fp2Config>::Fp>, Fp2ConfigWrapper<P>>;
impl<P: Fp2Parameters> QuadExtVarParams<FpVar<P::Fp>> for Fp2ParamsWrapper<P> {
impl<P: Fp2Config> QuadExtVarConfig<FpVar<P::Fp>> for Fp2ConfigWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut FpVar<P::Fp>, power: usize) { fn mul_base_field_var_by_frob_coeff(fe: &mut FpVar<P::Fp>, power: usize) {
*fe *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; *fe *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
} }

+ 4
- 3
src/fields/fp3.rs

@ -1,11 +1,12 @@
use crate::fields::{cubic_extension::*, fp::FpVar}; use crate::fields::{cubic_extension::*, fp::FpVar};
use ark_ff::fields::{CubicExtParameters, Fp3Parameters, Fp3ParamsWrapper};
use ark_ff::fields::{CubicExtConfig, Fp3ConfigWrapper};
use ark_ff::Fp3Config;
/// A cubic extension field constructed over a prime field. /// A cubic extension field constructed over a prime field.
/// This is the R1CS equivalent of `ark_ff::Fp3<P>`. /// This is the R1CS equivalent of `ark_ff::Fp3<P>`.
pub type Fp3Var<P> = CubicExtVar<FpVar<<P as Fp3Parameters>::Fp>, Fp3ParamsWrapper<P>>;
pub type Fp3Var<P> = CubicExtVar<FpVar<<P as Fp3Config>::Fp>, Fp3ConfigWrapper<P>>;
impl<P: Fp3Parameters> CubicExtVarParams<FpVar<P::Fp>> for Fp3ParamsWrapper<P> {
impl<P: Fp3Config> CubicExtVarConfig<FpVar<P::Fp>> for Fp3ConfigWrapper<P> {
fn mul_base_field_vars_by_frob_coeff( fn mul_base_field_vars_by_frob_coeff(
c1: &mut FpVar<P::Fp>, c1: &mut FpVar<P::Fp>,
c2: &mut FpVar<P::Fp>, c2: &mut FpVar<P::Fp>,

+ 5
- 4
src/fields/fp4.rs

@ -1,13 +1,14 @@
use crate::fields::{fp2::Fp2Var, quadratic_extension::*}; use crate::fields::{fp2::Fp2Var, quadratic_extension::*};
use ark_ff::fields::{Fp4Parameters, Fp4ParamsWrapper, QuadExtParameters};
use ark_ff::fields::{Fp4ConfigWrapper, QuadExtConfig};
use ark_ff::Fp4Config;
/// A quartic extension field constructed as the tower of a /// A quartic extension field constructed as the tower of a
/// quadratic extension over a quadratic extension field. /// quadratic extension over a quadratic extension field.
/// This is the R1CS equivalent of `ark_ff::Fp4<P>`. /// This is the R1CS equivalent of `ark_ff::Fp4<P>`.
pub type Fp4Var<P> = QuadExtVar<Fp2Var<<P as Fp4Parameters>::Fp2Params>, Fp4ParamsWrapper<P>>;
pub type Fp4Var<P> = QuadExtVar<Fp2Var<<P as Fp4Config>::Fp2Config>, Fp4ConfigWrapper<P>>;
impl<P: Fp4Parameters> QuadExtVarParams<Fp2Var<P::Fp2Params>> for Fp4ParamsWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp2Var<P::Fp2Params>, power: usize) {
impl<P: Fp4Config> QuadExtVarConfig<Fp2Var<P::Fp2Config>> for Fp4ConfigWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp2Var<P::Fp2Config>, power: usize) {
fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
} }

+ 5
- 4
src/fields/fp6_2over3.rs

@ -1,13 +1,14 @@
use crate::fields::{fp3::Fp3Var, quadratic_extension::*}; use crate::fields::{fp3::Fp3Var, quadratic_extension::*};
use ark_ff::fields::{fp6_2over3::*, QuadExtParameters};
use ark_ff::fields::fp6_2over3::*;
use ark_ff::QuadExtConfig;
/// A sextic extension field constructed as the tower of a /// A sextic extension field constructed as the tower of a
/// quadratic extension over a cubic extension field. /// quadratic extension over a cubic extension field.
/// This is the R1CS equivalent of `ark_ff::fp6_2over3::Fp6<P>`. /// This is the R1CS equivalent of `ark_ff::fp6_2over3::Fp6<P>`.
pub type Fp6Var<P> = QuadExtVar<Fp3Var<<P as Fp6Parameters>::Fp3Params>, Fp6ParamsWrapper<P>>;
pub type Fp6Var<P> = QuadExtVar<Fp3Var<<P as Fp6Config>::Fp3Config>, Fp6ConfigWrapper<P>>;
impl<P: Fp6Parameters> QuadExtVarParams<Fp3Var<P::Fp3Params>> for Fp6ParamsWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp3Var<P::Fp3Params>, power: usize) {
impl<P: Fp6Config> QuadExtVarConfig<Fp3Var<P::Fp3Config>> for Fp6ConfigWrapper<P> {
fn mul_base_field_var_by_frob_coeff(fe: &mut Fp3Var<P::Fp3Config>, power: usize) {
fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c0 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
fe.c2 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; fe.c2 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];

+ 13
- 12
src/fields/fp6_3over2.rs

@ -1,17 +1,18 @@
use crate::fields::{cubic_extension::*, fp2::*}; use crate::fields::{cubic_extension::*, fp2::*};
use ark_ff::fields::{fp6_3over2::*, CubicExtParameters, Fp2};
use ark_ff::fields::{fp6_3over2::*, Fp2};
use ark_ff::CubicExtConfig;
use ark_relations::r1cs::SynthesisError; use ark_relations::r1cs::SynthesisError;
use core::ops::MulAssign;
use ark_std::ops::MulAssign;
/// A sextic extension field constructed as the tower of a /// A sextic extension field constructed as the tower of a
/// cubic extension over a quadratic extension field. /// cubic extension over a quadratic extension field.
/// This is the R1CS equivalent of `ark_ff::fp6_3over3::Fp6<P>`. /// This is the R1CS equivalent of `ark_ff::fp6_3over3::Fp6<P>`.
pub type Fp6Var<P> = CubicExtVar<Fp2Var<<P as Fp6Parameters>::Fp2Params>, Fp6ParamsWrapper<P>>;
pub type Fp6Var<P> = CubicExtVar<Fp2Var<<P as Fp6Config>::Fp2Config>, Fp6ConfigWrapper<P>>;
impl<P: Fp6Parameters> CubicExtVarParams<Fp2Var<P::Fp2Params>> for Fp6ParamsWrapper<P> {
impl<P: Fp6Config> CubicExtVarConfig<Fp2Var<P::Fp2Config>> for Fp6ConfigWrapper<P> {
fn mul_base_field_vars_by_frob_coeff( fn mul_base_field_vars_by_frob_coeff(
c1: &mut Fp2Var<P::Fp2Params>,
c2: &mut Fp2Var<P::Fp2Params>,
c1: &mut Fp2Var<P::Fp2Config>,
c2: &mut Fp2Var<P::Fp2Config>,
power: usize, power: usize,
) { ) {
*c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD]; *c1 *= Self::FROBENIUS_COEFF_C1[power % Self::DEGREE_OVER_BASE_PRIME_FIELD];
@ -19,9 +20,9 @@ impl CubicExtVarParams> for Fp6ParamsWrap
} }
} }
impl<P: Fp6Parameters> Fp6Var<P> {
impl<P: Fp6Config> Fp6Var<P> {
/// Multiplies `self` by a sparse element which has `c0 == c2 == zero`. /// Multiplies `self` by a sparse element which has `c0 == c2 == zero`.
pub fn mul_by_0_c1_0(&self, c1: &Fp2Var<P::Fp2Params>) -> Result<Self, SynthesisError> {
pub fn mul_by_0_c1_0(&self, c1: &Fp2Var<P::Fp2Config>) -> Result<Self, SynthesisError> {
// Karatsuba multiplication // Karatsuba multiplication
// v0 = a0 * b0 = 0 // v0 = a0 * b0 = 0
@ -51,8 +52,8 @@ impl Fp6Var

{

/// Multiplies `self` by a sparse element which has `c2 == zero`. /// Multiplies `self` by a sparse element which has `c2 == zero`.
pub fn mul_by_c0_c1_0( pub fn mul_by_c0_c1_0(
&self, &self,
c0: &Fp2Var<P::Fp2Params>,
c1: &Fp2Var<P::Fp2Params>,
c0: &Fp2Var<P::Fp2Config>,
c1: &Fp2Var<P::Fp2Config>,
) -> Result<Self, SynthesisError> { ) -> Result<Self, SynthesisError> {
let v0 = &self.c0 * c0; let v0 = &self.c0 * c0;
let v1 = &self.c1 * c1; let v1 = &self.c1 * c1;
@ -76,8 +77,8 @@ impl Fp6Var

{

} }
} }
impl<P: Fp6Parameters> MulAssign<Fp2<P::Fp2Params>> for Fp6Var<P> {
fn mul_assign(&mut self, other: Fp2<P::Fp2Params>) {
impl<P: Fp6Config> MulAssign<Fp2<P::Fp2Config>> for Fp6Var<P> {
fn mul_assign(&mut self, other: Fp2<P::Fp2Config>) {
self.c0 *= other; self.c0 *= other;
self.c1 *= other; self.c1 *= other;
self.c2 *= other; self.c2 *= other;

+ 1
- 1
src/fields/mod.rs

@ -190,7 +190,7 @@ pub trait FieldVar:
})?; })?;
result.mul_equals(d, self)?; result.mul_equals(d, self)?;
Ok(result) Ok(result)
}
},
} }
} }

+ 38
- 36
src/fields/nonnative/allocated_field_var.rs

@ -4,7 +4,7 @@ use super::AllocatedNonNativeFieldMulResultVar;
use crate::fields::fp::FpVar; use crate::fields::fp::FpVar;
use crate::prelude::*; use crate::prelude::*;
use crate::ToConstraintFieldGadget; use crate::ToConstraintFieldGadget;
use ark_ff::{BigInteger, FpParameters, PrimeField};
use ark_ff::{BigInteger, PrimeField};
use ark_relations::r1cs::{OptimizationGoal, Result as R1CSResult}; use ark_relations::r1cs::{OptimizationGoal, Result as R1CSResult};
use ark_relations::{ use ark_relations::{
ns, ns,
@ -44,17 +44,17 @@ impl
optimization_type: OptimizationType, optimization_type: OptimizationType,
) -> TargetField { ) -> TargetField {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
optimization_type, optimization_type,
); );
let mut base_repr: <TargetField as PrimeField>::BigInt = TargetField::one().into_repr();
let mut base_repr: <TargetField as PrimeField>::BigInt = TargetField::one().into_bigint();
// Convert 2^{(params.bits_per_limb - 1)} into the TargetField and then double the base // Convert 2^{(params.bits_per_limb - 1)} into the TargetField and then double the base
// This is because 2^{(params.bits_per_limb)} might indeed be larger than the target field's prime. // This is because 2^{(params.bits_per_limb)} might indeed be larger than the target field's prime.
base_repr.muln((params.bits_per_limb - 1) as u32); base_repr.muln((params.bits_per_limb - 1) as u32);
let mut base: TargetField = TargetField::from_repr(base_repr).unwrap();
let mut base: TargetField = TargetField::from_bigint(base_repr).unwrap();
base = base + &base; base = base + &base;
let mut result = TargetField::zero(); let mut result = TargetField::zero();
@ -64,7 +64,7 @@ impl
let mut val = TargetField::zero(); let mut val = TargetField::zero();
let mut cur = TargetField::one(); let mut cur = TargetField::one();
for bit in limb.into_repr().to_bits_be().iter().rev() {
for bit in limb.into_bigint().to_bits_be().iter().rev() {
if *bit { if *bit {
val += &cur; val += &cur;
} }
@ -182,18 +182,19 @@ impl
assert_eq!(self.get_optimization_type(), other.get_optimization_type()); assert_eq!(self.get_optimization_type(), other.get_optimization_type());
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
// Step 1: reduce the `other` if needed // Step 1: reduce the `other` if needed
let mut surfeit = overhead!(other.num_of_additions_over_normal_form + BaseField::one()) + 1; let mut surfeit = overhead!(other.num_of_additions_over_normal_form + BaseField::one()) + 1;
let mut other = other.clone(); let mut other = other.clone();
if (surfeit + params.bits_per_limb > BaseField::size_in_bits() - 1)
if (surfeit + params.bits_per_limb > BaseField::MODULUS_BIT_SIZE as usize - 1)
|| (surfeit || (surfeit
+ (TargetField::size_in_bits() - params.bits_per_limb * (params.num_limbs - 1))
> BaseField::size_in_bits() - 1)
+ (TargetField::MODULUS_BIT_SIZE as usize
- params.bits_per_limb * (params.num_limbs - 1))
> BaseField::MODULUS_BIT_SIZE as usize - 1)
{ {
Reducer::reduce(&mut other)?; Reducer::reduce(&mut other)?;
surfeit = overhead!(other.num_of_additions_over_normal_form + BaseField::one()) + 1; surfeit = overhead!(other.num_of_additions_over_normal_form + BaseField::one()) + 1;
@ -201,18 +202,18 @@ impl
// Step 2: construct the padding // Step 2: construct the padding
let mut pad_non_top_limb_repr: <BaseField as PrimeField>::BigInt = let mut pad_non_top_limb_repr: <BaseField as PrimeField>::BigInt =
BaseField::one().into_repr();
BaseField::one().into_bigint();
let mut pad_top_limb_repr: <BaseField as PrimeField>::BigInt = pad_non_top_limb_repr; let mut pad_top_limb_repr: <BaseField as PrimeField>::BigInt = pad_non_top_limb_repr;
pad_non_top_limb_repr.muln((surfeit + params.bits_per_limb) as u32); pad_non_top_limb_repr.muln((surfeit + params.bits_per_limb) as u32);
let pad_non_top_limb = BaseField::from_repr(pad_non_top_limb_repr).unwrap();
let pad_non_top_limb = BaseField::from_bigint(pad_non_top_limb_repr).unwrap();
pad_top_limb_repr.muln( pad_top_limb_repr.muln(
(surfeit (surfeit
+ (TargetField::size_in_bits() - params.bits_per_limb * (params.num_limbs - 1)))
as u32,
+ (TargetField::MODULUS_BIT_SIZE as usize
- params.bits_per_limb * (params.num_limbs - 1))) as u32,
); );
let pad_top_limb = BaseField::from_repr(pad_top_limb_repr).unwrap();
let pad_top_limb = BaseField::from_bigint(pad_top_limb_repr).unwrap();
let mut pad_limbs = Vec::new(); let mut pad_limbs = Vec::new();
pad_limbs.push(pad_top_limb); pad_limbs.push(pad_top_limb);
@ -307,7 +308,7 @@ impl
elem: &TargetField, elem: &TargetField,
optimization_type: OptimizationType, optimization_type: OptimizationType,
) -> R1CSResult<Vec<BaseField>> { ) -> R1CSResult<Vec<BaseField>> {
Self::get_limbs_representations_from_big_integer(&elem.into_repr(), optimization_type)
Self::get_limbs_representations_from_big_integer(&elem.into_bigint(), optimization_type)
} }
/// Obtain the limbs directly from a big int /// Obtain the limbs directly from a big int
@ -316,8 +317,8 @@ impl
optimization_type: OptimizationType, optimization_type: OptimizationType,
) -> R1CSResult<Vec<BaseField>> { ) -> R1CSResult<Vec<BaseField>> {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
optimization_type, optimization_type,
); );
@ -329,7 +330,7 @@ impl
let cur_mod_r = <BaseField as PrimeField>::BigInt::from_bits_be( let cur_mod_r = <BaseField as PrimeField>::BigInt::from_bits_be(
&cur_bits[cur_bits.len() - params.bits_per_limb..], &cur_bits[cur_bits.len() - params.bits_per_limb..],
); // therefore, the lowest `bits_per_non_top_limb` bits is what we want. ); // therefore, the lowest `bits_per_non_top_limb` bits is what we want.
limbs.push(BaseField::from_repr(cur_mod_r).unwrap());
limbs.push(BaseField::from_bigint(cur_mod_r).unwrap());
cur.divn(params.bits_per_limb as u32); cur.divn(params.bits_per_limb as u32);
} }
@ -349,8 +350,8 @@ impl
assert_eq!(self.get_optimization_type(), other.get_optimization_type()); assert_eq!(self.get_optimization_type(), other.get_optimization_type());
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
@ -443,15 +444,15 @@ impl
assert_eq!(self.get_optimization_type(), other.get_optimization_type()); assert_eq!(self.get_optimization_type(), other.get_optimization_type());
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
// Get p // Get p
let p_representations = let p_representations =
AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer( AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer(
&<TargetField as PrimeField>::Params::MODULUS,
&<TargetField as PrimeField>::MODULUS,
self.get_optimization_type() self.get_optimization_type()
)?; )?;
let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations); let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations);
@ -594,8 +595,8 @@ impl
OptimizationGoal::Weight => OptimizationType::Weight, OptimizationGoal::Weight => OptimizationType::Weight,
}; };
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
optimization_type, optimization_type,
); );
let mut bits = Vec::new(); let mut bits = Vec::new();
@ -610,7 +611,8 @@ impl
bits.extend( bits.extend(
Reducer::<TargetField, BaseField>::limb_to_bits( Reducer::<TargetField, BaseField>::limb_to_bits(
&self.limbs[0], &self.limbs[0],
TargetField::size_in_bits() - (params.num_limbs - 1) * params.bits_per_limb,
TargetField::MODULUS_BIT_SIZE as usize
- (params.num_limbs - 1) * params.bits_per_limb,
)? )?
.into_iter() .into_iter()
.rev(), .rev(),
@ -640,8 +642,8 @@ impl ToBitsGadget
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_bits_le(&self) -> R1CSResult<Vec<Boolean<BaseField>>> { fn to_bits_le(&self) -> R1CSResult<Vec<Boolean<BaseField>>> {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
@ -746,8 +748,8 @@ impl TwoBitLookupGadget
}; };
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
optimization_type, optimization_type,
); );
let mut limbs_constants = Vec::new(); let mut limbs_constants = Vec::new();
@ -805,8 +807,8 @@ impl ThreeBitCondNegLookupGadget
}; };
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
optimization_type, optimization_type,
); );
@ -874,8 +876,8 @@ impl ToConstraintFieldGadget
// step 2: obtain the parameters for weight-optimized (often, fewer limbs) // step 2: obtain the parameters for weight-optimized (often, fewer limbs)
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
OptimizationType::Weight, OptimizationType::Weight,
); );

+ 12
- 12
src/fields/nonnative/allocated_mul_result.rs

@ -3,7 +3,7 @@ use super::reduce::{bigint_to_basefield, limbs_to_bigint, Reducer};
use super::AllocatedNonNativeFieldVar; use super::AllocatedNonNativeFieldVar;
use crate::fields::fp::FpVar; use crate::fields::fp::FpVar;
use crate::prelude::*; use crate::prelude::*;
use ark_ff::{FpParameters, PrimeField};
use ark_ff::PrimeField;
use ark_relations::r1cs::{OptimizationGoal, Result as R1CSResult}; use ark_relations::r1cs::{OptimizationGoal, Result as R1CSResult};
use ark_relations::{ns, r1cs::ConstraintSystemRef}; use ark_relations::{ns, r1cs::ConstraintSystemRef};
use ark_std::marker::PhantomData; use ark_std::marker::PhantomData;
@ -30,8 +30,8 @@ impl
{ {
fn from(src: &AllocatedNonNativeFieldVar<TargetField, BaseField>) -> Self { fn from(src: &AllocatedNonNativeFieldVar<TargetField, BaseField>) -> Self {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
src.get_optimization_type(), src.get_optimization_type(),
); );
@ -62,14 +62,14 @@ impl
/// Get the value of the multiplication result /// Get the value of the multiplication result
pub fn value(&self) -> R1CSResult<TargetField> { pub fn value(&self) -> R1CSResult<TargetField> {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
let p_representations = let p_representations =
AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer( AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer(
&<TargetField as PrimeField>::Params::MODULUS,
&<TargetField as PrimeField>::MODULUS,
self.get_optimization_type() self.get_optimization_type()
)?; )?;
let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations); let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations);
@ -87,15 +87,15 @@ impl
/// Constraints for reducing the result of a multiplication mod p, to get an original representation. /// Constraints for reducing the result of a multiplication mod p, to get an original representation.
pub fn reduce(&self) -> R1CSResult<AllocatedNonNativeFieldVar<TargetField, BaseField>> { pub fn reduce(&self) -> R1CSResult<AllocatedNonNativeFieldVar<TargetField, BaseField>> {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );
// Step 1: get p // Step 1: get p
let p_representations = let p_representations =
AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer( AllocatedNonNativeFieldVar::<TargetField, BaseField>::get_limbs_representations_from_big_integer(
&<TargetField as PrimeField>::Params::MODULUS,
&<TargetField as PrimeField>::MODULUS,
self.get_optimization_type() self.get_optimization_type()
)?; )?;
let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations); let p_bigint = limbs_to_bigint(params.bits_per_limb, &p_representations);
@ -127,7 +127,7 @@ impl
let value_bigint = limbs_to_bigint(params.bits_per_limb, &limbs_values); let value_bigint = limbs_to_bigint(params.bits_per_limb, &limbs_values);
let mut k_cur = value_bigint / p_bigint; let mut k_cur = value_bigint / p_bigint;
let total_len = TargetField::size_in_bits() + surfeit;
let total_len = TargetField::MODULUS_BIT_SIZE as usize + surfeit;
for _ in 0..total_len { for _ in 0..total_len {
res.push(Boolean::<BaseField>::new_witness(self.cs(), || { res.push(Boolean::<BaseField>::new_witness(self.cs(), || {
@ -184,8 +184,8 @@ impl
)?; )?;
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
self.get_optimization_type(), self.get_optimization_type(),
); );

+ 11
- 11
src/fields/nonnative/field_var.rs

@ -5,8 +5,8 @@ use crate::fields::fp::FpVar;
use crate::fields::FieldVar; use crate::fields::FieldVar;
use crate::prelude::*; use crate::prelude::*;
use crate::{R1CSVar, ToConstraintFieldGadget}; use crate::{R1CSVar, ToConstraintFieldGadget};
use ark_ff::to_bytes;
use ark_ff::PrimeField; use ark_ff::PrimeField;
use ark_ff::{to_bytes, FpParameters};
use ark_relations::r1cs::Result as R1CSResult; use ark_relations::r1cs::Result as R1CSResult;
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};
use ark_std::hash::{Hash, Hasher}; use ark_std::hash::{Hash, Hasher};
@ -248,12 +248,12 @@ impl EqGadget
should_enforce.enforce_equal(&Boolean::FALSE)?; should_enforce.enforce_equal(&Boolean::FALSE)?;
} }
Ok(()) Ok(())
}
},
(Self::Constant(c), Self::Var(v)) | (Self::Var(v), Self::Constant(c)) => { (Self::Constant(c), Self::Var(v)) | (Self::Var(v), Self::Constant(c)) => {
let cs = v.cs(); let cs = v.cs();
let c = AllocatedNonNativeFieldVar::new_constant(cs, c)?; let c = AllocatedNonNativeFieldVar::new_constant(cs, c)?;
c.conditional_enforce_equal(v, should_enforce) c.conditional_enforce_equal(v, should_enforce)
}
},
(Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_equal(v2, should_enforce), (Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_equal(v2, should_enforce),
} }
} }
@ -270,12 +270,12 @@ impl EqGadget
should_enforce.enforce_equal(&Boolean::FALSE)?; should_enforce.enforce_equal(&Boolean::FALSE)?;
} }
Ok(()) Ok(())
}
},
(Self::Constant(c), Self::Var(v)) | (Self::Var(v), Self::Constant(c)) => { (Self::Constant(c), Self::Var(v)) | (Self::Var(v), Self::Constant(c)) => {
let cs = v.cs(); let cs = v.cs();
let c = AllocatedNonNativeFieldVar::new_constant(cs, c)?; let c = AllocatedNonNativeFieldVar::new_constant(cs, c)?;
c.conditional_enforce_not_equal(v, should_enforce) c.conditional_enforce_not_equal(v, should_enforce)
}
},
(Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_not_equal(v2, should_enforce), (Self::Var(v1), Self::Var(v2)) => v1.conditional_enforce_not_equal(v2, should_enforce),
} }
} }
@ -296,8 +296,8 @@ impl ToBitsGadget
fn to_non_unique_bits_le(&self) -> R1CSResult<Vec<Boolean<BaseField>>> { fn to_non_unique_bits_le(&self) -> R1CSResult<Vec<Boolean<BaseField>>> {
use ark_ff::BitIteratorLE; use ark_ff::BitIteratorLE;
match self { match self {
Self::Constant(c) => Ok(BitIteratorLE::new(&c.into_repr())
.take((TargetField::Params::MODULUS_BITS) as usize)
Self::Constant(c) => Ok(BitIteratorLE::new(&c.into_bigint())
.take((TargetField::MODULUS_BIT_SIZE) as usize)
.map(Boolean::constant) .map(Boolean::constant)
.collect::<Vec<_>>()), .collect::<Vec<_>>()),
Self::Var(v) => v.to_non_unique_bits_le(), Self::Var(v) => v.to_non_unique_bits_le(),
@ -350,7 +350,7 @@ impl CondSelectGadget
Self::Var(v) => v.clone(), Self::Var(v) => v.clone(),
}; };
cond.select(&true_value, &false_value).map(Self::Var) cond.select(&true_value, &false_value).map(Self::Var)
}
},
} }
} }
} }
@ -473,7 +473,7 @@ impl NonNativeFieldVar
Ok(NonNativeFieldMulResultVar::Var( Ok(NonNativeFieldMulResultVar::Var(
other_v.mul_without_reduce(&self_v)?, other_v.mul_without_reduce(&self_v)?,
)) ))
}
},
}, },
Self::Var(v) => { Self::Var(v) => {
let other_v = match other { let other_v = match other {
@ -482,13 +482,13 @@ impl NonNativeFieldVar
self.cs(), self.cs(),
other_c, other_c,
)? )?
}
},
Self::Var(other_v) => other_v.clone(), Self::Var(other_v) => other_v.clone(),
}; };
Ok(NonNativeFieldMulResultVar::Var( Ok(NonNativeFieldMulResultVar::Var(
v.mul_without_reduce(&other_v)?, v.mul_without_reduce(&other_v)?,
)) ))
}
},
} }
} }
} }

+ 2
- 2
src/fields/nonnative/mod.rs

@ -130,7 +130,7 @@ macro_rules! overhead {
($x:expr) => {{ ($x:expr) => {{
use ark_ff::BigInteger; use ark_ff::BigInteger;
let num = $x; let num = $x;
let num_bits = num.into_repr().to_bits_be();
let num_bits = num.into_bigint().to_bits_be();
let mut skipped_bits = 0; let mut skipped_bits = 0;
for b in num_bits.iter() { for b in num_bits.iter() {
if *b == false { if *b == false {
@ -159,7 +159,7 @@ pub(crate) use overhead;
/// Parameters for a specific `NonNativeFieldVar` instantiation /// Parameters for a specific `NonNativeFieldVar` instantiation
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct NonNativeFieldParams {
pub struct NonNativeFieldConfig {
/// The number of limbs (`BaseField` elements) used to represent a `TargetField` element. Highest limb first. /// The number of limbs (`BaseField` elements) used to represent a `TargetField` element. Highest limb first.
pub num_limbs: usize, pub num_limbs: usize,

+ 1
- 1
src/fields/nonnative/mul_result.rs

@ -53,7 +53,7 @@ impl
TargetField, TargetField,
BaseField, BaseField,
>::from(v)) >::from(v))
}
},
} }
} }
} }

+ 7
- 7
src/fields/nonnative/params.rs

@ -1,4 +1,4 @@
use super::NonNativeFieldParams;
use super::NonNativeFieldConfig;
/// Obtain the parameters from a `ConstraintSystem`'s cache or generate a new one /// Obtain the parameters from a `ConstraintSystem`'s cache or generate a new one
#[must_use] #[must_use]
@ -6,10 +6,10 @@ pub const fn get_params(
target_field_size: usize, target_field_size: usize,
base_field_size: usize, base_field_size: usize,
optimization_type: OptimizationType, optimization_type: OptimizationType,
) -> NonNativeFieldParams {
) -> NonNativeFieldConfig {
let (num_of_limbs, limb_size) = let (num_of_limbs, limb_size) =
find_parameters(base_field_size, target_field_size, optimization_type); find_parameters(base_field_size, target_field_size, optimization_type);
NonNativeFieldParams {
NonNativeFieldConfig {
num_limbs: num_of_limbs, num_limbs: num_of_limbs,
bits_per_limb: limb_size, bits_per_limb: limb_size,
} }
@ -54,10 +54,10 @@ pub const fn find_parameters(
match optimization_type { match optimization_type {
OptimizationType::Constraints => { OptimizationType::Constraints => {
this_cost += 2 * num_of_limbs - 1; this_cost += 2 * num_of_limbs - 1;
}
},
OptimizationType::Weight => { OptimizationType::Weight => {
this_cost += 6 * num_of_limbs * num_of_limbs; this_cost += 6 * num_of_limbs * num_of_limbs;
}
},
}; };
match optimization_type { match optimization_type {
@ -67,7 +67,7 @@ pub const fn find_parameters(
//this_cost += 2 * num_of_limbs - 1; // compute kp //this_cost += 2 * num_of_limbs - 1; // compute kp
this_cost += num_of_groups + (num_of_groups - 1) * (limb_size * 2 + surfeit) + 1; this_cost += num_of_groups + (num_of_groups - 1) * (limb_size * 2 + surfeit) + 1;
// equality check // equality check
}
},
OptimizationType::Weight => { OptimizationType::Weight => {
this_cost += target_field_prime_bit_length * 3 + target_field_prime_bit_length; // allocation of k this_cost += target_field_prime_bit_length * 3 + target_field_prime_bit_length; // allocation of k
this_cost += target_field_prime_bit_length * 3 this_cost += target_field_prime_bit_length * 3
@ -79,7 +79,7 @@ pub const fn find_parameters(
+ 6 * num_of_groups + 6 * num_of_groups
+ (num_of_groups - 1) * (2 * limb_size + surfeit) * 4 + (num_of_groups - 1) * (2 * limb_size + surfeit) * 4
+ 2; // equality check + 2; // equality check
}
},
}; };
if !found || this_cost < min_cost { if !found || this_cost < min_cost {

+ 28
- 24
src/fields/nonnative/reduce.rs

@ -5,7 +5,7 @@ use crate::eq::EqGadget;
use crate::fields::fp::FpVar; use crate::fields::fp::FpVar;
use crate::fields::FieldVar; use crate::fields::FieldVar;
use crate::{alloc::AllocVar, boolean::Boolean, R1CSVar}; use crate::{alloc::AllocVar, boolean::Boolean, R1CSVar};
use ark_ff::{biginteger::BigInteger, fields::FpParameters, BitIteratorBE, One, PrimeField, Zero};
use ark_ff::{biginteger::BigInteger, BitIteratorBE, One, PrimeField, Zero};
use ark_relations::{ use ark_relations::{
ns, ns,
r1cs::{ConstraintSystemRef, Result as R1CSResult}, r1cs::{ConstraintSystemRef, Result as R1CSResult},
@ -22,7 +22,7 @@ pub fn limbs_to_bigint(
let mut big_cur = BigUint::one(); let mut big_cur = BigUint::one();
let two = BigUint::from(2u32); let two = BigUint::from(2u32);
for limb in limbs.iter().rev() { for limb in limbs.iter().rev() {
let limb_repr = limb.into_repr().to_bits_le();
let limb_repr = limb.into_bigint().to_bits_le();
let mut small_cur = big_cur.clone(); let mut small_cur = big_cur.clone();
for limb_bit in limb_repr.iter() { for limb_bit in limb_repr.iter() {
if *limb_bit { if *limb_bit {
@ -41,7 +41,8 @@ pub fn bigint_to_basefield(bigint: &BigUint) -> BaseField
let mut cur = BaseField::one(); let mut cur = BaseField::one();
let bytes = bigint.to_bytes_be(); let bytes = bigint.to_bytes_be();
let basefield_256 = BaseField::from_repr(<BaseField as PrimeField>::BigInt::from(256)).unwrap();
let basefield_256 =
BaseField::from_bigint(<BaseField as PrimeField>::BigInt::from(256u64)).unwrap();
for byte in bytes.iter().rev() { for byte in bytes.iter().rev() {
let bytes_basefield = BaseField::from(*byte as u128); let bytes_basefield = BaseField::from(*byte as u128);
@ -60,7 +61,7 @@ pub struct Reducer {
} }
impl<TargetField: PrimeField, BaseField: PrimeField> Reducer<TargetField, BaseField> { impl<TargetField: PrimeField, BaseField: PrimeField> Reducer<TargetField, BaseField> {
/// convert limbs to bits (take at most `BaseField::size_in_bits() - 1` bits)
/// convert limbs to bits (take at most `BaseField::MODULUS_BIT_SIZE as usize - 1` bits)
/// This implementation would be more efficient than the original `to_bits` /// This implementation would be more efficient than the original `to_bits`
/// or `to_non_unique_bits` since we enforce that some bits are always zero. /// or `to_non_unique_bits` since we enforce that some bits are always zero.
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
@ -70,14 +71,16 @@ impl Reducer
) -> R1CSResult<Vec<Boolean<BaseField>>> { ) -> R1CSResult<Vec<Boolean<BaseField>>> {
let cs = limb.cs(); let cs = limb.cs();
let num_bits = min(BaseField::size_in_bits() - 1, num_bits);
let num_bits = min(BaseField::MODULUS_BIT_SIZE as usize - 1, num_bits);
let mut bits_considered = Vec::with_capacity(num_bits); let mut bits_considered = Vec::with_capacity(num_bits);
let limb_value = limb.value().unwrap_or_default(); let limb_value = limb.value().unwrap_or_default();
for b in BitIteratorBE::new(limb_value.into_repr()).skip(
<<BaseField as PrimeField>::Params as FpParameters>::REPR_SHAVE_BITS as usize
+ (BaseField::size_in_bits() - num_bits),
) {
let num_bits_to_shave =
BaseField::BigInt::NUM_LIMBS * 64 - (BaseField::MODULUS_BIT_SIZE as usize);
for b in BitIteratorBE::new(limb_value.into_bigint())
.skip(num_bits_to_shave + (BaseField::MODULUS_BIT_SIZE as usize - num_bits))
{
bits_considered.push(b); bits_considered.push(b);
} }
@ -131,13 +134,13 @@ impl Reducer
elem: &mut AllocatedNonNativeFieldVar<TargetField, BaseField>, elem: &mut AllocatedNonNativeFieldVar<TargetField, BaseField>,
) -> R1CSResult<()> { ) -> R1CSResult<()> {
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
elem.get_optimization_type(), elem.get_optimization_type(),
); );
let surfeit = overhead!(elem.num_of_additions_over_normal_form + BaseField::one()) + 1; let surfeit = overhead!(elem.num_of_additions_over_normal_form + BaseField::one()) + 1;
if BaseField::size_in_bits() > 2 * params.bits_per_limb + surfeit + 1 {
if BaseField::MODULUS_BIT_SIZE as usize > 2 * params.bits_per_limb + surfeit + 1 {
Ok(()) Ok(())
} else { } else {
Self::reduce(elem) Self::reduce(elem)
@ -156,13 +159,13 @@ impl Reducer
); );
let params = get_params( let params = get_params(
TargetField::size_in_bits(),
BaseField::size_in_bits(),
TargetField::MODULUS_BIT_SIZE as usize,
BaseField::MODULUS_BIT_SIZE as usize,
elem.get_optimization_type(), elem.get_optimization_type(),
); );
if 2 * params.bits_per_limb + ark_std::log2(params.num_limbs) as usize if 2 * params.bits_per_limb + ark_std::log2(params.num_limbs) as usize
> BaseField::size_in_bits() - 1
> BaseField::MODULUS_BIT_SIZE as usize - 1
{ {
panic!("The current limb parameters do not support multiplication."); panic!("The current limb parameters do not support multiplication.");
} }
@ -172,14 +175,14 @@ impl Reducer
+ BaseField::one()) + BaseField::one())
* (elem_other.num_of_additions_over_normal_form + BaseField::one()); * (elem_other.num_of_additions_over_normal_form + BaseField::one());
let overhead_limb = overhead!(prod_of_num_of_additions.mul( let overhead_limb = overhead!(prod_of_num_of_additions.mul(
&BaseField::from_repr(<BaseField as PrimeField>::BigInt::from(
&BaseField::from_bigint(<BaseField as PrimeField>::BigInt::from(
(params.num_limbs) as u64 (params.num_limbs) as u64
)) ))
.unwrap() .unwrap()
)); ));
let bits_per_mulresult_limb = 2 * (params.bits_per_limb + 1) + overhead_limb; let bits_per_mulresult_limb = 2 * (params.bits_per_limb + 1) + overhead_limb;
if bits_per_mulresult_limb < BaseField::size_in_bits() {
if bits_per_mulresult_limb < BaseField::MODULUS_BIT_SIZE as usize {
break; break;
} }
@ -220,7 +223,7 @@ impl Reducer
let zero = FpVar::<BaseField>::zero(); let zero = FpVar::<BaseField>::zero();
let mut limb_pairs = Vec::<(FpVar<BaseField>, FpVar<BaseField>)>::new(); let mut limb_pairs = Vec::<(FpVar<BaseField>, FpVar<BaseField>)>::new();
let num_limb_in_a_group = (BaseField::size_in_bits()
let num_limb_in_a_group = (BaseField::MODULUS_BIT_SIZE as usize
- 1 - 1
- surfeit - surfeit
- 1 - 1
@ -231,9 +234,9 @@ impl Reducer
let shift_array = { let shift_array = {
let mut array = Vec::new(); let mut array = Vec::new();
let mut cur = BaseField::one().into_repr();
let mut cur = BaseField::one().into_bigint();
for _ in 0..num_limb_in_a_group { for _ in 0..num_limb_in_a_group {
array.push(BaseField::from_repr(cur).unwrap());
array.push(BaseField::from_bigint(cur).unwrap());
cur.muln(shift_per_limb as u32); cur.muln(shift_per_limb as u32);
} }
@ -273,7 +276,8 @@ impl Reducer
for (group_id, (left_total_limb, right_total_limb, num_limb_in_this_group)) in for (group_id, (left_total_limb, right_total_limb, num_limb_in_this_group)) in
groupped_limb_pairs.iter().enumerate() groupped_limb_pairs.iter().enumerate()
{ {
let mut pad_limb_repr: <BaseField as PrimeField>::BigInt = BaseField::one().into_repr();
let mut pad_limb_repr: <BaseField as PrimeField>::BigInt =
BaseField::one().into_bigint();
pad_limb_repr.muln( pad_limb_repr.muln(
(surfeit (surfeit
@ -282,7 +286,7 @@ impl Reducer
+ 1 + 1
+ 1) as u32, + 1) as u32,
); );
let pad_limb = BaseField::from_repr(pad_limb_repr).unwrap();
let pad_limb = BaseField::from_bigint(pad_limb_repr).unwrap();
let left_total_limb_value = left_total_limb.value().unwrap_or_default(); let left_total_limb_value = left_total_limb.value().unwrap_or_default();
let right_total_limb_value = right_total_limb.value().unwrap_or_default(); let right_total_limb_value = right_total_limb.value().unwrap_or_default();
@ -290,10 +294,10 @@ impl Reducer
let mut carry_value = let mut carry_value =
left_total_limb_value + carry_in_value + pad_limb - right_total_limb_value; left_total_limb_value + carry_in_value + pad_limb - right_total_limb_value;
let mut carry_repr = carry_value.into_repr();
let mut carry_repr = carry_value.into_bigint();
carry_repr.divn((shift_per_limb * num_limb_in_this_group) as u32); carry_repr.divn((shift_per_limb * num_limb_in_this_group) as u32);
carry_value = BaseField::from_repr(carry_repr).unwrap();
carry_value = BaseField::from_bigint(carry_repr).unwrap();
let carry = FpVar::<BaseField>::new_witness(cs.clone(), || Ok(carry_value))?; let carry = FpVar::<BaseField>::new_witness(cs.clone(), || Ok(carry_value))?;

+ 22
- 22
src/fields/quadratic_extension.rs

@ -1,5 +1,5 @@
use ark_ff::{ use ark_ff::{
fields::{Field, QuadExtField, QuadExtParameters},
fields::{Field, QuadExtConfig, QuadExtField},
Zero, Zero,
}; };
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError}; use ark_relations::r1cs::{ConstraintSystemRef, Namespace, SynthesisError};
@ -16,7 +16,7 @@ use crate::{
#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Debug(bound = "BF: core::fmt::Debug"), Clone(bound = "BF: Clone"))] #[derivative(Debug(bound = "BF: core::fmt::Debug"), Clone(bound = "BF: Clone"))]
#[must_use] #[must_use]
pub struct QuadExtVar<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarParams<BF>>
pub struct QuadExtVar<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarConfig<BF>>
where where
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
{ {
@ -30,8 +30,8 @@ where
/// This trait describes parameters that are used to implement arithmetic for /// This trait describes parameters that are used to implement arithmetic for
/// `QuadExtVar`. /// `QuadExtVar`.
pub trait QuadExtVarParams<BF: FieldVar<Self::BaseField, Self::BasePrimeField>>:
QuadExtParameters
pub trait QuadExtVarConfig<BF: FieldVar<Self::BaseField, Self::BasePrimeField>>:
QuadExtConfig
where where
for<'a> &'a BF: FieldOpsBounds<'a, Self::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, Self::BaseField, BF>,
{ {
@ -41,7 +41,7 @@ where
fn mul_base_field_var_by_frob_coeff(fe: &mut BF, power: usize); fn mul_base_field_var_by_frob_coeff(fe: &mut BF, power: usize);
} }
impl<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarParams<BF>> QuadExtVar<BF, P>
impl<BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarConfig<BF>> QuadExtVar<BF, P>
where where
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
{ {
@ -94,7 +94,7 @@ where
let self_inverse = self.unitary_inverse()?; let self_inverse = self.unitary_inverse()?;
let mut found_nonzero = false; let mut found_nonzero = false;
let naf = ark_ff::biginteger::arithmetic::find_wnaf(exponent.as_ref());
let naf = ark_ff::biginteger::arithmetic::find_naf(exponent.as_ref());
for &value in naf.iter().rev() { for &value in naf.iter().rev() {
if found_nonzero { if found_nonzero {
@ -120,7 +120,7 @@ impl R1CSVar for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
type Value = QuadExtField<P>; type Value = QuadExtField<P>;
@ -141,7 +141,7 @@ impl From> for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
fn from(other: Boolean<P::BasePrimeField>) -> Self { fn from(other: Boolean<P::BasePrimeField>) -> Self {
let c0 = BF::from(other); let c0 = BF::from(other);
@ -154,14 +154,14 @@ impl<'a, BF, P> FieldOpsBounds<'a, QuadExtField

, QuadExtVar> for QuadE

where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
} }
impl<'a, BF, P> FieldOpsBounds<'a, QuadExtField<P>, QuadExtVar<BF, P>> for &'a QuadExtVar<BF, P> impl<'a, BF, P> FieldOpsBounds<'a, QuadExtField<P>, QuadExtVar<BF, P>> for &'a QuadExtVar<BF, P>
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
} }
@ -169,7 +169,7 @@ impl FieldVar, P::BasePrimeField> for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
fn constant(other: QuadExtField<P>) -> Self { fn constant(other: QuadExtField<P>) -> Self {
let c0 = BF::constant(other.c0); let c0 = BF::constant(other.c0);
@ -308,7 +308,7 @@ impl_bounded_ops!(
|this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| { |this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| {
this + QuadExtVar::constant(other) this + QuadExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarConfig<BF>),
for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF> for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>
); );
impl_bounded_ops!( impl_bounded_ops!(
@ -326,7 +326,7 @@ impl_bounded_ops!(
|this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| { |this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| {
this - QuadExtVar::constant(other) this - QuadExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarConfig<BF>),
for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF> for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>
); );
impl_bounded_ops!( impl_bounded_ops!(
@ -363,7 +363,7 @@ impl_bounded_ops!(
|this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| { |this: &'a QuadExtVar<BF, P>, other: QuadExtField<P>| {
this * QuadExtVar::constant(other) this * QuadExtVar::constant(other)
}, },
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarParams<BF>),
(BF: FieldVar<P::BaseField, P::BasePrimeField>, P: QuadExtVarConfig<BF>),
for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF> for <'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>
); );
@ -371,7 +371,7 @@ impl EqGadget for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn is_eq(&self, other: &Self) -> Result<Boolean<P::BasePrimeField>, SynthesisError> { fn is_eq(&self, other: &Self) -> Result<Boolean<P::BasePrimeField>, SynthesisError> {
@ -410,7 +410,7 @@ impl ToBitsGadget for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_bits_le(&self) -> Result<Vec<Boolean<P::BasePrimeField>>, SynthesisError> { fn to_bits_le(&self) -> Result<Vec<Boolean<P::BasePrimeField>>, SynthesisError> {
@ -433,7 +433,7 @@ impl ToBytesGadget for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> { fn to_bytes(&self) -> Result<Vec<UInt8<P::BasePrimeField>>, SynthesisError> {
@ -456,7 +456,7 @@ impl ToConstraintFieldGadget for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>, for<'a> &'a BF: FieldOpsBounds<'a, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
BF: ToConstraintFieldGadget<P::BasePrimeField>, BF: ToConstraintFieldGadget<P::BasePrimeField>,
{ {
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
@ -474,7 +474,7 @@ impl CondSelectGadget for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
#[inline] #[inline]
fn conditionally_select( fn conditionally_select(
@ -493,7 +493,7 @@ where
BF: FieldVar<P::BaseField, P::BasePrimeField> BF: FieldVar<P::BaseField, P::BasePrimeField>
+ TwoBitLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>, + TwoBitLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
type TableConstant = QuadExtField<P>; type TableConstant = QuadExtField<P>;
@ -515,7 +515,7 @@ where
BF: FieldVar<P::BaseField, P::BasePrimeField> BF: FieldVar<P::BaseField, P::BasePrimeField>
+ ThreeBitCondNegLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>, + ThreeBitCondNegLookupGadget<P::BasePrimeField, TableConstant = P::BaseField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
type TableConstant = QuadExtField<P>; type TableConstant = QuadExtField<P>;
@ -537,7 +537,7 @@ impl AllocVar, P::BasePrimeField> for QuadExtVar
where where
BF: FieldVar<P::BaseField, P::BasePrimeField>, BF: FieldVar<P::BaseField, P::BasePrimeField>,
for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>, for<'b> &'b BF: FieldOpsBounds<'b, P::BaseField, BF>,
P: QuadExtVarParams<BF>,
P: QuadExtVarConfig<BF>,
{ {
fn new_variable<T: Borrow<QuadExtField<P>>>( fn new_variable<T: Borrow<QuadExtField<P>>>(
cs: impl Into<Namespace<P::BasePrimeField>>, cs: impl Into<Namespace<P::BasePrimeField>>,

+ 5
- 5
src/groups/curves/short_weierstrass/bls12/mod.rs

@ -98,14 +98,14 @@ impl ToBytesGadget for G1PreparedVar

{

} }
} }
type Fp2G<P> = Fp2Var<<P as Bls12Parameters>::Fp2Params>;
type Fp2G<P> = Fp2Var<<P as Bls12Parameters>::Fp2Config>;
type LCoeff<P> = (Fp2G<P>, Fp2G<P>); type LCoeff<P> = (Fp2G<P>, Fp2G<P>);
/// Represents the cached precomputation that can be performed on a G2 element /// Represents the cached precomputation that can be performed on a G2 element
/// which enables speeding up pairing computation. /// which enables speeding up pairing computation.
#[derive(Derivative)] #[derive(Derivative)]
#[derivative( #[derivative(
Clone(bound = "Fp2Var<P::Fp2Params>: Clone"),
Debug(bound = "Fp2Var<P::Fp2Params>: Debug")
Clone(bound = "Fp2Var<P::Fp2Config>: Clone"),
Debug(bound = "Fp2Var<P::Fp2Config>: Debug")
)] )]
pub struct G2PreparedVar<P: Bls12Parameters> { pub struct G2PreparedVar<P: Bls12Parameters> {
#[doc(hidden)] #[doc(hidden)]
@ -135,7 +135,7 @@ impl AllocVar, P::Fp> for G2PreparedVar

{

.zip(z_s) .zip(z_s)
.map(|((x, y, _), z_inv)| (*x * &z_inv, *y * &z_inv)) .map(|((x, y, _), z_inv)| (*x * &z_inv, *y * &z_inv))
.collect::<Vec<_>>() .collect::<Vec<_>>()
}
},
TwistType::D => { TwistType::D => {
let mut z_s = projective_coeffs let mut z_s = projective_coeffs
.iter() .iter()
@ -147,7 +147,7 @@ impl AllocVar, P::Fp> for G2PreparedVar

{

.zip(z_s) .zip(z_s)
.map(|((_, x, y), z_inv)| (*x * &z_inv, *y * &z_inv)) .map(|((_, x, y), z_inv)| (*x * &z_inv, *y * &z_inv))
.collect::<Vec<_>>() .collect::<Vec<_>>()
}
},
} }
}); });

+ 17
- 17
src/groups/curves/short_weierstrass/mnt4/mod.rs

@ -31,9 +31,9 @@ pub struct G1PreparedVar {
#[doc(hidden)] #[doc(hidden)]
pub y: FpVar<P::Fp>, pub y: FpVar<P::Fp>,
#[doc(hidden)] #[doc(hidden)]
pub x_twist: Fp2Var<P::Fp2Params>,
pub x_twist: Fp2Var<P::Fp2Config>,
#[doc(hidden)] #[doc(hidden)]
pub y_twist: Fp2Var<P::Fp2Params>,
pub y_twist: Fp2Var<P::Fp2Config>,
} }
impl<P: MNT4Parameters> AllocVar<G1Prepared<P>, P::Fp> for G1PreparedVar<P> { impl<P: MNT4Parameters> AllocVar<G1Prepared<P>, P::Fp> for G1PreparedVar<P> {
@ -131,7 +131,7 @@ impl ToBytesGadget for G1PreparedVar

{

} }
} }
type Fp2G<P> = Fp2Var<<P as MNT4Parameters>::Fp2Params>;
type Fp2G<P> = Fp2Var<<P as MNT4Parameters>::Fp2Config>;
/// Represents the cached precomputation that can be performed on a G2 element /// Represents the cached precomputation that can be performed on a G2 element
/// which enables speeding up pairing computation. /// which enables speeding up pairing computation.
@ -139,13 +139,13 @@ type Fp2G

= Fp2Var<

::Fp2Params>;

#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))] #[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
pub struct G2PreparedVar<P: MNT4Parameters> { pub struct G2PreparedVar<P: MNT4Parameters> {
#[doc(hidden)] #[doc(hidden)]
pub x: Fp2Var<P::Fp2Params>,
pub x: Fp2Var<P::Fp2Config>,
#[doc(hidden)] #[doc(hidden)]
pub y: Fp2Var<P::Fp2Params>,
pub y: Fp2Var<P::Fp2Config>,
#[doc(hidden)] #[doc(hidden)]
pub x_over_twist: Fp2Var<P::Fp2Params>,
pub x_over_twist: Fp2Var<P::Fp2Config>,
#[doc(hidden)] #[doc(hidden)]
pub y_over_twist: Fp2Var<P::Fp2Params>,
pub y_over_twist: Fp2Var<P::Fp2Config>,
#[doc(hidden)] #[doc(hidden)]
pub double_coefficients: Vec<AteDoubleCoefficientsVar<P>>, pub double_coefficients: Vec<AteDoubleCoefficientsVar<P>>,
#[doc(hidden)] #[doc(hidden)]
@ -344,10 +344,10 @@ impl G2PreparedVar

{

#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))] #[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
pub struct AteDoubleCoefficientsVar<P: MNT4Parameters> { pub struct AteDoubleCoefficientsVar<P: MNT4Parameters> {
pub c_h: Fp2Var<P::Fp2Params>,
pub c_4c: Fp2Var<P::Fp2Params>,
pub c_j: Fp2Var<P::Fp2Params>,
pub c_l: Fp2Var<P::Fp2Params>,
pub c_h: Fp2Var<P::Fp2Config>,
pub c_4c: Fp2Var<P::Fp2Config>,
pub c_j: Fp2Var<P::Fp2Config>,
pub c_l: Fp2Var<P::Fp2Config>,
} }
impl<P: MNT4Parameters> AllocVar<AteDoubleCoefficients<P>, P::Fp> for AteDoubleCoefficientsVar<P> { impl<P: MNT4Parameters> AllocVar<AteDoubleCoefficients<P>, P::Fp> for AteDoubleCoefficientsVar<P> {
@ -429,8 +429,8 @@ impl AteDoubleCoefficientsVar

{

#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))] #[derivative(Clone(bound = "P: MNT4Parameters"), Debug(bound = "P: MNT4Parameters"))]
pub struct AteAdditionCoefficientsVar<P: MNT4Parameters> { pub struct AteAdditionCoefficientsVar<P: MNT4Parameters> {
pub c_l1: Fp2Var<P::Fp2Params>,
pub c_rz: Fp2Var<P::Fp2Params>,
pub c_l1: Fp2Var<P::Fp2Config>,
pub c_rz: Fp2Var<P::Fp2Config>,
} }
impl<P: MNT4Parameters> AllocVar<AteAdditionCoefficients<P>, P::Fp> impl<P: MNT4Parameters> AllocVar<AteAdditionCoefficients<P>, P::Fp>
@ -488,8 +488,8 @@ impl AteAdditionCoefficientsVar

{

#[doc(hidden)] #[doc(hidden)]
pub struct G2ProjectiveExtendedVar<P: MNT4Parameters> { pub struct G2ProjectiveExtendedVar<P: MNT4Parameters> {
pub x: Fp2Var<P::Fp2Params>,
pub y: Fp2Var<P::Fp2Params>,
pub z: Fp2Var<P::Fp2Params>,
pub t: Fp2Var<P::Fp2Params>,
pub x: Fp2Var<P::Fp2Config>,
pub y: Fp2Var<P::Fp2Config>,
pub z: Fp2Var<P::Fp2Config>,
pub t: Fp2Var<P::Fp2Config>,
} }

+ 17
- 17
src/groups/curves/short_weierstrass/mnt6/mod.rs

@ -31,9 +31,9 @@ pub struct G1PreparedVar {
#[doc(hidden)] #[doc(hidden)]
pub y: FpVar<P::Fp>, pub y: FpVar<P::Fp>,
#[doc(hidden)] #[doc(hidden)]
pub x_twist: Fp3Var<P::Fp3Params>,
pub x_twist: Fp3Var<P::Fp3Config>,
#[doc(hidden)] #[doc(hidden)]
pub y_twist: Fp3Var<P::Fp3Params>,
pub y_twist: Fp3Var<P::Fp3Config>,
} }
impl<P: MNT6Parameters> G1PreparedVar<P> { impl<P: MNT6Parameters> G1PreparedVar<P> {
@ -131,7 +131,7 @@ impl ToBytesGadget for G1PreparedVar

{

} }
} }
type Fp3G<P> = Fp3Var<<P as MNT6Parameters>::Fp3Params>;
type Fp3G<P> = Fp3Var<<P as MNT6Parameters>::Fp3Config>;
/// Represents the cached precomputation that can be performed on a G2 element /// Represents the cached precomputation that can be performed on a G2 element
/// which enables speeding up pairing computation. /// which enables speeding up pairing computation.
@ -139,13 +139,13 @@ type Fp3G

= Fp3Var<

::Fp3Params>;

#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))] #[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
pub struct G2PreparedVar<P: MNT6Parameters> { pub struct G2PreparedVar<P: MNT6Parameters> {
#[doc(hidden)] #[doc(hidden)]
pub x: Fp3Var<P::Fp3Params>,
pub x: Fp3Var<P::Fp3Config>,
#[doc(hidden)] #[doc(hidden)]
pub y: Fp3Var<P::Fp3Params>,
pub y: Fp3Var<P::Fp3Config>,
#[doc(hidden)] #[doc(hidden)]
pub x_over_twist: Fp3Var<P::Fp3Params>,
pub x_over_twist: Fp3Var<P::Fp3Config>,
#[doc(hidden)] #[doc(hidden)]
pub y_over_twist: Fp3Var<P::Fp3Params>,
pub y_over_twist: Fp3Var<P::Fp3Config>,
#[doc(hidden)] #[doc(hidden)]
pub double_coefficients: Vec<AteDoubleCoefficientsVar<P>>, pub double_coefficients: Vec<AteDoubleCoefficientsVar<P>>,
#[doc(hidden)] #[doc(hidden)]
@ -344,10 +344,10 @@ impl G2PreparedVar

{

#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))] #[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
pub struct AteDoubleCoefficientsVar<P: MNT6Parameters> { pub struct AteDoubleCoefficientsVar<P: MNT6Parameters> {
pub c_h: Fp3Var<P::Fp3Params>,
pub c_4c: Fp3Var<P::Fp3Params>,
pub c_j: Fp3Var<P::Fp3Params>,
pub c_l: Fp3Var<P::Fp3Params>,
pub c_h: Fp3Var<P::Fp3Config>,
pub c_4c: Fp3Var<P::Fp3Config>,
pub c_j: Fp3Var<P::Fp3Config>,
pub c_l: Fp3Var<P::Fp3Config>,
} }
impl<P: MNT6Parameters> AllocVar<AteDoubleCoefficients<P>, P::Fp> for AteDoubleCoefficientsVar<P> { impl<P: MNT6Parameters> AllocVar<AteDoubleCoefficients<P>, P::Fp> for AteDoubleCoefficientsVar<P> {
@ -427,8 +427,8 @@ impl AteDoubleCoefficientsVar

{

#[derive(Derivative)] #[derive(Derivative)]
#[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))] #[derivative(Clone(bound = "P: MNT6Parameters"), Debug(bound = "P: MNT6Parameters"))]
pub struct AteAdditionCoefficientsVar<P: MNT6Parameters> { pub struct AteAdditionCoefficientsVar<P: MNT6Parameters> {
pub c_l1: Fp3Var<P::Fp3Params>,
pub c_rz: Fp3Var<P::Fp3Params>,
pub c_l1: Fp3Var<P::Fp3Config>,
pub c_rz: Fp3Var<P::Fp3Config>,
} }
impl<P: MNT6Parameters> AllocVar<AteAdditionCoefficients<P>, P::Fp> impl<P: MNT6Parameters> AllocVar<AteAdditionCoefficients<P>, P::Fp>
@ -487,8 +487,8 @@ impl AteAdditionCoefficientsVar

{

#[doc(hidden)] #[doc(hidden)]
pub struct G2ProjectiveExtendedVar<P: MNT6Parameters> { pub struct G2ProjectiveExtendedVar<P: MNT6Parameters> {
pub x: Fp3Var<P::Fp3Params>,
pub y: Fp3Var<P::Fp3Params>,
pub z: Fp3Var<P::Fp3Params>,
pub t: Fp3Var<P::Fp3Params>,
pub x: Fp3Var<P::Fp3Config>,
pub y: Fp3Var<P::Fp3Config>,
pub z: Fp3Var<P::Fp3Config>,
pub t: Fp3Var<P::Fp3Config>,
} }

+ 9
- 9
src/groups/curves/short_weierstrass/mod.rs

@ -209,7 +209,7 @@ where
} else { } else {
(Ok(ge.x), Ok(ge.y), Ok(P::BaseField::one())) (Ok(ge.x), Ok(ge.y), Ok(P::BaseField::one()))
} }
}
},
_ => ( _ => (
Err(SynthesisError::AssignmentMissing), Err(SynthesisError::AssignmentMissing),
Err(SynthesisError::AssignmentMissing), Err(SynthesisError::AssignmentMissing),
@ -276,7 +276,7 @@ where
multiple_of_power_of_two: &mut NonZeroAffineVar<P, F>, multiple_of_power_of_two: &mut NonZeroAffineVar<P, F>,
bits: &[&Boolean<<P::BaseField as Field>::BasePrimeField>], bits: &[&Boolean<<P::BaseField as Field>::BasePrimeField>],
) -> Result<(), SynthesisError> { ) -> Result<(), SynthesisError> {
let scalar_modulus_bits = <P::ScalarField as PrimeField>::size_in_bits();
let scalar_modulus_bits = <P::ScalarField as PrimeField>::MODULUS_BIT_SIZE as usize;
assert!(scalar_modulus_bits >= bits.len()); assert!(scalar_modulus_bits >= bits.len());
let split_len = ark_std::cmp::min(scalar_modulus_bits - 2, bits.len()); let split_len = ark_std::cmp::min(scalar_modulus_bits - 2, bits.len());
@ -418,7 +418,7 @@ where
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn enforce_prime_order(&self) -> Result<(), SynthesisError> { fn enforce_prime_order(&self) -> Result<(), SynthesisError> {
unimplemented!("cannot enforce prime order"); unimplemented!("cannot enforce prime order");
// let r_minus_1 = (-P::ScalarField::one()).into_repr();
// let r_minus_1 = (-P::ScalarField::one()).into_bigint();
// let mut result = Self::zero(); // let mut result = Self::zero();
// for b in BitIteratorBE::without_leading_zeros(r_minus_1) { // for b in BitIteratorBE::without_leading_zeros(r_minus_1) {
@ -513,11 +513,11 @@ where
// little-endian. // little-endian.
bits.reverse(); bits.reverse();
let scalar_modulus_bits = <P::ScalarField as PrimeField>::size_in_bits();
let scalar_modulus_bits = <P::ScalarField as PrimeField>::MODULUS_BIT_SIZE;
let mut mul_result = Self::zero(); let mut mul_result = Self::zero();
let mut power_of_two_times_self = non_zero_self; let mut power_of_two_times_self = non_zero_self;
// We chunk up `bits` into `p`-sized chunks. // We chunk up `bits` into `p`-sized chunks.
for bits in bits.chunks(scalar_modulus_bits) {
for bits in bits.chunks(scalar_modulus_bits as usize) {
self.fixed_scalar_mul_le(&mut mul_result, &mut power_of_two_times_self, bits)?; self.fixed_scalar_mul_le(&mut mul_result, &mut power_of_two_times_self, bits)?;
} }
@ -803,7 +803,7 @@ where
let cofactor_weight = BitIteratorBE::new(cofactor.as_slice()) let cofactor_weight = BitIteratorBE::new(cofactor.as_slice())
.filter(|b| *b) .filter(|b| *b)
.count(); .count();
let modulus_minus_1 = (-P::ScalarField::one()).into_repr(); // r - 1
let modulus_minus_1 = (-P::ScalarField::one()).into_bigint(); // r - 1
let modulus_minus_1_weight = let modulus_minus_1_weight =
BitIteratorBE::new(modulus_minus_1).filter(|b| *b).count(); BitIteratorBE::new(modulus_minus_1).filter(|b| *b).count();
@ -831,9 +831,9 @@ where
|| { || {
f().map(|g| { f().map(|g| {
let g = g.into_affine(); let g = g.into_affine();
let mut power_of_two = P::ScalarField::one().into_repr();
let mut power_of_two = P::ScalarField::one().into_bigint();
power_of_two.muln(power_of_2); power_of_two.muln(power_of_2);
let power_of_two_inv = P::ScalarField::from_repr(power_of_two)
let power_of_two_inv = P::ScalarField::from_bigint(power_of_two)
.and_then(|n| n.inverse()) .and_then(|n| n.inverse())
.unwrap(); .unwrap();
g.mul(power_of_two_inv) g.mul(power_of_two_inv)
@ -866,7 +866,7 @@ where
ge.enforce_equal(&ge)?; ge.enforce_equal(&ge)?;
Ok(ge) Ok(ge)
} }
}
},
} }
} }
} }

+ 6
- 6
src/groups/curves/twisted_edwards/mod.rs

@ -276,7 +276,7 @@ where
Ok(ge) => { Ok(ge) => {
let ge: TEAffine<P> = ge.into(); let ge: TEAffine<P> = ge.into();
(Ok(ge.x), Ok(ge.y)) (Ok(ge.x), Ok(ge.y))
}
},
_ => ( _ => (
Err(SynthesisError::AssignmentMissing), Err(SynthesisError::AssignmentMissing),
Err(SynthesisError::AssignmentMissing), Err(SynthesisError::AssignmentMissing),
@ -458,7 +458,7 @@ where
/// is unchanged. /// is unchanged.
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn enforce_prime_order(&self) -> Result<(), SynthesisError> { fn enforce_prime_order(&self) -> Result<(), SynthesisError> {
let r_minus_1 = (-P::ScalarField::one()).into_repr();
let r_minus_1 = (-P::ScalarField::one()).into_bigint();
let mut result = Self::zero(); let mut result = Self::zero();
for b in BitIteratorBE::without_leading_zeros(r_minus_1) { for b in BitIteratorBE::without_leading_zeros(r_minus_1) {
@ -592,7 +592,7 @@ where
let cofactor_weight = BitIteratorBE::new(cofactor.as_slice()) let cofactor_weight = BitIteratorBE::new(cofactor.as_slice())
.filter(|b| *b) .filter(|b| *b)
.count(); .count();
let modulus_minus_1 = (-P::ScalarField::one()).into_repr(); // r - 1
let modulus_minus_1 = (-P::ScalarField::one()).into_bigint(); // r - 1
let modulus_minus_1_weight = let modulus_minus_1_weight =
BitIteratorBE::new(modulus_minus_1).filter(|b| *b).count(); BitIteratorBE::new(modulus_minus_1).filter(|b| *b).count();
@ -620,9 +620,9 @@ where
|| { || {
f().map(|g| { f().map(|g| {
let g = g.into_affine(); let g = g.into_affine();
let mut power_of_two = P::ScalarField::one().into_repr();
let mut power_of_two = P::ScalarField::one().into_bigint();
power_of_two.muln(power_of_2); power_of_two.muln(power_of_2);
let power_of_two_inv = P::ScalarField::from_repr(power_of_two)
let power_of_two_inv = P::ScalarField::from_bigint(power_of_two)
.and_then(|n| n.inverse()) .and_then(|n| n.inverse())
.unwrap(); .unwrap();
g.mul(power_of_two_inv) g.mul(power_of_two_inv)
@ -654,7 +654,7 @@ where
ge.enforce_equal(&ge)?; ge.enforce_equal(&ge)?;
Ok(ge) Ok(ge)
} }
}
},
} }
} }
} }

+ 6
- 6
src/pairing/bls12/mod.rs

@ -13,13 +13,13 @@ use core::marker::PhantomData;
/// Specifies the constraints for computing a pairing in a BLS12 bilinear group. /// Specifies the constraints for computing a pairing in a BLS12 bilinear group.
pub struct PairingVar<P: Bls12Parameters>(PhantomData<P>); pub struct PairingVar<P: Bls12Parameters>(PhantomData<P>);
type Fp2V<P> = Fp2Var<<P as Bls12Parameters>::Fp2Params>;
type Fp2V<P> = Fp2Var<<P as Bls12Parameters>::Fp2Config>;
impl<P: Bls12Parameters> PairingVar<P> { impl<P: Bls12Parameters> PairingVar<P> {
// Evaluate the line function at point p. // Evaluate the line function at point p.
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn ell( fn ell(
f: &mut Fp12Var<P::Fp12Params>,
f: &mut Fp12Var<P::Fp12Config>,
coeffs: &(Fp2V<P>, Fp2V<P>), coeffs: &(Fp2V<P>, Fp2V<P>),
p: &G1AffineVar<P>, p: &G1AffineVar<P>,
) -> Result<(), SynthesisError> { ) -> Result<(), SynthesisError> {
@ -35,7 +35,7 @@ impl PairingVar

{

c1.c1 *= &p.x; c1.c1 *= &p.x;
*f = f.mul_by_014(&c0, &c1, &c2)?; *f = f.mul_by_014(&c0, &c1, &c2)?;
Ok(()) Ok(())
}
},
TwistType::D => { TwistType::D => {
let c0 = Fp2V::<P>::new(p.y.clone(), zero); let c0 = Fp2V::<P>::new(p.y.clone(), zero);
let mut c1 = coeffs.0.clone(); let mut c1 = coeffs.0.clone();
@ -45,12 +45,12 @@ impl PairingVar

{

c1.c1 *= &p.x; c1.c1 *= &p.x;
*f = f.mul_by_034(&c0, &c1, &c2)?; *f = f.mul_by_034(&c0, &c1, &c2)?;
Ok(()) Ok(())
}
},
} }
} }
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn exp_by_x(f: &Fp12Var<P::Fp12Params>) -> Result<Fp12Var<P::Fp12Params>, SynthesisError> {
fn exp_by_x(f: &Fp12Var<P::Fp12Config>) -> Result<Fp12Var<P::Fp12Config>, SynthesisError> {
let mut result = f.optimized_cyclotomic_exp(P::X)?; let mut result = f.optimized_cyclotomic_exp(P::X)?;
if P::X_IS_NEGATIVE { if P::X_IS_NEGATIVE {
result = result.unitary_inverse()?; result = result.unitary_inverse()?;
@ -64,7 +64,7 @@ impl PG, P::Fp> for PairingVar

{

type G2Var = G2Var<P>; type G2Var = G2Var<P>;
type G1PreparedVar = G1PreparedVar<P>; type G1PreparedVar = G1PreparedVar<P>;
type G2PreparedVar = G2PreparedVar<P>; type G2PreparedVar = G2PreparedVar<P>;
type GTVar = Fp12Var<P::Fp12Params>;
type GTVar = Fp12Var<P::Fp12Config>;
#[tracing::instrument(target = "r1cs")] #[tracing::instrument(target = "r1cs")]
fn miller_loop( fn miller_loop(

+ 2
- 2
src/pairing/mnt4/mod.rs

@ -17,8 +17,8 @@ use core::marker::PhantomData;
/// Specifies the constraints for computing a pairing in a MNT4 bilinear group. /// Specifies the constraints for computing a pairing in a MNT4 bilinear group.
pub struct PairingVar<P: MNT4Parameters>(PhantomData<P>); pub struct PairingVar<P: MNT4Parameters>(PhantomData<P>);
type Fp2G<P> = Fp2Var<<P as MNT4Parameters>::Fp2Params>;
type Fp4G<P> = Fp4Var<<P as MNT4Parameters>::Fp4Params>;
type Fp2G<P> = Fp2Var<<P as MNT4Parameters>::Fp2Config>;
type Fp4G<P> = Fp4Var<<P as MNT4Parameters>::Fp4Config>;
/// A variable corresponding to `ark_ec::mnt4::GT`. /// A variable corresponding to `ark_ec::mnt4::GT`.
pub type GTVar<P> = Fp4G<P>; pub type GTVar<P> = Fp4G<P>;

+ 2
- 2
src/pairing/mnt6/mod.rs

@ -16,8 +16,8 @@ use core::marker::PhantomData;
/// Specifies the constraints for computing a pairing in a MNT6 bilinear group. /// Specifies the constraints for computing a pairing in a MNT6 bilinear group.
pub struct PairingVar<P: MNT6Parameters>(PhantomData<P>); pub struct PairingVar<P: MNT6Parameters>(PhantomData<P>);
type Fp3G<P> = Fp3Var<<P as MNT6Parameters>::Fp3Params>;
type Fp6G<P> = Fp6Var<<P as MNT6Parameters>::Fp6Params>;
type Fp3G<P> = Fp3Var<<P as MNT6Parameters>::Fp3Config>;
type Fp6G<P> = Fp6Var<<P as MNT6Parameters>::Fp6Config>;
/// A variable corresponding to `ark_ec::mnt6::GT`. /// A variable corresponding to `ark_ec::mnt6::GT`.
pub type GTVar<P> = Fp6G<P>; pub type GTVar<P> = Fp6G<P>;

+ 1
- 1
src/poly/domain/mod.rs

@ -129,7 +129,7 @@ mod tests {
fn test_query_coset_template<F: PrimeField>() { fn test_query_coset_template<F: PrimeField>() {
const COSET_DIM: u64 = 7; const COSET_DIM: u64 = 7;
const COSET_SIZE: usize = 1 << COSET_DIM;
const COSET_SIZE: u64 = 1 << COSET_DIM;
const LOCALIZATION: u64 = 3; const LOCALIZATION: u64 = 3;
let cs = ConstraintSystem::new_ref(); let cs = ConstraintSystem::new_ref();
let mut rng = test_rng(); let mut rng = test_rng();

+ 1
- 1
src/poly/evaluations/univariate/lagrange_interpolator.rs

@ -118,7 +118,7 @@ mod tests {
let domain = Radix2DomainVar::new( let domain = Radix2DomainVar::new(
gen, gen,
4, // 2^4 = 16 4, // 2^4 = 16
FpVar::constant(Fr::multiplicative_generator()),
FpVar::constant(Fr::GENERATOR),
) )
.unwrap(); .unwrap();
// generate evaluations of `poly` on this domain // generate evaluations of `poly` on this domain

+ 1
- 1
src/poly/evaluations/univariate/mod.rs

@ -452,7 +452,7 @@ mod tests {
let domain = Radix2DomainVar::new( let domain = Radix2DomainVar::new(
gen, gen,
4, // 2^4 = 16 4, // 2^4 = 16
FpVar::constant(Fr::multiplicative_generator()),
FpVar::constant(Fr::GENERATOR),
) )
.unwrap(); .unwrap();
let cs = ConstraintSystem::new_ref(); let cs = ConstraintSystem::new_ref();

+ 24
- 24
tests/arithmetic_tests.rs

@ -47,8 +47,8 @@ fn allocation_test(
.unwrap(); .unwrap();
let a_bits_actual: Vec<bool> = a_bits.into_iter().map(|b| b.value().unwrap()).collect(); let a_bits_actual: Vec<bool> = a_bits.into_iter().map(|b| b.value().unwrap()).collect();
let mut a_bits_expected = a_native.into_repr().to_bits_le();
a_bits_expected.truncate(TargetField::size_in_bits());
let mut a_bits_expected = a_native.into_bigint().to_bits_le();
a_bits_expected.truncate(TargetField::MODULUS_BIT_SIZE as usize);
assert_eq!( assert_eq!(
a_bits_actual, a_bits_expected, a_bits_actual, a_bits_expected,
"allocated bits does not equal the expected bits" "allocated bits does not equal the expected bits"
@ -107,8 +107,8 @@ fn multiplication_test
a_times_b_actual.eq(&a_times_b_expected), a_times_b_actual.eq(&a_times_b_expected),
"a_times_b = {:?}, a_times_b_actual = {:?}, a_times_b_expected = {:?}", "a_times_b = {:?}, a_times_b_actual = {:?}, a_times_b_expected = {:?}",
a_times_b, a_times_b,
a_times_b_actual.into_repr().as_ref(),
a_times_b_expected.into_repr().as_ref()
a_times_b_actual.into_bigint().as_ref(),
a_times_b_expected.into_bigint().as_ref()
); );
} }
@ -181,50 +181,50 @@ fn edge_cases_test(
assert!( assert!(
a_plus_zero_native.eq(&a_native), a_plus_zero_native.eq(&a_native),
"a_plus_zero = {:?}, a = {:?}", "a_plus_zero = {:?}, a = {:?}",
a_plus_zero_native.into_repr().as_ref(),
a_native.into_repr().as_ref()
a_plus_zero_native.into_bigint().as_ref(),
a_native.into_bigint().as_ref()
); );
assert!( assert!(
a_minus_zero_native.eq(&a_native), a_minus_zero_native.eq(&a_native),
"a_minus_zero = {:?}, a = {:?}", "a_minus_zero = {:?}, a = {:?}",
a_minus_zero_native.into_repr().as_ref(),
a_native.into_repr().as_ref()
a_minus_zero_native.into_bigint().as_ref(),
a_native.into_bigint().as_ref()
); );
assert!( assert!(
zero_minus_a_native.eq(&minus_a_native), zero_minus_a_native.eq(&minus_a_native),
"zero_minus_a = {:?}, minus_a = {:?}", "zero_minus_a = {:?}, minus_a = {:?}",
zero_minus_a_native.into_repr().as_ref(),
minus_a_native.into_repr().as_ref()
zero_minus_a_native.into_bigint().as_ref(),
minus_a_native.into_bigint().as_ref()
); );
assert!( assert!(
a_times_zero_native.eq(&zero_native), a_times_zero_native.eq(&zero_native),
"a_times_zero = {:?}, zero = {:?}", "a_times_zero = {:?}, zero = {:?}",
a_times_zero_native.into_repr().as_ref(),
zero_native.into_repr().as_ref()
a_times_zero_native.into_bigint().as_ref(),
zero_native.into_bigint().as_ref()
); );
assert!( assert!(
zero_plus_a_native.eq(&a_native), zero_plus_a_native.eq(&a_native),
"zero_plus_a = {:?}, a = {:?}", "zero_plus_a = {:?}, a = {:?}",
zero_plus_a_native.into_repr().as_ref(),
a_native.into_repr().as_ref()
zero_plus_a_native.into_bigint().as_ref(),
a_native.into_bigint().as_ref()
); );
assert!( assert!(
zero_times_a_native.eq(&zero_native), zero_times_a_native.eq(&zero_native),
"zero_times_a = {:?}, zero = {:?}", "zero_times_a = {:?}, zero = {:?}",
zero_times_a_native.into_repr().as_ref(),
zero_native.into_repr().as_ref()
zero_times_a_native.into_bigint().as_ref(),
zero_native.into_bigint().as_ref()
); );
assert!( assert!(
a_times_one_native.eq(&a_native), a_times_one_native.eq(&a_native),
"a_times_one = {:?}, a = {:?}", "a_times_one = {:?}, a = {:?}",
a_times_one_native.into_repr().as_ref(),
a_native.into_repr().as_ref()
a_times_one_native.into_bigint().as_ref(),
a_native.into_bigint().as_ref()
); );
assert!( assert!(
one_times_a_native.eq(&a_native), one_times_a_native.eq(&a_native),
"one_times_a = {:?}, a = {:?}", "one_times_a = {:?}, a = {:?}",
one_times_a_native.into_repr().as_ref(),
a_native.into_repr().as_ref()
one_times_a_native.into_bigint().as_ref(),
a_native.into_bigint().as_ref()
); );
} }
@ -327,15 +327,15 @@ fn randomized_arithmetic_test
0 => { 0 => {
num_native += &next_native; num_native += &next_native;
num += &next; num += &next;
}
},
1 => { 1 => {
num_native *= &next_native; num_native *= &next_native;
num *= &next; num *= &next;
}
},
2 => { 2 => {
num_native -= &next_native; num_native -= &next_native;
num -= &next; num -= &next;
}
},
_ => (), _ => (),
}; };
@ -465,7 +465,7 @@ fn double_stress_test_1
) )
.unwrap(); .unwrap();
// Add to at least BaseField::size_in_bits() to ensure that we teat the overflowing // Add to at least BaseField::size_in_bits() to ensure that we teat the overflowing
for _ in 0..TEST_COUNT + BaseField::size_in_bits() {
for _ in 0..TEST_COUNT + BaseField::MODULUS_BIT_SIZE as usize {
// double // double
num_native = num_native + &num_native; num_native = num_native + &num_native;
num = &num + &num; num = &num + &num;

Loading…
Cancel
Save