Skip to content

Commit 6b9788a

Browse files
willieyzhanno-becker
authored andcommitted
Port: add native Keccak x1 and x4 unit tests
Add unit tests for keccakf1600 x1 and x4 permutation functions that compare native implementations against the C reference implementation. - test_keccakf1600_permute: tests x1 permutation when MLD_USE_FIPS202_X1_NATIVE - test_keccakf1600x4_permute: tests x4 permutation when MLD_USE_FIPS202_X4_NATIVE - Expose mld_keccakf1600_permute_c via MLD_STATIC_TESTABLE for testing Signed-off-by: willieyz <[email protected]>
1 parent 87f7a12 commit 6b9788a

File tree

2 files changed

+126
-7
lines changed

2 files changed

+126
-7
lines changed

mldsa/src/fips202/keccakf1600.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ static const uint64_t mld_KeccakF_RoundConstants[MLD_KECCAK_NROUNDS] = {
138138
(uint64_t)0x8000000080008081ULL, (uint64_t)0x8000000000008080ULL,
139139
(uint64_t)0x0000000080000001ULL, (uint64_t)0x8000000080008008ULL};
140140

141-
static void mld_keccakf1600_permute_c(uint64_t *state)
141+
MLD_STATIC_TESTABLE
142+
void mld_keccakf1600_permute_c(uint64_t *state)
142143
{
143144
unsigned round;
144145

test/src/test_unit.c

Lines changed: 124 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
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,
4445
void mld_polyvecl_pointwise_acc_montgomery_c(mld_poly *w, const mld_polyvecl *u,
4546
const mld_polyvecl *v);
4647
void 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 */
61117
static 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+
525632
static 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

584700
int 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

Comments
 (0)