Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Hyrax multilinear PCS #130

Merged
merged 37 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
f13a576
added hyrax PCS
Antonio95 Oct 25, 2023
69896d4
adapt the scheme to https://github.com/arkworks-rs/algebra/issues/691
mmagician Oct 26, 2023
ecf73f4
remove unused code in hyrax
mmagician Oct 26, 2023
f424c48
expanded on Future Optimisations section
Antonio95 Oct 26, 2023
dd58a1a
Merge branch 'master' into hyrax-pcs
mmagician Oct 28, 2023
06c59e9
Remove Prepared data types from `PolynomialCommitment` trait impl
mmagician Oct 28, 2023
a845018
merged master including new crate and directory structure
Antonio95 Oct 30, 2023
12afb33
added necessary dependencies overwritten by previous merge commit
Antonio95 Oct 30, 2023
6967c28
fixed hashbrown version
Antonio95 Oct 30, 2023
dd82dbc
pulled
Antonio95 Oct 30, 2023
a029081
created separate benchmark files
Antonio95 Oct 30, 2023
a7f465a
fixed duplicate dependency to match other branches
Antonio95 Oct 30, 2023
c010663
patched bn254 dep
Antonio95 Oct 30, 2023
d415053
restructured benchmark macros to accept ML schemes; benches working
Antonio95 Oct 31, 2023
3ef7309
Hyrax fix bench (#42)
mmagician Nov 13, 2023
cc1f75a
Hyrax parallel `commit` (#39)
mmagician Nov 13, 2023
7c7328d
Make Hyrax hiding again (#43)
Antonio95 Nov 13, 2023
55d7b58
Delete `IOPTranscript`, update with master (#50) (aka Hyrax++)
autquis Jan 18, 2024
d13296c
Merge branch 'master' into hyrax-pcs
autquis Jan 18, 2024
1f988ac
Add a few comments and update `Cargo.toml`
autquis Jan 18, 2024
5677c5b
Remove extra `cfg_iter!`
autquis Jan 22, 2024
c2e6412
Change `pedersen_commit` and add `cfg_into_iter!`
autquis Jan 22, 2024
ac4a14c
Hash and absorb
autquis Jan 23, 2024
f3495d0
various minor fixes
Antonio95 Jun 6, 2024
103669f
Reorder Hyrax checks
Cesar199999 Jun 10, 2024
eee8e0b
Add `ark-std` to patch
autquis Jun 9, 2024
65ef67c
Downgrade `hashbrown`
autquis Oct 21, 2024
67ddd9c
Fix breaking change from algebra/poly (#72)
Cesar199999 Jun 28, 2024
175a610
Reorder deps
autquis Oct 21, 2024
d3e3808
Add dummy doc for nightly
autquis Oct 21, 2024
0858433
Fix `hashbrown` + Replace Blake2 by Blake3
autquis Oct 24, 2024
c2ba181
Revert to Blake2
autquis Oct 25, 2024
9e310f5
Merge branch 'master' into hyrax-pcs
autquis Oct 25, 2024
9b03b60
Fix merging issues
autquis Oct 25, 2024
f5924ee
Test if CI is happy
autquis Oct 25, 2024
cb20740
Revert and cleanup
autquis Oct 25, 2024
5239162
Delete dummy doc
autquis Oct 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ ark-std = { git = "https://github.com/arkworks-rs/std/" }
ark-ff = { git = "https://github.com/arkworks-rs/algebra/" }
ark-ec = { git = "https://github.com/arkworks-rs/algebra/" }
ark-serialize = { git = "https://github.com/arkworks-rs/algebra/" }
ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives/" }
ark-poly = { git = "https://github.com/arkworks-rs/algebra/" }

ark-crypto-primitives = { git = "https://github.com/arkworks-rs/crypto-primitives" }
ark-r1cs-std = { git = "https://github.com/arkworks-rs/r1cs-std/" }

ark-bls12-377 = { git = "https://github.com/arkworks-rs/algebra/" }
ark-bls12-381 = { git = "https://github.com/arkworks-rs/algebra/" }
ark-bn254 = { git = "https://github.com/arkworks-rs/algebra/" }
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ Unless you explicitly state otherwise, any contribution that you submit to this
[aurora-light]: https://ia.cr/2019/601
[pcd-acc]: https://ia.cr/2020/499
[pst]: https://ia.cr/2011/587
[ligero]: https://ia.cr/2022/1608
[hyrax]: https://eprint.iacr.org/2017/1132

## Reference papers

Expand Down Expand Up @@ -210,6 +212,14 @@ TCC 2020
Charalampos Papamanthou, Elaine Shi, Roberto Tamassia
TCC 2013

[Ligero: Lightweight Sublinear Arguments Without a Trusted Setup][ligero]
Scott Ames, Carmit Hazay, Yuval Ishai, Muthuramakrishnan Venkitasubramaniam
CCS 2017

[Doubly-efficient zkSNARKs without trusted setup][hyrax]
Riad S. Wahby, Ioanna Tzialla, abhi shelat, Justin Thaler, Michael Walfish
2018 IEEE Symposium on Security and Privacy

## Acknowledgements

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.
40 changes: 26 additions & 14 deletions bench-templates/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,42 @@ use ark_poly_commit::{LabeledPolynomial, PolynomialCommitment};
pub use criterion::*;
pub use paste::paste;

/// Measure the time cost of {commit/open/verify} across a range of num_vars
/// Measure the time cost of `method` (i.e., commit/open/verify) of a
/// multilinear PCS for all `num_vars` specified in `nv_list`.
/// `rand_poly` is a function that outputs a random multilinear polynomial.
/// `rand_point` is a function that outputs a random point in the domain of polynomial.
pub fn bench_pcs_method<F: PrimeField, P: Polynomial<F>, PCS: PolynomialCommitment<F, P>>(
c: &mut Criterion,
range: Vec<usize>,
nv_list: Vec<usize>,
msg: &str,
method: impl Fn(
&PCS::CommitterKey,
&PCS::VerifierKey,
usize,
fn(usize, &mut ChaCha20Rng) -> P,
fn(usize, &mut ChaCha20Rng) -> P::Point,
mmagician marked this conversation as resolved.
Show resolved Hide resolved
) -> Duration,
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
) {
let mut group = c.benchmark_group(msg);
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();

for num_vars in range {
for num_vars in nv_list {
let pp = PCS::setup(num_vars, Some(num_vars), rng).unwrap();
let (ck, vk) = PCS::trim(&pp, num_vars, num_vars, None).unwrap();

group.bench_with_input(
BenchmarkId::from_parameter(num_vars),
&num_vars,
|b, num_vars| {
b.iter(|| method(&ck, &vk, *num_vars, rand_poly));
b.iter_custom(|i| {
let mut time = Duration::from_nanos(0);
for _ in 0..i {
time += method(&ck, &vk, *num_vars, rand_poly, rand_point);
}
time
});
},
);
}
Expand All @@ -54,6 +65,7 @@ pub fn commit<F: PrimeField, P: Polynomial<F>, PCS: PolynomialCommitment<F, P>>(
_vk: &PCS::VerifierKey,
num_vars: usize,
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
_rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
) -> Duration {
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();

Expand Down Expand Up @@ -90,20 +102,20 @@ pub fn open<F, P, PCS>(
_vk: &PCS::VerifierKey,
num_vars: usize,
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
) -> Duration
where
F: PrimeField,
P: Polynomial<F>,
PCS: PolynomialCommitment<F, P>,
P::Point: UniformRand,
{
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();

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

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

let start = Instant::now();
let _ = PCS::open(
Expand All @@ -125,7 +137,6 @@ where
F: PrimeField,
P: Polynomial<F>,
PCS: PolynomialCommitment<F, P>,

P::Point: UniformRand,
{
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();
Expand Down Expand Up @@ -161,20 +172,20 @@ pub fn verify<F, P, PCS>(
vk: &PCS::VerifierKey,
num_vars: usize,
rand_poly: fn(usize, &mut ChaCha20Rng) -> P,
rand_point: fn(usize, &mut ChaCha20Rng) -> P::Point,
) -> Duration
where
F: PrimeField,
P: Polynomial<F>,
PCS: PolynomialCommitment<F, P>,
P::Point: UniformRand,
{
let rng = &mut ChaCha20Rng::from_rng(test_rng()).unwrap();

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

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

#[macro_export]
macro_rules! bench_method {
($c:expr, $method:ident, $scheme_type:ty, $rand_poly:ident) => {
($c:expr, $method:ident, $scheme_type:ty, $rand_poly:ident, $rand_point:ident) => {
let scheme_type_str = stringify!($scheme_type);
let bench_name = format!("{} {}", stringify!($method), scheme_type_str);
bench_pcs_method::<_, _, $scheme_type>(
Expand All @@ -240,19 +251,20 @@ macro_rules! bench_method {
&bench_name,
$method::<_, _, $scheme_type>,
$rand_poly::<_>,
$rand_point::<_>,
);
};
}

#[macro_export]
macro_rules! bench {
(
$scheme_type:ty, $rand_poly:ident
$scheme_type:ty, $rand_poly:ident, $rand_point:ident
) => {
fn bench_pcs(c: &mut Criterion) {
bench_method!(c, commit, $scheme_type, $rand_poly);
bench_method!(c, open, $scheme_type, $rand_poly);
bench_method!(c, verify, $scheme_type, $rand_poly);
bench_method!(c, commit, $scheme_type, $rand_poly, $rand_point);
bench_method!(c, open, $scheme_type, $rand_poly, $rand_point);
bench_method!(c, verify, $scheme_type, $rand_poly, $rand_point);
}

criterion_group!(benches, bench_pcs);
Expand Down
24 changes: 19 additions & 5 deletions poly-commit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,44 @@ ark-poly = {version = "^0.4.0", default-features = false }
ark-crypto-primitives = {version = "^0.4.0", default-features = false, features = ["sponge", "merkle_tree"] }
ark-std = { version = "^0.4.0", default-features = false }

blake2 = { version = "0.10", default-features = false }
derivative = { version = "2", features = [ "use_core" ] }
digest = "0.10"

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

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

[[bench]]
name = "pcs"
path = "benches/pcs.rs"
name = "ipa_times"
path = "benches/ipa_times.rs"
harness = false

[[bench]]
name = "hyrax_times"
path = "benches/hyrax_times.rs"
harness = false

[[bench]]
name = "size"
path = "benches/size.rs"
harness = false

[target.'cfg(all(target_has_atomic = "8", target_has_atomic = "16", target_has_atomic = "32", target_has_atomic = "64", target_has_atomic = "ptr"))'.dependencies]
ahash = { version = "0.8", default-features = false}

[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]
fnv = { version = "1.0", default-features = false }

[dev-dependencies]
ark-ed-on-bls12-381 = { version = "^0.4.0", default-features = false }
ark-bls12-381 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
ark-bls12-377 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }
blake2 = { version = "0.10", default-features = false }
ark-bn254 = { version = "^0.4.0", default-features = false, features = [ "curve" ] }

rand_chacha = { version = "0.3.0", default-features = false }
ark-pcs-bench-templates = { path = "../bench-templates" }

Expand All @@ -48,4 +62,4 @@ default = [ "std", "parallel" ]
std = [ "ark-ff/std", "ark-ec/std", "ark-poly/std", "ark-std/std", "ark-relations/std", "ark-serialize/std", "ark-crypto-primitives/std"]
r1cs = [ "ark-relations", "ark-r1cs-std", "hashbrown", "ark-crypto-primitives/r1cs"]
print-trace = [ "ark-std/print-trace" ]
parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon" ]
parallel = [ "std", "ark-ff/parallel", "ark-ec/parallel", "ark-poly/parallel", "ark-std/parallel", "rayon", "rand" ]
10 changes: 10 additions & 0 deletions poly-commit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ EUROCRYPT 2020
Aniket Kate, Gregory M. Zaverucha, Ian Goldberg
ASIACRYPT 2010

### Hyrax multilinear PC

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.

[Doubly-efficient zkSNARKs without trusted setup][hyrax]
Riad S. Wahby, Ioanna Tzialla, abhi shelat, Justin Thaler, Michael Walfish
2018 IEEE Symposium on Security and Privacy

[hyrax]: https://eprint.iacr.org/2017/1132

### Marlin variant of the Papamanthou-Shi-Tamassia multivariate PC

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.
Expand Down
27 changes: 27 additions & 0 deletions poly-commit/benches/hyrax_times.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use ark_pcs_bench_templates::*;
use ark_poly::{DenseMultilinearExtension, MultilinearExtension};

use ark_bn254::{Fr, G1Affine};
use ark_ff::PrimeField;
use ark_poly_commit::hyrax::HyraxPC;

use rand_chacha::ChaCha20Rng;

// Hyrax PCS over BN254
type Hyrax254 = HyraxPC<G1Affine, DenseMultilinearExtension<Fr>>;

fn rand_poly_hyrax<F: PrimeField>(
num_vars: usize,
rng: &mut ChaCha20Rng,
) -> DenseMultilinearExtension<F> {
DenseMultilinearExtension::rand(num_vars, rng)
}

fn rand_point_hyrax<F: PrimeField>(num_vars: usize, rng: &mut ChaCha20Rng) -> Vec<F> {
(0..num_vars).map(|_| F::rand(rng)).collect()
}

const MIN_NUM_VARS: usize = 12;
const MAX_NUM_VARS: usize = 22;

bench!(Hyrax254, rand_poly_hyrax, rand_point_hyrax);
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ fn rand_poly_ipa_pc<F: PrimeField>(degree: usize, rng: &mut ChaCha20Rng) -> Dens
DenseUnivariatePoly::rand(degree, rng)
}

fn rand_point_ipa_pc<F: PrimeField>(_: usize, rng: &mut ChaCha20Rng) -> F {
F::rand(rng)
}

const MIN_NUM_VARS: usize = 10;
const MAX_NUM_VARS: usize = 20;

bench!(IPA_JubJub, rand_poly_ipa_pc);
bench!(IPA_JubJub, rand_poly_ipa_pc, rand_point_ipa_pc);
35 changes: 32 additions & 3 deletions poly-commit/src/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,33 @@ use ark_r1cs_std::{
prelude::*,
};
use ark_relations::r1cs::{ConstraintSystemRef, Namespace, Result as R1CSResult, SynthesisError};
use ark_std::{borrow::Borrow, cmp::Eq, cmp::PartialEq, hash::Hash};
use ark_std::{
borrow::Borrow,
cmp::{Eq, PartialEq},
hash::{BuildHasherDefault, Hash},
};
#[cfg(not(feature = "std"))]
use ark_std::{string::String, vec::Vec};
use hashbrown::{HashMap, HashSet};

#[cfg(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
))]
type DefaultHasher = ahash::AHasher;

#[cfg(not(all(
target_has_atomic = "8",
target_has_atomic = "16",
target_has_atomic = "32",
target_has_atomic = "64",
target_has_atomic = "ptr"
)))]
type DefaultHasher = fnv::FnvHasher;

/// Define the minimal interface of prepared allocated structures.
pub trait PrepareGadget<Unprepared, ConstraintF: PrimeField>: Sized {
/// Prepare from an unprepared element.
Expand Down Expand Up @@ -180,13 +202,20 @@ pub struct LabeledPointVar<TargetField: PrimeField, BaseField: PrimeField> {
/// An allocated version of `QuerySet`.
#[derive(Clone)]
pub struct QuerySetVar<TargetField: PrimeField, BaseField: PrimeField>(
pub HashSet<(String, LabeledPointVar<TargetField, BaseField>)>,
pub HashSet<
(String, LabeledPointVar<TargetField, BaseField>),
BuildHasherDefault<DefaultHasher>,
>,
);

/// An allocated version of `Evaluations`.
#[derive(Clone)]
pub struct EvaluationsVar<TargetField: PrimeField, BaseField: PrimeField>(
pub HashMap<LabeledPointVar<TargetField, BaseField>, EmulatedFpVar<TargetField, BaseField>>,
pub HashMap<
LabeledPointVar<TargetField, BaseField>,
EmulatedFpVar<TargetField, BaseField>,
BuildHasherDefault<DefaultHasher>,
>,
);

impl<TargetField: PrimeField, BaseField: PrimeField> EvaluationsVar<TargetField, BaseField> {
Expand Down
Loading
Loading