- Receive
contribution_urls.jsonfrom coordinator - Run:
cd contributor
./contribute.sh contribution_urls.json- When you're done, delete the files and wipe RAM — eg by shutting down machine and disconnecting from power.
Steps:
git clone https://github.com/lightprotocol/bmt-setup-ceremony
cd bmt-setup-ceremony
# One command:
# This builds the verifier (if needed) and verifies your latest contribution using saved offline inputs
make_verifier() { test -x semaphore-mtb-setup/semaphore-mtb-setup || (cd semaphore-mtb-setup && go build -o semaphore-mtb-setup .); }
make_verifier && contributor/verify_local.sh
# Optional: compare per-circuit hashes against a published attestation file
# Example: if the coordinator published 0003_swen_hashes.txt
# contributor/verify_local.sh "" "" path/to/0003_swen_hashes.txt
# Compare your local hashes.txt with what the coordinator publishes
HASH_FILE=contributor/ceremony_contribution_*/output/contribution_hashes.txt
echo "Your SHA256: $(shasum -a 256 $HASH_FILE | awk '{print $1}')"
echo "Coordinator's SHA256: <paste here>"If your presigned read-access URLs have expired, reach out via DM or on Discord.
Attest your contribution:
# The contributor script prints and writes hashes to this file
HASH_FILE=contributor/ceremony_contribution_*/output/contribution_hashes.txt
# Keep a local copy and optionally publish a public attestation:
# 1) Create a GitHub Gist and share the link; or
# 2) Open a PR adding the file under attestations/<your_contribution_id>/; or
# 3) Publish the file hash:
shasum -a 256 $HASH_FILEcd coordinator
# Set up service account for URL signing
./create_key.sh <bucket-name>
# Initialize ceremony (generates R1CS and initial contribution)
./init.sh# Upload to Google Cloud Storage
./upload.sh
# Verify upload
gsutil ls gs://<bucket>/ceremony/contributions/0000_initial/ | head -5For each contributor in sequence:
# Generate presigned URLs for contributor (all versions)
./generate_urls.sh <bucket> alice 0000_initial all
# → Creates 0001_alice_urls.json
# Send JSON file to Alice securely
# Wait for Alice to complete contribution
# Verify the contribution
./verify.sh 0001_alice
# If verification passes, continue to next contributor
# Generate presigned URLs for next contributor (all versions)
./generate_urls.sh <bucket> bob 0001_alice all
# → Creates 0002_bob_urls.jsonAfter the final contribution:
# Extract proving and verification keys and build .key files
# Usage:
# ./finalize.sh [contribution_id] [version]
# Example:
# ./finalize.sh 0003_swen v2
./finalize.sh XXXX_final_contributor
# Keys will be in ../proving-keys/
# Option to upload to GCS when prompted- Share final keys publicly
- Publish all contributions for transparency
- Create attestation document with contributor list
init.sh → upload → generate_urls.sh → [wait] → verify.sh → repeat → finalize.sh
coordinator/
├── init.sh # Initialize ceremony from R1CS
├── generate_urls.sh # Create presigned URLs for contributor
├── verify.sh # Verify contributions
└── finalize.sh # Extract pk/vk and build .key files
contributor/
└── contribute.sh # Run contribution with URLs file
-
89 total circuits
- V1: 30 circuits (tree height 26)
- V2: 56 circuits (tree heights 32/40)
- Batch: 3 circuits (batch operations)
-
PTAU sizes
- PTAU 19 for V1/V2 circuits
- PTAU 24 for batch circuits
Coordinator:
light-protocol/prover/server(Go project) to build .key filesgotoolchain (for running light-prover import-setup)gsutil(Google Cloud SDK) for GCS operations (keep keys safe; never commit them)jq(required when using generate_urls.sh with VERSION=all)
Contributor:
jq(auto-installed if missing)go(to build semaphore-mtb-setup)