research: Poseidon2 hash swap (REJECT) + adopt circom --O2 (KEEP) - #40
Open
alexandre-mrt wants to merge 1 commit into
Open
research: Poseidon2 hash swap (REJECT) + adopt circom --O2 (KEEP)#40alexandre-mrt wants to merge 1 commit into
alexandre-mrt wants to merge 1 commit into
Conversation
Queue item #2. Built and measured a Poseidon2 swap at the two hash arities (t=3 Merkle path, t=4 amount/nullifier hashes) with a verified BN254 parameterization; t=5/t=6 (the majority of hash call-sites) have no audited parameter set in any reachable package, so left unchanged. Result: worse constraints at circom's --O1 default (+11-14%), a wash at --O2 (+0.1-0.2%). Hypothesis falsified — parked as circuits/experiments/poseidon2/, not adopted. Measuring it honestly surfaced that Veil's own compile scripts were using circom's --O1 default instead of --O2 (full constraint simplification): ~53% fewer total constraints, ~23% faster Node proving time (transfer/ compliance), zero semantic change (108/108 existing circuit tests pass identically, same negative-test behavior). Adopted: compile*.sh now pass --O2; BASELINE.md/README/threat-model/SPEC updated with the new numbers. On-chain gas remains BLOCKED (3rd attempt) — root-caused this time to an egress-policy denial on both github.com release downloads and direct JSON-RPC to the testnet fullnode; re-ranked to stay #1 in EXPERIMENTS.md with the precise cause recorded for the next attempt. Full report: docs/research/2026-08-22-poseidon2-hash-swap.md Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018ghjBHmo2fhx7fETkBcA41
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Queue item #2 (
docs/research/EXPERIMENTS.md). Full report:docs/research/2026-08-22-poseidon2-hash-swap.md.Hypothesis: swapping circomlib's Poseidon for Poseidon2 at the hash arities with a verified
BN254 parameterization (t=3, the depth-20 Merkle path; t=4, amount/nullifier/context-binding
hashes) reduces R1CS constraints and Groth16 proving time.
Result: falsified.
--O1(circom default)--O2(full simplification)transfer.circomtotal constraints, Poseidon → Poseidon2compliance.circomwithdraw.circomWorse at
--O1, a wash at--O2. Built and cross-validated anyway(
circuits/experiments/poseidon2/,circuits/vendor/poseidon2/— vendored from@taceo/circom-libMIT, round constants trace to the HorizenLabs reference generator), with asoundness/leakage writeup and 8/8 new tests including malicious-witness negative tests
(
circuits/test/poseidon2-experiment.test.mjs). Not adopted — knowledge kept, not wired intocontracts/. t=5/t=6 (the majority of hash call-sites — both commitments and both nullifiers)have no audited BN254 Poseidon2 parameter set in any package reachable this session, and I didn't
derive my own for a hash securing commitments.
The actual find: measuring this exposed that Veil's
circuits/scripts/compile*.shwere usingcircom's
--O1default (only signal/constant simplification), not--O2(full constraintsimplification). Switching:
transfer/compliance), ~5% (withdraw)pass identically against the new O2 artifacts, including every existing negative test.
Adopted:
compile.sh/compile-withdraw.sh/compile-compliance.shnow pass--O2.BASELINE.md,README.md,docs/threat-model.md,docs/SPEC.md,docs/architecture.mdupdatedwith the new constraint counts (old O1 numbers kept alongside for the delta, not deleted).
Deployment note: switching optimization level changes every circuit's verifying key (different
R1CS layout → different zkey trapdoor → different
vk.json, same statement).compliance.move's1-epoch VK-update timelock applies whenever these circuits are actually redeployed — this PR only
touches local dev-build artifacts, not any live testnet contract state.
On-chain gas — still BLOCKED, third attempt. Root-caused precisely this time: this session's
egress policy denies both
github.comrelease-asset downloads and direct JSON-RPC tofullnode.testnet.sui.io(403on both), but permitsgit clone/ls-remoteagainstgithub.comitself (howcircomgets built from source each session).suihas no crates.iopackage. Stays #1 in
EXPERIMENTS.mdwith this root cause recorded for next time.Test plan
node --experimental-vm-modules test/{transfer,compliance,withdraw}.test.mjs— 43+30+35 =108/108 pass against the new
--O2build artifacts (same counts as before, same negativetests)
node --experimental-vm-modules test/poseidon2-experiment.test.mjs— 8/8 pass (correctnesscross-check vs
@taceo/poseidon2JS reference + malicious-witness negative tests per variantcircuit)
bun run src/test-converter.ts— 109/109 passbun run src/test-compliance-utils.ts— 67/67 passbunx vitest run(frontend) — 19/19 passbun run src/fuzz-tests.ts— 6/6 properties pass (500 cases each)cd contracts && sui move test— NOT RUN,suiCLI unavailable this session (see above;no contract code changed in this PR, so risk is low, but this is a real gap, not a passing
claim)
Generated by Claude Code