lambdaworks_crypto/merkle_tree/backends/
field_element_vector.rs1use core::marker::PhantomData;
2
3use crate::hash::poseidon::Poseidon;
4use crate::merkle_tree::traits::IsMerkleTreeBackend;
5use alloc::vec::Vec;
6use lambdaworks_math::{
7 field::{element::FieldElement, traits::IsField},
8 traits::AsBytes,
9};
10use sha3::{
11 digest::{generic_array::GenericArray, OutputSizeUser},
12 Digest,
13};
14
15#[derive(Clone)]
16pub struct FieldElementVectorBackend<F, D: Digest, const NUM_BYTES: usize> {
17 phantom1: PhantomData<F>,
18 phantom2: PhantomData<D>,
19}
20
21impl<F, D: Digest, const NUM_BYTES: usize> Default for FieldElementVectorBackend<F, D, NUM_BYTES> {
22 fn default() -> Self {
23 Self {
24 phantom1: PhantomData,
25 phantom2: PhantomData,
26 }
27 }
28}
29
30impl<F, D: Digest, const NUM_BYTES: usize> IsMerkleTreeBackend
31 for FieldElementVectorBackend<F, D, NUM_BYTES>
32where
33 F: IsField,
34 FieldElement<F>: AsBytes,
35 [u8; NUM_BYTES]: From<GenericArray<u8, <D as OutputSizeUser>::OutputSize>>,
36 Vec<FieldElement<F>>: Sync + Send,
37{
38 type Node = [u8; NUM_BYTES];
39 type Data = Vec<FieldElement<F>>;
40
41 fn hash_data(input: &Vec<FieldElement<F>>) -> [u8; NUM_BYTES] {
42 let mut hasher = D::new();
43 for element in input.iter() {
44 hasher.update(element.as_bytes());
45 }
46 let mut result_hash = [0_u8; NUM_BYTES];
47 result_hash.copy_from_slice(&hasher.finalize());
48 result_hash
49 }
50
51 fn hash_new_parent(left: &[u8; NUM_BYTES], right: &[u8; NUM_BYTES]) -> [u8; NUM_BYTES] {
52 let mut hasher = D::new();
53 hasher.update(left);
54 hasher.update(right);
55 let mut result_hash = [0_u8; NUM_BYTES];
56 result_hash.copy_from_slice(&hasher.finalize());
57 result_hash
58 }
59}
60
61#[derive(Clone, Default)]
62pub struct BatchPoseidonTree<P: Poseidon + Default> {
63 _poseidon: PhantomData<P>,
64}
65
66impl<P> IsMerkleTreeBackend for BatchPoseidonTree<P>
67where
68 P: Poseidon + Default,
69 Vec<FieldElement<P::F>>: Sync + Send,
70 FieldElement<P::F>: Sync + Send,
71{
72 type Node = FieldElement<P::F>;
73 type Data = Vec<FieldElement<P::F>>;
74
75 fn hash_data(input: &Vec<FieldElement<P::F>>) -> FieldElement<P::F> {
76 P::hash_many(input)
77 }
78
79 fn hash_new_parent(
80 left: &FieldElement<P::F>,
81 right: &FieldElement<P::F>,
82 ) -> FieldElement<P::F> {
83 P::hash(left, right)
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use lambdaworks_math::field::{
90 element::FieldElement, fields::fft_friendly::stark_252_prime_field::Stark252PrimeField,
91 };
92 use sha2::Sha512;
93 use sha3::{Keccak256, Keccak512, Sha3_256, Sha3_512};
94
95 use crate::merkle_tree::{
96 backends::field_element_vector::FieldElementVectorBackend, merkle::MerkleTree,
97 };
98
99 type F = Stark252PrimeField;
100 type FE = FieldElement<F>;
101
102 #[test]
103 fn hash_data_field_element_backend_works_with_sha3_256() {
104 let values = [
105 vec![FE::from(2u64), FE::from(11u64)],
106 vec![FE::from(3u64), FE::from(14u64)],
107 vec![FE::from(4u64), FE::from(7u64)],
108 vec![FE::from(5u64), FE::from(3u64)],
109 vec![FE::from(6u64), FE::from(5u64)],
110 vec![FE::from(7u64), FE::from(16u64)],
111 vec![FE::from(8u64), FE::from(19u64)],
112 vec![FE::from(9u64), FE::from(21u64)],
113 ];
114 let merkle_tree =
115 MerkleTree::<FieldElementVectorBackend<F, Sha3_256, 32>>::build(&values).unwrap();
116 let proof = merkle_tree.get_proof_by_pos(0).unwrap();
117 assert!(proof.verify::<FieldElementVectorBackend<F, Sha3_256, 32>>(
118 &merkle_tree.root,
119 0,
120 &values[0]
121 ));
122 }
123
124 #[test]
125 fn hash_data_field_element_backend_works_with_keccak256() {
126 let values = [
127 vec![FE::from(2u64), FE::from(11u64)],
128 vec![FE::from(3u64), FE::from(14u64)],
129 vec![FE::from(4u64), FE::from(7u64)],
130 vec![FE::from(5u64), FE::from(3u64)],
131 vec![FE::from(6u64), FE::from(5u64)],
132 vec![FE::from(7u64), FE::from(16u64)],
133 vec![FE::from(8u64), FE::from(19u64)],
134 vec![FE::from(9u64), FE::from(21u64)],
135 ];
136 let merkle_tree =
137 MerkleTree::<FieldElementVectorBackend<F, Keccak256, 32>>::build(&values).unwrap();
138 let proof = merkle_tree.get_proof_by_pos(0).unwrap();
139 assert!(proof.verify::<FieldElementVectorBackend<F, Keccak256, 32>>(
140 &merkle_tree.root,
141 0,
142 &values[0]
143 ));
144 }
145
146 #[test]
147 fn hash_data_field_element_backend_works_with_sha3_512() {
148 let values = [
149 vec![FE::from(2u64), FE::from(11u64)],
150 vec![FE::from(3u64), FE::from(14u64)],
151 vec![FE::from(4u64), FE::from(7u64)],
152 vec![FE::from(5u64), FE::from(3u64)],
153 vec![FE::from(6u64), FE::from(5u64)],
154 vec![FE::from(7u64), FE::from(16u64)],
155 vec![FE::from(8u64), FE::from(19u64)],
156 vec![FE::from(9u64), FE::from(21u64)],
157 ];
158 let merkle_tree =
159 MerkleTree::<FieldElementVectorBackend<F, Sha3_512, 64>>::build(&values).unwrap();
160 let proof = merkle_tree.get_proof_by_pos(0).unwrap();
161 assert!(proof.verify::<FieldElementVectorBackend<F, Sha3_512, 64>>(
162 &merkle_tree.root,
163 0,
164 &values[0]
165 ));
166 }
167
168 #[test]
169 fn hash_data_field_element_backend_works_with_keccak512() {
170 let values = [
171 vec![FE::from(2u64), FE::from(11u64)],
172 vec![FE::from(3u64), FE::from(14u64)],
173 vec![FE::from(4u64), FE::from(7u64)],
174 vec![FE::from(5u64), FE::from(3u64)],
175 vec![FE::from(6u64), FE::from(5u64)],
176 vec![FE::from(7u64), FE::from(16u64)],
177 vec![FE::from(8u64), FE::from(19u64)],
178 vec![FE::from(9u64), FE::from(21u64)],
179 ];
180 let merkle_tree =
181 MerkleTree::<FieldElementVectorBackend<F, Keccak512, 64>>::build(&values).unwrap();
182 let proof = merkle_tree.get_proof_by_pos(0).unwrap();
183 assert!(proof.verify::<FieldElementVectorBackend<F, Keccak512, 64>>(
184 &merkle_tree.root,
185 0,
186 &values[0]
187 ));
188 }
189
190 #[test]
191 fn hash_data_field_element_backend_works_with_sha2_512() {
192 let values = [
193 vec![FE::from(2u64), FE::from(11u64)],
194 vec![FE::from(3u64), FE::from(14u64)],
195 vec![FE::from(4u64), FE::from(7u64)],
196 vec![FE::from(5u64), FE::from(3u64)],
197 vec![FE::from(6u64), FE::from(5u64)],
198 vec![FE::from(7u64), FE::from(16u64)],
199 vec![FE::from(8u64), FE::from(19u64)],
200 vec![FE::from(9u64), FE::from(21u64)],
201 ];
202 let merkle_tree =
203 MerkleTree::<FieldElementVectorBackend<F, Sha512, 64>>::build(&values).unwrap();
204 let proof = merkle_tree.get_proof_by_pos(0).unwrap();
205 assert!(proof.verify::<FieldElementVectorBackend<F, Sha512, 64>>(
206 &merkle_tree.root,
207 0,
208 &values[0]
209 ));
210 }
211}