Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
4f272f0
Mark PCS fixed windows Permanent in verifier memory planner
jtcoolen Jun 28, 2026
bb6f463
Model selector accumulator phase span
jtcoolen Jun 28, 2026
4352a71
Use pairing batch hash size constant
jtcoolen Jun 28, 2026
bafd8d7
Account theta windows in trace scratch bound
jtcoolen Jun 28, 2026
de3bd7e
Reserve fused add-product constants early
jtcoolen Jun 28, 2026
7b498f7
Reserve limb decomposition constants early
jtcoolen Jun 28, 2026
5d7afe9
Guard rotated public instance queries in Solidity codegen
jtcoolen Jun 28, 2026
a01b1ea
Fix transcript buffer sizing and quotient VM const-table overflow
Jul 17, 2026
adc589f
Bound the Lagrange batch-invert input run in the memory planner
jtcoolen Jul 18, 2026
b24be9e
Reject off-curve points in EIP-2537 G1/G2 encoders
jtcoolen Jul 18, 2026
fc42518
Validate the SRS G1 base equals the canonical generator
jtcoolen Jul 18, 2026
c80cbc8
Invalidate reassigned variables in the limb7 chain rewriter
jtcoolen Jul 18, 2026
1fa3b41
Content-check embedded VK quotient program against the plan build
jtcoolen Jul 18, 2026
8db58be
Bounds-check quotient VM const-table slots in the offline validator
jtcoolen Jul 18, 2026
700af6d
Fail closed on zero KZG point sets in the PCS emitter
jtcoolen Jul 18, 2026
6e14bfe
Bound the unrolled PCS rotation-point walk at codegen
jtcoolen Jul 18, 2026
36fc616
Correct the KZG batch-inversion non-zero soundness comment
jtcoolen Jul 18, 2026
66c32f9
Fix inverted pairing-orientation comment in the KZG emitter
jtcoolen Jul 18, 2026
688efde
Document the pointer-identity KZG query-grouping invariant
jtcoolen Jul 18, 2026
098f6a1
Harden rotated-instance guard in the quotient VM lowerer
jtcoolen Jul 18, 2026
16f43b5
Use checked u32 conversion for quotient VM memory pointers
jtcoolen Jul 18, 2026
56f20be
Validate quotient VM memory pointers are word-aligned at construction
jtcoolen Jul 18, 2026
2286dff
Guard rotated non-committed instance queries in the Yul quotient emitter
jtcoolen Jul 18, 2026
d149f96
Use unsigned_abs in column_eval_var to avoid i32::MIN overflow
jtcoolen Jul 18, 2026
e5f77f8
Emit h_eval, not 0, for an empty lookup input chunk in the Yul emitter
jtcoolen Jul 18, 2026
33e183e
Guard against a lookup with zero helper chunks in the Yul emitter
jtcoolen Jul 18, 2026
0b56186
Floor quotient stack scratch at one word to cover the eval-scratch write
jtcoolen Jul 18, 2026
d67a2e9
Emit h_eval, not 0, for an empty lookup chunk in the structured path
jtcoolen Jul 18, 2026
63be029
Assert lookup chunk/helper-eval count parity at both zip sites
jtcoolen Jul 18, 2026
fd3842c
Document the proxy selector_gap in native_identity_estimate_block
jtcoolen Jul 18, 2026
b8b4c39
Fail closed on negative offset in Value::as_usize
jtcoolen Jul 18, 2026
a9032f8
Assert VK fixed-commitment count matches meta in Data::new
jtcoolen Jul 18, 2026
822980e
Correct dummy_eval_words address formula in the field doc
jtcoolen Jul 18, 2026
69889be
Reject VK runtime exceeding the EIP-170 code-size limit at codegen
jtcoolen Jul 18, 2026
01f4549
Harden accumulator fixed-base/scalar count check to a release assert
jtcoolen Jul 18, 2026
b2e99e8
Use checked arithmetic when reserving VK payload sections
jtcoolen Jul 18, 2026
68adb90
Range-check accumulator scalars where they are read
jtcoolen Jul 18, 2026
2e49d03
Leave batch_invert immediately on a failed modexp
jtcoolen Jul 18, 2026
636c7ec
Make the verifier's accept path fail closed locally
jtcoolen Jul 18, 2026
d870dd1
Reject non-reduced inputs in the Fr inversion helpers
jtcoolen Jul 18, 2026
b680bf2
Check spilled-stack balance in the quotient VM epilogue
jtcoolen Jul 18, 2026
3f95c05
Initialize the y^0 slot in the selector power table
jtcoolen Jul 18, 2026
14cb772
Count quotient limbs in absorb bytes in eval_run_bytes
jtcoolen Jul 18, 2026
79dd945
Assert VK permutation commitment count matches meta in Data::new
jtcoolen Jul 18, 2026
9d7081b
Panic instead of rendering a negative pointer as sub(0, N)
jtcoolen Jul 18, 2026
b4319da
Reject non-canonical scalars in the proof repacking shim
jtcoolen Jul 18, 2026
55d548b
Correct the pairing-batch domain tag comment
jtcoolen Jul 18, 2026
a1bb2c4
Move final pairing scratch past the accumulator batch frame
jtcoolen Jul 18, 2026
914c61c
Order MemoryPhase to match generated-verifier execution order
jtcoolen Jul 18, 2026
ed547ae
Register the trace-only linearization MSM scratch with the arena
jtcoolen Jul 19, 2026
5912061
Compile the accumulator render arm in the default EVM gate
jtcoolen Jul 19, 2026
48a6f0c
Regenerate tracked verifier fixture artifacts
jtcoolen Jul 19, 2026
54907b5
Reject an accumulator fixed-base tail the VK cannot supply bases for
jtcoolen Jul 19, 2026
bea362e
Fail loudly when the EVM gate is requested but cannot run
jtcoolen Jul 19, 2026
9e714b7
Require the pairing precompile to return exactly one
jtcoolen Jul 19, 2026
72bc1b2
Fix an always-false guard in the accumulator limb decoder
jtcoolen Jul 19, 2026
58824e8
Report unsupported constraint systems from try_new instead of panicking
jtcoolen Jul 19, 2026
75f9f99
Bound the public instance count at generator construction
jtcoolen Jul 19, 2026
06e46be
Pin the phase ordering the Lagrange denominator cap depends on
jtcoolen Jul 19, 2026
896fd04
Add a known-answer vector to the EIP-2537 constructor smoke test
jtcoolen Jul 19, 2026
6333673
Base the generated layout above solc's via-IR spill reservation
jtcoolen Jul 19, 2026
a30fef4
Enforce the EIP-170 runtime size limit on the verifier contracts
jtcoolen Jul 19, 2026
2938a40
Propagate the TranscriptInputBytes bound to LightAggregator::verify
jtcoolen Jul 19, 2026
70dd1a8
Add a CI replay that adversarially exercises the accumulator decoder
jtcoolen Jul 19, 2026
6f78686
Cover point_pair accumulators and port calldata attacks to the replays
jtcoolen Jul 19, 2026
29b4eb9
Record deployment status and bytecode verification for moonlight-wrap
jtcoolen Jul 19, 2026
9bf8c51
Regenerate tracked verifier fixture artifacts
jtcoolen Jul 19, 2026
0b27485
Self-certify emitted quotient VM bytecode at render time
jtcoolen Jul 19, 2026
94dfe37
Refresh moonlight-wrap fixture calldata
jtcoolen Jul 19, 2026
60f842b
Move the pairing-batch and final-pairing frames above solc's spill wi…
Jul 20, 2026
aa62d19
Reject non-canonical scalars in batch_invert's general path
Jul 20, 2026
0cd1bdb
Harden quotient certification and spill-window coverage
Jul 20, 2026
ffd39db
Run the Solidity verifier test suite in root CI
jtcoolen Aug 3, 2026
277c096
Refresh the lowering architecture spec's stale references
jtcoolen Aug 3, 2026
20766cb
Bounds-check the quotient VM's emitted memory pointers
jtcoolen Aug 3, 2026
743d5da
Unblock the clippy gate for the Solidity verifier package
jtcoolen Aug 3, 2026
11928d1
Apply rustfmt to the quotient pointer validator
jtcoolen Aug 3, 2026
0aab0cf
Make the gated EVM tests work under --all-features
jtcoolen Aug 3, 2026
3f89a98
Correct the I-12 challenge-sampling bias analysis
jtcoolen Aug 3, 2026
6753679
Register the Lagrange denominator run as planner-owned scratch
jtcoolen Aug 6, 2026
78556d0
Regenerate the IVC replay fixture on the registered Lagrange scratch …
jtcoolen Aug 6, 2026
3fb6d84
Refresh the tracked IVC bench dump for the Lagrange scratch layout
jtcoolen Aug 6, 2026
d6b248e
Regenerate the Moonlight wrap fixture on the registered Lagrange scra…
jtcoolen Aug 6, 2026
bee1833
ci: fix changelog, formatting, and docs
jtcoolen Aug 6, 2026
07d9a9d
Cover instance binding and the two unreachable accumulator decode guards
jtcoolen Aug 7, 2026
4ae8053
docs: add independent architecture review and redesign proposals (202…
jtcoolen Aug 8, 2026
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
119 changes: 119 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,125 @@
package: midnight-zkir
args: --release --all-features

# ---------------------------------------------------------------------
# Solidity verifier generator (halo2_solidity_verifier).
#
# These three jobs are the per-PR gate. The heavy IVC proof benches and
# the release bytecode size/hash checks live in
# `.github/workflows/solidity_verifier_bench.yml`, which runs on pushes to
# `main`, on a weekly schedule, and on demand.
#
# Every job needs the pinned solc from
# `proofs/solidity-verifier/scripts/install_pinned_solc.sh`; the EVM jobs
# additionally need the Filecoin SRS that the rest of this workflow already
# caches at `zk_stdlib/examples/assets/bls_filecoin_2p19`, which is where
# the crate's `srs_dir()` looks by default.
# ---------------------------------------------------------------------
test-solidity-verifier:
if: github.event.pull_request.draft == false
name: Test Solidity verifier
runs-on: ubuntu-latest

env:
SOLC_INSTALL_DIR: ${{ github.workspace }}/.solc

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

# Codegen/layout tests compile Solidity; the heavy proof/EVM cases
# self-skip because HALO2_SOLIDITY_RUN_EVM_TESTS is unset here.
- name: Install pinned solc
run: |
echo "SOLC=$(proofs/solidity-verifier/scripts/install_pinned_solc.sh "$SOLC_INSTALL_DIR" | tail -1)" >> "$GITHUB_ENV"

- uses: ./.github/actions/cargo-test
with:
package: halo2_solidity_verifier
args: --all-features --all-targets -- --nocapture

test-solidity-verifier-evm:
if: github.event.pull_request.draft == false
needs: download-srs
name: Test Solidity verifier real EVM
runs-on: ubuntu-latest

env:
SOLC_INSTALL_DIR: ${{ github.workspace }}/.solc
HALO2_SOLIDITY_RUN_EVM_TESTS: 1

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Restore SRS from cache
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: zk_stdlib/examples/assets/bls_filecoin_2p19
key: fixed-srs-cache

- name: Install pinned solc
run: |
echo "SOLC=$(proofs/solidity-verifier/scripts/install_pinned_solc.sh "$SOLC_INSTALL_DIR" | tail -1)" >> "$GITHUB_ENV"

- name: 'Install rust-toolchain.toml'
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2

Check warning on line 216 in .github/workflows/ci.yaml

View workflow job for this annotation

GitHub Actions / scan

[LOW] Unpinned Actions Full Length Commit SHA

Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
with:
cache-on-failure: true
shared-key: "ci"

# Adversarial property tests: proof/VK/calldata mutations, non-canonical
# scalar and G1 rejection, EIP-170 runtime size, and the memoryguard
# overlap check against real compiled bytecode.
- name: Real EVM property tests
run: cargo test -p halo2_solidity_verifier --release --all-features pbt_ -- --nocapture

# End-to-end: real proof -> render -> solc -> Prague revm verification.
- name: Poseidon fixture
run: |
cargo test -p halo2_solidity_verifier --release \
--features evm,truncated-challenges --test poseidon_fixture -- --nocapture

test-solidity-verifier-trace:
if: github.event.pull_request.draft == false
needs: download-srs
name: Test Solidity verifier trace equivalence
runs-on: ubuntu-latest

env:
SOLC_INSTALL_DIR: ${{ github.workspace }}/.solc
HALO2_SOLIDITY_RUN_EVM_TESTS: 1

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Restore SRS from cache
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: zk_stdlib/examples/assets/bls_filecoin_2p19
key: fixed-srs-cache

- name: Install pinned solc
run: |
echo "SOLC=$(proofs/solidity-verifier/scripts/install_pinned_solc.sh "$SOLC_INSTALL_DIR" | tail -1)" >> "$GITHUB_ENV"

- name: 'Install rust-toolchain.toml'
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2

Check warning on line 259 in .github/workflows/ci.yaml

View workflow job for this annotation

GitHub Actions / scan

[LOW] Unpinned Actions Full Length Commit SHA

Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
with:
cache-on-failure: true
shared-key: "ci"

# Per-identity differential between the native Midfall verifier and the
# generated Solidity verifier. This is the only check that compares
# quotient VM semantics against the Rust verifier end to end.
- name: Poseidon native/Solidity trace equivalence
run: |
cargo test -p halo2_solidity_verifier --release \
--features evm,truncated-challenges,rust-verifier-trace,solidity-trace \
--lib native_midfall_verifier_trace_matches_solidity_trace -- --nocapture

doc-links:
if: github.event.pull_request.draft == false
name: Intra-doc links
Expand All @@ -175,7 +294,7 @@
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: dtolnay/rust-toolchain@nightly

Check warning on line 297 in .github/workflows/ci.yaml

View workflow job for this annotation

GitHub Actions / scan

[LOW] Unpinned Actions Full Length Commit SHA

Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
- run: rustup component add rustfmt --toolchain nightly
- run: cargo +nightly fmt --all -- --check

Expand Down
110 changes: 110 additions & 0 deletions .github/workflows/solidity_verifier_bench.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
name: Solidity verifier IVC bench

# The two IVC jobs below each generate a real recursive proof and take up to
# ~90 minutes, so they are deliberately not part of the per-PR gate in
# `ci.yaml`. The fast Solidity verifier jobs (codegen/layout tests, real EVM
# property tests, Poseidon fixture, Poseidon trace equivalence) run there on
# every pull request.
#
# Run these here on pushes to `main`, weekly, and on demand. Trigger a run
# against a branch from the Actions tab (`workflow_dispatch`) before merging a
# change to memory layout, proof layout, the quotient VM, or the templates.
on:
push:
branches:
- main
schedule:
# Mondays 04:00 UTC.
- cron: "0 4 * * 1"
workflow_dispatch:

jobs:
full-ivc-bench:
name: Full IVC bench and release bytecode sizes
runs-on: ubuntu-latest
timeout-minutes: 90

env:
SOLC_INSTALL_DIR: ${{ github.workspace }}/.solc
SRS_DIR: ${{ github.workspace }}/.srs

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

# `ensure_srs_assets.sh` fetches bls_filecoin_2p19 plus the
# midnight-srs 2p19/2p20/2p22 powers the decider proof needs.
- name: Cache SRS assets
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: .srs
key: srs-solidity-verifier-ivc-v1

- name: Install pinned solc
run: |
echo "SOLC=$(proofs/solidity-verifier/scripts/install_pinned_solc.sh "$SOLC_INSTALL_DIR" | tail -1)" >> "$GITHUB_ENV"

- name: 'Install rust-toolchain.toml'
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2

Check warning on line 49 in .github/workflows/solidity_verifier_bench.yml

View workflow job for this annotation

GitHub Actions / scan

[LOW] Unpinned Actions Full Length Commit SHA

Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
with:
cache-on-failure: true
shared-key: "ci"

- name: Ensure SRS assets
run: proofs/solidity-verifier/scripts/ensure_srs_assets.sh

- name: Full IVC bench
run: proofs/solidity-verifier/scripts/run_ivc_bench.sh --skip-srs-download

# Fails the run when a generated runtime crosses EIP-170 or when the
# published verifier/VK/quotient runtime hashes drift from the values
# recorded in docs/reference/REPRODUCIBLE_BUILDS.md.
- name: Release bytecode size/hash checks
run: proofs/solidity-verifier/scripts/check_release_bytecode_sizes.sh

- name: Upload IVC artifacts
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
if: always()
with:
name: ivc-keccak-solidity-dump
path: proofs/solidity-verifier/target/ivc-keccak-solidity-dump

ivc-trace-equivalence:
name: IVC native/Solidity trace equivalence
runs-on: ubuntu-latest
timeout-minutes: 90

env:
SOLC_INSTALL_DIR: ${{ github.workspace }}/.solc
SRS_DIR: ${{ github.workspace }}/.srs

steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd

- name: Cache SRS assets
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb
with:
path: .srs
key: srs-solidity-verifier-ivc-v1

- name: Install pinned solc
run: |
echo "SOLC=$(proofs/solidity-verifier/scripts/install_pinned_solc.sh "$SOLC_INSTALL_DIR" | tail -1)" >> "$GITHUB_ENV"

- name: 'Install rust-toolchain.toml'
run: rustup toolchain install

- uses: Swatinem/rust-cache@v2

Check warning on line 98 in .github/workflows/solidity_verifier_bench.yml

View workflow job for this annotation

GitHub Actions / scan

[LOW] Unpinned Actions Full Length Commit SHA

Pinning an action to a full length commit SHA is currently the only way to use an action as an immutable release. Pinning to a particular SHA helps mitigate the risk of a bad actor adding a backdoor to the action's repository, as they would need to generate a SHA-1 collision for a valid Git object payload. When selecting a SHA, you should verify it is from the action's repository and not a repository fork.
with:
cache-on-failure: true
shared-key: "ci"

- name: Ensure SRS assets
run: proofs/solidity-verifier/scripts/ensure_srs_assets.sh

# Compares the native Midfall verifier trace against the generated
# Solidity trace on the IVC decider proof, including quotient identity
# trace ids from the pinned external Halo2QuotientEvaluator.
- name: IVC trace equivalence
run: proofs/solidity-verifier/scripts/run_ivc_bench.sh --trace --skip-srs-download
1 change: 1 addition & 0 deletions aggregation/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://book.async.rs/overview
* truncated_challenges feature to allow --all-features compilation [#146](https://github.com/midnightntwrk/midnight-zk/pull/146)
* Rebase to new `circuits/` with `keccak` and `blake2b` [#135](https://github.com/midnightntwrk/midnight-zk/pull/135)
### Fixed
* Restore the transcript input bound required by `LightAggregator::verify`.
* Fix cost model to pass correct number of committed instances [#280](https://github.com/midnightntwrk/midnight-zk/pull/280)

### Changed
Expand Down
9 changes: 8 additions & 1 deletion aggregation/src/light_aggregator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ use midnight_proofs::{
},
EvaluationDomain,
},
transcript::{CircuitTranscript, Hashable, Sampleable, Transcript},
transcript::{
CircuitTranscript, Hashable, Sampleable, Transcript, TranscriptHash, TranscriptInputBytes,
},
};
use rand::{CryptoRng, RngCore};

Expand Down Expand Up @@ -414,6 +416,11 @@ impl<const NB_PROOFS: usize> LightAggregator<NB_PROOFS> {
C: Hashable<T::Hash>,
F: Sampleable<T::Hash> + Hashable<T::Hash>,
u32: Hashable<T::Hash>,
// Required by `plonk::prepare`, which this method delegates to. The
// bound is satisfied by both real transcript input types (`Vec<u8>`
// and `Vec<Fq>`); propagating it here mirrors the other `prepare`
// callers in `proofs/tests/plonk_api.rs`.
<T::Hash as TranscriptHash>::Input: TranscriptInputBytes,
{
// Read the LHS of the acc from the transcript.
let acc_lhs: Msm<S> = {
Expand Down
1 change: 1 addition & 0 deletions proofs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Blind logup multiplicities polynomial on non-usable rows for ZK [#312](https://github.com/midnightntwrk/midnight-zk/pull/312)

### Changed
* Rework the Solidity verifier lowering pipeline and refresh its generated fixtures.
* Simplify `CommitmentReference` by removing unused `Chopped` variant [#314](https://github.com/midnightntwrk/midnight-zk/pull/314)
* Split linearization polynomial into non-constant and constant parts, removing the generator point from the MSM [#313](https://github.com/midnightntwrk/midnight-zk/pull/313)
* Remove unnecessary polynomial padding in KZG multi-open [#276](https://github.com/midnightntwrk/midnight-zk/pull/276)
Expand Down
Loading
Loading