Remove usage of `FieldExt::rand`

All APIs now take `R: RngCore` arguments instead of internally depending
on `rand::rngs::OsRng`.
This commit is contained in:
Jack Grigg 2021-12-25 13:36:41 +00:00
parent 9297a938ab
commit 1556489a9f
17 changed files with 145 additions and 58 deletions

View File

@ -10,6 +10,7 @@ and this project adheres to Rust's notion of
- `halo2::dev::LookupFailure` (used in `VerifyFailure::Lookup`) - `halo2::dev::LookupFailure` (used in `VerifyFailure::Lookup`)
### Changed ### Changed
- `halo2::plonk::create_proof` now takes an `R: rand::RngCore` argument.
- `halo2::plonk::Error` has been overhauled: - `halo2::plonk::Error` has been overhauled:
- `Error` now implements `std::fmt::Display` and `std::error::Error`. - `Error` now implements `std::fmt::Display` and `std::error::Error`.
- `Error` no longer implements `PartialEq`. Tests can check for specific error - `Error` no longer implements `PartialEq`. Tests can check for specific error

View File

@ -2,14 +2,18 @@
extern crate criterion; extern crate criterion;
extern crate halo2; extern crate halo2;
use crate::arithmetic::{small_multiexp, FieldExt}; use crate::arithmetic::small_multiexp;
use crate::pasta::{EqAffine, Fp}; use crate::pasta::{EqAffine, Fp};
use crate::poly::commitment::Params; use crate::poly::commitment::Params;
use group::ff::Field;
use halo2::*; use halo2::*;
use criterion::{black_box, Criterion}; use criterion::{black_box, Criterion};
use rand::rngs::OsRng;
fn criterion_benchmark(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) {
let rng = OsRng;
// small multiexp // small multiexp
{ {
let params: Params<EqAffine> = Params::new(5); let params: Params<EqAffine> = Params::new(5);
@ -17,8 +21,8 @@ fn criterion_benchmark(c: &mut Criterion) {
let len = g.len() / 2; let len = g.len() / 2;
let (g_lo, g_hi) = g.split_at_mut(len); let (g_lo, g_hi) = g.split_at_mut(len);
let coeff_1 = Fp::rand(); let coeff_1 = Fp::random(rng);
let coeff_2 = Fp::rand(); let coeff_2 = Fp::random(rng);
c.bench_function("double-and-add", |b| { c.bench_function("double-and-add", |b| {
b.iter(|| { b.iter(|| {

View File

@ -2,12 +2,14 @@
extern crate criterion; extern crate criterion;
extern crate halo2; extern crate halo2;
use group::ff::Field;
use halo2::arithmetic::FieldExt; use halo2::arithmetic::FieldExt;
use halo2::circuit::{Cell, Layouter, SimpleFloorPlanner}; use halo2::circuit::{Cell, Layouter, SimpleFloorPlanner};
use halo2::pasta::{EqAffine, Fp}; use halo2::pasta::{EqAffine, Fp};
use halo2::plonk::*; use halo2::plonk::*;
use halo2::poly::{commitment::Params, Rotation}; use halo2::poly::{commitment::Params, Rotation};
use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255}; use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255};
use rand::rngs::OsRng;
use std::marker::PhantomData; use std::marker::PhantomData;
@ -253,13 +255,15 @@ fn criterion_benchmark(c: &mut Criterion) {
} }
fn prover(k: u32, params: &Params<EqAffine>, pk: &ProvingKey<EqAffine>) -> Vec<u8> { fn prover(k: u32, params: &Params<EqAffine>, pk: &ProvingKey<EqAffine>) -> Vec<u8> {
let rng = OsRng;
let circuit: MyCircuit<Fp> = MyCircuit { let circuit: MyCircuit<Fp> = MyCircuit {
a: Some(Fp::rand()), a: Some(Fp::random(rng)),
k, k,
}; };
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
create_proof(params, pk, &[circuit], &[&[]], &mut transcript) create_proof(params, pk, &[circuit], &[&[]], rng, &mut transcript)
.expect("proof generation should not fail"); .expect("proof generation should not fail");
transcript.finalize() transcript.finalize()
} }

View File

@ -8,6 +8,7 @@ use halo2::{
poly::commitment::Params, poly::commitment::Params,
transcript::{Blake2bRead, Blake2bWrite, Challenge255}, transcript::{Blake2bRead, Blake2bWrite, Challenge255},
}; };
use rand::rngs::OsRng;
use std::{ use std::{
fs::File, fs::File,
@ -134,7 +135,7 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {
let proof_path = Path::new("./benches/sha256_assets/sha256_proof"); let proof_path = Path::new("./benches/sha256_assets/sha256_proof");
if File::open(&proof_path).is_err() { if File::open(&proof_path).is_err() {
let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
create_proof(&params, &pk, &[circuit], &[], &mut transcript) create_proof(&params, &pk, &[circuit], &[], OsRng, &mut transcript)
.expect("proof generation should not fail"); .expect("proof generation should not fail");
let proof: Vec<u8> = transcript.finalize(); let proof: Vec<u8> = transcript.finalize();
let mut file = File::create(&proof_path).expect("Failed to create sha256_proof"); let mut file = File::create(&proof_path).expect("Failed to create sha256_proof");

View File

@ -513,7 +513,9 @@ impl<F: FieldExt> Circuit<F> for MyCircuit<F> {
#[allow(clippy::many_single_char_names)] #[allow(clippy::many_single_char_names)]
fn main() { fn main() {
use group::ff::Field;
use halo2::{dev::MockProver, pasta::Fp}; use halo2::{dev::MockProver, pasta::Fp};
use rand::rngs::OsRng;
// ANCHOR: test-circuit // ANCHOR: test-circuit
// The number of rows in our circuit cannot exceed 2^k. Since our example // The number of rows in our circuit cannot exceed 2^k. Since our example
@ -521,9 +523,10 @@ fn main() {
let k = 4; let k = 4;
// Prepare the private and public inputs to the circuit! // Prepare the private and public inputs to the circuit!
let a = Fp::rand(); let rng = OsRng;
let b = Fp::rand(); let a = Fp::random(rng);
let c = Fp::rand(); let b = Fp::random(rng);
let c = Fp::random(rng);
let d = (a + b) * c; let d = (a + b) * c;
// Instantiate the circuit with the private inputs. // Instantiate the circuit with the private inputs.

View File

@ -402,13 +402,18 @@ pub fn lagrange_interpolate<F: FieldExt>(points: &[F], evals: &[F]) -> Vec<F> {
} }
} }
#[cfg(test)]
use rand::rngs::OsRng;
#[cfg(test)] #[cfg(test)]
use crate::pasta::Fp; use crate::pasta::Fp;
#[test] #[test]
fn test_lagrange_interpolate() { fn test_lagrange_interpolate() {
let points = (0..5).map(|_| Fp::rand()).collect::<Vec<_>>(); let rng = OsRng;
let evals = (0..5).map(|_| Fp::rand()).collect::<Vec<_>>();
let points = (0..5).map(|_| Fp::random(rng)).collect::<Vec<_>>();
let evals = (0..5).map(|_| Fp::random(rng)).collect::<Vec<_>>();
for coeffs in 0..5 { for coeffs in 0..5 {
let points = &points[0..coeffs]; let points = &points[0..coeffs];

View File

@ -16,6 +16,7 @@ use group::{
ff::{BatchInvert, Field}, ff::{BatchInvert, Field},
Curve, Curve,
}; };
use rand::RngCore;
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
iter, iter,
@ -73,6 +74,7 @@ impl<F: FieldExt> Argument<F> {
'a, 'a,
C, C,
E: EncodedChallenge<C>, E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>, T: TranscriptWrite<C, E>,
>( >(
&self, &self,
@ -86,6 +88,7 @@ impl<F: FieldExt> Argument<F> {
advice_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>], advice_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
fixed_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>], fixed_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
instance_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>], instance_cosets: &'a [Polynomial<C::Scalar, ExtendedLagrangeCoeff>],
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<Permuted<C>, Error> ) -> Result<Permuted<C>, Error>
where where
@ -173,14 +176,6 @@ impl<F: FieldExt> Argument<F> {
) )
}; };
// Closure to construct commitment to vector of values
let commit_values = |values: &Polynomial<C::Scalar, LagrangeCoeff>| {
let poly = pk.vk.domain.lagrange_to_coeff(values.clone());
let blind = Blind(C::Scalar::rand());
let commitment = params.commit_lagrange(values, blind).to_affine();
(poly, blind, commitment)
};
// Get values of input expressions involved in the lookup and compress them // Get values of input expressions involved in the lookup and compress them
let (unpermuted_input_expressions, unpermuted_input_cosets, compressed_input_expression) = let (unpermuted_input_expressions, unpermuted_input_cosets, compressed_input_expression) =
compress_expressions(&self.input_expressions); compress_expressions(&self.input_expressions);
@ -190,14 +185,23 @@ impl<F: FieldExt> Argument<F> {
compress_expressions(&self.table_expressions); compress_expressions(&self.table_expressions);
// Permute compressed (InputExpression, TableExpression) pair // Permute compressed (InputExpression, TableExpression) pair
let (permuted_input_expression, permuted_table_expression) = permute_expression_pair::<C>( let (permuted_input_expression, permuted_table_expression) = permute_expression_pair::<C, _>(
pk, pk,
params, params,
domain, domain,
&mut rng,
&compressed_input_expression, &compressed_input_expression,
&compressed_table_expression, &compressed_table_expression,
)?; )?;
// Closure to construct commitment to vector of values
let mut commit_values = |values: &Polynomial<C::Scalar, LagrangeCoeff>| {
let poly = pk.vk.domain.lagrange_to_coeff(values.clone());
let blind = Blind(C::Scalar::random(&mut rng));
let commitment = params.commit_lagrange(values, blind).to_affine();
(poly, blind, commitment)
};
// Commit to permuted input expression // Commit to permuted input expression
let (permuted_input_poly, permuted_input_blind, permuted_input_commitment) = let (permuted_input_poly, permuted_input_blind, permuted_input_commitment) =
commit_values(&permuted_input_expression); commit_values(&permuted_input_expression);
@ -238,13 +242,18 @@ impl<C: CurveAffine> Permuted<C> {
/// grand product polynomial over the lookup. The grand product polynomial /// grand product polynomial over the lookup. The grand product polynomial
/// is used to populate the Product<C> struct. The Product<C> struct is /// is used to populate the Product<C> struct. The Product<C> struct is
/// added to the Lookup and finally returned by the method. /// added to the Lookup and finally returned by the method.
pub(in crate::plonk) fn commit_product<E: EncodedChallenge<C>, T: TranscriptWrite<C, E>>( pub(in crate::plonk) fn commit_product<
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
>(
self, self,
pk: &ProvingKey<C>, pk: &ProvingKey<C>,
params: &Params<C>, params: &Params<C>,
theta: ChallengeTheta<C>, theta: ChallengeTheta<C>,
beta: ChallengeBeta<C>, beta: ChallengeBeta<C>,
gamma: ChallengeGamma<C>, gamma: ChallengeGamma<C>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<Committed<C>, Error> { ) -> Result<Committed<C>, Error> {
let blinding_factors = pk.vk.cs.blinding_factors(); let blinding_factors = pk.vk.cs.blinding_factors();
@ -326,7 +335,7 @@ impl<C: CurveAffine> Permuted<C> {
// be a boolean (and ideally 1, else soundness is broken) // be a boolean (and ideally 1, else soundness is broken)
.take(params.n as usize - blinding_factors) .take(params.n as usize - blinding_factors)
// Chain random blinding factors. // Chain random blinding factors.
.chain((0..blinding_factors).map(|_| C::Scalar::rand())) .chain((0..blinding_factors).map(|_| C::Scalar::random(&mut rng)))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!(z.len(), params.n as usize); assert_eq!(z.len(), params.n as usize);
let z = pk.vk.domain.lagrange_from_vec(z); let z = pk.vk.domain.lagrange_from_vec(z);
@ -376,7 +385,7 @@ impl<C: CurveAffine> Permuted<C> {
assert_eq!(z[u], C::Scalar::one()); assert_eq!(z[u], C::Scalar::one());
} }
let product_blind = Blind(C::Scalar::rand()); let product_blind = Blind(C::Scalar::random(rng));
let product_commitment = params.commit_lagrange(&z, product_blind).to_affine(); let product_commitment = params.commit_lagrange(&z, product_blind).to_affine();
let z = pk.vk.domain.lagrange_to_coeff(z); let z = pk.vk.domain.lagrange_to_coeff(z);
let product_coset = pk.vk.domain.coeff_to_extended(z.clone()); let product_coset = pk.vk.domain.coeff_to_extended(z.clone());
@ -587,10 +596,11 @@ type ExpressionPair<F> = (Polynomial<F, LagrangeCoeff>, Polynomial<F, LagrangeCo
/// - the first row in a sequence of like values in A' is the row /// - the first row in a sequence of like values in A' is the row
/// that has the corresponding value in S'. /// that has the corresponding value in S'.
/// This method returns (A', S') if no errors are encountered. /// This method returns (A', S') if no errors are encountered.
fn permute_expression_pair<C: CurveAffine>( fn permute_expression_pair<C: CurveAffine, R: RngCore>(
pk: &ProvingKey<C>, pk: &ProvingKey<C>,
params: &Params<C>, params: &Params<C>,
domain: &EvaluationDomain<C::Scalar>, domain: &EvaluationDomain<C::Scalar>,
mut rng: R,
input_expression: &Polynomial<C::Scalar, LagrangeCoeff>, input_expression: &Polynomial<C::Scalar, LagrangeCoeff>,
table_expression: &Polynomial<C::Scalar, LagrangeCoeff>, table_expression: &Polynomial<C::Scalar, LagrangeCoeff>,
) -> Result<ExpressionPair<C::Scalar>, Error> { ) -> Result<ExpressionPair<C::Scalar>, Error> {
@ -645,8 +655,9 @@ fn permute_expression_pair<C: CurveAffine>(
} }
assert!(repeated_input_rows.is_empty()); assert!(repeated_input_rows.is_empty());
permuted_input_expression.extend((0..(blinding_factors + 1)).map(|_| C::Scalar::rand())); permuted_input_expression
permuted_table_coeffs.extend((0..(blinding_factors + 1)).map(|_| C::Scalar::rand())); .extend((0..(blinding_factors + 1)).map(|_| C::Scalar::random(&mut rng)));
permuted_table_coeffs.extend((0..(blinding_factors + 1)).map(|_| C::Scalar::random(&mut rng)));
assert_eq!(permuted_input_expression.len(), params.n as usize); assert_eq!(permuted_input_expression.len(), params.n as usize);
assert_eq!(permuted_table_coeffs.len(), params.n as usize); assert_eq!(permuted_table_coeffs.len(), params.n as usize);

View File

@ -2,6 +2,7 @@ use group::{
ff::{BatchInvert, Field}, ff::{BatchInvert, Field},
Curve, Curve,
}; };
use rand::RngCore;
use std::iter::{self, ExactSizeIterator}; use std::iter::{self, ExactSizeIterator};
use super::super::{circuit::Any, ChallengeBeta, ChallengeGamma, ChallengeX}; use super::super::{circuit::Any, ChallengeBeta, ChallengeGamma, ChallengeX};
@ -44,6 +45,7 @@ impl Argument {
pub(in crate::plonk) fn commit< pub(in crate::plonk) fn commit<
C: CurveAffine, C: CurveAffine,
E: EncodedChallenge<C>, E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>, T: TranscriptWrite<C, E>,
>( >(
&self, &self,
@ -55,6 +57,7 @@ impl Argument {
instance: &[Polynomial<C::Scalar, LagrangeCoeff>], instance: &[Polynomial<C::Scalar, LagrangeCoeff>],
beta: ChallengeBeta<C>, beta: ChallengeBeta<C>,
gamma: ChallengeGamma<C>, gamma: ChallengeGamma<C>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<Committed<C>, Error> { ) -> Result<Committed<C>, Error> {
let domain = &pk.vk.domain; let domain = &pk.vk.domain;
@ -155,12 +158,12 @@ impl Argument {
let mut z = domain.lagrange_from_vec(z); let mut z = domain.lagrange_from_vec(z);
// Set blinding factors // Set blinding factors
for z in &mut z[params.n as usize - blinding_factors..] { for z in &mut z[params.n as usize - blinding_factors..] {
*z = C::Scalar::rand(); *z = C::Scalar::random(&mut rng);
} }
// Set new last_z // Set new last_z
last_z = z[params.n as usize - (blinding_factors + 1)]; last_z = z[params.n as usize - (blinding_factors + 1)];
let blind = Blind(C::Scalar::rand()); let blind = Blind(C::Scalar::random(&mut rng));
let permutation_product_commitment_projective = params.commit_lagrange(&z, blind); let permutation_product_commitment_projective = params.commit_lagrange(&z, blind);
let permutation_product_blind = blind; let permutation_product_blind = blind;

View File

@ -1,5 +1,6 @@
use ff::Field; use ff::Field;
use group::Curve; use group::Curve;
use rand::{rngs::OsRng, RngCore};
use std::iter; use std::iter;
use std::ops::RangeTo; use std::ops::RangeTo;
@ -32,6 +33,7 @@ use crate::{
pub fn create_proof< pub fn create_proof<
C: CurveAffine, C: CurveAffine,
E: EncodedChallenge<C>, E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>, T: TranscriptWrite<C, E>,
ConcreteCircuit: Circuit<C::Scalar>, ConcreteCircuit: Circuit<C::Scalar>,
>( >(
@ -39,6 +41,7 @@ pub fn create_proof<
pk: &ProvingKey<C>, pk: &ProvingKey<C>,
circuits: &[ConcreteCircuit], circuits: &[ConcreteCircuit],
instances: &[&[&[C::Scalar]]], instances: &[&[&[C::Scalar]]],
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<(), Error> { ) -> Result<(), Error> {
for instance in instances.iter() { for instance in instances.iter() {
@ -284,12 +287,15 @@ pub fn create_proof<
// Add blinding factors to advice columns // Add blinding factors to advice columns
for advice in &mut advice { for advice in &mut advice {
for cell in &mut advice[unusable_rows_start..] { for cell in &mut advice[unusable_rows_start..] {
*cell = C::Scalar::rand(); *cell = C::Scalar::random(&mut rng);
} }
} }
// Compute commitments to advice column polynomials // Compute commitments to advice column polynomials
let advice_blinds: Vec<_> = advice.iter().map(|_| Blind(C::Scalar::rand())).collect(); let advice_blinds: Vec<_> = advice
.iter()
.map(|_| Blind(C::Scalar::random(&mut rng)))
.collect();
let advice_commitments_projective: Vec<_> = advice let advice_commitments_projective: Vec<_> = advice
.iter() .iter()
.zip(advice_blinds.iter()) .zip(advice_blinds.iter())
@ -348,6 +354,7 @@ pub fn create_proof<
&advice.advice_cosets, &advice.advice_cosets,
&pk.fixed_cosets, &pk.fixed_cosets,
&instance.instance_cosets, &instance.instance_cosets,
&mut rng,
transcript, transcript,
) )
}) })
@ -375,6 +382,7 @@ pub fn create_proof<
&instance.instance_values, &instance.instance_values,
beta, beta,
gamma, gamma,
&mut rng,
transcript, transcript,
) )
}) })
@ -386,13 +394,15 @@ pub fn create_proof<
// Construct and commit to products for each lookup // Construct and commit to products for each lookup
lookups lookups
.into_iter() .into_iter()
.map(|lookup| lookup.commit_product(pk, params, theta, beta, gamma, transcript)) .map(|lookup| {
lookup.commit_product(pk, params, theta, beta, gamma, &mut rng, transcript)
})
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()
}) })
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
// Commit to the vanishing argument's random polynomial for blinding h(x_3) // Commit to the vanishing argument's random polynomial for blinding h(x_3)
let vanishing = vanishing::Argument::commit(params, domain, transcript)?; let vanishing = vanishing::Argument::commit(params, domain, &mut rng, transcript)?;
// Obtain challenge for keeping all separate gates linearly independent // Obtain challenge for keeping all separate gates linearly independent
let y: ChallengeY<_> = transcript.squeeze_challenge_scalar(); let y: ChallengeY<_> = transcript.squeeze_challenge_scalar();
@ -473,7 +483,7 @@ pub fn create_proof<
); );
// Construct the vanishing argument's h(X) commitments // Construct the vanishing argument's h(X) commitments
let vanishing = vanishing.construct(params, domain, expressions, y, transcript)?; let vanishing = vanishing.construct(params, domain, expressions, y, &mut rng, transcript)?;
let x: ChallengeX<_> = transcript.squeeze_challenge_scalar(); let x: ChallengeX<_> = transcript.squeeze_challenge_scalar();
let xn = x.pow(&[params.n as u64, 0, 0, 0]); let xn = x.pow(&[params.n as u64, 0, 0, 0]);
@ -601,5 +611,5 @@ pub fn create_proof<
// We query the h(X) polynomial at x // We query the h(X) polynomial at x
.chain(vanishing.open(x)); .chain(vanishing.open(x));
multiopen::create_proof(params, transcript, instances).map_err(|_| Error::Opening) multiopen::create_proof(params, rng, transcript, instances).map_err(|_| Error::Opening)
} }

View File

@ -2,6 +2,7 @@ use std::iter;
use ff::Field; use ff::Field;
use group::Curve; use group::Curve;
use rand::RngCore;
use super::Argument; use super::Argument;
use crate::{ use crate::{
@ -33,18 +34,19 @@ pub(in crate::plonk) struct Evaluated<C: CurveAffine> {
} }
impl<C: CurveAffine> Argument<C> { impl<C: CurveAffine> Argument<C> {
pub(in crate::plonk) fn commit<E: EncodedChallenge<C>, T: TranscriptWrite<C, E>>( pub(in crate::plonk) fn commit<E: EncodedChallenge<C>, R: RngCore, T: TranscriptWrite<C, E>>(
params: &Params<C>, params: &Params<C>,
domain: &EvaluationDomain<C::Scalar>, domain: &EvaluationDomain<C::Scalar>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<Committed<C>, Error> { ) -> Result<Committed<C>, Error> {
// Sample a random polynomial of degree n - 1 // Sample a random polynomial of degree n - 1
let mut random_poly = domain.empty_coeff(); let mut random_poly = domain.empty_coeff();
for coeff in random_poly.iter_mut() { for coeff in random_poly.iter_mut() {
*coeff = C::Scalar::rand(); *coeff = C::Scalar::random(&mut rng);
} }
// Sample a random blinding factor // Sample a random blinding factor
let random_blind = Blind(C::Scalar::rand()); let random_blind = Blind(C::Scalar::random(rng));
// Commit // Commit
let c = params.commit(&random_poly, random_blind).to_affine(); let c = params.commit(&random_poly, random_blind).to_affine();
@ -58,12 +60,17 @@ impl<C: CurveAffine> Argument<C> {
} }
impl<C: CurveAffine> Committed<C> { impl<C: CurveAffine> Committed<C> {
pub(in crate::plonk) fn construct<E: EncodedChallenge<C>, T: TranscriptWrite<C, E>>( pub(in crate::plonk) fn construct<
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
>(
self, self,
params: &Params<C>, params: &Params<C>,
domain: &EvaluationDomain<C::Scalar>, domain: &EvaluationDomain<C::Scalar>,
expressions: impl Iterator<Item = Polynomial<C::Scalar, ExtendedLagrangeCoeff>>, expressions: impl Iterator<Item = Polynomial<C::Scalar, ExtendedLagrangeCoeff>>,
y: ChallengeY<C>, y: ChallengeY<C>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
) -> Result<Constructed<C>, Error> { ) -> Result<Constructed<C>, Error> {
// Evaluate the h(X) polynomial's constraint system expressions for the constraints provided // Evaluate the h(X) polynomial's constraint system expressions for the constraints provided
@ -81,7 +88,10 @@ impl<C: CurveAffine> Committed<C> {
.map(|v| domain.coeff_from_vec(v.to_vec())) .map(|v| domain.coeff_from_vec(v.to_vec()))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
drop(h_poly); drop(h_poly);
let h_blinds: Vec<_> = h_pieces.iter().map(|_| Blind(C::Scalar::rand())).collect(); let h_blinds: Vec<_> = h_pieces
.iter()
.map(|_| Blind(C::Scalar::random(&mut rng)))
.collect();
// Compute commitments to each h(X) piece // Compute commitments to each h(X) piece
let h_commitments_projective: Vec<_> = h_pieces let h_commitments_projective: Vec<_> = h_pieces

View File

@ -256,6 +256,8 @@ impl<F: FieldExt> MulAssign<F> for Blind<F> {
fn test_commit_lagrange_epaffine() { fn test_commit_lagrange_epaffine() {
const K: u32 = 6; const K: u32 = 6;
use rand::rngs::OsRng;
use crate::pasta::{EpAffine, Fq}; use crate::pasta::{EpAffine, Fq};
let params = Params::<EpAffine>::new(K); let params = Params::<EpAffine>::new(K);
let domain = super::EvaluationDomain::new(1, K); let domain = super::EvaluationDomain::new(1, K);
@ -268,7 +270,7 @@ fn test_commit_lagrange_epaffine() {
let b = domain.lagrange_to_coeff(a.clone()); let b = domain.lagrange_to_coeff(a.clone());
let alpha = Blind(Fq::rand()); let alpha = Blind(Fq::random(OsRng));
assert_eq!(params.commit(&b, alpha), params.commit_lagrange(&a, alpha)); assert_eq!(params.commit(&b, alpha), params.commit_lagrange(&a, alpha));
} }
@ -277,6 +279,8 @@ fn test_commit_lagrange_epaffine() {
fn test_commit_lagrange_eqaffine() { fn test_commit_lagrange_eqaffine() {
const K: u32 = 6; const K: u32 = 6;
use rand::rngs::OsRng;
use crate::pasta::{EqAffine, Fp}; use crate::pasta::{EqAffine, Fp};
let params = Params::<EqAffine>::new(K); let params = Params::<EqAffine>::new(K);
let domain = super::EvaluationDomain::new(1, K); let domain = super::EvaluationDomain::new(1, K);
@ -289,7 +293,7 @@ fn test_commit_lagrange_eqaffine() {
let b = domain.lagrange_to_coeff(a.clone()); let b = domain.lagrange_to_coeff(a.clone());
let alpha = Blind(Fp::rand()); let alpha = Blind(Fp::random(OsRng));
assert_eq!(params.commit(&b, alpha), params.commit_lagrange(&a, alpha)); assert_eq!(params.commit(&b, alpha), params.commit_lagrange(&a, alpha));
} }
@ -299,6 +303,7 @@ fn test_opening_proof() {
const K: u32 = 6; const K: u32 = 6;
use ff::Field; use ff::Field;
use rand::rngs::OsRng;
use super::{ use super::{
commitment::{Blind, Params}, commitment::{Blind, Params},
@ -310,6 +315,8 @@ fn test_opening_proof() {
Blake2bRead, Blake2bWrite, Challenge255, Transcript, TranscriptRead, TranscriptWrite, Blake2bRead, Blake2bWrite, Challenge255, Transcript, TranscriptRead, TranscriptWrite,
}; };
let rng = OsRng;
let params = Params::<EpAffine>::new(K); let params = Params::<EpAffine>::new(K);
let mut params_buffer = vec![]; let mut params_buffer = vec![];
params.write(&mut params_buffer).unwrap(); params.write(&mut params_buffer).unwrap();
@ -323,7 +330,7 @@ fn test_opening_proof() {
*a = Fq::from(i as u64); *a = Fq::from(i as u64);
} }
let blind = Blind(Fq::rand()); let blind = Blind(Fq::random(rng));
let p = params.commit(&px, blind).to_affine(); let p = params.commit(&px, blind).to_affine();
@ -335,7 +342,7 @@ fn test_opening_proof() {
transcript.write_scalar(v).unwrap(); transcript.write_scalar(v).unwrap();
let (proof, ch_prover) = { let (proof, ch_prover) = {
create_proof(&params, &mut transcript, &px, blind, *x).unwrap(); create_proof(&params, rng, &mut transcript, &px, blind, *x).unwrap();
let ch_prover = transcript.squeeze_challenge(); let ch_prover = transcript.squeeze_challenge();
(transcript.finalize(), ch_prover) (transcript.finalize(), ch_prover)
}; };

View File

@ -1,4 +1,5 @@
use ff::Field; use ff::Field;
use rand::RngCore;
use super::super::{Coeff, Polynomial}; use super::super::{Coeff, Polynomial};
use super::{Blind, Params}; use super::{Blind, Params};
@ -23,8 +24,14 @@ use std::io;
/// opening v, and the point x. It's probably also nice for the transcript /// opening v, and the point x. It's probably also nice for the transcript
/// to have seen the elliptic curve description and the URS, if you want to /// to have seen the elliptic curve description and the URS, if you want to
/// be rigorous. /// be rigorous.
pub fn create_proof<C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptWrite<C, E>>( pub fn create_proof<
C: CurveAffine,
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
>(
params: &Params<C>, params: &Params<C>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
px: &Polynomial<C::Scalar, Coeff>, px: &Polynomial<C::Scalar, Coeff>,
blind: Blind<C::Scalar>, blind: Blind<C::Scalar>,
@ -37,14 +44,14 @@ pub fn create_proof<C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptWrite<C
// by setting all coefficients to random values. // by setting all coefficients to random values.
let mut s_poly = (*px).clone(); let mut s_poly = (*px).clone();
for coeff in s_poly.iter_mut() { for coeff in s_poly.iter_mut() {
*coeff = C::Scalar::rand(); *coeff = C::Scalar::random(&mut rng);
} }
// Evaluate the random polynomial at x // Evaluate the random polynomial at x
let v_prime = eval_polynomial(&s_poly[..], x); let v_prime = eval_polynomial(&s_poly[..], x);
// Subtract constant coefficient to get a random polynomial with a root at x // Subtract constant coefficient to get a random polynomial with a root at x
s_poly[0] = s_poly[0] - &v_prime; s_poly[0] = s_poly[0] - &v_prime;
// And sample a random blind // And sample a random blind
let s_poly_blind = Blind(C::Scalar::rand()); let s_poly_blind = Blind(C::Scalar::random(&mut rng));
// Write a commitment to the random polynomial to the transcript // Write a commitment to the random polynomial to the transcript
let s_poly_commitment = params.commit(&s_poly, s_poly_blind).to_affine(); let s_poly_commitment = params.commit(&s_poly, s_poly_blind).to_affine();
@ -99,8 +106,8 @@ pub fn create_proof<C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptWrite<C
let r = best_multiexp(&a[0..half], &g[half..]); let r = best_multiexp(&a[0..half], &g[half..]);
let value_l = compute_inner_product(&a[half..], &b[0..half]); let value_l = compute_inner_product(&a[half..], &b[0..half]);
let value_r = compute_inner_product(&a[0..half], &b[half..]); let value_r = compute_inner_product(&a[0..half], &b[half..]);
let l_randomness = C::Scalar::rand(); let l_randomness = C::Scalar::random(&mut rng);
let r_randomness = C::Scalar::rand(); let r_randomness = C::Scalar::random(&mut rng);
let l = l + &best_multiexp(&[value_l * &z, l_randomness], &[params.u, params.h]); let l = l + &best_multiexp(&[value_l * &z, l_randomness], &[params.u, params.h]);
let r = r + &best_multiexp(&[value_r * &z, r_randomness], &[params.u, params.h]); let r = r + &best_multiexp(&[value_r * &z, r_randomness], &[params.u, params.h]);
let l = l.to_affine(); let l = l.to_affine();

View File

@ -554,14 +554,18 @@ pub struct PinnedEvaluationDomain<'a, G: Group> {
#[test] #[test]
fn test_rotate() { fn test_rotate() {
use rand::rngs::OsRng;
use crate::arithmetic::eval_polynomial; use crate::arithmetic::eval_polynomial;
use crate::pasta::pallas::Scalar; use crate::pasta::pallas::Scalar;
let domain = EvaluationDomain::<Scalar>::new(1, 3); let domain = EvaluationDomain::<Scalar>::new(1, 3);
let rng = OsRng;
let mut poly = domain.empty_lagrange(); let mut poly = domain.empty_lagrange();
assert_eq!(poly.len(), 8); assert_eq!(poly.len(), 8);
for value in poly.iter_mut() { for value in poly.iter_mut() {
*value = Scalar::rand(); *value = Scalar::random(rng);
} }
let poly_rotated_cur = poly.rotate(Rotation::cur()); let poly_rotated_cur = poly.rotate(Rotation::cur());
@ -573,7 +577,7 @@ fn test_rotate() {
let poly_rotated_next = domain.lagrange_to_coeff(poly_rotated_next); let poly_rotated_next = domain.lagrange_to_coeff(poly_rotated_next);
let poly_rotated_prev = domain.lagrange_to_coeff(poly_rotated_prev); let poly_rotated_prev = domain.lagrange_to_coeff(poly_rotated_prev);
let x = Scalar::rand(); let x = Scalar::random(rng);
assert_eq!( assert_eq!(
eval_polynomial(&poly[..], x), eval_polynomial(&poly[..], x),
@ -591,6 +595,8 @@ fn test_rotate() {
#[test] #[test]
fn test_l_i() { fn test_l_i() {
use rand::rngs::OsRng;
use crate::arithmetic::{eval_polynomial, lagrange_interpolate}; use crate::arithmetic::{eval_polynomial, lagrange_interpolate};
use crate::pasta::pallas::Scalar; use crate::pasta::pallas::Scalar;
let domain = EvaluationDomain::<Scalar>::new(1, 3); let domain = EvaluationDomain::<Scalar>::new(1, 3);
@ -607,7 +613,7 @@ fn test_l_i() {
l.push(l_i); l.push(l_i);
} }
let x = Scalar::rand(); let x = Scalar::random(OsRng);
let xn = x.pow(&[8, 0, 0, 0]); let xn = x.pow(&[8, 0, 0, 0]);
let evaluations = domain.l_i_range(x, xn, -7..=7); let evaluations = domain.l_i_range(x, xn, -7..=7);

View File

@ -250,6 +250,7 @@ where
#[test] #[test]
fn test_roundtrip() { fn test_roundtrip() {
use group::Curve; use group::Curve;
use rand::rngs::OsRng;
use super::commitment::{Blind, Params}; use super::commitment::{Blind, Params};
use crate::arithmetic::{eval_polynomial, FieldExt}; use crate::arithmetic::{eval_polynomial, FieldExt};
@ -260,6 +261,7 @@ fn test_roundtrip() {
let params: Params<EqAffine> = Params::new(K); let params: Params<EqAffine> = Params::new(K);
let domain = EvaluationDomain::new(1, K); let domain = EvaluationDomain::new(1, K);
let rng = OsRng;
let mut ax = domain.empty_coeff(); let mut ax = domain.empty_coeff();
for (i, a) in ax.iter_mut().enumerate() { for (i, a) in ax.iter_mut().enumerate() {
@ -276,14 +278,14 @@ fn test_roundtrip() {
*a = Fp::from(100 + i as u64); *a = Fp::from(100 + i as u64);
} }
let blind = Blind(Fp::rand()); let blind = Blind(Fp::random(rng));
let a = params.commit(&ax, blind).to_affine(); let a = params.commit(&ax, blind).to_affine();
let b = params.commit(&bx, blind).to_affine(); let b = params.commit(&bx, blind).to_affine();
let c = params.commit(&cx, blind).to_affine(); let c = params.commit(&cx, blind).to_affine();
let x = Fp::rand(); let x = Fp::random(rng);
let y = Fp::rand(); let y = Fp::random(rng);
let avx = eval_polynomial(&ax, x); let avx = eval_polynomial(&ax, x);
let bvx = eval_polynomial(&bx, x); let bvx = eval_polynomial(&bx, x);
let cvy = eval_polynomial(&cx, y); let cvy = eval_polynomial(&cx, y);
@ -291,6 +293,7 @@ fn test_roundtrip() {
let mut transcript = crate::transcript::Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]); let mut transcript = crate::transcript::Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
create_proof( create_proof(
&params, &params,
rng,
&mut transcript, &mut transcript,
std::iter::empty() std::iter::empty()
.chain(Some(ProverQuery { .chain(Some(ProverQuery {

View File

@ -12,12 +12,21 @@ use crate::transcript::{EncodedChallenge, TranscriptWrite};
use ff::Field; use ff::Field;
use group::Curve; use group::Curve;
use rand::RngCore;
use std::io; use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
/// Create a multi-opening proof /// Create a multi-opening proof
pub fn create_proof<'a, I, C: CurveAffine, E: EncodedChallenge<C>, T: TranscriptWrite<C, E>>( pub fn create_proof<
'a,
I,
C: CurveAffine,
E: EncodedChallenge<C>,
R: RngCore,
T: TranscriptWrite<C, E>,
>(
params: &Params<C>, params: &Params<C>,
mut rng: R,
transcript: &mut T, transcript: &mut T,
queries: I, queries: I,
) -> io::Result<()> ) -> io::Result<()>
@ -78,7 +87,7 @@ where
}) })
.unwrap(); .unwrap();
let f_blind = Blind(C::Scalar::rand()); let f_blind = Blind(C::Scalar::random(&mut rng));
let f_commitment = params.commit(&f_poly, f_blind).to_affine(); let f_commitment = params.commit(&f_poly, f_blind).to_affine();
transcript.write_point(f_commitment)?; transcript.write_point(f_commitment)?;
@ -106,7 +115,7 @@ where
}, },
); );
commitment::create_proof(params, transcript, &f_poly, f_blind_try, *x_3) commitment::create_proof(params, rng, transcript, &f_poly, f_blind_try, *x_3)
} }
#[doc(hidden)] #[doc(hidden)]

View File

@ -1,4 +1,5 @@
use ff::Field; use ff::Field;
use rand::rngs::OsRng;
use super::super::{ use super::super::{
commitment::{Guard, Params, MSM}, commitment::{Guard, Params, MSM},
@ -31,7 +32,7 @@ where
// Scale the MSM by a random factor to ensure that if the existing MSM // Scale the MSM by a random factor to ensure that if the existing MSM
// has is_zero() == false then this argument won't be able to interfere // has is_zero() == false then this argument won't be able to interfere
// with it to make it true, with high probability. // with it to make it true, with high probability.
msm.scale(C::Scalar::rand()); msm.scale(C::Scalar::random(OsRng));
// Sample x_1 for compressing openings at the same point sets together // Sample x_1 for compressing openings at the same point sets together
let x_1: ChallengeX1<_> = transcript.squeeze_challenge_scalar(); let x_1: ChallengeX1<_> = transcript.squeeze_challenge_scalar();

View File

@ -12,6 +12,7 @@ use halo2::plonk::{
}; };
use halo2::poly::{commitment::Params, Rotation}; use halo2::poly::{commitment::Params, Rotation};
use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255}; use halo2::transcript::{Blake2bRead, Blake2bWrite, Challenge255};
use rand::rngs::OsRng;
use std::marker::PhantomData; use std::marker::PhantomData;
#[test] #[test]
@ -436,6 +437,7 @@ fn plonk_api() {
&pk, &pk,
&[circuit.clone(), circuit.clone()], &[circuit.clone(), circuit.clone()],
&[&[&[instance]], &[&[instance]]], &[&[&[instance]], &[&[instance]]],
OsRng,
&mut transcript, &mut transcript,
) )
.expect("proof generation should not fail"); .expect("proof generation should not fail");