Skip to content

Commit 464c622

Browse files
mkannwischerhanno-becker
authored andcommitted
Adjust KAT test to work with PCT
Currently our KAT tests do not work in case the pairwise-consistency test (PCT) is enabled through MLD_CONFIG_KEYGEN_PCT. The reason for this is that when PCT is enabled, a signature is generated at the end of key generation which requires randomness to be sampled from randombytes() messing with the state of the deterministic random number generator used for KAT tests. To work around this, this commit changes the KAT tests to follow the same approach that is also used by mlkem-native: Only use the de-randomized APIs and derive all random coins deterministically using SHAKE instead of randombytes(). This enabled KAT tests even when PCT is enabled. Unfortunately, it requires changing the KAT hashes once. Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent fe3aafc commit 464c622

File tree

2 files changed

+33
-26
lines changed

2 files changed

+33
-26
lines changed

META.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ implementations:
88
length-public-key: 1312
99
length-secret-key: 2560
1010
length-signature: 2420
11-
kat-sha256: 9d4ae4ea0c1b56f96650838c7425cc2167a0754643b79a93bee28cb039ac2fc2
11+
kat-sha256: 33e7eb7e3b4965fc8b8274ebf8a222c519008ec242b3f753d1bc240f1ee3cb1f
1212
- name: ML-DSA-65
1313
claimed-nist-level: 3
1414
length-public-key: 1952
1515
length-secret-key: 4032
1616
length-signature: 3309
17-
kat-sha256: b66d7de88a3bec2d7cf171a7a1198f6de47384e2a1dd3bf7d07432316a9a40f8
17+
kat-sha256: 2ff0ddcd0dc08b746aa04853d6f84c82c6c8ac38783c9061aed78e29c1698ae5
1818
- name: ML-DSA-87
1919
claimed-nist-level: 5
2020
length-public-key: 2592
2121
length-secret-key: 4896
2222
length-signature: 4627
23-
kat-sha256: 93029142bf62f67ae3df0d31c2fccf8c9fa1e61ab388048e1b3faeb9451a61ce
23+
kat-sha256: 1bfb25b29f6f2bc89057e3bddee055a8f7df563b0e747004b2968159f7739afa

test/gen_KAT.c

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
#include <stddef.h>
77
#include <stdio.h>
88
#include <string.h>
9-
#include "../mldsa/api.h"
9+
#include "../mldsa/fips202/fips202.h"
10+
#include "../mldsa/sign.h"
1011
#include "../mldsa/sys.h"
1112
#include "notrandombytes/notrandombytes.h"
1213

@@ -30,55 +31,61 @@ static void print_hex(const uint8_t *data, size_t size)
3031

3132
int main(void)
3233
{
33-
unsigned i, j;
34+
unsigned i;
3435
int rc;
3536
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
3637
uint8_t sk[CRYPTO_SECRETKEYBYTES];
37-
uint8_t sm[MAXMLEN + CRYPTO_BYTES];
3838
uint8_t s[CRYPTO_BYTES];
39-
uint8_t m[MAXMLEN];
40-
uint8_t m2[MAXMLEN + CRYPTO_BYTES];
41-
size_t smlen;
39+
uint8_t *m;
40+
/* empty ctx */
41+
uint8_t pre[2] = {0, 0};
4242
size_t slen;
43-
size_t mlen;
43+
44+
const uint8_t seed[64] = {
45+
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
46+
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
47+
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
48+
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
49+
};
50+
uint8_t coins[MLDSA_SEEDBYTES + MLDSA_RNDBYTES + MAXMLEN];
4451

4552
#if defined(MLD_SYS_WINDOWS)
4653
/* Disable automatic CRLF conversion on Windows to match testvector hashes */
4754
_setmode(_fileno(stdout), _O_BINARY);
4855
#endif
4956

57+
/*
58+
* We cannot rely on randombytes in the KAT test as randombytes() is used
59+
* inside of crypto_sign_signature() which is called as a part of
60+
* key generation in case PCT (pairwise-consistency test) is enabled.
61+
* To allow KAT tests to still pass successfully, we derandomize the
62+
* KAT test to only use deterministic randomness derived using SHAKE.
63+
*/
64+
65+
shake256(coins, sizeof(coins), seed, sizeof(seed));
66+
5067
for (i = 0; i < MAXMLEN; i = (i == 0) ? i + 1 : i << 2)
5168
{
52-
randombytes(m, i);
69+
shake256(coins, sizeof(coins), coins, sizeof(coins));
70+
m = coins + MLDSA_SEEDBYTES + MLDSA_RNDBYTES;
5371

54-
55-
crypto_sign_keypair(pk, sk);
72+
crypto_sign_keypair_internal(pk, sk, coins);
5673

5774
print_hex(pk, CRYPTO_PUBLICKEYBYTES);
5875
print_hex(sk, CRYPTO_SECRETKEYBYTES);
5976

60-
crypto_sign(sm, &smlen, m, i, NULL, CTXLEN, sk);
61-
crypto_sign_signature(s, &slen, m, i, NULL, CTXLEN, sk);
77+
crypto_sign_signature_internal(s, &slen, m, i, pre, sizeof(pre),
78+
coins + MLDSA_SEEDBYTES, sk, 0);
6279

63-
print_hex(sm, smlen);
6480
print_hex(s, slen);
6581

66-
rc = crypto_sign_open(m2, &mlen, sm, smlen, NULL, CTXLEN, pk);
67-
rc |= crypto_sign_verify(s, slen, m, i, NULL, CTXLEN, pk);
82+
rc = crypto_sign_verify(s, slen, m, i, NULL, CTXLEN, pk);
6883

6984
if (rc)
7085
{
7186
printf("ERROR: signature verification failed\n");
7287
return -1;
7388
}
74-
for (j = 0; j < i; j++)
75-
{
76-
if (m2[j] != m[j])
77-
{
78-
printf("ERROR: message recovery failed\n");
79-
return -1;
80-
}
81-
}
8289
}
8390
return 0;
8491
}

0 commit comments

Comments
 (0)