Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*.json
# Allow JSON files in csca_registry
!**/csca_registry/**/*.json
# Allow package.json files
!**/package.json
*.gz
*.bin
*.nps
Expand Down Expand Up @@ -43,4 +45,9 @@ Cargo.lock
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
circuit_stats_examples/
circuit_stats_examples/
# Node.js
node_modules/

# Old test directories (root level only)
/wasm-node-demo/
21 changes: 17 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ members = [
"provekit/verifier",
"tooling/cli",
"tooling/provekit-bench",
"tooling/provekit-ffi",
"tooling/provekit-gnark",
"tooling/provekit-wasm",
"tooling/verifier-server",
"ntt",
]
Expand Down Expand Up @@ -56,7 +58,6 @@ missing_docs_in_private_items = { level = "allow", priority = 1 }
missing_safety_doc = { level = "deny", priority = 1 }

[profile.release]
debug = true # Generate symbol info for profiling
opt-level = 3
codegen-units = 1
lto = "fat"
Expand All @@ -80,12 +81,14 @@ skyscraper = { path = "skyscraper/core" }
# Workspace members - ProveKit
provekit-bench = { path = "tooling/provekit-bench" }
provekit-cli = { path = "tooling/cli" }
provekit-common = { path = "provekit/common" }
provekit-common = { path = "provekit/common", default-features = true }
provekit-ffi = { path = "tooling/provekit-ffi" }
provekit-gnark = { path = "tooling/provekit-gnark" }
provekit-prover = { path = "provekit/prover" }
provekit-prover = { path = "provekit/prover", default-features = true }
provekit-r1cs-compiler = { path = "provekit/r1cs-compiler" }
provekit-verifier = { path = "provekit/verifier" }
provekit-verifier-server = { path = "tooling/verifier-server" }
provekit-wasm = { path = "tooling/provekit-wasm" }

# 3rd party
anyhow = "1.0.93"
Expand Down Expand Up @@ -126,6 +129,14 @@ tracy-client-sys= "=0.24.3"
zerocopy = "0.8.25"
zeroize = "1.8.1"
zstd = "0.13.3"
ruzstd = "0.7" # Pure Rust zstd decoder for WASM compatibility

# WASM-specific dependencies
wasm-bindgen = "0.2"
serde-wasm-bindgen = "0.6"
console_error_panic_hook = "0.1"
getrandom = { version = "0.2", features = ["js"] }
getrandom03 = { package = "getrandom", version = "0.3", features = ["wasm_js"] }

# Noir language dependencies
acir = { git = "https://github.com/noir-lang/noir", rev = "v1.0.0-beta.11" }
Expand All @@ -150,5 +161,7 @@ ark-std = { version = "0.5", features = ["std"] }
spongefish = { git = "https://github.com/arkworks-rs/spongefish", features = [
"arkworks-algebra",
], rev = "ecb4f08373ed930175585c856517efdb1851fb47" }
# spongefish-pow with parallel feature for wasm-bindgen-rayon support
spongefish-pow = { git = "https://github.com/arkworks-rs/spongefish", rev = "ecb4f08373ed930175585c856517efdb1851fb47" }
whir = { git = "https://github.com/WizardOfMenlo/whir/", features = ["tracing"], rev = "15cf6668e904ed2e80c9e6209dcce69f5bcf79b9" }
# WHIR proof system with parallel feature for wasm-bindgen-rayon support
whir = { git = "https://github.com/WizardOfMenlo/whir/", features = ["tracing"], rev = "15cf6668e904ed2e80c9e6209dcce69f5bcf79b9" }
12 changes: 12 additions & 0 deletions playground/wasm-demo/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Dependencies
node_modules/

# Generated artifacts (created by setup script)
artifacts/
pkg/
pkg-web/
noir-web/

# Build outputs
*.wasm
!src/**/*.wasm
118 changes: 118 additions & 0 deletions playground/wasm-demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# ProveKit WASM Node.js Demo

A Node.js demonstration of ProveKit's WASM bindings for zero-knowledge proof generation using the **OPRF Nullifier** circuit.

## Prerequisites

1. **Noir toolchain** (v1.0.0-beta.11):
```bash
noirup --version v1.0.0-beta.11
```

2. **Rust** with wasm32 target:
```bash
rustup target add wasm32-unknown-unknown
```

3. **wasm-pack**:
```bash
cargo install wasm-pack
```

## Setup

Run the setup script to build all required artifacts:

```bash
npm install
npm run setup
```

This will:
1. Build the WASM package (`wasm-pack build`)
2. Compile the OPRF Noir circuit (`nargo compile`)
3. Prepare prover/verifier JSON artifacts (`provekit-cli prepare`)
4. Build the native CLI for verification

## Run the Demo

```bash
npm run demo
```

The demo will:
1. Load the compiled OPRF circuit and prover artifact
2. Generate a witness using `@noir-lang/noir_js`
3. Generate a zero-knowledge proof using ProveKit WASM
4. Verify the proof using the native ProveKit CLI

## Architecture

```
┌─────────────────────────────────────────────────────────────┐
│ Node.js Demo │
├─────────────────────────────────────────────────────────────┤
│ │
│ Circuit: OPRF Nullifier │
│ ├─ Merkle tree membership proof (depth 10) │
│ ├─ ECDSA signature verification │
│ ├─ DLOG equality proof │
│ └─ Poseidon2 hashing │
│ │
│ 1. Witness Generation │
│ ├─ Input: Noir circuit + OPRF inputs │
│ └─ Tool: @noir-lang/noir_js │
│ │
│ 2. Proof Generation │
│ ├─ Input: Witness + Prover.json │
│ └─ Tool: ProveKit WASM │
│ │
│ 3. Verification │
│ ├─ Input: Proof + Verifier.pkv │
│ └─ Tool: ProveKit native CLI* │
│ │
└─────────────────────────────────────────────────────────────┘

* WASM Verifier is WIP due to tokio/mio dependency resolution
```

## Files

- `scripts/setup.mjs` - Setup script that builds all artifacts
- `src/demo.mjs` - Main demo showing WASM proof generation
- `src/wasm-loader.mjs` - Helper to load WASM module in Node.js
- `artifacts/` - Generated artifacts (circuit, prover, verifier, proofs)

## Notes

- **WASM Verifier**: Currently disabled in ProveKit WASM due to tokio/mio dependencies.
Verification uses the native CLI as a workaround.
- **JSON Format**: WASM bindings use JSON artifacts (not binary `.pkp`/`.pkv`) to avoid
compression dependencies in the browser.
- **Witness Format**: The witness map uses hex-encoded field elements as strings.
- **Circuit Complexity**: The OPRF circuit is moderately complex (~100k constraints).
Proof generation may take 30-60 seconds on modern hardware.

## Troubleshooting

### "command not found: nargo"
Install the Noir toolchain:
```bash
curl -L https://raw.githubusercontent.com/noir-lang/noirup/refs/heads/main/install | bash
noirup --version v1.0.0-beta.11
```

### "wasm-pack: command not found"
```bash
cargo install wasm-pack
```

### WASM memory errors
The OPRF circuit requires significant memory for proof generation. Increase Node.js memory limit:
```bash
NODE_OPTIONS="--max-old-space-size=8192" npm run demo
```

### Slow proof generation
The OPRF circuit is complex. On Apple Silicon (M1/M2/M3), expect ~30-60s for proof generation.
On x86_64, it may take longer. This is normal for WASM execution.
Loading
Loading