blob: afa97a45051c957f56ce6c8a66cde5994808f8ed [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
Gilles Peskine449bd832023-01-11 14:50:10 +010036typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010037 data_t *data;
38 size_t pos;
39 size_t chunk_len;
40} mbedtls_test_mpi_random;
41
42/*
43 * This function is called by the Miller-Rabin primality test each time it
44 * chooses a random witness. The witnesses (or non-witnesses as provided by the
45 * test) are stored in the data member of the state structure. Each number is in
46 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
47 */
Gilles Peskine449bd832023-01-11 14:50:10 +010048int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
49 unsigned char *buf,
50 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010051{
Gilles Peskine449bd832023-01-11 14:50:10 +010052 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010053
Gilles Peskine449bd832023-01-11 14:50:10 +010054 if (random == NULL || random->data->x == NULL || buf == NULL) {
55 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010056 }
57
Gilles Peskine449bd832023-01-11 14:50:10 +010058 if (random->pos + random->chunk_len > random->data->len
59 || random->chunk_len > len) {
60 return -1;
61 }
62
63 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010064
65 /* The witness is written to the end of the buffer, since the buffer is
66 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
67 * Writing the witness to the start of the buffer would result in the
68 * buffer being 'witness 000...000', which would be treated as
69 * witness * 2^n for some n. */
Gilles Peskine449bd832023-01-11 14:50:10 +010070 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
71 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010072
73 random->pos += random->chunk_len;
74
Gilles Peskine449bd832023-01-11 14:50:10 +010075 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010076}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010077
78/* Random generator that is told how many bytes to return. */
Gilles Peskine449bd832023-01-11 14:50:10 +010079static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010080{
81 size_t *bytes_left = state;
82 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010083 for (i = 0; i < len; i++) {
84 if (*bytes_left == 0) {
85 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
86 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010087 buf[i] = *bytes_left & 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010088 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010089 }
Gilles Peskine449bd832023-01-11 14:50:10 +010090 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010091}
92
Paul Bakker33b43f12013-08-20 11:48:36 +020093/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000094
Paul Bakker33b43f12013-08-20 11:48:36 +020095/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020097 * END_DEPENDENCIES
98 */
Paul Bakker5690efc2011-05-26 13:16:06 +000099
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000100/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100101void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200102{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200103 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200104
Gilles Peskine449bd832023-01-11 14:50:10 +0100105 mbedtls_mpi_init(&X);
106 mbedtls_mpi_init(&Y);
107 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200108
Gilles Peskine449bd832023-01-11 14:50:10 +0100109 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
110 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
111 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
112 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200113
114exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100115 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200116}
117/* END_CASE */
118
119/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100120void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
121 char *input_A, int output_size, int result_read,
122 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000123{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000125 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100126 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000127
Gilles Peskine449bd832023-01-11 14:50:10 +0100128 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000129
Gilles Peskine449bd832023-01-11 14:50:10 +0100130 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000131
Gilles Peskine449bd832023-01-11 14:50:10 +0100132 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
133 if (result_read == 0) {
134 TEST_ASSERT(sign_is_valid(&X));
135 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
136 if (result_write == 0) {
Gilles Peskine017f0b72022-12-04 13:29:20 +0100137 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine449bd832023-01-11 14:50:10 +0100138 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000139 }
140 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000141
Paul Bakkerbd51b262014-07-10 15:26:12 +0200142exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100143 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000144}
Paul Bakker33b43f12013-08-20 11:48:36 +0200145/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000146
Paul Bakker33b43f12013-08-20 11:48:36 +0200147/* BEGIN_CASE */
Valerio Settif988f952024-01-30 14:40:31 +0100148void mpi_zero_length_buffer_is_null()
149{
150 mbedtls_mpi X;
151 size_t olen;
152
153 mbedtls_mpi_init(&X);
154
155 /* Simply test that the following functions do not crash when a NULL buffer
156 * pointer and 0 length is passed. We don't care much about the return value. */
157 TEST_EQUAL(mbedtls_mpi_read_binary(&X, NULL, 0), 0);
158 TEST_EQUAL(mbedtls_mpi_read_binary_le(&X, NULL, 0), 0);
159 TEST_EQUAL(mbedtls_mpi_write_string(&X, 16, NULL, 0, &olen), MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
160 TEST_EQUAL(mbedtls_mpi_write_binary(&X, NULL, 0), 0);
161
162exit:
163 mbedtls_mpi_free(&X);
164}
165/* END_CASE */
166
167/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100168void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000169{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200170 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000171 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100172 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000173
Gilles Peskine449bd832023-01-11 14:50:10 +0100174 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000175
Paul Bakkere896fea2009-07-06 06:40:23 +0000176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
178 TEST_ASSERT(sign_is_valid(&X));
179 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
180 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000181
Paul Bakkerbd51b262014-07-10 15:26:12 +0200182exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100183 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000184}
Paul Bakker33b43f12013-08-20 11:48:36 +0200185/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000186
Paul Bakker33b43f12013-08-20 11:48:36 +0200187/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100188void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000189{
190 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000191 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000192 size_t len;
193
Gilles Peskine449bd832023-01-11 14:50:10 +0100194 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000195
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
198 TEST_ASSERT(sign_is_valid(&X));
199 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
200 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000201
202exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100203 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000204}
205/* END_CASE */
206
207/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100208void mpi_write_binary(char *input_X, data_t *input_A,
209 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000210{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200211 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000212 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000213 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000214
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000216
Gilles Peskine449bd832023-01-11 14:50:10 +0100217 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000218
Gilles Peskine449bd832023-01-11 14:50:10 +0100219 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100220
Gilles Peskine449bd832023-01-11 14:50:10 +0100221 buflen = mbedtls_mpi_size(&X);
222 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200223 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000225
Gilles Peskine449bd832023-01-11 14:50:10 +0100226 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
227 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
230 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000231 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000232
Paul Bakkerbd51b262014-07-10 15:26:12 +0200233exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100234 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000235}
Paul Bakker33b43f12013-08-20 11:48:36 +0200236/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000237
Janos Follathe344d0f2019-02-19 16:17:40 +0000238/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100239void mpi_write_binary_le(char *input_X, data_t *input_A,
240 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000241{
242 mbedtls_mpi X;
243 unsigned char buf[1000];
244 size_t buflen;
245
Gilles Peskine449bd832023-01-11 14:50:10 +0100246 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000247
Gilles Peskine449bd832023-01-11 14:50:10 +0100248 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000249
Gilles Peskine449bd832023-01-11 14:50:10 +0100250 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000251
Gilles Peskine449bd832023-01-11 14:50:10 +0100252 buflen = mbedtls_mpi_size(&X);
253 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000254 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000256
Gilles Peskine449bd832023-01-11 14:50:10 +0100257 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
258 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
261 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000262 }
263
264exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100265 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000266}
267/* END_CASE */
268
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200269/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100270void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000271{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000273 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000274 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000275 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000276 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000277
Gilles Peskine449bd832023-01-11 14:50:10 +0100278 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000279
Gilles Peskine449bd832023-01-11 14:50:10 +0100280 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000281
Gilles Peskine449bd832023-01-11 14:50:10 +0100282 file = fopen(input_file, "r");
283 TEST_ASSERT(file != NULL);
284 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000285 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100286 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000287
Gilles Peskine449bd832023-01-11 14:50:10 +0100288 if (result == 0) {
289 TEST_ASSERT(sign_is_valid(&X));
290 buflen = mbedtls_mpi_size(&X);
291 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000292
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Gilles Peskine449bd832023-01-11 14:50:10 +0100294 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
295 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000296 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000297
Paul Bakkerbd51b262014-07-10 15:26:12 +0200298exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100299 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000300}
Paul Bakker33b43f12013-08-20 11:48:36 +0200301/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100304void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000305{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000307 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200308 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000309
Gilles Peskine449bd832023-01-11 14:50:10 +0100310 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000311
Gilles Peskine449bd832023-01-11 14:50:10 +0100312 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000313
Gilles Peskine449bd832023-01-11 14:50:10 +0100314 file_out = fopen(output_file, "w");
315 TEST_ASSERT(file_out != NULL);
316 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000317 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100318 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000319
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 file_in = fopen(output_file, "r");
321 TEST_ASSERT(file_in != NULL);
322 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000323 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100324 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000325
Gilles Peskine449bd832023-01-11 14:50:10 +0100326 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000327
Paul Bakkerbd51b262014-07-10 15:26:12 +0200328exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000330}
Paul Bakker33b43f12013-08-20 11:48:36 +0200331/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000332
Paul Bakker33b43f12013-08-20 11:48:36 +0200333/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100334void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000335{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100337 mbedtls_mpi_init(&X);
338 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
339 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
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);
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_set_bit(char *input_X, int pos, int val,
348 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000349{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100351 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000352
Gilles Peskine449bd832023-01-11 14:50:10 +0100353 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
354 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
355 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100356
Gilles Peskine449bd832023-01-11 14:50:10 +0100357 if (result == 0) {
358 TEST_ASSERT(sign_is_valid(&X));
359 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100360 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000361
Paul Bakkerbd51b262014-07-10 15:26:12 +0200362exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100363 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000364}
Paul Bakker33b43f12013-08-20 11:48:36 +0200365/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000366
Paul Bakker33b43f12013-08-20 11:48:36 +0200367/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100368void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000369{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100371 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000372
Gilles Peskine449bd832023-01-11 14:50:10 +0100373 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
374 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000375
Paul Bakkerbd51b262014-07-10 15:26:12 +0200376exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100377 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000378}
Paul Bakker33b43f12013-08-20 11:48:36 +0200379/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000380
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100382void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000383{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100385 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000386
Gilles Peskine449bd832023-01-11 14:50:10 +0100387 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
388 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000389
Paul Bakkerbd51b262014-07-10 15:26:12 +0200390exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000392}
Paul Bakker33b43f12013-08-20 11:48:36 +0200393/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000394
Paul Bakker33b43f12013-08-20 11:48:36 +0200395/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100396void mpi_gcd(char *input_X, char *input_Y,
397 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000398{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200399 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100400 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000401
Gilles Peskine449bd832023-01-11 14:50:10 +0100402 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
403 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
404 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
405 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
406 TEST_ASSERT(sign_is_valid(&Z));
407 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000408
Paul Bakkerbd51b262014-07-10 15:26:12 +0200409exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100410 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000411}
Paul Bakker33b43f12013-08-20 11:48:36 +0200412/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000413
Paul Bakker33b43f12013-08-20 11:48:36 +0200414/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100415void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000416{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100418 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000419
Gilles Peskine449bd832023-01-11 14:50:10 +0100420 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
421 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000422
Paul Bakkerbd51b262014-07-10 15:26:12 +0200423exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000425}
Paul Bakker33b43f12013-08-20 11:48:36 +0200426/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000427
Paul Bakker33b43f12013-08-20 11:48:36 +0200428/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100429void mpi_cmp_mpi(char *input_X, char *input_Y,
430 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000431{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100433 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000434
Gilles Peskine449bd832023-01-11 14:50:10 +0100435 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
436 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
437 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000438
Paul Bakkerbd51b262014-07-10 15:26:12 +0200439exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100440 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000441}
Paul Bakker33b43f12013-08-20 11:48:36 +0200442/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000443
Paul Bakker33b43f12013-08-20 11:48:36 +0200444/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100445void mpi_lt_mpi_ct(int size_X, char *input_X,
446 int size_Y, char *input_Y,
447 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100448{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200449 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100450 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100451 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100452 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100453
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
455 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
458 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
461 if (input_err == 0) {
Dave Rodgman14bec142023-05-11 16:19:27 +0100462 TEST_EQUAL(ret, input_uret);
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 }
Janos Follath385d5b82019-09-11 16:07:14 +0100464
465exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100467}
468/* END_CASE */
469
470/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100471void mpi_cmp_abs(char *input_X, char *input_Y,
472 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000473{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100475 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000476
Gilles Peskine449bd832023-01-11 14:50:10 +0100477 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
478 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
479 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000480
Paul Bakkerbd51b262014-07-10 15:26:12 +0200481exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100482 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000483}
Paul Bakker33b43f12013-08-20 11:48:36 +0200484/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000485
Paul Bakker33b43f12013-08-20 11:48:36 +0200486/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100487void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000488{
Gilles Peskined0722f82021-06-10 23:00:33 +0200489 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100490 mbedtls_mpi_init(&src);
491 mbedtls_mpi_init(&dst);
492 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000493
Gilles Peskine449bd832023-01-11 14:50:10 +0100494 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
495 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200496
497 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100498 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
499 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
500 TEST_ASSERT(sign_is_valid(&dst));
501 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000502
Gilles Peskined0722f82021-06-10 23:00:33 +0200503 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100504 mbedtls_mpi_free(&dst);
505 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
506 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
507 TEST_ASSERT(sign_is_valid(&dst));
508 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200509
510 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100511 mbedtls_mpi_free(&dst);
512 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
513 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
514 TEST_ASSERT(sign_is_valid(&dst));
515 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200516
Paul Bakkerbd51b262014-07-10 15:26:12 +0200517exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100518 mbedtls_mpi_free(&src);
519 mbedtls_mpi_free(&dst);
520 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100521}
522/* END_CASE */
523
524/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100525void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100526{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200527 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100528 mbedtls_mpi_init(&A);
529 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000530
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
532 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
535 TEST_ASSERT(sign_is_valid(&X));
536 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000537
Paul Bakkerbd51b262014-07-10 15:26:12 +0200538exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 mbedtls_mpi_free(&A);
540 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000541}
Paul Bakker33b43f12013-08-20 11:48:36 +0200542/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000543
Paul Bakker33b43f12013-08-20 11:48:36 +0200544/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100545void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200546{
547 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100548 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
549 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200550
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
552 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200553
Gilles Peskined0722f82021-06-10 23:00:33 +0200554 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
556 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
557 mbedtls_mpi_swap(&X, &Y);
558 TEST_ASSERT(sign_is_valid(&X));
559 TEST_ASSERT(sign_is_valid(&Y));
560 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
561 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200562
Gilles Peskined0722f82021-06-10 23:00:33 +0200563 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100564 mbedtls_mpi_free(&X);
565 mbedtls_mpi_free(&Y);
566 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
567 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
568 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
569 TEST_ASSERT(sign_is_valid(&X));
570 TEST_ASSERT(sign_is_valid(&Y));
571 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
572 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200573
574 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100575 mbedtls_mpi_free(&X);
576 mbedtls_mpi_free(&Y);
577 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
578 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
579 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
580 TEST_ASSERT(sign_is_valid(&X));
581 TEST_ASSERT(sign_is_valid(&Y));
582 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
583 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200584
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200585exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
587 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200588}
589/* END_CASE */
590
591/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100592void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200593{
594 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100595 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200596
Gilles Peskine449bd832023-01-11 14:50:10 +0100597 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
598 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 mbedtls_mpi_swap(&X, &X);
601 TEST_ASSERT(sign_is_valid(&X));
602 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200603
604exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100605 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200606}
607/* END_CASE */
608
609/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100610void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100611{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200612 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100613 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100614
Gilles Peskine449bd832023-01-11 14:50:10 +0100615 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
616 if (used > 0) {
617 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
618 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200619 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100620 TEST_EQUAL(X.n, (size_t) before);
621 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
622 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100623
Paul Bakkerbd51b262014-07-10 15:26:12 +0200624exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100626}
627/* END_CASE */
628
629/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100630void mpi_add_mpi(char *input_X, char *input_Y,
631 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000632{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100634 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000635
Gilles Peskine449bd832023-01-11 14:50:10 +0100636 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
637 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
638 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
639 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
640 TEST_ASSERT(sign_is_valid(&Z));
641 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000642
Gilles Peskine56f943a2020-07-23 01:18:11 +0200643 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100644 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
645 TEST_ASSERT(sign_is_valid(&X));
646 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
647 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200648
649 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100650 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
651 TEST_ASSERT(sign_is_valid(&Y));
652 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200653
Paul Bakkerbd51b262014-07-10 15:26:12 +0200654exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100655 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000656}
Paul Bakker33b43f12013-08-20 11:48:36 +0200657/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000658
Paul Bakker33b43f12013-08-20 11:48:36 +0200659/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100660void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100661{
662 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100664
Gilles Peskine449bd832023-01-11 14:50:10 +0100665 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100666
Gilles Peskine449bd832023-01-11 14:50:10 +0100667 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
668 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
669 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
670 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100671
Gilles Peskine449bd832023-01-11 14:50:10 +0100672 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
673 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
674 TEST_ASSERT(sign_is_valid(&X));
675 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100676
Gilles Peskine449bd832023-01-11 14:50:10 +0100677 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
678 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
679 TEST_ASSERT(sign_is_valid(&X));
680 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100681
682exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100683 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100684}
685/* END_CASE */
686
687
688/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100689void mpi_add_abs(char *input_X, char *input_Y,
690 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000691{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100693 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000694
Gilles Peskine449bd832023-01-11 14:50:10 +0100695 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
696 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
697 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
698 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
699 TEST_ASSERT(sign_is_valid(&Z));
700 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000701
Gilles Peskine56f943a2020-07-23 01:18:11 +0200702 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100703 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
704 TEST_ASSERT(sign_is_valid(&X));
705 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
706 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200707
708 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100709 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
710 TEST_ASSERT(sign_is_valid(&Y));
711 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000712
Paul Bakkerbd51b262014-07-10 15:26:12 +0200713exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000715}
Paul Bakker33b43f12013-08-20 11:48:36 +0200716/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000717
Paul Bakker33b43f12013-08-20 11:48:36 +0200718/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100719void mpi_add_int(char *input_X, int input_Y,
720 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000721{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000724
Gilles Peskine449bd832023-01-11 14:50:10 +0100725 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
726 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
727 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
728 TEST_ASSERT(sign_is_valid(&Z));
729 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000730
Paul Bakkerbd51b262014-07-10 15:26:12 +0200731exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000733}
Paul Bakker33b43f12013-08-20 11:48:36 +0200734/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000735
Paul Bakker33b43f12013-08-20 11:48:36 +0200736/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100737void mpi_sub_mpi(char *input_X, char *input_Y,
738 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000739{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100741 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000742
Gilles Peskine449bd832023-01-11 14:50:10 +0100743 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
744 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
745 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
746 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
747 TEST_ASSERT(sign_is_valid(&Z));
748 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000749
Gilles Peskine56f943a2020-07-23 01:18:11 +0200750 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100751 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
752 TEST_ASSERT(sign_is_valid(&X));
753 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
754 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200755
756 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100757 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
758 TEST_ASSERT(sign_is_valid(&Y));
759 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200760
Paul Bakkerbd51b262014-07-10 15:26:12 +0200761exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100762 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000763}
Paul Bakker33b43f12013-08-20 11:48:36 +0200764/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000765
Paul Bakker33b43f12013-08-20 11:48:36 +0200766/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100767void mpi_sub_abs(char *input_X, char *input_Y,
768 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000769{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200770 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000771 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100772 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000773
Gilles Peskine449bd832023-01-11 14:50:10 +0100774 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
775 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
776 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100777
Gilles Peskine449bd832023-01-11 14:50:10 +0100778 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
779 TEST_ASSERT(res == sub_result);
780 TEST_ASSERT(sign_is_valid(&Z));
781 if (res == 0) {
782 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
783 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000784
Gilles Peskine56f943a2020-07-23 01:18:11 +0200785 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100786 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
787 TEST_ASSERT(sign_is_valid(&X));
788 if (sub_result == 0) {
789 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
790 }
791 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200792
793 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100794 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
795 TEST_ASSERT(sign_is_valid(&Y));
796 if (sub_result == 0) {
797 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
798 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200799
Paul Bakkerbd51b262014-07-10 15:26:12 +0200800exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000802}
Paul Bakker33b43f12013-08-20 11:48:36 +0200803/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000804
Paul Bakker33b43f12013-08-20 11:48:36 +0200805/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100806void mpi_sub_int(char *input_X, int input_Y,
807 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000808{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000811
Gilles Peskine449bd832023-01-11 14:50:10 +0100812 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
813 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
814 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
815 TEST_ASSERT(sign_is_valid(&Z));
816 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000817
Paul Bakkerbd51b262014-07-10 15:26:12 +0200818exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000820}
Paul Bakker33b43f12013-08-20 11:48:36 +0200821/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000822
Paul Bakker33b43f12013-08-20 11:48:36 +0200823/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100824void mpi_mul_mpi(char *input_X, char *input_Y,
825 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000826{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100828 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000829
Gilles Peskine449bd832023-01-11 14:50:10 +0100830 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
831 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
832 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
833 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
834 TEST_ASSERT(sign_is_valid(&Z));
835 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000836
Paul Bakkerbd51b262014-07-10 15:26:12 +0200837exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000839}
Paul Bakker33b43f12013-08-20 11:48:36 +0200840/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000841
Paul Bakker33b43f12013-08-20 11:48:36 +0200842/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100843void mpi_mul_int(char *input_X, int input_Y,
844 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000845{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100847 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000848
Gilles Peskine449bd832023-01-11 14:50:10 +0100849 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
850 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
851 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
852 TEST_ASSERT(sign_is_valid(&Z));
853 if (strcmp(result_comparison, "==") == 0) {
854 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
855 } else if (strcmp(result_comparison, "!=") == 0) {
856 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
857 } else {
Agathiyan Bragadeesh763b3532023-07-27 13:52:31 +0100858 TEST_FAIL("unknown operator");
Gilles Peskine449bd832023-01-11 14:50:10 +0100859 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000860
Paul Bakkerbd51b262014-07-10 15:26:12 +0200861exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000863}
Paul Bakker33b43f12013-08-20 11:48:36 +0200864/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000865
Paul Bakker33b43f12013-08-20 11:48:36 +0200866/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100867void mpi_div_mpi(char *input_X, char *input_Y,
868 char *input_A, char *input_B,
869 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000870{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000872 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100873 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
874 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000875
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
877 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
878 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
879 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
880 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
881 TEST_ASSERT(res == div_result);
882 if (res == 0) {
883 TEST_ASSERT(sign_is_valid(&Q));
884 TEST_ASSERT(sign_is_valid(&R));
885 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
886 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000887 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000888
Paul Bakkerbd51b262014-07-10 15:26:12 +0200889exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100890 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
891 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000892}
Paul Bakker33b43f12013-08-20 11:48:36 +0200893/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000894
Paul Bakker33b43f12013-08-20 11:48:36 +0200895/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100896void mpi_div_int(char *input_X, int input_Y,
897 char *input_A, char *input_B,
898 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000899{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000901 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100902 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
903 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000904
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
906 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
907 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
908 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
909 TEST_ASSERT(res == div_result);
910 if (res == 0) {
911 TEST_ASSERT(sign_is_valid(&Q));
912 TEST_ASSERT(sign_is_valid(&R));
913 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
914 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000915 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000916
Paul Bakkerbd51b262014-07-10 15:26:12 +0200917exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100918 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
919 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000920}
Paul Bakker33b43f12013-08-20 11:48:36 +0200921/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000922
Paul Bakker33b43f12013-08-20 11:48:36 +0200923/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100924void mpi_mod_mpi(char *input_X, char *input_Y,
925 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100926{
927 mbedtls_mpi X, Y, A;
928 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100929 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100930
Gilles Peskine449bd832023-01-11 14:50:10 +0100931 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
932 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
933 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
934 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
935 TEST_ASSERT(res == div_result);
936 if (res == 0) {
937 TEST_ASSERT(sign_is_valid(&X));
938 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100939 }
940
941exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100942 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100943}
944/* END_CASE */
945
946/* BEGIN_CASE */
Gilles Peskine7768a8e2022-12-04 15:58:48 +0100947void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
948 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100949{
950 mbedtls_mpi X;
951 int res;
952 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100953
Gilles Peskine449bd832023-01-11 14:50:10 +0100954 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000955
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000957
Gilles Peskine449bd832023-01-11 14:50:10 +0100958 res = mbedtls_mpi_mod_int(&r, &X, y);
959 TEST_EQUAL(res, mod_result);
960 if (res == 0) {
961 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100962 }
963
964exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100965 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100966}
967/* END_CASE */
968
969/* BEGIN_CASE */
Janos Follath0512d172024-02-20 14:30:46 +0000970void mpi_exp_mod_min_RR(char *input_A, char *input_E,
Janos Follath09025722024-02-21 11:50:25 +0000971 char *input_N, char *input_X,
972 int exp_result)
Janos Follath0512d172024-02-20 14:30:46 +0000973{
974 mbedtls_mpi A, E, N, RR, Z, X;
975 int res;
976 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
977 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
978
Janos Follathfdab7862024-02-22 15:19:13 +0000979 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
980 TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
981 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
982 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000983
Janos Follathfdab7862024-02-22 15:19:13 +0000984 TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
985 TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
Gilles Peskine673461c2024-02-21 16:03:04 +0100986 /* The objective of this test is to check that exp_mod defends
987 * against a smaller RR. */
988 TEST_LE_U(RR.n, N.n - 1);
Janos Follath0512d172024-02-20 14:30:46 +0000989
990 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Gilles Peskine673461c2024-02-21 16:03:04 +0100991 /* We know that exp_mod internally needs RR to be as large as N.
992 * Validate that it is the case now, otherwise there was probably
993 * a buffer overread. */
994 TEST_EQUAL(RR.n, N.n);
995
Janos Follathfdab7862024-02-22 15:19:13 +0000996 TEST_EQUAL(res, exp_result);
Janos Follath0512d172024-02-20 14:30:46 +0000997 if (res == 0) {
Janos Follathfdab7862024-02-22 15:19:13 +0000998 TEST_EQUAL(sign_is_valid(&Z), 1);
999 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
Janos Follath0512d172024-02-20 14:30:46 +00001000 }
1001
1002exit:
1003 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1004 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
1005}
1006/* END_CASE */
1007
1008/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001009void mpi_exp_mod(char *input_A, char *input_E,
1010 char *input_N, char *input_X,
1011 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001012{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001013 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001014 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1016 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001017
Gilles Peskine449bd832023-01-11 14:50:10 +01001018 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1019 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1020 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1021 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001022
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
1024 TEST_ASSERT(res == exp_result);
1025 if (res == 0) {
1026 TEST_ASSERT(sign_is_valid(&Z));
1027 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001028 }
1029
1030 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001031 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1032 TEST_ASSERT(res == exp_result);
1033 if (res == 0) {
1034 TEST_ASSERT(sign_is_valid(&Z));
1035 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001036 }
1037
1038 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001039 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1040 TEST_ASSERT(res == exp_result);
1041 if (res == 0) {
1042 TEST_ASSERT(sign_is_valid(&Z));
1043 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001044 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001045
Paul Bakkerbd51b262014-07-10 15:26:12 +02001046exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001047 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1048 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001049}
Paul Bakker33b43f12013-08-20 11:48:36 +02001050/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001051
Paul Bakker33b43f12013-08-20 11:48:36 +02001052/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001053void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1054 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001055{
1056 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1058 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001059
Chris Jonesaa850cd2020-12-03 11:35:41 +00001060 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001061 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1062 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1063 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001064
1065 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1067 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1068 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001069
1070 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001071 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1072 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1073 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001074
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 if (strlen(input_RR)) {
1076 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1077 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001078
Gilles Peskine449bd832023-01-11 14:50:10 +01001079 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001080
1081exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001082 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1083 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001084}
1085/* END_CASE */
1086
1087/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001088void mpi_inv_mod(char *input_X, char *input_Y,
1089 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001090{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001092 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001093 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001094
Gilles Peskine449bd832023-01-11 14:50:10 +01001095 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1096 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1097 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1098 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1099 TEST_ASSERT(res == div_result);
1100 if (res == 0) {
1101 TEST_ASSERT(sign_is_valid(&Z));
1102 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001103 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001104
Paul Bakkerbd51b262014-07-10 15:26:12 +02001105exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001107}
Paul Bakker33b43f12013-08-20 11:48:36 +02001108/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001111void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001112{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001114 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001116
Gilles Peskine449bd832023-01-11 14:50:10 +01001117 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1118 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1119 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001120
Paul Bakkerbd51b262014-07-10 15:26:12 +02001121exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001123}
Paul Bakker33b43f12013-08-20 11:48:36 +02001124/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001125
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001127void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1128 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001129{
1130 mbedtls_mpi X;
1131 int res;
1132 mbedtls_test_mpi_random rand;
1133
Gilles Peskine449bd832023-01-11 14:50:10 +01001134 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001135 rand.data = witnesses;
1136 rand.pos = 0;
1137 rand.chunk_len = chunk_len;
1138
Gilles Peskine449bd832023-01-11 14:50:10 +01001139 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1140 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1141 mbedtls_test_mpi_miller_rabin_determinizer,
1142 &rand);
1143 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001144
1145 rand.data = witnesses;
1146 rand.pos = 0;
1147 rand.chunk_len = chunk_len;
1148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1150 mbedtls_test_mpi_miller_rabin_determinizer,
1151 &rand);
1152 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001153
1154exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001155 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001156}
1157/* END_CASE */
1158
1159/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001160void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001163 int my_ret;
1164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001166
Gilles Peskine449bd832023-01-11 14:50:10 +01001167 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1168 mbedtls_test_rnd_std_rand, NULL);
1169 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001170
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 if (ref_ret == 0) {
1172 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001173
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 TEST_ASSERT(actual_bits >= (size_t) bits);
1175 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1176 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001177
Gilles Peskine449bd832023-01-11 14:50:10 +01001178 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1179 mbedtls_test_rnd_std_rand,
1180 NULL) == 0);
1181 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001182 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001183 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1184 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1185 mbedtls_test_rnd_std_rand,
1186 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001187 }
1188 }
1189
Paul Bakkerbd51b262014-07-10 15:26:12 +02001190exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001192}
1193/* END_CASE */
1194
Paul Bakker33b43f12013-08-20 11:48:36 +02001195/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001196void mpi_shift_l(char *input_X, int shift_X,
1197 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001198{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001199 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001201
Gilles Peskine449bd832023-01-11 14:50:10 +01001202 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1203 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1204 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1205 TEST_ASSERT(sign_is_valid(&X));
1206 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001207
Paul Bakkerbd51b262014-07-10 15:26:12 +02001208exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001210}
Paul Bakker33b43f12013-08-20 11:48:36 +02001211/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001212
Paul Bakker33b43f12013-08-20 11:48:36 +02001213/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001214void mpi_shift_r(char *input_X, int shift_X,
1215 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001216{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001217 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001219
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1221 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1222 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1223 TEST_ASSERT(sign_is_valid(&X));
1224 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001225
Paul Bakkerbd51b262014-07-10 15:26:12 +02001226exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001227 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001228}
Paul Bakker33b43f12013-08-20 11:48:36 +02001229/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001230
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001231/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001232void mpi_fill_random(int wanted_bytes, int rng_bytes,
1233 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001234{
1235 mbedtls_mpi X;
1236 int ret;
1237 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001238 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001239
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001241 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1243 if (before < 0) {
1244 before = -before;
1245 }
1246 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001247 }
1248
Gilles Peskine449bd832023-01-11 14:50:10 +01001249 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1250 f_rng_bytes_left, &bytes_left);
1251 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001252
Gilles Peskine449bd832023-01-11 14:50:10 +01001253 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001254 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1255 * as a big-endian representation of the number. We know when
1256 * our RNG function returns null bytes, so we know how many
1257 * leading zero bytes the number has. */
1258 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001259 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001260 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001261 }
1262 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1263 (size_t) wanted_bytes);
1264 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1265 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001266 }
1267
1268exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001270}
1271/* END_CASE */
1272
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001273/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001275{
1276 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1277 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1278 * is a valid value. However, negating it (`-n`) has undefined behavior
1279 * (although in practice `-n` evaluates to the value n).
1280 *
1281 * This function has ad hoc tests for this value. It's separated from other
1282 * functions because the test framework makes it hard to pass this value
1283 * into test cases.
1284 *
1285 * In the comments here:
1286 * - biL = number of bits in limbs
1287 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1288 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1289 */
1290
1291 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 mbedtls_mpi_init(&A);
1293 mbedtls_mpi_init(&R);
1294 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001295
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001297 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001298 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1299 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1300 (mbedtls_mpi_uint) 1 << (biL - 1));
1301 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001302
1303 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001304 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1305 TEST_EQUAL(A.s, -1);
1306 TEST_EQUAL(A.n, 1);
1307 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001308
1309 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001310 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001311
1312 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1313 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001314 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001315
1316 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1317 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001318 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001319
1320 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001321 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1322 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1323 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001324
1325 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001326 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1327 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1328 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001329
1330 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001331 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1332 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1333 TEST_EQUAL(X.s, -1);
1334 TEST_EQUAL(X.n, 2);
1335 TEST_EQUAL(X.p[0], 0);
1336 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001337
1338 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001339 mbedtls_mpi_free(&X);
1340 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1341 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1342 TEST_EQUAL(X.s, 1);
1343 TEST_EQUAL(X.n, 1);
1344 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001345
1346 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001347 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1348 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1349 TEST_EQUAL(X.s, 1);
1350 TEST_EQUAL(X.n, 1);
1351 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001352
1353 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001354 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1355 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1356 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001357
1358 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001359 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1360 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1361 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1362 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001363
1364 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001365 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1366 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1367 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1368 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001369
1370 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001371 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1372 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1373 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1374 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001375
1376 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001377 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1378 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1379 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1380 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001381
1382 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001383 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1384 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1385 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1386 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001387
1388 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1390 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1391 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1392 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001393
1394 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001395 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1396 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1397 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1398 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001399
1400 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1402 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001403
1404 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001405 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1406 mbedtls_test_rnd_std_rand, NULL),
1407 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001408
1409exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 mbedtls_mpi_free(&A);
1411 mbedtls_mpi_free(&R);
1412 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001413}
1414/* END_CASE */
1415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001416/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001417void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001418{
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001420}
Paul Bakker33b43f12013-08-20 11:48:36 +02001421/* END_CASE */