lambdaworks-groth16-ts
v0.5.0
Published
TypeScript bindings for LambdaWorks Groth16 SNARK prover
Maintainers
Readme
lambdaworks-groth16-ts
LambdaWorks Groth16 TypeScript Package
A high-performance TypeScript wrapper for LambdaWorks Groth16 SNARK prover, compiled to WebAssembly for browser and Node.js environments.
Features
- Fast Groth16 Implementation: Built on LambdaWorks' optimized Rust implementation
- WebAssembly Performance: Near-native performance in browsers and Node.js
- TypeScript Support: Full type safety and excellent developer experience
- Cross-Platform: Works in browsers, Node.js, and React Native
- Circom Compatible: Direct integration with Circom circuit compiler
- Production Ready: Memory-safe Rust implementation with comprehensive testing
Installation
npm install lambdaworks-groth16-tsQuick Start
import LambdaWorksGroth16 from 'lambdaworks-groth16-ts';
async function example() {
// Initialize the library
const groth16 = await LambdaWorksGroth16.init();
// Load circuit from Circom
const r1csData = await fetch('./circuit.r1cs').then(r => r.arrayBuffer());
const wasmData = await fetch('./circuit.wasm').then(r => r.arrayBuffer());
const circuit = await groth16.circuitProcessor.loadFromCircom(
new Uint8Array(r1csData),
new Uint8Array(wasmData)
);
// Generate trusted setup (for testing - use ceremony setup in production)
const setup = groth16.setupManager.generateUnsafeSetup(circuit);
// Generate proof
const inputs = { x: "123", y: "456" };
const proof = await groth16.prover.proveWithInputs(circuit, setup.provingKey, inputs);
// Verify proof
const witness = groth16.circuitProcessor.computeWitness(circuit, inputs);
const isValid = groth16.verifier.verify(setup.verifyingKey, witness.publicInputs, proof);
console.log('Proof valid:', isValid);
}API Reference
LambdaWorksGroth16
Main class providing access to all Groth16 functionality.
static async init(wasmPath?: string): Promise<LambdaWorksGroth16>
Initialize the library. Automatically detects browser/Node.js environment.
wasmPath: Optional custom path to WASM file
Properties
prover: Groth16Prover- Proof generationverifier: Groth16Verifier- Proof verificationsetupManager: TrustedSetupManager- Trusted setup handlingfieldOps: FieldOperations- Field arithmetic operationscircuitProcessor: CircuitProcessor- Circuit loading and witness computation
CircuitProcessor
Handle circuit loading and witness computation.
loadFromCircom(r1cs: Uint8Array, wasm: Uint8Array): Promise<Circuit>
Load a circuit compiled with Circom.
computeWitness(circuit: Circuit, inputs: Record<string, string>): Witness
Compute witness for given circuit inputs.
validateWitness(circuit: Circuit, witness: Witness): boolean
Validate that witness satisfies circuit constraints.
TrustedSetupManager
Manage trusted setup parameters.
generateUnsafeSetup(circuit: Circuit): TrustedSetup
⚠️ WARNING: Only for testing! Generate unsafe trusted setup.
loadSetup(powersOfTau: Uint8Array, circuitSetup: Uint8Array): Promise<TrustedSetup>
Load trusted setup from ceremony files.
exportVerifyingKey(setup: TrustedSetup): string
Export verifying key for on-chain verification.
Groth16Prover
Generate Groth16 proofs.
prove(circuit: Circuit, provingKey: ProvingKey, witness: Witness): Promise<Proof>
Generate proof from circuit, proving key, and witness.
proveWithInputs(circuit: Circuit, provingKey: ProvingKey, inputs: Record<string, string>): Promise<Proof>
Generate proof directly from inputs (computes witness automatically).
exportProof(proof: Proof, format: 'json' | 'solidity' | 'bytes'): string | Uint8Array
Export proof in different formats for various use cases.
Groth16Verifier
Verify Groth16 proofs.
verify(verifyingKey: VerifyingKey, publicInputs: FieldElement[], proof: Proof): boolean
Verify a single proof.
batchVerify(verifyingKey: VerifyingKey, proofData: ProofData[]): boolean[]
Efficiently verify multiple proofs.
FieldOperations
Low-level field arithmetic operations.
fromHex(hex: string): FieldElement
Create field element from hex string.
add(a: FieldElement, b: FieldElement): FieldElement
Add two field elements.
multiply(a: FieldElement, b: FieldElement): FieldElement
Multiply two field elements.
Building from Source
Prerequisites
- Rust 1.70+
- Node.js 18+
- wasm-pack
Build Steps
# Clone repository
git clone https://github.com/your-org/lambdaworks-groth16-ts
cd lambdaworks-groth16-ts
# Install dependencies
npm install
# Build WASM module
npm run build:wasm
# Build TypeScript
npm run build:ts
# Run tests
npm testProject Structure
├── src/ # TypeScript source
│ ├── index.ts # Main exports
│ ├── types.ts # Type definitions
│ ├── prover.ts # Prover implementation
│ ├── verifier.ts # Verifier implementation
│ └── ...
├── rust-src/ # Rust WASM wrapper
│ ├── Cargo.toml # Rust dependencies
│ └── src/lib.rs # WASM bindings
├── pkg/ # Generated WASM files
├── dist/ # Compiled TypeScript
└── examples/ # Usage examplesAdvanced Usage
Using with React
import { useEffect, useState } from 'react';
import LambdaWorksGroth16 from 'lambdaworks-groth16-ts';
function ProofGenerator() {
const [groth16, setGroth16] = useState<LambdaWorksGroth16 | null>(null);
const [proof, setProof] = useState<string | null>(null);
useEffect(() => {
LambdaWorksGroth16.init().then(setGroth16);
}, []);
const generateProof = async () => {
if (!groth16) return;
// Load your circuit and generate proof
const inputs = { secret: "42" };
const proof = await groth16.prover.proveWithInputs(circuit, provingKey, inputs);
setProof(groth16.prover.exportProof(proof, 'json'));
};
return (
<div>
<button onClick={generateProof} disabled={!groth16}>
Generate Proof
</button>
{proof && <pre>{proof}</pre>}
</div>
);
}Integration with Ethereum
import { ethers } from 'ethers';
// Export proof for Solidity verification
const solidityProof = groth16.prover.exportProof(proof, 'solidity');
const vkJson = groth16.setupManager.exportVerifyingKey(setup.verifyingKey);
// Call verifier contract
const contract = new ethers.Contract(verifierAddress, verifierABI, signer);
const isValid = await contract.verifyProof(
solidityProof[0], // a
solidityProof[1], // b
solidityProof[2], // c
publicSignals
);Performance Optimization
// Preload WASM for faster initialization
const wasmPromise = LambdaWorksGroth16.init();
// Use batch verification for multiple proofs
const results = groth16.verifier.batchVerify(vk, proofBatch);
// Reuse proving key for multiple proofs
const pk = setup.provingKey;
const proof1 = await groth16.prover.prove(circuit, pk, witness1);
const proof2 = await groth16.prover.prove(circuit, pk, witness2);Security Considerations
Trusted Setup
⚠️ CRITICAL: Never use generateUnsafeSetup() in production. Always use setup parameters from a trusted ceremony.
// ❌ DON'T DO THIS IN PRODUCTION
const setup = groth16.setupManager.generateUnsafeSetup(circuit);
// ✅ Use ceremony setup instead
const powersOfTau = await loadCeremonyFile('powers_of_tau.ptau');
const setup = await groth16.setupManager.loadSetup(powersOfTau, circuitSetup);Input Validation
Always validate inputs before proof generation:
// Validate circuit constraints
if (!groth16.circuitProcessor.validateWitness(circuit, witness)) {
throw new Error('Invalid witness');
}
// Sanitize user inputs
const sanitizedInputs = Object.fromEntries(
Object.entries(userInputs).map(([k, v]) => [k, sanitizeFieldElement(v)])
);Supported Curves
- BN254 (bn128) - Default, Ethereum compatible
- BLS12-381 - High security applications
Browser Compatibility
- Chrome 57+
- Firefox 52+
- Safari 11+
- Edge 16+
Node.js Compatibility
- Node.js 14+
- Full ESM and CommonJS support
Contributing
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'Add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open Pull Request
Testing
# Run all tests
npm test
# Run specific test suite
npm test -- --testNamePattern="Prover"
# Run with coverage
npm test -- --coverageBenchmarks
Performance on various platforms:
| Platform | Proof Generation | Verification | |----------|------------------|--------------| | Chrome M1 Mac | ~2.1s | ~15ms | | Node.js x64 | ~1.8s | ~12ms | | Firefox x64 | ~2.4s | ~18ms |
Benchmarks for 2^16 constraint circuit
License
MIT License - see LICENSE for details.
Acknowledgments
- LambdaClass for the core Rust implementation
- Circom for circuit compilation tools
- SnarkJS for inspiration on API design
Package Maintenance Status: 🟢 Actively maintained
For issues and support, please visit our GitHub repository.
