noir_flutter is a Flutter package for generating and verifying Noir zero-knowledge proofs using the Barretenberg backend.
The Flutter bindings are generated by the mopro CLI using the Noir adapter, which relies on a prebuilt Barretenberg backend.
To learn more about the original Rust implementation before generating bindings, please refer to noir-rs.
-
Manual Edit (Required for local path or specific Git dependencies): Open your
pubspec.yamlfile and addnoir_flutterunderdependencies.```yaml dependencies: flutter: sdk: flutter noir_flutter: git: url: https://github.com/zkmopro/noir_flutter # Or # mopro_flutter_package: # path: ../noir_flutter ``` -
Update Circuit Asset: Include your compiled Noir circuit
.jsonand.srsfile as an asset. Add the asset path to yourpubspec.yamlunder theflutter:section:flutter: uses-material-design: true # Ensure this is present assets: # Add the directory containing your .json file(s) - assets/....json - assets/....srs # Or specify the file directly: # - assets/noir_multiplier2.json
Make sure the path points correctly to where you've placed your
.jsonfile within your Flutter project. -
Install Package: Run the following command in your terminal from the root of your Flutter project:
flutter pub get
import 'package:noir_flutter/src/rust/third_party/mopro_example_app_noir.dart';
import 'package:noir_flutter/src/rust/frb_generated.dart';Update the main function to initialize the Rust library before running the app:
void main() async {
await RustLib.init();
runApp(const MyApp());
}Please checkout noir-rs to see how to generate the circuit and the srs.
final circuitPath = await copyAssetToFileSystem(
'assets/noir_multiplier2.json');
final srsPath = await copyAssetToFileSystem(
'assets/noir_multiplier2.srs');Note
To learn how to read a .json file from an app, please refer to the copyAssetToFileSystem function in the Flutter app.
const bool onChain = true;
const bool lowMemoryMode = false;
var inputs = ["3","5"];
final vk = await getNoirVerificationKey(
circuitPath: circuitPath,
srsPath: srsPath,
onChain: onChain,
lowMemoryMode: lowMemoryMode,
);final proofData = await generateNoirProof(
circuitPath: circuitPath,
srsPath: srsPath,
inputs: inputs,
onChain: onChain,
vk: vk,
lowMemoryMode: lowMemoryMode
);final isValid = await verifyNoirProof(
circuitPath: circuitPath,
proof: proofData,
onChain: onChain,
vk: vk,
lowMemoryMode: lowMemoryMode,
);This package relies on bindings generated by the Mopro CLI. To learn how to build Mopro bindings, refer to the Getting Started section. If you'd like to generate custom bindings for your own circuits or proving schemes, check out the guide on how to use the Mopro CLI: Rust Setup for Android/iOS Bindings.
Choose Flutter to build the bindings, or run
mopro build --platforms flutterto generate the flutter package.
Then, replace the entire bindings directory mopro_flutter_package with your generated files in the current folder:
├── android
├── cargokit
├── flutter_rust_bridge.yaml
├── ios
├── lib
├── pubspec.yaml
└── rustor running e.g.
cp -R \
mopro_flutter_bindings/android \
mopro_flutter_bindings/cargokit \
mopro_flutter_bindings/flutter_rust_bridge.yaml \
mopro_flutter_bindings/ios \
mopro_flutter_bindings/lib \
mopro_flutter_bindings/pubspec.yaml \
mopro_flutter_bindings/rust \
noir_flutter/- Open the example app that uses the defined flutter package in the
example/foldercd example - Install the dependencies
flutter pub get
- Open an iOS simulator/device or an Android emulator/device and run the example app
flutter run
- Clean the cache if you update the bindings and it throws errors
flutter clean
![WARNING] Bindings generated by the mopro CLI use local crate paths by default, which makes them non-reproducible on other devices. To make the build reproducible, publish your Rust crate and reference it via a Git source instead of a local path at here. If you’d like to help address this limitation, contributions are welcome — see zkmopro/mopro#647 .
This work was initially sponsored by a joint grant from PSE and 0xPARC. It is currently incubated by PSE.