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