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