@@ -6,10 +6,14 @@ use backend::*;
66use utils:: { ToUsize , poseidon16_compress} ;
77
88/// Dispatch `mds_circ_16` through concrete types.
9- /// All five AIR types (`F`, `EF`, `FPacking<F>`, `EFPacking<EF>`, `SymbolicExpression<KoalaBear>`)
10- /// satisfy the `PrimeCharacteristicRing + Mul<KoalaBear>` bound required by `mds_circ_16` .
9+ /// For `SymbolicExpression` we use the dense form so the zkDSL generator can
10+ /// emit `dot_product_be` precompile calls instead of Karatsuba arithmetic .
1111#[ inline( always) ]
1212fn mds_air_16 < A : PrimeCharacteristicRing + ' static > ( state : & mut [ A ; WIDTH ] ) {
13+ if TypeId :: of :: < A > ( ) == TypeId :: of :: < SymbolicExpression < KoalaBear > > ( ) {
14+ dense_mat_vec_air_16 ( mds_dense_16 ( ) , state) ;
15+ return ;
16+ }
1317 macro_rules! dispatch {
1418 ( $t: ty) => {
1519 if TypeId :: of:: <A >( ) == TypeId :: of:: <$t>( ) {
@@ -22,10 +26,23 @@ fn mds_air_16<A: PrimeCharacteristicRing + 'static>(state: &mut [A; WIDTH]) {
2226 dispatch ! ( EF ) ;
2327 dispatch ! ( FPacking <F >) ;
2428 dispatch ! ( EFPacking <EF >) ;
25- dispatch ! ( SymbolicExpression <KoalaBear >) ;
2629 unreachable ! ( )
2730}
2831
32+ fn mds_dense_16 ( ) -> & ' static [ [ F ; 16 ] ; 16 ] {
33+ use std:: sync:: OnceLock ;
34+ static MAT : OnceLock < [ [ KoalaBear ; 16 ] ; 16 ] > = OnceLock :: new ( ) ;
35+ MAT . get_or_init ( || {
36+ let cols: [ [ F ; 16 ] ; 16 ] = std:: array:: from_fn ( |j| {
37+ let mut e = [ F :: ZERO ; 16 ] ;
38+ e[ j] = F :: ONE ;
39+ mds_circ_16 ( & mut e) ;
40+ e
41+ } ) ;
42+ std:: array:: from_fn ( |i| std:: array:: from_fn ( |j| cols[ j] [ i] ) )
43+ } )
44+ }
45+
2946/// Add a `KoalaBear` constant to any AIR type.
3047#[ inline( always) ]
3148fn add_kb < A : ' static > ( a : & mut A , value : F ) {
0 commit comments