blob: 3ac4e10ea6cc7acfa1a98e1902863935d0265921 [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 Follath5f316972024-08-22 14:53:13 +01006#include "bignum_internal.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01007#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01008
Chris Jonese64a46f2020-12-03 17:44:03 +00009#if MBEDTLS_MPI_MAX_BITS > 792
10#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000011#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020012
Gilles Peskinedffc7102021-06-10 15:34:15 +020013/* Check the validity of the sign bit in an MPI object. Reject representations
14 * that are not supported by the rest of the library and indicate a bug when
15 * constructing the value. */
Gilles Peskine449bd832023-01-11 14:50:10 +010016static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskinedffc7102021-06-10 15:34:15 +020017{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010018 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +010019 if (X->s != 1 && X->s != -1) {
20 return 0;
21 }
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010022
23 /* The value 0 must be represented with the sign +1. A "negative zero"
24 * with s=-1 is an invalid representation. Forbid that. As an exception,
25 * we sometimes test the robustness of library functions when given
26 * a negative zero input. If a test case has a negative zero as input,
27 * we don't mind if the function has a negative zero output. */
Paul Elliottc7a1e992023-11-03 18:44:57 +000028 if (!mbedtls_test_get_case_uses_negative_0() &&
Gilles Peskine449bd832023-01-11 14:50:10 +010029 mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
30 return 0;
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010031 }
32
Gilles Peskine449bd832023-01-11 14:50:10 +010033 return 1;
Gilles Peskinedffc7102021-06-10 15:34:15 +020034}
35
Michael Schuster275b6982024-06-07 01:51:54 +020036#if defined(MBEDTLS_GENPRIME)
Gilles Peskine449bd832023-01-11 14:50:10 +010037typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010038 data_t *data;
39 size_t pos;
40 size_t chunk_len;
41} mbedtls_test_mpi_random;
42
43/*
44 * This function is called by the Miller-Rabin primality test each time it
45 * chooses a random witness. The witnesses (or non-witnesses as provided by the
46 * test) are stored in the data member of the state structure. Each number is in
47 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
48 */
Michael Schusterb1e33fb2024-06-04 02:30:22 +020049static int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
Michael Schuster31b1cb82024-06-04 02:41:10 +020050 unsigned char *buf,
51 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010052{
Gilles Peskine449bd832023-01-11 14:50:10 +010053 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010054
Gilles Peskine449bd832023-01-11 14:50:10 +010055 if (random == NULL || random->data->x == NULL || buf == NULL) {
56 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010057 }
58
Gilles Peskine449bd832023-01-11 14:50:10 +010059 if (random->pos + random->chunk_len > random->data->len
60 || random->chunk_len > len) {
61 return -1;
62 }
63
64 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010065
66 /* The witness is written to the end of the buffer, since the buffer is
67 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
68 * Writing the witness to the start of the buffer would result in the
69 * buffer being 'witness 000...000', which would be treated as
70 * witness * 2^n for some n. */
Gilles Peskine449bd832023-01-11 14:50:10 +010071 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
72 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010073
74 random->pos += random->chunk_len;
75
Gilles Peskine449bd832023-01-11 14:50:10 +010076 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010077}
Michael Schuster275b6982024-06-07 01:51:54 +020078#endif /* MBEDTLS_GENPRIME */
Gilles Peskine3cb1e292020-11-25 15:37:20 +010079
80/* Random generator that is told how many bytes to return. */
Gilles Peskine449bd832023-01-11 14:50:10 +010081static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010082{
83 size_t *bytes_left = state;
84 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010085 for (i = 0; i < len; i++) {
86 if (*bytes_left == 0) {
87 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
88 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010089 buf[i] = *bytes_left & 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010090 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010091 }
Gilles Peskine449bd832023-01-11 14:50:10 +010092 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010093}
94
Paul Bakker33b43f12013-08-20 11:48:36 +020095/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000096
Paul Bakker33b43f12013-08-20 11:48:36 +020097/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020098 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020099 * END_DEPENDENCIES
100 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000101
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000102/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100103void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200104{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200105 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200106
Gilles Peskine449bd832023-01-11 14:50:10 +0100107 mbedtls_mpi_init(&X);
108 mbedtls_mpi_init(&Y);
109 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200110
Gilles Peskine449bd832023-01-11 14:50:10 +0100111 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
112 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
113 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
114 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200115
116exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100117 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200118}
119/* END_CASE */
120
121/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100122void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
123 char *input_A, int output_size, int result_read,
124 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000125{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000127 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100128 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000133
Gilles Peskine449bd832023-01-11 14:50:10 +0100134 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
135 if (result_read == 0) {
136 TEST_ASSERT(sign_is_valid(&X));
137 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
138 if (result_write == 0) {
Gilles Peskine017f0b72022-12-04 13:29:20 +0100139 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine449bd832023-01-11 14:50:10 +0100140 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000141 }
142 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000143
Paul Bakkerbd51b262014-07-10 15:26:12 +0200144exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100145 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000146}
Paul Bakker33b43f12013-08-20 11:48:36 +0200147/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000148
Paul Bakker33b43f12013-08-20 11:48:36 +0200149/* BEGIN_CASE */
Valerio Settif988f952024-01-30 14:40:31 +0100150void mpi_zero_length_buffer_is_null()
151{
152 mbedtls_mpi X;
153 size_t olen;
154
155 mbedtls_mpi_init(&X);
156
157 /* Simply test that the following functions do not crash when a NULL buffer
158 * pointer and 0 length is passed. We don't care much about the return value. */
159 TEST_EQUAL(mbedtls_mpi_read_binary(&X, NULL, 0), 0);
160 TEST_EQUAL(mbedtls_mpi_read_binary_le(&X, NULL, 0), 0);
161 TEST_EQUAL(mbedtls_mpi_write_string(&X, 16, NULL, 0, &olen), MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
162 TEST_EQUAL(mbedtls_mpi_write_binary(&X, NULL, 0), 0);
163
164exit:
165 mbedtls_mpi_free(&X);
166}
167/* END_CASE */
168
169/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100170void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000171{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000173 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100174 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000177
Paul Bakkere896fea2009-07-06 06:40:23 +0000178
Gilles Peskine449bd832023-01-11 14:50:10 +0100179 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
180 TEST_ASSERT(sign_is_valid(&X));
181 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
182 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000183
Paul Bakkerbd51b262014-07-10 15:26:12 +0200184exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100185 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000186}
Paul Bakker33b43f12013-08-20 11:48:36 +0200187/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000188
Paul Bakker33b43f12013-08-20 11:48:36 +0200189/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100190void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000191{
192 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000193 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000194 size_t len;
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000197
198
Gilles Peskine449bd832023-01-11 14:50:10 +0100199 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
200 TEST_ASSERT(sign_is_valid(&X));
201 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
202 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000203
204exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100205 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000206}
207/* END_CASE */
208
209/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100210void mpi_write_binary(char *input_X, data_t *input_A,
211 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000212{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200213 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000214 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000215 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100222
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 buflen = mbedtls_mpi_size(&X);
224 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200225 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000227
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
229 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000230
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
232 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000233 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000234
Paul Bakkerbd51b262014-07-10 15:26:12 +0200235exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100236 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000237}
Paul Bakker33b43f12013-08-20 11:48:36 +0200238/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000239
Janos Follathe344d0f2019-02-19 16:17:40 +0000240/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100241void mpi_write_binary_le(char *input_X, data_t *input_A,
242 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000243{
244 mbedtls_mpi X;
245 unsigned char buf[1000];
246 size_t buflen;
247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000253
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 buflen = mbedtls_mpi_size(&X);
255 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000256 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
260 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000261
Gilles Peskine449bd832023-01-11 14:50:10 +0100262 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
263 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000264 }
265
266exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100267 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000268}
269/* END_CASE */
270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100272void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000273{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000275 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000276 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000277 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000278 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000283
Gilles Peskine449bd832023-01-11 14:50:10 +0100284 file = fopen(input_file, "r");
285 TEST_ASSERT(file != NULL);
286 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000287 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000289
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 if (result == 0) {
291 TEST_ASSERT(sign_is_valid(&X));
292 buflen = mbedtls_mpi_size(&X);
293 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000294
Paul Bakkere896fea2009-07-06 06:40:23 +0000295
Gilles Peskine449bd832023-01-11 14:50:10 +0100296 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
297 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000298 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000299
Paul Bakkerbd51b262014-07-10 15:26:12 +0200300exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000302}
Paul Bakker33b43f12013-08-20 11:48:36 +0200303/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100306void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000307{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200308 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000309 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200310 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000315
Gilles Peskine449bd832023-01-11 14:50:10 +0100316 file_out = fopen(output_file, "w");
317 TEST_ASSERT(file_out != NULL);
318 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000319 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000321
Gilles Peskine449bd832023-01-11 14:50:10 +0100322 file_in = fopen(output_file, "r");
323 TEST_ASSERT(file_in != NULL);
324 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000325 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000327
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000329
Paul Bakkerbd51b262014-07-10 15:26:12 +0200330exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100331 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000332}
Paul Bakker33b43f12013-08-20 11:48:36 +0200333/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000334
Paul Bakker33b43f12013-08-20 11:48:36 +0200335/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100336void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000337{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100339 mbedtls_mpi_init(&X);
340 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
341 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000342
Paul Bakkerbd51b262014-07-10 15:26:12 +0200343exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000345}
Paul Bakker33b43f12013-08-20 11:48:36 +0200346/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000347
Paul Bakker33b43f12013-08-20 11:48:36 +0200348/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100349void mpi_set_bit(char *input_X, int pos, int val,
350 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000351{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000354
Gilles Peskine449bd832023-01-11 14:50:10 +0100355 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
356 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
357 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100358
Gilles Peskine449bd832023-01-11 14:50:10 +0100359 if (result == 0) {
360 TEST_ASSERT(sign_is_valid(&X));
361 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100362 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000363
Paul Bakkerbd51b262014-07-10 15:26:12 +0200364exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100365 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000366}
Paul Bakker33b43f12013-08-20 11:48:36 +0200367/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000368
Paul Bakker33b43f12013-08-20 11:48:36 +0200369/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100370void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000371{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000374
Gilles Peskine449bd832023-01-11 14:50:10 +0100375 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
376 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000377
Paul Bakkerbd51b262014-07-10 15:26:12 +0200378exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100379 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000380}
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000382
Paul Bakker33b43f12013-08-20 11:48:36 +0200383/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100384void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000385{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000388
Gilles Peskine449bd832023-01-11 14:50:10 +0100389 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
390 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000391
Paul Bakkerbd51b262014-07-10 15:26:12 +0200392exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000394}
Paul Bakker33b43f12013-08-20 11:48:36 +0200395/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000396
Paul Bakker33b43f12013-08-20 11:48:36 +0200397/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100398void mpi_gcd(char *input_X, char *input_Y,
399 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000400{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000403
Gilles Peskine449bd832023-01-11 14:50:10 +0100404 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
405 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
406 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
407 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
408 TEST_ASSERT(sign_is_valid(&Z));
409 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000410
Paul Bakkerbd51b262014-07-10 15:26:12 +0200411exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100412 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000413}
Paul Bakker33b43f12013-08-20 11:48:36 +0200414/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000415
Paul Bakker33b43f12013-08-20 11:48:36 +0200416/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100417void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000418{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000421
Gilles Peskine449bd832023-01-11 14:50:10 +0100422 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
423 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000424
Paul Bakkerbd51b262014-07-10 15:26:12 +0200425exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000427}
Paul Bakker33b43f12013-08-20 11:48:36 +0200428/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000429
Paul Bakker33b43f12013-08-20 11:48:36 +0200430/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100431void mpi_cmp_mpi(char *input_X, char *input_Y,
432 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000433{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000436
Gilles Peskine449bd832023-01-11 14:50:10 +0100437 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
438 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
439 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000440
Paul Bakkerbd51b262014-07-10 15:26:12 +0200441exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100442 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000443}
Paul Bakker33b43f12013-08-20 11:48:36 +0200444/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000445
Paul Bakker33b43f12013-08-20 11:48:36 +0200446/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100447void mpi_lt_mpi_ct(int size_X, char *input_X,
448 int size_Y, char *input_Y,
449 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100450{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200451 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100452 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100453 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100455
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);
Janos Follath385d5b82019-09-11 16:07:14 +0100458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
460 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100461
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
463 if (input_err == 0) {
Dave Rodgman14bec142023-05-11 16:19:27 +0100464 TEST_EQUAL(ret, input_uret);
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 }
Janos Follath385d5b82019-09-11 16:07:14 +0100466
467exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100469}
470/* END_CASE */
471
472/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100473void mpi_cmp_abs(char *input_X, char *input_Y,
474 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000475{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200476 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000478
Gilles Peskine449bd832023-01-11 14:50:10 +0100479 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
480 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
481 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000482
Paul Bakkerbd51b262014-07-10 15:26:12 +0200483exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100484 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000485}
Paul Bakker33b43f12013-08-20 11:48:36 +0200486/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000487
Paul Bakker33b43f12013-08-20 11:48:36 +0200488/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100489void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000490{
Gilles Peskined0722f82021-06-10 23:00:33 +0200491 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100492 mbedtls_mpi_init(&src);
493 mbedtls_mpi_init(&dst);
494 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000495
Gilles Peskine449bd832023-01-11 14:50:10 +0100496 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
497 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200498
499 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100500 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
501 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
502 TEST_ASSERT(sign_is_valid(&dst));
503 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000504
Gilles Peskined0722f82021-06-10 23:00:33 +0200505 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100506 mbedtls_mpi_free(&dst);
507 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
508 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
509 TEST_ASSERT(sign_is_valid(&dst));
510 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200511
512 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100513 mbedtls_mpi_free(&dst);
514 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
515 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
516 TEST_ASSERT(sign_is_valid(&dst));
517 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200518
Paul Bakkerbd51b262014-07-10 15:26:12 +0200519exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100520 mbedtls_mpi_free(&src);
521 mbedtls_mpi_free(&dst);
522 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100523}
524/* END_CASE */
525
526/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100527void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100528{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200529 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_mpi_init(&A);
531 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
534 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200535
Gilles Peskine449bd832023-01-11 14:50:10 +0100536 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
537 TEST_ASSERT(sign_is_valid(&X));
538 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000539
Paul Bakkerbd51b262014-07-10 15:26:12 +0200540exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100541 mbedtls_mpi_free(&A);
542 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000543}
Paul Bakker33b43f12013-08-20 11:48:36 +0200544/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000545
Paul Bakker33b43f12013-08-20 11:48:36 +0200546/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100547void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200548{
549 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
551 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200552
Gilles Peskine449bd832023-01-11 14:50:10 +0100553 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
554 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200555
Gilles Peskined0722f82021-06-10 23:00:33 +0200556 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100557 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
558 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
559 mbedtls_mpi_swap(&X, &Y);
560 TEST_ASSERT(sign_is_valid(&X));
561 TEST_ASSERT(sign_is_valid(&Y));
562 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
563 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200564
Gilles Peskined0722f82021-06-10 23:00:33 +0200565 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 mbedtls_mpi_free(&X);
567 mbedtls_mpi_free(&Y);
568 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
569 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
570 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
571 TEST_ASSERT(sign_is_valid(&X));
572 TEST_ASSERT(sign_is_valid(&Y));
573 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
574 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200575
576 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 mbedtls_mpi_free(&X);
578 mbedtls_mpi_free(&Y);
579 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
580 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
581 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
582 TEST_ASSERT(sign_is_valid(&X));
583 TEST_ASSERT(sign_is_valid(&Y));
584 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
585 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200586
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200587exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
589 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200590}
591/* END_CASE */
592
593/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100594void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200595{
596 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
600 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200601
Gilles Peskine449bd832023-01-11 14:50:10 +0100602 mbedtls_mpi_swap(&X, &X);
603 TEST_ASSERT(sign_is_valid(&X));
604 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200605
606exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100607 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200608}
609/* END_CASE */
610
611/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100612void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100613{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100616
Gilles Peskine449bd832023-01-11 14:50:10 +0100617 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
618 if (used > 0) {
619 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
620 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200621 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100622 TEST_EQUAL(X.n, (size_t) before);
623 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
624 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100625
Paul Bakkerbd51b262014-07-10 15:26:12 +0200626exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100628}
629/* END_CASE */
630
631/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100632void mpi_add_mpi(char *input_X, char *input_Y,
633 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000634{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000637
Gilles Peskine449bd832023-01-11 14:50:10 +0100638 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
639 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
640 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
641 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
642 TEST_ASSERT(sign_is_valid(&Z));
643 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000644
Gilles Peskine56f943a2020-07-23 01:18:11 +0200645 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
647 TEST_ASSERT(sign_is_valid(&X));
648 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
649 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200650
651 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100652 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
653 TEST_ASSERT(sign_is_valid(&Y));
654 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200655
Paul Bakkerbd51b262014-07-10 15:26:12 +0200656exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100657 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000658}
Paul Bakker33b43f12013-08-20 11:48:36 +0200659/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000660
Paul Bakker33b43f12013-08-20 11:48:36 +0200661/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100662void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100663{
664 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100668
Gilles Peskine449bd832023-01-11 14:50:10 +0100669 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
670 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
671 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
672 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100673
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
675 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
676 TEST_ASSERT(sign_is_valid(&X));
677 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100678
Gilles Peskine449bd832023-01-11 14:50:10 +0100679 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
680 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
681 TEST_ASSERT(sign_is_valid(&X));
682 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100683
684exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100685 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100686}
687/* END_CASE */
688
689
690/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100691void mpi_add_abs(char *input_X, char *input_Y,
692 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000693{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000696
Gilles Peskine449bd832023-01-11 14:50:10 +0100697 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
698 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
699 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
700 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
701 TEST_ASSERT(sign_is_valid(&Z));
702 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000703
Gilles Peskine56f943a2020-07-23 01:18:11 +0200704 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
706 TEST_ASSERT(sign_is_valid(&X));
707 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
708 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200709
710 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100711 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
712 TEST_ASSERT(sign_is_valid(&Y));
713 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000714
Paul Bakkerbd51b262014-07-10 15:26:12 +0200715exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000717}
Paul Bakker33b43f12013-08-20 11:48:36 +0200718/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000719
Paul Bakker33b43f12013-08-20 11:48:36 +0200720/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100721void mpi_add_int(char *input_X, int input_Y,
722 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000723{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000726
Gilles Peskine449bd832023-01-11 14:50:10 +0100727 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
728 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
729 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
730 TEST_ASSERT(sign_is_valid(&Z));
731 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000732
Paul Bakkerbd51b262014-07-10 15:26:12 +0200733exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000735}
Paul Bakker33b43f12013-08-20 11:48:36 +0200736/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000737
Paul Bakker33b43f12013-08-20 11:48:36 +0200738/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100739void mpi_sub_mpi(char *input_X, char *input_Y,
740 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000741{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000744
Gilles Peskine449bd832023-01-11 14:50:10 +0100745 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
746 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
747 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
748 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
749 TEST_ASSERT(sign_is_valid(&Z));
750 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000751
Gilles Peskine56f943a2020-07-23 01:18:11 +0200752 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
754 TEST_ASSERT(sign_is_valid(&X));
755 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
756 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200757
758 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100759 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
760 TEST_ASSERT(sign_is_valid(&Y));
761 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200762
Paul Bakkerbd51b262014-07-10 15:26:12 +0200763exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100764 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000765}
Paul Bakker33b43f12013-08-20 11:48:36 +0200766/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000767
Paul Bakker33b43f12013-08-20 11:48:36 +0200768/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100769void mpi_sub_abs(char *input_X, char *input_Y,
770 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000771{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200772 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000773 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000775
Gilles Peskine449bd832023-01-11 14:50:10 +0100776 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
777 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
778 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100779
Gilles Peskine449bd832023-01-11 14:50:10 +0100780 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
781 TEST_ASSERT(res == sub_result);
782 TEST_ASSERT(sign_is_valid(&Z));
783 if (res == 0) {
784 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
785 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000786
Gilles Peskine56f943a2020-07-23 01:18:11 +0200787 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100788 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
789 TEST_ASSERT(sign_is_valid(&X));
790 if (sub_result == 0) {
791 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
792 }
793 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200794
795 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100796 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
797 TEST_ASSERT(sign_is_valid(&Y));
798 if (sub_result == 0) {
799 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
800 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200801
Paul Bakkerbd51b262014-07-10 15:26:12 +0200802exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000804}
Paul Bakker33b43f12013-08-20 11:48:36 +0200805/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000806
Paul Bakker33b43f12013-08-20 11:48:36 +0200807/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100808void mpi_sub_int(char *input_X, int input_Y,
809 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000810{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000813
Gilles Peskine449bd832023-01-11 14:50:10 +0100814 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
815 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
816 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
817 TEST_ASSERT(sign_is_valid(&Z));
818 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000819
Paul Bakkerbd51b262014-07-10 15:26:12 +0200820exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000822}
Paul Bakker33b43f12013-08-20 11:48:36 +0200823/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000824
Paul Bakker33b43f12013-08-20 11:48:36 +0200825/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100826void mpi_mul_mpi(char *input_X, char *input_Y,
827 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000828{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000831
Gilles Peskine449bd832023-01-11 14:50:10 +0100832 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
833 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
834 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
835 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
836 TEST_ASSERT(sign_is_valid(&Z));
837 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000838
Paul Bakkerbd51b262014-07-10 15:26:12 +0200839exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000841}
Paul Bakker33b43f12013-08-20 11:48:36 +0200842/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000843
Paul Bakker33b43f12013-08-20 11:48:36 +0200844/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100845void mpi_mul_int(char *input_X, int input_Y,
846 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000847{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000850
Gilles Peskine449bd832023-01-11 14:50:10 +0100851 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
852 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
853 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
854 TEST_ASSERT(sign_is_valid(&Z));
855 if (strcmp(result_comparison, "==") == 0) {
856 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
857 } else if (strcmp(result_comparison, "!=") == 0) {
858 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
859 } else {
Agathiyan Bragadeesh763b3532023-07-27 13:52:31 +0100860 TEST_FAIL("unknown operator");
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000862
Paul Bakkerbd51b262014-07-10 15:26:12 +0200863exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000865}
Paul Bakker33b43f12013-08-20 11:48:36 +0200866/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000867
Paul Bakker33b43f12013-08-20 11:48:36 +0200868/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100869void mpi_div_mpi(char *input_X, char *input_Y,
870 char *input_A, char *input_B,
871 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000872{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000874 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
876 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000877
Gilles Peskine449bd832023-01-11 14:50:10 +0100878 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
879 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
880 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
881 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
882 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
883 TEST_ASSERT(res == div_result);
884 if (res == 0) {
885 TEST_ASSERT(sign_is_valid(&Q));
886 TEST_ASSERT(sign_is_valid(&R));
887 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
888 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000889 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000890
Paul Bakkerbd51b262014-07-10 15:26:12 +0200891exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100892 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
893 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000894}
Paul Bakker33b43f12013-08-20 11:48:36 +0200895/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000896
Paul Bakker33b43f12013-08-20 11:48:36 +0200897/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100898void mpi_div_int(char *input_X, int input_Y,
899 char *input_A, char *input_B,
900 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000901{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000903 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
905 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000906
Gilles Peskine449bd832023-01-11 14:50:10 +0100907 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
908 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
909 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
910 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
911 TEST_ASSERT(res == div_result);
912 if (res == 0) {
913 TEST_ASSERT(sign_is_valid(&Q));
914 TEST_ASSERT(sign_is_valid(&R));
915 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
916 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000917 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000918
Paul Bakkerbd51b262014-07-10 15:26:12 +0200919exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
921 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000922}
Paul Bakker33b43f12013-08-20 11:48:36 +0200923/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000924
Paul Bakker33b43f12013-08-20 11:48:36 +0200925/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100926void mpi_mod_mpi(char *input_X, char *input_Y,
927 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100928{
929 mbedtls_mpi X, Y, A;
930 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100932
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
934 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
935 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
936 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
937 TEST_ASSERT(res == div_result);
938 if (res == 0) {
939 TEST_ASSERT(sign_is_valid(&X));
940 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100941 }
942
943exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100944 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100945}
946/* END_CASE */
947
948/* BEGIN_CASE */
Gilles Peskine7768a8e2022-12-04 15:58:48 +0100949void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
950 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100951{
952 mbedtls_mpi X;
953 int res;
954 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000959
Gilles Peskine449bd832023-01-11 14:50:10 +0100960 res = mbedtls_mpi_mod_int(&r, &X, y);
961 TEST_EQUAL(res, mod_result);
962 if (res == 0) {
963 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100964 }
965
966exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100967 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100968}
969/* END_CASE */
970
971/* BEGIN_CASE */
Janos Follath0512d172024-02-20 14:30:46 +0000972void mpi_exp_mod_min_RR(char *input_A, char *input_E,
Janos Follath09025722024-02-21 11:50:25 +0000973 char *input_N, char *input_X,
974 int exp_result)
Janos Follath0512d172024-02-20 14:30:46 +0000975{
976 mbedtls_mpi A, E, N, RR, Z, X;
977 int res;
978 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
979 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
980
Janos Follathfdab7862024-02-22 15:19:13 +0000981 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
982 TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
983 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
984 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000985
Janos Follathfdab7862024-02-22 15:19:13 +0000986 TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
987 TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
Gilles Peskine673461c2024-02-21 16:03:04 +0100988 /* The objective of this test is to check that exp_mod defends
989 * against a smaller RR. */
990 TEST_LE_U(RR.n, N.n - 1);
Janos Follath0512d172024-02-20 14:30:46 +0000991
992 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Gilles Peskine673461c2024-02-21 16:03:04 +0100993 /* We know that exp_mod internally needs RR to be as large as N.
994 * Validate that it is the case now, otherwise there was probably
995 * a buffer overread. */
996 TEST_EQUAL(RR.n, N.n);
997
Janos Follathfdab7862024-02-22 15:19:13 +0000998 TEST_EQUAL(res, exp_result);
Janos Follath0512d172024-02-20 14:30:46 +0000999 if (res == 0) {
Janos Follathfdab7862024-02-22 15:19:13 +00001000 TEST_EQUAL(sign_is_valid(&Z), 1);
1001 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
Janos Follath0512d172024-02-20 14:30:46 +00001002 }
1003
1004exit:
1005 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1006 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
1007}
1008/* END_CASE */
1009
1010/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001011void mpi_exp_mod(char *input_A, char *input_E,
1012 char *input_N, char *input_X,
1013 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001014{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001016 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1018 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001019
Gilles Peskine449bd832023-01-11 14:50:10 +01001020 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1021 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1022 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1023 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001024
Gilles Peskine449bd832023-01-11 14:50:10 +01001025 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
1026 TEST_ASSERT(res == exp_result);
1027 if (res == 0) {
1028 TEST_ASSERT(sign_is_valid(&Z));
1029 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001030 }
1031
1032 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001033 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1034 TEST_ASSERT(res == exp_result);
1035 if (res == 0) {
1036 TEST_ASSERT(sign_is_valid(&Z));
1037 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001038 }
1039
1040 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001041 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1042 TEST_ASSERT(res == exp_result);
1043 if (res == 0) {
1044 TEST_ASSERT(sign_is_valid(&Z));
1045 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001046 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001047
Paul Bakkerbd51b262014-07-10 15:26:12 +02001048exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001049 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1050 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001051}
Paul Bakker33b43f12013-08-20 11:48:36 +02001052/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001053
Paul Bakker33b43f12013-08-20 11:48:36 +02001054/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001055void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1056 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001057{
1058 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001059 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1060 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001061
Chris Jonesaa850cd2020-12-03 11:35:41 +00001062 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001063 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1064 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1065 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001066
1067 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1069 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1070 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001071
1072 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1074 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1075 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001076
Gilles Peskine449bd832023-01-11 14:50:10 +01001077 if (strlen(input_RR)) {
1078 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1079 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001080
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001082
1083exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1085 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001086}
1087/* END_CASE */
1088
1089/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001090void mpi_inv_mod(char *input_X, char *input_Y,
1091 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001092{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001094 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001096
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1098 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1099 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1100 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1101 TEST_ASSERT(res == div_result);
1102 if (res == 0) {
1103 TEST_ASSERT(sign_is_valid(&Z));
1104 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001105 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001106
Paul Bakkerbd51b262014-07-10 15:26:12 +02001107exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001109}
Paul Bakker33b43f12013-08-20 11:48:36 +02001110/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001113void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001114{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001116 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001118
Gilles Peskine449bd832023-01-11 14:50:10 +01001119 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1120 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1121 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001122
Paul Bakkerbd51b262014-07-10 15:26:12 +02001123exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001125}
Paul Bakker33b43f12013-08-20 11:48:36 +02001126/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001129void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1130 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001131{
1132 mbedtls_mpi X;
1133 int res;
1134 mbedtls_test_mpi_random rand;
1135
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001137 rand.data = witnesses;
1138 rand.pos = 0;
1139 rand.chunk_len = chunk_len;
1140
Gilles Peskine449bd832023-01-11 14:50:10 +01001141 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1142 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1143 mbedtls_test_mpi_miller_rabin_determinizer,
1144 &rand);
1145 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001146
1147 rand.data = witnesses;
1148 rand.pos = 0;
1149 rand.chunk_len = chunk_len;
1150
Gilles Peskine449bd832023-01-11 14:50:10 +01001151 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1152 mbedtls_test_mpi_miller_rabin_determinizer,
1153 &rand);
1154 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001155
1156exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001158}
1159/* END_CASE */
1160
1161/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001162void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001163{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001165 int my_ret;
1166
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1170 mbedtls_test_rnd_std_rand, NULL);
1171 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 if (ref_ret == 0) {
1174 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 TEST_ASSERT(actual_bits >= (size_t) bits);
1177 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1178 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001179
Gilles Peskine449bd832023-01-11 14:50:10 +01001180 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1181 mbedtls_test_rnd_std_rand,
1182 NULL) == 0);
1183 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001184 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001185 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1186 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1187 mbedtls_test_rnd_std_rand,
1188 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001189 }
1190 }
1191
Paul Bakkerbd51b262014-07-10 15:26:12 +02001192exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001194}
1195/* END_CASE */
1196
Paul Bakker33b43f12013-08-20 11:48:36 +02001197/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001198void mpi_shift_l(char *input_X, int shift_X,
1199 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001200{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001201 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001203
Gilles Peskine449bd832023-01-11 14:50:10 +01001204 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1205 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1206 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1207 TEST_ASSERT(sign_is_valid(&X));
1208 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001209
Paul Bakkerbd51b262014-07-10 15:26:12 +02001210exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001212}
Paul Bakker33b43f12013-08-20 11:48:36 +02001213/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001214
Paul Bakker33b43f12013-08-20 11:48:36 +02001215/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001216void mpi_shift_r(char *input_X, int shift_X,
1217 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001218{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001221
Gilles Peskine449bd832023-01-11 14:50:10 +01001222 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1223 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1224 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1225 TEST_ASSERT(sign_is_valid(&X));
1226 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001227
Paul Bakkerbd51b262014-07-10 15:26:12 +02001228exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001230}
Paul Bakker33b43f12013-08-20 11:48:36 +02001231/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001232
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001233/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001234void mpi_fill_random(int wanted_bytes, int rng_bytes,
1235 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001236{
1237 mbedtls_mpi X;
1238 int ret;
1239 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001241
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001243 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1245 if (before < 0) {
1246 before = -before;
1247 }
1248 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001249 }
1250
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1252 f_rng_bytes_left, &bytes_left);
1253 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001254
Gilles Peskine449bd832023-01-11 14:50:10 +01001255 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001256 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1257 * as a big-endian representation of the number. We know when
1258 * our RNG function returns null bytes, so we know how many
1259 * leading zero bytes the number has. */
1260 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001262 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 }
1264 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1265 (size_t) wanted_bytes);
1266 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1267 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001268 }
1269
1270exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001271 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001272}
1273/* END_CASE */
1274
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001275/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001276void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001277{
1278 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1279 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1280 * is a valid value. However, negating it (`-n`) has undefined behavior
1281 * (although in practice `-n` evaluates to the value n).
1282 *
1283 * This function has ad hoc tests for this value. It's separated from other
1284 * functions because the test framework makes it hard to pass this value
1285 * into test cases.
1286 *
1287 * In the comments here:
1288 * - biL = number of bits in limbs
1289 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1290 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1291 */
1292
1293 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 mbedtls_mpi_init(&A);
1295 mbedtls_mpi_init(&R);
1296 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001297
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001299 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001300 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1301 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1302 (mbedtls_mpi_uint) 1 << (biL - 1));
1303 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001304
1305 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001306 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1307 TEST_EQUAL(A.s, -1);
1308 TEST_EQUAL(A.n, 1);
1309 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001310
1311 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001313
1314 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1315 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001316 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001317
1318 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1319 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001321
1322 /* Test mbedtls_mpi_add_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_add_int(&X, &A, most_negative), 0);
1325 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001326
1327 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001328 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1329 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1330 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001331
1332 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001333 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1334 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1335 TEST_EQUAL(X.s, -1);
1336 TEST_EQUAL(X.n, 2);
1337 TEST_EQUAL(X.p[0], 0);
1338 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001339
1340 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001341 mbedtls_mpi_free(&X);
1342 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1343 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1344 TEST_EQUAL(X.s, 1);
1345 TEST_EQUAL(X.n, 1);
1346 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001347
1348 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001349 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1350 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1351 TEST_EQUAL(X.s, 1);
1352 TEST_EQUAL(X.n, 1);
1353 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001354
1355 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1357 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1358 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001359
1360 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001361 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1362 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1363 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1364 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001365
1366 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001367 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1368 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1369 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1370 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001371
1372 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1374 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1375 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1376 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001377
1378 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001379 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1380 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1381 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1382 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001383
1384 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1386 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1387 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1388 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001389
1390 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001391 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1392 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1393 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1394 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001395
1396 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001397 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1398 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1399 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1400 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001401
1402 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001403 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1404 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001405
1406 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1408 mbedtls_test_rnd_std_rand, NULL),
1409 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001410
1411exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001412 mbedtls_mpi_free(&A);
1413 mbedtls_mpi_free(&R);
1414 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001415}
1416/* END_CASE */
1417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001419void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001420{
Gilles Peskine449bd832023-01-11 14:50:10 +01001421 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001422}
Paul Bakker33b43f12013-08-20 11:48:36 +02001423/* END_CASE */