@@ -6,6 +6,7 @@ use ethers::{
66 providers:: { Http , Middleware , Provider } ,
77 types:: Filter ,
88} ;
9+ use lambdaworks_crypto:: merkle_tree:: { merkle:: MerkleTree , traits:: IsMerkleTreeBackend } ;
910use sha3:: { Digest , Keccak256 } ;
1011
1112/// How much to go back from current block if from_block is not provided
@@ -24,6 +25,12 @@ pub enum AggregationModeVerificationData {
2425 } ,
2526}
2627
28+ impl Default for AggregationModeVerificationData {
29+ fn default ( ) -> Self {
30+ todo ! ( )
31+ }
32+ }
33+
2734impl AggregationModeVerificationData {
2835 fn commitment ( & self ) -> [ u8 ; 32 ] {
2936 match self {
@@ -46,6 +53,33 @@ impl AggregationModeVerificationData {
4653 }
4754}
4855
56+ // We use a newtype wrapper around `[u8; 32]` because Rust's orphan rule
57+ // prevents implementing a foreign trait (`IsMerkleTreeBackend`) for a foreign type (`[u8; 32]`).
58+ #[ derive( Default , PartialEq , Eq ) ]
59+ struct Hash32 ( [ u8 ; 32 ] ) ;
60+
61+ impl IsMerkleTreeBackend for Hash32 {
62+ type Data = Hash32 ;
63+ type Node = [ u8 ; 32 ] ;
64+
65+ fn hash_data ( leaf : & Self :: Data ) -> Self :: Node {
66+ let mut hasher = Keccak256 :: new ( ) ;
67+ hasher. update ( leaf. 0 ) ;
68+ hasher. finalize ( ) . into ( )
69+ }
70+
71+ fn hash_leaves ( leaves : & [ Self :: Data ] ) -> Vec < Self :: Node > {
72+ leaves. iter ( ) . map ( |l| l. 0 ) . collect ( )
73+ }
74+
75+ fn hash_new_parent ( child_1 : & Self :: Node , child_2 : & Self :: Node ) -> Self :: Node {
76+ let mut hasher = Keccak256 :: new ( ) ;
77+ hasher. update ( child_1) ;
78+ hasher. update ( child_2) ;
79+ hasher. finalize ( ) . into ( )
80+ }
81+ }
82+
4983#[ derive( Debug ) ]
5084pub enum ProofVerificationAggModeError {
5185 ProvingSystemNotSupportedInAggMode ,
@@ -158,10 +192,14 @@ pub async fn is_proof_verified_in_aggregation_mode(
158192
159193 let blob_bytes =
160194 hex:: decode ( blob_data. blob . replace ( "0x" , "" ) ) . expect ( "A valid hex encoded data" ) ;
161- let proof_commitments = decoded_blob ( blob_bytes) ;
162-
163- if proof_commitments. contains ( & verification_data. commitment ( ) ) {
164- return if verify_blob_merkle_root ( proof_commitments, merkle_root) {
195+ let proof_commitments: Vec < Hash32 > = decoded_blob ( blob_bytes)
196+ . iter ( )
197+ . map ( |p| Hash32 ( * p) )
198+ . collect ( ) ;
199+ let merkle_tree: MerkleTree < Hash32 > = MerkleTree :: build ( & proof_commitments) . unwrap ( ) ;
200+
201+ if proof_commitments. contains ( & Hash32 ( verification_data. commitment ( ) ) ) {
202+ return if merkle_tree. root == merkle_root {
165203 Ok ( merkle_root)
166204 } else {
167205 Err ( ProofVerificationAggModeError :: UnmatchedBlobAndEventMerkleRoot )
@@ -206,25 +244,3 @@ fn decoded_blob(blob_data: Vec<u8>) -> Vec<[u8; 32]> {
206244
207245 proof_hashes
208246}
209-
210- pub fn combine_hashes ( hash_a : & [ u8 ; 32 ] , hash_b : & [ u8 ; 32 ] ) -> [ u8 ; 32 ] {
211- let mut hasher = Keccak256 :: new ( ) ;
212- hasher. update ( hash_a) ;
213- hasher. update ( hash_b) ;
214- hasher. finalize ( ) . into ( )
215- }
216-
217- fn verify_blob_merkle_root ( mut commitments : Vec < [ u8 ; 32 ] > , merkle_root : [ u8 ; 32 ] ) -> bool {
218- while commitments. len ( ) > 1 {
219- commitments = commitments
220- . chunks ( 2 )
221- . map ( |chunk| match chunk {
222- [ a, b] => combine_hashes ( a, b) ,
223- [ a] => combine_hashes ( a, a) ,
224- _ => panic ! ( "Unexpected chunk size in leaves" ) ,
225- } )
226- . collect ( )
227- }
228-
229- commitments[ 0 ] == merkle_root
230- }
0 commit comments