diff --git a/Cargo.toml b/Cargo.toml index 27de33d..792b2f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ metrics = "=0.13.0-alpha.13" metrics-macros = "=0.1.0-alpha.9" num_cpus = "1.13" rand = "0.7" +blake2b_simd = "0.5" [features] sanity-checks = [] diff --git a/benches/arithmetic.rs b/benches/arithmetic.rs index 67d51a6..ec13c74 100644 --- a/benches/arithmetic.rs +++ b/benches/arithmetic.rs @@ -5,7 +5,6 @@ extern crate halo2; use crate::arithmetic::{small_multiexp, FieldExt}; use crate::pasta::{EqAffine, Fp}; use crate::poly::commitment::Params; -use crate::transcript::DummyHashWrite; use halo2::*; use criterion::{black_box, Criterion}; @@ -13,7 +12,7 @@ use criterion::{black_box, Criterion}; fn criterion_benchmark(c: &mut Criterion) { // small multiexp { - let params: Params = Params::new::>(5); + let params: Params = Params::new(5); let g = &mut params.get_g(); let len = g.len() / 2; let (g_lo, g_hi) = g.split_at_mut(len); diff --git a/benches/plonk.rs b/benches/plonk.rs index 33c0533..6712db2 100644 --- a/benches/plonk.rs +++ b/benches/plonk.rs @@ -18,7 +18,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) { pub struct Variable(Column, usize); // Initialize the polynomial commitment parameters - let params: Params = Params::new::>(k); + let params: Params = Params::new(k); struct PLONKConfig { a: Column, diff --git a/examples/performance_model.rs b/examples/performance_model.rs index 2d382cc..2408899 100644 --- a/examples/performance_model.rs +++ b/examples/performance_model.rs @@ -7,7 +7,6 @@ use halo2::{ transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite}, }; -use std::io; use std::marker::PhantomData; /// This represents an advice column at a certain row in the ConstraintSystem @@ -250,7 +249,7 @@ fn main() { let k = 11; // Initialize the polynomial commitment parameters - let params: Params = Params::new::>(k); + let params: Params = Params::new(k); let empty_circuit: MyCircuit = MyCircuit { a: None, k }; diff --git a/src/arithmetic/curves.rs b/src/arithmetic/curves.rs index 3d6befb..6210031 100644 --- a/src/arithmetic/curves.rs +++ b/src/arithmetic/curves.rs @@ -122,6 +122,10 @@ pub trait CurveAffine: /// The base field over which this elliptic curve is constructed. type Base: FieldExt; + /// Personalization of BLAKE2b hasher used to generate the uniform + /// random string. + const BLAKE2B_PERSONALIZATION: &'static [u8; 16]; + /// Obtains the additive identity. fn zero() -> Self; diff --git a/src/pasta/curves.rs b/src/pasta/curves.rs index 8d5ad8a..01ef683 100644 --- a/src/pasta/curves.rs +++ b/src/pasta/curves.rs @@ -11,7 +11,7 @@ use super::{Fp, Fq}; use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group}; macro_rules! new_curve_impl { - ($name:ident, $name_affine:ident, $base:ident, $scalar:ident) => { + ($name:ident, $name_affine:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal) => { /// Represents a point in the projective coordinate space. #[derive(Copy, Clone, Debug)] pub struct $name { @@ -497,6 +497,8 @@ macro_rules! new_curve_impl { type Scalar = $scalar; type Base = $base; + const BLAKE2B_PERSONALIZATION: &'static [u8; 16] = $blake2b_personalization; + fn zero() -> Self { Self { x: $base::zero(), @@ -700,5 +702,5 @@ macro_rules! new_curve_impl { }; } -new_curve_impl!(Ep, EpAffine, Fp, Fq); -new_curve_impl!(Eq, EqAffine, Fq, Fp); +new_curve_impl!(Ep, EpAffine, Fp, Fq, b"halo2_____pallas"); +new_curve_impl!(Eq, EqAffine, Fq, Fp, b"halo2______vesta"); diff --git a/src/plonk.rs b/src/plonk.rs index 56825ca..222471e 100644 --- a/src/plonk.rs +++ b/src/plonk.rs @@ -107,7 +107,6 @@ fn test_proving() { use crate::poly::commitment::{Blind, Params}; use crate::transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite}; use circuit::{Advice, Column, Fixed}; - use std::io; use std::marker::PhantomData; const K: u32 = 5; @@ -116,7 +115,7 @@ fn test_proving() { pub struct Variable(Column, usize); // Initialize the polynomial commitment parameters - let params: Params = Params::new::>(K); + let params: Params = Params::new(K); struct PLONKConfig { a: Column, diff --git a/src/poly/commitment.rs b/src/poly/commitment.rs index 9e19369..25a5849 100644 --- a/src/poly/commitment.rs +++ b/src/poly/commitment.rs @@ -3,12 +3,12 @@ //! //! [halo]: https://eprint.iacr.org/2019/1021 +use blake2b_simd::{Params as Blake2bParams, State as Blake2bState}; + use super::{Coeff, LagrangeCoeff, Polynomial}; use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, FieldExt}; -use crate::transcript::{Transcript, TranscriptWrite}; use ff::{Field, PrimeField}; -use std::io; use std::ops::{Add, AddAssign, Mul, MulAssign}; mod msm; @@ -33,7 +33,7 @@ pub struct Params { impl Params { /// Initializes parameters for the curve, given a random oracle to draw /// points from. - pub fn new + Sync>(k: u32) -> Self { + pub fn new(k: u32) -> Self { // This is usually a limitation on the curve, but we also want 32-bit // architectures to be supported. assert!(k < 32); @@ -42,27 +42,38 @@ impl Params { let n: u64 = 1 << k; - let g = { - let hasher = &T::init(io::sink(), C::Base::one()); + let try_and_increment = |hasher: &Blake2bState| { + let mut trial = 0u64; + loop { + let mut hasher = hasher.clone(); + hasher.update(&(trial.to_le_bytes())[..]); + let mut hash = [0u8; 32]; + hash[..].copy_from_slice(hasher.finalize().as_bytes()); + let p = C::from_bytes(&hash); + if bool::from(p.is_some()) { + break p.unwrap(); + } + trial += 1; + } + }; + let g = { let mut g = Vec::with_capacity(n as usize); g.resize(n as usize, C::zero()); parallelize(&mut g, move |g, start| { - let mut cur_value = C::Scalar::from(start as u64); - for g in g.iter_mut() { - let mut hasher = hasher.fork(); - hasher.write_scalar(cur_value).unwrap(); - cur_value += &C::Scalar::one(); - loop { - let x: C::Base = hasher.squeeze_challenge(); - let x = x.to_bytes(); - let p = C::from_bytes(&x); - if bool::from(p.is_some()) { - *g = p.unwrap(); - break; - } - } + let mut hasher = Blake2bParams::new() + .hash_length(32) + .personal(C::BLAKE2B_PERSONALIZATION) + .to_state(); + hasher.update(b"G vector"); + + for (i, g) in g.iter_mut().enumerate() { + let i = (i + start) as u64; + let mut hasher = hasher.clone(); + hasher.update(&(i.to_le_bytes())[..]); + + *g = try_and_increment(&hasher); } }); @@ -97,17 +108,23 @@ impl Params { }; let h = { - let mut hasher = T::init(io::sink(), C::Base::from_u64(2)); - let x = hasher.squeeze_challenge().to_bytes(); - let p = C::from_bytes(&x); - p.unwrap() + let mut hasher = Blake2bParams::new() + .hash_length(32) + .personal(C::BLAKE2B_PERSONALIZATION) + .to_state(); + hasher.update(b"H"); + + try_and_increment(&hasher) }; let u = { - let mut hasher = T::init(io::sink(), C::Base::from_u64(3)); - let x = hasher.squeeze_challenge().to_bytes(); - let p = C::from_bytes(&x); - p.unwrap() + let mut hasher = Blake2bParams::new() + .hash_length(32) + .personal(C::BLAKE2B_PERSONALIZATION) + .to_state(); + hasher.update(b"U"); + + try_and_increment(&hasher) }; Params { @@ -229,8 +246,7 @@ fn test_commit_lagrange_epaffine() { const K: u32 = 6; use crate::pasta::{EpAffine, Fq}; - use crate::transcript::DummyHashWrite; - let params = Params::::new::>(K); + let params = Params::::new(K); let domain = super::EvaluationDomain::new(1, K); let mut a = domain.empty_lagrange(); @@ -251,8 +267,7 @@ fn test_commit_lagrange_eqaffine() { const K: u32 = 6; use crate::pasta::{EqAffine, Fp}; - use crate::transcript::DummyHashWrite; - let params = Params::::new::>(K); + let params = Params::::new(K); let domain = super::EvaluationDomain::new(1, K); let mut a = domain.empty_lagrange(); @@ -284,7 +299,7 @@ fn test_opening_proof() { ChallengeScalar, DummyHashRead, DummyHashWrite, Transcript, TranscriptRead, TranscriptWrite, }; - let params = Params::::new::>(K); + let params = Params::::new(K); let domain = EvaluationDomain::new(1, K); let mut px = domain.empty_coeff();