binius_core/merkle_tree/
prover.rs

1// Copyright 2024-2025 Irreducible Inc.
2
3use binius_field::TowerField;
4use binius_hash::PseudoCompressionFunction;
5use binius_maybe_rayon::iter::IndexedParallelIterator;
6use bytes::BufMut;
7use digest::{core_api::BlockSizeUser, Digest, FixedOutputReset, Output};
8use getset::Getters;
9use tracing::instrument;
10
11use super::{
12	binary_merkle_tree::{self, BinaryMerkleTree},
13	errors::Error,
14	merkle_tree_vcs::{Commitment, MerkleTreeProver},
15	scheme::BinaryMerkleTreeScheme,
16};
17use crate::transcript::TranscriptWriter;
18
19#[derive(Debug, Getters)]
20pub struct BinaryMerkleTreeProver<T, H, C> {
21	#[getset(get = "pub")]
22	scheme: BinaryMerkleTreeScheme<T, H, C>,
23}
24
25impl<T, C, H> BinaryMerkleTreeProver<T, H, C> {
26	pub fn new(compression: C) -> Self {
27		Self {
28			scheme: BinaryMerkleTreeScheme::new(compression),
29		}
30	}
31}
32
33impl<F, H, C> MerkleTreeProver<F> for BinaryMerkleTreeProver<F, H, C>
34where
35	F: TowerField,
36	H: Digest + BlockSizeUser + FixedOutputReset,
37	C: PseudoCompressionFunction<Output<H>, 2> + Sync,
38{
39	type Scheme = BinaryMerkleTreeScheme<F, H, C>;
40	type Committed = BinaryMerkleTree<Output<H>>;
41
42	fn scheme(&self) -> &Self::Scheme {
43		&self.scheme
44	}
45
46	fn commit(
47		&self,
48		data: &[F],
49		batch_size: usize,
50	) -> Result<(Commitment<Output<H>>, Self::Committed), Error> {
51		let tree =
52			binary_merkle_tree::build::<_, H, _>(self.scheme.compression(), data, batch_size)?;
53
54		let commitment = Commitment {
55			root: tree.root(),
56			depth: tree.log_len,
57		};
58
59		Ok((commitment, tree))
60	}
61
62	fn layer<'a>(
63		&self,
64		committed: &'a Self::Committed,
65		depth: usize,
66	) -> Result<&'a [Output<H>], Error> {
67		committed.layer(depth)
68	}
69
70	fn prove_opening<B: BufMut>(
71		&self,
72		committed: &Self::Committed,
73		layer_depth: usize,
74		index: usize,
75		proof: &mut TranscriptWriter<B>,
76	) -> Result<(), Error> {
77		let branch = committed.branch(index, layer_depth)?;
78		proof.write_slice(&branch);
79		Ok(())
80	}
81
82	#[instrument(skip_all, level = "debug")]
83	#[allow(clippy::type_complexity)]
84	fn commit_iterated<ParIter>(
85		&self,
86		iterated_chunks: ParIter,
87		log_len: usize,
88	) -> Result<
89		(Commitment<<Self::Scheme as super::MerkleTreeScheme<F>>::Digest>, Self::Committed),
90		Error,
91	>
92	where
93		ParIter: IndexedParallelIterator<Item: IntoIterator<Item = F>>,
94	{
95		let tree = binary_merkle_tree::build_from_iterator::<F, H, C, _>(
96			self.scheme.compression(),
97			iterated_chunks,
98			log_len,
99		)?;
100
101		let commitment = Commitment {
102			root: tree.root(),
103			depth: tree.log_len,
104		};
105
106		Ok((commitment, tree))
107	}
108}