Skip to content
Merged
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
26 changes: 16 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache: 'pnpm'

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Check TypeScript types
run: npm run lint
run: pnpm lint

- name: Check code formatting
run: npm run format:check
run: pnpm format:check

build-typescript:
name: Build TypeScript
Expand All @@ -36,17 +38,19 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache: 'pnpm'

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Build TypeScript
run: npm run build
run: pnpm build

- name: Upload TypeScript artifact
uses: actions/upload-artifact@v4
Expand All @@ -63,14 +67,16 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache: 'pnpm'

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Download TypeScript build
uses: actions/download-artifact@v4
Expand All @@ -79,7 +85,7 @@ jobs:
path: dist/

- name: Run tests
run: npm test
run: pnpm test

all-checks:
name: All Checks Passed
Expand Down
14 changes: 8 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ jobs:
with:
fetch-depth: 0

- uses: pnpm/action-setup@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
cache: "npm"
cache: "pnpm"
registry-url: "https://registry.npmjs.org"

- name: Install dependencies
run: npm ci
run: pnpm install --frozen-lockfile

- name: Extract version from package.json
id: version
Expand All @@ -51,15 +53,15 @@ jobs:

- name: Check code formatting
if: steps.check_tag.outputs.exists == 'false'
run: npm run format:check
run: pnpm format:check

- name: Build TypeScript
if: steps.check_tag.outputs.exists == 'false'
run: npm run build
run: pnpm build

- name: Run tests
if: steps.check_tag.outputs.exists == 'false'
run: npm test
run: pnpm test

- name: Create GitHub Release and Tag
if: steps.check_tag.outputs.exists == 'false'
Expand All @@ -74,6 +76,6 @@ jobs:

- name: Publish to NPM
if: steps.check_tag.outputs.exists == 'false'
run: npm publish --access public
run: pnpm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
1 change: 0 additions & 1 deletion .husky/pre-commit

This file was deleted.

51 changes: 51 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,57 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.5.0] - 2026-04-08

### Added

- **`src/circuits/types.ts`** — circuit types extracted to their own module: `CircuitType`, `CircuitInputValue`, `CircuitInputs`, `ProofResult`, `CircuitConfig`.
- **`src/wasm/`** — universal WASM loader (`initWasm`, `compressSnarkjsProofWasm`, `generateProofFromWitnessWasm`) supporting Node.js (reads `.wasm` from disk) and browser (fetches from CDN).
- **`src/wasm/types.ts`** — `WitnessData` type.
- **`src/errors/index.ts`** — error hierarchy: `ProofGeneratorError`, `WitnessCalculationError`, `ProofGenerationError`, `CircuitNotFoundError`, `InvalidInputsError`.
- **`src/disclosure/types.ts`** — `DisclosureMask`, `DisclosureProofOutput`.
- **`src/generate/types.ts`** — `GenerateOptions` interface (public).
- **`src/generate/provider.ts`** — `resolveProvider()` (auto-detects Node.js vs browser/web worker).
- **`src/generate/backends/snarkjs.ts`** — `runSnarkjsBackend()`.
- **`src/generate/backends/arkworks.ts`** — `runArkworksBackend()` using `@orbinum/groth16-proofs` WASM.
- **`src/providers/`** — `NodeArtifactProvider`, `WebArtifactProvider` (accepts `WebProviderOptions`), `ArtifactProvider` interface.
- **`src/utils/`** — `encoding.ts`, `formatting.ts`, `validation.ts`.
- **`scripts/benchmark.ts`** — full benchmark with `PhaseResult` / `benchPhased()` and PHASE BREAKDOWN output (Load / Witness / Serialize / Prove / Compress per circuit per backend).
- **New docs**: `docs/backends.md`, `docs/usage.md`.
- **New tests**: `tests/generate/`, `tests/disclosure/`, `tests/errors/`, `tests/circuits/`, `tests/providers/`, `tests/utils/`, `tests/wasm/` — full coverage for all new modules.

### Changed

- **`@orbinum/groth16-proofs`** bumped `2.1.0` → `3.0.0`.
- `generate_proof_from_witness` now requires explicit `num_public_signals` — bug fix for heuristic that produced wrong public signal counts.
- Return type changed from `String` to typed `ProofError` enum.
- New exports: `from_decimal_str<F>`, `from_hex_le<F>`, `prove_from_witness`, `compress_snarkjs_proof`.
- Benchmark verified: no performance regression.
- **`@orbinum/circuits`** bumped `^0.4.1` → `0.4.4`.
- **`src/generate.ts`** (flat file) refactored into `src/generate/` with orchestrator, provider resolution, and two isolated backends.
- **`src/disclosure.ts`** converted to `src/disclosure/` directory.
- **`src/errors.ts`** converted to `src/errors/` directory.
- **`src/index.ts`** reorganised into explicit sections: Core API, Types, Circuits, Providers, Utils, WASM.
- Migrated from **Jest** to **Vitest** (`vitest.config.ts`).
- Migrated from **npm** / `package-lock.json` to **pnpm**.
- **`docs/api.md`** updated: `generateProof` signature reflects `GenerateOptions`; full error hierarchy; performance tables with per-circuit / per-backend times.
- **`docs/development.md`** updated: directory tree, pnpm, Vitest, architecture diagram, key source files.
- **`README.md`** updated: real benchmark numbers and phase breakdown table.

### Removed

- **`src/types.ts`** — types distributed to their respective modules.
- **`src/generate.ts`**, **`src/disclosure.ts`**, **`src/errors.ts`**, **`src/provider.ts`**, **`src/utils.ts`**, **`src/circuits.ts`**, **`src/wasm-loader.ts`** — replaced by directory-based modules.
- **`jest.config.js`**, **`lint-staged.config.js`**, **`package-lock.json`**, **`.husky/pre-commit`** — replaced by Vitest + pnpm.
- **`CircuitConfig.provingKeyPath`** — `.ark` path no longer exposed in the public interface.
- Tests under `tests/unit/` and `tests/integration/` — reorganised into module-based directories.



- **`CircuitConfig.provingKeyPath`** removed from the interface in `src/types.ts` — the `.ark` file path is no longer exposed.
- Monolithic source files replaced: `src/circuits.ts`, `src/provider.ts`, `src/utils.ts`, `src/wasm-loader.ts`.
- **Husky pre-commit hook** and **lint-staged** removed.

## [3.3.2] - 2026-03-08

### Changed
Expand Down
36 changes: 34 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[![License](https://img.shields.io/badge/License-Apache%202.0%20%7C%20GPL%203.0-blue.svg)](LICENSE)
[![Node.js](https://img.shields.io/badge/node-%3E%3D22.0.0-brightgreen.svg)](https://nodejs.org/)

Generate **128-byte Groth16 ZK-SNARK proofs** in ~6-8.5 seconds. Same TypeScript code runs identically in Node.js, browsers, Electron, and Tauri.
Generate **128-byte Groth16 ZK-SNARK proofs** in ~400ms (small circuits, post-warmup). Same TypeScript code runs identically in Node.js, browsers, Electron, and Tauri.

**New in v2.0**: Circuit artifacts and WASM modules are now installed automatically as npm dependencies (`@orbinum/circuits` and `@orbinum/groth16-proofs`). No more manual downloads!

Expand Down Expand Up @@ -43,13 +43,45 @@ console.log('Signals:', result.publicSignals); // ['0x...', ...]

## Features

- ✅ **Fast**: ~8.5s end-to-end (500ms witness + 5-8s proof)
- ✅ **Fast**: ~80ms per proof (small circuits, snarkjs backend); ~253ms with arkworks backend
- ✅ **Optimized**: Direct decimal format pipeline (no conversion overhead)
- ✅ **Compact**: 128-byte proofs (50% smaller than snarkjs)
- ✅ **Universal**: Node.js, browsers, Electron, Tauri - same code
- ✅ **Simple**: No build tools, no Rust, no setup
- ✅ **Type-Safe**: Full TypeScript types

## Performance

Benchmarked on Apple M-series (Node.js, 3 runs post-warmup):

| Circuit | snarkjs backend | arkworks backend | First call overhead |
|---------|----------------|-----------------|---------------------|
| Disclosure | ~80ms | ~253ms | +1.5–2s (WASM init) |
| PrivateLink | ~73ms | ~234ms | +1.5–2s (WASM init) |
| Unshield | ~407ms | ~2.1s | +1.5–2s (WASM init) |
| Transfer | ~1.2s | ~7.2s | +1.5–2s (WASM init) |

> **snarkjs backend** (default): uses snarkjs `fullProve` with `.zkey` proving keys — fastest option post-warmup.
>
> **arkworks backend**: uses snarkjs witness-only + arkworks WASM with `.ark` proving keys — ~3× slower for small circuits (Disclosure, PrivateLink), ~5× slower for large circuits (Unshield, Transfer). `.ark` artifacts are 2–3× smaller than `.zkey`.

The first proof call in a process incurs the WASM initialization overhead (~1.5–2s). All subsequent proofs skip this.

**Phase breakdown — where each backend spends its time (1 run):**

| Circuit | Backend | Load | Witness | Serialize | Prove | Compress | Total |
|---------|---------|------|---------|-----------|-------|----------|-------|
| Disclosure | snarkjs | 9ms | — | — | 78ms | — | 87ms |
| Disclosure | arkworks | 2ms | 20ms | 3ms | 228ms | — | 253ms |
| PrivateLink | snarkjs | 8ms | — | — | 75ms | — | 83ms |
| PrivateLink | arkworks | 2ms | 14ms | 2ms | 216ms | — | 234ms |
| Unshield | snarkjs | 21ms | — | — | 367ms | — | 388ms |
| Unshield | arkworks | 8ms | 28ms | 26ms | 1965ms | — | 2027ms |
| Transfer | snarkjs | 54ms | — | — | 1212ms | — | 1266ms |
| Transfer | arkworks | 24ms | 94ms | 101ms | 6901ms | — | 7120ms |

> `Prove` represents 97% of total time for large circuits (Unshield, Transfer). Load, witness calculation, and serialization are negligible. For arkworks, `Prove` includes PK deserialization + `Groth16::prove` inside WASM.

## Supported Circuits

| Circuit | Use Case |
Expand Down
Loading
Loading