Skip to content

Commit 77de8eb

Browse files
Antonio95mmagicianautquisPratyushCesar199999
authored
Add Hyrax multilinear PCS (#130)
* added hyrax PCS * adapt the scheme to arkworks-rs/algebra#691 * remove unused code in hyrax * expanded on Future Optimisations section * Remove Prepared data types from `PolynomialCommitment` trait impl * added necessary dependencies overwritten by previous merge commit * fixed hashbrown version * pulled * created separate benchmark files * fixed duplicate dependency to match other branches * patched bn254 dep * restructured benchmark macros to accept ML schemes; benches working * Hyrax fix bench (#42) * fix bench call * set num vars from 12-20 * Hyrax parallel `commit` (#39) * Enable parallel commitment in hyrax amend * make `rand` optional * remove dead code * Make Hyrax hiding again (#43) * removed evaluation randomness from proof and ignored claimed value in check to make scheme hiding * fmt * removed unnecessary usage of argument in check, added _ * Delete `IOPTranscript`, update with master (#50) (aka Hyrax++) * Add the trait bounds * Add `CommitmentState` * Update benches for the new type * Fix the name of local variable * Merge `PCCommitmentState` with `PCRandomness` * Update `README.md` * Fix a bug * Change `Randomness` to `CommitmentState` * Maybe `empty` not return `Self` * Make `empty` return `Self` * Rename `rand` to `state` * Partially integrate the new design into Hyrax * Update Hyrax with the shared state * Rename nonnative to emulated, as in `r1cs-std` (#137) * Rename nonnative to emulated, as in `r1cs-std` * Run `fmt` * Temporarily change `Cargo.toml` * Revert `Cargo.toml` * Refactor `FoldedPolynomialStream` partially * Substitute `ChallengeGenerator` by the generic sponge (#139) * Rename nonnative to emulated, as in `r1cs-std` * Run `fmt` * Temporarily change `Cargo.toml` * Substitute `ChallengeGenerator` with the generic sponge * Run `fmt` * Remove the extra file * Update modules * Delete the unnecessary loop * Revert `Cargo.toml` * Refactor `FoldedPolynomialStream` partially * Update README * Make the diff more readable * Bring the whitespace back * Make diff more readable, 2 * Fix according to breaking changes in `ark-ec` (#141) * Fix for KZG10 * Fix the breaking changes in `ark-ec` * Remove the extra loop * Fix the loop range * re-use the preprocessing table * also re-use the preprocessing table for multilinear_pc --------- Co-authored-by: mmagician <[email protected]> * Auxiliary opening data (#134) * Add the trait bounds * Add `CommitmentState` * Update benches for the new type * Fix the name of local variable * Merge `PCCommitmentState` with `PCRandomness` * Update `README.md` * Fix a bug * Put `Randomness` in `CommitmentState` * Add a comment * Remove the extra loop * Update the comment for `CommitmentState` Co-authored-by: Marcin <[email protected]> * cargo fmt --------- Co-authored-by: Marcin <[email protected]> * `batch_mul_with_preprocessing` no longer takes `self` as argument (#142) * batch_mul_with_preprocessing no longer takes `self` as argument * Apply suggestions from code review Co-authored-by: Pratyush Mishra <[email protected]> * fix variable name --------- Co-authored-by: Pratyush Mishra <[email protected]> * Remove ChallengeGenerator for Ligero (#56) * Squash and merge `delete-chalgen` onto here * Fix for `ChallengeGenerator` * Delete `IOPTranscript` for Hyrax (#55) * Use the sponge generic and rearrange `use`s * Use sponge instead of `IOPTransript` * Fix benches * Remove the extra loop --------- Co-authored-by: mmagician <[email protected]> Co-authored-by: Pratyush Mishra <[email protected]> * Add a few comments and update `Cargo.toml` * Remove extra `cfg_iter!` Co-authored-by: Pratyush Mishra <[email protected]> * Change `pedersen_commit` and add `cfg_into_iter!` * Hash and absorb * various minor fixes * Reorder Hyrax checks Co-authored-by: Antonio Mejías Gil <[email protected]> * Add `ark-std` to patch * Downgrade `hashbrown` * Fix breaking change from algebra/poly (#72) * Reorder deps * Add dummy doc for nightly * Fix `hashbrown` + Replace Blake2 by Blake3 * Revert to Blake2 * Fix merging issues * Test if CI is happy * Revert and cleanup * Delete dummy doc --------- Co-authored-by: mmagician <[email protected]> Co-authored-by: Hossein Moghaddas <[email protected]> Co-authored-by: Pratyush Mishra <[email protected]> Co-authored-by: Cesar199999 <[email protected]>
1 parent bbdb37e commit 77de8eb

20 files changed

+1248
-44
lines changed

Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,11 @@ ark-std = { git = "https://github.com/arkworks-rs/std/" }
3232
ark-ff = { git = "https://github.com/arkworks-rs/algebra/" }
3333
ark-ec = { git = "https://github.com/arkworks-rs/algebra/" }
3434
ark-serialize = { git = "https://github.com/arkworks-rs/algebra/" }
35-
ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives/" }
35+
ark-poly = { git = "https://github.com/arkworks-rs/algebra/" }
36+
37+
ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives" }
3638
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/" }
3739

3840
ark-bls12-377 = { git = "https://github.com/arkworks-rs/algebra/" }
3941
ark-bls12-381 = { git = "https://github.com/arkworks-rs/algebra/" }
42+
ark-bn254 = { git = "https://github.com/arkworks-rs/algebra/" }

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ Unless you explicitly state otherwise, any contribution that you submit to this
183183
[aurora-light]: https://ia.cr/2019/601
184184
[pcd-acc]: https://ia.cr/2020/499
185185
[pst]: https://ia.cr/2011/587
186+
[ligero]: https://ia.cr/2022/1608
187+
[hyrax]: https://eprint.iacr.org/2017/1132
186188

187189
## Reference papers
188190

@@ -210,6 +212,14 @@ TCC 2020
210212
Charalampos Papamanthou, Elaine Shi, Roberto Tamassia
211213
TCC 2013
212214

215+
[Ligero: Lightweight Sublinear Arguments Without a Trusted Setup][ligero]
216+
Scott Ames, Carmit Hazay, Yuval Ishai, Muthuramakrishnan Venkitasubramaniam
217+
CCS 2017
218+
219+
[Doubly-efficient zkSNARKs without trusted setup][hyrax]
220+
Riad S. Wahby, Ioanna Tzialla, abhi shelat, Justin Thaler, Michael Walfish
221+
2018 IEEE Symposium on Security and Privacy
222+
213223
## Acknowledgements
214224

215225
This work was supported by: an Engineering and Physical Sciences Research Council grant; a Google Faculty Award; the RISELab at UC Berkeley; and donations from the Ethereum Foundation and the Interchain Foundation.

bench-templates/src/lib.rs

+26-14
Original file line numberDiff line numberDiff line change
@@ -16,31 +16,42 @@ use ark_poly_commit::{LabeledPolynomial, PolynomialCommitment};
1616
pub use criterion::*;
1717
pub use paste::paste;
1818

19-
/// Measure the time cost of {commit/open/verify} across a range of num_vars
19+
/// Measure the time cost of `method` (i.e., commit/open/verify) of a
20+
/// multilinear PCS for all `num_vars` specified in `nv_list`.
21+
/// `rand_poly` is a function that outputs a random multilinear polynomial.
22+
/// `rand_point` is a function that outputs a random point in the domain of polynomial.
2023
pub fn bench_pcs_method<F: PrimeField, P: Polynomial<F>, PCS: PolynomialCommitment<F, P>>(
2124
c: &mut Criterion,
22-
range: Vec<usize>,
25+
nv_list: Vec<usize>,
2326
msg: &str,
2427
method: impl Fn(
2528
&PCS::CommitterKey,
2629
&PCS::VerifierKey,
2730
usize,
2831
fn(usize, &mut ChaCha20Rng) -> P,
32+
fn(usize, &mut ChaCha20Rng) -> P::Point,
2933
) -> Duration,
3034
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
35+
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
3136
) {
3237
let mut group = c.benchmark_group(msg);
3338
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
3439

35-
for num_vars in range {
40+
for num_vars in nv_list {
3641
let pp = PCS::setup(num_vars, Some(num_vars), rng).unwrap();
3742
let (ck, vk) = PCS::trim(&pp, num_vars, num_vars, None).unwrap();
3843

3944
group.bench_with_input(
4045
BenchmarkId::from_parameter(num_vars),
4146
&num_vars,
4247
|b, num_vars| {
43-
b.iter(|| method(&ck, &vk, *num_vars, rand_poly));
48+
b.iter_custom(|i| {
49+
let mut time = Duration::from_nanos(0);
50+
for _ in 0..i {
51+
time += method(&ck, &vk, *num_vars, rand_poly, rand_point);
52+
}
53+
time
54+
});
4455
},
4556
);
4657
}
@@ -54,6 +65,7 @@ pub fn commit<F: PrimeField, P: Polynomial<F>, PCS: PolynomialCommitment<F, P>>(
5465
_vk: &PCS::VerifierKey,
5566
num_vars: usize,
5667
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
68+
_rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
5769
) -> Duration {
5870
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
5971

@@ -90,20 +102,20 @@ pub fn open<F, P, PCS>(
90102
_vk: &PCS::VerifierKey,
91103
num_vars: usize,
92104
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
105+
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
93106
) -> Duration
94107
where
95108
F: PrimeField,
96109
P: Polynomial<F>,
97110
PCS: PolynomialCommitment<F, P>,
98-
P::Point: UniformRand,
99111
{
100112
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
101113

102114
let labeled_poly =
103115
LabeledPolynomial::new("test".to_string(), rand_poly(num_vars, rng), None, None);
104116

105117
let (coms, states) = PCS::commit(&ck, [&labeled_poly], Some(rng)).unwrap();
106-
let point = P::Point::rand(rng);
118+
let point = rand_point(num_vars, rng);
107119

108120
let start = Instant::now();
109121
let _ = PCS::open(
@@ -125,7 +137,6 @@ where
125137
F: PrimeField,
126138
P: Polynomial<F>,
127139
PCS: PolynomialCommitment<F, P>,
128-
129140
P::Point: UniformRand,
130141
{
131142
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
@@ -161,20 +172,20 @@ pub fn verify<F, P, PCS>(
161172
vk: &PCS::VerifierKey,
162173
num_vars: usize,
163174
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
175+
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
164176
) -> Duration
165177
where
166178
F: PrimeField,
167179
P: Polynomial<F>,
168180
PCS: PolynomialCommitment<F, P>,
169-
P::Point: UniformRand,
170181
{
171182
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
172183

173184
let labeled_poly =
174185
LabeledPolynomial::new("test".to_string(), rand_poly(num_vars, rng), None, None);
175186

176187
let (coms, states) = PCS::commit(&ck, [&labeled_poly], Some(rng)).unwrap();
177-
let point = P::Point::rand(rng);
188+
let point = rand_point(num_vars, rng);
178189
let claimed_eval = labeled_poly.evaluate(&point);
179190
let proof = PCS::open(
180191
&ck,
@@ -231,7 +242,7 @@ fn test_sponge<F: PrimeField>() -> PoseidonSponge<F> {
231242

232243
#[macro_export]
233244
macro_rules! bench_method {
234-
($c:expr, $method:ident, $scheme_type:ty, $rand_poly:ident) => {
245+
($c:expr, $method:ident, $scheme_type:ty, $rand_poly:ident, $rand_point:ident) => {
235246
let scheme_type_str = stringify!($scheme_type);
236247
let bench_name = format!("{} {}", stringify!($method), scheme_type_str);
237248
bench_pcs_method::<_, _, $scheme_type>(
@@ -240,19 +251,20 @@ macro_rules! bench_method {
240251
&bench_name,
241252
$method::<_, _, $scheme_type>,
242253
$rand_poly::<_>,
254+
$rand_point::<_>,
243255
);
244256
};
245257
}
246258

247259
#[macro_export]
248260
macro_rules! bench {
249261
(
250-
$scheme_type:ty, $rand_poly:ident
262+
$scheme_type:ty, $rand_poly:ident, $rand_point:ident
251263
) => {
252264
fn bench_pcs(c: &mut Criterion) {
253-
bench_method!(c, commit, $scheme_type, $rand_poly);
254-
bench_method!(c, open, $scheme_type, $rand_poly);
255-
bench_method!(c, verify, $scheme_type, $rand_poly);
265+
bench_method!(c, commit, $scheme_type, $rand_poly, $rand_point);
266+
bench_method!(c, open, $scheme_type, $rand_poly, $rand_point);
267+
bench_method!(c, verify, $scheme_type, $rand_poly, $rand_point);
256268
}
257269

258270
criterion_group!(benches, bench_pcs);

poly-commit/Cargo.toml

+19-5
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,44 @@ ark-poly = {version = "^0.4.0", default-features = false }
1616
ark-crypto-primitives = {version = "^0.4.0", default-features = false, features = ["sponge", "merkle_tree"] }
1717
ark-std = { version = "^0.4.0", default-features = false }
1818

19+
blake2 = { version = "0.10", default-features = false }
1920
derivative = { version = "2", features = [ "use_core" ] }
2021
digest = "0.10"
2122

2223
ark-relations = { version = "^0.4.0", default-features = false, optional = true }
2324
ark-r1cs-std = { version = "^0.4.0", default-features = false, optional = true }
2425

25-
hashbrown = { version = "0.13", default-features = false, optional = true}
26+
hashbrown = { version = "0.15", default-features = false, features = ["inline-more", "allocator-api2"], optional = true }
27+
rand = { version = "0.8.0", optional = true }
2628
rayon = { version = "1", optional = true }
2729

2830
[[bench]]
29-
name = "pcs"
30-
path = "benches/pcs.rs"
31+
name = "ipa_times"
32+
path = "benches/ipa_times.rs"
33+
harness = false
34+
35+
[[bench]]
36+
name = "hyrax_times"
37+
path = "benches/hyrax_times.rs"
3138
harness = false
3239

3340
[[bench]]
3441
name = "size"
3542
path = "benches/size.rs"
3643
harness = false
3744

45+
[target.'cfg(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr"))'.dependencies]
46+
ahash = { version = "0.8", default-features = false}
47+
48+
[target.'cfg(not(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr")))'.dependencies]
49+
fnv = { version = "1.0", default-features = false }
50+
3851
[dev-dependencies]
3952
ark-ed-on-bls12-381 = { version = "^0.4.0", default-features = false }
4053
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
4154
ark-bls12-377 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
42-
blake2 = { version = "0.10", default-features = false }
55+
ark-bn254 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
56+
4357
rand_chacha = { version = "0.3.0", default-features = false }
4458
ark-pcs-bench-templates = { path = "../bench-templates" }
4559

@@ -48,4 +62,4 @@ default = [ "std", "parallel" ]
4862
std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std", "ark-crypto-primitives/std"]
4963
r1cs = [ "ark-relations", "ark-r1cs-std", "hashbrown", "ark-crypto-primitives/r1cs"]
5064
print-trace = [ "ark-std/print-trace" ]
51-
parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ]
65+
parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon", "rand" ]

poly-commit/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ EUROCRYPT 2020
5656
Aniket Kate, Gregory M. Zaverucha, Ian Goldberg
5757
ASIACRYPT 2010
5858

59+
### Hyrax multilinear PC
60+
61+
Polynomial commitment scheme introduced together with the Hyrax zkSNARK (in [this](https://eprint.iacr.org/2017/1132) article). It is based on Pedersen commitments and therefore relies on the difficulty of the discrete logarithm problem in order to provide a hiding PCS.
62+
63+
[Doubly-efficient zkSNARKs without trusted setup][hyrax]
64+
Riad S. Wahby, Ioanna Tzialla, abhi shelat, Justin Thaler, Michael Walfish
65+
2018 IEEE Symposium on Security and Privacy
66+
67+
[hyrax]: https://eprint.iacr.org/2017/1132
68+
5969
### Marlin variant of the Papamanthou-Shi-Tamassia multivariate PC
6070

6171
Multivariate polynomial commitment based on the construction in the Papamanthou-Shi-Tamassia construction with batching and (optional) hiding property inspired by the univariate scheme in Marlin.

poly-commit/benches/hyrax_times.rs

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
use ark_pcs_bench_templates::*;
2+
use ark_poly::{DenseMultilinearExtension, MultilinearExtension};
3+
4+
use ark_bn254::{Fr, G1Affine};
5+
use ark_ff::PrimeField;
6+
use ark_poly_commit::hyrax::HyraxPC;
7+
8+
use rand_chacha::ChaCha20Rng;
9+
10+
// Hyrax PCS over BN254
11+
type Hyrax254 = HyraxPC<G1Affine, DenseMultilinearExtension<Fr>>;
12+
13+
fn rand_poly_hyrax<F: PrimeField>(
14+
num_vars: usize,
15+
rng: &mut ChaCha20Rng,
16+
) -> DenseMultilinearExtension<F> {
17+
DenseMultilinearExtension::rand(num_vars, rng)
18+
}
19+
20+
fn rand_point_hyrax<F: PrimeField>(num_vars: usize, rng: &mut ChaCha20Rng) -> Vec<F> {
21+
(0..num_vars).map(|_| F::rand(rng)).collect()
22+
}
23+
24+
const MIN_NUM_VARS: usize = 12;
25+
const MAX_NUM_VARS: usize = 22;
26+
27+
bench!(Hyrax254, rand_poly_hyrax, rand_point_hyrax);

poly-commit/benches/pcs.rs poly-commit/benches/ipa_times.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ fn rand_poly_ipa_pc<F: PrimeField>(degree: usize, rng: &mut ChaCha20Rng) -> Dens
1919
DenseUnivariatePoly::rand(degree, rng)
2020
}
2121

22+
fn rand_point_ipa_pc<F: PrimeField>(_: usize, rng: &mut ChaCha20Rng) -> F {
23+
F::rand(rng)
24+
}
25+
2226
const MIN_NUM_VARS: usize = 10;
2327
const MAX_NUM_VARS: usize = 20;
2428

25-
bench!(IPA_JubJub, rand_poly_ipa_pc);
29+
bench!(IPA_JubJub, rand_poly_ipa_pc, rand_point_ipa_pc);

poly-commit/src/constraints.rs

+32-3
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,33 @@ use ark_r1cs_std::{
99
prelude::*,
1010
};
1111
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError};
12-
use ark_std::{borrow::Borrow, cmp::Eq, cmp::PartialEq, hash::Hash};
12+
use ark_std::{
13+
borrow::Borrow,
14+
cmp::{Eq, PartialEq},
15+
hash::{BuildHasherDefault, Hash},
16+
};
1317
#[cfg(not(feature = "std"))]
1418
use ark_std::{string::String, vec::Vec};
1519
use hashbrown::{HashMap, HashSet};
1620

21+
#[cfg(all(
22+
target_has_atomic = "8",
23+
target_has_atomic = "16",
24+
target_has_atomic = "32",
25+
target_has_atomic = "64",
26+
target_has_atomic = "ptr"
27+
))]
28+
type DefaultHasher = ahash::AHasher;
29+
30+
#[cfg(not(all(
31+
target_has_atomic = "8",
32+
target_has_atomic = "16",
33+
target_has_atomic = "32",
34+
target_has_atomic = "64",
35+
target_has_atomic = "ptr"
36+
)))]
37+
type DefaultHasher = fnv::FnvHasher;
38+
1739
/// Define the minimal interface of prepared allocated structures.
1840
pub trait PrepareGadget<Unprepared, ConstraintF: PrimeField>: Sized {
1941
/// Prepare from an unprepared element.
@@ -180,13 +202,20 @@ pub struct LabeledPointVar<TargetField: PrimeField, BaseField: PrimeField> {
180202
/// An allocated version of `QuerySet`.
181203
#[derive(Clone)]
182204
pub struct QuerySetVar<TargetField: PrimeField, BaseField: PrimeField>(
183-
pub HashSet<(String, LabeledPointVar<TargetField, BaseField>)>,
205+
pub HashSet<
206+
(String, LabeledPointVar<TargetField, BaseField>),
207+
BuildHasherDefault<DefaultHasher>,
208+
>,
184209
);
185210

186211
/// An allocated version of `Evaluations`.
187212
#[derive(Clone)]
188213
pub struct EvaluationsVar<TargetField: PrimeField, BaseField: PrimeField>(
189-
pub HashMap<LabeledPointVar<TargetField, BaseField>, EmulatedFpVar<TargetField, BaseField>>,
214+
pub HashMap<
215+
LabeledPointVar<TargetField, BaseField>,
216+
EmulatedFpVar<TargetField, BaseField>,
217+
BuildHasherDefault<DefaultHasher>,
218+
>,
190219
);
191220

192221
impl<TargetField: PrimeField, BaseField: PrimeField> EvaluationsVar<TargetField, BaseField> {

0 commit comments

Comments
 (0)