UNPKG

lambdaworks-groth16-ts

Version:

TypeScript bindings for LambdaWorks Groth16 SNARK prover

362 lines (241 loc) 9.51 kB
# 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 ```bash npm install lambdaworks-groth16-ts ``` ## Quick Start ```typescript 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 generation - `verifier: Groth16Verifier` - Proof verification - `setupManager: TrustedSetupManager` - Trusted setup handling - `fieldOps: FieldOperations` - Field arithmetic operations - `circuitProcessor: 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 ```bash # 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 test ``` ### Project 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 examples ``` ## Advanced Usage ### Using with React ```typescript 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 ```typescript 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 ```typescript // 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. ```typescript // ❌ 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: ```typescript // 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 1. Fork the repository 2. Create feature branch: `git checkout -b feature/amazing-feature` 3. Commit changes: `git commit -m 'Add amazing feature'` 4. Push to branch: `git push origin feature/amazing-feature` 5. Open Pull Request ## Testing ```bash # Run all tests npm test # Run specific test suite npm test -- --testNamePattern="Prover" # Run with coverage npm test -- --coverage ``` ## Benchmarks 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](LICENSE) for details. ## Acknowledgments - [LambdaClass](https://lambdaclass.com) for the core Rust implementation - [Circom](https://circom.io) for circuit compilation tools - [SnarkJS](https://github.com/iden3/snarkjs) for inspiration on API design --- **Package Maintenance Status**: 🟢 Actively maintained For issues and support, please visit our [GitHub repository](https://github.com/your-org/lambdaworks-groth16-ts).