### Noir Getting Started and Learning Resources Source: https://context7.com/noir-lang/awesome-noir/llms.txt This snippet outlines official resources, interactive learning platforms like Noirlings and Glass Bridge, and educational courses for getting started with Noir and zero-knowledge proofs. It requires no specific installation for browser-based resources. ```markdown ## Official Resources - Documentation: https://noir-lang.org/docs - GitHub Organization: https://github.com/noir-lang - Discord Community: https://discord.gg/RJdCBN373S - Twitter/X: @NoirLang ## Interactive Learning - Noirlings: https://github.com/satyambnsal/noirlings - Hands-on exercises for learning Noir programming - Noirlings.app: https://www.noirlings.app/ - Browser-based learning, no setup required - Glass Bridge With Noir: https://zkdev.net/docs/tutorial/glass-bridge - Learn ZK proofs through a browser game ## Educational Courses - Cyfrin Updraft: https://updraft.cyfrin.io/courses/noir-programming-and-zk-circuits - Complete course on Noir, circuits, and ZK app development - ZKCamp Open Source Course: https://github.com/ZKCamp/aztec-noir-course - 6 lectures covering ZKP fundamentals through advanced Noir ``` -------------------------------- ### Noir Performance Profiling with nargo-profiler Source: https://context7.com/noir-lang/awesome-noir/llms.txt Guides on installing and using the Noir profiler for analyzing circuit performance. It helps identify bottlenecks in opcode usage and proving times by generating flamegraphs and detailed analysis reports. Supports benchmarking via `noir-benchmark-cli`. ```bash # Install Noir profiler cargo install --git https://github.com/noir-lang/noir noir-profiler # Generate profile data during compilation nargo compile --profile # Generate flamegraph for opcodes noir-profiler flamegraph --output opcodes.svg # Generate flamegraph for proving costs noir-profiler flamegraph --proving-costs --output proving.svg # Analyze specific function costs noir-profiler analyze --function calculate_hash # Example output: # Function: calculate_hash # Opcodes: 1,234 # Constraints: 5,678 # Proving time: 45ms # Hotspots: # - sha256 hash: 3,456 opcodes (71%) # - merkle verification: 1,012 opcodes (23%) # Benchmark with noir-benchmark-cli npx noir-benchmark-cli --circuit ./circuits/target/circuit.json # Example benchmark output: # Circuit: main # Witness generation: 123ms # Proof generation: 2.4s # Proof size: 1,234 bytes # Public inputs: 3 # Memory usage: 45MB ``` -------------------------------- ### Noir Package Management and Compilation Source: https://context7.com/noir-lang/awesome-noir/llms.txt This snippet demonstrates how to install and use the `noir-libs` CLI for managing Noir packages, adding dependencies to `Nargo.toml`, updating Noir and Barretenberg with `noirupi` and `bbupi`, and compiling/proving/verifying Noir programs using `nargo`. ```bash # Install noir-libs CLI manager npm install -g noir-libs # Browse available libraries # Visit: https://noir-libs.org/ # Add a library to your Noir project # Example: Adding the BigNum library # In your Nargo.toml file: [dependencies] bignum = { tag = "v0.2.0", git = "https://github.com/noir-lang/noir-bignum" } # Update Noir and Barretenberg interactively npm install -g noirupi noirupi # Interactive update for noir bbupi # Interactive update for barretenberg # Compile your Noir program nargo compile # Generate proof nargo prove # Verify proof nargo verify ``` -------------------------------- ### Ethereum ERC20 Balance Verification with Storage Proofs Source: https://context7.com/noir-lang/awesome-noir/llms.txt Verifies the ERC20 token balance of a user in a specific Ethereum block using a storage proof. It computes the correct storage slot for the balance mapping and uses the `ethereum_storage_proof` library to verify the data. A JavaScript example illustrates how to obtain the necessary proof from an Ethereum provider. ```Noir // File: src/eth_storage_proof.nr use dep::ethereum_storage_proof::{verify_storage_proof, StorageProof}; fn verify_erc20_balance( block_hash: [u8; 32], contract_address: [u8; 20], user_address: [u8; 20], claimed_balance: Field, proof: StorageProof ) -> pub bool { // Compute storage slot for ERC20 balance mapping // balanceOf[user] = keccak256(user_address . slot_number) let storage_slot = compute_erc20_balance_slot(user_address, 0); // Verify the storage proof let verified_value = verify_storage_proof( block_hash, contract_address, storage_slot, proof ); // Check that verified value matches claimed balance verified_value == claimed_balance } fn compute_erc20_balance_slot(user: [u8; 20], slot: Field) -> [u8; 32] { // ERC20 storage layout: mapping(address => uint256) at slot 0 let mut data: [u8; 52] = [0; 52]; // Concatenate user address (32 bytes padded) + slot for i in 0..20 { data[12 + i] = user[i]; } // Return keccak256 hash as storage key std::hash::keccak256(data) } ``` ```JavaScript // JavaScript example to generate proof: // const { ethers } = require('ethers') // const provider = new ethers.JsonRpcProvider(RPC_URL) // // // Get proof for USDC balance // const proof = await provider.send('eth_getProof', [ // '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC address // [storageSlot], // blockNumber // ]) // // // Use proof.accountProof and proof.storageProof as circuit inputs ``` -------------------------------- ### Merkle Tree Membership Verification with ZK-Kit Source: https://context7.com/noir-lang/awesome-noir/llms.txt Verifies if a leaf is a member of a Merkle tree given the root, leaf, path indices, and siblings. It relies on the MerkleProof structure from the ZK-Kit library. The companion JavaScript example demonstrates tree construction and proof generation. ```Noir // File: src/merkle_proof.nr use dep::zk_kit::merkle_trees::MerkleProof; fn verify_membership( root: Field, leaf: Field, path_indices: [u1; 20], siblings: [Field; 20] ) -> pub bool { // Create Merkle proof structure let proof = MerkleProof { leaf, siblings, path_indices, }; // Verify the leaf is in the tree with given root let computed_root = proof.compute_root(); // Return whether computed root matches expected root computed_root == root } ``` ```JavaScript // Example verification in JavaScript (companion): import { MerkleTree } from '@zk-kit/merkle-tree' import { poseidon2 } from 'poseidon-lite' // Build tree const leaves = [1n, 2n, 3n, 4n, 5n] const tree = new MerkleTree(poseidon2, leaves) // Generate proof for leaf 3 const proof = tree.createProof(2) // index 2 console.log('Root:', tree.root) console.log('Siblings:', proof.siblings) console.log('Path indices:', proof.pathIndices) // Use these values as inputs to Noir circuit // Expected output: true if proof is valid ``` -------------------------------- ### JSON Parsing and Extraction in Noir Circuits Source: https://context7.com/noir-lang/awesome-noir/llms.txt Parses JSON strings within Noir circuits using the official JSON parser library, allowing for data extraction. It supports navigating JSON structures and can be used for verifying claims from sources like JWTs. The example demonstrates extracting a user's age and verifying JWT claims. ```Noir // File: src/json_parser.nr use dep::json_parser::{parse, JSONValue}; fn extract_user_age(json_string: str<1024>) -> pub Field { // Parse JSON string (IETF RFC 8259 compliant) let parsed = parse(json_string); // Navigate JSON structure // Example JSON: {"user": {"name": "Alice", "age": 30, "verified": true}} let user_obj = parsed.get("user").as_object(); let age_value = user_obj.get("age").as_number(); // Return age as Field element age_value } // Example usage: // Input JSON in Prover.toml: // json_string = "{\"user\":{\"name\":\"Alice\",\"age\":30,\"verified\":true}}" // Expected output: 30 // Use case: Verify claims from JSON Web Tokens (JWTs) fn verify_jwt_claim( jwt_payload: str<2048>, expected_issuer: str<256>, min_exp_time: Field ) -> pub bool { let payload = parse(jwt_payload); let issuer = payload.get("iss").as_string(); let exp = payload.get("exp").as_number(); // Verify issuer matches and token not expired (issuer == expected_issuer) & (exp > min_exp_time) } ``` -------------------------------- ### Prove and Verify Noir Circuits with NoirJS and Barretenberg Source: https://context7.com/noir-lang/awesome-noir/llms.txt This snippet shows how to initialize NoirJS with the Barretenberg backend, execute a Noir circuit with given inputs, generate a proof, and verify it. It also demonstrates generating a Solidity verifier for on-chain verification. Dependencies include '@noir-lang/noir_js' and '@noir-lang/backend_barretenberg'. ```typescript import { Noir } from '@noir-lang/noir_js' import { BarretenbergBackend } from '@noir-lang/backend_barretenberg' import circuit from '../circuits/target/circuit.json' async function proveAndVerify() { // Initialize backend with circuit const backend = new BarretenbergBackend(circuit) // Initialize Noir instance const noir = new Noir(circuit, backend) // Define circuit inputs const inputs = { secret_number: '42', public_limit: '100' } // Generate witness (compute circuit outputs) const { witness } = await noir.execute(inputs) console.log('Circuit outputs:', witness) // Generate proof console.log('Generating proof...') const proof = await backend.generateProof(witness) console.log('Proof generated:', proof.proof) console.log('Public inputs:', proof.publicInputs) // Verify proof console.log('Verifying proof...') const isValid = await backend.verifyProof(proof) console.log('Proof valid:', isValid) // Cleanup await backend.destroy() return { proof, isValid } } // Generate Solidity verifier for on-chain verification async function generateSolidityVerifier() { const backend = new BarretenbergBackend(circuit) const verifierContract = await backend.generateSolidityVerifier() // Write to file or deploy console.log('Solidity verifier contract:') console.log(verifierContract) await backend.destroy() } proveAndVerify().catch(console.error) ``` -------------------------------- ### Mobile Proof Generation with MoPro (Android) Source: https://context7.com/noir-lang/awesome-noir/llms.txt Illustrates how to generate and verify Noir proofs on Android devices using MoPro with Kotlin. This code shows loading a circuit from assets, setting up inputs, generating a proof, measuring the generation time, and verifying the proof using the MoPro library. ```kotlin // File: android/ProofGenerator.kt import org.mopro.MoPro import kotlinx.coroutines.* class ProofGenerator(private val context: Context) { suspend fun generateProof(secretValue: Int): ProofResult = withContext(Dispatchers.IO) { // Load circuit from assets val circuit = MoPro.loadCircuit(context, "circuit.json") // Prepare inputs val inputs = mapOf( "secret" to secretValue, "limit" to 100 ) // Generate proof val startTime = System.currentTimeMillis() val proof = circuit.generateProof(inputs) val duration = System.currentTimeMillis() - startTime // Verify val isValid = circuit.verifyProof(proof) ProofResult(proof, isValid, duration) } } // Benchmarks from MoPro documentation: // Android (Pixel 7): // - Simple circuit: ~1.2s proving ``` -------------------------------- ### Mobile Proof Generation with MoPro (iOS) Source: https://context7.com/noir-lang/awesome-noir/llms.txt Demonstrates generating and verifying Noir proofs on iOS devices using the MoPro library. This Swift code snippet shows how to load a Noir circuit, prepare inputs, generate a proof, measure the time taken, and verify the proof locally on the device. ```swift // File: iOS/ProofGenerator.swift import MoPro import Foundation class ProofGenerator { func generateProof(secretValue: Int) async throws -> ProofResult { // Initialize MoPro with circuit let circuitPath = Bundle.main.path(forResource: "circuit", ofType: "json")! let circuit = try await MoPro.loadCircuit(path: circuitPath) // Prepare inputs let inputs: [String: Any] = [ "secret": secretValue, "limit": 100 ] // Generate proof on mobile device let startTime = Date() let proof = try await circuit.generateProof(inputs: inputs) let duration = Date().timeIntervalSince(startTime) print("Proof generated in \(duration)s") print("Proof size: \(proof.data.count) bytes") // Verify locally let isValid = try await circuit.verifyProof(proof: proof) return ProofResult( proof: proof, isValid: isValid, generationTime: duration ) } } // Benchmarks from MoPro documentation: // iOS (iPhone 14 Pro): // - Simple circuit: ~800ms proving ``` -------------------------------- ### Test Noir Circuit Verification in Hardhat Source: https://context7.com/noir-lang/awesome-noir/llms.txt This JavaScript snippet demonstrates testing Noir circuit verification within a Hardhat project using Chai and ethers.js. It includes setting up the Noir backend, generating proofs, and verifying them both off-chain and on-chain against a deployed verifier contract. It covers testing for both valid and invalid proofs. ```javascript const { expect } = require('chai') const { ethers } = require('hardhat') const { Noir } = require('@noir-lang/noir_js') const { BarretenbergBackend } = require('@noir-lang/backend_barretenberg') const circuit = require('../circuits/target/circuit.json') describe('ZK Proof Verification', function () { let verifier let backend let noir before(async function () { // Deploy verifier contract const Verifier = await ethers.getContractFactory('UltraVerifier') verifier = await Verifier.deploy() await verifier.deployed() // Setup Noir backend = new BarretenbergBackend(circuit) noir = new Noir(circuit, backend) }) it('should verify valid proof on-chain', async function () { // Generate proof const inputs = { x: '5', y: '10' } const { witness } = await noir.execute(inputs) const proof = await backend.generateProof(witness) // Verify on-chain const result = await verifier.verify( proof.proof, proof.publicInputs ) expect(result).to.be.true }) it('should reject invalid proof', async function () { // Generate proof with different inputs const inputs = { x: '5', y: '10' } const { witness } = await noir.execute(inputs) const proof = await backend.generateProof(witness) // Tamper with proof proof.proof[0] ^= 0xff // Attempt verification await expect( verifier.verify(proof.proof, proof.publicInputs) ).to.be.revertedWith('Invalid proof') }) }) ``` -------------------------------- ### Hardhat Configuration for Noir Integration Source: https://context7.com/noir-lang/awesome-noir/llms.txt This JavaScript snippet configures Hardhat to automatically compile Noir circuits and generate Solidity verifiers during the Hardhat compile process. It requires the 'hardhat-noir' plugin. Ensure the 'circuits' path and 'generateVerifiers' flag are correctly set. ```javascript require('@nomicfoundation/hardhat-toolbox') require('hardhat-noir') module.exports = { solidity: '0.8.20', noir: { // Compile Noir circuits during hardhat compile circuits: ['circuits/src/main.nr'], // Generate Solidity verifiers generateVerifiers: true, }, } ``` -------------------------------- ### Noir RSA Signature Verification Source: https://context7.com/noir-lang/awesome-noir/llms.txt This Noir code snippet demonstrates how to verify RSA signatures using the zkPassport RSA library within a Noir circuit. It takes a message hash, signature, public key modulus, and public key exponent as input and returns a boolean indicating verification success. It relies on the `dep::rsa` library. ```noir // File: src/main.nr use dep::rsa; fn main( message_hash: [u8; 32], signature: [Field; 32], public_key_modulus: [Field; 32], public_key_exponent: Field ) -> pub bool { // Verify RSA signature let is_valid = rsa::verify_sha256_pkcs1v15( message_hash, signature, public_key_modulus, public_key_exponent ); // Return verification result is_valid } // Example usage in Prover.toml: // message_hash = [0x6a, 0x09, 0xe6, 0x67, ..., 0x3b, 0xc8] # 32 bytes // signature = ["0x1234...", "0x5678...", ...] # 32 Field elements // public_key_modulus = ["0xabcd...", "0xef01...", ...] # 32 Field elements // public_key_exponent = "0x10001" # Typically 65537 // Benchmarks (from zkPassport): // - RSA-2048: ~2.5s proving time // - RSA-4096: ~8.5s proving time // - Circuit size: ~1M constraints for 2048-bit ``` -------------------------------- ### EdDSA Signature Verification in Noir Source: https://context7.com/noir-lang/awesome-noir/llms.txt Verifies EdDSA signatures on the Baby Jubjub curve using the `eddsa` dependency. This function is crucial for privacy-preserving authentication schemes. It takes message, public key components, and signature components as input and returns a boolean indicating verification success. ```noir // File: src/eddsa_verify.nr use dep::eddsa::{verify_signature, PublicKey, Signature}; fn verify_message( message: [u8; 32], public_key_x: Field, public_key_y: Field, signature_r_x: Field, signature_r_y: Field, signature_s: Field ) -> pub bool { // Construct public key let public_key = PublicKey { x: public_key_x, y: public_key_y, }; // Construct signature let signature = Signature { r_x: signature_r_x, r_y: signature_r_y, s: signature_s, }; // Verify EdDSA signature verify_signature(message, public_key, signature) } // Example: Anonymous voting system fn cast_anonymous_vote( vote: Field, // 0 or 1 voter_public_key: PublicKey, nullifier: Field, signature: Signature, merkle_root: Field, merkle_proof: [Field; 20] ) -> pub Field { // 1. Verify voter is in voter registry (Merkle proof) let voter_hash = std::hash::poseidon2([voter_public_key.x, voter_public_key.y]); assert(verify_merkle_proof(merkle_root, voter_hash, merkle_proof)); // 2. Verify signature on vote message let vote_message = std::hash::poseidon2([vote, nullifier]); assert(verify_signature(vote_message, voter_public_key, signature)); // 3. Return nullifier to prevent double voting nullifier } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.