blob: 47a6c981aa20bb214a8fbb923169a757141a7754 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/bignum.h"
Gilles Peskine3cb1e292020-11-25 15:37:20 +01003#include "mbedtls/entropy.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01004#include "constant_time_internal.h"
Gilles Peskine34e8a2c2022-09-27 22:04:51 +02005#include "bignum_core.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01006#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01007
Chris Jonese64a46f2020-12-03 17:44:03 +00008#if MBEDTLS_MPI_MAX_BITS > 792
9#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000010#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020011
Gilles Peskinedffc7102021-06-10 15:34:15 +020012/* Check the validity of the sign bit in an MPI object. Reject representations
13 * that are not supported by the rest of the library and indicate a bug when
14 * constructing the value. */
Gilles Peskine449bd832023-01-11 14:50:10 +010015static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskinedffc7102021-06-10 15:34:15 +020016{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010017 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +010018 if (X->s != 1 && X->s != -1) {
19 return 0;
20 }
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010021
22 /* The value 0 must be represented with the sign +1. A "negative zero"
23 * with s=-1 is an invalid representation. Forbid that. As an exception,
24 * we sometimes test the robustness of library functions when given
25 * a negative zero input. If a test case has a negative zero as input,
26 * we don't mind if the function has a negative zero output. */
Paul Elliottc7a1e992023-11-03 18:44:57 +000027 if (!mbedtls_test_get_case_uses_negative_0() &&
Gilles Peskine449bd832023-01-11 14:50:10 +010028 mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
29 return 0;
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010030 }
31
Gilles Peskine449bd832023-01-11 14:50:10 +010032 return 1;
Gilles Peskinedffc7102021-06-10 15:34:15 +020033}
34
Gilles Peskine449bd832023-01-11 14:50:10 +010035typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010036 data_t *data;
37 size_t pos;
38 size_t chunk_len;
39} mbedtls_test_mpi_random;
40
41/*
42 * This function is called by the Miller-Rabin primality test each time it
43 * chooses a random witness. The witnesses (or non-witnesses as provided by the
44 * test) are stored in the data member of the state structure. Each number is in
45 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
46 */
Gilles Peskine449bd832023-01-11 14:50:10 +010047int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
48 unsigned char *buf,
49 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010050{
Gilles Peskine449bd832023-01-11 14:50:10 +010051 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010052
Gilles Peskine449bd832023-01-11 14:50:10 +010053 if (random == NULL || random->data->x == NULL || buf == NULL) {
54 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010055 }
56
Gilles Peskine449bd832023-01-11 14:50:10 +010057 if (random->pos + random->chunk_len > random->data->len
58 || random->chunk_len > len) {
59 return -1;
60 }
61
62 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010063
64 /* The witness is written to the end of the buffer, since the buffer is
65 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
66 * Writing the witness to the start of the buffer would result in the
67 * buffer being 'witness 000...000', which would be treated as
68 * witness * 2^n for some n. */
Gilles Peskine449bd832023-01-11 14:50:10 +010069 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
70 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010071
72 random->pos += random->chunk_len;
73
Gilles Peskine449bd832023-01-11 14:50:10 +010074 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010075}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010076
77/* Random generator that is told how many bytes to return. */
Gilles Peskine449bd832023-01-11 14:50:10 +010078static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010079{
80 size_t *bytes_left = state;
81 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010082 for (i = 0; i < len; i++) {
83 if (*bytes_left == 0) {
84 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
85 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010086 buf[i] = *bytes_left & 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010087 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010088 }
Gilles Peskine449bd832023-01-11 14:50:10 +010089 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010090}
91
Paul Bakker33b43f12013-08-20 11:48:36 +020092/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000093
Paul Bakker33b43f12013-08-20 11:48:36 +020094/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020095 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020096 * END_DEPENDENCIES
97 */
Paul Bakker5690efc2011-05-26 13:16:06 +000098
Hanno Beckerb48e1aa2018-12-18 23:25:01 +000099/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100100void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200101{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200102 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200103
Gilles Peskine449bd832023-01-11 14:50:10 +0100104 mbedtls_mpi_init(&X);
105 mbedtls_mpi_init(&Y);
106 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
109 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
110 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
111 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200112
113exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100114 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200115}
116/* END_CASE */
117
118/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100119void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
120 char *input_A, int output_size, int result_read,
121 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000122{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200123 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000124 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100125 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000126
Gilles Peskine449bd832023-01-11 14:50:10 +0100127 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000128
Gilles Peskine449bd832023-01-11 14:50:10 +0100129 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
132 if (result_read == 0) {
133 TEST_ASSERT(sign_is_valid(&X));
134 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
135 if (result_write == 0) {
Gilles Peskine017f0b72022-12-04 13:29:20 +0100136 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine449bd832023-01-11 14:50:10 +0100137 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000138 }
139 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000140
Paul Bakkerbd51b262014-07-10 15:26:12 +0200141exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100142 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000143}
Paul Bakker33b43f12013-08-20 11:48:36 +0200144/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000145
Paul Bakker33b43f12013-08-20 11:48:36 +0200146/* BEGIN_CASE */
Valerio Settif988f952024-01-30 14:40:31 +0100147void mpi_zero_length_buffer_is_null()
148{
149 mbedtls_mpi X;
150 size_t olen;
151
152 mbedtls_mpi_init(&X);
153
154 /* Simply test that the following functions do not crash when a NULL buffer
155 * pointer and 0 length is passed. We don't care much about the return value. */
156 TEST_EQUAL(mbedtls_mpi_read_binary(&X, NULL, 0), 0);
157 TEST_EQUAL(mbedtls_mpi_read_binary_le(&X, NULL, 0), 0);
158 TEST_EQUAL(mbedtls_mpi_write_string(&X, 16, NULL, 0, &olen), MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
159 TEST_EQUAL(mbedtls_mpi_write_binary(&X, NULL, 0), 0);
160
161exit:
162 mbedtls_mpi_free(&X);
163}
164/* END_CASE */
165
166/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100167void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000168{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000170 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100171 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000172
Gilles Peskine449bd832023-01-11 14:50:10 +0100173 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000174
Paul Bakkere896fea2009-07-06 06:40:23 +0000175
Gilles Peskine449bd832023-01-11 14:50:10 +0100176 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
177 TEST_ASSERT(sign_is_valid(&X));
178 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
179 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000180
Paul Bakkerbd51b262014-07-10 15:26:12 +0200181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100182 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000183}
Paul Bakker33b43f12013-08-20 11:48:36 +0200184/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000185
Paul Bakker33b43f12013-08-20 11:48:36 +0200186/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100187void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000188{
189 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000190 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000191 size_t len;
192
Gilles Peskine449bd832023-01-11 14:50:10 +0100193 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000194
195
Gilles Peskine449bd832023-01-11 14:50:10 +0100196 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
197 TEST_ASSERT(sign_is_valid(&X));
198 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
199 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000200
201exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100202 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000203}
204/* END_CASE */
205
206/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100207void mpi_write_binary(char *input_X, data_t *input_A,
208 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000209{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000211 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000212 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000213
Gilles Peskine449bd832023-01-11 14:50:10 +0100214 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000215
Gilles Peskine449bd832023-01-11 14:50:10 +0100216 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 buflen = mbedtls_mpi_size(&X);
221 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200222 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100223 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000224
Gilles Peskine449bd832023-01-11 14:50:10 +0100225 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
226 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000227
Gilles Peskine449bd832023-01-11 14:50:10 +0100228 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
229 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000230 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000231
Paul Bakkerbd51b262014-07-10 15:26:12 +0200232exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100233 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000234}
Paul Bakker33b43f12013-08-20 11:48:36 +0200235/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000236
Janos Follathe344d0f2019-02-19 16:17:40 +0000237/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100238void mpi_write_binary_le(char *input_X, data_t *input_A,
239 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000240{
241 mbedtls_mpi X;
242 unsigned char buf[1000];
243 size_t buflen;
244
Gilles Peskine449bd832023-01-11 14:50:10 +0100245 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000246
Gilles Peskine449bd832023-01-11 14:50:10 +0100247 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 buflen = mbedtls_mpi_size(&X);
252 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000253 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100254 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000255
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
257 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000258
Gilles Peskine449bd832023-01-11 14:50:10 +0100259 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
260 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000261 }
262
263exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100264 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000265}
266/* END_CASE */
267
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100269void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000270{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200271 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000272 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000273 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000274 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000275 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000276
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 file = fopen(input_file, "r");
282 TEST_ASSERT(file != NULL);
283 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000284 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000286
Gilles Peskine449bd832023-01-11 14:50:10 +0100287 if (result == 0) {
288 TEST_ASSERT(sign_is_valid(&X));
289 buflen = mbedtls_mpi_size(&X);
290 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000291
Paul Bakkere896fea2009-07-06 06:40:23 +0000292
Gilles Peskine449bd832023-01-11 14:50:10 +0100293 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
294 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000295 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000296
Paul Bakkerbd51b262014-07-10 15:26:12 +0200297exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100298 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000299}
Paul Bakker33b43f12013-08-20 11:48:36 +0200300/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000301
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200302/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100303void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000304{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000306 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200307 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000308
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 file_out = fopen(output_file, "w");
314 TEST_ASSERT(file_out != NULL);
315 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000316 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000318
Gilles Peskine449bd832023-01-11 14:50:10 +0100319 file_in = fopen(output_file, "r");
320 TEST_ASSERT(file_in != NULL);
321 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000322 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000324
Gilles Peskine449bd832023-01-11 14:50:10 +0100325 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000326
Paul Bakkerbd51b262014-07-10 15:26:12 +0200327exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000329}
Paul Bakker33b43f12013-08-20 11:48:36 +0200330/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000331
Paul Bakker33b43f12013-08-20 11:48:36 +0200332/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100333void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000334{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100336 mbedtls_mpi_init(&X);
337 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
338 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000339
Paul Bakkerbd51b262014-07-10 15:26:12 +0200340exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100341 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000342}
Paul Bakker33b43f12013-08-20 11:48:36 +0200343/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000344
Paul Bakker33b43f12013-08-20 11:48:36 +0200345/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100346void mpi_set_bit(char *input_X, int pos, int val,
347 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000348{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100350 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000351
Gilles Peskine449bd832023-01-11 14:50:10 +0100352 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
353 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
354 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 if (result == 0) {
357 TEST_ASSERT(sign_is_valid(&X));
358 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100359 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000360
Paul Bakkerbd51b262014-07-10 15:26:12 +0200361exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000363}
Paul Bakker33b43f12013-08-20 11:48:36 +0200364/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000365
Paul Bakker33b43f12013-08-20 11:48:36 +0200366/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100367void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000368{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100370 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000371
Gilles Peskine449bd832023-01-11 14:50:10 +0100372 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
373 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000374
Paul Bakkerbd51b262014-07-10 15:26:12 +0200375exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000377}
Paul Bakker33b43f12013-08-20 11:48:36 +0200378/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000379
Paul Bakker33b43f12013-08-20 11:48:36 +0200380/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100381void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000382{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100384 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000385
Gilles Peskine449bd832023-01-11 14:50:10 +0100386 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
387 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000388
Paul Bakkerbd51b262014-07-10 15:26:12 +0200389exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000391}
Paul Bakker33b43f12013-08-20 11:48:36 +0200392/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000393
Paul Bakker33b43f12013-08-20 11:48:36 +0200394/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100395void mpi_gcd(char *input_X, char *input_Y,
396 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000397{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100399 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000400
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
402 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
403 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
404 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
405 TEST_ASSERT(sign_is_valid(&Z));
406 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000407
Paul Bakkerbd51b262014-07-10 15:26:12 +0200408exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000410}
Paul Bakker33b43f12013-08-20 11:48:36 +0200411/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000412
Paul Bakker33b43f12013-08-20 11:48:36 +0200413/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100414void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000415{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100417 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000418
Gilles Peskine449bd832023-01-11 14:50:10 +0100419 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
420 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000421
Paul Bakkerbd51b262014-07-10 15:26:12 +0200422exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000424}
Paul Bakker33b43f12013-08-20 11:48:36 +0200425/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000426
Paul Bakker33b43f12013-08-20 11:48:36 +0200427/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100428void mpi_cmp_mpi(char *input_X, char *input_Y,
429 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000430{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100432 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000433
Gilles Peskine449bd832023-01-11 14:50:10 +0100434 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
435 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
436 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000437
Paul Bakkerbd51b262014-07-10 15:26:12 +0200438exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100439 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000440}
Paul Bakker33b43f12013-08-20 11:48:36 +0200441/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000442
Paul Bakker33b43f12013-08-20 11:48:36 +0200443/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100444void mpi_lt_mpi_ct(int size_X, char *input_X,
445 int size_Y, char *input_Y,
446 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100447{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200448 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100449 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100450 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100452
Gilles Peskine449bd832023-01-11 14:50:10 +0100453 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
454 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100455
Gilles Peskine449bd832023-01-11 14:50:10 +0100456 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
457 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100458
Gilles Peskine449bd832023-01-11 14:50:10 +0100459 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
460 if (input_err == 0) {
Dave Rodgman14bec142023-05-11 16:19:27 +0100461 TEST_EQUAL(ret, input_uret);
Gilles Peskine449bd832023-01-11 14:50:10 +0100462 }
Janos Follath385d5b82019-09-11 16:07:14 +0100463
464exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100465 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100466}
467/* END_CASE */
468
469/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100470void mpi_cmp_abs(char *input_X, char *input_Y,
471 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000472{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100474 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000475
Gilles Peskine449bd832023-01-11 14:50:10 +0100476 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
477 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
478 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000479
Paul Bakkerbd51b262014-07-10 15:26:12 +0200480exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000482}
Paul Bakker33b43f12013-08-20 11:48:36 +0200483/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000484
Paul Bakker33b43f12013-08-20 11:48:36 +0200485/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100486void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000487{
Gilles Peskined0722f82021-06-10 23:00:33 +0200488 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 mbedtls_mpi_init(&src);
490 mbedtls_mpi_init(&dst);
491 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000492
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
494 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200495
496 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
498 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
499 TEST_ASSERT(sign_is_valid(&dst));
500 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000501
Gilles Peskined0722f82021-06-10 23:00:33 +0200502 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100503 mbedtls_mpi_free(&dst);
504 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
505 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
506 TEST_ASSERT(sign_is_valid(&dst));
507 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200508
509 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100510 mbedtls_mpi_free(&dst);
511 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
512 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
513 TEST_ASSERT(sign_is_valid(&dst));
514 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200515
Paul Bakkerbd51b262014-07-10 15:26:12 +0200516exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100517 mbedtls_mpi_free(&src);
518 mbedtls_mpi_free(&dst);
519 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100520}
521/* END_CASE */
522
523/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100524void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100525{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200526 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100527 mbedtls_mpi_init(&A);
528 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000529
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
531 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200532
Gilles Peskine449bd832023-01-11 14:50:10 +0100533 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
534 TEST_ASSERT(sign_is_valid(&X));
535 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000536
Paul Bakkerbd51b262014-07-10 15:26:12 +0200537exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100538 mbedtls_mpi_free(&A);
539 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000540}
Paul Bakker33b43f12013-08-20 11:48:36 +0200541/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000542
Paul Bakker33b43f12013-08-20 11:48:36 +0200543/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100544void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200545{
546 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100547 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
548 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200549
Gilles Peskine449bd832023-01-11 14:50:10 +0100550 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
551 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200552
Gilles Peskined0722f82021-06-10 23:00:33 +0200553 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
555 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
556 mbedtls_mpi_swap(&X, &Y);
557 TEST_ASSERT(sign_is_valid(&X));
558 TEST_ASSERT(sign_is_valid(&Y));
559 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
560 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200561
Gilles Peskined0722f82021-06-10 23:00:33 +0200562 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100563 mbedtls_mpi_free(&X);
564 mbedtls_mpi_free(&Y);
565 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
566 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
567 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
568 TEST_ASSERT(sign_is_valid(&X));
569 TEST_ASSERT(sign_is_valid(&Y));
570 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
571 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200572
573 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100574 mbedtls_mpi_free(&X);
575 mbedtls_mpi_free(&Y);
576 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
577 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
578 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
579 TEST_ASSERT(sign_is_valid(&X));
580 TEST_ASSERT(sign_is_valid(&Y));
581 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
582 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200583
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200584exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100585 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
586 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200587}
588/* END_CASE */
589
590/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100591void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200592{
593 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100594 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200595
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
597 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200598
Gilles Peskine449bd832023-01-11 14:50:10 +0100599 mbedtls_mpi_swap(&X, &X);
600 TEST_ASSERT(sign_is_valid(&X));
601 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200602
603exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200605}
606/* END_CASE */
607
608/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100609void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100610{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100612 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100613
Gilles Peskine449bd832023-01-11 14:50:10 +0100614 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
615 if (used > 0) {
616 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
617 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200618 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100619 TEST_EQUAL(X.n, (size_t) before);
620 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
621 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100622
Paul Bakkerbd51b262014-07-10 15:26:12 +0200623exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100624 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100625}
626/* END_CASE */
627
628/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100629void mpi_add_mpi(char *input_X, char *input_Y,
630 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000631{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200632 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100633 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000634
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
636 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
637 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
638 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
639 TEST_ASSERT(sign_is_valid(&Z));
640 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000641
Gilles Peskine56f943a2020-07-23 01:18:11 +0200642 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100643 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
644 TEST_ASSERT(sign_is_valid(&X));
645 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
646 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200647
648 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100649 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
650 TEST_ASSERT(sign_is_valid(&Y));
651 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200652
Paul Bakkerbd51b262014-07-10 15:26:12 +0200653exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000655}
Paul Bakker33b43f12013-08-20 11:48:36 +0200656/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000657
Paul Bakker33b43f12013-08-20 11:48:36 +0200658/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100659void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100660{
661 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100662 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100663
Gilles Peskine449bd832023-01-11 14:50:10 +0100664 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100665
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
667 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
668 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
669 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100670
Gilles Peskine449bd832023-01-11 14:50:10 +0100671 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
672 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
673 TEST_ASSERT(sign_is_valid(&X));
674 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100675
Gilles Peskine449bd832023-01-11 14:50:10 +0100676 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
677 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
678 TEST_ASSERT(sign_is_valid(&X));
679 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100680
681exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100682 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100683}
684/* END_CASE */
685
686
687/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100688void mpi_add_abs(char *input_X, char *input_Y,
689 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000690{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100692 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000693
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
695 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
696 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
697 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
698 TEST_ASSERT(sign_is_valid(&Z));
699 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000700
Gilles Peskine56f943a2020-07-23 01:18:11 +0200701 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100702 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
703 TEST_ASSERT(sign_is_valid(&X));
704 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
705 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200706
707 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100708 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
709 TEST_ASSERT(sign_is_valid(&Y));
710 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000711
Paul Bakkerbd51b262014-07-10 15:26:12 +0200712exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100713 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000714}
Paul Bakker33b43f12013-08-20 11:48:36 +0200715/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000716
Paul Bakker33b43f12013-08-20 11:48:36 +0200717/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100718void mpi_add_int(char *input_X, int input_Y,
719 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000720{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100722 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000723
Gilles Peskine449bd832023-01-11 14:50:10 +0100724 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
725 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
726 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
727 TEST_ASSERT(sign_is_valid(&Z));
728 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000729
Paul Bakkerbd51b262014-07-10 15:26:12 +0200730exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100731 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000732}
Paul Bakker33b43f12013-08-20 11:48:36 +0200733/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000734
Paul Bakker33b43f12013-08-20 11:48:36 +0200735/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100736void mpi_sub_mpi(char *input_X, char *input_Y,
737 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000738{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100740 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000741
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
743 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
744 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
745 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
746 TEST_ASSERT(sign_is_valid(&Z));
747 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000748
Gilles Peskine56f943a2020-07-23 01:18:11 +0200749 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100750 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
751 TEST_ASSERT(sign_is_valid(&X));
752 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
753 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200754
755 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100756 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
757 TEST_ASSERT(sign_is_valid(&Y));
758 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200759
Paul Bakkerbd51b262014-07-10 15:26:12 +0200760exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100761 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000762}
Paul Bakker33b43f12013-08-20 11:48:36 +0200763/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000764
Paul Bakker33b43f12013-08-20 11:48:36 +0200765/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100766void mpi_sub_abs(char *input_X, char *input_Y,
767 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000768{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000770 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100771 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000772
Gilles Peskine449bd832023-01-11 14:50:10 +0100773 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
774 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
775 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
778 TEST_ASSERT(res == sub_result);
779 TEST_ASSERT(sign_is_valid(&Z));
780 if (res == 0) {
781 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
782 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000783
Gilles Peskine56f943a2020-07-23 01:18:11 +0200784 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
786 TEST_ASSERT(sign_is_valid(&X));
787 if (sub_result == 0) {
788 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
789 }
790 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200791
792 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100793 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
794 TEST_ASSERT(sign_is_valid(&Y));
795 if (sub_result == 0) {
796 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
797 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200798
Paul Bakkerbd51b262014-07-10 15:26:12 +0200799exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100800 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000801}
Paul Bakker33b43f12013-08-20 11:48:36 +0200802/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000803
Paul Bakker33b43f12013-08-20 11:48:36 +0200804/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100805void mpi_sub_int(char *input_X, int input_Y,
806 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000807{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100809 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000810
Gilles Peskine449bd832023-01-11 14:50:10 +0100811 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
812 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
813 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
814 TEST_ASSERT(sign_is_valid(&Z));
815 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000816
Paul Bakkerbd51b262014-07-10 15:26:12 +0200817exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100818 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000819}
Paul Bakker33b43f12013-08-20 11:48:36 +0200820/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000821
Paul Bakker33b43f12013-08-20 11:48:36 +0200822/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100823void mpi_mul_mpi(char *input_X, char *input_Y,
824 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000825{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100827 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000828
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
830 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
831 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
832 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
833 TEST_ASSERT(sign_is_valid(&Z));
834 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000835
Paul Bakkerbd51b262014-07-10 15:26:12 +0200836exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100837 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000838}
Paul Bakker33b43f12013-08-20 11:48:36 +0200839/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000840
Paul Bakker33b43f12013-08-20 11:48:36 +0200841/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100842void mpi_mul_int(char *input_X, int input_Y,
843 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000844{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100846 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000847
Gilles Peskine449bd832023-01-11 14:50:10 +0100848 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
849 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
850 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
851 TEST_ASSERT(sign_is_valid(&Z));
852 if (strcmp(result_comparison, "==") == 0) {
853 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
854 } else if (strcmp(result_comparison, "!=") == 0) {
855 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
856 } else {
Agathiyan Bragadeesh763b3532023-07-27 13:52:31 +0100857 TEST_FAIL("unknown operator");
Gilles Peskine449bd832023-01-11 14:50:10 +0100858 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000859
Paul Bakkerbd51b262014-07-10 15:26:12 +0200860exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100861 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000862}
Paul Bakker33b43f12013-08-20 11:48:36 +0200863/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000864
Paul Bakker33b43f12013-08-20 11:48:36 +0200865/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100866void mpi_div_mpi(char *input_X, char *input_Y,
867 char *input_A, char *input_B,
868 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000869{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000871 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100872 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
873 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000874
Gilles Peskine449bd832023-01-11 14:50:10 +0100875 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
876 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
877 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
878 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
879 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
880 TEST_ASSERT(res == div_result);
881 if (res == 0) {
882 TEST_ASSERT(sign_is_valid(&Q));
883 TEST_ASSERT(sign_is_valid(&R));
884 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
885 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000886 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000887
Paul Bakkerbd51b262014-07-10 15:26:12 +0200888exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100889 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
890 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000891}
Paul Bakker33b43f12013-08-20 11:48:36 +0200892/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000893
Paul Bakker33b43f12013-08-20 11:48:36 +0200894/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100895void mpi_div_int(char *input_X, int input_Y,
896 char *input_A, char *input_B,
897 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000898{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200899 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000900 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100901 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
902 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000903
Gilles Peskine449bd832023-01-11 14:50:10 +0100904 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
905 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
906 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
907 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
908 TEST_ASSERT(res == div_result);
909 if (res == 0) {
910 TEST_ASSERT(sign_is_valid(&Q));
911 TEST_ASSERT(sign_is_valid(&R));
912 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
913 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000914 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000915
Paul Bakkerbd51b262014-07-10 15:26:12 +0200916exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100917 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
918 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000919}
Paul Bakker33b43f12013-08-20 11:48:36 +0200920/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000921
Paul Bakker33b43f12013-08-20 11:48:36 +0200922/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100923void mpi_mod_mpi(char *input_X, char *input_Y,
924 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100925{
926 mbedtls_mpi X, Y, A;
927 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100928 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100929
Gilles Peskine449bd832023-01-11 14:50:10 +0100930 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
931 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
932 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
933 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
934 TEST_ASSERT(res == div_result);
935 if (res == 0) {
936 TEST_ASSERT(sign_is_valid(&X));
937 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100938 }
939
940exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100941 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100942}
943/* END_CASE */
944
945/* BEGIN_CASE */
Gilles Peskine7768a8e2022-12-04 15:58:48 +0100946void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
947 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100948{
949 mbedtls_mpi X;
950 int res;
951 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100952
Gilles Peskine449bd832023-01-11 14:50:10 +0100953 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000954
Gilles Peskine449bd832023-01-11 14:50:10 +0100955 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 res = mbedtls_mpi_mod_int(&r, &X, y);
958 TEST_EQUAL(res, mod_result);
959 if (res == 0) {
960 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100961 }
962
963exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100964 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100965}
966/* END_CASE */
967
968/* BEGIN_CASE */
Janos Follath0512d172024-02-20 14:30:46 +0000969void mpi_exp_mod_min_RR(char *input_A, char *input_E,
Janos Follath09025722024-02-21 11:50:25 +0000970 char *input_N, char *input_X,
971 int exp_result)
Janos Follath0512d172024-02-20 14:30:46 +0000972{
973 mbedtls_mpi A, E, N, RR, Z, X;
974 int res;
975 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
976 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
977
978 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
979 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
980 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
981 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
982
983 TEST_ASSERT(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N) == 0);
984 TEST_ASSERT(mbedtls_mpi_shrink(&RR, 0) == 0);
985
986 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
987 TEST_ASSERT(res == exp_result);
988 if (res == 0) {
989 TEST_ASSERT(sign_is_valid(&Z));
990 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
991 }
992
993exit:
994 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
995 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
996}
997/* END_CASE */
998
999/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001000void mpi_exp_mod(char *input_A, char *input_E,
1001 char *input_N, char *input_X,
1002 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001003{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001004 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001005 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001006 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1007 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001008
Gilles Peskine449bd832023-01-11 14:50:10 +01001009 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1010 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1011 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1012 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001013
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
1015 TEST_ASSERT(res == exp_result);
1016 if (res == 0) {
1017 TEST_ASSERT(sign_is_valid(&Z));
1018 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001019 }
1020
1021 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1023 TEST_ASSERT(res == exp_result);
1024 if (res == 0) {
1025 TEST_ASSERT(sign_is_valid(&Z));
1026 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001027 }
1028
1029 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001030 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1031 TEST_ASSERT(res == exp_result);
1032 if (res == 0) {
1033 TEST_ASSERT(sign_is_valid(&Z));
1034 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001035 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001036
Paul Bakkerbd51b262014-07-10 15:26:12 +02001037exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1039 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001040}
Paul Bakker33b43f12013-08-20 11:48:36 +02001041/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001042
Paul Bakker33b43f12013-08-20 11:48:36 +02001043/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001044void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1045 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001046{
1047 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001048 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1049 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001050
Chris Jonesaa850cd2020-12-03 11:35:41 +00001051 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1053 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1054 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001055
1056 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001057 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1058 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1059 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001060
1061 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1063 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1064 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001065
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 if (strlen(input_RR)) {
1067 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1068 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001069
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001071
1072exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001073 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1074 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001075}
1076/* END_CASE */
1077
1078/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001079void mpi_inv_mod(char *input_X, char *input_Y,
1080 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001081{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001083 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001084 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001085
Gilles Peskine449bd832023-01-11 14:50:10 +01001086 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1087 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1088 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1089 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1090 TEST_ASSERT(res == div_result);
1091 if (res == 0) {
1092 TEST_ASSERT(sign_is_valid(&Z));
1093 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001094 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001095
Paul Bakkerbd51b262014-07-10 15:26:12 +02001096exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001098}
Paul Bakker33b43f12013-08-20 11:48:36 +02001099/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001100
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001102void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001103{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001104 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001105 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001107
Gilles Peskine449bd832023-01-11 14:50:10 +01001108 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1109 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1110 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001111
Paul Bakkerbd51b262014-07-10 15:26:12 +02001112exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001113 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001114}
Paul Bakker33b43f12013-08-20 11:48:36 +02001115/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001118void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1119 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001120{
1121 mbedtls_mpi X;
1122 int res;
1123 mbedtls_test_mpi_random rand;
1124
Gilles Peskine449bd832023-01-11 14:50:10 +01001125 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001126 rand.data = witnesses;
1127 rand.pos = 0;
1128 rand.chunk_len = chunk_len;
1129
Gilles Peskine449bd832023-01-11 14:50:10 +01001130 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1131 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1132 mbedtls_test_mpi_miller_rabin_determinizer,
1133 &rand);
1134 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001135
1136 rand.data = witnesses;
1137 rand.pos = 0;
1138 rand.chunk_len = chunk_len;
1139
Gilles Peskine449bd832023-01-11 14:50:10 +01001140 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1141 mbedtls_test_mpi_miller_rabin_determinizer,
1142 &rand);
1143 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001144
1145exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001146 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001147}
1148/* END_CASE */
1149
1150/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001151void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001152{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001154 int my_ret;
1155
Gilles Peskine449bd832023-01-11 14:50:10 +01001156 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001157
Gilles Peskine449bd832023-01-11 14:50:10 +01001158 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1159 mbedtls_test_rnd_std_rand, NULL);
1160 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001161
Gilles Peskine449bd832023-01-11 14:50:10 +01001162 if (ref_ret == 0) {
1163 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001164
Gilles Peskine449bd832023-01-11 14:50:10 +01001165 TEST_ASSERT(actual_bits >= (size_t) bits);
1166 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1167 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001168
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1170 mbedtls_test_rnd_std_rand,
1171 NULL) == 0);
1172 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001173 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001174 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1175 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1176 mbedtls_test_rnd_std_rand,
1177 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001178 }
1179 }
1180
Paul Bakkerbd51b262014-07-10 15:26:12 +02001181exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001183}
1184/* END_CASE */
1185
Paul Bakker33b43f12013-08-20 11:48:36 +02001186/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001187void mpi_shift_l(char *input_X, int shift_X,
1188 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001189{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1194 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1195 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1196 TEST_ASSERT(sign_is_valid(&X));
1197 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001198
Paul Bakkerbd51b262014-07-10 15:26:12 +02001199exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001200 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001201}
Paul Bakker33b43f12013-08-20 11:48:36 +02001202/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001203
Paul Bakker33b43f12013-08-20 11:48:36 +02001204/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001205void mpi_shift_r(char *input_X, int shift_X,
1206 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001207{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001208 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001210
Gilles Peskine449bd832023-01-11 14:50:10 +01001211 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1212 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1213 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1214 TEST_ASSERT(sign_is_valid(&X));
1215 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001216
Paul Bakkerbd51b262014-07-10 15:26:12 +02001217exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001218 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001219}
Paul Bakker33b43f12013-08-20 11:48:36 +02001220/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001221
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001222/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001223void mpi_fill_random(int wanted_bytes, int rng_bytes,
1224 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001225{
1226 mbedtls_mpi X;
1227 int ret;
1228 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001229 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001230
Gilles Peskine449bd832023-01-11 14:50:10 +01001231 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001232 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1234 if (before < 0) {
1235 before = -before;
1236 }
1237 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001238 }
1239
Gilles Peskine449bd832023-01-11 14:50:10 +01001240 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1241 f_rng_bytes_left, &bytes_left);
1242 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001245 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1246 * as a big-endian representation of the number. We know when
1247 * our RNG function returns null bytes, so we know how many
1248 * leading zero bytes the number has. */
1249 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001250 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001251 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 }
1253 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1254 (size_t) wanted_bytes);
1255 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1256 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001257 }
1258
1259exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001261}
1262/* END_CASE */
1263
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001264/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001265void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001266{
1267 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1268 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1269 * is a valid value. However, negating it (`-n`) has undefined behavior
1270 * (although in practice `-n` evaluates to the value n).
1271 *
1272 * This function has ad hoc tests for this value. It's separated from other
1273 * functions because the test framework makes it hard to pass this value
1274 * into test cases.
1275 *
1276 * In the comments here:
1277 * - biL = number of bits in limbs
1278 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1279 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1280 */
1281
1282 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001283 mbedtls_mpi_init(&A);
1284 mbedtls_mpi_init(&R);
1285 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001286
Gilles Peskine449bd832023-01-11 14:50:10 +01001287 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001288 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001289 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1290 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1291 (mbedtls_mpi_uint) 1 << (biL - 1));
1292 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001293
1294 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1296 TEST_EQUAL(A.s, -1);
1297 TEST_EQUAL(A.n, 1);
1298 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001299
1300 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001302
1303 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1304 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001305 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001306
1307 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1308 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001310
1311 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001312 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1313 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1314 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001315
1316 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1318 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1319 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001320
1321 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001322 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1323 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1324 TEST_EQUAL(X.s, -1);
1325 TEST_EQUAL(X.n, 2);
1326 TEST_EQUAL(X.p[0], 0);
1327 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001328
1329 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 mbedtls_mpi_free(&X);
1331 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1332 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1333 TEST_EQUAL(X.s, 1);
1334 TEST_EQUAL(X.n, 1);
1335 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001336
1337 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1339 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1340 TEST_EQUAL(X.s, 1);
1341 TEST_EQUAL(X.n, 1);
1342 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001343
1344 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001345 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1346 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1347 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001348
1349 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1351 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1352 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1353 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001354
1355 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1357 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1358 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1359 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001360
1361 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001362 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1363 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1364 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1365 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001366
1367 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1369 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1370 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1371 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001372
1373 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001374 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1375 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1376 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1377 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001378
1379 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1381 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1382 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1383 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001384
1385 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001386 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1387 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1388 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1389 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001390
1391 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001392 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1393 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001394
1395 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1397 mbedtls_test_rnd_std_rand, NULL),
1398 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001399
1400exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 mbedtls_mpi_free(&A);
1402 mbedtls_mpi_free(&R);
1403 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001404}
1405/* END_CASE */
1406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001408void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001409{
Gilles Peskine449bd832023-01-11 14:50:10 +01001410 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001411}
Paul Bakker33b43f12013-08-20 11:48:36 +02001412/* END_CASE */