@@ -19,58 +19,88 @@ use utils::log2_ceil_usize;
1919
2020use crate :: DenseMatrix ;
2121use crate :: Dimensions ;
22- use crate :: FlatMatrixView ;
2322use crate :: Matrix ;
2423pub use symetric:: DIGEST_ELEMS ;
2524
26- pub ( crate ) type RoundMerkleTree < F , EF > = WhirMerkleTree < F , FlatMatrixView < F , EF , DenseMatrix < EF > > , DIGEST_ELEMS > ;
25+ pub ( crate ) type RoundMerkleTree < F > = WhirMerkleTree < F , DenseMatrix < F > , DIGEST_ELEMS > ;
2726
2827#[ allow( clippy:: missing_transmute_annotations) ]
2928pub ( crate ) fn merkle_commit < F : Field , EF : ExtensionField < F > > (
3029 matrix : DenseMatrix < EF > ,
3130 full_n_cols : usize ,
3231 effective_n_cols : usize ,
33- ) -> ( [ F ; DIGEST_ELEMS ] , RoundMerkleTree < F , EF > ) {
34- let perm = default_koalabear_poseidon1_16 ( ) ;
32+ ) -> ( [ F ; DIGEST_ELEMS ] , RoundMerkleTree < F > ) {
3533 if TypeId :: of :: < ( F , EF ) > ( ) == TypeId :: of :: < ( KoalaBear , QuinticExtensionFieldKB ) > ( ) {
3634 let matrix = unsafe { std:: mem:: transmute :: < _ , DenseMatrix < QuinticExtensionFieldKB > > ( matrix) } ;
37- let view = FlatMatrixView :: new ( matrix) ;
3835 let dim = <QuinticExtensionFieldKB as BasedVectorSpace < KoalaBear > >:: DIMENSION ;
36+ let dft_base_width = matrix. width * dim;
3937 let full_base_width = full_n_cols * dim;
4038 let effective_base_width = effective_n_cols * dim;
41- let tree =
42- WhirMerkleTree :: new :: < PFPacking < KoalaBear > , _ , 16 , 8 > ( & perm, view, full_base_width, effective_base_width) ;
39+ let base_values = QuinticExtensionFieldKB :: flatten_to_base ( matrix. values ) ;
40+ let base_matrix = DenseMatrix :: < KoalaBear > :: new ( base_values, dft_base_width) ;
41+ let tree = build_merkle_tree_koalabear ( base_matrix, full_base_width, effective_base_width) ;
4342 let root: [ _ ; DIGEST_ELEMS ] = tree. root ( ) ;
4443 let root = unsafe { std:: mem:: transmute_copy :: < _ , [ F ; DIGEST_ELEMS ] > ( & root) } ;
45- let tree = unsafe { std:: mem:: transmute :: < _ , RoundMerkleTree < F , EF > > ( tree) } ;
44+ let tree = unsafe { std:: mem:: transmute :: < _ , RoundMerkleTree < F > > ( tree) } ;
4645 ( root, tree)
4746 } else if TypeId :: of :: < ( F , EF ) > ( ) == TypeId :: of :: < ( KoalaBear , KoalaBear ) > ( ) {
4847 let matrix = unsafe { std:: mem:: transmute :: < _ , DenseMatrix < KoalaBear > > ( matrix) } ;
49- let tree = WhirMerkleTree :: new :: < PFPacking < KoalaBear > , _ , 16 , 8 > ( & perm , matrix, full_n_cols, effective_n_cols) ;
48+ let tree = build_merkle_tree_koalabear ( matrix, full_n_cols, effective_n_cols) ;
5049 let root: [ _ ; DIGEST_ELEMS ] = tree. root ( ) ;
5150 let root = unsafe { std:: mem:: transmute_copy :: < _ , [ F ; DIGEST_ELEMS ] > ( & root) } ;
52- let tree = unsafe { std:: mem:: transmute :: < _ , RoundMerkleTree < F , EF > > ( tree) } ;
51+ let tree = unsafe { std:: mem:: transmute :: < _ , RoundMerkleTree < F > > ( tree) } ;
5352 ( root, tree)
5453 } else {
5554 unimplemented ! ( )
5655 }
5756}
5857
58+ #[ instrument( name = "build merkle tree" , skip_all) ]
59+ fn build_merkle_tree_koalabear (
60+ leaf : DenseMatrix < KoalaBear > ,
61+ full_base_width : usize ,
62+ effective_base_width : usize ,
63+ ) -> RoundMerkleTree < KoalaBear > {
64+ let perm = default_koalabear_poseidon1_16 ( ) ;
65+ let n_zero_suffix_rate_chunks = ( full_base_width - effective_base_width) / 8 ;
66+ let first_layer = if n_zero_suffix_rate_chunks >= 2 {
67+ let scalar_state = symetric:: precompute_zero_suffix_state :: < KoalaBear , _ , 16 , 8 , DIGEST_ELEMS > (
68+ & perm,
69+ n_zero_suffix_rate_chunks,
70+ ) ;
71+ let packed_state: [ PFPacking < KoalaBear > ; 16 ] =
72+ std:: array:: from_fn ( |i| PFPacking :: < KoalaBear > :: from_fn ( |_| scalar_state[ i] ) ) ;
73+ first_digest_layer_with_initial_state :: < PFPacking < KoalaBear > , _ , _ , DIGEST_ELEMS , 16 , 8 > (
74+ & perm,
75+ & leaf,
76+ & packed_state,
77+ effective_base_width,
78+ )
79+ } else {
80+ first_digest_layer :: < PFPacking < KoalaBear > , _ , _ , DIGEST_ELEMS , 16 , 8 > ( & perm, & leaf, full_base_width)
81+ } ;
82+ let tree = symetric:: merkle:: MerkleTree :: from_first_layer :: < PFPacking < KoalaBear > , _ , 16 > ( & perm, first_layer) ;
83+ WhirMerkleTree {
84+ leaf,
85+ tree,
86+ full_leaf_base_width : full_base_width,
87+ }
88+ }
89+
5990#[ allow( clippy:: missing_transmute_annotations) ]
6091pub ( crate ) fn merkle_open < F : Field , EF : ExtensionField < F > > (
61- merkle_tree : & RoundMerkleTree < F , EF > ,
92+ merkle_tree : & RoundMerkleTree < F > ,
6293 index : usize ,
6394) -> ( Vec < EF > , Vec < [ F ; DIGEST_ELEMS ] > ) {
6495 if TypeId :: of :: < ( F , EF ) > ( ) == TypeId :: of :: < ( KoalaBear , QuinticExtensionFieldKB ) > ( ) {
65- let merkle_tree =
66- unsafe { std:: mem:: transmute :: < _ , & RoundMerkleTree < KoalaBear , QuinticExtensionFieldKB > > ( merkle_tree) } ;
96+ let merkle_tree = unsafe { std:: mem:: transmute :: < _ , & RoundMerkleTree < KoalaBear > > ( merkle_tree) } ;
6797 let ( inner_leaf, proof) = merkle_tree. open ( index) ;
6898 let leaf = QuinticExtensionFieldKB :: reconstitute_from_base ( inner_leaf) ;
6999 let leaf = unsafe { std:: mem:: transmute :: < _ , Vec < EF > > ( leaf) } ;
70100 let proof = unsafe { std:: mem:: transmute :: < _ , Vec < [ F ; DIGEST_ELEMS ] > > ( proof) } ;
71101 ( leaf, proof)
72102 } else if TypeId :: of :: < ( F , EF ) > ( ) == TypeId :: of :: < ( KoalaBear , KoalaBear ) > ( ) {
73- let merkle_tree = unsafe { std:: mem:: transmute :: < _ , & RoundMerkleTree < KoalaBear , KoalaBear > > ( merkle_tree) } ;
103+ let merkle_tree = unsafe { std:: mem:: transmute :: < _ , & RoundMerkleTree < KoalaBear > > ( merkle_tree) } ;
74104 let ( inner_leaf, proof) = merkle_tree. open ( index) ;
75105 let leaf = KoalaBear :: reconstitute_from_base ( inner_leaf) ;
76106 let leaf = unsafe { std:: mem:: transmute :: < _ , Vec < EF > > ( leaf) } ;
0 commit comments