Skip to content

Commit

Permalink
Add Hyrax multilinear PCS (#130)
Browse files Browse the repository at this point in the history
* 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

---------

Co-authored-by: mmagician <[email protected]>
Co-authored-by: Hossein Moghaddas <[email protected]>
Co-authored-by: Pratyush Mishra <[email protected]>
  • Loading branch information
4 people authored Mar 25, 2024
1 parent 12f5529 commit 2973e7a
Show file tree
Hide file tree
Showing 18 changed files with 1,217 additions and 33 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ debug = true
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-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/curves/" }
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/" }
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 @@ -184,6 +184,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 @@ -211,6 +213,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.
39 changes: 26 additions & 13 deletions bench-templates/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,46 @@ 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, PoseidonSponge<F>>,
>(
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,
) -> 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 @@ -62,6 +73,7 @@ pub fn commit<
_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 @@ -102,20 +114,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, PoseidonSponge<F>>,
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 Down Expand Up @@ -173,20 +185,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, PoseidonSponge<F>>,
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 @@ -243,7 +255,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 @@ -252,19 +264,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
19 changes: 13 additions & 6 deletions poly-commit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,24 @@ ark-ec = { version = "^0.4.0", default-features = false }
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 }
rand = { version = "0.8.0", optional = true }
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 }

digest = "0.10"
derivative = { version = "2", features = [ "use_core" ] }
rayon = { version = "1", optional = true }
hashbrown = { version = "0.14", default-features = false, 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]]
Expand All @@ -38,7 +44,8 @@ harness = false
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 @@ -47,4 +54,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
28 changes: 28 additions & 0 deletions poly-commit/benches/hyrax_times.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use ark_crypto_primitives::sponge::poseidon::PoseidonSponge;
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>, PoseidonSponge<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 @@ -22,7 +22,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);
65 changes: 65 additions & 0 deletions poly-commit/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,49 @@ pub enum Error {
/// Index of the offending polynomial.
label: String,
},

/// This means a failure in verifying the commitment or the opening.
InvalidCommitment,

/// This means during opening or verification, a commitment of incorrect
/// size (for example, with an insufficient number of entries) was
/// encountered
IncorrectCommitmentSize {
/// Encountered commitment size
encountered: usize,
/// Expected commitment size
expected: usize,
},

/// For PCS which rely on Fiat-Shamir to be rendered non-interactive,
/// these are errors that result from incorrect transcript manipulation.
TranscriptError,

/// This means the required soundness error bound is inherently impossible.
/// E.g., the field is not big enough.
InvalidParameters(String),

/// Error resulting from hashing in linear code - based PCS.
HashingError,

/// This means a commitment with a certain label was matched with a
/// a polynomial which has a different label - which shouldn't happen
MismatchedLabels {
/// The label of the commitment
commitment_label: String,
/// The label of the polynomial
polynomial_label: String,
},

/// This means multivariate polynomial with a certain number of variables
/// was matched (for instance, during commitment, opening or verification)
/// to a point with a different number of variables.
MismatchedNumVars {
/// The number of variables of the polynomial
poly_nv: usize,
/// The number of variables of the point
point_nv: usize,
},
}

impl core::fmt::Display for Error {
Expand Down Expand Up @@ -179,6 +222,28 @@ impl core::fmt::Display for Error {
support up to degree ({:?})", label, poly_degree, supported_degree
),
Error::IncorrectInputLength(err) => write!(f, "{}", err),
Error::InvalidCommitment => write!(f, "Failed to verify the commitment"),
Error::IncorrectCommitmentSize {
encountered,
expected,
} => write!(
f,
"the commitment has size {}, but size {} was expected",
encountered, expected
),
Error::TranscriptError => write!(f, "Incorrect transcript manipulation"),
Error::InvalidParameters(err) => write!(f, "{}", err),
Error::HashingError => write!(f, "Error resulting from hashing"),
Error::MismatchedLabels { commitment_label, polynomial_label } =>
write!(f, "Mismatched labels: commitment label: {}, polynomial label: {}",
commitment_label,
polynomial_label
),
Error::MismatchedNumVars { poly_nv, point_nv } =>
write!(f, "Mismatched number of variables: polynomial has {}, point has {}",
poly_nv,
point_nv,
),
}
}
}
Expand Down
Loading

0 comments on commit 2973e7a

Please sign in to comment.