Groth16 proving flows for ID-related circuits, with proof posting to XRPL and on-chain verification.
- Allowed: age ≥ 16 check from DOB.
- VerifySign: ECDSA P‑256 signature verification (6×43-bit limb encoding).
- Freshness: nonce + expiration freshness check.
- Full: composite of Allowed + VerifySign + Freshness.
| Module | # Constraints | # Wires | Prover runtime (s) | Proof JSON size (bytes) | Max RSS (MB) |
|---|---|---|---|---|---|
| Allowed | 121 | 124 | 4.82 | 806 | 63.75 |
| Freshness | 74 | 75 | 4.37 | 803 | 61.98c |
| VerifySign | 2,205,407 | 2,190,922 | 115.89 | 803 | 57.25 |
| Full | 2,205,606 | 2,191,121 | 113.21 | 806 | 60.88 |
- Circom, SnarkJS, circomlib.
circom-ecdsa-p256cloned in the repo root (with itscircom-pairingsubmodule installed).- Python 3;
xrpl-py(seerequirements.txt). For key-based signing in VerifySign/Full, installcryptography.
git submodule update --init --recursive
pip3 install -r requirements.txt
# Create node_modules symlink for circomlib (required for circom-ecdsa-p256)
mkdir -p node_modules
ln -sf ../circomlib node_modules/circomlib
cd circom-ecdsa-p256/circuits
yarnUse build_setup_multi.py to compile a circuit and produce setup/<Circuit>/ artifacts:
python3 build_setup_multi.py -c Allowed
python3 build_setup_multi.py -c VerifySign
python3 build_setup_multi.py -c Freshness
python3 build_setup_multi.py -c FullArtifacts: <Circuit>_js/<Circuit>.wasm, <Circuit>_final.zkey, <Circuit>_verification_key.json under setup/<Circuit>/.
prover.py builds the witness, proves with Groth16, compresses proof/public, and posts them as XRPL memos.
Common inputs:
--raw-id: raw ID JSON (for Allowed and Full).--vs-json: optional prebuilt VerifySign witness JSON. If omitted,--vs-priv/--vs-pub+--raw-idare used to sign and build VerifySign witness.--fresh-json: freshness input JSON (expectedNonce/nonce/holderTimestamp/validUntil).- Paths (
--wasm/--zkey/--winput/--wtns/--proof/--public) default tosetup/<Circuit>/.... --label: memo label (defaultGroth16-Proof).
Example:
python3 prover.py -c AllowedOnly
python3 prover.py -c VerifySignOnly
# For Freshness, use a future timestamp for validUntil (e.g., current time + 24 hours)
# Calculate timestamp: python3 -c "import time; print(int(time.time()) + 86400)"
python3 prover.py -c FreshnessOnly --fresh-nonce 123456789 --fresh-valid-until $(python3 -c "import time; print(int(time.time()) + 86400)")
python3 prover.py -c Full --fresh-nonce 123456789 --fresh-valid-until $(python3 -c "import time; print(int(time.time()) + 86400)")verifier.py fetches memos by tx hash, reconstructs proof/public, and runs snarkjs groth16 verify.
python3 verifier.py --module Allowed <tx_hash>
python3 verifier.py --module VerifySign <tx_hash>
python3 verifier.py --module Freshness <tx_hash>
python3 verifier.py --module Full <tx_hash>util/make_dummy_id_and_signature.py generates a fresh P‑256 keypair (private.pem, public.pem) under test_inputs/dummy_id1/.