Migrate to ff 0.8

MSRV is now 1.44.0, matching the ff crate.
This commit is contained in:
Jack Grigg 2020-09-02 15:20:12 +01:00
parent 81f4aac8c7
commit f90fa65a32
12 changed files with 84 additions and 65 deletions

View File

@ -11,20 +11,21 @@ edition = "2018"
[dependencies]
bit-vec = "0.6"
bitvec = "0.18"
blake2s_simd = "0.5"
ff = "0.7"
ff = "0.8"
futures = "0.1"
futures-cpupool = { version = "0.1", optional = true }
group = "0.7"
group = "0.8"
num_cpus = { version = "1", optional = true }
crossbeam = { version = "0.7", optional = true }
pairing = { version = "0.17", optional = true }
pairing = { version = "0.18", optional = true }
rand_core = "0.5"
byteorder = "1"
subtle = "2.2.1"
[dev-dependencies]
bls12_381 = "0.2"
bls12_381 = "0.3"
hex-literal = "0.2"
rand = "0.7"
rand_xorshift = "0.2"

View File

@ -378,13 +378,17 @@ fn polynomial_arith() {
use bls12_381::Scalar as Fr;
use rand_core::RngCore;
fn test_mul<S: PrimeField, R: RngCore>(rng: &mut R) {
fn test_mul<S: PrimeField, R: RngCore>(mut rng: &mut R) {
let worker = Worker::new();
for coeffs_a in 0..70 {
for coeffs_b in 0..70 {
let mut a: Vec<_> = (0..coeffs_a).map(|_| Scalar::<S>(S::random(rng))).collect();
let mut b: Vec<_> = (0..coeffs_b).map(|_| Scalar::<S>(S::random(rng))).collect();
let mut a: Vec<_> = (0..coeffs_a)
.map(|_| Scalar::<S>(S::random(&mut rng)))
.collect();
let mut b: Vec<_> = (0..coeffs_b)
.map(|_| Scalar::<S>(S::random(&mut rng)))
.collect();
// naive evaluation
let mut naive = vec![Scalar(S::zero()); coeffs_a + coeffs_b];
@ -425,7 +429,7 @@ fn fft_composition() {
use bls12_381::Scalar as Fr;
use rand_core::RngCore;
fn test_comp<S: PrimeField, R: RngCore>(rng: &mut R) {
fn test_comp<S: PrimeField, R: RngCore>(mut rng: &mut R) {
let worker = Worker::new();
for coeffs in 0..10 {
@ -433,7 +437,7 @@ fn fft_composition() {
let mut v = vec![];
for _ in 0..coeffs {
v.push(Scalar::<S>(S::random(rng)));
v.push(Scalar::<S>(S::random(&mut rng)));
}
let mut domain = EvaluationDomain::from_coeffs(v.clone()).unwrap();
@ -464,7 +468,7 @@ fn parallel_fft_consistency() {
use rand_core::RngCore;
use std::cmp::min;
fn test_consistency<S: PrimeField, R: RngCore>(rng: &mut R) {
fn test_consistency<S: PrimeField, R: RngCore>(mut rng: &mut R) {
let worker = Worker::new();
for _ in 0..5 {
@ -472,7 +476,7 @@ fn parallel_fft_consistency() {
let d = 1 << log_d;
let v1 = (0..d)
.map(|_| Scalar::<S>(S::random(rng)))
.map(|_| Scalar::<S>(S::random(&mut rng)))
.collect::<Vec<_>>();
let mut v1 = EvaluationDomain::from_coeffs(v1).unwrap();
let mut v2 = EvaluationDomain::from_coeffs(v1.coeffs.clone()).unwrap();

View File

@ -1,6 +1,6 @@
//! Gadgets for allocating bits in the circuit and performing boolean logic.
use ff::{BitIterator, PrimeField};
use ff::PrimeField;
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
@ -321,12 +321,13 @@ pub fn field_into_allocated_bits_le<
// Deconstruct in big-endian bit order
let values = match value {
Some(ref value) => {
let mut field_char = BitIterator::<u8, _>::new(F::char());
let field_char = F::char_le_bits();
let mut field_char = field_char.into_iter().rev();
let mut tmp = Vec::with_capacity(F::NUM_BITS as usize);
let mut found_one = false;
for b in BitIterator::<u8, _>::new(value.to_repr()) {
for b in value.to_le_bits().into_iter().rev().cloned() {
// Skip leading bits
found_one |= field_char.next().unwrap();
if !found_one {

View File

@ -1,6 +1,6 @@
//! Gadgets representing numbers in the scalar field of the underlying curve.
use ff::{BitIterator, PrimeField};
use ff::PrimeField;
use crate::{ConstraintSystem, LinearCombination, SynthesisError, Variable};
@ -102,8 +102,11 @@ impl<Scalar: PrimeField> AllocatedNum<Scalar> {
// We want to ensure that the bit representation of a is
// less than or equal to r - 1.
let mut a = self.value.map(|e| BitIterator::<u8, _>::new(e.to_repr()));
let b = (-Scalar::one()).to_repr();
let a = self.value.map(|e| e.to_le_bits());
let b = (-Scalar::one()).to_le_bits();
// Get the bits of a in big-endian order
let mut a = a.as_ref().map(|e| e.into_iter().rev());
let mut result = vec![];
@ -113,7 +116,7 @@ impl<Scalar: PrimeField> AllocatedNum<Scalar> {
let mut found_one = false;
let mut i = 0;
for b in BitIterator::<u8, _>::new(b) {
for b in b.into_iter().rev().cloned() {
let a_bit = a.as_mut().map(|e| e.next().unwrap());
// Skip over unset bits at the beginning
@ -127,7 +130,8 @@ impl<Scalar: PrimeField> AllocatedNum<Scalar> {
if b {
// This is part of a run of ones. Let's just
// allocate the boolean with the expected value.
let a_bit = AllocatedBit::alloc(cs.namespace(|| format!("bit {}", i)), a_bit)?;
let a_bit =
AllocatedBit::alloc(cs.namespace(|| format!("bit {}", i)), a_bit.cloned())?;
// ... and add it to the current run of ones.
current_run.push(a_bit.clone());
result.push(a_bit);
@ -153,7 +157,7 @@ impl<Scalar: PrimeField> AllocatedNum<Scalar> {
let a_bit = AllocatedBit::alloc_conditionally(
cs.namespace(|| format!("bit {}", i)),
a_bit,
a_bit.cloned(),
&last_run.as_ref().expect("char always starts with a one"),
)?;
result.push(a_bit);
@ -411,7 +415,7 @@ impl<Scalar: PrimeField> Num<Scalar> {
mod test {
use crate::ConstraintSystem;
use bls12_381::Scalar;
use ff::{BitIterator, Field, PrimeField};
use ff::{Field, PrimeField};
use rand_core::SeedableRng;
use rand_xorshift::XorShiftRng;
use std::ops::{Neg, SubAssign};
@ -560,8 +564,12 @@ mod test {
assert!(cs.is_satisfied());
for (b, a) in BitIterator::<u8, _>::new(r.to_repr())
for (b, a) in r
.to_le_bits()
.into_iter()
.rev()
.skip(1)
.cloned()
.zip(bits.iter().rev())
{
if let &Boolean::Is(ref a) = a {

View File

@ -1,6 +1,6 @@
//! Helpers for testing circuit implementations.
use ff::{Endianness, PrimeField};
use ff::PrimeField;
use crate::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
@ -105,8 +105,9 @@ fn hash_lc<Scalar: PrimeField>(terms: &[(Variable, Scalar)], h: &mut Blake2sStat
}
}
let mut coeff_repr = coeff.to_repr();
<Scalar as PrimeField>::ReprEndianness::toggle_little_endian(&mut coeff_repr);
// TODO: Change this to hash over the standard scalar endianness, not an assumed
// little-endian representation that we flip to big-endian.
let coeff_repr = coeff.to_repr();
let coeff_be: Vec<_> = coeff_repr.as_ref().iter().cloned().rev().collect();
buf[9..].copy_from_slice(&coeff_be[..]);
@ -179,7 +180,7 @@ impl<Scalar: PrimeField> TestConstraintSystem<Scalar> {
}
}
write!(s, "{} . ", coeff).unwrap();
write!(s, "{:?} . ", coeff).unwrap();
}
match var.0.get_unchecked() {

View File

@ -18,7 +18,7 @@ use crate::multicore::Worker;
/// a circuit.
pub fn generate_random_parameters<E, C, R>(
circuit: C,
rng: &mut R,
mut rng: &mut R,
) -> Result<Parameters<E>, SynthesisError>
where
E: Engine,
@ -27,13 +27,13 @@ where
C: Circuit<E::Fr>,
R: RngCore,
{
let g1 = E::G1::random(rng);
let g2 = E::G2::random(rng);
let alpha = E::Fr::random(rng);
let beta = E::Fr::random(rng);
let gamma = E::Fr::random(rng);
let delta = E::Fr::random(rng);
let tau = E::Fr::random(rng);
let g1 = E::G1::random(&mut rng);
let g2 = E::G2::random(&mut rng);
let alpha = E::Fr::random(&mut rng);
let beta = E::Fr::random(&mut rng);
let gamma = E::Fr::random(&mut rng);
let delta = E::Fr::random(&mut rng);
let tau = E::Fr::random(&mut rng);
generate_parameters::<E, C>(circuit, g1, g2, alpha, beta, gamma, delta, tau)
}

View File

@ -515,11 +515,13 @@ mod test_with_bls12_381 {
}
}
let rng = &mut thread_rng();
let mut rng = thread_rng();
let params =
generate_random_parameters::<Bls12, _, _>(MySillyCircuit { a: None, b: None }, rng)
.unwrap();
let params = generate_random_parameters::<Bls12, _, _>(
MySillyCircuit { a: None, b: None },
&mut rng,
)
.unwrap();
{
let mut v = vec![];
@ -537,8 +539,8 @@ mod test_with_bls12_381 {
let pvk = prepare_verifying_key::<Bls12>(&params.vk);
for _ in 0..100 {
let a = Scalar::random(rng);
let b = Scalar::random(rng);
let a = Scalar::random(&mut rng);
let b = Scalar::random(&mut rng);
let mut c = a;
c.mul_assign(&b);
@ -548,7 +550,7 @@ mod test_with_bls12_381 {
b: Some(b),
},
&params,
rng,
&mut rng,
)
.unwrap();

View File

@ -162,15 +162,15 @@ impl<S: PrimeField> ConstraintSystem<S> for ProvingAssignment<S> {
pub fn create_random_proof<E, C, R, P: ParameterSource<E>>(
circuit: C,
params: P,
rng: &mut R,
mut rng: &mut R,
) -> Result<Proof<E>, SynthesisError>
where
E: Engine,
C: Circuit<E::Fr>,
R: RngCore,
{
let r = E::Fr::random(rng);
let s = E::Fr::random(rng);
let r = E::Fr::random(&mut rng);
let s = E::Fr::random(&mut rng);
create_proof::<E, C, P>(circuit, params, r, s)
}

View File

@ -1,3 +1,4 @@
use bitvec::{array::BitArray, order::Lsb0};
use ff::{Field, PrimeField};
use group::{
prime::{PrimeCurve, PrimeCurveAffine, PrimeGroup},
@ -182,7 +183,7 @@ impl Shr<u32> for Fr {
}
impl Field for Fr {
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
fn random(mut rng: impl RngCore) -> Self {
Fr(Wrapping(rng.next_u32()) % MODULUS_R)
}
@ -288,7 +289,7 @@ impl Default for FrRepr {
impl PrimeField for Fr {
type Repr = FrRepr;
type ReprEndianness = byteorder::LittleEndian;
type ReprBits = u64;
const NUM_BITS: u32 = 16;
const CAPACITY: u32 = 15;
@ -307,12 +308,16 @@ impl PrimeField for Fr {
FrRepr::from(*self)
}
fn to_le_bits(&self) -> BitArray<Lsb0, Self::ReprBits> {
BitArray::new((self.0).0 as u64)
}
fn is_odd(&self) -> bool {
(self.0).0 % 2 != 0
}
fn char() -> FrRepr {
Fr(MODULUS_R).into()
fn char_le_bits() -> BitArray<Lsb0, Self::ReprBits> {
BitArray::new(MODULUS_R.0 as u64)
}
fn multiplicative_generator() -> Fr {
@ -372,7 +377,7 @@ impl MillerLoopResult for Fr {
impl Group for Fr {
type Scalar = Fr;
fn random<R: RngCore + ?Sized>(rng: &mut R) -> Self {
fn random(rng: impl RngCore) -> Self {
<Fr as Field>::random(rng)
}

View File

@ -367,7 +367,7 @@ fn test_xordemo() {
.iter()
.enumerate()
{
let coeff = Fr::from_str(&format!("{}", coeff)).unwrap();
let coeff = Fr::from_str(&format!("{:?}", coeff)).unwrap();
let mut tmp = params.h[i];
tmp.mul_assign(&coeff);

View File

@ -1,6 +1,6 @@
use super::multicore::Worker;
use bit_vec::{self, BitVec};
use ff::{Endianness, Field, PrimeField};
use ff::{Field, PrimeField};
use futures::Future;
use group::prime::{PrimeCurve, PrimeCurveAffine};
use std::io;
@ -195,16 +195,13 @@ where
bases.skip(1)?;
}
} else {
let mut exp = exp.to_repr();
<G::Scalar as PrimeField>::ReprEndianness::toggle_little_endian(&mut exp);
let exp = exp.to_le_bits();
let exp = exp
.as_ref()
.into_iter()
.map(|b| (0..8).map(move |i| (b >> i) & 1u8))
.flatten()
.skip(skip as usize)
.take(c as usize)
.cloned()
.enumerate()
.fold(0u64, |acc, (i, b)| acc + ((b as u64) << i));
@ -318,15 +315,15 @@ fn test_with_bls12() {
const SAMPLES: usize = 1 << 14;
let rng = &mut rand::thread_rng();
let mut rng = rand::thread_rng();
let v = Arc::new(
(0..SAMPLES)
.map(|_| Scalar::random(rng))
.map(|_| Scalar::random(&mut rng))
.collect::<Vec<_>>(),
);
let g = Arc::new(
(0..SAMPLES)
.map(|_| <Bls12 as Engine>::G1::random(rng).to_affine())
.map(|_| <Bls12 as Engine>::G1::random(&mut rng).to_affine())
.collect::<Vec<_>>(),
);

View File

@ -147,11 +147,11 @@ impl<'a, Scalar: PrimeField> Circuit<Scalar> for MiMCDemo<'a, Scalar> {
fn test_mimc() {
// This may not be cryptographically safe, use
// `OsRng` (for example) in production software.
let rng = &mut thread_rng();
let mut rng = thread_rng();
// Generate the MiMC round constants
let constants = (0..MIMC_ROUNDS)
.map(|_| Scalar::random(rng))
.map(|_| Scalar::random(&mut rng))
.collect::<Vec<_>>();
println!("Creating parameters...");
@ -164,7 +164,7 @@ fn test_mimc() {
constants: &constants,
};
generate_random_parameters::<Bls12, _, _>(c, rng).unwrap()
generate_random_parameters::<Bls12, _, _>(c, &mut rng).unwrap()
};
// Prepare the verification key (for proof verification)
@ -183,8 +183,8 @@ fn test_mimc() {
for _ in 0..SAMPLES {
// Generate a random preimage and compute the image
let xl = Scalar::random(rng);
let xr = Scalar::random(rng);
let xl = Scalar::random(&mut rng);
let xr = Scalar::random(&mut rng);
let image = mimc(xl, xr, &constants);
proof_vec.truncate(0);
@ -200,7 +200,7 @@ fn test_mimc() {
};
// Create a groth16 proof with our parameters.
let proof = create_random_proof(c, &params, rng).unwrap();
let proof = create_random_proof(c, &params, &mut rng).unwrap();
proof.write(&mut proof_vec).unwrap();
}