Skip to content

zkmopro/noir-rs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Noir-rs

Noir‑rs is a Rust crate that turns Noir circuits into Rust and (optionally) links the Barretenberg prover for Ultra‑Honk proofs. It works on macOS, Linux, iOS (aarch64‑apple‑ios), and Android (aarch64‑linux‑android).

Installation

# Cargo.toml
[dependencies]
noir = { git = "https://github.com/zkmopro/noir-rs", features = ["barretenberg"] }

# For Android add the `android-compat` feature:
noir = { git = "https://github.com/zkmopro/noir-rs", features = ["barretenberg", "android-compat"] }

Platform Support

For details, please check released artifacts in zkmopro/aztec-packages

  • macOS
    • aarch64-apple-darwin
    • x86_64-apple-darwin
  • iOS
    • aarch64‑apple‑ios
    • aarch64-apple-ios-sim
    • x86_64-apple-ios
  • Android
    • aarch64‑linux‑android
    • x86_64-linux-android
  • Linux
    • x86_64-unknown-linux-gnu

Low Memory Mode for Mobile

Noir-rs supports a low memory mode specifically optimized for mobile devices and resource-constrained environments. This mode reduces memory usage during proof generation at the cost of slightly increased proving time.

To enable low memory mode, pass true to the low_memory_mode parameter in proving and verification key generation functions:

// Enable low memory mode for mobile proving
let vk = get_ultra_honk_verification_key(BYTECODE, true).unwrap();
let proof = prove_ultra_honk(BYTECODE, witness, vk.clone(), true).unwrap();

This feature is particularly useful for:

  • iOS and Android applications with limited RAM
  • Embedded systems
  • Resource-constrained server environments

Solidity On-Chain Verification

Noir-rs enables the generation of proofs that are compatible with Solidity verifier contracts. While Noir's default proof system use Poseidon2 as its hash function, it now supports both proof generation and verification with keccak. This provides optimization benefits for Solidity verifiers, allowing developers to efficiently verify ZKPs directly on Ethereum and other EVM-compatible blockchain networks.

For detailed instructions, see the Noir documentation on Solidity verifiers.

For demo implementation, check out mopro-wallet-connect-noir repository.

Using Ultra Honk Keccak for Solidity

Ultra Honk with keccak provides better optimization for Solidity verifiers, making it ideal for on-chain applications. To generate proofs optimized for on-chain verification, use prove_ultra_honk_keccak function. Alternatively, when generating proofs for off-chain verification scenarios, use prove_ultra_honk, which employs Poseidon2 hashing.

Below is a minimal a * b = res circuit proof. Compile your circuit with nargo compile, copy the bytecode string into BYTECODE, then:

use noir::{
    barretenberg::{
        prove::prove_ultra_honk_keccak,
        srs::{setup_srs_from_bytecode, setup_srs},
        utils::get_ultra_honk_keccak_verification_key,
        verify::verify_ultra_honk_keccak,
    },
    witness::from_vec_str_to_witness_map,
};

const BYTECODE: &str = "H4sIAAAAAAAA/62QQQqAMAwErfigpEna5OZXLLb/f4KKLZbiTQdCQg7Dsm66mc9x00O717rhG9ico5cgMOfoMxJu4C2pAEsKioqisnslysoaLVkEQ6aMRYxKFc//ZYQr29L10XfhXv4jB52E+OpMAQAA";    // output of `nargo compile`

fn main() {
     /// Download SRS via `srs_downloader`:
    /// - Circuit-specific (`-c path/to/my_circuit.json`): `./srs_cache/my_circuit.srs`
    /// - Default (no `-c`): `./srs_cache/default_18.srs`
    ///

    // 1. Update srs_path to the location of your downloaded SRS file.
    // (Option 1)
    // let srs_path = "./srs_cache/my_circuit.srs";
    // setup_srs_from_bytecode(BYTECODE, Some(srs_path), false).unwrap();

    // (Option 2)
    // Alternatively, if you know the circuit size, you can use the following function
    // Assuming the circuit size is 40 here
    setup_srs_from_bytecode(BYTECODE, None, false).unwrap();
    setup_srs(40, None).unwrap();
    
    // 2. Witness
    let witness = from_vec_str_to_witness_map(vec!["5", "6", "0x1e"]).unwrap();
    
    // 3. Get verification key with Keccak optimization for Solidity
    let disable_zk = false; // Set to true to disable zero-knowledge for debugging
    let low_memory_mode = false; // Set to true for mobile devices
    let vk = get_ultra_honk_keccak_verification_key(BYTECODE, disable_zk, low_memory_mode).unwrap();
    
    // 4. Generate proof with Keccak (optimized for Solidity verification)
    let proof = prove_ultra_honk_keccak(BYTECODE, witness, vk.clone(), disable_zk, low_memory_mode).unwrap();
    
    // 5. Verify (optional - verification will happen on-chain)
    let is_valid = verify_ultra_honk_keccak(proof, vk, disable_zk).unwrap();
    println!("✔ proof valid? {:?}", is_valid);
}

Generating a Solidity Verifier

  1. Compile your Noir circuit:

    nargo compile
  2. Generate the verification key:

    bb write_vk -b ./target/<circuit_name>.json -o ./target --oracle_hash keccak
  3. Generate the Solidity verifier contract:

    bb write_solidity_verifier -k ./target/vk -o ./target/Verifier.sol

Proof and Public Inputs Separation

Noir-rs provides utilities to separate public inputs from proof data, which is essential for constructing proper calldata for on-chain verification:

use noir::utils::{
    parse_proof_with_public_inputs,
    get_num_public_inputs_from_circuit,
    combine_proof_and_public_inputs,
};

// Get the number of public inputs from your circuit
let num_public_inputs = get_num_public_inputs_from_circuit(BYTECODE)?;

// Generate proof (public inputs are concatenated at the beginning)
let proof = prove_ultra_honk_keccak(BYTECODE, witness, vk, false, false)?;

// Parse the proof into separated components
let proof_with_public_inputs = parse_proof_with_public_inputs(&proof, num_public_inputs)?;

// Access the separated proof and public inputs
let pure_proof = &proof_with_public_inputs.proof;
let public_inputs = &proof_with_public_inputs.public_inputs;

// Use pure_proof and public_inputs for constructing calldata for Solidity verifier

Downloading SRS (Structured Reference String)

Noir requires a Structured Reference String (SRS) for its operations. You can download the necessary SRS files using the srs_downloader utility included in the noir crate.

1. SRS for a Specific Circuit

If you have a compiled circuit (e.g., circuit.json from nargo compile), you can download the SRS tailored for that circuit.

cargo run --bin srs_downloader --features srs-downloader -- -c path/to/your/circuit.json

This will download the SRS and save it to ./srs_cache/your_circuit_name.srs by default (e.g., ./srs_cache/my_circuit.srs).

Recursive Mode:

For recursive circuits, you can enable recursive mode for circuit size calculation using the --recursive or -r flag:

cargo run --bin srs_downloader --features srs-downloader -- -c path/to/your/circuit.json --recursive

2. Default SRS

If you don't have a specific circuit manifest or want a general-purpose SRS, you can download a default one (supports up to 2^18 constraints):

cargo run --bin srs_downloader --features srs-downloader

This will download the SRS and save it to ./srs_cache/default_18.srs by default.

Custom Output Path:

You can specify a custom output path for the downloaded SRS file using the -o flag:

# For a specific circuit
cargo run --bin srs_downloader --features srs-downloader -- -c path/to/your/circuit.json -o /custom/path/to/srs_file.srs

# For a specific circuit with recursive mode
cargo run --bin srs_downloader --features srs-downloader -- -c path/to/your/circuit.json -o /custom/path/to/srs_file.srs --recursive

# For a default SRS
cargo run --bin srs_downloader --features srs-downloader -- -o /custom/path/to/default.srs

The tool will automatically create parent directories if they don't exist.

Community

  • X account:
  • Telegram group:

Acknowledgements

This work was initially sponsored by a joint grant from PSE and 0xPARC. It is currently incubated by PSE.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •