Skip to main content

binius_examples/circuits/
blake2b.rs

1// Copyright 2026 The Binius Developers
2// Copyright 2025 Irreducible Inc.
3
4use anyhow::Result;
5use binius_circuits::blake2b::{Blake2bCircuit, blake2b};
6use binius_frontend::{CircuitBuilder, WitnessFiller};
7
8use super::utils::{self, HasherInstance, HasherMode, HasherParams};
9use crate::ExampleCircuit;
10
11/// Blake2b circuit example demonstrating the Blake2b hash function implementation
12pub struct Blake2bExample {
13	blake2b_circuit: Blake2bCircuit,
14	mode: HasherMode,
15}
16
17impl ExampleCircuit for Blake2bExample {
18	type Params = HasherParams;
19	type Instance = HasherInstance;
20
21	fn build(params: HasherParams, builder: &mut CircuitBuilder) -> Result<Self> {
22		// TODO: pass `supports_variable = true` and wire up a variable-length Blake2b gadget here
23		// once one exists in binius-circuits. Until then `--max-message-len` is rejected.
24		let mode = utils::resolve_hasher_mode(&params, "Blake2b", false)?;
25		let HasherMode::Fixed { len_bytes } = mode else {
26			unreachable!("Blake2b only supports the fixed-length gadget")
27		};
28
29		let blake2b_circuit = Blake2bCircuit::new_with_length(builder, len_bytes);
30
31		Ok(Self {
32			blake2b_circuit,
33			mode,
34		})
35	}
36
37	fn populate_witness(&self, instance: HasherInstance, w: &mut WitnessFiller<'_>) -> Result<()> {
38		let message = utils::resolve_hasher_message(&self.mode, &instance)?;
39
40		// Compute digest using reference implementation
41		let expected_digest_vec = blake2b(&message, 64);
42		let mut expected_digest = [0u8; 64];
43		expected_digest.copy_from_slice(&expected_digest_vec);
44
45		// Populate witness values (Blake2b doesn't use len_bytes)
46		self.blake2b_circuit.populate_message(w, &message);
47		self.blake2b_circuit.populate_digest(w, &expected_digest);
48
49		Ok(())
50	}
51
52	fn param_summary(params: &Self::Params) -> Option<String> {
53		utils::hasher_param_summary(params)
54	}
55}