blob: f7f8a5914e097525dae10e75c244db6922f00e0f [file] [log] [blame]
Tom Rini0344c602024-10-08 13:56:50 -06001/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_core.h"
5#include "bignum_mod_raw.h"
6#include "constant_time_internal.h"
7#include "test/constant_flow.h"
8
9#include "bignum_mod_raw_invasive.h"
10
11/* END_HEADER */
12
13/* BEGIN_DEPENDENCIES
14 * depends_on:MBEDTLS_BIGNUM_C:MBEDTLS_ECP_WITH_MPI_UINT
15 * END_DEPENDENCIES
16 */
17
18/* BEGIN_CASE */
19void mpi_mod_raw_io(data_t *input, int nb_int, int nx_32_int,
20 int iendian, int iret, int oret)
21{
22 mbedtls_mpi_mod_modulus m;
23 mbedtls_mpi_mod_modulus_init(&m);
24
25 if (iret != 0) {
26 TEST_ASSERT(oret == 0);
27 }
28
29 TEST_LE_S(0, nb_int);
30 size_t nb = nb_int;
31
32 unsigned char buf[1024];
33 TEST_LE_U(nb, sizeof(buf));
34
35 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
36 * to halve the number of limbs to have the same size. */
37 size_t nx;
38 TEST_LE_S(0, nx_32_int);
39 if (sizeof(mbedtls_mpi_uint) == 8) {
40 nx = nx_32_int / 2 + nx_32_int % 2;
41 } else {
42 nx = nx_32_int;
43 }
44
45 mbedtls_mpi_uint X[sizeof(buf) / sizeof(mbedtls_mpi_uint)];
46 TEST_LE_U(nx, sizeof(X) / sizeof(X[0]));
47
48 int endian;
49 if (iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID) {
50 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
51 } else {
52 endian = iendian;
53 }
54
55 mbedtls_mpi_uint init[sizeof(X) / sizeof(X[0])];
56 memset(init, 0xFF, sizeof(init));
57 int ret = mbedtls_mpi_mod_modulus_setup(&m, init, nx);
58 TEST_EQUAL(ret, 0);
59
60 if (iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0) {
61 endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
62 }
63
64 ret = mbedtls_mpi_mod_raw_read(X, &m, input->x, input->len, endian);
65 TEST_EQUAL(ret, iret);
66
67 if (iret == 0) {
68 if (iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0) {
69 endian = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
70 }
71
72 ret = mbedtls_mpi_mod_raw_write(X, &m, buf, nb, endian);
73 TEST_EQUAL(ret, oret);
74 }
75
76 if ((iret == 0) && (oret == 0)) {
77 if (nb > input->len) {
78 if (endian == MBEDTLS_MPI_MOD_EXT_REP_BE) {
79 size_t leading_zeroes = nb - input->len;
80 TEST_ASSERT(memcmp(buf + nb - input->len, input->x, input->len) == 0);
81 for (size_t i = 0; i < leading_zeroes; i++) {
82 TEST_EQUAL(buf[i], 0);
83 }
84 } else {
85 TEST_ASSERT(memcmp(buf, input->x, input->len) == 0);
86 for (size_t i = input->len; i < nb; i++) {
87 TEST_EQUAL(buf[i], 0);
88 }
89 }
90 } else {
91 if (endian == MBEDTLS_MPI_MOD_EXT_REP_BE) {
92 size_t leading_zeroes = input->len - nb;
93 TEST_ASSERT(memcmp(input->x + input->len - nb, buf, nb) == 0);
94 for (size_t i = 0; i < leading_zeroes; i++) {
95 TEST_EQUAL(input->x[i], 0);
96 }
97 } else {
98 TEST_ASSERT(memcmp(input->x, buf, nb) == 0);
99 for (size_t i = nb; i < input->len; i++) {
100 TEST_EQUAL(input->x[i], 0);
101 }
102 }
103 }
104 }
105
106exit:
107 mbedtls_mpi_mod_modulus_free(&m);
108}
109/* END_CASE */
110
111/* BEGIN_CASE */
112void mpi_mod_raw_cond_assign(char *input_X,
113 char *input_Y,
114 int input_bytes)
115{
116 mbedtls_mpi_uint *X = NULL;
117 mbedtls_mpi_uint *Y = NULL;
118 mbedtls_mpi_uint *buff_m = NULL;
119 size_t limbs_X;
120 size_t limbs_Y;
121
122 mbedtls_mpi_mod_modulus m;
123 mbedtls_mpi_mod_modulus_init(&m);
124
125 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
126 TEST_EQUAL(mbedtls_test_read_mpi_core(&Y, &limbs_Y, input_Y), 0);
127
128 size_t limbs = limbs_X;
129 size_t copy_limbs = CHARS_TO_LIMBS(input_bytes);
130 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
131 size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint);
132
133 TEST_EQUAL(limbs_X, limbs_Y);
134 TEST_ASSERT(copy_limbs <= limbs);
135
136 TEST_CALLOC(buff_m, copy_limbs);
137 memset(buff_m, 0xFF, copy_limbs);
138 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
139 &m, buff_m, copy_limbs), 0);
140
141 /* condition is false */
142 TEST_CF_SECRET(X, bytes);
143 TEST_CF_SECRET(Y, bytes);
144
145 mbedtls_mpi_mod_raw_cond_assign(X, Y, &m, 0);
146
147 TEST_CF_PUBLIC(X, bytes);
148 TEST_CF_PUBLIC(Y, bytes);
149
150 TEST_ASSERT(memcmp(X, Y, bytes) != 0);
151
152 /* condition is true */
153 TEST_CF_SECRET(X, bytes);
154 TEST_CF_SECRET(Y, bytes);
155
156 mbedtls_mpi_mod_raw_cond_assign(X, Y, &m, 1);
157
158 TEST_CF_PUBLIC(X, bytes);
159 TEST_CF_PUBLIC(Y, bytes);
160
161 /* Check if the given length is copied even it is smaller
162 than the length of the given MPIs. */
163 if (copy_limbs < limbs) {
164 TEST_MEMORY_COMPARE(X, copy_bytes, Y, copy_bytes);
165 TEST_ASSERT(memcmp(X, Y, bytes) != 0);
166 } else {
167 TEST_MEMORY_COMPARE(X, bytes, Y, bytes);
168 }
169
170exit:
171 mbedtls_free(X);
172 mbedtls_free(Y);
173
174 mbedtls_mpi_mod_modulus_free(&m);
175 mbedtls_free(buff_m);
176}
177/* END_CASE */
178
179/* BEGIN_CASE */
180void mpi_mod_raw_cond_swap(char *input_X,
181 char *input_Y,
182 int input_bytes)
183{
184 mbedtls_mpi_uint *tmp_X = NULL;
185 mbedtls_mpi_uint *tmp_Y = NULL;
186 mbedtls_mpi_uint *X = NULL;
187 mbedtls_mpi_uint *Y = NULL;
188 mbedtls_mpi_uint *buff_m = NULL;
189 size_t limbs_X;
190 size_t limbs_Y;
191
192 mbedtls_mpi_mod_modulus m;
193 mbedtls_mpi_mod_modulus_init(&m);
194
195 TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_X, &limbs_X, input_X), 0);
196 TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_Y, &limbs_Y, input_Y), 0);
197
198 size_t limbs = limbs_X;
199 size_t copy_limbs = CHARS_TO_LIMBS(input_bytes);
200 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
201 size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint);
202
203 TEST_EQUAL(limbs_X, limbs_Y);
204 TEST_ASSERT(copy_limbs <= limbs);
205
206 TEST_CALLOC(buff_m, copy_limbs);
207 memset(buff_m, 0xFF, copy_limbs);
208 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
209 &m, buff_m, copy_limbs), 0);
210
211 TEST_CALLOC(X, limbs);
212 memcpy(X, tmp_X, bytes);
213
214 TEST_CALLOC(Y, bytes);
215 memcpy(Y, tmp_Y, bytes);
216
217 /* condition is false */
218 TEST_CF_SECRET(X, bytes);
219 TEST_CF_SECRET(Y, bytes);
220
221 mbedtls_mpi_mod_raw_cond_swap(X, Y, &m, 0);
222
223 TEST_CF_PUBLIC(X, bytes);
224 TEST_CF_PUBLIC(Y, bytes);
225
226 TEST_MEMORY_COMPARE(X, bytes, tmp_X, bytes);
227 TEST_MEMORY_COMPARE(Y, bytes, tmp_Y, bytes);
228
229 /* condition is true */
230 TEST_CF_SECRET(X, bytes);
231 TEST_CF_SECRET(Y, bytes);
232
233 mbedtls_mpi_mod_raw_cond_swap(X, Y, &m, 1);
234
235 TEST_CF_PUBLIC(X, bytes);
236 TEST_CF_PUBLIC(Y, bytes);
237
238 /* Check if the given length is copied even it is smaller
239 than the length of the given MPIs. */
240 if (copy_limbs < limbs) {
241 TEST_MEMORY_COMPARE(X, copy_bytes, tmp_Y, copy_bytes);
242 TEST_MEMORY_COMPARE(Y, copy_bytes, tmp_X, copy_bytes);
243 TEST_ASSERT(memcmp(X, tmp_X, bytes) != 0);
244 TEST_ASSERT(memcmp(X, tmp_Y, bytes) != 0);
245 TEST_ASSERT(memcmp(Y, tmp_X, bytes) != 0);
246 TEST_ASSERT(memcmp(Y, tmp_Y, bytes) != 0);
247 } else {
248 TEST_MEMORY_COMPARE(X, bytes, tmp_Y, bytes);
249 TEST_MEMORY_COMPARE(Y, bytes, tmp_X, bytes);
250 }
251
252exit:
253 mbedtls_free(tmp_X);
254 mbedtls_free(tmp_Y);
255 mbedtls_free(X);
256 mbedtls_free(Y);
257
258 mbedtls_mpi_mod_modulus_free(&m);
259 mbedtls_free(buff_m);
260}
261/* END_CASE */
262
263/* BEGIN_CASE */
264void mpi_mod_raw_sub(char *input_A,
265 char *input_B,
266 char *input_N,
267 char *result)
268{
269 mbedtls_mpi_uint *A = NULL;
270 mbedtls_mpi_uint *B = NULL;
271 mbedtls_mpi_uint *N = NULL;
272 mbedtls_mpi_uint *X = NULL;
273 mbedtls_mpi_uint *res = NULL;
274 size_t limbs_A;
275 size_t limbs_B;
276 size_t limbs_N;
277 size_t limbs_res;
278
279 mbedtls_mpi_mod_modulus m;
280 mbedtls_mpi_mod_modulus_init(&m);
281
282 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
283 TEST_EQUAL(mbedtls_test_read_mpi_core(&B, &limbs_B, input_B), 0);
284 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
285 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
286
287 size_t limbs = limbs_N;
288 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
289
290 TEST_EQUAL(limbs_A, limbs);
291 TEST_EQUAL(limbs_B, limbs);
292 TEST_EQUAL(limbs_res, limbs);
293
294 TEST_CALLOC(X, limbs);
295
296 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
297 &m, N, limbs), 0);
298
299 mbedtls_mpi_mod_raw_sub(X, A, B, &m);
300 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
301
302 /* alias X to A */
303 memcpy(X, A, bytes);
304 mbedtls_mpi_mod_raw_sub(X, X, B, &m);
305 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
306
307 /* alias X to B */
308 memcpy(X, B, bytes);
309 mbedtls_mpi_mod_raw_sub(X, A, X, &m);
310 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
311
312 /* A == B: alias A and B */
313 if (memcmp(A, B, bytes) == 0) {
314 mbedtls_mpi_mod_raw_sub(X, A, A, &m);
315 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
316
317 /* X, A, B all aliased together */
318 memcpy(X, A, bytes);
319 mbedtls_mpi_mod_raw_sub(X, X, X, &m);
320 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
321 }
322exit:
323 mbedtls_free(A);
324 mbedtls_free(B);
325 mbedtls_free(X);
326 mbedtls_free(res);
327
328 mbedtls_mpi_mod_modulus_free(&m);
329 mbedtls_free(N);
330}
331/* END_CASE */
332
333/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
334void mpi_mod_raw_fix_quasi_reduction(char *input_N,
335 char *input_X,
336 char *result)
337{
338 mbedtls_mpi_uint *X = NULL;
339 mbedtls_mpi_uint *N = NULL;
340 mbedtls_mpi_uint *res = NULL;
341 mbedtls_mpi_uint *tmp = NULL;
342 size_t limbs_X;
343 size_t limbs_N;
344 size_t limbs_res;
345
346 mbedtls_mpi_mod_modulus m;
347 mbedtls_mpi_mod_modulus_init(&m);
348
349 TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
350 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
351 TEST_EQUAL(mbedtls_test_read_mpi_core(&res, &limbs_res, result), 0);
352
353 size_t limbs = limbs_N;
354 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
355
356 TEST_EQUAL(limbs_X, limbs);
357 TEST_EQUAL(limbs_res, limbs);
358
359 TEST_CALLOC(tmp, limbs);
360 memcpy(tmp, X, bytes);
361
362 /* Check that 0 <= X < 2N */
363 mbedtls_mpi_uint c = mbedtls_mpi_core_sub(tmp, X, N, limbs);
364 TEST_ASSERT(c || mbedtls_mpi_core_lt_ct(tmp, N, limbs));
365
366 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
367 &m, N, limbs), 0);
368
369 mbedtls_mpi_mod_raw_fix_quasi_reduction(X, &m);
370 TEST_MEMORY_COMPARE(X, bytes, res, bytes);
371
372exit:
373 mbedtls_free(X);
374 mbedtls_free(res);
375 mbedtls_free(tmp);
376
377 mbedtls_mpi_mod_modulus_free(&m);
378 mbedtls_free(N);
379}
380/* END_CASE */
381
382/* BEGIN_CASE */
383void mpi_mod_raw_mul(char *input_A,
384 char *input_B,
385 char *input_N,
386 char *result)
387{
388 mbedtls_mpi_uint *A = NULL;
389 mbedtls_mpi_uint *B = NULL;
390 mbedtls_mpi_uint *N = NULL;
391 mbedtls_mpi_uint *X = NULL;
392 mbedtls_mpi_uint *R = NULL;
393 mbedtls_mpi_uint *T = NULL;
394 size_t limbs_A;
395 size_t limbs_B;
396 size_t limbs_N;
397 size_t limbs_R;
398
399 mbedtls_mpi_mod_modulus m;
400 mbedtls_mpi_mod_modulus_init(&m);
401
402 TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &limbs_A, input_A), 0);
403 TEST_EQUAL(mbedtls_test_read_mpi_core(&B, &limbs_B, input_B), 0);
404 TEST_EQUAL(mbedtls_test_read_mpi_core(&N, &limbs_N, input_N), 0);
405 TEST_EQUAL(mbedtls_test_read_mpi_core(&R, &limbs_R, result), 0);
406
407 const size_t limbs = limbs_N;
408 const size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
409
410 TEST_EQUAL(limbs_A, limbs);
411 TEST_EQUAL(limbs_B, limbs);
412 TEST_EQUAL(limbs_R, limbs);
413
414 TEST_CALLOC(X, limbs);
415
416 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
417 &m, N, limbs), 0);
418
419 const size_t limbs_T = limbs * 2 + 1;
420 TEST_CALLOC(T, limbs_T);
421
422 mbedtls_mpi_mod_raw_mul(X, A, B, &m, T);
423 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
424
425 /* alias X to A */
426 memcpy(X, A, bytes);
427 mbedtls_mpi_mod_raw_mul(X, X, B, &m, T);
428 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
429
430 /* alias X to B */
431 memcpy(X, B, bytes);
432 mbedtls_mpi_mod_raw_mul(X, A, X, &m, T);
433 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
434
435 /* A == B: alias A and B */
436 if (memcmp(A, B, bytes) == 0) {
437 mbedtls_mpi_mod_raw_mul(X, A, A, &m, T);
438 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
439
440 /* X, A, B all aliased together */
441 memcpy(X, A, bytes);
442 mbedtls_mpi_mod_raw_mul(X, X, X, &m, T);
443 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
444 }
445 /* A != B: test B * A */
446 else {
447 mbedtls_mpi_mod_raw_mul(X, B, A, &m, T);
448 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
449
450 /* B * A: alias X to A */
451 memcpy(X, A, bytes);
452 mbedtls_mpi_mod_raw_mul(X, B, X, &m, T);
453 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
454
455 /* B + A: alias X to B */
456 memcpy(X, B, bytes);
457 mbedtls_mpi_mod_raw_mul(X, X, A, &m, T);
458 TEST_MEMORY_COMPARE(X, bytes, R, bytes);
459 }
460
461exit:
462 mbedtls_free(A);
463 mbedtls_free(B);
464 mbedtls_free(X);
465 mbedtls_free(R);
466 mbedtls_free(T);
467
468 mbedtls_mpi_mod_modulus_free(&m);
469 mbedtls_free(N);
470}
471/* END_CASE */
472
473/* BEGIN_CASE */
474void mpi_mod_raw_inv_prime(char *input_N, char *input_A, char *input_X)
475{
476 mbedtls_mpi_uint *A = NULL;
477 mbedtls_mpi_uint *N = NULL;
478 mbedtls_mpi_uint *X = NULL;
479 size_t A_limbs, N_limbs, X_limbs;
480 mbedtls_mpi_uint *Y = NULL;
481 mbedtls_mpi_uint *T = NULL;
482 const mbedtls_mpi_uint *R2 = NULL;
483
484 /* Legacy MPIs for computing R2 */
485 mbedtls_mpi N_mpi; /* gets set up manually, aliasing N, so no need to free */
486 mbedtls_mpi R2_mpi;
487 mbedtls_mpi_init(&R2_mpi);
488
489 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
490 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N));
491 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
492 TEST_CALLOC(Y, N_limbs);
493
494 TEST_EQUAL(A_limbs, N_limbs);
495 TEST_EQUAL(X_limbs, N_limbs);
496
497 N_mpi.s = 1;
498 N_mpi.p = N;
499 N_mpi.n = N_limbs;
500 TEST_EQUAL(0, mbedtls_mpi_core_get_mont_r2_unsafe(&R2_mpi, &N_mpi));
501 TEST_EQUAL(0, mbedtls_mpi_grow(&R2_mpi, N_limbs));
502 R2 = R2_mpi.p;
503
504 size_t working_limbs = mbedtls_mpi_mod_raw_inv_prime_working_limbs(N_limbs);
505
506 /* No point exactly duplicating the code in mbedtls_mpi_mod_raw_inv_prime_working_limbs()
507 * to see if the output is correct, but we can check that it's in a
508 * reasonable range. The current calculation works out as
509 * `1 + N_limbs * (welem + 4)`, where welem is the number of elements in
510 * the window (1 << 1 up to 1 << 6).
511 */
512 size_t min_expected_working_limbs = 1 + N_limbs * 5;
513 size_t max_expected_working_limbs = 1 + N_limbs * 68;
514
515 TEST_LE_U(min_expected_working_limbs, working_limbs);
516 TEST_LE_U(working_limbs, max_expected_working_limbs);
517
518 /* Should also be at least mbedtls_mpi_core_montmul_working_limbs() */
519 TEST_LE_U(mbedtls_mpi_core_montmul_working_limbs(N_limbs),
520 working_limbs);
521
522 TEST_CALLOC(T, working_limbs);
523
524 mbedtls_mpi_mod_raw_inv_prime(Y, A, N, N_limbs, R2, T);
525
526 TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
527
528 /* Check when output aliased to input */
529
530 mbedtls_mpi_mod_raw_inv_prime(A, A, N, N_limbs, R2, T);
531
532 TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
533
534exit:
535 mbedtls_free(T);
536 mbedtls_free(A);
537 mbedtls_free(N);
538 mbedtls_free(X);
539 mbedtls_free(Y);
540 mbedtls_mpi_free(&R2_mpi);
541 // R2 doesn't need to be freed as it is only aliasing R2_mpi
542 // N_mpi doesn't need to be freed as it is only aliasing N
543}
544/* END_CASE */
545
546/* BEGIN_CASE */
547void mpi_mod_raw_add(char *input_N,
548 char *input_A, char *input_B,
549 char *input_S)
550{
551 mbedtls_mpi_uint *A = NULL;
552 mbedtls_mpi_uint *B = NULL;
553 mbedtls_mpi_uint *S = NULL;
554 mbedtls_mpi_uint *N = NULL;
555 mbedtls_mpi_uint *X = NULL;
556 size_t A_limbs, B_limbs, N_limbs, S_limbs;
557
558 mbedtls_mpi_mod_modulus m;
559 mbedtls_mpi_mod_modulus_init(&m);
560
561 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
562 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&B, &B_limbs, input_B));
563 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N));
564 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&S, &S_limbs, input_S));
565
566 /* Modulus gives the number of limbs; all inputs must have the same. */
567 size_t limbs = N_limbs;
568 size_t bytes = limbs * sizeof(*A);
569
570 TEST_EQUAL(A_limbs, limbs);
571 TEST_EQUAL(B_limbs, limbs);
572 TEST_EQUAL(S_limbs, limbs);
573
574 TEST_CALLOC(X, limbs);
575
576 TEST_EQUAL(mbedtls_mpi_mod_modulus_setup(
577 &m, N, limbs), 0);
578
579 /* A + B => Correct result */
580 mbedtls_mpi_mod_raw_add(X, A, B, &m);
581 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
582
583 /* A + B: alias X to A => Correct result */
584 memcpy(X, A, bytes);
585 mbedtls_mpi_mod_raw_add(X, X, B, &m);
586 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
587
588 /* A + B: alias X to B => Correct result */
589 memcpy(X, B, bytes);
590 mbedtls_mpi_mod_raw_add(X, A, X, &m);
591 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
592
593 if (memcmp(A, B, bytes) == 0) {
594 /* A == B: alias A and B */
595
596 /* A + A => Correct result */
597 mbedtls_mpi_mod_raw_add(X, A, A, &m);
598 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
599
600 /* A + A: X, A, B all aliased together => Correct result */
601 memcpy(X, A, bytes);
602 mbedtls_mpi_mod_raw_add(X, X, X, &m);
603 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
604 } else {
605 /* A != B: test B + A */
606
607 /* B + A => Correct result */
608 mbedtls_mpi_mod_raw_add(X, B, A, &m);
609 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
610
611 /* B + A: alias X to A => Correct result */
612 memcpy(X, A, bytes);
613 mbedtls_mpi_mod_raw_add(X, B, X, &m);
614 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
615
616 /* B + A: alias X to B => Correct result */
617 memcpy(X, B, bytes);
618 mbedtls_mpi_mod_raw_add(X, X, A, &m);
619 TEST_MEMORY_COMPARE(X, bytes, S, bytes);
620 }
621
622exit:
623 mbedtls_mpi_mod_modulus_free(&m);
624
625 mbedtls_free(A);
626 mbedtls_free(B);
627 mbedtls_free(S);
628 mbedtls_free(N);
629 mbedtls_free(X);
630}
631/* END_CASE */
632
633/* BEGIN_CASE */
634void mpi_mod_raw_canonical_to_modulus_rep(const char *input_N, int rep,
635 const char *input_A,
636 const char *input_X)
637{
638 mbedtls_mpi_mod_modulus N;
639 mbedtls_mpi_mod_modulus_init(&N);
640 mbedtls_mpi_uint *A = NULL;
641 size_t A_limbs = 0;;
642 mbedtls_mpi_uint *X = NULL;
643 size_t X_limbs = 0;
644
645 TEST_EQUAL(0, mbedtls_test_read_mpi_modulus(&N, input_N, rep));
646 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
647 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
648
649 TEST_EQUAL(0, mbedtls_mpi_mod_raw_canonical_to_modulus_rep(A, &N));
650 TEST_MEMORY_COMPARE(A, A_limbs * sizeof(mbedtls_mpi_uint),
651 X, X_limbs * sizeof(mbedtls_mpi_uint));
652
653exit:
654 mbedtls_test_mpi_mod_modulus_free_with_limbs(&N);
655 mbedtls_free(A);
656 mbedtls_free(X);
657}
658/* END_CASE */
659
660/* BEGIN_CASE */
661void mpi_mod_raw_modulus_to_canonical_rep(const char *input_N, int rep,
662 const char *input_A,
663 const char *input_X)
664{
665 mbedtls_mpi_mod_modulus N;
666 mbedtls_mpi_mod_modulus_init(&N);
667 mbedtls_mpi_uint *A = NULL;
668 size_t A_limbs = 0;
669 mbedtls_mpi_uint *X = NULL;
670 size_t X_limbs = 0;
671
672 TEST_EQUAL(0, mbedtls_test_read_mpi_modulus(&N, input_N, rep));
673 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
674 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
675
676 TEST_EQUAL(0, mbedtls_mpi_mod_raw_modulus_to_canonical_rep(A, &N));
677 TEST_MEMORY_COMPARE(A, A_limbs * sizeof(mbedtls_mpi_uint),
678 X, X_limbs * sizeof(mbedtls_mpi_uint));
679
680exit:
681 mbedtls_test_mpi_mod_modulus_free_with_limbs(&N);
682 mbedtls_free(A);
683 mbedtls_free(X);
684}
685/* END_CASE */
686
687/* BEGIN_CASE */
688void mpi_mod_raw_to_mont_rep(char *input_N, char *input_A, char *input_X)
689{
690 mbedtls_mpi_uint *N = NULL;
691 mbedtls_mpi_uint *A = NULL;
692 mbedtls_mpi_uint *R = NULL; /* for result of low-level conversion */
693 mbedtls_mpi_uint *X = NULL;
694 mbedtls_mpi_uint *T = NULL;
695 size_t n_limbs, a_limbs, x_limbs;
696
697 mbedtls_mpi_mod_modulus m;
698 mbedtls_mpi_mod_modulus_init(&m);
699
700 /* Read inputs */
701 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
702 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &a_limbs, input_A));
703 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &x_limbs, input_X));
704
705 /* Number to convert must have same number of limbs as modulus */
706 TEST_EQUAL(a_limbs, n_limbs);
707
708 /* Higher-level conversion is in-place, so expected result must have the
709 * same number of limbs too */
710 TEST_EQUAL(x_limbs, n_limbs);
711
712 size_t limbs = n_limbs;
713 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
714
715 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
716
717 /* 1. Test low-level function first */
718
719 /* It has separate output, and requires temporary working storage */
720 size_t temp_limbs = mbedtls_mpi_core_montmul_working_limbs(limbs);
721 TEST_CALLOC(T, temp_limbs);
722 TEST_CALLOC(R, limbs);
723 mbedtls_mpi_core_to_mont_rep(R, A, N, n_limbs,
724 m.rep.mont.mm, m.rep.mont.rr, T);
725 /* Test that the low-level function gives the required value */
726 TEST_MEMORY_COMPARE(R, bytes, X, bytes);
727
728 /* Test when output is aliased to input */
729 memcpy(R, A, bytes);
730 mbedtls_mpi_core_to_mont_rep(R, R, N, n_limbs,
731 m.rep.mont.mm, m.rep.mont.rr, T);
732 TEST_MEMORY_COMPARE(R, bytes, X, bytes);
733
734 /* 2. Test higher-level cannonical to Montgomery conversion */
735
736 TEST_EQUAL(0, mbedtls_mpi_mod_raw_to_mont_rep(A, &m));
737
738 /* The result matches expected value */
739 TEST_MEMORY_COMPARE(A, bytes, X, bytes);
740
741exit:
742 mbedtls_mpi_mod_modulus_free(&m);
743 mbedtls_free(T);
744 mbedtls_free(N);
745 mbedtls_free(A);
746 mbedtls_free(R);
747 mbedtls_free(X);
748}
749/* END_CASE */
750
751/* BEGIN_CASE */
752void mpi_mod_raw_from_mont_rep(char *input_N, char *input_A, char *input_X)
753{
754 mbedtls_mpi_uint *N = NULL;
755 mbedtls_mpi_uint *A = NULL;
756 mbedtls_mpi_uint *R = NULL; /* for result of low-level conversion */
757 mbedtls_mpi_uint *X = NULL;
758 mbedtls_mpi_uint *T = NULL;
759 size_t n_limbs, a_limbs, x_limbs;
760
761 mbedtls_mpi_mod_modulus m;
762 mbedtls_mpi_mod_modulus_init(&m);
763
764 /* Read inputs */
765 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
766 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &a_limbs, input_A));
767 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &x_limbs, input_X));
768
769 /* Number to convert must have same number of limbs as modulus */
770 TEST_EQUAL(a_limbs, n_limbs);
771
772 /* Higher-level conversion is in-place, so expected result must have the
773 * same number of limbs too */
774 TEST_EQUAL(x_limbs, n_limbs);
775
776 size_t limbs = n_limbs;
777 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
778
779 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
780
781 /* 1. Test low-level function first */
782
783 /* It has separate output, and requires temporary working storage */
784 size_t temp_limbs = mbedtls_mpi_core_montmul_working_limbs(limbs);
785 TEST_CALLOC(T, temp_limbs);
786 TEST_CALLOC(R, limbs);
787 mbedtls_mpi_core_from_mont_rep(R, A, N, n_limbs,
788 m.rep.mont.mm, T);
789 /* Test that the low-level function gives the required value */
790 TEST_MEMORY_COMPARE(R, bytes, X, bytes);
791
792 /* Test when output is aliased to input */
793 memcpy(R, A, bytes);
794 mbedtls_mpi_core_from_mont_rep(R, R, N, n_limbs,
795 m.rep.mont.mm, T);
796 TEST_MEMORY_COMPARE(R, bytes, X, bytes);
797
798 /* 2. Test higher-level Montgomery to cannonical conversion */
799
800 TEST_EQUAL(0, mbedtls_mpi_mod_raw_from_mont_rep(A, &m));
801
802 /* The result matches expected value */
803 TEST_MEMORY_COMPARE(A, bytes, X, bytes);
804
805exit:
806 mbedtls_mpi_mod_modulus_free(&m);
807 mbedtls_free(T);
808 mbedtls_free(N);
809 mbedtls_free(A);
810 mbedtls_free(R);
811 mbedtls_free(X);
812}
813/* END_CASE */
814
815/* BEGIN_CASE */
816void mpi_mod_raw_neg(char *input_N, char *input_A, char *input_X)
817{
818 mbedtls_mpi_uint *N = NULL;
819 mbedtls_mpi_uint *A = NULL;
820 mbedtls_mpi_uint *X = NULL;
821 mbedtls_mpi_uint *R = NULL;
822 mbedtls_mpi_uint *Z = NULL;
823 size_t n_limbs, a_limbs, x_limbs, bytes;
824
825 mbedtls_mpi_mod_modulus m;
826 mbedtls_mpi_mod_modulus_init(&m);
827
828 /* Read inputs */
829 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &n_limbs, input_N));
830 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &a_limbs, input_A));
831 TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &x_limbs, input_X));
832
833 TEST_EQUAL(a_limbs, n_limbs);
834 TEST_EQUAL(x_limbs, n_limbs);
835 bytes = n_limbs * sizeof(mbedtls_mpi_uint);
836
837 TEST_CALLOC(R, n_limbs);
838 TEST_CALLOC(Z, n_limbs);
839
840 TEST_EQUAL(0, mbedtls_mpi_mod_modulus_setup(&m, N, n_limbs));
841
842 /* Neg( A == 0 ) => Zero result */
843 mbedtls_mpi_mod_raw_neg(R, Z, &m);
844 TEST_MEMORY_COMPARE(R, bytes, Z, bytes);
845
846 /* Neg( A == N ) => Zero result */
847 mbedtls_mpi_mod_raw_neg(R, N, &m);
848 TEST_MEMORY_COMPARE(R, bytes, Z, bytes);
849
850 /* Neg( A ) => Correct result */
851 mbedtls_mpi_mod_raw_neg(R, A, &m);
852 TEST_MEMORY_COMPARE(R, bytes, X, bytes);
853
854 /* Neg( A ): alias A to R => Correct result */
855 mbedtls_mpi_mod_raw_neg(A, A, &m);
856 TEST_MEMORY_COMPARE(A, bytes, X, bytes);
857exit:
858 mbedtls_mpi_mod_modulus_free(&m);
859 mbedtls_free(N);
860 mbedtls_free(A);
861 mbedtls_free(X);
862 mbedtls_free(R);
863 mbedtls_free(Z);
864}
865/* END_CASE */