R1CS Binary File Parser
r1csfile is a JavaScript library designed for parsing and interpreting R1CS (Rank-1 Constraint System) binary files. These files are commonly generated by tools like Circom for zero-knowledge proof circuits, containing the constraints and witness information essential for SNARK proofs. The library provides programmatic access to read the structured data within an R1CS file, which typically includes details about the circuit's header, number of variables, number of constraints, and the wire mapping. As of version 0.0.48, the package is under active maintenance, primarily focusing on dependency updates to ensure security and compatibility. It exhibits a stable but infrequent release cadence, prioritizing robustness within the zero-knowledge ecosystem. Its key differentiator is its specific utility within the Iden3 ecosystem, offering a direct and reliable method to interact with R1CS files, which is crucial for building and integrating tools that depend on SNARK-based proof generation and verification without needing to recompile circuits repeatedly. It serves as a foundational component for developers working with these advanced cryptographic systems.
Common errors
-
Error: ENOENT: no such file or directory, open 'path/to/your/file.r1cs'
cause The specified R1CS file path does not exist or is inaccessible.fixVerify the file path is correct and absolute, or relative to the current working directory of the script. Check file permissions to ensure the Node.js process can read the file. -
Error: Invalid R1CS header magic: 0x...
cause The file being read is not a valid R1CS binary file, or it's corrupted, or it follows a different format.fixConfirm the file is a legitimate R1CS binary generated by a compatible tool like Circom. Try regenerating the R1CS file or inspecting it with a hex editor if possible to ensure its integrity. -
RangeError: Invalid array length
cause Occurs when parsing a malformed or extremely large R1CS file, leading to attempts to allocate an array exceeding JavaScript's memory limits.fixCheck the R1CS file for corruption or unusually large/incorrect values in its header fields (e.g., `nVars`, `nConstraints`). For very large legitimate files, consider increasing Node.js's memory limit (`node --max-old-space-size=8192 script.js`).
Warnings
- breaking Due to the package's early version (0.0.x), the API surface is not yet considered stable. Minor version bumps (e.g., 0.0.40 to 0.0.41) could potentially introduce breaking changes without adhering to semantic versioning for major versions. Always review the changelog when updating.
- gotcha Parsing large R1CS files can be memory-intensive, especially for circuits with millions of constraints or variables. This can lead to out-of-memory errors in Node.js environments if not managed carefully.
- gotcha The library is designed to parse the specific R1CS binary format defined by Iden3 (e.g., from Circom). Using it with R1CS files generated by other tools or custom formats may lead to parsing errors or incorrect interpretation of data.
Install
-
npm install r1csfile -
yarn add r1csfile -
pnpm add r1csfile
Imports
- readR1cs
const readR1cs = require('r1csfile');import { readR1cs } from 'r1csfile'; - readR1cs
const { readR1cs } = require('r1csfile'); - R1CS
import { R1CS } from 'r1csfile';import type { R1CS } from 'r1csfile';
Quickstart
import { readR1cs } from 'r1csfile';
import { promises as fs } from 'fs';
async function parseR1CSFile(filePath: string) {
try {
// Ensure the R1CS file exists before attempting to read
await fs.access(filePath);
console.log(`Attempting to read R1CS file: ${filePath}`);
const r1cs = await readR1cs(filePath);
console.log('Successfully parsed R1CS file.');
console.log(`Number of wires: ${r1cs.nVars}`);
console.log(`Number of constraints: ${r1cs.nConstraints}`);
console.log('R1CS structure (truncated):', {
header: r1cs.header,
nVars: r1cs.nVars,
nConstraints: r1cs.nConstraints,
// Further properties like `constraints` or `witness` can be very large.
// For demonstration, we'll just log header info.
});
// Example: Accessing specific header fields
if (r1cs.header.q instanceof Uint8Array) {
console.log(`Field prime (q): 0x${Buffer.from(r1cs.header.q).toString('hex')}`);
} else {
console.log(`Field prime (q): ${r1cs.header.q}`);
}
} catch (error) {
if (error instanceof Error) {
console.error(`Error parsing R1CS file ${filePath}: ${error.message}`);
if ((error as any).code === 'ENOENT') {
console.error('File not found. Please ensure the path is correct.');
}
} else {
console.error(`An unknown error occurred: ${error}`);
}
process.exit(1);
}
}
// To run this, you would need an actual .r1cs file.
// For demonstration, let's assume 'example.r1cs' exists in the current directory.
// Replace 'example.r1cs' with your actual file path.
// If you don't have one, this will output a 'File not found' error.
parseR1CSFile('example.r1cs');