blob: f3a64e18374248d74861915fa3d41073b9b63660 [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
Janos Follathfdab7862024-02-22 15:19:13 +0000978 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
979 TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
980 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
981 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000982
Janos Follathfdab7862024-02-22 15:19:13 +0000983 TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
984 TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
Gilles Peskine673461c2024-02-21 16:03:04 +0100985 /* The objective of this test is to check that exp_mod defends
986 * against a smaller RR. */
987 TEST_LE_U(RR.n, N.n - 1);
Janos Follath0512d172024-02-20 14:30:46 +0000988
989 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Gilles Peskine673461c2024-02-21 16:03:04 +0100990 /* We know that exp_mod internally needs RR to be as large as N.
991 * Validate that it is the case now, otherwise there was probably
992 * a buffer overread. */
993 TEST_EQUAL(RR.n, N.n);
994
Janos Follathfdab7862024-02-22 15:19:13 +0000995 TEST_EQUAL(res, exp_result);
Janos Follath0512d172024-02-20 14:30:46 +0000996 if (res == 0) {
Janos Follathfdab7862024-02-22 15:19:13 +0000997 TEST_EQUAL(sign_is_valid(&Z), 1);
998 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000999 }
1000
1001exit:
1002 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1003 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
1004}
1005/* END_CASE */
1006
1007/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001008void mpi_exp_mod(char *input_A, char *input_E,
1009 char *input_N, char *input_X,
1010 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001011{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001013 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001014 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1015 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001016
Gilles Peskine449bd832023-01-11 14:50:10 +01001017 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1018 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1019 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1020 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001021
Gilles Peskine449bd832023-01-11 14:50:10 +01001022 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
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 as an output. */
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);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001035 }
1036
1037 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine449bd832023-01-11 14:50:10 +01001038 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1039 TEST_ASSERT(res == exp_result);
1040 if (res == 0) {
1041 TEST_ASSERT(sign_is_valid(&Z));
1042 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001043 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001044
Paul Bakkerbd51b262014-07-10 15:26:12 +02001045exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001046 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1047 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001048}
Paul Bakker33b43f12013-08-20 11:48:36 +02001049/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001050
Paul Bakker33b43f12013-08-20 11:48:36 +02001051/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001052void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1053 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001054{
1055 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001056 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1057 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001058
Chris Jonesaa850cd2020-12-03 11:35:41 +00001059 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001060 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1061 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1062 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001063
1064 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001065 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1066 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1067 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001068
1069 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001070 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1071 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1072 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001073
Gilles Peskine449bd832023-01-11 14:50:10 +01001074 if (strlen(input_RR)) {
1075 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1076 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001077
Gilles Peskine449bd832023-01-11 14:50:10 +01001078 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001079
1080exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001081 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1082 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001083}
1084/* END_CASE */
1085
1086/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001087void mpi_inv_mod(char *input_X, char *input_Y,
1088 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001089{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001090 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001091 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001092 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001093
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1095 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1096 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1097 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1098 TEST_ASSERT(res == div_result);
1099 if (res == 0) {
1100 TEST_ASSERT(sign_is_valid(&Z));
1101 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001102 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001103
Paul Bakkerbd51b262014-07-10 15:26:12 +02001104exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001105 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001106}
Paul Bakker33b43f12013-08-20 11:48:36 +02001107/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001110void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001111{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001113 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001114 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001115
Gilles Peskine449bd832023-01-11 14:50:10 +01001116 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1117 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1118 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001119
Paul Bakkerbd51b262014-07-10 15:26:12 +02001120exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001121 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001122}
Paul Bakker33b43f12013-08-20 11:48:36 +02001123/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001124
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001126void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1127 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001128{
1129 mbedtls_mpi X;
1130 int res;
1131 mbedtls_test_mpi_random rand;
1132
Gilles Peskine449bd832023-01-11 14:50:10 +01001133 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001134 rand.data = witnesses;
1135 rand.pos = 0;
1136 rand.chunk_len = chunk_len;
1137
Gilles Peskine449bd832023-01-11 14:50:10 +01001138 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1139 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1140 mbedtls_test_mpi_miller_rabin_determinizer,
1141 &rand);
1142 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001143
1144 rand.data = witnesses;
1145 rand.pos = 0;
1146 rand.chunk_len = chunk_len;
1147
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1149 mbedtls_test_mpi_miller_rabin_determinizer,
1150 &rand);
1151 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001152
1153exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001154 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001155}
1156/* END_CASE */
1157
1158/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001159void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001160{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001162 int my_ret;
1163
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001165
Gilles Peskine449bd832023-01-11 14:50:10 +01001166 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1167 mbedtls_test_rnd_std_rand, NULL);
1168 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001169
Gilles Peskine449bd832023-01-11 14:50:10 +01001170 if (ref_ret == 0) {
1171 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001172
Gilles Peskine449bd832023-01-11 14:50:10 +01001173 TEST_ASSERT(actual_bits >= (size_t) bits);
1174 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1175 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001176
Gilles Peskine449bd832023-01-11 14:50:10 +01001177 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1178 mbedtls_test_rnd_std_rand,
1179 NULL) == 0);
1180 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001181 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001182 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1183 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1184 mbedtls_test_rnd_std_rand,
1185 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001186 }
1187 }
1188
Paul Bakkerbd51b262014-07-10 15:26:12 +02001189exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001190 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001191}
1192/* END_CASE */
1193
Paul Bakker33b43f12013-08-20 11:48:36 +02001194/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001195void mpi_shift_l(char *input_X, int shift_X,
1196 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001197{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001199 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001200
Gilles Peskine449bd832023-01-11 14:50:10 +01001201 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1202 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1203 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1204 TEST_ASSERT(sign_is_valid(&X));
1205 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001206
Paul Bakkerbd51b262014-07-10 15:26:12 +02001207exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001208 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001209}
Paul Bakker33b43f12013-08-20 11:48:36 +02001210/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001211
Paul Bakker33b43f12013-08-20 11:48:36 +02001212/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001213void mpi_shift_r(char *input_X, int shift_X,
1214 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001215{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001217 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1220 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1221 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1222 TEST_ASSERT(sign_is_valid(&X));
1223 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001224
Paul Bakkerbd51b262014-07-10 15:26:12 +02001225exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001226 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001227}
Paul Bakker33b43f12013-08-20 11:48:36 +02001228/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001229
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001230/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001231void mpi_fill_random(int wanted_bytes, int rng_bytes,
1232 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001233{
1234 mbedtls_mpi X;
1235 int ret;
1236 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001238
Gilles Peskine449bd832023-01-11 14:50:10 +01001239 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001240 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001241 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1242 if (before < 0) {
1243 before = -before;
1244 }
1245 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001246 }
1247
Gilles Peskine449bd832023-01-11 14:50:10 +01001248 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1249 f_rng_bytes_left, &bytes_left);
1250 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001251
Gilles Peskine449bd832023-01-11 14:50:10 +01001252 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001253 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1254 * as a big-endian representation of the number. We know when
1255 * our RNG function returns null bytes, so we know how many
1256 * leading zero bytes the number has. */
1257 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001258 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001259 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 }
1261 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1262 (size_t) wanted_bytes);
1263 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1264 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001265 }
1266
1267exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001268 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001269}
1270/* END_CASE */
1271
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001272/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001273void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001274{
1275 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1276 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1277 * is a valid value. However, negating it (`-n`) has undefined behavior
1278 * (although in practice `-n` evaluates to the value n).
1279 *
1280 * This function has ad hoc tests for this value. It's separated from other
1281 * functions because the test framework makes it hard to pass this value
1282 * into test cases.
1283 *
1284 * In the comments here:
1285 * - biL = number of bits in limbs
1286 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1287 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1288 */
1289
1290 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 mbedtls_mpi_init(&A);
1292 mbedtls_mpi_init(&R);
1293 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001296 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001297 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1298 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1299 (mbedtls_mpi_uint) 1 << (biL - 1));
1300 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001301
1302 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1304 TEST_EQUAL(A.s, -1);
1305 TEST_EQUAL(A.n, 1);
1306 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001307
1308 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001309 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001310
1311 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1312 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001314
1315 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1316 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001317 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001318
1319 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001320 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1321 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1322 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001323
1324 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001325 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1326 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1327 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001328
1329 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001330 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1331 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1332 TEST_EQUAL(X.s, -1);
1333 TEST_EQUAL(X.n, 2);
1334 TEST_EQUAL(X.p[0], 0);
1335 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001336
1337 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 mbedtls_mpi_free(&X);
1339 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1340 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1341 TEST_EQUAL(X.s, 1);
1342 TEST_EQUAL(X.n, 1);
1343 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001344
1345 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1347 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1348 TEST_EQUAL(X.s, 1);
1349 TEST_EQUAL(X.n, 1);
1350 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001351
1352 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001353 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1354 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1355 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001356
1357 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1359 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1360 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1361 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001362
1363 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1365 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1366 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1367 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001368
1369 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001370 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1371 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1372 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1373 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001374
1375 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001376 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1377 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1378 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1379 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001380
1381 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001382 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1383 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1384 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1385 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001386
1387 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001388 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1389 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1390 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1391 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001392
1393 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001394 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1395 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1396 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1397 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001398
1399 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001400 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1401 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001402
1403 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001404 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1405 mbedtls_test_rnd_std_rand, NULL),
1406 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001407
1408exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001409 mbedtls_mpi_free(&A);
1410 mbedtls_mpi_free(&R);
1411 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001412}
1413/* END_CASE */
1414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001416void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001417{
Gilles Peskine449bd832023-01-11 14:50:10 +01001418 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001419}
Paul Bakker33b43f12013-08-20 11:48:36 +02001420/* END_CASE */