quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_suite_bignum_core.function (43216B)


      1 /* BEGIN_HEADER */
      2 #include "mbedtls/bignum.h"
      3 #include "mbedtls/entropy.h"
      4 #include "bignum_core.h"
      5 #include "constant_time_internal.h"
      6 #include "test/constant_flow.h"
      7 #include "test/bignum_codepath_check.h"
      8 
      9 /** Verifies mbedtls_mpi_core_add().
     10  *
     11  * \param[in] A       Little-endian presentation of the left operand.
     12  * \param[in] B       Little-endian presentation of the right operand.
     13  * \param limbs       Number of limbs in each MPI (\p A, \p B, \p S and \p X).
     14  * \param[in] S       Little-endian presentation of the expected sum.
     15  * \param carry       Expected carry from the addition.
     16  * \param[in,out] X   Temporary storage to be used for results.
     17  *
     18  * \return  1 if mbedtls_mpi_core_add() passes this test, otherwise 0.
     19  */
     20 static int mpi_core_verify_add(mbedtls_mpi_uint *A,
     21                                mbedtls_mpi_uint *B,
     22                                size_t limbs,
     23                                mbedtls_mpi_uint *S,
     24                                int carry,
     25                                mbedtls_mpi_uint *X)
     26 {
     27     int ret = 0;
     28 
     29     size_t bytes = limbs * sizeof(*A);
     30 
     31     /* The test cases have A <= B to avoid repetition, so we test A + B then,
     32      * if A != B, B + A. If A == B, we can test when A and B are aliased */
     33 
     34     /* A + B */
     35 
     36     /* A + B => correct result and carry */
     37     TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, B, limbs));
     38     TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     39 
     40     /* A + B; alias output and first operand => correct result and carry */
     41     memcpy(X, A, bytes);
     42     TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, B, limbs));
     43     TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     44 
     45     /* A + B; alias output and second operand => correct result and carry */
     46     memcpy(X, B, bytes);
     47     TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, X, limbs));
     48     TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     49 
     50     if (memcmp(A, B, bytes) == 0) {
     51         /* A == B, so test where A and B are aliased */
     52 
     53         /* A + A => correct result and carry */
     54         TEST_EQUAL(carry, mbedtls_mpi_core_add(X, A, A, limbs));
     55         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     56 
     57         /* A + A, output aliased to both operands => correct result and carry */
     58         memcpy(X, A, bytes);
     59         TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, X, limbs));
     60         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     61     } else {
     62         /* A != B, so test B + A */
     63 
     64         /* B + A => correct result and carry */
     65         TEST_EQUAL(carry, mbedtls_mpi_core_add(X, B, A, limbs));
     66         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     67 
     68         /* B + A; alias output and first operand => correct result and carry */
     69         memcpy(X, B, bytes);
     70         TEST_EQUAL(carry, mbedtls_mpi_core_add(X, X, A, limbs));
     71         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     72 
     73         /* B + A; alias output and second operand => correct result and carry */
     74         memcpy(X, A, bytes);
     75         TEST_EQUAL(carry, mbedtls_mpi_core_add(X, B, X, limbs));
     76         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
     77     }
     78 
     79     ret = 1;
     80 
     81 exit:
     82     return ret;
     83 }
     84 
     85 /** Verifies mbedtls_mpi_core_add_if().
     86  *
     87  * \param[in] A       Little-endian presentation of the left operand.
     88  * \param[in] B       Little-endian presentation of the right operand.
     89  * \param limbs       Number of limbs in each MPI (\p A, \p B, \p S and \p X).
     90  * \param[in] S       Little-endian presentation of the expected sum.
     91  * \param carry       Expected carry from the addition.
     92  * \param[in,out] X   Temporary storage to be used for results.
     93  *
     94  * \return  1 if mbedtls_mpi_core_add_if() passes this test, otherwise 0.
     95  */
     96 static int mpi_core_verify_add_if(mbedtls_mpi_uint *A,
     97                                   mbedtls_mpi_uint *B,
     98                                   size_t limbs,
     99                                   mbedtls_mpi_uint *S,
    100                                   int carry,
    101                                   mbedtls_mpi_uint *X)
    102 {
    103     int ret = 0;
    104 
    105     size_t bytes = limbs * sizeof(*A);
    106 
    107     /* The test cases have A <= B to avoid repetition, so we test A + B then,
    108      * if A != B, B + A. If A == B, we can test when A and B are aliased */
    109 
    110     /* A + B */
    111 
    112     /* cond = 0 => X unchanged, no carry */
    113     memcpy(X, A, bytes);
    114     TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, B, limbs, 0));
    115     TEST_MEMORY_COMPARE(X, bytes, A, bytes);
    116 
    117     /* cond = 1 => correct result and carry */
    118     TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, B, limbs, 1));
    119     TEST_MEMORY_COMPARE(X, bytes, S, bytes);
    120 
    121     if (memcmp(A, B, bytes) == 0) {
    122         /* A == B, so test where A and B are aliased */
    123 
    124         /* cond = 0 => X unchanged, no carry */
    125         memcpy(X, B, bytes);
    126         TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, X, limbs, 0));
    127         TEST_MEMORY_COMPARE(X, bytes, B, bytes);
    128 
    129         /* cond = 1 => correct result and carry */
    130         TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, X, limbs, 1));
    131         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
    132     } else {
    133         /* A != B, so test B + A */
    134 
    135         /* cond = 0 => d unchanged, no carry */
    136         memcpy(X, B, bytes);
    137         TEST_EQUAL(0, mbedtls_mpi_core_add_if(X, A, limbs, 0));
    138         TEST_MEMORY_COMPARE(X, bytes, B, bytes);
    139 
    140         /* cond = 1 => correct result and carry */
    141         TEST_EQUAL(carry, mbedtls_mpi_core_add_if(X, A, limbs, 1));
    142         TEST_MEMORY_COMPARE(X, bytes, S, bytes);
    143     }
    144 
    145     ret = 1;
    146 
    147 exit:
    148     return ret;
    149 }
    150 
    151 /* END_HEADER */
    152 
    153 /* BEGIN_DEPENDENCIES
    154  * depends_on:MBEDTLS_BIGNUM_C
    155  * END_DEPENDENCIES
    156  */
    157 
    158 /* BEGIN_CASE */
    159 void mpi_core_io_null()
    160 {
    161     mbedtls_mpi_uint X = 0;
    162     int ret;
    163 
    164     ret = mbedtls_mpi_core_read_be(&X, 1, NULL, 0);
    165     TEST_EQUAL(ret, 0);
    166     ret = mbedtls_mpi_core_write_be(&X, 1, NULL, 0);
    167     TEST_EQUAL(ret, 0);
    168 
    169     ret = mbedtls_mpi_core_read_be(NULL, 0, NULL, 0);
    170     TEST_EQUAL(ret, 0);
    171     ret = mbedtls_mpi_core_write_be(NULL, 0, NULL, 0);
    172     TEST_EQUAL(ret, 0);
    173 
    174     ret = mbedtls_mpi_core_read_le(&X, 1, NULL, 0);
    175     TEST_EQUAL(ret, 0);
    176     ret = mbedtls_mpi_core_write_le(&X, 1, NULL, 0);
    177     TEST_EQUAL(ret, 0);
    178 
    179     ret = mbedtls_mpi_core_read_le(NULL, 0, NULL, 0);
    180     TEST_EQUAL(ret, 0);
    181     ret = mbedtls_mpi_core_write_le(NULL, 0, NULL, 0);
    182     TEST_EQUAL(ret, 0);
    183 
    184 exit:
    185     ;
    186 }
    187 /* END_CASE */
    188 
    189 /* BEGIN_CASE */
    190 void mpi_core_io_be(data_t *input, int nb_int, int nx_32_int, int iret,
    191                     int oret)
    192 {
    193     if (iret != 0) {
    194         TEST_ASSERT(oret == 0);
    195     }
    196 
    197     TEST_LE_S(0, nb_int);
    198     size_t nb = nb_int;
    199 
    200     unsigned char buf[1024];
    201     TEST_LE_U(nb, sizeof(buf));
    202 
    203     /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
    204      * to halve the number of limbs to have the same size. */
    205     size_t nx;
    206     TEST_LE_S(0, nx_32_int);
    207     if (sizeof(mbedtls_mpi_uint) == 8) {
    208         nx = nx_32_int / 2 + nx_32_int % 2;
    209     } else {
    210         nx = nx_32_int;
    211     }
    212 
    213     mbedtls_mpi_uint X[sizeof(buf) / sizeof(mbedtls_mpi_uint)];
    214     TEST_LE_U(nx, sizeof(X) / sizeof(X[0]));
    215 
    216     int ret = mbedtls_mpi_core_read_be(X, nx, input->x, input->len);
    217     TEST_EQUAL(ret, iret);
    218 
    219     if (iret == 0) {
    220         ret =  mbedtls_mpi_core_write_be(X, nx, buf, nb);
    221         TEST_EQUAL(ret, oret);
    222     }
    223 
    224     if ((iret == 0) && (oret == 0)) {
    225         if (nb > input->len) {
    226             size_t leading_zeroes = nb - input->len;
    227             TEST_ASSERT(memcmp(buf + nb - input->len, input->x, input->len) == 0);
    228             for (size_t i = 0; i < leading_zeroes; i++) {
    229                 TEST_EQUAL(buf[i], 0);
    230             }
    231         } else {
    232             size_t leading_zeroes = input->len - nb;
    233             TEST_ASSERT(memcmp(input->x + input->len - nb, buf, nb) == 0);
    234             for (size_t i = 0; i < leading_zeroes; i++) {
    235                 TEST_EQUAL(input->x[i], 0);
    236             }
    237         }
    238     }
    239 
    240 exit:
    241     ;
    242 }
    243 /* END_CASE */
    244 
    245 /* BEGIN_CASE */
    246 void mpi_core_io_le(data_t *input, int nb_int, int nx_32_int, int iret,
    247                     int oret)
    248 {
    249     if (iret != 0) {
    250         TEST_ASSERT(oret == 0);
    251     }
    252 
    253     TEST_LE_S(0, nb_int);
    254     size_t nb = nb_int;
    255 
    256     unsigned char buf[1024];
    257     TEST_LE_U(nb, sizeof(buf));
    258 
    259     /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
    260      * to halve the number of limbs to have the same size. */
    261     size_t nx;
    262     TEST_LE_S(0, nx_32_int);
    263     if (sizeof(mbedtls_mpi_uint) == 8) {
    264         nx = nx_32_int / 2 + nx_32_int % 2;
    265     } else {
    266         nx = nx_32_int;
    267     }
    268 
    269     mbedtls_mpi_uint X[sizeof(buf) / sizeof(mbedtls_mpi_uint)];
    270     TEST_LE_U(nx, sizeof(X) / sizeof(X[0]));
    271 
    272     int ret =  mbedtls_mpi_core_read_le(X, nx, input->x, input->len);
    273     TEST_EQUAL(ret, iret);
    274 
    275     if (iret == 0) {
    276         ret =  mbedtls_mpi_core_write_le(X, nx, buf, nb);
    277         TEST_EQUAL(ret, oret);
    278     }
    279 
    280     if ((iret == 0) && (oret == 0)) {
    281         if (nb > input->len) {
    282             TEST_ASSERT(memcmp(buf, input->x, input->len) == 0);
    283             for (size_t i = input->len; i < nb; i++) {
    284                 TEST_EQUAL(buf[i], 0);
    285             }
    286         } else {
    287             TEST_ASSERT(memcmp(input->x, buf, nb) == 0);
    288             for (size_t i = nb; i < input->len; i++) {
    289                 TEST_EQUAL(input->x[i], 0);
    290             }
    291         }
    292     }
    293 
    294 exit:
    295     ;
    296 }
    297 /* END_CASE */
    298 
    299 /* BEGIN_CASE */
    300 void mpi_core_bitlen(char *input_X, int nr_bits)
    301 {
    302     mbedtls_mpi_uint *X = NULL;
    303     size_t limbs;
    304 
    305     TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs, input_X), 0);
    306     TEST_EQUAL(mbedtls_mpi_core_bitlen(X, limbs), nr_bits);
    307 
    308 exit:
    309     mbedtls_free(X);
    310 }
    311 /* END_CASE */
    312 
    313 
    314 /* BEGIN_CASE */
    315 void mpi_core_clz(int leading_zeros, int trailing_zeros)
    316 {
    317     if ((size_t) (leading_zeros + trailing_zeros) >= (sizeof(mbedtls_mpi_uint) * 8)) {
    318         // can't fit required number of leading and trailing zeros - skip test
    319         goto exit;
    320     }
    321 
    322     // Construct a test input value where the count of leading zeros and
    323     // trailing zeros is given in the test case, and we add ones to fill
    324     // the gap.
    325     mbedtls_mpi_uint x;
    326     if ((leading_zeros + trailing_zeros) > 0) {
    327         // some zero bits
    328         uint32_t s = (sizeof(mbedtls_mpi_uint) * 8 - leading_zeros - trailing_zeros);
    329         x = ((((mbedtls_mpi_uint) 1) << s) - 1) << trailing_zeros;
    330     } else {
    331         // all bits set
    332         x = ~((mbedtls_mpi_uint) 0);
    333     }
    334 
    335     size_t n = mbedtls_mpi_core_clz(x);
    336     TEST_EQUAL(n, leading_zeros);
    337 exit:
    338     ;
    339 }
    340 /* END_CASE */
    341 
    342 
    343 /* BEGIN_CASE */
    344 void mpi_core_lt_ct(char *input_X, char *input_Y, int exp_ret)
    345 {
    346     mbedtls_mpi_uint *X = NULL;
    347     size_t X_limbs;
    348     mbedtls_mpi_uint *Y = NULL;
    349     size_t Y_limbs;
    350     int ret;
    351 
    352     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
    353     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &Y_limbs, input_Y));
    354 
    355     /* We need two same-length limb arrays */
    356     TEST_EQUAL(X_limbs, Y_limbs);
    357 
    358     TEST_CF_SECRET(X, X_limbs * sizeof(mbedtls_mpi_uint));
    359     TEST_CF_SECRET(Y, X_limbs * sizeof(mbedtls_mpi_uint));
    360 
    361     ret = mbedtls_mpi_core_lt_ct(X, Y, X_limbs);
    362     TEST_EQUAL(!!ret, exp_ret);
    363 
    364 exit:
    365     mbedtls_free(X);
    366     mbedtls_free(Y);
    367 }
    368 /* END_CASE */
    369 
    370 /* BEGIN_CASE */
    371 void mpi_core_uint_le_mpi(char *input_A)
    372 {
    373     mbedtls_mpi_uint *A = NULL;
    374     size_t A_limbs = 0;
    375 
    376     TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &A_limbs, input_A), 0);
    377 
    378     int is_large = 0; /* nonzero limbs beyond the lowest-order one? */
    379     for (size_t i = 1; i < A_limbs; i++) {
    380         if (A[i] != 0) {
    381             is_large = 1;
    382             break;
    383         }
    384     }
    385 
    386     TEST_CF_SECRET(A, A_limbs * sizeof(*A));
    387 
    388     TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(0, A, A_limbs), 1);
    389     TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0], A, A_limbs), 1);
    390 
    391     if (is_large) {
    392         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0] + 1,
    393                                                   A, A_limbs), 1);
    394         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1) >> 1,
    395                                                   A, A_limbs), 1);
    396         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1),
    397                                                   A, A_limbs), 1);
    398     } else {
    399         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi(A[0] + 1,
    400                                                   A, A_limbs),
    401                    A[0] + 1 <= A[0]);
    402         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1) >> 1,
    403                                                   A, A_limbs),
    404                    (mbedtls_mpi_uint) (-1) >> 1 <= A[0]);
    405         TEST_EQUAL(!!mbedtls_mpi_core_uint_le_mpi((mbedtls_mpi_uint) (-1),
    406                                                   A, A_limbs),
    407                    (mbedtls_mpi_uint) (-1) <= A[0]);
    408     }
    409 
    410 exit:
    411     mbedtls_free(A);
    412 }
    413 /* END_CASE */
    414 
    415 /* BEGIN_CASE */
    416 void mpi_core_cond_assign(char *input_X,
    417                           char *input_Y,
    418                           int input_bytes)
    419 {
    420     mbedtls_mpi_uint *X = NULL;
    421     mbedtls_mpi_uint *Y = NULL;
    422     size_t limbs_X;
    423     size_t limbs_Y;
    424 
    425     TEST_EQUAL(mbedtls_test_read_mpi_core(&X, &limbs_X, input_X), 0);
    426     TEST_EQUAL(mbedtls_test_read_mpi_core(&Y, &limbs_Y, input_Y), 0);
    427 
    428     size_t limbs = limbs_X;
    429     size_t copy_limbs = CHARS_TO_LIMBS(input_bytes);
    430     size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
    431     size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint);
    432 
    433     TEST_EQUAL(limbs_X, limbs_Y);
    434     TEST_ASSERT(copy_limbs <= limbs);
    435 
    436     /* condition is false */
    437     TEST_CF_SECRET(X, bytes);
    438     TEST_CF_SECRET(Y, bytes);
    439 
    440     mbedtls_mpi_core_cond_assign(X, Y, copy_limbs, 0);
    441 
    442     TEST_CF_PUBLIC(X, bytes);
    443     TEST_CF_PUBLIC(Y, bytes);
    444 
    445     TEST_ASSERT(memcmp(X, Y, bytes) != 0);
    446 
    447     /* condition is true */
    448     TEST_CF_SECRET(X, bytes);
    449     TEST_CF_SECRET(Y, bytes);
    450 
    451     mbedtls_mpi_core_cond_assign(X, Y, copy_limbs, mbedtls_ct_bool(1));
    452 
    453     TEST_CF_PUBLIC(X, bytes);
    454     TEST_CF_PUBLIC(Y, bytes);
    455 
    456     /* Check if the given length is copied even it is smaller
    457        than the length of the given MPIs. */
    458     if (copy_limbs < limbs) {
    459         TEST_CF_PUBLIC(X, bytes);
    460         TEST_CF_PUBLIC(Y, bytes);
    461 
    462         TEST_MEMORY_COMPARE(X, copy_bytes, Y, copy_bytes);
    463         TEST_ASSERT(memcmp(X, Y, bytes) != 0);
    464     } else {
    465         TEST_MEMORY_COMPARE(X, bytes, Y, bytes);
    466     }
    467 
    468 exit:
    469     mbedtls_free(X);
    470     mbedtls_free(Y);
    471 }
    472 /* END_CASE */
    473 
    474 /* BEGIN_CASE */
    475 void mpi_core_cond_swap(char *input_X,
    476                         char *input_Y,
    477                         int input_bytes)
    478 {
    479     mbedtls_mpi_uint *tmp_X = NULL;
    480     mbedtls_mpi_uint *tmp_Y = NULL;
    481     mbedtls_mpi_uint *X = NULL;
    482     mbedtls_mpi_uint *Y = NULL;
    483     size_t limbs_X;
    484     size_t limbs_Y;
    485 
    486     TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_X, &limbs_X, input_X), 0);
    487     TEST_EQUAL(mbedtls_test_read_mpi_core(&tmp_Y, &limbs_Y, input_Y), 0);
    488 
    489     size_t limbs = limbs_X;
    490     size_t copy_limbs = CHARS_TO_LIMBS(input_bytes);
    491     size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
    492     size_t copy_bytes = copy_limbs * sizeof(mbedtls_mpi_uint);
    493 
    494     TEST_EQUAL(limbs_X, limbs_Y);
    495     TEST_ASSERT(copy_limbs <= limbs);
    496 
    497     TEST_CALLOC(X, limbs);
    498     memcpy(X, tmp_X, bytes);
    499 
    500     TEST_CALLOC(Y, limbs);
    501     memcpy(Y, tmp_Y, bytes);
    502 
    503     /* condition is false */
    504     TEST_CF_SECRET(X, bytes);
    505     TEST_CF_SECRET(Y, bytes);
    506 
    507     mbedtls_mpi_core_cond_swap(X, Y, copy_limbs, 0);
    508 
    509     TEST_CF_PUBLIC(X, bytes);
    510     TEST_CF_PUBLIC(Y, bytes);
    511 
    512     TEST_MEMORY_COMPARE(X, bytes, tmp_X, bytes);
    513     TEST_MEMORY_COMPARE(Y, bytes, tmp_Y, bytes);
    514 
    515     /* condition is true */
    516     TEST_CF_SECRET(X, bytes);
    517     TEST_CF_SECRET(Y, bytes);
    518 
    519     mbedtls_mpi_core_cond_swap(X, Y, copy_limbs, mbedtls_ct_bool(1));
    520 
    521     TEST_CF_PUBLIC(X, bytes);
    522     TEST_CF_PUBLIC(Y, bytes);
    523 
    524     /* Check if the given length is copied even it is smaller
    525        than the length of the given MPIs. */
    526     if (copy_limbs < limbs) {
    527         TEST_MEMORY_COMPARE(X, copy_bytes, tmp_Y, copy_bytes);
    528         TEST_MEMORY_COMPARE(Y, copy_bytes, tmp_X, copy_bytes);
    529         TEST_ASSERT(memcmp(X, tmp_X, bytes) != 0);
    530         TEST_ASSERT(memcmp(X, tmp_Y, bytes) != 0);
    531         TEST_ASSERT(memcmp(Y, tmp_X, bytes) != 0);
    532         TEST_ASSERT(memcmp(Y, tmp_Y, bytes) != 0);
    533     } else {
    534         TEST_MEMORY_COMPARE(X, bytes, tmp_Y, bytes);
    535         TEST_MEMORY_COMPARE(Y, bytes, tmp_X, bytes);
    536     }
    537 
    538 exit:
    539     mbedtls_free(tmp_X);
    540     mbedtls_free(tmp_Y);
    541     mbedtls_free(X);
    542     mbedtls_free(Y);
    543 }
    544 /* END_CASE */
    545 
    546 /* BEGIN_CASE */
    547 void mpi_core_shift_r(char *input, int count, char *result)
    548 {
    549     mbedtls_mpi_uint *X = NULL;
    550     mbedtls_mpi_uint *Y = NULL;
    551     size_t limbs, n;
    552 
    553     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &limbs, input));
    554     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &n, result));
    555     TEST_EQUAL(limbs, n);
    556 
    557     mbedtls_mpi_core_shift_r(X, limbs, count);
    558     TEST_MEMORY_COMPARE(X, limbs * ciL, Y, limbs * ciL);
    559 
    560 exit:
    561     mbedtls_free(X);
    562     mbedtls_free(Y);
    563 }
    564 /* END_CASE */
    565 
    566 /* BEGIN_CASE */
    567 void mpi_core_shift_l(char *input, int count, char *result)
    568 {
    569     mbedtls_mpi_uint *X = NULL;
    570     mbedtls_mpi_uint *Y = NULL;
    571     size_t limbs, n;
    572 
    573     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &limbs, input));
    574     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&Y, &n, result));
    575     TEST_EQUAL(limbs, n);
    576 
    577     mbedtls_mpi_core_shift_l(X, limbs, count);
    578     TEST_MEMORY_COMPARE(X, limbs * ciL, Y, limbs * ciL);
    579 
    580 exit:
    581     mbedtls_free(X);
    582     mbedtls_free(Y);
    583 }
    584 /* END_CASE */
    585 
    586 /* BEGIN_CASE */
    587 void mpi_core_add_and_add_if(char *input_A, char *input_B,
    588                              char *input_S, int carry)
    589 {
    590     mbedtls_mpi_uint *A = NULL; /* first value to add */
    591     mbedtls_mpi_uint *B = NULL; /* second value to add */
    592     mbedtls_mpi_uint *S = NULL; /* expected result */
    593     mbedtls_mpi_uint *X = NULL; /* destination - the in/out first operand */
    594     size_t A_limbs, B_limbs, S_limbs;
    595 
    596     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
    597     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&B, &B_limbs, input_B));
    598     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&S, &S_limbs, input_S));
    599 
    600     /* add and add_if expect all operands to be the same length */
    601     TEST_EQUAL(A_limbs, B_limbs);
    602     TEST_EQUAL(A_limbs, S_limbs);
    603 
    604     size_t limbs = A_limbs;
    605     TEST_CALLOC(X, limbs);
    606 
    607     TEST_ASSERT(mpi_core_verify_add(A, B, limbs, S, carry, X));
    608     TEST_ASSERT(mpi_core_verify_add_if(A, B, limbs, S, carry, X));
    609 
    610 exit:
    611     mbedtls_free(A);
    612     mbedtls_free(B);
    613     mbedtls_free(S);
    614     mbedtls_free(X);
    615 }
    616 /* END_CASE */
    617 
    618 /* BEGIN_CASE */
    619 void mpi_core_sub(char *input_A, char *input_B,
    620                   char *input_X, int carry)
    621 {
    622     mbedtls_mpi A, B, X;
    623     mbedtls_mpi_uint *a = NULL;
    624     mbedtls_mpi_uint *b = NULL;
    625     mbedtls_mpi_uint *x = NULL; /* expected */
    626     mbedtls_mpi_uint *r = NULL; /* result */
    627 
    628     mbedtls_mpi_init(&A);
    629     mbedtls_mpi_init(&B);
    630     mbedtls_mpi_init(&X);
    631 
    632     TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A));
    633     TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B));
    634     TEST_EQUAL(0, mbedtls_test_read_mpi(&X, input_X));
    635 
    636     /* All of the inputs are +ve (or zero) */
    637     TEST_EQUAL(1, A.s);
    638     TEST_EQUAL(1, B.s);
    639     TEST_EQUAL(1, X.s);
    640 
    641     /* Get the number of limbs we will need */
    642     size_t limbs = MAX(A.n, B.n);
    643     size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
    644 
    645     /* The result shouldn't have more limbs than the longest input */
    646     TEST_LE_U(X.n, limbs);
    647 
    648     /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
    649 
    650     /* TEST_CALLOC() uses calloc() under the hood, so these do get zeroed */
    651     TEST_CALLOC(a, bytes);
    652     TEST_CALLOC(b, bytes);
    653     TEST_CALLOC(x, bytes);
    654     TEST_CALLOC(r, bytes);
    655 
    656     /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
    657      * processed by mbedtls_mpi_core_sub()) are little endian, we can just
    658      * copy what we have as long as MSBs are 0 (which they are from TEST_CALLOC())
    659      */
    660     memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint));
    661     memcpy(b, B.p, B.n * sizeof(mbedtls_mpi_uint));
    662     memcpy(x, X.p, X.n * sizeof(mbedtls_mpi_uint));
    663 
    664     /* 1a) r = a - b => we should get the correct carry */
    665     TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, b, limbs));
    666 
    667     /* 1b) r = a - b => we should get the correct result */
    668     TEST_MEMORY_COMPARE(r, bytes, x, bytes);
    669 
    670     /* 2 and 3 test "r may be aliased to a or b" */
    671     /* 2a) r = a; r -= b => we should get the correct carry (use r to avoid clobbering a) */
    672     memcpy(r, a, bytes);
    673     TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, b, limbs));
    674 
    675     /* 2b) r -= b => we should get the correct result */
    676     TEST_MEMORY_COMPARE(r, bytes, x, bytes);
    677 
    678     /* 3a) r = b; r = a - r => we should get the correct carry (use r to avoid clobbering b) */
    679     memcpy(r, b, bytes);
    680     TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, a, r, limbs));
    681 
    682     /* 3b) r = a - b => we should get the correct result */
    683     TEST_MEMORY_COMPARE(r, bytes, x, bytes);
    684 
    685     /* 4 tests "r may be aliased to [...] both" */
    686     if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) {
    687         memcpy(r, b, bytes);
    688         TEST_EQUAL(carry, mbedtls_mpi_core_sub(r, r, r, limbs));
    689         TEST_MEMORY_COMPARE(r, bytes, x, bytes);
    690     }
    691 
    692 exit:
    693     mbedtls_free(a);
    694     mbedtls_free(b);
    695     mbedtls_free(x);
    696     mbedtls_free(r);
    697 
    698     mbedtls_mpi_free(&A);
    699     mbedtls_mpi_free(&B);
    700     mbedtls_mpi_free(&X);
    701 }
    702 /* END_CASE */
    703 
    704 /* BEGIN_CASE */
    705 void mpi_core_mla(char *input_A, char *input_B, char *input_S,
    706                   char *input_X4, char *input_cy4,
    707                   char *input_X8, char *input_cy8)
    708 {
    709     /* We are testing A += B * s; A, B are MPIs, s is a scalar.
    710      *
    711      * However, we encode s as an MPI in the .data file as the test framework
    712      * currently only supports `int`-typed scalars, and that doesn't cover the
    713      * full range of `mbedtls_mpi_uint`.
    714      *
    715      * We also have the different results for sizeof(mbedtls_mpi_uint) == 4 or 8.
    716      */
    717     mbedtls_mpi A, B, S, X4, X8, cy4, cy8;
    718     mbedtls_mpi_uint *a = NULL;
    719     mbedtls_mpi_uint *x = NULL;
    720 
    721     mbedtls_mpi_init(&A);
    722     mbedtls_mpi_init(&B);
    723     mbedtls_mpi_init(&S);
    724     mbedtls_mpi_init(&X4);
    725     mbedtls_mpi_init(&X8);
    726     mbedtls_mpi_init(&cy4);
    727     mbedtls_mpi_init(&cy8);
    728 
    729     TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A));
    730     TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B));
    731     TEST_EQUAL(0, mbedtls_test_read_mpi(&S, input_S));
    732     TEST_EQUAL(0, mbedtls_test_read_mpi(&X4, input_X4));
    733     TEST_EQUAL(0, mbedtls_test_read_mpi(&cy4, input_cy4));
    734     TEST_EQUAL(0, mbedtls_test_read_mpi(&X8, input_X8));
    735     TEST_EQUAL(0, mbedtls_test_read_mpi(&cy8, input_cy8));
    736 
    737     /* The MPI encoding of scalar s must be only 1 limb */
    738     TEST_EQUAL(1, S.n);
    739 
    740     /* We only need to work with X4 or X8, and cy4 or cy8, depending on sizeof(mbedtls_mpi_uint) */
    741     mbedtls_mpi *X = (sizeof(mbedtls_mpi_uint) == 4) ? &X4 : &X8;
    742     mbedtls_mpi *cy = (sizeof(mbedtls_mpi_uint) == 4) ? &cy4 : &cy8;
    743 
    744     /* The carry should only have one limb */
    745     TEST_EQUAL(1, cy->n);
    746 
    747     /* All of the inputs are +ve (or zero) */
    748     TEST_EQUAL(1, A.s);
    749     TEST_EQUAL(1, B.s);
    750     TEST_EQUAL(1, S.s);
    751     TEST_EQUAL(1, X->s);
    752     TEST_EQUAL(1, cy->s);
    753 
    754     /* Get the (max) number of limbs we will need */
    755     size_t limbs = MAX(A.n, B.n);
    756     size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
    757 
    758     /* The result shouldn't have more limbs than the longest input */
    759     TEST_LE_U(X->n, limbs);
    760 
    761     /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
    762 
    763     /* TEST_CALLOC() uses calloc() under the hood, so these do get zeroed */
    764     TEST_CALLOC(a, bytes);
    765     TEST_CALLOC(x, bytes);
    766 
    767     /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
    768      * processed by mbedtls_mpi_core_mla()) are little endian, we can just
    769      * copy what we have as long as MSBs are 0 (which they are from TEST_CALLOC()).
    770      */
    771     memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint));
    772     memcpy(x, X->p, X->n * sizeof(mbedtls_mpi_uint));
    773 
    774     /* 1a) A += B * s => we should get the correct carry */
    775     TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, B.p, B.n, *S.p), *cy->p);
    776 
    777     /* 1b) A += B * s => we should get the correct result */
    778     TEST_MEMORY_COMPARE(a, bytes, x, bytes);
    779 
    780     if (A.n == B.n && memcmp(A.p, B.p, bytes) == 0) {
    781         /* Check when A and B are aliased */
    782         memcpy(a, A.p, A.n * sizeof(mbedtls_mpi_uint));
    783         TEST_EQUAL(mbedtls_mpi_core_mla(a, limbs, a, limbs, *S.p), *cy->p);
    784         TEST_MEMORY_COMPARE(a, bytes, x, bytes);
    785     }
    786 
    787 exit:
    788     mbedtls_free(a);
    789     mbedtls_free(x);
    790 
    791     mbedtls_mpi_free(&A);
    792     mbedtls_mpi_free(&B);
    793     mbedtls_mpi_free(&S);
    794     mbedtls_mpi_free(&X4);
    795     mbedtls_mpi_free(&X8);
    796     mbedtls_mpi_free(&cy4);
    797     mbedtls_mpi_free(&cy8);
    798 }
    799 /* END_CASE */
    800 
    801 
    802 /* BEGIN_CASE */
    803 void mpi_montg_init(char *input_N, char *input_mm)
    804 {
    805     mbedtls_mpi N, mm;
    806 
    807     mbedtls_mpi_init(&N);
    808     mbedtls_mpi_init(&mm);
    809 
    810     TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N));
    811     TEST_EQUAL(0, mbedtls_test_read_mpi(&mm, input_mm));
    812 
    813     /* The MPI encoding of mm should be 1 limb (sizeof(mbedtls_mpi_uint) == 8) or
    814      * 2 limbs (sizeof(mbedtls_mpi_uint) == 4).
    815      *
    816      * The data file contains the expected result for sizeof(mbedtls_mpi_uint) == 8;
    817      * for sizeof(mbedtls_mpi_uint) == 4 it's just the LSW of this.
    818      */
    819     TEST_ASSERT(mm.n == 1  || mm.n == 2);
    820 
    821     /* All of the inputs are +ve (or zero) */
    822     TEST_EQUAL(1, N.s);
    823     TEST_EQUAL(1, mm.s);
    824 
    825     /* mbedtls_mpi_core_montmul_init() only returns a result, no error possible */
    826     mbedtls_mpi_uint result = mbedtls_mpi_core_montmul_init(N.p);
    827 
    828     /* Check we got the correct result */
    829     TEST_EQUAL(result, mm.p[0]);
    830 
    831 exit:
    832     mbedtls_mpi_free(&N);
    833     mbedtls_mpi_free(&mm);
    834 }
    835 /* END_CASE */
    836 
    837 /* BEGIN_CASE */
    838 void mpi_core_montmul(int limbs_AN4, int limbs_B4,
    839                       int limbs_AN8, int limbs_B8,
    840                       char *input_A,
    841                       char *input_B,
    842                       char *input_N,
    843                       char *input_X4,
    844                       char *input_X8)
    845 {
    846     mbedtls_mpi A, B, N, X4, X8, T, R;
    847 
    848     mbedtls_mpi_init(&A);
    849     mbedtls_mpi_init(&B);
    850     mbedtls_mpi_init(&N);
    851     mbedtls_mpi_init(&X4);      /* expected result, sizeof(mbedtls_mpi_uint) == 4 */
    852     mbedtls_mpi_init(&X8);      /* expected result, sizeof(mbedtls_mpi_uint) == 8 */
    853     mbedtls_mpi_init(&T);
    854     mbedtls_mpi_init(&R);       /* for the result */
    855 
    856     TEST_EQUAL(0, mbedtls_test_read_mpi(&A, input_A));
    857     TEST_EQUAL(0, mbedtls_test_read_mpi(&B, input_B));
    858     TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N));
    859     TEST_EQUAL(0, mbedtls_test_read_mpi(&X4, input_X4));
    860     TEST_EQUAL(0, mbedtls_test_read_mpi(&X8, input_X8));
    861 
    862     mbedtls_mpi *X = (sizeof(mbedtls_mpi_uint) == 4) ? &X4 : &X8;
    863 
    864     int limbs_AN = (sizeof(mbedtls_mpi_uint) == 4) ? limbs_AN4 : limbs_AN8;
    865     int limbs_B = (sizeof(mbedtls_mpi_uint) == 4) ? limbs_B4 : limbs_B8;
    866 
    867     TEST_LE_U(A.n, (size_t) limbs_AN);
    868     TEST_LE_U(X->n, (size_t) limbs_AN);
    869     TEST_LE_U(B.n, (size_t) limbs_B);
    870     TEST_LE_U(limbs_B, limbs_AN);
    871 
    872     /* All of the inputs are +ve (or zero) */
    873     TEST_EQUAL(1, A.s);
    874     TEST_EQUAL(1, B.s);
    875     TEST_EQUAL(1, N.s);
    876     TEST_EQUAL(1, X->s);
    877 
    878     TEST_EQUAL(0, mbedtls_mpi_grow(&A, limbs_AN));
    879     TEST_EQUAL(0, mbedtls_mpi_grow(&N, limbs_AN));
    880     TEST_EQUAL(0, mbedtls_mpi_grow(X, limbs_AN));
    881     TEST_EQUAL(0, mbedtls_mpi_grow(&B, limbs_B));
    882 
    883     size_t working_limbs = mbedtls_mpi_core_montmul_working_limbs(limbs_AN);
    884     TEST_EQUAL(working_limbs, limbs_AN * 2 + 1);
    885     TEST_EQUAL(0, mbedtls_mpi_grow(&T, working_limbs));
    886 
    887     /* Calculate the Montgomery constant (this is unit tested separately) */
    888     mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N.p);
    889 
    890     TEST_EQUAL(0, mbedtls_mpi_grow(&R, limbs_AN));     /* ensure it's got the right number of limbs */
    891 
    892     mbedtls_mpi_core_montmul(R.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
    893     size_t bytes = N.n * sizeof(mbedtls_mpi_uint);
    894     TEST_MEMORY_COMPARE(R.p, bytes, X->p, bytes);
    895 
    896     /* The output (R, above) may be aliased to A - use R to save the value of A */
    897 
    898     memcpy(R.p, A.p, bytes);
    899 
    900     mbedtls_mpi_core_montmul(A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
    901     TEST_MEMORY_COMPARE(A.p, bytes, X->p, bytes);
    902 
    903     memcpy(A.p, R.p, bytes);    /* restore A */
    904 
    905     /* The output may be aliased to N - use R to save the value of N */
    906 
    907     memcpy(R.p, N.p, bytes);
    908 
    909     mbedtls_mpi_core_montmul(N.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
    910     TEST_MEMORY_COMPARE(N.p, bytes, X->p, bytes);
    911 
    912     memcpy(N.p, R.p, bytes);
    913 
    914     if (limbs_AN == limbs_B) {
    915         /* Test when A aliased to B (requires A == B on input values) */
    916         if (memcmp(A.p, B.p, bytes) == 0) {
    917             /* Test with A aliased to B and output, since this is permitted -
    918              * don't bother with yet another test with only A and B aliased */
    919 
    920             mbedtls_mpi_core_montmul(B.p, B.p, B.p, B.n, N.p, N.n, mm, T.p);
    921             TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes);
    922 
    923             memcpy(B.p, A.p, bytes);    /* restore B from equal value A */
    924         }
    925 
    926         /* The output may be aliased to B - last test, so we don't save B */
    927 
    928         mbedtls_mpi_core_montmul(B.p, A.p, B.p, B.n, N.p, N.n, mm, T.p);
    929         TEST_MEMORY_COMPARE(B.p, bytes, X->p, bytes);
    930     }
    931 
    932 exit:
    933     mbedtls_mpi_free(&A);
    934     mbedtls_mpi_free(&B);
    935     mbedtls_mpi_free(&N);
    936     mbedtls_mpi_free(&X4);
    937     mbedtls_mpi_free(&X8);
    938     mbedtls_mpi_free(&T);
    939     mbedtls_mpi_free(&R);
    940 }
    941 /* END_CASE */
    942 
    943 /* BEGIN_CASE */
    944 void mpi_core_get_mont_r2_unsafe_neg()
    945 {
    946     mbedtls_mpi N, RR;
    947     mbedtls_mpi_init(&N);
    948     mbedtls_mpi_init(&RR);
    949     const char *n = "7ffffffffffffff1";
    950 
    951     /* Test for zero divisor */
    952     TEST_EQUAL(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO,
    953                mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N));
    954 
    955     /* Test for negative input */
    956     TEST_EQUAL(0, mbedtls_test_read_mpi(&N, n));
    957     N.s = -1;
    958     TEST_EQUAL(MBEDTLS_ERR_MPI_NEGATIVE_VALUE,
    959                mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N));
    960     N.s = 1;
    961 
    962 exit:
    963     mbedtls_mpi_free(&N);
    964     mbedtls_mpi_free(&RR);
    965 }
    966 /* END_CASE */
    967 
    968 /* BEGIN_CASE */
    969 void mpi_core_get_mont_r2_unsafe(char *input_N,
    970                                  char *input_RR_X4,
    971                                  char *input_RR_X8)
    972 {
    973     mbedtls_mpi N, RR, RR_REF;
    974 
    975     /* Select the appropriate output */
    976     char *input_rr = (sizeof(mbedtls_mpi_uint) == 4) ? input_RR_X4 : input_RR_X8;
    977 
    978     mbedtls_mpi_init(&N);
    979     mbedtls_mpi_init(&RR);
    980     mbedtls_mpi_init(&RR_REF);
    981 
    982     /* Read inputs */
    983     TEST_EQUAL(0, mbedtls_test_read_mpi(&N, input_N));
    984     TEST_EQUAL(0, mbedtls_test_read_mpi(&RR_REF, input_rr));
    985 
    986     /* All of the inputs are +ve (or zero) */
    987     TEST_EQUAL(1, N.s);
    988     TEST_EQUAL(1, RR_REF.s);
    989 
    990     /* Test valid input */
    991     TEST_EQUAL(0, mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N));
    992 
    993     /* Test that the moduli is odd */
    994     TEST_EQUAL(N.p[0] ^ 1, N.p[0] - 1);
    995 
    996     /* Output is +ve (or zero) */
    997     TEST_EQUAL(1, RR_REF.s);
    998 
    999     /* rr is updated to a valid pointer */
   1000     TEST_ASSERT(RR.p != NULL);
   1001 
   1002     /* Calculated rr matches expected value */
   1003     TEST_ASSERT(mbedtls_mpi_cmp_mpi(&RR, &RR_REF) == 0);
   1004 
   1005 exit:
   1006     mbedtls_mpi_free(&N);
   1007     mbedtls_mpi_free(&RR);
   1008     mbedtls_mpi_free(&RR_REF);
   1009 }
   1010 /* END_CASE */
   1011 
   1012 /* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
   1013 void mpi_core_ct_uint_table_lookup(int bitlen, int window_size)
   1014 {
   1015     size_t limbs = BITS_TO_LIMBS(bitlen);
   1016     size_t count = ((size_t) 1) << window_size;
   1017 
   1018     mbedtls_mpi_uint *table = NULL;
   1019     mbedtls_mpi_uint *dest = NULL;
   1020 
   1021     TEST_CALLOC(table, limbs * count);
   1022     TEST_CALLOC(dest, limbs);
   1023 
   1024     /*
   1025      * Fill the table with a unique counter so that differences are easily
   1026      * detected. (And have their relationship to the index relatively non-trivial just
   1027      * to be sure.)
   1028      */
   1029     for (size_t i = 0; i < count * limbs; i++) {
   1030         table[i] = ~i - 1;
   1031     }
   1032 
   1033     for (size_t i = 0; i < count; i++) {
   1034         mbedtls_mpi_uint *current = table + i * limbs;
   1035         memset(dest, 0x00, limbs * sizeof(*dest));
   1036 
   1037         /*
   1038          * We shouldn't leak anything through timing.
   1039          * We need to set these in every loop as we need to make the loop
   1040          * variable public for the loop head and the buffers for comparison.
   1041          */
   1042         TEST_CF_SECRET(&i, sizeof(i));
   1043         TEST_CF_SECRET(dest, limbs * sizeof(*dest));
   1044         TEST_CF_SECRET(table, count * limbs * sizeof(*table));
   1045 
   1046         mbedtls_mpi_core_ct_uint_table_lookup(dest, table, limbs, count, i);
   1047 
   1048         TEST_CF_PUBLIC(dest, limbs * sizeof(*dest));
   1049         TEST_CF_PUBLIC(table, count * limbs * sizeof(*table));
   1050         TEST_MEMORY_COMPARE(dest, limbs * sizeof(*dest),
   1051                             current, limbs * sizeof(*current));
   1052         TEST_CF_PUBLIC(&i, sizeof(i));
   1053     }
   1054 
   1055 exit:
   1056     mbedtls_free(table);
   1057     mbedtls_free(dest);
   1058 }
   1059 /* END_CASE */
   1060 
   1061 /* BEGIN_CASE */
   1062 void mpi_core_fill_random(int wanted_bytes_arg, int extra_rng_bytes,
   1063                           int extra_limbs, int before, int expected_ret)
   1064 {
   1065     size_t wanted_bytes = wanted_bytes_arg;
   1066     mbedtls_mpi_uint *X = NULL;
   1067     size_t X_limbs = CHARS_TO_LIMBS(wanted_bytes) + extra_limbs;
   1068     size_t rng_bytes = wanted_bytes + extra_rng_bytes;
   1069     unsigned char *rnd_data = NULL;
   1070     mbedtls_test_rnd_buf_info rnd_info = { NULL, rng_bytes, NULL, NULL };
   1071     int ret;
   1072 
   1073     /* Prepare an RNG with known output, limited to rng_bytes. */
   1074     TEST_CALLOC(rnd_data, rng_bytes);
   1075     TEST_EQUAL(0, mbedtls_test_rnd_std_rand(NULL, rnd_data, rng_bytes));
   1076     rnd_info.buf = rnd_data;
   1077 
   1078     /* Allocate an MPI with room for wanted_bytes plus extra_limbs.
   1079      * extra_limbs may be negative but the total limb count must be positive.
   1080      * Fill the MPI with the byte value in before. */
   1081     TEST_LE_U(1, X_limbs);
   1082     TEST_CALLOC(X, X_limbs);
   1083     memset(X, before, X_limbs * sizeof(*X));
   1084 
   1085     ret = mbedtls_mpi_core_fill_random(X, X_limbs, wanted_bytes,
   1086                                        mbedtls_test_rnd_buffer_rand,
   1087                                        &rnd_info);
   1088     TEST_EQUAL(expected_ret, ret);
   1089 
   1090     if (expected_ret == 0) {
   1091         /* mbedtls_mpi_core_fill_random is documented to use bytes from the
   1092          * RNG as a big-endian representation of the number. We used an RNG
   1093          * with known output, so check that the output contains the
   1094          * expected value. Bytes above wanted_bytes must be zero. */
   1095         for (size_t i = 0; i < wanted_bytes; i++) {
   1096             mbedtls_test_set_step(i);
   1097             TEST_EQUAL(GET_BYTE(X, i), rnd_data[wanted_bytes - 1 - i]);
   1098         }
   1099         for (size_t i = wanted_bytes; i < X_limbs * ciL; i++) {
   1100             mbedtls_test_set_step(i);
   1101             TEST_EQUAL(GET_BYTE(X, i), 0);
   1102         }
   1103     }
   1104 
   1105 exit:
   1106     mbedtls_free(rnd_data);
   1107     mbedtls_free(X);
   1108 }
   1109 /* END_CASE */
   1110 
   1111 /* BEGIN_CASE */
   1112 void mpi_core_mul(char *input_A,
   1113                   char *input_B,
   1114                   char *result)
   1115 {
   1116     mbedtls_mpi_uint *A      = NULL;
   1117     mbedtls_mpi_uint *A_orig = NULL;
   1118     mbedtls_mpi_uint *B      = NULL;
   1119     mbedtls_mpi_uint *B_orig = NULL;
   1120     mbedtls_mpi_uint *R      = NULL;
   1121     mbedtls_mpi_uint *X      = NULL;
   1122     size_t A_limbs, B_limbs, R_limbs;
   1123 
   1124     TEST_EQUAL(mbedtls_test_read_mpi_core(&A, &A_limbs, input_A), 0);
   1125     TEST_EQUAL(mbedtls_test_read_mpi_core(&B, &B_limbs, input_B), 0);
   1126     TEST_EQUAL(mbedtls_test_read_mpi_core(&R, &R_limbs, result), 0);
   1127 
   1128     TEST_EQUAL(R_limbs, A_limbs + B_limbs);
   1129 
   1130     const size_t X_limbs = A_limbs + B_limbs;
   1131     const size_t X_bytes = X_limbs * sizeof(mbedtls_mpi_uint);
   1132     TEST_CALLOC(X, X_limbs);
   1133 
   1134     const size_t A_bytes = A_limbs * sizeof(mbedtls_mpi_uint);
   1135     TEST_CALLOC(A_orig, A_limbs);
   1136     memcpy(A_orig, A, A_bytes);
   1137 
   1138     const size_t B_bytes = B_limbs * sizeof(mbedtls_mpi_uint);
   1139     TEST_CALLOC(B_orig, B_limbs);
   1140     memcpy(B_orig, B, B_bytes);
   1141 
   1142     /* Set result to something that is unlikely to be correct */
   1143     memset(X, '!', X_bytes);
   1144 
   1145     /* 1. X = A * B - result should be correct, A and B unchanged */
   1146     mbedtls_mpi_core_mul(X, A, A_limbs, B, B_limbs);
   1147     TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes);
   1148     TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes);
   1149     TEST_MEMORY_COMPARE(B, B_bytes, B_orig, B_bytes);
   1150 
   1151     /* 2. A == B: alias A and B - result should be correct, A and B unchanged */
   1152     if (A_bytes == B_bytes && memcmp(A, B, A_bytes) == 0) {
   1153         memset(X, '!', X_bytes);
   1154         mbedtls_mpi_core_mul(X, A, A_limbs, A, A_limbs);
   1155         TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes);
   1156         TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes);
   1157     }
   1158     /* 3. X = B * A - result should be correct, A and B unchanged */
   1159     else {
   1160         memset(X, '!', X_bytes);
   1161         mbedtls_mpi_core_mul(X, B, B_limbs, A, A_limbs);
   1162         TEST_MEMORY_COMPARE(X, X_bytes, R, X_bytes);
   1163         TEST_MEMORY_COMPARE(A, A_bytes, A_orig, A_bytes);
   1164         TEST_MEMORY_COMPARE(B, B_bytes, B_orig, B_bytes);
   1165     }
   1166 
   1167 exit:
   1168     mbedtls_free(A);
   1169     mbedtls_free(A_orig);
   1170     mbedtls_free(B);
   1171     mbedtls_free(B_orig);
   1172     mbedtls_free(R);
   1173     mbedtls_free(X);
   1174 }
   1175 /* END_CASE */
   1176 
   1177 /* BEGIN_CASE */
   1178 void mpi_core_exp_mod(char *input_N, char *input_A,
   1179                       char *input_E, char *input_X)
   1180 {
   1181     mbedtls_mpi_uint *A = NULL;
   1182     mbedtls_mpi_uint *A_copy = NULL;
   1183     mbedtls_mpi_uint *E = NULL;
   1184     mbedtls_mpi_uint *N = NULL;
   1185     mbedtls_mpi_uint *X = NULL;
   1186     size_t A_limbs, E_limbs, N_limbs, X_limbs;
   1187     const mbedtls_mpi_uint *R2 = NULL;
   1188     mbedtls_mpi_uint *Y = NULL;
   1189     mbedtls_mpi_uint *T = NULL;
   1190     /* Legacy MPIs for computing R2 */
   1191     mbedtls_mpi N_mpi;
   1192     mbedtls_mpi_init(&N_mpi);
   1193     mbedtls_mpi R2_mpi;
   1194     mbedtls_mpi_init(&R2_mpi);
   1195 
   1196     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
   1197     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&E, &E_limbs, input_E));
   1198     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&N, &N_limbs, input_N));
   1199     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
   1200     TEST_CALLOC(Y, N_limbs);
   1201 
   1202     TEST_EQUAL(A_limbs, N_limbs);
   1203     TEST_EQUAL(X_limbs, N_limbs);
   1204 
   1205     TEST_EQUAL(0, mbedtls_mpi_grow(&N_mpi, N_limbs));
   1206     memcpy(N_mpi.p, N, N_limbs * sizeof(*N));
   1207     N_mpi.n = N_limbs;
   1208     TEST_EQUAL(0,
   1209                mbedtls_mpi_core_get_mont_r2_unsafe(&R2_mpi, &N_mpi));
   1210     TEST_EQUAL(0, mbedtls_mpi_grow(&R2_mpi, N_limbs));
   1211     R2 = R2_mpi.p;
   1212 
   1213     size_t working_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N_limbs,
   1214                                                                   E_limbs);
   1215 
   1216     /* No point exactly duplicating the code in mbedtls_mpi_core_exp_mod_working_limbs()
   1217      * to see if the output is correct, but we can check that it's in a
   1218      * reasonable range.  The current calculation works out as
   1219      * `1 + N_limbs * (welem + 3)`, where welem is the number of elements in
   1220      * the window (1 << 1 up to 1 << 6).
   1221      */
   1222     size_t min_expected_working_limbs = 1 + N_limbs * 4;
   1223     size_t max_expected_working_limbs = 1 + N_limbs * 67;
   1224 
   1225     TEST_LE_U(min_expected_working_limbs, working_limbs);
   1226     TEST_LE_U(working_limbs, max_expected_working_limbs);
   1227 
   1228     /* Should also be at least mbedtls_mpi_core_montmul_working_limbs() */
   1229     TEST_LE_U(mbedtls_mpi_core_montmul_working_limbs(N_limbs),
   1230               working_limbs);
   1231 
   1232     TEST_CALLOC(T, working_limbs);
   1233 
   1234     /* Test the safe variant */
   1235 
   1236 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1237     mbedtls_codepath_reset();
   1238 #endif
   1239     mbedtls_mpi_core_exp_mod(Y, A, N, N_limbs, E, E_limbs, R2, T);
   1240 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1241     TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
   1242 #endif
   1243     TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
   1244 
   1245     /* Test the unsafe variant */
   1246 
   1247 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1248     mbedtls_codepath_reset();
   1249 #endif
   1250     mbedtls_mpi_core_exp_mod_unsafe(Y, A, N, N_limbs, E, E_limbs, R2, T);
   1251 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1252     TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_PUBLIC);
   1253 #endif
   1254     TEST_EQUAL(0, memcmp(X, Y, N_limbs * sizeof(mbedtls_mpi_uint)));
   1255 
   1256     /* Check both with output aliased to input */
   1257 
   1258     TEST_CALLOC(A_copy, A_limbs);
   1259     memcpy(A_copy, A, sizeof(*A_copy) * A_limbs);
   1260 
   1261 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1262     mbedtls_codepath_reset();
   1263 #endif
   1264     mbedtls_mpi_core_exp_mod(A, A, N, N_limbs, E, E_limbs, R2, T);
   1265 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1266     TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
   1267 #endif
   1268     TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
   1269 
   1270     memcpy(A, A_copy, sizeof(*A) * A_limbs);
   1271 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1272     mbedtls_codepath_reset();
   1273 #endif
   1274     mbedtls_mpi_core_exp_mod_unsafe(A, A, N, N_limbs, E, E_limbs, R2, T);
   1275 #if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
   1276     TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_PUBLIC);
   1277 #endif
   1278     TEST_EQUAL(0, memcmp(X, A, N_limbs * sizeof(mbedtls_mpi_uint)));
   1279 
   1280 exit:
   1281     mbedtls_free(T);
   1282     mbedtls_free(A);
   1283     mbedtls_free(A_copy);
   1284     mbedtls_free(E);
   1285     mbedtls_free(N);
   1286     mbedtls_free(X);
   1287     mbedtls_free(Y);
   1288     mbedtls_mpi_free(&N_mpi);
   1289     mbedtls_mpi_free(&R2_mpi);
   1290     // R2 doesn't need to be freed as it is only aliasing R2_mpi
   1291 }
   1292 /* END_CASE */
   1293 
   1294 /* BEGIN_CASE */
   1295 void mpi_core_sub_int(char *input_A, char *input_B,
   1296                       char *input_X, int borrow)
   1297 {
   1298     /* We are testing A - b, where A is an MPI and b is a scalar, expecting
   1299      * result X with borrow borrow.  However, for ease of handling we encode b
   1300      * as a 1-limb MPI (B) in the .data file. */
   1301 
   1302     mbedtls_mpi_uint *A = NULL;
   1303     mbedtls_mpi_uint *B = NULL;
   1304     mbedtls_mpi_uint *X = NULL;
   1305     mbedtls_mpi_uint *R = NULL;
   1306     size_t A_limbs, B_limbs, X_limbs;
   1307 
   1308     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&A, &A_limbs, input_A));
   1309     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&B, &B_limbs, input_B));
   1310     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
   1311 
   1312     /* The MPI encoding of scalar b must be only 1 limb */
   1313     TEST_EQUAL(B_limbs, 1);
   1314 
   1315     /* The subtraction is fixed-width, so A and X must have the same number of limbs */
   1316     TEST_EQUAL(A_limbs, X_limbs);
   1317     size_t limbs = A_limbs;
   1318 
   1319     TEST_CALLOC(R, limbs);
   1320 
   1321 #define TEST_COMPARE_CORE_MPIS(A, B, limbs) \
   1322     TEST_MEMORY_COMPARE(A, (limbs) * sizeof(mbedtls_mpi_uint), \
   1323                         B, (limbs) * sizeof(mbedtls_mpi_uint))
   1324 
   1325     /* 1. R = A - b. Result and borrow should be correct */
   1326     TEST_EQUAL(mbedtls_mpi_core_sub_int(R, A, B[0], limbs), borrow);
   1327     TEST_COMPARE_CORE_MPIS(R, X, limbs);
   1328 
   1329     /* 2. A = A - b. Result and borrow should be correct */
   1330     TEST_EQUAL(mbedtls_mpi_core_sub_int(A, A, B[0], limbs), borrow);
   1331     TEST_COMPARE_CORE_MPIS(A, X, limbs);
   1332 
   1333 exit:
   1334     mbedtls_free(A);
   1335     mbedtls_free(B);
   1336     mbedtls_free(X);
   1337     mbedtls_free(R);
   1338 }
   1339 /* END_CASE */
   1340 
   1341 /* BEGIN_CASE */
   1342 void mpi_core_check_zero_ct(char *input_X, int expected_is_zero)
   1343 {
   1344     mbedtls_mpi_uint *X = NULL;
   1345     size_t X_limbs;
   1346 
   1347     TEST_EQUAL(0, mbedtls_test_read_mpi_core(&X, &X_limbs, input_X));
   1348 
   1349     TEST_CF_SECRET(X, X_limbs * sizeof(mbedtls_mpi_uint));
   1350 
   1351     mbedtls_mpi_uint check = mbedtls_mpi_core_check_zero_ct(X, X_limbs);
   1352     int is_zero = (check == 0);
   1353     TEST_EQUAL(is_zero, expected_is_zero);
   1354 
   1355 exit:
   1356     mbedtls_free(X);
   1357 }
   1358 /* END_CASE */