quickjs-tart

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

test_suite_bignum_mod_raw.function (26073B)


      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 */
     19 void 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 
    106 exit:
    107     mbedtls_mpi_mod_modulus_free(&m);
    108 }
    109 /* END_CASE */
    110 
    111 /* BEGIN_CASE */
    112 void 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 
    170 exit:
    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 */
    180 void 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 
    252 exit:
    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 */
    264 void 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     }
    322 exit:
    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 */
    334 void 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 
    372 exit:
    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 */
    383 void 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 
    461 exit:
    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 */
    474 void 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 
    534 exit:
    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 */
    547 void 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 
    622 exit:
    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 */
    634 void 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 
    653 exit:
    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 */
    661 void 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 
    680 exit:
    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 */
    688 void 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 
    741 exit:
    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 */
    752 void 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 
    805 exit:
    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 */
    816 void 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);
    857 exit:
    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 */