Skip to content

Commit eb80797

Browse files
committed
Extended API: Adjust tests and benchmarks
Signed-off-by: Matthias J. Kannwischer <[email protected]>
1 parent 40a1319 commit eb80797

File tree

2 files changed

+214
-4
lines changed

2 files changed

+214
-4
lines changed

test/bench_mlkem.c

Lines changed: 154 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@
88
#include <stdlib.h>
99
#include <string.h>
1010
#include "../mlkem/common.h"
11-
#include "../mlkem/mlkem_native.h"
11+
#include "../mlkem/kem.h"
1212
#include "../mlkem/randombytes.h"
1313
#include "hal.h"
1414

15+
#define CRYPTO_PUBLICKEYBYTES MLKEM_INDCCA_PUBLICKEYBYTES
16+
#define CRYPTO_SECRETKEYBYTES MLKEM_INDCCA_SECRETKEYBYTES
17+
#define CRYPTO_CIPHERTEXTBYTES MLKEM_INDCCA_CIPHERTEXTBYTES
18+
#define CRYPTO_BYTES MLKEM_SYMBYTES
19+
1520
#define NWARMUP 50
1621
#define NITERATIONS 300
1722
#define NTESTS 500
@@ -35,15 +40,15 @@ static int cmp_uint64_t(const void *a, const void *b)
3540

3641
static void print_median(const char *txt, uint64_t cyc[NTESTS])
3742
{
38-
printf("%10s cycles = %" PRIu64 "\n", txt, cyc[NTESTS >> 1] / NITERATIONS);
43+
printf("%14s cycles = %" PRIu64 "\n", txt, cyc[NTESTS >> 1] / NITERATIONS);
3944
}
4045

4146
static int percentiles[] = {1, 10, 20, 30, 40, 50, 60, 70, 80, 90, 99};
4247

4348
static void print_percentile_legend(void)
4449
{
4550
unsigned i;
46-
printf("%21s", "percentile");
51+
printf("%25s", "percentile");
4752
for (i = 0; i < sizeof(percentiles) / sizeof(percentiles[0]); i++)
4853
{
4954
printf("%7d", percentiles[i]);
@@ -54,7 +59,7 @@ static void print_percentile_legend(void)
5459
static void print_percentiles(const char *txt, uint64_t cyc[NTESTS])
5560
{
5661
unsigned i;
57-
printf("%10s percentiles:", txt);
62+
printf("%14s percentiles:", txt);
5863
for (i = 0; i < sizeof(percentiles) / sizeof(percentiles[0]); i++)
5964
{
6065
printf("%7" PRIu64, (cyc)[NTESTS * percentiles[i] / 100] / NITERATIONS);
@@ -72,6 +77,19 @@ static int bench(void)
7277
unsigned char kg_rand[2 * CRYPTO_BYTES], enc_rand[CRYPTO_BYTES];
7378
uint64_t cycles_kg[NTESTS], cycles_enc[NTESTS], cycles_dec[NTESTS];
7479

80+
81+
mlk_public_key pks;
82+
mlk_secret_key sks;
83+
uint64_t cycles_kg_struct[NTESTS];
84+
uint64_t cycles_pk_marshal[NTESTS];
85+
uint64_t cycles_sk_marshal[NTESTS];
86+
87+
uint64_t cycles_pk_parse[NTESTS];
88+
uint64_t cycles_enc_struct[NTESTS];
89+
90+
uint64_t cycles_sk_parse[NTESTS];
91+
uint64_t cycles_dec_struct[NTESTS];
92+
7593
unsigned i, j;
7694
uint64_t t0, t1;
7795

@@ -125,16 +143,140 @@ static int bench(void)
125143

126144
CHECK(ret == 0);
127145
CHECK(memcmp(key_a, key_b, CRYPTO_BYTES) == 0);
146+
147+
148+
/* Key-pair generation */
149+
for (j = 0; j < NWARMUP; j++)
150+
{
151+
ret |= crypto_kem_keypair_derand_struct(&pks, &sks, kg_rand);
152+
}
153+
154+
t0 = get_cyclecounter();
155+
for (j = 0; j < NITERATIONS; j++)
156+
{
157+
ret |= crypto_kem_keypair_derand_struct(&pks, &sks, kg_rand);
158+
}
159+
t1 = get_cyclecounter();
160+
cycles_kg_struct[i] = t1 - t0;
161+
162+
163+
/* Marshal public key */
164+
for (j = 0; j < NWARMUP; j++)
165+
{
166+
crypto_kem_marshal_pk(pk, &pks);
167+
}
168+
169+
t0 = get_cyclecounter();
170+
for (j = 0; j < NITERATIONS; j++)
171+
{
172+
crypto_kem_marshal_pk(pk, &pks);
173+
}
174+
t1 = get_cyclecounter();
175+
cycles_pk_marshal[i] = t1 - t0;
176+
177+
/* Marshal secret key */
178+
for (j = 0; j < NWARMUP; j++)
179+
{
180+
crypto_kem_marshal_sk(sk, &sks);
181+
}
182+
183+
t0 = get_cyclecounter();
184+
for (j = 0; j < NITERATIONS; j++)
185+
{
186+
crypto_kem_marshal_sk(sk, &sks);
187+
}
188+
t1 = get_cyclecounter();
189+
cycles_sk_marshal[i] = t1 - t0;
190+
191+
192+
/* pk parse */
193+
for (j = 0; j < NWARMUP; j++)
194+
{
195+
ret |= crypto_kem_parse_pk(&pks, pk);
196+
}
197+
198+
t0 = get_cyclecounter();
199+
for (j = 0; j < NITERATIONS; j++)
200+
{
201+
ret |= crypto_kem_parse_pk(&pks, pk);
202+
}
203+
t1 = get_cyclecounter();
204+
cycles_pk_parse[i] = t1 - t0;
205+
206+
207+
/* encaps */
208+
for (j = 0; j < NWARMUP; j++)
209+
{
210+
ret |= crypto_kem_enc_derand_struct(ct, key_a, &pks, enc_rand);
211+
}
212+
213+
t0 = get_cyclecounter();
214+
for (j = 0; j < NITERATIONS; j++)
215+
{
216+
ret |= crypto_kem_enc_derand_struct(ct, key_a, &pks, enc_rand);
217+
}
218+
t1 = get_cyclecounter();
219+
cycles_enc_struct[i] = t1 - t0;
220+
221+
222+
/* sk prase */
223+
for (j = 0; j < NWARMUP; j++)
224+
{
225+
ret |= crypto_kem_parse_sk(&sks, sk);
226+
}
227+
228+
t0 = get_cyclecounter();
229+
for (j = 0; j < NITERATIONS; j++)
230+
{
231+
ret |= crypto_kem_parse_sk(&sks, sk);
232+
}
233+
t1 = get_cyclecounter();
234+
cycles_sk_parse[i] = t1 - t0;
235+
236+
237+
/* decaps */
238+
for (j = 0; j < NWARMUP; j++)
239+
{
240+
ret |= crypto_kem_dec_struct(key_b, ct, &sks);
241+
}
242+
243+
t0 = get_cyclecounter();
244+
for (j = 0; j < NITERATIONS; j++)
245+
{
246+
ret |= crypto_kem_dec_struct(key_b, ct, &sks);
247+
}
248+
t1 = get_cyclecounter();
249+
cycles_dec_struct[i] = t1 - t0;
250+
251+
CHECK(ret == 0);
252+
CHECK(memcmp(key_a, key_b, CRYPTO_BYTES) == 0);
128253
}
129254

130255
qsort(cycles_kg, NTESTS, sizeof(uint64_t), cmp_uint64_t);
131256
qsort(cycles_enc, NTESTS, sizeof(uint64_t), cmp_uint64_t);
132257
qsort(cycles_dec, NTESTS, sizeof(uint64_t), cmp_uint64_t);
133258

259+
qsort(cycles_kg_struct, NTESTS, sizeof(uint64_t), cmp_uint64_t);
260+
qsort(cycles_pk_marshal, NTESTS, sizeof(uint64_t), cmp_uint64_t);
261+
qsort(cycles_sk_marshal, NTESTS, sizeof(uint64_t), cmp_uint64_t);
262+
qsort(cycles_pk_parse, NTESTS, sizeof(uint64_t), cmp_uint64_t);
263+
qsort(cycles_enc_struct, NTESTS, sizeof(uint64_t), cmp_uint64_t);
264+
qsort(cycles_sk_parse, NTESTS, sizeof(uint64_t), cmp_uint64_t);
265+
qsort(cycles_dec_struct, NTESTS, sizeof(uint64_t), cmp_uint64_t);
266+
267+
134268
print_median("keypair", cycles_kg);
135269
print_median("encaps", cycles_enc);
136270
print_median("decaps", cycles_dec);
137271

272+
print_median("keypair_struct", cycles_kg_struct);
273+
print_median("marshal_pk", cycles_pk_marshal);
274+
print_median("marshal_sk", cycles_sk_marshal);
275+
print_median("parse_pk", cycles_pk_parse);
276+
print_median("encaps_struct", cycles_enc_struct);
277+
print_median("parse_sk", cycles_sk_parse);
278+
print_median("decaps_struct", cycles_dec_struct);
279+
138280
printf("\n");
139281

140282
print_percentile_legend();
@@ -143,6 +285,14 @@ static int bench(void)
143285
print_percentiles("encaps", cycles_enc);
144286
print_percentiles("decaps", cycles_dec);
145287

288+
print_percentiles("keypair_struct", cycles_kg_struct);
289+
print_percentiles("marshal_pk", cycles_pk_marshal);
290+
print_percentiles("marshal_sk", cycles_sk_marshal);
291+
print_percentiles("parse_pk", cycles_pk_parse);
292+
print_percentiles("encaps_struct", cycles_enc_struct);
293+
print_percentiles("parse_sk", cycles_sk_parse);
294+
print_percentiles("decaps_struct", cycles_dec_struct);
295+
146296
return 0;
147297
}
148298

test/test_mlkem.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,64 @@ static int test_keys(void)
5555
return 0;
5656
}
5757

58+
static int test_keys_struct_no_marshal(void)
59+
{
60+
mlk_public_key pk;
61+
mlk_secret_key sk;
62+
uint8_t ct[CRYPTO_CIPHERTEXTBYTES];
63+
uint8_t key_a[CRYPTO_BYTES];
64+
uint8_t key_b[CRYPTO_BYTES];
65+
66+
67+
/* Alice generates a public key */
68+
CHECK(crypto_kem_keypair_struct(&pk, &sk) == 0);
69+
/* Bob derives a secret key and creates a response */
70+
CHECK(crypto_kem_enc_struct(ct, key_b, &pk) == 0);
71+
/* Alice uses Bobs response to get her shared key */
72+
CHECK(crypto_kem_dec_struct(key_a, ct, &sk) == 0);
73+
74+
/* mark as defined, so we can compare */
75+
MLK_CT_TESTING_DECLASSIFY(key_a, CRYPTO_BYTES);
76+
MLK_CT_TESTING_DECLASSIFY(key_b, CRYPTO_BYTES);
77+
78+
CHECK(memcmp(key_a, key_b, CRYPTO_BYTES) == 0);
79+
return 0;
80+
}
81+
82+
static int test_keys_struct_marshal(void)
83+
{
84+
mlk_public_key pk;
85+
mlk_secret_key sk;
86+
uint8_t pkb[CRYPTO_PUBLICKEYBYTES];
87+
uint8_t skb[CRYPTO_SECRETKEYBYTES];
88+
uint8_t ct[CRYPTO_CIPHERTEXTBYTES];
89+
uint8_t key_a[CRYPTO_BYTES];
90+
uint8_t key_b[CRYPTO_BYTES];
91+
92+
/* Alice generates a public key */
93+
CHECK(crypto_kem_keypair_struct(&pk, &sk) == 0);
94+
95+
crypto_kem_marshal_pk(pkb, &pk);
96+
crypto_kem_marshal_sk(skb, &sk);
97+
memset(&pk, 0, sizeof(mlk_public_key));
98+
memset(&sk, 0, sizeof(mlk_secret_key));
99+
100+
/* Bob derives a secret key and creates a response */
101+
CHECK(crypto_kem_parse_pk(&pk, pkb) == 0);
102+
CHECK(crypto_kem_enc_struct(ct, key_b, &pk) == 0);
103+
104+
/* Alice uses Bobs response to get her shared key */
105+
CHECK(crypto_kem_parse_sk(&sk, skb) == 0);
106+
CHECK(crypto_kem_dec_struct(key_a, ct, &sk) == 0);
107+
108+
/* mark as defined, so we can compare */
109+
MLK_CT_TESTING_DECLASSIFY(key_a, CRYPTO_BYTES);
110+
MLK_CT_TESTING_DECLASSIFY(key_b, CRYPTO_BYTES);
111+
112+
CHECK(memcmp(key_a, key_b, CRYPTO_BYTES) == 0);
113+
return 0;
114+
}
115+
58116
static int test_invalid_pk(void)
59117
{
60118
uint8_t pk[CRYPTO_PUBLICKEYBYTES];
@@ -228,6 +286,8 @@ int main(void)
228286
for (i = 0; i < NTESTS; i++)
229287
{
230288
CHECK(test_keys() == 0);
289+
CHECK(test_keys_struct_no_marshal() == 0);
290+
CHECK(test_keys_struct_marshal() == 0);
231291
CHECK(test_invalid_pk() == 0);
232292
CHECK(test_invalid_sk_a() == 0);
233293
CHECK(test_invalid_sk_b() == 0);

0 commit comments

Comments
 (0)