Black box functions are operations in Noir that are delegated to the proving backend rather than compiled into plain arithmetic constraints. The backend may implement them using optimised native gadgets, which can be far cheaper than an equivalent hand-written Noir circuit. If a backend does not have a native implementation, it must supply a fallback. The ACVM specification defines the exact interface that backends must support. You can browse the canonical list in the ACIR source.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/noir-lang/noir/llms.txt
Use this file to discover all available pages before exploring further.
Why black box functions exist
ZK-SNARK backends represent programs as arithmetic circuits over a finite field. Some computations — such as SHA-256 — involve operations (bit rotations, XOR, modular arithmetic over a different field) that are expensive when expressed as field arithmetic. A backend with a purpose-built gadget for SHA-256 can express the same computation in far fewer constraints. Black box functions give Noir a way to call these gadgets without hard-coding knowledge of any particular backend. The tradeoff is that if a backend does not implement a specific black box function, it must fall back to a generic (and possibly slow) implementation.Complete function list
AES128
AES128
Encrypts a byte array with AES-128 in CBC mode. PKCS#7 padding is applied automatically.Stdlib entry point: See Cryptographic primitives — AES128 for a usage example.
std::aes128::aes128_encryptSHA256 (sha256_compression)
SHA256 (sha256_compression)
A single SHA-256 compression round. Not a full SHA-256 digest — use the sha256 library for a complete implementation.Stdlib entry point:
std::hash::sha256_compressionBlake2s
Blake2s
Hashes an arbitrary byte array with Blake2s, returning a 32-byte digest.Stdlib entry point:
std::hash::blake2sBlake3
Blake3
Hashes an arbitrary byte array with Blake3, returning a 32-byte digest. Input is limited to 1024 bytes under Barretenberg.Stdlib entry point:
std::hash::blake3Pedersen hash and commitment
Pedersen hash and commitment
Computes a Pedersen hash (returning a
Field) or Pedersen commitment (returning an EmbeddedCurvePoint) over an array of field elements.Stdlib entry points: std::hash::pedersen_hash, std::hash::pedersen_commitmentECDSA signature verification
ECDSA signature verification
Verifies an ECDSA signature over secp256k1 or secp256r1. Both functions share the same signature shape.Stdlib entry points:
std::ecdsa_secp256k1::verify_signature, std::ecdsa_secp256r1::verify_signatureEmbedded curve operations (MSM, point addition)
Embedded curve operations (MSM, point addition)
Multi-scalar multiplication and point addition on the embedded curve (Grumpkin for BN254 / Barretenberg).Stdlib entry points:
std::embedded_curve_ops::multi_scalar_mul, std::embedded_curve_ops::embedded_curve_add, std::embedded_curve_ops::fixed_base_scalar_mulAND
AND
Constrains the bitwise AND of two integers. Exposed through the
& operator in Noir source rather than as a direct function call.XOR
XOR
Constrains the bitwise XOR of two integers. Exposed through the
^ operator.RANGE
RANGE
Constrains that a value fits within a given bit width. Exposed through Noir’s range constraint syntax.You can also call
std::as_witness and use explicit range assertions in some contexts.Keccakf1600
Keccakf1600
Applies a single Keccak-f[1600] permutation to a 25-word (64-bit) state. Use this primitive to build Keccak-256 or SHA-3.Stdlib entry point:
std::hash::keccakf1600Recursive proof verification
Recursive proof verification
Verifies a proof of a Noir program inside another Noir program. This is how recursive aggregation is performed.Stdlib entry point: See Recursion for a full walkthrough.
std::verify_proof (via #[foreign(recursive_aggregation)])Language-level black box operations
Three black box functions are not callable as library functions — they are instead invoked by Noir language operators:| Language construct | Black box function |
|---|---|
a & b (bitwise AND) | AND |
a ^ b (bitwise XOR) | XOR |
| Integer casts / range assertions | RANGE |
Fallback implementations
Backends are required to support all black box functions defined in the ACVM spec. If a backend does not have a native gadget for a particular function, it must supply a fallback implementation expressed in terms of basic constraints. Fallback implementations are correct but may produce significantly larger circuits. When targeting Barretenberg, all functions listed above have native gadget support and will not fall back.If you are building a new backend and need to understand the expected semantics for each black box function, refer to the ACIR black box function definitions and the blackbox_solver crate.