| WASM wrapper library for KZG/EIP-4844/PeerDAS functionality. |
|---|
This module implements a JS wrapper around a WASM compilation of the c-kzg-4844 C library built for use with EIP-4844. Starting with v1.0.0, the library also support cell-based operations in the context of EIP-7594 (PeerDAS).
This library is produced by building the original C code to WASM using the empscripten toolchain in this fork of c-kzg-4844.
If you are looking for a pure JS implementation of KZG/EIP-4844/PeerDAS functionality, check out the micro-eth-signer library. For a comparison on how these libraries roughly compare in terms of performance, see the Performance Comparison section.
This module exposes a single export, an async function called loadKZG which loads and compiles the WASM object, loads a trusted setup (defaults to the official setup from the KZG ceremony) and returns an object that exposes the API defined in the KZG type interface in @ethereumjs/util
To use with the @ethereumjs libraries, do the following:
import { loadKZG } from 'kzg-wasm'
import { Common, Chain, Hardfork } from '@ethereumjs/common'
const main = async () => {
const kzg = await loadKZG()
const common = new Common({
chain: Chain.Mainnet,
hardfork: Hardfork.Cancun,
customCrypto: { kzg },
})
console.log(common.customCrypto.kzg) // Should print the initialized KZG interface
}
main()The loadKZG() function returns an object that implements the KZG interface with the following methods:
loadTrustedSetup(trustedSetup: TrustedSetup = mainnetTrustedSetup, precompute: number = 0): numberLoads a trusted setup for KZG operations. Returns 0 on success, non-zero on failure.
freeTrustedSetup(): voidFrees the loaded trusted setup from memory.
blobToKZGCommitment(blob: string): stringConverts a blob of data into a KZG commitment. Takes a prefixed hex string containing 4096 big endian KZG field elements and returns a 48-byte KZG commitment as a prefixed hex string.
computeBlobKZGProof(blob: string, commitment: string): stringComputes a KZG proof for a blob and its commitment. Returns a 48-byte KZG proof as a prefixed hex string.
verifyBlobKZGProof(blob: string, commitment: string, proof: string): booleanVerifies a KZG proof against a blob and its commitment. Returns true if the proof is valid, false otherwise.
verifyBlobKZGProofBatch(blobs: string[], commitments: string[], proofs: string[]): booleanVerifies multiple KZG proofs in batch. All arrays must have the same length. Returns true if all proofs are valid, false otherwise.
verifyKZGProof(commitment: string, z: string, y: string, proof: string): booleanVerifies a KZG proof for specific points z and y against a commitment. Returns true if the proof is valid, false otherwise.
computeCellsAndKZGProofs(blob: string): KZGProofWithCellsComputes all 128 cells and their corresponding KZG proofs for a blob. Returns an object containing arrays of proofs and cells.
recoverCellsFromKZGProofs(cellIndices: number[], partialCells: string[], numCells: number): KZGProofWithCellsRecovers all cells and proofs from partial cell data. Requires at least 50% of the total cells to be provided. Returns the complete set of proofs and cells.
verifyCellKZGProof(commitment: string, cells: string[], proofs: string[]): booleanVerifies KZG proofs for specific cells against a commitment. Returns true if all proofs are valid, false otherwise.
verifyCellKZGProofBatch(commitments: string[], cellIndices: number[], cells: string[], proofs: string[], numCells: number): booleanVerifies multiple cell KZG proofs in batch. All arrays must have the same length and match numCells. Returns true if all proofs are valid, false otherwise.
The library also provides aliases for compatibility with different naming conventions:
blobToKzgCommitment- alias forblobToKZGCommitmentcomputeBlobProof- alias forcomputeBlobKZGProof
type TrustedSetup = {
g1_monomial: string
g1_lagrange: string
g2_monomial: string
}type KZGProofWithCells = {
proofs: string[] // Array of 128 proofs, each 48 bytes
cells: string[] // Array of 128 cells, each 2048 bytes
}The following numbers can give you some idea of the performance of the library. Note that these are rather "napkin numbers" and no benchmarks (30 runs each using Chrome), but they should nevertheless give you an idea if this wrapper library is a good fit for your use case.
WASM KZG: 27.866666666666667 ms per commitment
JS KZG: 4.466666666666667 ms per commitment
WASM KZG: 276.06666666666666 ms per proof
JS KZG: 644.7666666666667 ms per proof
WASM KZG: 12.233333333333333 ms per verify proof
JS KZG: 28.333333333333332 ms per verify proofGenerally note that initialization of this library is pretty slow due to the large KZG setup, so it is likely only worth to use in long-running production contexts.
This section outlines the build scripts included in this repository to create distributable JavaScript/TypeScript packages from the WASM compilation.
Ensure you have the following installed:
- Node.js (v16+)
- npm
- TypeScript (installed as dev dependency)
- Babel (installed as dev dependency)
The repository includes the following build scripts:
build- Main build commandbuild:ts- TypeScript compilation to multiple targetstranspileCJS- Babel transpilation for CommonJS compatibilityfixRequire- Fix dynamic require statementsfixWasmDirInNode- Fix WASM paths for Node.js buildsfixWasmDirInWeb- Fix WASM paths for browser builds
build:ts (scripts/ts-build.sh)
- Copies WASM file to
dist/wasm/ - Compiles TypeScript to CommonJS (
dist/cjs/) - Compiles TypeScript to ESM (
dist/esm/) - Creates browser build (
dist/browser/)
transpileCJS
- Uses Babel to transpile
src/kzg.jstodist/cjs/ - Ensures CommonJS compatibility
fixRequire
- Fixes dynamic require statements in CommonJS build
- Replaces
\_require('url')withrequire('url')
fixWasmDirInNode
- Updates WASM file paths in Node.js builds
- Changes
kzg-node.wasm→kzg.wasm→../wasm/kzg.wasm
fixWasmDirInWeb
- Updates WASM file paths in browser builds
- Changes
kzg-web.wasm→../wasm/kzg.wasm
dist/
├── cjs/ # CommonJS build for Node.js
│ ├── index.js
│ ├── kzg.js
│ ├── loader.cjs
│ └── package.json
├── esm/ # ES Modules build
│ ├── index.js
│ ├── kzg.js
│ ├── loader.mjs
│ └── package.json
├── browser/ # Browser build
│ ├── index.js
│ ├── kzg.js
│ └── package.json
└── wasm/ # WASM binary
└── kzg.wasm
# Test all builds
npm test
# Test specific builds
npm run test:dist # Test distribution build
npm run test:src # Test source code
npm run test:browser # Test browser environment