88#include <string.h>
99#include "../notrandombytes/notrandombytes.h"
1010
11+ #include "../../mldsa/src/fips202/keccakf1600.h"
1112#include "../../mldsa/src/poly.h"
1213#include "../../mldsa/src/poly_kl.h"
1314#include "../../mldsa/src/polyvec.h"
1415
1516#ifndef NUM_RANDOM_TESTS
1617#ifdef MLDSA_DEBUG
17- #define NUM_RANDOM_TESTS 1000
18+ #define NUM_RANDOM_TESTS 800
1819#else
19- #define NUM_RANDOM_TESTS 5000
20+ #define NUM_RANDOM_TESTS 4000
2021#endif
2122#endif /* !NUM_RANDOM_TESTS */
2223
@@ -44,6 +45,59 @@ void mld_poly_pointwise_montgomery_c(mld_poly *c, const mld_poly *a,
4445void mld_polyvecl_pointwise_acc_montgomery_c (mld_poly * w , const mld_polyvecl * u ,
4546 const mld_polyvecl * v );
4647void mld_polyz_unpack_c (mld_poly * r , const uint8_t a [MLDSA_POLYZ_PACKEDBYTES ]);
48+ void mld_keccakf1600_permute_c (uint64_t * state );
49+
50+ #if defined(MLD_USE_FIPS202_X1_NATIVE ) || defined(MLD_USE_FIPS202_X4_NATIVE )
51+ static void print_u64_array (const char * label , const uint64_t * array ,
52+ size_t len )
53+ {
54+ size_t i ;
55+ fprintf (stderr , "%s:\n" , label );
56+ for (i = 0 ; i < len ; i ++ )
57+ {
58+ if (i % 4 == 0 )
59+ {
60+ fprintf (stderr , " " );
61+ }
62+ fprintf (stderr , "%016llx" , (unsigned long long )array [i ]);
63+ if (i % 4 == 3 )
64+ {
65+ fprintf (stderr , "\n" );
66+ }
67+ else
68+ {
69+ fprintf (stderr , " " );
70+ }
71+ }
72+ if (len % 4 != 0 )
73+ {
74+ fprintf (stderr , "\n" );
75+ }
76+ }
77+
78+ static int compare_u64_arrays (const uint64_t * a , const uint64_t * b ,
79+ unsigned len , const char * test_name )
80+ {
81+ unsigned i ;
82+ for (i = 0 ; i < len ; i ++ )
83+ {
84+ if (a [i ] != b [i ])
85+ {
86+ fprintf (stderr , "FAIL: %s\n" , test_name );
87+ fprintf (
88+ stderr ,
89+ " First difference at index %u: got=0x%016llx, expected=0x%016llx\n" ,
90+ i , (unsigned long long )a [i ], (unsigned long long )b [i ]);
91+ print_u64_array ("Got" , a , len );
92+ print_u64_array ("Expected" , b , len );
93+ return 0 ;
94+ }
95+ }
96+ return 1 ;
97+ }
98+
99+ #endif /* MLD_USE_FIPS202_X1_NATIVE || MLD_USE_FIPS202_X4_NATIVE */
100+
47101#if defined(MLD_USE_NATIVE_NTT ) || defined(MLD_USE_NATIVE_INTT ) || \
48102 defined(MLD_USE_NATIVE_POLY_DECOMPOSE_32 ) || \
49103 defined(MLD_USE_NATIVE_POLY_DECOMPOSE_88 ) || \
@@ -56,7 +110,9 @@ void mld_polyz_unpack_c(mld_poly *r, const uint8_t a[MLDSA_POLYZ_PACKEDBYTES]);
56110 defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 ) || \
57111 defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 ) || \
58112 defined(MLD_USE_NATIVE_POLYZ_UNPACK_17 ) || \
59- defined(MLD_USE_NATIVE_POLYZ_UNPACK_19 )
113+ defined(MLD_USE_NATIVE_POLYZ_UNPACK_19 ) || \
114+ defined(MLD_USE_FIPS202_X1_NATIVE ) || defined(MLD_USE_FIPS202_X4_NATIVE )
115+
60116/* Backend unit test helper functions */
61117static void print_i32_array (const char * label , const int32_t * array , size_t len )
62118{
@@ -522,6 +578,57 @@ static int test_native_polyz_unpack(void)
522578#endif /* MLD_USE_NATIVE_POLYZ_UNPACK_17 || MLD_USE_NATIVE_POLYZ_UNPACK_19 */
523579
524580
581+ #ifdef MLD_USE_FIPS202_X1_NATIVE
582+ static int test_keccakf1600_permute (void )
583+ {
584+ uint64_t state [MLD_KECCAK_LANES ];
585+ uint64_t state_ref [MLD_KECCAK_LANES ];
586+ int i ;
587+
588+ for (i = 0 ; i < NUM_RANDOM_TESTS ; i ++ )
589+ {
590+ randombytes ((uint8_t * )state , sizeof (state ));
591+ memcpy (state_ref , state , sizeof (state ));
592+
593+ mld_keccakf1600_permute (state );
594+ mld_keccakf1600_permute_c (state_ref );
595+
596+ CHECK (compare_u64_arrays (state , state_ref , MLD_KECCAK_LANES ,
597+ "keccakf1600_permute" ));
598+ }
599+
600+ return 0 ;
601+ }
602+ #endif /* MLD_USE_FIPS202_X1_NATIVE */
603+
604+ #ifdef MLD_USE_FIPS202_X4_NATIVE
605+ static int test_keccakf1600x4_permute (void )
606+ {
607+ uint64_t state_x4 [MLD_KECCAK_LANES * MLD_KECCAK_WAY ];
608+ uint64_t state_x1 [MLD_KECCAK_LANES * MLD_KECCAK_WAY ];
609+ int i , j ;
610+
611+ for (i = 0 ; i < NUM_RANDOM_TESTS ; i ++ )
612+ {
613+ randombytes ((uint8_t * )state_x4 , sizeof (state_x4 ));
614+ memcpy (state_x1 , state_x4 , sizeof (state_x4 ));
615+
616+ mld_keccakf1600x4_permute (state_x4 );
617+
618+ for (j = 0 ; j < MLD_KECCAK_WAY ; j ++ )
619+ {
620+ mld_keccakf1600_permute_c (state_x1 + j * MLD_KECCAK_LANES );
621+ }
622+
623+ CHECK (compare_u64_arrays (state_x4 , state_x1 ,
624+ MLD_KECCAK_LANES * MLD_KECCAK_WAY ,
625+ "keccakf1600x4_permute" ));
626+ }
627+
628+ return 0 ;
629+ }
630+ #endif /* MLD_USE_FIPS202_X4_NATIVE */
631+
525632static int test_backend_units (void )
526633{
527634 /* Set fixed seed for reproducible tests */
@@ -569,6 +676,14 @@ static int test_backend_units(void)
569676 CHECK (test_native_polyz_unpack () == 0 );
570677#endif
571678
679+ #ifdef MLD_USE_FIPS202_X1_NATIVE
680+ CHECK (test_keccakf1600_permute () == 0 );
681+ #endif
682+
683+ #ifdef MLD_USE_FIPS202_X4_NATIVE
684+ CHECK (test_keccakf1600x4_permute () == 0 );
685+ #endif
686+
572687 return 0 ;
573688}
574689#endif /* MLD_USE_NATIVE_NTT || MLD_USE_NATIVE_INTT || \
@@ -579,7 +694,8 @@ static int test_backend_units(void)
579694 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4 || \
580695 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 || \
581696 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 || \
582- MLD_USE_NATIVE_POLYZ_UNPACK_17 || MLD_USE_NATIVE_POLYZ_UNPACK_19 */
697+ MLD_USE_NATIVE_POLYZ_UNPACK_17 || MLD_USE_NATIVE_POLYZ_UNPACK_19 || \
698+ MLD_USE_FIPS202_X1_NATIVE || MLD_USE_FIPS202_X4_NATIVE */
583699
584700int main (void )
585701{
@@ -600,7 +716,8 @@ int main(void)
600716 defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 ) || \
601717 defined(MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 ) || \
602718 defined(MLD_USE_NATIVE_POLYZ_UNPACK_17 ) || \
603- defined(MLD_USE_NATIVE_POLYZ_UNPACK_19 )
719+ defined(MLD_USE_NATIVE_POLYZ_UNPACK_19 ) || \
720+ defined(MLD_USE_FIPS202_X1_NATIVE ) || defined(MLD_USE_FIPS202_X4_NATIVE )
604721 CHECK (test_backend_units () == 0 );
605722#endif /* MLD_USE_NATIVE_NTT || MLD_USE_NATIVE_INTT || \
606723 MLD_USE_NATIVE_POLY_DECOMPOSE_32 || MLD_USE_NATIVE_POLY_DECOMPOSE_88 \
@@ -610,7 +727,8 @@ int main(void)
610727 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L4 || \
611728 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L5 || \
612729 MLD_USE_NATIVE_POLYVECL_POINTWISE_ACC_MONTGOMERY_L7 || \
613- MLD_USE_NATIVE_POLYZ_UNPACK_17 || MLD_USE_NATIVE_POLYZ_UNPACK_19 */
730+ MLD_USE_NATIVE_POLYZ_UNPACK_17 || MLD_USE_NATIVE_POLYZ_UNPACK_19 || \
731+ MLD_USE_FIPS202_X1_NATIVE || MLD_USE_FIPS202_X4_NATIVE */
614732
615733
616734 return 0 ;
0 commit comments