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"
num_cpus = "1.13"
rand = "0.7"
blake2b_simd = "0.5"
[features]
sanity-checks = []

View file

@ -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<EqAffine> = Params::new::<DummyHashWrite<_, _>>(5);
let params: Params<EqAffine> = Params::new(5);
let g = &mut params.get_g();
let len = g.len() / 2;
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);
// Initialize the polynomial commitment parameters
let params: Params<EqAffine> = Params::new::<DummyHashWrite<_, _>>(k);
let params: Params<EqAffine> = Params::new(k);
struct PLONKConfig {
a: Column<Advice>,

View file

@ -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<EqAffine> = Params::new::<DummyHashWrite<io::Sink, _>>(k);
let params: Params<EqAffine> = Params::new(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.
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;

View file

@ -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");

View file

@ -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<Advice>, usize);
// Initialize the polynomial commitment parameters
let params: Params<EqAffine> = Params::new::<DummyHashWrite<io::Sink, _>>(K);
let params: Params<EqAffine> = Params::new(K);
struct PLONKConfig {
a: Column<Advice>,

View file

@ -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<C: CurveAffine> {
impl<C: CurveAffine> Params<C> {
/// Initializes parameters for the curve, given a random oracle to draw
/// 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
// architectures to be supported.
assert!(k < 32);
@ -42,27 +42,38 @@ impl<C: CurveAffine> Params<C> {
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<C: CurveAffine> Params<C> {
};
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::<EpAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K);
let params = Params::<EpAffine>::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::<EqAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K);
let params = Params::<EqAffine>::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::<EpAffine>::new::<DummyHashWrite<std::io::Sink, _>>(K);
let params = Params::<EpAffine>::new(K);
let domain = EvaluationDomain::new(1, K);
let mut px = domain.empty_coeff();