blob: cefbfc37fb2d31acf3e2fc5ac90aa962bb776c8d [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/bignum.h"
Gilles Peskine3cb1e292020-11-25 15:37:20 +01003#include "mbedtls/entropy.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01004#include "constant_time_internal.h"
Gilles Peskine34e8a2c2022-09-27 22:04:51 +02005#include "bignum_core.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01006#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01007
Chris Jonese64a46f2020-12-03 17:44:03 +00008#if MBEDTLS_MPI_MAX_BITS > 792
9#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000010#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020011
Gilles Peskinedffc7102021-06-10 15:34:15 +020012/* Check the validity of the sign bit in an MPI object. Reject representations
13 * that are not supported by the rest of the library and indicate a bug when
14 * constructing the value. */
Gilles Peskine449bd832023-01-11 14:50:10 +010015static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskinedffc7102021-06-10 15:34:15 +020016{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010017 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +010018 if (X->s != 1 && X->s != -1) {
19 return 0;
20 }
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010021
22 /* The value 0 must be represented with the sign +1. A "negative zero"
23 * with s=-1 is an invalid representation. Forbid that. As an exception,
24 * we sometimes test the robustness of library functions when given
25 * a negative zero input. If a test case has a negative zero as input,
26 * we don't mind if the function has a negative zero output. */
Gilles Peskine449bd832023-01-11 14:50:10 +010027 if (!mbedtls_test_case_uses_negative_0 &&
28 mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
29 return 0;
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010030 }
31
Gilles Peskine449bd832023-01-11 14:50:10 +010032 return 1;
Gilles Peskinedffc7102021-06-10 15:34:15 +020033}
34
Gilles Peskine449bd832023-01-11 14:50:10 +010035typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010036 data_t *data;
37 size_t pos;
38 size_t chunk_len;
39} mbedtls_test_mpi_random;
40
41/*
42 * This function is called by the Miller-Rabin primality test each time it
43 * chooses a random witness. The witnesses (or non-witnesses as provided by the
44 * test) are stored in the data member of the state structure. Each number is in
45 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
46 */
Gilles Peskine449bd832023-01-11 14:50:10 +010047int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
48 unsigned char *buf,
49 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010050{
Gilles Peskine449bd832023-01-11 14:50:10 +010051 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010052
Gilles Peskine449bd832023-01-11 14:50:10 +010053 if (random == NULL || random->data->x == NULL || buf == NULL) {
54 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010055 }
56
Gilles Peskine449bd832023-01-11 14:50:10 +010057 if (random->pos + random->chunk_len > random->data->len
58 || random->chunk_len > len) {
59 return -1;
60 }
61
62 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010063
64 /* The witness is written to the end of the buffer, since the buffer is
65 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
66 * Writing the witness to the start of the buffer would result in the
67 * buffer being 'witness 000...000', which would be treated as
68 * witness * 2^n for some n. */
Gilles Peskine449bd832023-01-11 14:50:10 +010069 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
70 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010071
72 random->pos += random->chunk_len;
73
Gilles Peskine449bd832023-01-11 14:50:10 +010074 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010075}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010076
77/* Random generator that is told how many bytes to return. */
Gilles Peskine449bd832023-01-11 14:50:10 +010078static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010079{
80 size_t *bytes_left = state;
81 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010082 for (i = 0; i < len; i++) {
83 if (*bytes_left == 0) {
84 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
85 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010086 buf[i] = *bytes_left & 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010087 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010088 }
Gilles Peskine449bd832023-01-11 14:50:10 +010089 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010090}
91
Paul Bakker33b43f12013-08-20 11:48:36 +020092/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000093
Paul Bakker33b43f12013-08-20 11:48:36 +020094/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020096 * END_DEPENDENCIES
97 */
Paul Bakker5690efc2011-05-26 13:16:06 +000098
Hanno Beckerb48e1aa2018-12-18 23:25:01 +000099/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100100void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200101{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200102 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 mbedtls_mpi_init(&X);
105 mbedtls_mpi_init(&Y);
106 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
109 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
110 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
111 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200112
113exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200115}
116/* END_CASE */
117
118/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100119void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
120 char *input_A, int output_size, int result_read,
121 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000122{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000124 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100125 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
132 if (result_read == 0) {
133 TEST_ASSERT(sign_is_valid(&X));
134 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
135 if (result_write == 0) {
136 TEST_ASSERT(strcasecmp(str, input_A) == 0);
137 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000138 }
139 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000140
Paul Bakkerbd51b262014-07-10 15:26:12 +0200141exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000143}
Paul Bakker33b43f12013-08-20 11:48:36 +0200144/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000145
Paul Bakker33b43f12013-08-20 11:48:36 +0200146/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100147void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000148{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200149 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000150 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100151 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000152
Gilles Peskine449bd832023-01-11 14:50:10 +0100153 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000154
Paul Bakkere896fea2009-07-06 06:40:23 +0000155
Gilles Peskine449bd832023-01-11 14:50:10 +0100156 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
157 TEST_ASSERT(sign_is_valid(&X));
158 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
159 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000160
Paul Bakkerbd51b262014-07-10 15:26:12 +0200161exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100162 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000163}
Paul Bakker33b43f12013-08-20 11:48:36 +0200164/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000165
Paul Bakker33b43f12013-08-20 11:48:36 +0200166/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100167void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000168{
169 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000170 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000171 size_t len;
172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000174
175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
177 TEST_ASSERT(sign_is_valid(&X));
178 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
179 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000180
181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000183}
184/* END_CASE */
185
186/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100187void mpi_write_binary(char *input_X, data_t *input_A,
188 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000189{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000191 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000192 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000197
Gilles Peskine449bd832023-01-11 14:50:10 +0100198 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 buflen = mbedtls_mpi_size(&X);
201 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200202 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000204
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
206 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000207
Gilles Peskine449bd832023-01-11 14:50:10 +0100208 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
209 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000210 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000211
Paul Bakkerbd51b262014-07-10 15:26:12 +0200212exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100213 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000214}
Paul Bakker33b43f12013-08-20 11:48:36 +0200215/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000216
Janos Follathe344d0f2019-02-19 16:17:40 +0000217/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100218void mpi_write_binary_le(char *input_X, data_t *input_A,
219 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000220{
221 mbedtls_mpi X;
222 unsigned char buf[1000];
223 size_t buflen;
224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000226
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 buflen = mbedtls_mpi_size(&X);
232 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000233 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000235
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
237 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000238
Gilles Peskine449bd832023-01-11 14:50:10 +0100239 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
240 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000241 }
242
243exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100244 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000245}
246/* END_CASE */
247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100249void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000250{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000252 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000253 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000254 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000255 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000260
Gilles Peskine449bd832023-01-11 14:50:10 +0100261 file = fopen(input_file, "r");
262 TEST_ASSERT(file != NULL);
263 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000264 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000266
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 if (result == 0) {
268 TEST_ASSERT(sign_is_valid(&X));
269 buflen = mbedtls_mpi_size(&X);
270 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000271
Paul Bakkere896fea2009-07-06 06:40:23 +0000272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
274 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000275 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000276
Paul Bakkerbd51b262014-07-10 15:26:12 +0200277exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000279}
Paul Bakker33b43f12013-08-20 11:48:36 +0200280/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100283void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000284{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200285 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000286 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200287 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000288
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 file_out = fopen(output_file, "w");
294 TEST_ASSERT(file_out != NULL);
295 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000296 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000298
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 file_in = fopen(output_file, "r");
300 TEST_ASSERT(file_in != NULL);
301 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000302 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000306
Paul Bakkerbd51b262014-07-10 15:26:12 +0200307exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100308 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000309}
Paul Bakker33b43f12013-08-20 11:48:36 +0200310/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000311
Paul Bakker33b43f12013-08-20 11:48:36 +0200312/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100313void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000314{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 mbedtls_mpi_init(&X);
317 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
318 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000319
Paul Bakkerbd51b262014-07-10 15:26:12 +0200320exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000322}
Paul Bakker33b43f12013-08-20 11:48:36 +0200323/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000324
Paul Bakker33b43f12013-08-20 11:48:36 +0200325/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100326void mpi_set_bit(char *input_X, int pos, int val,
327 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000328{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100330 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000331
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
333 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
334 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100335
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 if (result == 0) {
337 TEST_ASSERT(sign_is_valid(&X));
338 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100339 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000340
Paul Bakkerbd51b262014-07-10 15:26:12 +0200341exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000343}
Paul Bakker33b43f12013-08-20 11:48:36 +0200344/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000345
Paul Bakker33b43f12013-08-20 11:48:36 +0200346/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100347void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000348{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
353 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000354
Paul Bakkerbd51b262014-07-10 15:26:12 +0200355exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000357}
Paul Bakker33b43f12013-08-20 11:48:36 +0200358/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000359
Paul Bakker33b43f12013-08-20 11:48:36 +0200360/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100361void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000362{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000365
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
367 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000368
Paul Bakkerbd51b262014-07-10 15:26:12 +0200369exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000371}
Paul Bakker33b43f12013-08-20 11:48:36 +0200372/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000373
Paul Bakker33b43f12013-08-20 11:48:36 +0200374/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100375void mpi_gcd(char *input_X, char *input_Y,
376 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000377{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000380
Gilles Peskine449bd832023-01-11 14:50:10 +0100381 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
382 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
383 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
384 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
385 TEST_ASSERT(sign_is_valid(&Z));
386 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000387
Paul Bakkerbd51b262014-07-10 15:26:12 +0200388exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000390}
Paul Bakker33b43f12013-08-20 11:48:36 +0200391/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000392
Paul Bakker33b43f12013-08-20 11:48:36 +0200393/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100394void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000395{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100397 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000398
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
400 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000401
Paul Bakkerbd51b262014-07-10 15:26:12 +0200402exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000404}
Paul Bakker33b43f12013-08-20 11:48:36 +0200405/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000406
Paul Bakker33b43f12013-08-20 11:48:36 +0200407/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100408void mpi_cmp_mpi(char *input_X, char *input_Y,
409 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000410{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000413
Gilles Peskine449bd832023-01-11 14:50:10 +0100414 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
415 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
416 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000417
Paul Bakkerbd51b262014-07-10 15:26:12 +0200418exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000420}
Paul Bakker33b43f12013-08-20 11:48:36 +0200421/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000422
Paul Bakker33b43f12013-08-20 11:48:36 +0200423/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100424void mpi_lt_mpi_ct(int size_X, char *input_X,
425 int size_Y, char *input_Y,
426 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100427{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200428 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100429 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100430 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100432
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
434 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100435
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
437 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100438
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
440 if (input_err == 0) {
441 TEST_ASSERT(ret == input_uret);
442 }
Janos Follath385d5b82019-09-11 16:07:14 +0100443
444exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100446}
447/* END_CASE */
448
449/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100450void mpi_cmp_abs(char *input_X, char *input_Y,
451 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000452{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
457 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
458 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000459
Paul Bakkerbd51b262014-07-10 15:26:12 +0200460exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100461 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000462}
Paul Bakker33b43f12013-08-20 11:48:36 +0200463/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000464
Paul Bakker33b43f12013-08-20 11:48:36 +0200465/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100466void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000467{
Gilles Peskined0722f82021-06-10 23:00:33 +0200468 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 mbedtls_mpi_init(&src);
470 mbedtls_mpi_init(&dst);
471 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000472
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
474 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200475
476 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
478 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
479 TEST_ASSERT(sign_is_valid(&dst));
480 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000481
Gilles Peskined0722f82021-06-10 23:00:33 +0200482 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100483 mbedtls_mpi_free(&dst);
484 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
485 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
486 TEST_ASSERT(sign_is_valid(&dst));
487 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200488
489 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_mpi_free(&dst);
491 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
492 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
493 TEST_ASSERT(sign_is_valid(&dst));
494 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200495
Paul Bakkerbd51b262014-07-10 15:26:12 +0200496exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 mbedtls_mpi_free(&src);
498 mbedtls_mpi_free(&dst);
499 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100500}
501/* END_CASE */
502
503/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100505{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200506 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 mbedtls_mpi_init(&A);
508 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000509
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
511 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200512
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
514 TEST_ASSERT(sign_is_valid(&X));
515 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000516
Paul Bakkerbd51b262014-07-10 15:26:12 +0200517exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_mpi_free(&A);
519 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000520}
Paul Bakker33b43f12013-08-20 11:48:36 +0200521/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000522
Paul Bakker33b43f12013-08-20 11:48:36 +0200523/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200525{
526 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
528 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
531 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200532
Gilles Peskined0722f82021-06-10 23:00:33 +0200533 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
535 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
536 mbedtls_mpi_swap(&X, &Y);
537 TEST_ASSERT(sign_is_valid(&X));
538 TEST_ASSERT(sign_is_valid(&Y));
539 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
540 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200541
Gilles Peskined0722f82021-06-10 23:00:33 +0200542 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100543 mbedtls_mpi_free(&X);
544 mbedtls_mpi_free(&Y);
545 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
546 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
547 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
548 TEST_ASSERT(sign_is_valid(&X));
549 TEST_ASSERT(sign_is_valid(&Y));
550 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
551 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200552
553 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 mbedtls_mpi_free(&X);
555 mbedtls_mpi_free(&Y);
556 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
557 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
558 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
559 TEST_ASSERT(sign_is_valid(&X));
560 TEST_ASSERT(sign_is_valid(&Y));
561 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
562 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200563
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200564exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100565 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
566 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200567}
568/* END_CASE */
569
570/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100571void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200572{
573 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200575
Gilles Peskine449bd832023-01-11 14:50:10 +0100576 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
577 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200578
Gilles Peskine449bd832023-01-11 14:50:10 +0100579 mbedtls_mpi_swap(&X, &X);
580 TEST_ASSERT(sign_is_valid(&X));
581 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200582
583exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100584 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200585}
586/* END_CASE */
587
588/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100589void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100590{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100592 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100593
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
595 if (used > 0) {
596 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
597 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200598 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 TEST_EQUAL(X.n, (size_t) before);
600 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
601 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100602
Paul Bakkerbd51b262014-07-10 15:26:12 +0200603exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100605}
606/* END_CASE */
607
608/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609void mpi_add_mpi(char *input_X, char *input_Y,
610 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000611{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
616 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
617 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
618 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
619 TEST_ASSERT(sign_is_valid(&Z));
620 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000621
Gilles Peskine56f943a2020-07-23 01:18:11 +0200622 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
624 TEST_ASSERT(sign_is_valid(&X));
625 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
626 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200627
628 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100629 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
630 TEST_ASSERT(sign_is_valid(&Y));
631 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200632
Paul Bakkerbd51b262014-07-10 15:26:12 +0200633exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000635}
Paul Bakker33b43f12013-08-20 11:48:36 +0200636/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000637
Paul Bakker33b43f12013-08-20 11:48:36 +0200638/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100639void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100640{
641 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100642 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100643
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100645
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
647 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
648 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
649 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100650
Gilles Peskine449bd832023-01-11 14:50:10 +0100651 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
652 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
653 TEST_ASSERT(sign_is_valid(&X));
654 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
657 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
658 TEST_ASSERT(sign_is_valid(&X));
659 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100660
661exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100663}
664/* END_CASE */
665
666
667/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100668void mpi_add_abs(char *input_X, char *input_Y,
669 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000670{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
675 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
676 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
677 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
678 TEST_ASSERT(sign_is_valid(&Z));
679 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000680
Gilles Peskine56f943a2020-07-23 01:18:11 +0200681 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
683 TEST_ASSERT(sign_is_valid(&X));
684 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
685 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200686
687 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
689 TEST_ASSERT(sign_is_valid(&Y));
690 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000691
Paul Bakkerbd51b262014-07-10 15:26:12 +0200692exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000694}
Paul Bakker33b43f12013-08-20 11:48:36 +0200695/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000696
Paul Bakker33b43f12013-08-20 11:48:36 +0200697/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100698void mpi_add_int(char *input_X, int input_Y,
699 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000700{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000703
Gilles Peskine449bd832023-01-11 14:50:10 +0100704 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
705 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
706 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
707 TEST_ASSERT(sign_is_valid(&Z));
708 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000709
Paul Bakkerbd51b262014-07-10 15:26:12 +0200710exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000712}
Paul Bakker33b43f12013-08-20 11:48:36 +0200713/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000714
Paul Bakker33b43f12013-08-20 11:48:36 +0200715/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100716void mpi_sub_mpi(char *input_X, char *input_Y,
717 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000718{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100720 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000721
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
723 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
724 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
725 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
726 TEST_ASSERT(sign_is_valid(&Z));
727 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000728
Gilles Peskine56f943a2020-07-23 01:18:11 +0200729 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100730 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
731 TEST_ASSERT(sign_is_valid(&X));
732 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
733 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200734
735 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100736 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
737 TEST_ASSERT(sign_is_valid(&Y));
738 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200739
Paul Bakkerbd51b262014-07-10 15:26:12 +0200740exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000742}
Paul Bakker33b43f12013-08-20 11:48:36 +0200743/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000744
Paul Bakker33b43f12013-08-20 11:48:36 +0200745/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100746void mpi_sub_abs(char *input_X, char *input_Y,
747 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000748{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000750 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000752
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
754 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
755 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100756
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
758 TEST_ASSERT(res == sub_result);
759 TEST_ASSERT(sign_is_valid(&Z));
760 if (res == 0) {
761 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
762 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000763
Gilles Peskine56f943a2020-07-23 01:18:11 +0200764 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
766 TEST_ASSERT(sign_is_valid(&X));
767 if (sub_result == 0) {
768 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
769 }
770 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200771
772 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
774 TEST_ASSERT(sign_is_valid(&Y));
775 if (sub_result == 0) {
776 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
777 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200778
Paul Bakkerbd51b262014-07-10 15:26:12 +0200779exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000781}
Paul Bakker33b43f12013-08-20 11:48:36 +0200782/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000783
Paul Bakker33b43f12013-08-20 11:48:36 +0200784/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100785void mpi_sub_int(char *input_X, int input_Y,
786 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000787{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000790
Gilles Peskine449bd832023-01-11 14:50:10 +0100791 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
792 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
793 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
794 TEST_ASSERT(sign_is_valid(&Z));
795 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000796
Paul Bakkerbd51b262014-07-10 15:26:12 +0200797exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100798 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000799}
Paul Bakker33b43f12013-08-20 11:48:36 +0200800/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000801
Paul Bakker33b43f12013-08-20 11:48:36 +0200802/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100803void mpi_mul_mpi(char *input_X, char *input_Y,
804 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000805{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100807 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000808
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
810 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
811 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
812 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
813 TEST_ASSERT(sign_is_valid(&Z));
814 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000815
Paul Bakkerbd51b262014-07-10 15:26:12 +0200816exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100817 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000818}
Paul Bakker33b43f12013-08-20 11:48:36 +0200819/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000820
Paul Bakker33b43f12013-08-20 11:48:36 +0200821/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100822void mpi_mul_int(char *input_X, int input_Y,
823 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000824{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100826 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000827
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
829 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
830 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
831 TEST_ASSERT(sign_is_valid(&Z));
832 if (strcmp(result_comparison, "==") == 0) {
833 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
834 } else if (strcmp(result_comparison, "!=") == 0) {
835 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
836 } else {
837 TEST_ASSERT("unknown operator" == 0);
838 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000839
Paul Bakkerbd51b262014-07-10 15:26:12 +0200840exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000842}
Paul Bakker33b43f12013-08-20 11:48:36 +0200843/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000844
Paul Bakker33b43f12013-08-20 11:48:36 +0200845/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846void mpi_div_mpi(char *input_X, char *input_Y,
847 char *input_A, char *input_B,
848 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000849{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200850 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000851 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
853 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000854
Gilles Peskine449bd832023-01-11 14:50:10 +0100855 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
856 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
857 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
858 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
859 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
860 TEST_ASSERT(res == div_result);
861 if (res == 0) {
862 TEST_ASSERT(sign_is_valid(&Q));
863 TEST_ASSERT(sign_is_valid(&R));
864 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
865 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000866 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000867
Paul Bakkerbd51b262014-07-10 15:26:12 +0200868exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100869 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
870 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000871}
Paul Bakker33b43f12013-08-20 11:48:36 +0200872/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000873
Paul Bakker33b43f12013-08-20 11:48:36 +0200874/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100875void mpi_div_int(char *input_X, int input_Y,
876 char *input_A, char *input_B,
877 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000878{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000880 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
882 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000883
Gilles Peskine449bd832023-01-11 14:50:10 +0100884 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
885 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
886 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
887 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
888 TEST_ASSERT(res == div_result);
889 if (res == 0) {
890 TEST_ASSERT(sign_is_valid(&Q));
891 TEST_ASSERT(sign_is_valid(&R));
892 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
893 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000894 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000895
Paul Bakkerbd51b262014-07-10 15:26:12 +0200896exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100897 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
898 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000899}
Paul Bakker33b43f12013-08-20 11:48:36 +0200900/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000901
Paul Bakker33b43f12013-08-20 11:48:36 +0200902/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100903void mpi_mod_mpi(char *input_X, char *input_Y,
904 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100905{
906 mbedtls_mpi X, Y, A;
907 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100909
Gilles Peskine449bd832023-01-11 14:50:10 +0100910 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
911 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
912 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
913 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
914 TEST_ASSERT(res == div_result);
915 if (res == 0) {
916 TEST_ASSERT(sign_is_valid(&X));
917 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100918 }
919
920exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100922}
923/* END_CASE */
924
925/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100926void mpi_mod_int(char *input_X, char *input_Y,
927 char *input_A, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100928{
929 mbedtls_mpi X;
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000930 mbedtls_mpi Y;
931 mbedtls_mpi A;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100932 int res;
933 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 mbedtls_mpi_init(&X);
936 mbedtls_mpi_init(&Y);
937 mbedtls_mpi_init(&A);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000938
939 /* We use MPIs to read Y and A since the test framework limits us to
940 * ints, so we can't have 64-bit values */
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
942 TEST_EQUAL(mbedtls_test_read_mpi(&Y, input_Y), 0);
943 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 TEST_EQUAL(Y.n, 1);
946 TEST_EQUAL(A.n, 1);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000947
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000948 /* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
949
950 /* Since we're converting sign+magnitude to two's complement, we lose one
951 * bit of value in the output. This means there are some values we can't
952 * represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
953 * invalid test cases, so could be considered "won't happen", but they are
954 * easy to test for, and this helps guard against human error. */
955
956 mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 TEST_ASSERT(y >= 0); /* If y < 0 here, we can't make negative y */
958 if (Y.s == -1) {
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000959 y = -y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 }
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000961
962 mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 TEST_ASSERT(a >= 0); /* Same goes for a */
964 if (A.s == -1) {
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000965 a = -a;
Gilles Peskine449bd832023-01-11 14:50:10 +0100966 }
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000967
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 res = mbedtls_mpi_mod_int(&r, &X, y);
969 TEST_EQUAL(res, mod_result);
970 if (res == 0) {
971 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100972 }
973
974exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100975 mbedtls_mpi_free(&X);
976 mbedtls_mpi_free(&Y);
977 mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100978}
979/* END_CASE */
980
981/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100982void mpi_exp_mod(char *input_A, char *input_E,
983 char *input_N, char *input_X,
984 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000985{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +0000987 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100988 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
989 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000990
Gilles Peskine449bd832023-01-11 14:50:10 +0100991 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
992 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
993 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
994 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000995
Gilles Peskine449bd832023-01-11 14:50:10 +0100996 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
997 TEST_ASSERT(res == exp_result);
998 if (res == 0) {
999 TEST_ASSERT(sign_is_valid(&Z));
1000 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001001 }
1002
1003 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001004 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1005 TEST_ASSERT(res == exp_result);
1006 if (res == 0) {
1007 TEST_ASSERT(sign_is_valid(&Z));
1008 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001009 }
1010
1011 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1013 TEST_ASSERT(res == exp_result);
1014 if (res == 0) {
1015 TEST_ASSERT(sign_is_valid(&Z));
1016 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001017 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001018
Paul Bakkerbd51b262014-07-10 15:26:12 +02001019exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1021 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001022}
Paul Bakker33b43f12013-08-20 11:48:36 +02001023/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001024
Paul Bakker33b43f12013-08-20 11:48:36 +02001025/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001026void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1027 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001028{
1029 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1031 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001032
Chris Jonesaa850cd2020-12-03 11:35:41 +00001033 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001034 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1035 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1036 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001037
1038 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1040 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1041 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001042
1043 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001044 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1045 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1046 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001047
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 if (strlen(input_RR)) {
1049 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1050 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001051
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001053
1054exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1056 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001057}
1058/* END_CASE */
1059
1060/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001061void mpi_inv_mod(char *input_X, char *input_Y,
1062 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001063{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001065 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001067
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1069 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1070 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1071 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1072 TEST_ASSERT(res == div_result);
1073 if (res == 0) {
1074 TEST_ASSERT(sign_is_valid(&Z));
1075 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001076 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001077
Paul Bakkerbd51b262014-07-10 15:26:12 +02001078exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001080}
Paul Bakker33b43f12013-08-20 11:48:36 +02001081/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001082
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001084void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001085{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001087 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001088 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001089
Gilles Peskine449bd832023-01-11 14:50:10 +01001090 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1091 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1092 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001093
Paul Bakkerbd51b262014-07-10 15:26:12 +02001094exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001096}
Paul Bakker33b43f12013-08-20 11:48:36 +02001097/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001098
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001099/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001100void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1101 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001102{
1103 mbedtls_mpi X;
1104 int res;
1105 mbedtls_test_mpi_random rand;
1106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001108 rand.data = witnesses;
1109 rand.pos = 0;
1110 rand.chunk_len = chunk_len;
1111
Gilles Peskine449bd832023-01-11 14:50:10 +01001112 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1113 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1114 mbedtls_test_mpi_miller_rabin_determinizer,
1115 &rand);
1116 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001117
1118 rand.data = witnesses;
1119 rand.pos = 0;
1120 rand.chunk_len = chunk_len;
1121
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1123 mbedtls_test_mpi_miller_rabin_determinizer,
1124 &rand);
1125 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001126
1127exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001128 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001129}
1130/* END_CASE */
1131
1132/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001133void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001134{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001136 int my_ret;
1137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1141 mbedtls_test_rnd_std_rand, NULL);
1142 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001143
Gilles Peskine449bd832023-01-11 14:50:10 +01001144 if (ref_ret == 0) {
1145 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001146
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 TEST_ASSERT(actual_bits >= (size_t) bits);
1148 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1149 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001150
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1152 mbedtls_test_rnd_std_rand,
1153 NULL) == 0);
1154 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001155 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1157 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1158 mbedtls_test_rnd_std_rand,
1159 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001160 }
1161 }
1162
Paul Bakkerbd51b262014-07-10 15:26:12 +02001163exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001165}
1166/* END_CASE */
1167
Paul Bakker33b43f12013-08-20 11:48:36 +02001168/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001169void mpi_shift_l(char *input_X, int shift_X,
1170 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001171{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001174
Gilles Peskine449bd832023-01-11 14:50:10 +01001175 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1176 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1177 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1178 TEST_ASSERT(sign_is_valid(&X));
1179 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001180
Paul Bakkerbd51b262014-07-10 15:26:12 +02001181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001183}
Paul Bakker33b43f12013-08-20 11:48:36 +02001184/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001185
Paul Bakker33b43f12013-08-20 11:48:36 +02001186/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001187void mpi_shift_r(char *input_X, int shift_X,
1188 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001189{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1194 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1195 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1196 TEST_ASSERT(sign_is_valid(&X));
1197 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001198
Paul Bakkerbd51b262014-07-10 15:26:12 +02001199exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001201}
Paul Bakker33b43f12013-08-20 11:48:36 +02001202/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001203
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001204/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001205void mpi_fill_random(int wanted_bytes, int rng_bytes,
1206 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001207{
1208 mbedtls_mpi X;
1209 int ret;
1210 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001214 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001215 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1216 if (before < 0) {
1217 before = -before;
1218 }
1219 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001220 }
1221
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1223 f_rng_bytes_left, &bytes_left);
1224 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001225
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001227 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1228 * as a big-endian representation of the number. We know when
1229 * our RNG function returns null bytes, so we know how many
1230 * leading zero bytes the number has. */
1231 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001233 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001234 }
1235 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1236 (size_t) wanted_bytes);
1237 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1238 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001239 }
1240
1241exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001243}
1244/* END_CASE */
1245
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001246/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001247void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001248{
1249 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1250 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1251 * is a valid value. However, negating it (`-n`) has undefined behavior
1252 * (although in practice `-n` evaluates to the value n).
1253 *
1254 * This function has ad hoc tests for this value. It's separated from other
1255 * functions because the test framework makes it hard to pass this value
1256 * into test cases.
1257 *
1258 * In the comments here:
1259 * - biL = number of bits in limbs
1260 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1261 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1262 */
1263
1264 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001265 mbedtls_mpi_init(&A);
1266 mbedtls_mpi_init(&R);
1267 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001268
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001270 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1272 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1273 (mbedtls_mpi_uint) 1 << (biL - 1));
1274 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001275
1276 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001277 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1278 TEST_EQUAL(A.s, -1);
1279 TEST_EQUAL(A.n, 1);
1280 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001281
1282 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001284
1285 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1286 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001288
1289 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1290 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001292
1293 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1295 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1296 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001297
1298 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1300 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1301 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001302
1303 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1305 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1306 TEST_EQUAL(X.s, -1);
1307 TEST_EQUAL(X.n, 2);
1308 TEST_EQUAL(X.p[0], 0);
1309 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001310
1311 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 mbedtls_mpi_free(&X);
1313 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1314 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1315 TEST_EQUAL(X.s, 1);
1316 TEST_EQUAL(X.n, 1);
1317 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001318
1319 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1321 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1322 TEST_EQUAL(X.s, 1);
1323 TEST_EQUAL(X.n, 1);
1324 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001325
1326 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001327 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1328 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1329 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001330
1331 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001332 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1333 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1334 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1335 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001336
1337 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1339 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1340 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1341 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001342
1343 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001344 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1345 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1346 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1347 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001348
1349 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1351 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1352 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1353 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001354
1355 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1357 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1358 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1359 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001360
1361 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1363 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1364 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1365 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001366
1367 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1369 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1370 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1371 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001372
1373 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1375 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001376
1377 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001378 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1379 mbedtls_test_rnd_std_rand, NULL),
1380 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001381
1382exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 mbedtls_mpi_free(&A);
1384 mbedtls_mpi_free(&R);
1385 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001386}
1387/* END_CASE */
1388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001389/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001390void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001391{
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001393}
Paul Bakker33b43f12013-08-20 11:48:36 +02001394/* END_CASE */