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: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 */ 866