Skip to content

Commit

Permalink
Merge pull request #204 from zcash/parameter-gen
Browse files Browse the repository at this point in the history
Generate parameters using hash to curve
  • Loading branch information
ebfull authored Feb 22, 2021
2 parents 2e8af8f + 12230a4 commit c5c0dbe
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 93 deletions.
26 changes: 15 additions & 11 deletions src/arithmetic/curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! write code that generalizes over a pair of groups.

use core::cmp;
use core::ops::{Add, Sub};
use core::ops::{Add, Mul, Sub};
use group::prime::{PrimeCurve, PrimeCurveAffine};
use subtle::{Choice, ConditionallySelectable, ConstantTimeEq, CtOption};

Expand All @@ -14,7 +14,7 @@ use std::io::{self, Read, Write};
/// curve group in a "projective" form, where that arithmetic is usually more
/// efficient.
pub trait CurveExt:
PrimeCurve
PrimeCurve<Affine = <Self as CurveExt>::AffineExt>
+ group::Group<Scalar = <Self as CurveExt>::ScalarExt>
+ Default
+ PartialEq
Expand All @@ -28,6 +28,13 @@ pub trait CurveExt:
type ScalarExt: FieldExt;
/// The base field over which this elliptic curve is constructed.
type Base: FieldExt;
/// The affine version of the curve
type AffineExt: CurveAffine<CurveExt = Self, ScalarExt = <Self as CurveExt>::ScalarExt>
+ Mul<Self::ScalarExt, Output = Self>
+ for<'r> Mul<Self::ScalarExt, Output = Self>;

/// CURVE_ID used for hash-to-curve.
const CURVE_ID: &'static str;

/// Apply the curve endomorphism by multiplying the x-coordinate
/// by an element of multiplicative order 3.
Expand Down Expand Up @@ -75,8 +82,10 @@ pub trait CurveExt:
/// This trait is the affine counterpart to `Curve` and is used for
/// serialization, storage in memory, and inspection of $x$ and $y$ coordinates.
pub trait CurveAffine:
PrimeCurveAffine<Scalar = <Self as CurveAffine>::ScalarExt>
+ Default
PrimeCurveAffine<
Scalar = <Self as CurveAffine>::ScalarExt,
Curve = <Self as CurveAffine>::CurveExt,
> + Default
+ Add<Output = <Self as PrimeCurveAffine>::Curve>
+ Sub<Output = <Self as PrimeCurveAffine>::Curve>
+ ConditionallySelectable
Expand All @@ -87,13 +96,8 @@ pub trait CurveAffine:
type ScalarExt: FieldExt;
/// 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];

/// CURVE_ID used for hash-to-curve.
const CURVE_ID: &'static str;
/// The projective form of the curve
type CurveExt: CurveExt<AffineExt = Self, ScalarExt = <Self as CurveAffine>::ScalarExt>;

/// Gets the $(x, y)$ coordinates of this point.
fn get_xy(&self) -> CtOption<(Self::Base, Self::Base)>;
Expand Down
21 changes: 9 additions & 12 deletions src/pasta/curves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::{Fp, Fq};
use crate::arithmetic::{CurveAffine, CurveExt, FieldExt, Group};

macro_rules! new_curve_impl {
(($($privacy:tt)*), $name:ident, $name_affine:ident, $iso:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
(($($privacy:tt)*), $name:ident, $name_affine:ident, $iso:ident, $base:ident, $scalar:ident,
$curve_id:literal, $a_raw:expr, $b_raw:expr, $curve_type:ident) => {
/// Represents a point in the projective coordinate space.
#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -90,8 +90,11 @@ macro_rules! new_curve_impl {
impl CurveExt for $name {
type ScalarExt = $scalar;
type Base = $base;
type AffineExt = $name_affine;

impl_projective_curve_ext!($name, $name_affine, $iso, $base, $curve_type);
const CURVE_ID: &'static str = $curve_id;

impl_projective_curve_ext!($name, $iso, $base, $curve_type);

fn a() -> Self::Base {
$name::curve_constant_a()
Expand Down Expand Up @@ -612,9 +615,7 @@ macro_rules! new_curve_impl {
impl CurveAffine for $name_affine {
type ScalarExt = $scalar;
type Base = $base;

const BLAKE2B_PERSONALIZATION: &'static [u8; 16] = $blake2b_personalization;
const CURVE_ID: &'static str = $curve_id;
type CurveExt = $name;

fn is_on_curve(&self) -> Choice {
// y^2 - x^3 - ax ?= b
Expand Down Expand Up @@ -833,13 +834,13 @@ macro_rules! impl_projective_curve_specific {
}

macro_rules! impl_projective_curve_ext {
($name:ident, $name_affine:ident, $iso:ident, $base:ident, special_a0_b5) => {
($name:ident, $iso:ident, $base:ident, special_a0_b5) => {
fn hash_to_curve<'a>(domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
use super::hashtocurve;

Box::new(move |message| {
let mut us = [Field::zero(); 2];
hashtocurve::hash_to_field($name_affine::CURVE_ID, domain_prefix, message, &mut us);
hashtocurve::hash_to_field($name::CURVE_ID, domain_prefix, message, &mut us);
let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>(
&us[0],
$name::THETA,
Expand All @@ -866,7 +867,7 @@ macro_rules! impl_projective_curve_ext {
}
}
};
($name:ident, $name_affine:ident, $iso:ident, $base:ident, general) => {
($name:ident, $iso:ident, $base:ident, general) => {
/// Unimplemented: hashing to this curve is not supported
fn hash_to_curve<'a>(_domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
unimplemented!()
Expand Down Expand Up @@ -909,7 +910,6 @@ new_curve_impl!(
IsoEp,
Fp,
Fq,
b"halo2_____pallas",
"pallas",
[0, 0, 0, 0],
[5, 0, 0, 0],
Expand All @@ -922,7 +922,6 @@ new_curve_impl!(
IsoEq,
Fq,
Fp,
b"halo2______vesta",
"vesta",
[0, 0, 0, 0],
[5, 0, 0, 0],
Expand All @@ -935,7 +934,6 @@ new_curve_impl!(
Ep,
Fp,
Fq,
b"halo2_iso_pallas",
"iso-pallas",
[
0x92bb4b0b657a014b,
Expand All @@ -953,7 +951,6 @@ new_curve_impl!(
Eq,
Fq,
Fp,
b"halo2__iso_vesta",
"iso-vesta",
[
0xc515ad7242eaa6b1,
Expand Down
28 changes: 14 additions & 14 deletions src/plonk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -946,28 +946,28 @@ fn test_proving() {
],
},
fixed_commitments: [
(0x3710f15f98bf0a7421343fdf390b9519506c67431a5c78678fbcc4db815c8547, 0x0a3c77f30ab2a2741b21cd45326c87dc7f7050b1a5e8c181a534b9c84a09cb02),
(0x115235d6bd2467772db857d66e7f44837cd38bb6ac0c7b412c2997dd47cbbc3c, 0x0f339c20c40e10bed476699e2ddb88256092447582b250f329b0cbf6c3f66f17),
(0x2a9ba245dcce53752e1de999b45c975472bb33b58aed8bcebdfcd185627895f0, 0x1252bf596b7acd19625f68845749f6672b99e71238cfabe91ca545103168d0f0),
(0x2a9ba245dcce53752e1de999b45c975472bb33b58aed8bcebdfcd185627895f0, 0x1252bf596b7acd19625f68845749f6672b99e71238cfabe91ca545103168d0f0),
(0x241d6d9c2060ce821d4b05ff2f9566c3947541f3d14a9aabcdb96c19158e8bc7, 0x39582cc6bdb1a4a88e89c050ad6db0ade34f45ec5791b07de6e694e9627ca66a),
(0x1ee805e20232ba31eeae1fa345bd88ac7df81dc43ffb3967a218ea4defc9d17d, 0x2838c83c064d44e87e5c8d05a234ad24d2d4a502a370acb514b430f516c0f0bf),
(0x37ead9904c760201ec4734ef398f0bdb5fe5a5e6e9db19c85e6b5483bdeb0a0b, 0x1dc08c38ed713b14f7a21a891a83b52160a3ffb0dccfbd70db7c7eb235dd193e),
(0x2dc3d20553691216c988ecbb596c4bda329f27d50bd8a7c2fb0d84b423da3cb4, 0x025b40e800020458e15e3a57268562e6c08c6971d71262bd67c72437cfc60b4c),
(0x046711bb0579a337420e33de9d54438e7c3a9cc47b6728b873d1fd0214d7eb58, 0x2416b30fadfacd828cf76891a2a5f0fe90d7ae0e5a8df947e98660ffbebf72e4),
(0x241db4dcb35d3977d45a57a9c5053e8f2c2310fa98738feb48430254034e42bc, 0x3e9545f6b9aa955ce50450eb1b37fb69d5891bca9b5193e6e8288675abded312),
(0x15a0f4deb421ccdfb7cebd60fe7055d406e8f24e9bf37d304327b2adb53e2f7a, 0x1811c4a5f95dc72b15e780bb76d5d0e91dc315c0726a361712bdcb7afd11dc6c),
(0x15a0f4deb421ccdfb7cebd60fe7055d406e8f24e9bf37d304327b2adb53e2f7a, 0x1811c4a5f95dc72b15e780bb76d5d0e91dc315c0726a361712bdcb7afd11dc6c),
(0x2c1e1e702ea5a876188a2e2d1f7fcbee31e5fba48ccd1d7d8dc000393da5b6cb, 0x302338ba3f31351e080311442a59fc9fd9cc30700ce33f4775741d6888df63ea),
(0x3e6b7c66782b06e0e7cd5bd7930b0204dee22b44a25d7c405909d4ca4eb604a7, 0x19b69444de257eb1dd99020a8c615fdc6bed7308ea63b1d4b3c0430f15e71568),
(0x05dfc2fbe7800a57610e7b61e4cd7e96f96026cc192a92750e50e9c35c2d262d, 0x3b2c6101d9a2bbf8982f84e2bd818952ea1d53c5a815c7a4d900cc27f67da390),
(0x318668190ba5ac1d3a1f93b13dd611e4dd3d68b1ea2ae1fe15b99bfc0858cc94, 0x18edacbf7ad8d4b3e43d9cab81c696cb3671ac3a9007610a5c949d85f9790841),
],
permutations: [
VerifyingKey {
commitments: [
(0x289f468bca3471a3d240169ec65047d0c4bb5e1135e81822523c74b596139fed, 0x1a585c821c71fb49c883859f1389bcae45f17593ddb5f9fee1781b27129e1b06),
(0x096ef96a7725c636e7ca645dfe539694cf2a988da1ca50a468320f419d008054, 0x1ac0b48a254f8e2311081f81aa4a8ff39e37e40aa4c003325f1ac1219d231818),
(0x254c9f0088599aba37607cfd1700c653ef3ec21bfd60b98c3d725678540bc4df, 0x134d9818929589052f3cd80d50140b851db26231b2b784a6b2528a64805598dc),
(0x02d8dce08483e705f124b2e3db76a8065bfd8d893a1de76fd4ba586acb8e2cd0, 0x1456b7e28d96b5f90f885d21fde2ed00d1774cdebc358a95383b95302a87e09d),
(0x1d8a9751a63cbdf4c87787424b9c4a347483d5138943470dd1a73e1d1fd336b1, 0x2b1f6a54bff445799b6abf5bb0ed734d1cabdb46b4966556e753097ed87cef1b),
(0x1592b59a2a90b155420abde2bcf6fb822d80a11e1b44306dc07fc45025f214e5, 0x3802666ef284d7db51cbd2f9be20014e19f0f6a22e1a4d3a0db124b7bdd7fa1b),
],
},
VerifyingKey {
commitments: [
(0x289f468bca3471a3d240169ec65047d0c4bb5e1135e81822523c74b596139fed, 0x1a585c821c71fb49c883859f1389bcae45f17593ddb5f9fee1781b27129e1b06),
(0x096ef96a7725c636e7ca645dfe539694cf2a988da1ca50a468320f419d008054, 0x1ac0b48a254f8e2311081f81aa4a8ff39e37e40aa4c003325f1ac1219d231818),
(0x254c9f0088599aba37607cfd1700c653ef3ec21bfd60b98c3d725678540bc4df, 0x134d9818929589052f3cd80d50140b851db26231b2b784a6b2528a64805598dc),
(0x02d8dce08483e705f124b2e3db76a8065bfd8d893a1de76fd4ba586acb8e2cd0, 0x1456b7e28d96b5f90f885d21fde2ed00d1774cdebc358a95383b95302a87e09d),
(0x1d8a9751a63cbdf4c87787424b9c4a347483d5138943470dd1a73e1d1fd336b1, 0x2b1f6a54bff445799b6abf5bb0ed734d1cabdb46b4966556e753097ed87cef1b),
(0x1592b59a2a90b155420abde2bcf6fb822d80a11e1b44306dc07fc45025f214e5, 0x3802666ef284d7db51cbd2f9be20014e19f0f6a22e1a4d3a0db124b7bdd7fa1b),
],
},
],
Expand Down
79 changes: 25 additions & 54 deletions src/poly/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
//!
//! [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, CurveAffine, FieldExt, Group};
use crate::arithmetic::{
best_fft, best_multiexp, parallelize, CurveAffine, CurveExt, FieldExt, Group,
};

use ff::{Field, PrimeField};
use group::{prime::PrimeCurveAffine, Curve};
use group::{prime::PrimeCurveAffine, Curve, Group as _};
use std::ops::{Add, AddAssign, Mul, MulAssign};

mod msm;
Expand All @@ -36,10 +36,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(k: u32) -> Self
where
<C as PrimeCurveAffine>::Curve: Group,
{
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);
Expand All @@ -48,51 +45,41 @@ impl<C: CurveAffine> Params<C> {

let n: u64 = 1 << k;

let try_and_increment = |hasher: &Blake2bState| {
let mut trial = 0u64;
loop {
let mut hasher = hasher.clone();
hasher.update(&(trial.to_le_bytes())[..]);
let mut repr = C::Repr::default();
repr.as_mut().copy_from_slice(hasher.finalize().as_bytes());
let p = C::from_bytes(&repr);
if bool::from(p.is_some()) {
break p.unwrap();
}
trial += 1;
}
};

let g = {
let g_projective = {
let mut g = Vec::with_capacity(n as usize);
g.resize(n as usize, C::identity());
g.resize(n as usize, C::Curve::identity());

parallelize(&mut g, move |g, start| {
let mut hasher = Blake2bParams::new()
.hash_length(32)
.personal(C::BLAKE2B_PERSONALIZATION)
.to_state();
hasher.update(b"G vector");
let hasher = C::CurveExt::hash_to_curve("Halo2-Parameters");

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())[..]);
let i = (i + start) as u32;

*g = try_and_increment(&hasher);
let mut message = [0u8; 5];
message[1..5].copy_from_slice(&i.to_le_bytes());

*g = hasher(&message);
}
});

g
};

let g = {
let mut g = vec![C::identity(); n as usize];
parallelize(&mut g, |g, starts| {
C::Curve::batch_normalize(&g_projective[starts..(starts + g.len())], g);
});
g
};

// Let's evaluate all of the Lagrange basis polynomials
// using an inverse FFT.
let mut alpha_inv = <<C as PrimeCurveAffine>::Curve as Group>::Scalar::ROOT_OF_UNITY_INV;
for _ in k..C::Scalar::S {
alpha_inv = alpha_inv.square();
}
let mut g_lagrange_projective = g.iter().map(|g| g.to_curve()).collect::<Vec<_>>();
let mut g_lagrange_projective = g_projective;
best_fft(&mut g_lagrange_projective, alpha_inv, k);
let minv = C::Scalar::TWO_INV.pow_vartime(&[k as u64, 0, 0, 0]);
parallelize(&mut g_lagrange_projective, |g, _| {
Expand All @@ -113,25 +100,9 @@ impl<C: CurveAffine> Params<C> {
g_lagrange
};

let h = {
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 = Blake2bParams::new()
.hash_length(32)
.personal(C::BLAKE2B_PERSONALIZATION)
.to_state();
hasher.update(b"U");

try_and_increment(&hasher)
};
let hasher = C::CurveExt::hash_to_curve("Halo2-Parameters");
let h = hasher(&[1]).to_affine();
let u = hasher(&[2]).to_affine();

Params {
k,
Expand Down
4 changes: 2 additions & 2 deletions src/transcript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ impl<R: Read, C: CurveAffine> Blake2bRead<R, C> {
Blake2bRead {
state: Blake2bParams::new()
.hash_length(64)
.personal(C::BLAKE2B_PERSONALIZATION)
.personal(b"Halo2-Transcript")
.to_state(),
reader,
_marker: PhantomData,
Expand Down Expand Up @@ -136,7 +136,7 @@ impl<W: Write, C: CurveAffine> Blake2bWrite<W, C> {
Blake2bWrite {
state: Blake2bParams::new()
.hash_length(64)
.personal(C::BLAKE2B_PERSONALIZATION)
.personal(b"Halo2-Transcript")
.to_state(),
writer,
_marker: PhantomData,
Expand Down

0 comments on commit c5c0dbe

Please sign in to comment.