Skip to content

feat: optimize zk honk solidity verifier #20495

Draft
Maddiaa0 wants to merge 19 commits intonextfrom
md/zk-sol-opt-2
Draft

feat: optimize zk honk solidity verifier #20495
Maddiaa0 wants to merge 19 commits intonextfrom
md/zk-sol-opt-2

Conversation

@Maddiaa0
Copy link
Member

Currently at 845k to run the test

includes some optimizations to the original verifier which ill probably move into a new pr

aztec-dev and others added 14 commits February 12, 2026 18:06
Fix multiple bugs in generate_offsets.py preventing correct ZK offset
generation:
- Python boolean: true -> True
- Inverted condition: 8 if is_zk else 9 -> 9 if is_zk else 8
- Typo: FIELD_ELEMENTS_BYTES -> FIELD_ELEMENT_BYTES
- Undefined variable: after_proof_zk -> after_proof_g1_zk
- G1 point size: use GROUP_ELEMENT_BYTES (64) not 128
- VK G1 spacing: use GROUP_ELEMENT_BYTES in print_vk()
- PROOF_SIZE_LOG_N: 28 -> 15
- Sumcheck univariate loop: fix to round-major order

All 753 constants verified to match non-ZK template when is_zk=False.
…llenges

Create the ZK variant of the optimized Honk verifier template.
Copied from honk-optimized.sol.template with the following changes:

Memory layout:
- Full ZK memory layout from generate_offsets.py (is_zk=True)
- GEMINI_MASKING_POLY, LIBRA_CONCAT, LIBRA_SUM, LIBRA_EVALUATION
- LIBRA_GRAND_PRODUCT, LIBRA_QUOTIENT, LIBRA_POLY_EVAL_0..3
- GEMINI_MASKING_EVAL (entity index 0), LIBRA_CHALLENGE
- 9 barycentric denominators, 135 inverse slots

Constants:
- BATCHED_RELATION_PARTIAL_LENGTH=9, NUMBER_OF_ENTITIES=42
- NUMBER_UNSHIFTED=37, SHIFTED_COMMITMENTS_START=30
- ZK constants: SUBGROUP_SIZE, SUBGROUP_GENERATOR, etc.
- P_SUB_8 for 9th barycentric point

Proof validation:
- Pairing limbs stop at GEMINI_MASKING_POLY_X_LOC
- G1 validation covers geminiMaskingPoly, libraConcat, libraGrandProduct, libraQuotient
- Fr validation covers libraSum, geminiMaskingEval, libraEvaluation, libraPolyEvals

Challenge generation:
- Eta: includes geminiMaskingPoly (+0x40 bytes)
- Libra challenge: NEW, after gate challenges
- Sumcheck U: 9 elements per round (0x120 bytes)
- Rho: 42 evals + libraEval + 2 libra G1 (0x5e0 bytes)
- ShplonkNu: 15 gemini evals + 4 libra poly evals (0x260 bytes)

Remaining: sumcheck barycentric, ZK final check, shplemini, MSM updates.
Update sumcheck section of zk-honk-optimized.sol.template:
- 9th barycentric denominator mstore
- 9th unrolled iteration in inverse computation (index 8, P_SUB_8)
- Batch inversion backward loop stops at DENOMINATOR_8 boundary
- Initial round_target = libraChallenge * libraSum (nonzero init)
- P_SUB_8 factor added to numerator_value product
- Final check: accumulator * (1 - eval) + libraEval * libraChallenge
  where eval = product(u[2..LOG_N-1])
- Shift all batch scalar indices +1 to accommodate geminiMaskingPoly at position [1]
- Add gemini_masking_eval as first unshifted entity (37 total, was 36)
- Update shifted entity indices to BATCH_SCALAR_30..34 (was 29..33)
- Add libra polynomial batching after gemini fold loop
  - Compute 1/(shplonkZ - SUBGROUP_GENERATOR * geminiR) via modexp
  - Process 4 libra poly evals with correct denominators
  - Store 3 commitment scalars (combining scalars[1]+[2] for grand product)
- Insert geminiMaskingPoly accumulation in MSM at position [1]
- Add 3 libra commitment MSM entries (libraConcat, libraGrandProduct, libraQuotient)
- Update gemini fold loop start to BATCH_SCALAR_38_LOC (was 37)
Implements the small subgroup IPA consistency check for Libra polynomial
evaluations. Uses 24KB scratch memory (0x6000-0xBFFF) for:
- challengePolyLagrange[256]: built from sumcheck U challenges
- denominators[256]: rootPower * geminiR - 1 for each subgroup element
- batch inversion products[256]: Montgomery's trick

Validates the polynomial identity relating libraPolyEvals, libraEvaluation,
challengePolyEval, lagrangeFirst, and lagrangeLast.
Refactor sync script into a reusable sync_template() function with
--zk and --all flags. Generate BlakeOptZK.sol instance from the ZK
optimized template with correct VK values.
Add blakeOptZK.t.sol differential fuzz test and fix
LIBRA_UNIVARIATES_LENGTH (9, not 17). Template compiles
but ShpleminiFailed at pairing check - see
ZK_TEMPLATE_DEBUG_LOG.md for investigation areas.
@Maddiaa0 Maddiaa0 marked this pull request as draft February 13, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant