On this page

Proof Artifacts & Verification Keys

Download, host and check the files used to prove private spends and holder disclosures.

What each proof file does#

To prove a spend in the browser, load the witness-generation WebAssembly file, Groth16 proving key and JSON verification key. The browser uses the JSON key to check its proof locally, then submits the proof and public inputs. Onchain, the Pool checks them with its fixed verifier. Transactions don't upload a replacement verifying key.

Fuyu uses one private-spend relation and two holder-audit step relations. spend/admission.circom handles private transfers, consolidation, withdrawals and admitted actions with 39 public inputs. owned-notes-4.circom processes four padded note slots per audit step. spend-records-8.circom processes eight padded authenticated spend records. An independent verifier checks holder audit answers offchain against finalized history.

The app checks each artifact's SHA-256 before loading it. You can move a file to another CDN or static host, provided the bytes match and the app accepts the deployment and artifact settings. Treat the download URL as a location and the digest as the file identity.

From an audit question to a verified answer
From an audit question to a verified answer

Private-spend files and hashes#

The source and public API configuration list the same digests for these three spend files. During the check, GET requests for the WASM and proving key succeeded with the sizes below. We closed those streams after the first 16 bytes. We downloaded the whole JSON verification key and confirmed its SHA-256. The large files' listed hashes come from the source and configuration; we didn't rehash their full hosted downloads.

The proving key's source filename is TEST-ONLY-UNISWAP-SETTLEMENT.zkey. Use it with the configured routes. The Pool and runtime still check the route, public context, controller approvals and token effects, so the filename doesn't grant permission to execute arbitrary Uniswap calls.

Role and service pathExpected bytesSHA-256
Witness program · /artifacts/queue-private.wasm2583534f2359cf11cc8a1708fb57b7b27989662f59ed9ec065985d49c0d0237317afad0
Proving key · /artifacts/queue-private.zkey68769773bfcf453c294e56fc37d38a3d1af25eb7e56e7e5df0c9d4de9f4e571bd04440dd
Local verification key · /artifacts/queue-private-vk.json98873f0d7f8bcafceb54c3a452156d3cbc15c4414955c3b1ff0d64d9719d6be69a8e

Holder-audit files and hashes#

The audit companion serves the six files below from the directories you configure. Git LFS stores four large WASM and proving-key files under circuits/owned-notes/artifacts. The two JSON verification keys are under apps/privacy/public/audit-keys. Their paths and hashes are listed in apps/privacy/runtime/audit-artifacts-manifest.json.

The holder worker checks the proving files before using them. The independent verifier checks the verification-key bytes for the audit relation. Keep these checks separate from the Pool's spend verification: an audit answer uses its own relations, artifacts and offchain verification flow.

Manifest pathSHA-256
owned-notes-4_js/owned-notes-4.wasmb0c7db68d0a6f0da7d975d41cd3338e6db656b4ee7f8739bfd1390fab705b463
TEST-ONLY-owned-notes-4.zkey323b4a50d8f82e1f90ed8550170376f8ffc2f55cae0b64ca474a5673744ffabf
TEST-ONLY-owned-notes-4-vk.jsonb244f82bf1b564987e5528c2adf3e51372651ced4526d378035e29a8df25ed54
spend-records-8_js/spend-records-8.wasmb0ea4ce8280cb6105642dc87181e728a1cb658bb552a181ea6c8e89a50ce4906
TEST-ONLY-spend-records-8.zkey813b24cbfde966b9bc6922655b64909961e5f0a94d897829755162d4c50c8612
TEST-ONLY-spend-records-8-vk.json457307e28269e2cb0def19f894ef6dfa0329c58c5e3fa1a5ea8ad83a992c4307

Check the files, relation and onchain key#

Pull Git LFS files before hashing artifacts. Otherwise, you may be looking at a pointer instead of the proving key. Check the circuit include graph with circuits/source-artifact-manifest.json, run the repository artifact checker, and read Pool.VK_HASH() for the deployed verifier.

The onchain verification-key Keccak-256 is 0x9be4fc098eacb83c4f84f0bca3a466803158f921960f8ac2981372aadd49352d. It hashes the canonical verifier-key encoding. The JSON file has a separate SHA-256, so compare each value with the format expected by the browser, exporter or contract you're checking.

Run artifact and circuit verification on the Linux development host. A successful key-to-relation check confirms which compiled relation and transcript the key uses. Then run the application checks you need for your change and keep the setup records with the result.

bash
# Run in the protocol checkout on the Linux development host.
git lfs pull
python3 scripts/check-artifacts.py
node circuits/scripts/check-sources.cjs
node apps/privacy/runtime/audit-artifacts.cjs check \
  --directory "$PWD/circuits/owned-notes/artifacts" \
  --keys "$PWD/apps/privacy/public/audit-keys"

Test-key setup#

These checked-in keys are test-only. The circuit documentation records single-party phase-two contributions over the public ppot_0080_17.ptau transcript, size 2^17, SHA-256 f807e065fde53f72f4bf4d57140fab85b26daa6cc95bdfec7cce93622b3a367c. Keep the setup identified as a test contribution when distributing the files or deploying an app that uses them.

Keep that label visible in the development app. Compilation checks the relation, snarkjs zkey verify checks the key against its relation and transcript, and onchain key checks compare the deployed verifier. A successful testnet spend confirms that transaction's verification. These checks don't add contributors to the single-party setup or create a production ceremony.

Serve and cache verified artifacts#

For disclosure development, start the loopback artifact companion with all six files. It checks their hashes before listening, serves only the allowed paths and rejects a file if it changes. If you use a separate host, set the artifact base URL in the app and allow the app's origin in the host's CORS configuration.

The app caches spend artifacts by SHA-256 and rehashes entries when it reads them. It discards a mismatched entry and downloads it again. Prefetch can run while account history is recovering; if the user starts proving before the download finishes, they still wait for the remaining bytes. Keep account secrets, recovery words and private witnesses out of this public cache.

bash
node apps/privacy/runtime/audit-artifacts.cjs serve \
  --directory "$PWD/circuits/owned-notes/artifacts" \
  --keys "$PWD/apps/privacy/public/audit-keys" \
  --port 8799
# In a second Linux terminal:
FUYU_AUDIT_ARTIFACTS_SERVER=http://127.0.0.1:8799 \
  npm --prefix apps/privacy run preview

Export a service-independent bundle#

The static exporter reads public deployment state at one anchor block and checks the contracts and proving files. It writes deployment.json and hash-named artifacts to a fresh directory, leaving out RPC credentials, demo accounts, process IDs and private account material. When opening the app, supply the SHA-256 of the deployment JSON you intend to use.

The source recovery entry sepolia-8af98425 lists deployment JSON SHA-256 a6fcfabb28d713a212ff12e2b4df602d64ec5d04125e88bb7b091f47ff9ce9ad and checked block 11812907. Download it from the host you plan to use and check its hash. The expected app-host URL returned 404 during the documentation check, so confirm a reachable copy before depending on this bundle for recovery.

bash
node apps/privacy/runtime/queue-static-deployment.cjs \
  --config /absolute/path/to/runtime/config.json \
  --out /absolute/path/to/fresh-bundle
# Serve the exported directory with the required CORS policy.
# Open the matching app with:
# ?deployment=<deployment.json URL>&deploymentSha256=<printed SHA-256>