{"id":46039800,"url":"https://github.com/salazarsebas/stellar-zk","last_synced_at":"2026-03-01T06:09:01.842Z","repository":{"id":341273768,"uuid":"1167335437","full_name":"salazarsebas/stellar-zk","owner":"salazarsebas","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-28T20:44:41.000Z","size":136,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T23:41:32.009Z","etag":null,"topics":["developer-tools","stellar","zero-knowledge"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/salazarsebas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-26T07:22:06.000Z","updated_at":"2026-02-28T20:44:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/salazarsebas/stellar-zk","commit_stats":null,"previous_names":["salazarsebas/stellar-zk"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/salazarsebas/stellar-zk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salazarsebas%2Fstellar-zk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salazarsebas%2Fstellar-zk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salazarsebas%2Fstellar-zk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salazarsebas%2Fstellar-zk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/salazarsebas","download_url":"https://codeload.github.com/salazarsebas/stellar-zk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/salazarsebas%2Fstellar-zk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29962004,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T05:59:08.471Z","status":"ssl_error","status_checked_at":"2026-03-01T05:58:04.208Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["developer-tools","stellar","zero-knowledge"],"created_at":"2026-03-01T06:08:56.392Z","updated_at":"2026-03-01T06:08:56.962Z","avatar_url":"https://github.com/salazarsebas.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# stellar-zk\n\n**ZK DevKit for Stellar/Soroban** — unified CLI for Groth16, UltraHonk, and RISC Zero.\n\n[![CI](https://github.com/salazarsebas/stellar-zk/actions/workflows/ci.yml/badge.svg)](https://github.com/salazarsebas/stellar-zk/actions/workflows/ci.yml)\n[![crates.io](https://img.shields.io/crates/v/stellar-zk.svg)](https://crates.io/crates/stellar-zk)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![Rust](https://img.shields.io/badge/rust-1.85%2B-orange.svg)](https://www.rust-lang.org/)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md)\n\nThe easiest way to build, prove, and verify zero-knowledge proofs on the [Stellar](https://stellar.org/) network. stellar-zk orchestrates ZK proof systems for [Soroban](https://soroban.stellar.org/) smart contracts — handling circuit compilation, trusted setup, proof generation, contract deployment, and on-chain verification so you can focus on your ZK application logic.\n\nBuilt for Stellar Protocol 25, which introduced native BN254 host functions (`g1_add`, `g1_mul`, `g1_neg`, `fr_from_bytes`, `pairing_check`) enabling on-chain ZK verification within the 100M CPU instruction budget. Groth16 verification costs ~12M CPU instructions (~1,100 stroops) — just 12% of the budget.\n\n---\n\n## Table of Contents\n\n- [Features](#features)\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n- [Backends](#backends)\n- [CLI Reference](#cli-reference)\n- [Prerequisites](#prerequisites)\n- [Project Structure](#project-structure)\n- [Workflow](#workflow)\n- [Optimization Profiles](#optimization-profiles)\n- [On-Chain Verification](#on-chain-verification)\n- [Architecture](#architecture)\n- [Configuration](#configuration)\n- [Cost Estimation](#cost-estimation)\n- [Security Model](#security-model)\n- [Documentation](#documentation)\n- [License](#license)\n\n---\n\n## Features\n\n- **Three backends**: Groth16 (Circom), UltraHonk (Noir), RISC Zero (Rust zkVM)\n- **Full lifecycle CLI**: `init` -\u003e `build` -\u003e `prove` -\u003e `deploy` -\u003e `call` -\u003e `estimate`\n- **Soroban-optimized**: enforces 64 KB WASM limit and 100M CPU instruction budget\n- **Contract templates**: generated Soroban verifier contracts with BN254 pairing checks, nullifier tracking, and structured events\n- **Three-tier cost estimation**: static models, artifact-based, and on-chain simulation\n- **Optimization profiles**: development (fast builds), testnet (balanced), stellar-production (aggressive)\n- **Artifact persistence**: build artifacts link all CLI commands without manual path wiring\n- **Anti-replay protection**: SHA256-based nullifiers prevent double verification\n\n---\n\n## Quick Start\n\n```bash\n# Install (see Installation section for all options)\ncurl -fsSL https://raw.githubusercontent.com/salazarsebas/stellar-zk/main/scripts/install.sh | bash\n\n# Create a new project with Groth16\nstellar-zk init myapp --backend groth16\ncd myapp\n\n# Build circuit + verifier contract\nstellar-zk build\n\n# Generate a proof\nstellar-zk prove --input inputs/input.json\n\n# Estimate on-chain costs\nstellar-zk estimate\n\n# Deploy to testnet\nstellar-zk deploy --network testnet --source alice\n\n# Verify the proof on-chain\nstellar-zk call --contract-id CXYZ... --proof proofs/proof.bin --source alice\n```\n\n---\n\n## Installation\n\n### Pre-built binaries (recommended)\n\nDownload and install the latest release with the install script:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/salazarsebas/stellar-zk/main/scripts/install.sh | bash\n```\n\nYou can also specify a version:\n\n```bash\nSTELLAR_ZK_VERSION=0.1.0 curl -fsSL https://raw.githubusercontent.com/salazarsebas/stellar-zk/main/scripts/install.sh | bash\n```\n\nOr download binaries directly from [GitHub Releases](https://github.com/salazarsebas/stellar-zk/releases).\n\n### Homebrew (macOS / Linux)\n\n```bash\nbrew tap salazarsebas/tap\nbrew install stellar-zk\n```\n\n### crates.io\n\nRequires [Rust](https://rustup.rs/) 1.85.0+:\n\n```bash\ncargo install stellar-zk\n```\n\n### From source\n\n```bash\ngit clone https://github.com/salazarsebas/stellar-zk.git\ncd stellar-zk\ncargo install --path crates/stellar-zk-cli\n```\n\n### Verify installation\n\n```bash\nstellar-zk --help\n```\n\n### Requirements\n\n- **Stellar CLI** — for deploy/call commands ([installation guide](https://developers.stellar.org/docs/tools/developer-tools/cli/stellar-cli))\n\nBackend-specific prerequisites are listed in the [Prerequisites](#prerequisites) section below.\n\n---\n\n## Backends\n\nstellar-zk supports three proving systems, each with different trade-offs:\n\n| | Groth16 | UltraHonk | RISC Zero |\n|---|---------|-----------|-----------|\n| **Circuit language** | Circom | Noir | Rust |\n| **Proof size** | 256 bytes | ~14 KB | ~260 bytes |\n| **On-chain CPU** | ~12M instructions | ~35M instructions | ~15M instructions |\n| **Trusted setup** | Yes (per-circuit) | No (universal SRS) | No (universal) |\n| **WASM size** | ~10 KB | ~50 KB | ~10 KB |\n| **Verification** | BN254 pairing check | Sumcheck + MSM | BN254 pairing check (Groth16 seal) |\n| **Best for** | Simple proofs, lowest cost | Modern ZK apps, complex logic | Arbitrary Rust computation |\n\n### Groth16 (Circom)\n\nThe most cost-efficient option for simple circuits. Proof generation uses [Circom](https://docs.circom.io/) for circuit definition and [snarkjs](https://github.com/iden3/snarkjs) for key generation, witness computation, and proving. Requires a per-circuit trusted setup (Powers of Tau ceremony), which is generated automatically in development mode.\n\n**Proof format**: 256 bytes — `A(64) | B(128) | C(64)` (G1, G2, G1 points on BN254)\n\n### UltraHonk (Noir)\n\nA modern proving system with no trusted setup, using a universal Structured Reference String (SRS). Circuits are written in [Noir](https://noir-lang.org/), a Rust-inspired DSL. Proof generation uses [nargo](https://noir-lang.org/docs/getting_started/noir_installation/) for compilation/execution and [Barretenberg](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) (`bb`) for proving/verification.\n\n**Proof format**: ~14 KB (sumcheck proofs + commitments)\n\n### RISC Zero (zkVM)\n\nProves execution of arbitrary Rust programs. A guest program runs inside the RISC-V zkVM, producing a STARK proof that is wrapped into a ~260-byte Groth16 seal for on-chain verification. Uses [cargo-risczero](https://risczero.com/docs) for building guest programs and Docker for Groth16 wrapping.\n\n**Proof format**: 260 bytes — `selector(4) | Groth16_proof(256)` (selector identifies the circuit version)\n\n---\n\n## CLI Reference\n\n### `stellar-zk init`\n\nScaffold a new ZK project with circuit and contract templates.\n\n```bash\nstellar-zk init \u003cname\u003e [--backend \u003cbackend\u003e] [--profile \u003cprofile\u003e]\n```\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--backend` | *(interactive)* | `groth16`, `ultrahonk`, or `risc0` |\n| `--profile` | `development` | `development`, `testnet`, or `stellar-production` |\n\nCreates the project directory with:\n- Circuit/program source files\n- Soroban verifier contract template\n- Configuration files (`stellar-zk.config.json`, `backend.config.json`)\n- Input template (`inputs/input.json`)\n- Cargo.toml files (for Rust-based backends)\n\n### `stellar-zk build`\n\nCompile the circuit and generate the verifier contract WASM.\n\n```bash\nstellar-zk build [--profile \u003cprofile\u003e] [--circuit-only] [--contract-only]\n```\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--profile` | from config | Override optimization profile |\n| `--circuit-only` | `false` | Only compile the circuit |\n| `--contract-only` | `false` | Only build the WASM contract |\n\nWhat happens per backend:\n- **Groth16**: compiles Circom circuit, generates R1CS, runs trusted setup, serializes VK, builds WASM\n- **UltraHonk**: compiles Noir circuit with nargo, generates VK with bb, builds WASM\n- **RISC Zero**: compiles guest ELF, builds host binary, caches config, builds WASM\n\nOutputs are saved to `target/build_artifacts.json` for use by subsequent commands.\n\n### `stellar-zk prove`\n\nGenerate a proof from input data.\n\n```bash\nstellar-zk prove --input \u003cfile\u003e [--output \u003cfile\u003e]\n```\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--input` | *(required)* | Path to input JSON file |\n| `--output` | auto | Path for proof output |\n\nOutputs:\n- `proofs/proof.bin` or `proofs/receipt.bin` — the proof bytes\n- `proofs/public_inputs.json` — hex-encoded public inputs for the `call` command\n\n### `stellar-zk deploy`\n\nDeploy the verifier contract to a Stellar network.\n\n```bash\nstellar-zk deploy [--network \u003cnetwork\u003e] --source \u003cidentity\u003e\n```\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--network` | `testnet` | `local`, `testnet`, or `mainnet` |\n| `--source` | *(required)* | Stellar identity for signing |\n\nThe contract is deployed with the verification key passed to `__constructor(vk_bytes)`, initializing it for on-chain verification.\n\n### `stellar-zk call`\n\nInvoke the deployed verifier contract with a proof.\n\n```bash\nstellar-zk call --contract-id \u003cid\u003e --proof \u003cfile\u003e [--public-inputs \u003cfile\u003e] [--network \u003cnetwork\u003e] --source \u003cidentity\u003e\n```\n\n| Flag | Default | Description |\n|------|---------|-------------|\n| `--contract-id` | *(required)* | Deployed contract address |\n| `--proof` | *(required)* | Path to proof binary |\n| `--public-inputs` | auto | Path to public inputs (auto-detected from `proofs/public_inputs.json`) |\n| `--network` | `testnet` | Target network |\n| `--source` | *(required)* | Stellar identity |\n\nComputes `nullifier = SHA256(proof || public_inputs)` and calls `verify(proof, public_inputs, nullifier)`.\n\n### `stellar-zk estimate`\n\nEstimate on-chain verification costs.\n\n```bash\nstellar-zk estimate [--network \u003cnetwork\u003e] [--source \u003cidentity\u003e] [--contract-id \u003cid\u003e]\n```\n\nThree tiers of estimation:\n1. **Static**: offline cost models per backend (always available)\n2. **Artifact**: uses actual WASM size from build output (after `build`)\n3. **Simulation**: runs `stellar --sim-only` on the deployed contract (after `deploy`)\n\n### Global flags\n\n| Flag | Description |\n|------|-------------|\n| `--config \u003cpath\u003e` | Path to config file (default: `stellar-zk.config.json`) |\n| `-v`, `-vv`, `-vvv` | Increase log verbosity (info, debug, trace) |\n\n---\n\n## Prerequisites\n\n### All backends\n\n- [Rust](https://rustup.rs/) 1.85.0+\n- [Stellar CLI](https://developers.stellar.org/docs/tools/developer-tools/cli/stellar-cli) (for deploy and call commands)\n\n### Groth16\n\n- [Circom](https://docs.circom.io/getting-started/installation/) — circuit compiler\n- [snarkjs](https://github.com/iden3/snarkjs) — `npm install -g snarkjs`\n- [Node.js](https://nodejs.org/) — required by snarkjs\n\n### UltraHonk\n\n- [nargo](https://noir-lang.org/docs/getting_started/noir_installation/) — Noir toolchain (`noirup`)\n- [bb](https://github.com/AztecProtocol/aztec-packages/tree/master/barretenberg) — Barretenberg backend (`bbup`)\n\n### RISC Zero\n\n- [cargo-risczero](https://risczero.com/docs) — `curl -L https://risczero.com/install | bash \u0026\u0026 rzup install`\n- [Docker](https://docs.docker.com/get-docker/) — needed for Groth16 proof wrapping\n\n---\n\n## Project Structure\n\n### Workspace layout\n\n```\nstellar-zk/\n├── Cargo.toml                          # Workspace manifest\n├── crates/\n│   ├── stellar-zk-cli/                 # Binary entry point (clap)\n│   │   └── src/\n│   │       ├── main.rs                 # CLI definition + subcommand dispatch\n│   │       ├── output.rs               # Terminal formatting (colors, progress)\n│   │       └── commands/               # Subcommand implementations\n│   │           ├── init.rs             # Project scaffolding + backend factory\n│   │           ├── build.rs            # Circuit compile + WASM build\n│   │           ├── prove.rs            # Proof generation\n│   │           ├── deploy.rs           # Contract deployment via stellar CLI\n│   │           ├── call.rs             # Contract invocation + nullifier\n│   │           └── estimate.rs         # Cost estimation (3 tiers)\n│   │\n│   ├── stellar-zk-core/                # Shared library\n│   │   └── src/\n│   │       ├── backend.rs              # ZkBackend trait + types\n│   │       ├── config.rs               # ProjectConfig + BackendConfig\n│   │       ├── error.rs                # StellarZkError enum\n│   │       ├── estimator.rs            # Static cost models per backend\n│   │       ├── pipeline.rs             # WASM build pipeline (cargo -\u003e wasm-opt -\u003e strip)\n│   │       ├── profile.rs              # OptimizationProfile (3 presets)\n│   │       ├── project.rs              # Directory creation, config I/O\n│   │       ├── artifacts.rs            # BuildArtifacts persistence (JSON)\n│   │       ├── stellar.rs              # Stellar CLI wrapper (deploy, invoke, simulate)\n│   │       └── templates/\n│   │           ├── embedded.rs         # include_str! constants for all templates\n│   │           └── renderer.rs         # Handlebars template engine\n│   │\n│   ├── stellar-zk-groth16/             # Groth16 backend\n│   │   └── src/\n│   │       ├── lib.rs                  # Groth16Backend (ZkBackend impl)\n│   │       ├── circuit.rs              # Circom compilation wrapper\n│   │       ├── prover.rs               # snarkjs keygen + prove\n│   │       └── serializer.rs           # JSON decimal strings -\u003e big-endian bytes\n│   │\n│   ├── stellar-zk-ultrahonk/           # UltraHonk backend\n│   │   └── src/\n│   │       ├── lib.rs                  # UltraHonkBackend (ZkBackend impl)\n│   │       ├── nargo.rs                # nargo + bb CLI wrappers\n│   │       ├── proof_convert.rs        # Extract public inputs from proof\n│   │       └── serializer.rs           # Proof format utilities\n│   │\n│   ├── stellar-zk-risc0/               # RISC Zero backend\n│   │   └── src/\n│   │       ├── lib.rs                  # Risc0Backend (ZkBackend impl)\n│   │       ├── guest.rs                # Build guest ELF + host binary\n│   │       ├── prover.rs               # Shell out to host binary\n│   │       └── serializer.rs           # Seal validation (selector + length)\n│   │\n│   └── stellar-zk-core/templates/      # Embedded via include_str!\n│       ├── circuits/\n│       │   ├── groth16/example.circom  # Starter Circom circuit\n│       │   ├── ultrahonk/              # Nargo.toml + main.nr\n│       │   └── risc0/                  # guest/ + host/ (Cargo.toml + main.rs)\n│       ├── contracts/\n│       │   ├── groth16_verifier/       # Soroban contract (Groth16 pairing check)\n│       │   ├── ultrahonk_verifier/     # Soroban contract (KZG pairing check)\n│       │   └── risc0_verifier/         # Soroban contract (Groth16 seal verification)\n│       └── config/\n│           └── input.json.tmpl         # Starter input file\n```\n\n### Scaffolded project layout\n\nWhen you run `stellar-zk init myapp --backend groth16`, the generated project looks like:\n\n```\nmyapp/\n├── stellar-zk.config.json     # Project configuration\n├── backend.config.json        # Backend-specific settings\n├── circuits/\n│   └── main.circom            # Your circuit (Groth16)\n├── contracts/\n│   └── verifier/\n│       ├── Cargo.toml         # Soroban contract manifest\n│       └── src/lib.rs         # Verifier contract\n├── inputs/\n│   └── input.json             # Proof inputs\n├── proofs/                    # Generated proofs (after prove)\n└── target/                    # Build artifacts (after build)\n```\n\nFor RISC Zero, `circuits/` is replaced by `programs/guest/` and `programs/host/`.\n\n---\n\n## Workflow\n\nThe standard workflow follows a linear pipeline where each command produces artifacts consumed by the next:\n\n```\ninit --\u003e build --\u003e prove --\u003e deploy --\u003e call\n                    |                    |\n                    +--- estimate -------+\n```\n\n### 1. Initialize (`init`)\n\nCreates the project directory, writes configuration files, scaffolds circuit/program templates and verifier contract.\n\n### 2. Build (`build`)\n\nCompiles the circuit or program and generates the verifier contract WASM. Saves `build_artifacts.json` to `target/` so subsequent commands can locate compiled artifacts without manual path arguments.\n\nPer backend:\n- **Groth16**: `circom` compile -\u003e Powers of Tau -\u003e `snarkjs groth16 setup` -\u003e VK serialization -\u003e WASM pipeline\n- **UltraHonk**: `nargo compile` -\u003e `bb write_vk` -\u003e WASM pipeline\n- **RISC Zero**: `cargo build` guest -\u003e `cargo build` host -\u003e cache config -\u003e WASM pipeline\n\n### 3. Prove (`prove`)\n\nGenerates a zero-knowledge proof from the provided inputs. Writes the proof binary and `public_inputs.json` (hex-encoded field elements).\n\nPer backend:\n- **Groth16**: `snarkjs wtns calculate` -\u003e `snarkjs groth16 prove` -\u003e serialize to 256 bytes\n- **UltraHonk**: `nargo execute` -\u003e `bb prove_ultra_honk` -\u003e `bb verify_ultra_honk` (off-chain check)\n- **RISC Zero**: run host binary -\u003e read seal/journal/image_id -\u003e validate seal -\u003e compute journal digest\n\n### 4. Deploy (`deploy`)\n\nUploads the compiled WASM to a Stellar network and deploys the contract. The verification key is passed to the `__constructor` so it is available for all subsequent `verify()` calls.\n\n### 5. Call (`call`)\n\nInvokes the on-chain `verify()` function with the proof, public inputs, and a computed nullifier. The nullifier (`SHA256(proof || public_inputs)`) prevents the same proof from being verified twice.\n\n### 6. Estimate (`estimate`)\n\nReports estimated on-chain costs. Can be run at any point:\n- After `build`: includes actual WASM file size\n- After `deploy`: can run on-chain simulation for real resource usage\n\n---\n\n## Optimization Profiles\n\nThree preset profiles control compilation and optimization behavior:\n\n| Setting | development | testnet | stellar-production |\n|---------|------------|---------|-------------------|\n| Cargo opt-level | 0 | \"s\" | \"z\" |\n| LTO | off | thin | full |\n| wasm-opt | skip | -Os | -Oz |\n| Symbol stripping | no | no | yes |\n| WASM size limit | none | 64 KB | 64 KB |\n| CPU limit check | no | no | yes (100M) |\n\nUse `--profile` to override the project default:\n\n```bash\nstellar-zk build --profile stellar-production\n```\n\n### Soroban resource limits\n\n- **Max WASM size**: 64 KB (65,536 bytes)\n- **Max CPU instructions per tx**: 100,000,000 (100M)\n- **Max memory**: varies by network configuration\n\nThe `stellar-production` profile enforces all limits at build time and will fail if the contract exceeds them.\n\n---\n\n## On-Chain Verification\n\nAll three backends generate Soroban smart contracts that verify proofs using the BN254 elliptic curve host functions introduced in Protocol 25.\n\n### Verifier contract interface\n\nEvery generated verifier contract exposes the same interface:\n\n```rust\n// Initialize with the verification key (called at deploy time)\nfn __constructor(env: Env, vk_bytes: Bytes);\n\n// Verify a proof (the main entry point)\nfn verify(\n    env: Env,\n    proof: Bytes,           // Backend-specific proof bytes\n    public_inputs: Bytes,   // Concatenated 32-byte field elements\n    nullifier: BytesN\u003c32\u003e,  // Anti-replay token\n) -\u003e Result\u003cbool, VerifierError\u003e;\n\n// Query nullifier status\nfn is_nullifier_used(env: Env, nullifier: BytesN\u003c32\u003e) -\u003e bool;\n\n// Get total successful verifications\nfn verify_count(env: Env) -\u003e u64;\n```\n\n### Verification logic\n\n**Groth16 and RISC Zero** use the standard Groth16 pairing check:\n\n```\ne(-A, B) * e(alpha, beta) * e(vk_x, gamma) * e(C, delta) == 1\n```\n\nWhere `vk_x = IC[0] + sum(public_input[i] * IC[i+1])` is computed from the public inputs and the verification key's IC (Input Commitment) points.\n\n**UltraHonk** uses a KZG-based pairing check appropriate for the UltraHonk verification scheme.\n\n### VK format (Groth16 / RISC Zero)\n\n```\nalpha(64 bytes, G1) | beta(128 bytes, G2) | gamma(128 bytes, G2) | delta(128 bytes, G2) | ic_count(4 bytes, big-endian u32) | IC[0..n](64 bytes each, G1)\n```\n\nAll points are serialized as big-endian 32-byte coordinates (x, y for G1; x_re, x_im, y_re, y_im for G2).\n\n### Security features\n\n- **Nullifier tracking**: each proof can only be verified once (stored in persistent storage)\n- **Event emission**: every successful verification emits a `verified` event\n- **Verification counter**: contracts track the total number of successful verifications\n- **Input validation**: proof length, public input alignment, and selector checks (RISC Zero) are enforced before any cryptographic operations\n\n---\n\n## Architecture\n\n### Crate dependency graph\n\n```\n                    ┌──────────────────┐\n                    │  stellar-zk-cli  │\n                    │    (binary)      │\n                    └────────┬─────────┘\n                             │ depends on\n              ┌──────────────┼──────────────┐\n              │              │              │\n              ▼              ▼              ▼\n   ┌──────────────┐ ┌──────────────┐ ┌──────────────┐\n   │  stellar-zk  │ │  stellar-zk  │ │  stellar-zk  │\n   │   -groth16   │ │  -ultrahonk  │ │    -risc0    │\n   └──────┬───────┘ └──────┬───────┘ └──────┬───────┘\n          │                │                │\n          │  impl ZkBackend trait           │\n          │                │                │\n          └────────────────┼────────────────┘\n                           │\n                           ▼\n                  ┌──────────────────┐\n                  │  stellar-zk-core │\n                  │  (shared types,  │\n                  │   traits, config)│\n                  └──────────────────┘\n```\n\n### Data flow pipeline\n\n```\n  init              build              prove             deploy            call\n┌──────┐         ┌──────────┐       ┌──────────┐      ┌──────────┐     ┌──────────┐\n│Create│         │ Compile  │       │ Generate │      │ Upload   │     │ Invoke   │\n│ dirs,│────────▶│ circuit, │──────▶│  proof   │─────▶│ WASM +   │────▶│ verify() │\n│config│         │build WASM│       │  bytes   │      │ deploy   │     │ on-chain │\n└──────┘         └──────────┘       └──────────┘      └──────────┘     └──────────┘\n                      │                  │                                  │\n                      ▼                  ▼                                  ▼\n               build_artifacts     proof.bin +                        TX result +\n                   .json          public_inputs                        nullifier\n                                     .json\n                                                    estimate\n                                              ┌─────────────────┐\n                                              │ Static/Artifact/│\n                                              │   Simulation    │\n                                              └─────────────────┘\n```\n\n### Backend trait\n\nstellar-zk uses a trait-based backend system. Each proving system implements [`ZkBackend`](crates/stellar-zk-core/src/backend.rs):\n\n```rust\n#[async_trait]\npub trait ZkBackend: Send + Sync {\n    fn name(\u0026self) -\u003e \u0026'static str;\n    fn display_name(\u0026self) -\u003e \u0026'static str;\n    fn check_prerequisites(\u0026self) -\u003e Result\u003c(), Vec\u003cPrerequisiteError\u003e\u003e;\n    async fn init_project(\u0026self, dir: \u0026Path, config: \u0026ProjectConfig) -\u003e Result\u003c()\u003e;\n    async fn build(\u0026self, dir: \u0026Path, config: \u0026BackendConfig, profile: \u0026OptimizationProfile) -\u003e Result\u003cBuildArtifacts\u003e;\n    async fn prove(\u0026self, dir: \u0026Path, artifacts: \u0026BuildArtifacts, input: \u0026Path) -\u003e Result\u003cProofArtifacts\u003e;\n    async fn estimate_cost(\u0026self, dir: \u0026Path, proof: \u0026ProofArtifacts, build: \u0026BuildArtifacts) -\u003e Result\u003cCostEstimate\u003e;\n}\n```\n\n### Shell-out strategy\n\nAll backends shell out to external toolchains rather than linking them as Rust dependencies:\n\n- **Groth16**: `circom` (circuit compilation), `snarkjs` via Node.js (keygen, witness, proving)\n- **UltraHonk**: `nargo` (compile, execute), `bb` (VK generation, prove, verify)\n- **RISC Zero**: `cargo build` (guest/host compilation), host binary (proof generation)\n\nThis avoids heavy dependency trees (e.g., `risc0-zkvm` is ~300 MB) and compilation issues (e.g., `wasmer-wasix` doesn't compile on Rust 1.84+).\n\n### Key types\n\n```rust\n// Output of build step\npub struct BuildArtifacts {\n    pub circuit_artifact: PathBuf,      // R1CS, ACIR, or ELF\n    pub verifier_wasm: PathBuf,         // Compiled Soroban contract\n    pub proving_key: Option\u003cPathBuf\u003e,   // zkey (Groth16 only)\n    pub verification_key: PathBuf,      // Binary format for on-chain\n}\n\n// Output of prove step\npub struct ProofArtifacts {\n    pub proof: Vec\u003cu8\u003e,                 // Soroban-compatible proof bytes\n    pub public_inputs: Vec\u003c[u8; 32]\u003e,   // 32-byte big-endian field elements\n    pub proof_path: PathBuf,            // Disk location\n}\n\n// Cost estimation result\npub struct CostEstimate {\n    pub cpu_instructions: u64,\n    pub memory_bytes: u64,\n    pub wasm_size: u64,\n    pub ledger_reads: u32,\n    pub ledger_writes: u32,\n    pub estimated_fee_stroops: u64,\n    pub warnings: Vec\u003cString\u003e,\n}\n```\n\n### WASM pipeline\n\nThe build pipeline compiles and optimizes the Soroban verifier contract:\n\n1. `cargo build` with the appropriate `--release` or `--dev` profile\n2. `wasm-opt` optimization (if configured by the profile)\n3. `wasm-strip` to remove debug symbols (production only)\n4. Size validation against the 64 KB limit\n\n### Adding a new backend\n\n1. Create a new crate: `crates/stellar-zk-\u003cname\u003e/`\n2. Implement the `ZkBackend` trait\n3. Add circuit and contract templates to `crates/stellar-zk-core/templates/`\n4. Register in the CLI factory (`init.rs::create_backend`)\n5. Add to the `BackendChoice` enum in `main.rs`\n6. Add cost model to `estimator.rs`\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n---\n\n## Configuration\n\n### `stellar-zk.config.json`\n\nProject-level configuration generated by `init`:\n\n```json\n{\n  \"version\": \"0.1.0\",\n  \"project_name\": \"myapp\",\n  \"backend\": \"groth16\",\n  \"profile\": \"development\",\n  \"circuit\": {\n    \"entry_point\": \"circuits/main.circom\",\n    \"input_file\": \"inputs/input.json\"\n  },\n  \"contract\": {\n    \"name\": \"groth16_verifier\",\n    \"source_dir\": \"contracts/verifier\",\n    \"wasm_output\": \"target/wasm32v1-none/release/groth16_verifier.wasm\"\n  },\n  \"deploy\": {\n    \"network\": \"testnet\",\n    \"source_identity\": \"default\"\n  }\n}\n```\n\n### `backend.config.json`\n\nBackend-specific settings:\n\n**Groth16**:\n```json\n{\n  \"backend\": \"groth16\",\n  \"groth16\": {\n    \"curve\": \"bn254\",\n    \"trusted_setup\": null,\n    \"circuit_power\": 14\n  }\n}\n```\n\n**UltraHonk**:\n```json\n{\n  \"backend\": \"ultrahonk\",\n  \"ultrahonk\": {\n    \"oracle_hash\": \"keccak\",\n    \"recursive\": false\n  }\n}\n```\n\n**RISC Zero**:\n```json\n{\n  \"backend\": \"risc0\",\n  \"risc0\": {\n    \"guest_target\": \"riscv32im-risc0-zkvm-elf\",\n    \"segment_limit_po2\": 20,\n    \"groth16_wrap\": true\n  }\n}\n```\n\n---\n\n## Cost Estimation\n\nThe `estimate` command provides three tiers of increasingly accurate cost data:\n\n### Tier 1: Static models (offline)\n\nBaseline estimates per backend derived from the BN254 operation costs:\n\n| Backend | Base CPU | Per-input CPU | WASM size | Memory |\n|---------|----------|---------------|-----------|--------|\n| Groth16 | 10M | +500K | ~45 KB | 500 KB |\n| UltraHonk | 35M | +200K | ~55 KB | 2 MB |\n| RISC Zero | 15M | fixed | ~48 KB | 600 KB |\n\nFee estimation: `stroops = 100 + (cpu_instructions / 10,000)`\n\n### Tier 2: Artifact-based (after build)\n\nReplaces the estimated WASM size with the actual compiled contract size from build output.\n\n### Tier 3: Simulation (after deploy)\n\nRuns `stellar contract invoke --sim-only` against the deployed contract to get real resource usage from the network.\n\n---\n\n## Security Model\n\n### On-chain guarantees\n\n- **Cryptographic verification**: all proofs are verified via BN254 pairing checks using Soroban's native host functions — no custom elliptic curve arithmetic in WASM\n- **Nullifier tracking**: prevents double-spending by storing `SHA256(proof || public_inputs)` in persistent contract storage\n- **Selector validation** (RISC Zero): verifies the 4-byte seal prefix matches the expected Groth16 circuit version\n\n### Trust assumptions\n\n- **Groth16**: requires a trusted setup (Powers of Tau ceremony). In development mode, a local ceremony is generated automatically. For production, use a community-generated ceremony file\n- **UltraHonk**: no trusted setup — uses a universal SRS\n- **RISC Zero**: no trusted setup — uses a universal verification key\n\n### External tool security\n\nstellar-zk shells out to external tools (`circom`, `snarkjs`, `nargo`, `bb`, `cargo-risczero`). The security of generated proofs depends on the correctness of these tools. Always use official releases from their respective repositories.\n\n---\n\n## Documentation\n\n- **[Tutorial](docs/tutorial.md)** — Step-by-step guide to your first ZK proof on Stellar. Covers project creation, building, proving, deploying, and verifying on-chain.\n- **[USAGE.md](USAGE.md)** — Complete CLI reference with detailed examples for every command and workflow.\n- **[Troubleshooting \u0026 FAQ](docs/troubleshooting.md)** — Solutions for common errors, installation issues, and frequently asked questions.\n- **[CONTRIBUTING.md](CONTRIBUTING.md)** — Development setup and contribution guidelines.\n- **[ROADMAP.md](ROADMAP.md)** — Planned features and milestones.\n\n---\n\n## License\n\nLicensed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalazarsebas%2Fstellar-zk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsalazarsebas%2Fstellar-zk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsalazarsebas%2Fstellar-zk/lists"}