mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Merge pull request #204 from zcash/parameter-gen
Generate parameters using hash to curve
This commit is contained in:
commit
c5c0dbe190
5 changed files with 65 additions and 93 deletions
|
|
@ -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};
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
|
@ -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
|
||||
|
|
@ -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)>;
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
|
||||
|
|
@ -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,
|
||||
|
|
@ -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!()
|
||||
|
|
@ -909,7 +910,6 @@ new_curve_impl!(
|
|||
IsoEp,
|
||||
Fp,
|
||||
Fq,
|
||||
b"halo2_____pallas",
|
||||
"pallas",
|
||||
[0, 0, 0, 0],
|
||||
[5, 0, 0, 0],
|
||||
|
|
@ -922,7 +922,6 @@ new_curve_impl!(
|
|||
IsoEq,
|
||||
Fq,
|
||||
Fp,
|
||||
b"halo2______vesta",
|
||||
"vesta",
|
||||
[0, 0, 0, 0],
|
||||
[5, 0, 0, 0],
|
||||
|
|
@ -935,7 +934,6 @@ new_curve_impl!(
|
|||
Ep,
|
||||
Fp,
|
||||
Fq,
|
||||
b"halo2_iso_pallas",
|
||||
"iso-pallas",
|
||||
[
|
||||
0x92bb4b0b657a014b,
|
||||
|
|
@ -953,7 +951,6 @@ new_curve_impl!(
|
|||
Eq,
|
||||
Fq,
|
||||
Fp,
|
||||
b"halo2__iso_vesta",
|
||||
"iso-vesta",
|
||||
[
|
||||
0xc515ad7242eaa6b1,
|
||||
|
|
|
|||
28
src/plonk.rs
28
src/plonk.rs
|
|
@ -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),
|
||||
],
|
||||
},
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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);
|
||||
|
|
@ -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, _| {
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue