Generate the URS using a homebrew mixture of blake2b and try-and-increment.

This commit is contained in:
Sean Bowe 2020-12-23 16:09:17 -07:00
parent a2999accb5
commit dff5a3a692
No known key found for this signature in database
GPG key ID: 95684257D8F8B031
8 changed files with 61 additions and 42 deletions

View file

@ -42,6 +42,7 @@ metrics = "=0.13.0-alpha.13"
metrics-macros = "=0.1.0-alpha.9" metrics-macros = "=0.1.0-alpha.9"
num_cpus = "1.13" num_cpus = "1.13"
rand = "0.7" rand = "0.7"
blake2b_simd = "0.5"
[features] [features]
sanity-checks = [] sanity-checks = []

View file

@ -5,7 +5,6 @@ extern crate halo2;
use crate::arithmetic::{small_multiexp, FieldExt}; use crate::arithmetic::{small_multiexp, FieldExt};
use crate::pasta::{EqAffine, Fp}; use crate::pasta::{EqAffine, Fp};
use crate::poly::commitment::Params; use crate::poly::commitment::Params;
use crate::transcript::DummyHashWrite;
use halo2::*; use halo2::*;
use criterion::{black_box, Criterion}; use criterion::{black_box, Criterion};
@ -13,7 +12,7 @@ use criterion::{black_box, Criterion};
fn criterion_benchmark(c: &mut Criterion) { fn criterion_benchmark(c: &mut Criterion) {
// small multiexp // small multiexp
{ {
let params: Params<EqAffine> = Params::new::<DummyHashWrite<_, _>>(5); let params: Params<EqAffine> = Params::new(5);
let g = &mut params.get_g(); let g = &mut params.get_g();
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);

View file

@ -18,7 +18,7 @@ fn bench_with_k(name: &str, k: u32, c: &mut Criterion) {
pub struct Variable(Column<Advice>, usize); pub struct Variable(Column<Advice>, usize);
// Initialize the polynomial commitment parameters // Initialize the polynomial commitment parameters
let params: Params<EqAffine> = Params::new::<DummyHashWrite<_, _>>(k); let params: Params<EqAffine> = Params::new(k);
struct PLONKConfig { struct PLONKConfig {
a: Column<Advice>, a: Column<Advice>,

View file

@ -7,7 +7,6 @@ use halo2::{
transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite}, transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite},
}; };
use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
/// This represents an advice column at a certain row in the ConstraintSystem /// This represents an advice column at a certain row in the ConstraintSystem
@ -250,7 +249,7 @@ fn main() {
let k = 11; let k = 11;
// Initialize the polynomial commitment parameters // Initialize the polynomial commitment parameters
let params: Params<EqAffine> = Params::new::<DummyHashWrite<io::Sink, _>>(k); let params: Params<EqAffine> = Params::new(k);
let empty_circuit: MyCircuit<Fp> = MyCircuit { a: None, k }; let empty_circuit: MyCircuit<Fp> = MyCircuit { a: None, k };

View file

@ -122,6 +122,10 @@ pub trait CurveAffine:
/// The base field over which this elliptic curve is constructed. /// The base field over which this elliptic curve is constructed.
type Base: FieldExt; type Base: FieldExt;
/// Personalization of BLAKE2b hasher used to generate the uniform
/// random string.
const BLAKE2B_PERSONALIZATION: &'static [u8; 16];
/// Obtains the additive identity. /// Obtains the additive identity.
fn zero() -> Self; fn zero() -> Self;

View file

@ -11,7 +11,7 @@ use super::{Fp, Fq};
use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group}; use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group};
macro_rules! new_curve_impl { 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. /// Represents a point in the projective coordinate space.
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct $name { pub struct $name {
@ -497,6 +497,8 @@ macro_rules! new_curve_impl {
type Scalar = $scalar; type Scalar = $scalar;
type Base = $base; type Base = $base;
const BLAKE2B_PERSONALIZATION: &'static [u8; 16] = $blake2b_personalization;
fn zero() -> Self { fn zero() -> Self {
Self { Self {
x: $base::zero(), x: $base::zero(),
@ -700,5 +702,5 @@ macro_rules! new_curve_impl {
}; };
} }
new_curve_impl!(Ep, EpAffine, Fp, Fq); new_curve_impl!(Ep, EpAffine, Fp, Fq, b"halo2_____pallas");
new_curve_impl!(Eq, EqAffine, Fq, Fp); new_curve_impl!(Eq, EqAffine, Fq, Fp, b"halo2______vesta");

View file

@ -107,7 +107,6 @@ fn test_proving() {
use crate::poly::commitment::{Blind, Params}; use crate::poly::commitment::{Blind, Params};
use crate::transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite}; use crate::transcript::{DummyHashRead, DummyHashWrite, TranscriptRead, TranscriptWrite};
use circuit::{Advice, Column, Fixed}; use circuit::{Advice, Column, Fixed};
use std::io;
use std::marker::PhantomData; use std::marker::PhantomData;
const K: u32 = 5; const K: u32 = 5;
@ -116,7 +115,7 @@ fn test_proving() {
pub struct Variable(Column<Advice>, usize); pub struct Variable(Column<Advice>, usize);
// Initialize the polynomial commitment parameters // Initialize the polynomial commitment parameters
let params: Params<EqAffine> = Params::new::<DummyHashWrite<io::Sink, _>>(K); let params: Params<EqAffine> = Params::new(K);
struct PLONKConfig { struct PLONKConfig {
a: Column<Advice>, a: Column<Advice>,

View file

@ -3,12 +3,12 @@
//! //!
//! [halo]: https://eprint.iacr.org/2019/1021 //! [halo]: https://eprint.iacr.org/2019/1021
use blake2b_simd::{Params as Blake2bParams, State as Blake2bState};
use super::{Coeff, LagrangeCoeff, Polynomial}; use super::{Coeff, LagrangeCoeff, Polynomial};
use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, FieldExt}; use crate::arithmetic::{best_fft, best_multiexp, parallelize, Curve, CurveAffine, FieldExt};
use crate::transcript::{Transcript, TranscriptWrite};
use ff::{Field, PrimeField}; use ff::{Field, PrimeField};
use std::io;
use std::ops::{Add, AddAssign, Mul, MulAssign}; use std::ops::{Add, AddAssign, Mul, MulAssign};
mod msm; mod msm;
@ -33,7 +33,7 @@ pub struct Params<C: CurveAffine> {
impl<C: CurveAffine> Params<C> { impl<C: CurveAffine> Params<C> {
/// Initializes parameters for the curve, given a random oracle to draw /// Initializes parameters for the curve, given a random oracle to draw
/// points from. /// points from.
pub fn new<T: TranscriptWrite<io::Sink, C> + Sync>(k: u32) -> Self { pub fn new(k: u32) -> Self {
// This is usually a limitation on the curve, but we also want 32-bit // This is usually a limitation on the curve, but we also want 32-bit
// architectures to be supported. // architectures to be supported.
assert!(k < 32); assert!(k < 32);
@ -42,27 +42,38 @@ impl<C: CurveAffine> Params<C> {
let n: u64 = 1 << k; let n: u64 = 1 << k;
let g = { let try_and_increment = |hasher: &Blake2bState| {
let hasher = &T::init(io::sink(), C::Base::one()); 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); let mut g = Vec::with_capacity(n as usize);
g.resize(n as usize, C::zero()); g.resize(n as usize, C::zero());
parallelize(&mut g, move |g, start| { parallelize(&mut g, move |g, start| {
let mut cur_value = C::Scalar::from(start as u64); let mut hasher = Blake2bParams::new()
for g in g.iter_mut() { .hash_length(32)
let mut hasher = hasher.fork(); .personal(C::BLAKE2B_PERSONALIZATION)
hasher.write_scalar(cur_value).unwrap(); .to_state();
cur_value += &C::Scalar::one(); hasher.update(b"G vector");
loop {
let x: C::Base = hasher.squeeze_challenge(); for (i, g) in g.iter_mut().enumerate() {
let x = x.to_bytes(); let i = (i + start) as u64;
let p = C::from_bytes(&x); let mut hasher = hasher.clone();
if bool::from(p.is_some()) { hasher.update(&(i.to_le_bytes())[..]);
*g = p.unwrap();
break; *g = try_and_increment(&hasher);
}
}
} }
}); });
@ -97,17 +108,23 @@ impl<C: CurveAffine> Params<C> {
}; };
let h = { let h = {
let mut hasher = T::init(io::sink(), C::Base::from_u64(2)); let mut hasher = Blake2bParams::new()
let x = hasher.squeeze_challenge().to_bytes(); .hash_length(32)
let p = C::from_bytes(&x); .personal(C::BLAKE2B_PERSONALIZATION)
p.unwrap() .to_state();
hasher.update(b"H");
try_and_increment(&hasher)
}; };
let u = { let u = {
let mut hasher = T::init(io::sink(), C::Base::from_u64(3)); let mut hasher = Blake2bParams::new()
let x = hasher.squeeze_challenge().to_bytes(); .hash_length(32)
let p = C::from_bytes(&x); .personal(C::BLAKE2B_PERSONALIZATION)
p.unwrap() .to_state();
hasher.update(b"U");
try_and_increment(&hasher)
}; };
Params { Params {
@ -229,8 +246,7 @@ fn test_commit_lagrange_epaffine() {
const K: u32 = 6; const K: u32 = 6;
use crate::pasta::{EpAffine, Fq}; use crate::pasta::{EpAffine, Fq};
use crate::transcript::DummyHashWrite; let params = Params::<EpAffine>::new(K);
let params = Params::<EpAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K);
let domain = super::EvaluationDomain::new(1, K); let domain = super::EvaluationDomain::new(1, K);
let mut a = domain.empty_lagrange(); let mut a = domain.empty_lagrange();
@ -251,8 +267,7 @@ fn test_commit_lagrange_eqaffine() {
const K: u32 = 6; const K: u32 = 6;
use crate::pasta::{EqAffine, Fp}; use crate::pasta::{EqAffine, Fp};
use crate::transcript::DummyHashWrite; let params = Params::<EqAffine>::new(K);
let params = Params::<EqAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K);
let domain = super::EvaluationDomain::new(1, K); let domain = super::EvaluationDomain::new(1, K);
let mut a = domain.empty_lagrange(); let mut a = domain.empty_lagrange();
@ -284,7 +299,7 @@ fn test_opening_proof() {
ChallengeScalar, DummyHashRead, DummyHashWrite, Transcript, TranscriptRead, TranscriptWrite, ChallengeScalar, DummyHashRead, DummyHashWrite, Transcript, TranscriptRead, TranscriptWrite,
}; };
let params = Params::<EpAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K); let params = Params::<EpAffine>::new(K);
let domain = EvaluationDomain::new(1, K); let domain = EvaluationDomain::new(1, K);
let mut px = domain.empty_coeff(); let mut px = domain.empty_coeff();