Skip to content

Commit 28322ca

Browse files
authored
Merge branch 'main' into dev-avx2
2 parents 15c0cbb + 4e0834d commit 28322ca

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+1104
-346
lines changed

Diff for: .github/CODEOWNERS

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @muursh @wborgeaud @Nashtare
1+
* @muursh @wborgeaud @Nashtare @LindaGuiga

Diff for: CHANGELOG.md

+33
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,41 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.0.0] - 2024-11-25
11+
12+
### Changed
13+
- Unified Recursion Circuit for Multi-Degree Starky Proof Verification ([#1635](https://github.com/0xPolygonZero/plonky2/pull/1635))
14+
- Fix `DummyProofGenerator` serialization ([#1634](https://github.com/0xPolygonZero/plonky2/pull/1634))
15+
- Refactor CTL Handling ([#1629](https://github.com/0xPolygonZero/plonky2/pull/1629))
16+
- Added serialize and deserialize to starky proofs ([#1630](https://github.com/0xPolygonZero/plonky2/pull/1630))
17+
- changed to web-time in circuit_builder ([#1624](https://github.com/0xPolygonZero/plonky2/pull/1624))
18+
- Fix example and documentation rendering ([#1614](https://github.com/0xPolygonZero/plonky2/pull/1614))
19+
- Add `connect_array` convenience method in `CircuitBuilder` ([#1620](https://github.com/0xPolygonZero/plonky2/pull/1620))
20+
- chore: remove compressed StarkProof variant ([#1618](https://github.com/0xPolygonZero/plonky2/pull/1618))
21+
- Do not panic on `wire set twice` or `generator not run` issues ([#1611](https://github.com/0xPolygonZero/plonky2/pull/1611))
22+
- Add Support for Batch STARKs with Proving, Verification, and Recursion ([#1600](https://github.com/0xPolygonZero/plonky2/pull/1600))
23+
- chore: fix clippy ([#1609](https://github.com/0xPolygonZero/plonky2/pull/1609))
24+
- fix(starky): observe public inputs ([#1607](https://github.com/0xPolygonZero/plonky2/pull/1607))
25+
- ci: add PR check job ([#1604](https://github.com/0xPolygonZero/plonky2/pull/1604))
26+
- Add `Field::shifted_powers` and some iterator niceties ([#1599](https://github.com/0xPolygonZero/plonky2/pull/1599))
27+
- fix(field): Re-enable `alloc` for tests ([#1601](https://github.com/0xPolygonZero/plonky2/pull/1601))
28+
- Add row index to constraint failure message ([#1598](https://github.com/0xPolygonZero/plonky2/pull/1598))
29+
- doc: clarify that `zk` is disabled with `starky` ([#1596](https://github.com/0xPolygonZero/plonky2/pull/1596))
30+
- Allow multiple `extra_looking_sums` for the same looked table ([#1591](https://github.com/0xPolygonZero/plonky2/pull/1591))
31+
- Fix CTL generation of last row ([#1585](https://github.com/0xPolygonZero/plonky2/pull/1585))
32+
- change `set_stark_proof_target`'s witness to `WitnessWrite` ([#1592](https://github.com/0xPolygonZero/plonky2/pull/1592))
33+
- doc+fix: `clippy::doc-lazy-continuation` ([#1594](https://github.com/0xPolygonZero/plonky2/pull/1594))
34+
- fix: remove clippy unexpected_cfgs warning ([#1588](https://github.com/0xPolygonZero/plonky2/pull/1588))
35+
- Changes to prepare for dummy segment removal in zk_evm's continuations ([#1587](https://github.com/0xPolygonZero/plonky2/pull/1587))
36+
- update 2-adic generator to `0x64fdd1a46201e246` ([#1579](https://github.com/0xPolygonZero/plonky2/pull/1579))
37+
- Fix `verify_cross_table_lookups` with no `ctl_extra_looking_sums` ([#1584](https://github.com/0xPolygonZero/plonky2/pull/1584))
38+
- Remove restriction to binary-only multiplicities ([#1577](https://github.com/0xPolygonZero/plonky2/pull/1577))
39+
- Remove obsolete function `ceil_div_usize` ([#1574](https://github.com/0xPolygonZero/plonky2/pull/1574))
40+
41+
1042
## [0.2.3] - 2024-04-16
1143

44+
### Changed
1245
- Code refactoring ([#1558](https://github.com/0xPolygonZero/plonky2/pull/1558))
1346
- Simplify types: remove option from CTL filters ([#1567](https://github.com/0xPolygonZero/plonky2/pull/1567))
1447
- Add stdarch_x86_avx512 feature ([#1566](https://github.com/0xPolygonZero/plonky2/pull/1566))

Diff for: LICENSE-APACHE

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ APPENDIX: How to apply the Apache License to your work.
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright [yyyy] [name of copyright owner]
189+
Copyright [2022-2025] The Plonky2 Authors
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

Diff for: LICENSE-MIT

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
The MIT License (MIT)
22

3-
Copyright (c) 2022 The Plonky2 Authors
3+
Copyright (c) 2022-2025 The Plonky2 Authors
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

Diff for: README.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,10 @@ at your option.
8484

8585
## Security
8686

87-
This code has not yet been audited, and should not be used in any production systems.
87+
This code has been audited prior to the `v1.0.0` release. The audits reports and findings are available in the [audits](./audits/) folder of this repository.
88+
An audited codebase isn't necessarily free of bugs and security exploits, hence we recommend care when using `plonky2` in production settings.
89+
90+
If you find a security issue in the codebase, please refer to our [Security guidelines](./SECURITY.md) for private disclosure.
8891

8992
While Plonky2 is configurable, its defaults generally target 100 bits of security. The default FRI configuration targets 100 bits of *conjectured* security based on the conjecture in [ethSTARK](https://eprint.iacr.org/2021/582).
9093

@@ -93,12 +96,7 @@ Plonky2's default hash function is Poseidon, configured with 8 full rounds, 22 p
9396

9497
## Links
9598

96-
#### Actively maintained
97-
9899
- [Polygon Zero's zkEVM](https://github.com/0xPolygonZero/zk_evm), an efficient Type 1 zkEVM built on top of Starky and plonky2
99-
100-
#### No longer maintained
101-
102100
- [System Zero](https://github.com/0xPolygonZero/system-zero), a zkVM built on top of Starky
103101
- [Waksman](https://github.com/0xPolygonZero/plonky2-waksman), Plonky2 gadgets for permutation checking using Waksman networks
104102
- [Insertion](https://github.com/0xPolygonZero/plonky2-insertion), Plonky2 gadgets for insertion into a list

Diff for: SECURITY.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Polygon Technology Security Information
22

3+
For findings related to plonky2 repository, please contact us with relevant information privately
4+
through our security contact details: [email protected].
5+
6+
Depending on the severity of the findings, the team may reserve the rights to keep the information private
7+
while addressing it internally, and disclose it along a new release after having informed relevant parties.
8+
39
## Link to vulnerability disclosure details (Bug Bounty).
410
- Websites and Applications: https://hackerone.com/polygon-technology
511
- Smart Contracts: https://immunefi.com/bounty/polygon

Diff for: field/Cargo.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "plonky2_field"
33
description = "Finite field arithmetic"
4-
version = "0.2.2"
4+
version = "1.0.0"
55
authors = ["Daniel Lubarov <[email protected]>", "William Borgeaud <[email protected]>", "Jacqueline Nabaglo <[email protected]>", "Hamish Ivey-Law <[email protected]>"]
66
edition.workspace = true
77
license.workspace = true
@@ -20,7 +20,7 @@ static_assertions = { workspace = true }
2020
unroll = { workspace = true }
2121

2222
# Local dependencies
23-
plonky2_util = { version = "0.2.0", path = "../util", default-features = false }
23+
plonky2_util = { version = "1.0.0", path = "../util", default-features = false }
2424

2525

2626
# Display math equations properly in documentation

Diff for: field/src/fft.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ mod tests {
222222
// "random", the last degree_padded-degree of them are zero.
223223
let coeffs = (0..degree)
224224
.map(|i| F::from_canonical_usize(i * 1337 % 100))
225-
.chain(core::iter::repeat(F::ZERO).take(degree_padded - degree))
225+
.chain(core::iter::repeat_n(F::ZERO, degree_padded - degree))
226226
.collect::<Vec<_>>();
227227
assert_eq!(coeffs.len(), degree_padded);
228228
let coefficients = PolynomialCoeffs { coeffs };

Diff for: field/src/prime_field_testing.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ macro_rules! test_prime_field_arithmetic {
160160
fn subtraction_double_wraparound() {
161161
type F = $field;
162162

163-
let (a, b) = (F::from_canonical_u64((F::ORDER + 1u64) / 2u64), F::TWO);
163+
let (a, b) = (F::from_canonical_u64(F::ORDER.div_ceil(2u64)), F::TWO);
164164
let x = a * b;
165165
assert_eq!(x, F::ONE);
166166
assert_eq!(F::ZERO - x, F::NEG_ONE);

Diff for: field/src/types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ pub trait Field:
369369
let mut product = Self::ONE;
370370

371371
for j in 0..bits_u64(power) {
372-
if (power >> j & 1) != 0 {
372+
if ((power >> j) & 1) != 0 {
373373
product *= current;
374374
}
375375
current = current.square();

Diff for: maybe_rayon/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "plonky2_maybe_rayon"
33
description = "Feature-gated wrapper around rayon"
4-
version = "0.2.0"
4+
version = "1.0.0"
55
edition.workspace = true
66
license.workspace = true
77
homepage.workspace = true

Diff for: plonky2/Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "plonky2"
33
description = "Recursive SNARKs based on PLONK and FRI"
4-
version = "0.2.2"
4+
version = "1.0.2"
55
authors = ["Daniel Lubarov <[email protected]>", "William Borgeaud <[email protected]>", "Nicholas Ward <[email protected]>"]
66
readme = "README.md"
77
edition.workspace = true
@@ -34,9 +34,9 @@ unroll = { workspace = true }
3434
web-time = { version = "1.0.0", optional = true }
3535

3636
# Local dependencies
37-
plonky2_field = { version = "0.2.2", path = "../field", default-features = false }
38-
plonky2_maybe_rayon = { version = "0.2.0", path = "../maybe_rayon", default-features = false }
39-
plonky2_util = { version = "0.2.0", path = "../util", default-features = false }
37+
plonky2_field = { version = "1.0.0", path = "../field", default-features = false }
38+
plonky2_maybe_rayon = { version = "1.0.0", path = "../maybe_rayon", default-features = false }
39+
plonky2_util = { version = "1.0.0", path = "../util", default-features = false }
4040

4141

4242
[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies]

Diff for: plonky2/src/batch_fri/oracle.rs

+2
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,8 @@ mod test {
450450
proof.pow_witness,
451451
k0,
452452
&fri_params.config,
453+
None,
454+
None,
453455
);
454456
let degree_bits = [k0, k1, k2];
455457
let merkle_cap = trace_oracle.batch_merkle_tree.cap;

Diff for: plonky2/src/batch_fri/prover.rs

+4
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ mod tests {
318318
proof.pow_witness,
319319
k,
320320
&fri_params.config,
321+
None,
322+
None,
321323
);
322324

323325
let fri_opening_batch = FriOpeningBatch {
@@ -440,6 +442,8 @@ mod tests {
440442
proof.pow_witness,
441443
k0,
442444
&fri_params.config,
445+
None,
446+
None,
443447
);
444448
let fri_opening_batch_0 = FriOpenings {
445449
batches: vec![FriOpeningBatch {

Diff for: plonky2/src/fri/challenges.rs

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
#[cfg(not(feature = "std"))]
2+
use alloc::vec;
3+
14
use crate::field::extension::Extendable;
25
use crate::field::polynomial::PolynomialCoeffs;
6+
use crate::field::types::Field;
37
use crate::fri::proof::{FriChallenges, FriChallengesTarget};
48
use crate::fri::structure::{FriOpenings, FriOpeningsTarget};
59
use crate::fri::FriConfig;
610
use crate::gadgets::polynomial::PolynomialCoeffsExtTarget;
7-
use crate::hash::hash_types::{MerkleCapTarget, RichField};
11+
use crate::hash::hash_types::{MerkleCapTarget, RichField, NUM_HASH_OUT_ELTS};
812
use crate::hash::merkle_tree::MerkleCap;
913
use crate::iop::challenger::{Challenger, RecursiveChallenger};
1014
use crate::iop::target::Target;
@@ -28,6 +32,8 @@ impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
2832
pow_witness: F,
2933
degree_bits: usize,
3034
config: &FriConfig,
35+
final_poly_coeff_len: Option<usize>,
36+
max_num_query_steps: Option<usize>,
3137
) -> FriChallenges<F, D>
3238
where
3339
F: RichField + Extendable<D>,
@@ -46,7 +52,26 @@ impl<F: RichField, H: Hasher<F>> Challenger<F, H> {
4652
})
4753
.collect();
4854

55+
// When this proof was generated in a circuit with a different number of query steps,
56+
// the challenger needs to observe the additional hash caps.
57+
if let Some(step_count) = max_num_query_steps {
58+
let cap_len = (1 << config.cap_height) * NUM_HASH_OUT_ELTS;
59+
let zero_cap = vec![F::ZERO; cap_len];
60+
for _ in commit_phase_merkle_caps.len()..step_count {
61+
self.observe_elements(&zero_cap);
62+
self.get_extension_challenge::<D>();
63+
}
64+
}
65+
4966
self.observe_extension_elements(&final_poly.coeffs);
67+
// When this proof was generated in a circuit with a different final polynomial length,
68+
// the challenger needs to observe the full length of the final polynomial.
69+
if let Some(len) = final_poly_coeff_len {
70+
let current_len = final_poly.coeffs.len();
71+
for _ in current_len..len {
72+
self.observe_extension_element(&F::Extension::ZERO);
73+
}
74+
}
5075

5176
self.observe_element(pow_witness);
5277
let fri_pow_response = self.get_challenge();

Diff for: plonky2/src/fri/oracle.rs

+4
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
178178
oracles: &[&Self],
179179
challenger: &mut Challenger<F, C::Hasher>,
180180
fri_params: &FriParams,
181+
final_poly_coeff_len: Option<usize>,
182+
max_num_query_steps: Option<usize>,
181183
timing: &mut TimingTree,
182184
) -> FriProof<F, C::Hasher, D> {
183185
assert!(D > 1, "Not implemented for D=1.");
@@ -226,6 +228,8 @@ impl<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>
226228
lde_final_values,
227229
challenger,
228230
fri_params,
231+
final_poly_coeff_len,
232+
max_num_query_steps,
229233
timing,
230234
);
231235

Diff for: plonky2/src/fri/prover.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#[cfg(not(feature = "std"))]
2+
use alloc::vec;
3+
#[cfg(not(feature = "std"))]
24
use alloc::vec::Vec;
35

6+
use plonky2_field::types::Field;
47
use plonky2_maybe_rayon::*;
58

69
use crate::field::extension::{flatten, unflatten, Extendable};
710
use crate::field::polynomial::{PolynomialCoeffs, PolynomialValues};
811
use crate::fri::proof::{FriInitialTreeProof, FriProof, FriQueryRound, FriQueryStep};
912
use crate::fri::{FriConfig, FriParams};
10-
use crate::hash::hash_types::RichField;
13+
use crate::hash::hash_types::{RichField, NUM_HASH_OUT_ELTS};
1114
use crate::hash::hashing::PlonkyPermutation;
1215
use crate::hash::merkle_tree::MerkleTree;
1316
use crate::iop::challenger::Challenger;
@@ -26,6 +29,8 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
2629
lde_polynomial_values: PolynomialValues<F::Extension>,
2730
challenger: &mut Challenger<F, C::Hasher>,
2831
fri_params: &FriParams,
32+
final_poly_coeff_len: Option<usize>,
33+
max_num_query_steps: Option<usize>,
2934
timing: &mut TimingTree,
3035
) -> FriProof<F, C::Hasher, D> {
3136
let n = lde_polynomial_values.len();
@@ -40,6 +45,8 @@ pub fn fri_proof<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const
4045
lde_polynomial_values,
4146
challenger,
4247
fri_params,
48+
final_poly_coeff_len,
49+
max_num_query_steps,
4350
)
4451
);
4552

@@ -67,11 +74,20 @@ pub(crate) type FriCommitedTrees<F, C, const D: usize> = (
6774
PolynomialCoeffs<<F as Extendable<D>>::Extension>,
6875
);
6976

77+
pub fn final_poly_coeff_len(mut degree_bits: usize, reduction_arity_bits: &Vec<usize>) -> usize {
78+
for arity_bits in reduction_arity_bits {
79+
degree_bits -= *arity_bits;
80+
}
81+
1 << degree_bits
82+
}
83+
7084
fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>, const D: usize>(
7185
mut coeffs: PolynomialCoeffs<F::Extension>,
7286
mut values: PolynomialValues<F::Extension>,
7387
challenger: &mut Challenger<F, C::Hasher>,
7488
fri_params: &FriParams,
89+
final_poly_coeff_len: Option<usize>,
90+
max_num_query_steps: Option<usize>,
7591
) -> FriCommitedTrees<F, C, D> {
7692
let mut trees = Vec::with_capacity(fri_params.reduction_arity_bits.len());
7793

@@ -103,12 +119,33 @@ fn fri_committed_trees<F: RichField + Extendable<D>, C: GenericConfig<D, F = F>,
103119
values = coeffs.coset_fft(shift.into())
104120
}
105121

122+
// When verifying this proof in a circuit with a different number of query steps,
123+
// we need the challenger to stay in sync with the verifier. Therefore, the challenger
124+
// must observe the additional hash caps and generate dummy challenges.
125+
if let Some(step_count) = max_num_query_steps {
126+
let cap_len = (1 << fri_params.config.cap_height) * NUM_HASH_OUT_ELTS;
127+
let zero_cap = vec![F::ZERO; cap_len];
128+
for _ in fri_params.reduction_arity_bits.len()..step_count {
129+
challenger.observe_elements(&zero_cap);
130+
challenger.get_extension_challenge::<D>();
131+
}
132+
}
133+
106134
// The coefficients being removed here should always be zero.
107135
coeffs
108136
.coeffs
109137
.truncate(coeffs.len() >> fri_params.config.rate_bits);
110138

111139
challenger.observe_extension_elements(&coeffs.coeffs);
140+
// When verifying this proof in a circuit with a different final polynomial length,
141+
// the challenger needs to observe the full length of the final polynomial.
142+
if let Some(len) = final_poly_coeff_len {
143+
let current_len = coeffs.coeffs.len();
144+
for _ in current_len..len {
145+
challenger.observe_extension_element(&F::Extension::ZERO);
146+
}
147+
}
148+
112149
(trees, coeffs)
113150
}
114151

0 commit comments

Comments
 (0)