blob: 7f858e5543a49de47ac12ec2860cd6a7c9103000 [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) {
Gilles Peskine017f0b72022-12-04 13:29:20 +0100136 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 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 Peskine7768a8e2022-12-04 15:58:48 +0100926void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
927 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100928{
929 mbedtls_mpi X;
930 int res;
931 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000934
Gilles Peskine449bd832023-01-11 14:50:10 +0100935 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000936
Gilles Peskine449bd832023-01-11 14:50:10 +0100937 res = mbedtls_mpi_mod_int(&r, &X, y);
938 TEST_EQUAL(res, mod_result);
939 if (res == 0) {
940 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100941 }
942
943exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100945}
946/* END_CASE */
947
948/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100949void mpi_exp_mod(char *input_A, char *input_E,
950 char *input_N, char *input_X,
951 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000952{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +0000954 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
956 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
959 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
960 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
961 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000962
Gilles Peskine449bd832023-01-11 14:50:10 +0100963 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
964 TEST_ASSERT(res == exp_result);
965 if (res == 0) {
966 TEST_ASSERT(sign_is_valid(&Z));
967 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +0200968 }
969
970 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100971 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
972 TEST_ASSERT(res == exp_result);
973 if (res == 0) {
974 TEST_ASSERT(sign_is_valid(&Z));
975 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +0200976 }
977
978 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +0100979 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
980 TEST_ASSERT(res == exp_result);
981 if (res == 0) {
982 TEST_ASSERT(sign_is_valid(&Z));
983 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000984 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000985
Paul Bakkerbd51b262014-07-10 15:26:12 +0200986exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100987 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
988 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000989}
Paul Bakker33b43f12013-08-20 11:48:36 +0200990/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000991
Paul Bakker33b43f12013-08-20 11:48:36 +0200992/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100993void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
994 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +0000995{
996 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100997 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
998 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +0000999
Chris Jonesaa850cd2020-12-03 11:35:41 +00001000 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001001 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1002 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1003 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001004
1005 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1007 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1008 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001009
1010 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001011 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1012 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1013 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 if (strlen(input_RR)) {
1016 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1017 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001018
Gilles Peskine449bd832023-01-11 14:50:10 +01001019 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001020
1021exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1023 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001024}
1025/* END_CASE */
1026
1027/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001028void mpi_inv_mod(char *input_X, char *input_Y,
1029 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001030{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001031 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001032 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001034
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1036 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1037 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1038 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1039 TEST_ASSERT(res == div_result);
1040 if (res == 0) {
1041 TEST_ASSERT(sign_is_valid(&Z));
1042 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001043 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001044
Paul Bakkerbd51b262014-07-10 15:26:12 +02001045exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001047}
Paul Bakker33b43f12013-08-20 11:48:36 +02001048/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001049
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001051void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001052{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001054 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001055 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001056
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1058 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1059 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001060
Paul Bakkerbd51b262014-07-10 15:26:12 +02001061exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001063}
Paul Bakker33b43f12013-08-20 11:48:36 +02001064/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001065
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001067void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1068 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001069{
1070 mbedtls_mpi X;
1071 int res;
1072 mbedtls_test_mpi_random rand;
1073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001075 rand.data = witnesses;
1076 rand.pos = 0;
1077 rand.chunk_len = chunk_len;
1078
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1080 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1081 mbedtls_test_mpi_miller_rabin_determinizer,
1082 &rand);
1083 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001084
1085 rand.data = witnesses;
1086 rand.pos = 0;
1087 rand.chunk_len = chunk_len;
1088
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1090 mbedtls_test_mpi_miller_rabin_determinizer,
1091 &rand);
1092 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001093
1094exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001096}
1097/* END_CASE */
1098
1099/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001100void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001101{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001103 int my_ret;
1104
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001106
Gilles Peskine449bd832023-01-11 14:50:10 +01001107 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1108 mbedtls_test_rnd_std_rand, NULL);
1109 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001110
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 if (ref_ret == 0) {
1112 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001113
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 TEST_ASSERT(actual_bits >= (size_t) bits);
1115 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1116 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001117
Gilles Peskine449bd832023-01-11 14:50:10 +01001118 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1119 mbedtls_test_rnd_std_rand,
1120 NULL) == 0);
1121 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001122 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001123 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1124 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1125 mbedtls_test_rnd_std_rand,
1126 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001127 }
1128 }
1129
Paul Bakkerbd51b262014-07-10 15:26:12 +02001130exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001131 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001132}
1133/* END_CASE */
1134
Paul Bakker33b43f12013-08-20 11:48:36 +02001135/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001136void mpi_shift_l(char *input_X, int shift_X,
1137 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001138{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001139 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001141
Gilles Peskine449bd832023-01-11 14:50:10 +01001142 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1143 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1144 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1145 TEST_ASSERT(sign_is_valid(&X));
1146 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001147
Paul Bakkerbd51b262014-07-10 15:26:12 +02001148exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001150}
Paul Bakker33b43f12013-08-20 11:48:36 +02001151/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001152
Paul Bakker33b43f12013-08-20 11:48:36 +02001153/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001154void mpi_shift_r(char *input_X, int shift_X,
1155 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001156{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001157 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001159
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1161 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1162 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1163 TEST_ASSERT(sign_is_valid(&X));
1164 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001165
Paul Bakkerbd51b262014-07-10 15:26:12 +02001166exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001168}
Paul Bakker33b43f12013-08-20 11:48:36 +02001169/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001170
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001171/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001172void mpi_fill_random(int wanted_bytes, int rng_bytes,
1173 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001174{
1175 mbedtls_mpi X;
1176 int ret;
1177 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001181 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1183 if (before < 0) {
1184 before = -before;
1185 }
1186 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001187 }
1188
Gilles Peskine449bd832023-01-11 14:50:10 +01001189 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1190 f_rng_bytes_left, &bytes_left);
1191 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001194 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1195 * as a big-endian representation of the number. We know when
1196 * our RNG function returns null bytes, so we know how many
1197 * leading zero bytes the number has. */
1198 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001200 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001201 }
1202 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1203 (size_t) wanted_bytes);
1204 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1205 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001206 }
1207
1208exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001210}
1211/* END_CASE */
1212
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001213/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001214void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001215{
1216 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1217 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1218 * is a valid value. However, negating it (`-n`) has undefined behavior
1219 * (although in practice `-n` evaluates to the value n).
1220 *
1221 * This function has ad hoc tests for this value. It's separated from other
1222 * functions because the test framework makes it hard to pass this value
1223 * into test cases.
1224 *
1225 * In the comments here:
1226 * - biL = number of bits in limbs
1227 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1228 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1229 */
1230
1231 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 mbedtls_mpi_init(&A);
1233 mbedtls_mpi_init(&R);
1234 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001235
Gilles Peskine449bd832023-01-11 14:50:10 +01001236 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001237 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1239 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1240 (mbedtls_mpi_uint) 1 << (biL - 1));
1241 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001242
1243 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1245 TEST_EQUAL(A.s, -1);
1246 TEST_EQUAL(A.n, 1);
1247 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001248
1249 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001251
1252 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1253 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001255
1256 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1257 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001259
1260 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1262 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1263 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001264
1265 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001266 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1267 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1268 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001269
1270 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1272 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1273 TEST_EQUAL(X.s, -1);
1274 TEST_EQUAL(X.n, 2);
1275 TEST_EQUAL(X.p[0], 0);
1276 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001277
1278 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001279 mbedtls_mpi_free(&X);
1280 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1281 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1282 TEST_EQUAL(X.s, 1);
1283 TEST_EQUAL(X.n, 1);
1284 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001285
1286 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1288 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1289 TEST_EQUAL(X.s, 1);
1290 TEST_EQUAL(X.n, 1);
1291 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001292
1293 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1295 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1296 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001297
1298 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001299 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1300 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1301 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1302 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001303
1304 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1306 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1307 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1308 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001309
1310 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1312 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1313 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1314 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001315
1316 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1318 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1319 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1320 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001321
1322 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1324 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1325 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1326 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001327
1328 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001329 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1330 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1331 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1332 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001333
1334 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001335 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1336 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1337 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1338 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001339
1340 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1342 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001343
1344 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1346 mbedtls_test_rnd_std_rand, NULL),
1347 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001348
1349exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 mbedtls_mpi_free(&A);
1351 mbedtls_mpi_free(&R);
1352 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001353}
1354/* END_CASE */
1355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001357void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001358{
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001360}
Paul Bakker33b43f12013-08-20 11:48:36 +02001361/* END_CASE */