v0.6.0-rc2 — Ceremony on a Public Transcript
Pre-releaseRelease candidate
v0.6.0-rc2 stages the multi-party trusted-setup ceremony for the unified transact circuit, and pins the circuit it will run against. The final v0.6.0 follows once the ceremony completes and its verifying key is cut into a redeployed program.
Highlights
The ceremony now starts from a public transcript. The v0.5.0 withdraw and transfer chains were phase-2 rounds built on an initial key generated on one machine. That is not the same thing as a trusted setup, and this release says so with a test rather than a caveat: src/ceremony/phase1_trapdoor.rs runs a setup while keeping the trapdoor, forges a proof for a statement with no witness, applies three real contributions, and forges the same statement again — using no contributor's secret. Phase 2 re-randomises δ and nothing else; α, β and everything derived from τ pass through untouched. The module docs claimed otherwise and have been corrected. (#662)
The path to fixing it is implemented and rehearsed end to end. The circuit exports to circom R1CS, snarkjs groth16 setup builds an initial key from the Perpetual Powers of Tau transcript, contributions and the closing beacon run in snarkjs, and the finalized key converts back to an arkworks proving key that proves a real TransactCircuitV3 spend. (#664, #665, #666, #671)
- The R1CS export needs no wire renumbering — arkworks and circom agree on layout once public outputs are zero — and the format was read off a circom-produced file rather than the spec, which settled that coefficients are plain little-endian, not Montgomery. (#665)
- Keys produced this way are circom-convention, so proof generation moves to
CircomReductionat cutover. Verification is unaffected, so the on-chain verifier is untouched by the change. (#666) - The constraint shape is pinned — 18,477 constraints, 8 public inputs, domain 2^15 — because a change mid-chain voids every contribution already made. That measurement also revealed the dev key on disk predates the input-amount range constraint and belongs to an older circuit. (#664)
CircuitIdlearned the transact circuit, appended rather than inserted: the wire format encodes variants positionally and the published transcripts pin the current indices. (#660)paraloom_ceremony_verifynow binds the initial key to the transcript, the check onlyfinalizeperformed — and the coordinator runsverifyafter every contribution. The circuit-freeze guard also watches the Poseidon gadgets, where all five of the v3 circuit's constraints actually live. (#661)
Capped-beta de-risk, from a divergence audit against an audited reference. An on-chain TVL cap bounds funds at risk and starts closed on a fresh deploy (#642). Poseidon is anchored to circomlib KATs at five widths against two implementations independent of ours (#641). The Merkle tree gained property tests over random append sequences (#644). A Pedersen generator was being derived with a known discrete log, which broke commitment binding outright — fixed with a regression test (#643).
Dual-stake. Validators lock SOL and PARALOOM together, over the Token-2022 interface the real mint uses, with a configurable floor the cold authority tunes without a redeploy (#645, #646, #647, #649). The floor now starts closed: zero passed every registration, and the code defended that default by analogy to the deposit cap, which fails the opposite way (#667, reported by kiyeps). Validator stakes are reconciled against real on-chain state rather than trusted from gossip (#646).
Off-chain hardening, largely from external reports. Co-sign requesters are authenticated against the validator set (#650); per-settlement co-sign work is capped (#602, #615, #628); compute verification fails closed when its verifying key is missing (#654); libp2p connections are bounded and idle ones reaped (#651); the off-chain quorum is stake-weighted (#617); deposit-note inputs are canonicalised (#616). Credits in docs/security-log.md.
Confidential inference. A sealed-channel worker that runs inside a GCP Confidential Space enclave, with attestation binding the channel key, so an operator sees ciphertext rather than prompts (#589, #590, #591, #595, #596). Alpha, and out of Stage 1 bounty scope.
Checks that gated nothing now gate. The eleven integration files under tests/ were compiled and never executed, so two assertions had been failing on main unnoticed — and the subsystem behind them turned out to be pre-v3 dead code whose consensus threshold was unreachable by construction (#670, #672, #674). Nothing ran cargo doc either, which is why seventeen doc links were broken, five of them pointing at modules the v3 unification deleted (#675). Both reported by wakiyamap, who also removed an unused dependency that was silently supplying tokio's test-util through feature unification (#658, #669).
Trust note (pre-mainnet — honest)
The proving keys on this build are still single-party dev keys. Everything above makes the ceremony runnable; it has not been run. Until it is, a forgery that requires the setup secret is possible for whoever generated it, and that remains an assumption you are asked to take on trust rather than verify.
The same is true, in retrospect, of the v0.5.0 withdraw and transfer ceremonies. Those chains are real and their transcripts verify, but they were built on a locally generated initial key, so "one honest contributor is enough" was never true of them. It will be true of the transact chain, because that one starts from a transcript with 54 public contributions and a beacon.
Unchanged from rc1: the on-chain quorum is not Sybil-resistant — registration is permissionless and one key is both program upgrade authority and registry admin, with no multisig or timelock. The authority key remains the trust anchor. Dual-stake and the TVL cap are merged but redeploy-gated: the deployed program predates them, so they are not in force on devnet today. A Sybil-resistant quorum, the ceremony keys, multisig with timelock, and an external audit are mainnet gates not delivered by this release.
Ceremony artefacts
transact_v3.r1cs is attached, with transact_v3.r1cs.sha256 beside it — kept separate because SHA256SUMS is cosign-signed over the binaries and appending to it would break that signature.
c468ebf1d15a82aeb7c00ece6cf714dc742b1660b8b04634b096e548a8fbe6d7 transact_v3.r1cs
It is the constraint system the ceremony runs against, and the second argument to the verification anyone can run once the chain closes:
snarkjs zkey verify transact_v3.r1cs powersOfTau28_hez_final_16.ptau <final>.zkey
It is reproducible from this tag — cargo run --release --bin export_transact_v3_r1cs — so regenerate and compare rather than trusting the copy here.
The powers-of-tau file is not mirrored; download it from the Perpetual Powers of Tau and check it against the BLAKE2b published by snarkjs:
6a6277a2f74e1073601b4f9fed6e1e55226917efb0f0db8a07d98ab01df1ccf4
3eb0e8c3159432acd4960e2f29fe84a4198501fa54c8dad9e43297453efec125
Contributor instructions are in ceremony/transact/RUNBOOK.md.
Upgrading (validators)
No re-registration yet. The dual-stake registry layout changes on the ceremony-key redeploy, which is when validators re-register against the real co-signer set and restart onto the new verifying key. This build is the one to test against until then.
Download the signed binary (linux-amd64):
curl -LO https://github.com/paraloom-labs/paraloom-core/releases/download/v0.6.0-rc2/paraloom-node-linux-amd64
curl -LO https://github.com/paraloom-labs/paraloom-core/releases/download/v0.6.0-rc2/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
chmod +x paraloom-node-linux-amd64