CircomReactNative is a React Native package for generating and verifying Circom zero-knowledge proofs using the groth16 backend.
The Swift and Android bindings are generated by the mopro CLI using the Circom adapter, which utilizes circom-prover with circom-witnesscalc for witness generation and arkworks for groth16 proof construction.
To learn more about the original Rust implementation before generating bindings, please refer to zkmopro documentation.
Note
To use circom-witnesscalc, follow the README instructions to generate the graph file from your Circom circuits.
Or the script from semaphore-rs
Use a Node.js package manager in your React Native app to install dependencies. For example:
# npm
npm install https://github.com/zkmopro/CircomReactNative
# yarn / pnpm
yarn add https://github.com/zkmopro/CircomReactNativeAlternatively, you can manually add it to your package.json:
"dependencies": {
"circom-react-native": "github:zkmopro/CircomReactNative",
}Here is an example of how to integrate and use this package.
For the full test implementation, see example/App.tsx.
import CircomReactNative, {
CircomProofLib,
CircomProofResult,
ProofLibOption,
} from "circom-react-native";Please checkout circom and circom-witensscalc to see how to generate the zkey and the graph.
To load the circuit and graph in an Expo app, please checkout e.g. zkeyFilePath to get the path. Then define the file path, e.g.
const circuitInputs = {
a: [a],
b: [b],
};
// Generate proof
const res: CircomProofResult =
await CircomReactNative.circomProve(
graphFilePath.replace("file://", ""),
JSON.stringify(circuitInputs),
zkeyFilePath.replace("file://", ""),
);// Verify proof
const proofLib: CircomProofLib = {
proofLib: ProofLibOption.Arkworks,
};
const isValid: boolean = await Circom.verifyCircomProof(
zkeyFilePath.replace("file://", ""),
res,
proofLib,
);
console.log("Proof verification result:", isValid);Warning
The default bindings are built specifically for the multiplier2 circom circuit. If you'd like to update the circuit or switch to a different proving scheme, please refer to the How to Build the Package section.
Circuit source code: https://github.com/zkmopro/circuit-registry/tree/main/multiplier2
Example .zkey file for the circuit: http://ci-keys.zkmopro.org/multiplier2_final.zkey
Example graph file for the circuit: https://github.com/zkmopro/mopro/raw/refs/heads/main/circom-prover/test-vectors/multiplier2.bin
Use the example app folder:
cd example- Install the dependencies
npm install- Start the server
npm run start- Run the app on iOS
npm run ios- Run the app on Android
export ANDROID_HOME=~/Library/Android/sdk/npm run androidWarning
If you are using Expo, run the app with:
"ios": "expo run:ios",
"android": "expo run:android"These commands build and run the native iOS and Android projects.
And make sure the Android minSdkVersion is set to 28.
If you see errors like this:
Unable to resolve "./assets/keys/multiplier2_final.zkey" from "app/(tabs)/index.tsx"To make .zkey and .bin files accessible as assets, update metro.config.js like this:
config.resolver.assetExts.push('zkey');
config.resolver.assetExts.push('bin');This work was initially sponsored by a joint grant from PSE and 0xPARC. It is currently incubated by PSE.
This project is heavily inspired by ezkl-swift-package and follows a similar approach for integrating native cryptographic libraries into Swift via a Swift Package.