blob: a65a4897b57ac357cc7624d38c73b73796f616c5 [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 Follath64eca052018-09-05 17:04:49 +01004
Chris Jonese64a46f2020-12-03 17:44:03 +00005#if MBEDTLS_MPI_MAX_BITS > 792
6#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +00007#endif
Janos Follath64eca052018-09-05 17:04:49 +01008
Gilles Peskineb53b2182021-06-10 15:34:15 +02009/* Check the validity of the sign bit in an MPI object. Reject representations
10 * that are not supported by the rest of the library and indicate a bug when
11 * constructing the value. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010012static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskineb53b2182021-06-10 15:34:15 +020013{
Gilles Peskine53a72062022-11-09 21:08:44 +010014 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010015 if (X->s != 1 && X->s != -1) {
16 return 0;
17 }
Gilles Peskine53a72062022-11-09 21:08:44 +010018
19 /* The value 0 must be represented with the sign +1. A "negative zero"
20 * with s=-1 is an invalid representation. Forbid that. As an exception,
21 * we sometimes test the robustness of library functions when given
22 * a negative zero input. If a test case has a negative zero as input,
23 * we don't mind if the function has a negative zero output. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010024 if (!mbedtls_test_case_uses_negative_0 &&
25 mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
26 return 0;
Gilles Peskine53a72062022-11-09 21:08:44 +010027 }
28
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010029 return 1;
Gilles Peskineb53b2182021-06-10 15:34:15 +020030}
31
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010032typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010033 data_t *data;
34 size_t pos;
35 size_t chunk_len;
36} mbedtls_test_mpi_random;
37
38/*
39 * This function is called by the Miller-Rabin primality test each time it
40 * chooses a random witness. The witnesses (or non-witnesses as provided by the
41 * test) are stored in the data member of the state structure. Each number is in
42 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
43 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010044int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
45 unsigned char *buf,
46 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010047{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010048 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010049
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010050 if (random == NULL || random->data->x == NULL || buf == NULL) {
51 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010052 }
53
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010054 if (random->pos + random->chunk_len > random->data->len
55 || random->chunk_len > len) {
56 return -1;
57 }
58
59 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010060
61 /* The witness is written to the end of the buffer, since the buffer is
62 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
63 * Writing the witness to the start of the buffer would result in the
64 * buffer being 'witness 000...000', which would be treated as
65 * witness * 2^n for some n. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010066 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
67 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010068
69 random->pos += random->chunk_len;
70
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010071 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010072}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010073
74/* Random generator that is told how many bytes to return. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010075static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010076{
77 size_t *bytes_left = state;
78 size_t i;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010079 for (i = 0; i < len; i++) {
80 if (*bytes_left == 0) {
81 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
82 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010083 buf[i] = *bytes_left & 0xff;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010084 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010085 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +010086 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010087}
88
Gilles Peskine3b056152021-04-13 19:50:04 +020089/* Test whether bytes represents (in big-endian base 256) a number b that
90 * is significantly above a power of 2. That is, b must not have a long run
91 * of unset bits after the most significant bit.
92 *
93 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
94 * This function returns 1 if, when drawing a number between 0 and b,
95 * the probability that this number is at least 2^n is not negligible.
96 * This probability is (b - 2^n) / b and this function checks that this
97 * number is above some threshold A. The threshold value is heuristic and
98 * based on the needs of mpi_random_many().
Gilles Peskine4699fa42021-03-29 22:02:55 +020099 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100100static int is_significantly_above_a_power_of_2(data_t *bytes)
Gilles Peskine4699fa42021-03-29 22:02:55 +0200101{
102 const uint8_t *p = bytes->x;
103 size_t len = bytes->len;
104 unsigned x;
Gilles Peskine3b056152021-04-13 19:50:04 +0200105
106 /* Skip leading null bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100107 while (len > 0 && p[0] == 0) {
Gilles Peskine4699fa42021-03-29 22:02:55 +0200108 ++p;
109 --len;
110 }
Gilles Peskine3b056152021-04-13 19:50:04 +0200111 /* 0 is not significantly above a power of 2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100112 if (len == 0) {
113 return 0;
114 }
Gilles Peskine3b056152021-04-13 19:50:04 +0200115 /* Extract the (up to) 2 most significant bytes */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100116 if (len == 1) {
Gilles Peskine4699fa42021-03-29 22:02:55 +0200117 x = p[0];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100118 } else {
119 x = (p[0] << 8) | p[1];
120 }
Gilles Peskine4699fa42021-03-29 22:02:55 +0200121
Gilles Peskine3b056152021-04-13 19:50:04 +0200122 /* Shift the most significant bit of x to position 8 and mask it out */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100123 while ((x & 0xfe00) != 0) {
Gilles Peskine3b056152021-04-13 19:50:04 +0200124 x >>= 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100125 }
Gilles Peskine3b056152021-04-13 19:50:04 +0200126 x &= 0x00ff;
Gilles Peskine4699fa42021-03-29 22:02:55 +0200127
Gilles Peskine3b056152021-04-13 19:50:04 +0200128 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
129 * a power of 2 iff x is significantly above 0 compared to 2^8.
130 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
131 * description above. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100132 return x >= 0x10;
Gilles Peskine4699fa42021-03-29 22:02:55 +0200133}
134
Paul Bakker33b43f12013-08-20 11:48:36 +0200135/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000136
Paul Bakker33b43f12013-08-20 11:48:36 +0200137/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200138 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200139 * END_DEPENDENCIES
140 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000141
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000142/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100143void mpi_valid_param()
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000144{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100145 TEST_VALID_PARAM(mbedtls_mpi_free(NULL));
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000146}
147/* END_CASE */
148
Hanno Beckerafb607b2018-12-11 14:27:08 +0000149/* BEGIN_CASE depends_on:MBEDTLS_CHECK_PARAMS:!MBEDTLS_PARAM_FAILED_ALT */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100150void mpi_invalid_param()
Hanno Beckerafb607b2018-12-11 14:27:08 +0000151{
152 mbedtls_mpi X;
153 const char *s_in = "00101000101010";
154 char s_out[16] = { 0 };
155 unsigned char u_out[16] = { 0 };
156 unsigned char u_in[16] = { 0 };
157 size_t olen;
158 mbedtls_mpi_uint mpi_uint;
159
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100160 TEST_INVALID_PARAM(mbedtls_mpi_init(NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000161
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100162 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
163 mbedtls_mpi_grow(NULL, 42));
164 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
165 mbedtls_mpi_copy(NULL, &X));
166 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
167 mbedtls_mpi_copy(&X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000168
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100169 TEST_INVALID_PARAM(mbedtls_mpi_swap(NULL, &X));
170 TEST_INVALID_PARAM(mbedtls_mpi_swap(&X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000171
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100172 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
173 mbedtls_mpi_safe_cond_assign(NULL, &X, 0));
174 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
175 mbedtls_mpi_safe_cond_assign(&X, NULL, 0));
Hanno Beckere1185042018-12-13 14:31:46 +0000176
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100177 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
178 mbedtls_mpi_safe_cond_swap(NULL, &X, 0));
179 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
180 mbedtls_mpi_safe_cond_swap(&X, NULL, 0));
Hanno Beckere1185042018-12-13 14:31:46 +0000181
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100182 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
183 mbedtls_mpi_lset(NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000184
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100185 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
186 mbedtls_mpi_get_bit(NULL, 42));
187 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
188 mbedtls_mpi_set_bit(NULL, 42, 0));
Hanno Beckere1185042018-12-13 14:31:46 +0000189
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100190 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
191 mbedtls_mpi_read_string(NULL, 2, s_in));
192 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
193 mbedtls_mpi_read_string(&X, 2, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100195 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
196 mbedtls_mpi_write_string(NULL, 2,
197 s_out, sizeof(s_out),
198 &olen));
199 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
200 mbedtls_mpi_write_string(&X, 2,
201 NULL, sizeof(s_out),
202 &olen));
203 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
204 mbedtls_mpi_write_string(&X, 2,
205 s_out, sizeof(s_out),
206 NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000207
Hanno Beckerafb607b2018-12-11 14:27:08 +0000208#if defined(MBEDTLS_FS_IO)
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100209 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
210 mbedtls_mpi_read_file(NULL, 2, stdin));
211 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
212 mbedtls_mpi_read_file(&X, 2, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000213
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100214 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
215 mbedtls_mpi_write_file("", NULL, 2, NULL));
Hanno Beckerafb607b2018-12-11 14:27:08 +0000216#endif /* MBEDTLS_FS_IO */
217
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100218 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
219 mbedtls_mpi_read_binary(NULL, u_in,
220 sizeof(u_in)));
221 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
222 mbedtls_mpi_read_binary(&X, NULL,
223 sizeof(u_in)));
Hanno Beckere1185042018-12-13 14:31:46 +0000224
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100225 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
226 mbedtls_mpi_write_binary(NULL, u_out,
227 sizeof(u_out)));
228 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
229 mbedtls_mpi_write_binary(&X, NULL,
230 sizeof(u_out)));
Hanno Beckere1185042018-12-13 14:31:46 +0000231
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100232 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
233 mbedtls_mpi_shift_l(NULL, 42));
234 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
235 mbedtls_mpi_shift_r(NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000236
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100237 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
238 mbedtls_mpi_cmp_abs(NULL, &X));
239 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
240 mbedtls_mpi_cmp_abs(&X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000241
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100242 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
243 mbedtls_mpi_cmp_mpi(NULL, &X));
244 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
245 mbedtls_mpi_cmp_mpi(&X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000246
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100247 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
248 mbedtls_mpi_cmp_int(NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000249
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100250 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
251 mbedtls_mpi_add_abs(NULL, &X, &X));
252 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
253 mbedtls_mpi_add_abs(&X, NULL, &X));
254 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
255 mbedtls_mpi_add_abs(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000256
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100257 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
258 mbedtls_mpi_sub_abs(NULL, &X, &X));
259 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
260 mbedtls_mpi_sub_abs(&X, NULL, &X));
261 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
262 mbedtls_mpi_sub_abs(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000263
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100264 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
265 mbedtls_mpi_add_mpi(NULL, &X, &X));
266 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
267 mbedtls_mpi_add_mpi(&X, NULL, &X));
268 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
269 mbedtls_mpi_add_mpi(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000270
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100271 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
272 mbedtls_mpi_sub_mpi(NULL, &X, &X));
273 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
274 mbedtls_mpi_sub_mpi(&X, NULL, &X));
275 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
276 mbedtls_mpi_sub_mpi(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000277
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100278 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
279 mbedtls_mpi_add_int(NULL, &X, 42));
280 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
281 mbedtls_mpi_add_int(&X, NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000282
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100283 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
284 mbedtls_mpi_sub_int(NULL, &X, 42));
285 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
286 mbedtls_mpi_sub_int(&X, NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000287
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100288 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
289 mbedtls_mpi_mul_mpi(NULL, &X, &X));
290 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
291 mbedtls_mpi_mul_mpi(&X, NULL, &X));
292 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
293 mbedtls_mpi_mul_mpi(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000294
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100295 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
296 mbedtls_mpi_mul_int(NULL, &X, 42));
297 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
298 mbedtls_mpi_mul_int(&X, NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000299
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100300 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
301 mbedtls_mpi_div_mpi(&X, &X, NULL, &X));
302 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
303 mbedtls_mpi_div_mpi(&X, &X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000304
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100305 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
306 mbedtls_mpi_div_int(&X, &X, NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000307
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100308 TEST_INVALID_PARAM_RET(0, mbedtls_mpi_lsb(NULL));
Hanno Beckerf25ee7f2018-12-19 16:51:02 +0000309
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100310 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
311 mbedtls_mpi_mod_mpi(NULL, &X, &X));
312 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
313 mbedtls_mpi_mod_mpi(&X, NULL, &X));
314 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
315 mbedtls_mpi_mod_mpi(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000316
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100317 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
318 mbedtls_mpi_mod_int(NULL, &X, 42));
319 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
320 mbedtls_mpi_mod_int(&mpi_uint, NULL, 42));
Hanno Beckere1185042018-12-13 14:31:46 +0000321
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100322 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
323 mbedtls_mpi_exp_mod(NULL, &X, &X, &X, NULL));
324 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
325 mbedtls_mpi_exp_mod(&X, NULL, &X, &X, NULL));
326 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
327 mbedtls_mpi_exp_mod(&X, &X, NULL, &X, NULL));
328 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
329 mbedtls_mpi_exp_mod(&X, &X, &X, NULL, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000330
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100331 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
332 mbedtls_mpi_fill_random(NULL, 42,
333 mbedtls_test_rnd_std_rand,
334 NULL));
335 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
336 mbedtls_mpi_fill_random(&X, 42, NULL, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000337
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100338 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
339 mbedtls_mpi_gcd(NULL, &X, &X));
340 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
341 mbedtls_mpi_gcd(&X, NULL, &X));
342 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
343 mbedtls_mpi_gcd(&X, &X, NULL));
Hanno Beckere1185042018-12-13 14:31:46 +0000344
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100345 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
346 mbedtls_mpi_inv_mod(NULL, &X, &X));
347 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
348 mbedtls_mpi_inv_mod(&X, NULL, &X));
349 TEST_INVALID_PARAM_RET(MBEDTLS_ERR_MPI_BAD_INPUT_DATA,
350 mbedtls_mpi_inv_mod(&X, &X, NULL));
Hanno Beckerafb607b2018-12-11 14:27:08 +0000351
352exit:
353 return;
Hanno Beckerafb607b2018-12-11 14:27:08 +0000354}
355/* END_CASE */
356
Paul Bakker33b43f12013-08-20 11:48:36 +0200357/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100358void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200359{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200360 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200361
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100362 mbedtls_mpi_init(&X);
363 mbedtls_mpi_init(&Y);
364 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200365
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100366 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
367 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
368 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
369 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200370
371exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100372 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200373}
374/* END_CASE */
375
376/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100377void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
378 char *input_A, int output_size, int result_read,
379 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000380{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000382 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100383 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000384
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100385 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000386
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100387 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000388
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100389 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
390 if (result_read == 0) {
391 TEST_ASSERT(sign_is_valid(&X));
392 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
393 if (result_write == 0) {
Gilles Peskinef549d9c2022-12-04 13:29:20 +0100394 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100395 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000396 }
397 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000398
Paul Bakkerbd51b262014-07-10 15:26:12 +0200399exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100400 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000401}
Paul Bakker33b43f12013-08-20 11:48:36 +0200402/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000403
Paul Bakker33b43f12013-08-20 11:48:36 +0200404/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200405void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000406{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000408 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100409 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000410
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100411 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000412
Paul Bakkere896fea2009-07-06 06:40:23 +0000413
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100414 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
415 TEST_ASSERT(sign_is_valid(&X));
416 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
417 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000418
Paul Bakkerbd51b262014-07-10 15:26:12 +0200419exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100420 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000421}
Paul Bakker33b43f12013-08-20 11:48:36 +0200422/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000423
Paul Bakker33b43f12013-08-20 11:48:36 +0200424/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200425void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000426{
427 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000428 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000429 size_t len;
430
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100431 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000432
433
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100434 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
435 TEST_ASSERT(sign_is_valid(&X));
436 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
437 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000438
439exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100440 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000441}
442/* END_CASE */
443
444/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200445void mpi_write_binary(char *input_X, data_t *input_A,
446 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000447{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000449 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000450 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000451
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100452 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000453
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100454 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000455
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100456 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100457
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100458 buflen = mbedtls_mpi_size(&X);
459 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200460 buflen = (size_t) output_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100461 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000462
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100463 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
464 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000465
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100466 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
467 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000468 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000469
Paul Bakkerbd51b262014-07-10 15:26:12 +0200470exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100471 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000472}
Paul Bakker33b43f12013-08-20 11:48:36 +0200473/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000474
Janos Follathe344d0f2019-02-19 16:17:40 +0000475/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200476void mpi_write_binary_le(char *input_X, data_t *input_A,
477 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000478{
479 mbedtls_mpi X;
480 unsigned char buf[1000];
481 size_t buflen;
482
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100483 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000484
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100485 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000486
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100487 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000488
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100489 buflen = mbedtls_mpi_size(&X);
490 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000491 buflen = (size_t) output_size;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100492 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000493
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100494 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
495 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000496
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100497 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
498 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000499 }
500
501exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100502 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000503}
504/* END_CASE */
505
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine366e6852023-04-26 22:43:54 +0200507void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000508{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000510 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000511 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000512 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000513 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000514
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100515 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100517 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000518
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100519 file = fopen(input_file, "r");
520 TEST_ASSERT(file != NULL);
521 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000522 fclose(file);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100523 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000524
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100525 if (result == 0) {
526 TEST_ASSERT(sign_is_valid(&X));
527 buflen = mbedtls_mpi_size(&X);
528 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000529
Paul Bakkere896fea2009-07-06 06:40:23 +0000530
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100531 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
532 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000533 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000534
Paul Bakkerbd51b262014-07-10 15:26:12 +0200535exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100536 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000537}
Paul Bakker33b43f12013-08-20 11:48:36 +0200538/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000539
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine366e6852023-04-26 22:43:54 +0200541void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000542{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000544 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200545 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000546
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100547 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000548
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100549 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000550
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100551 file_out = fopen(output_file, "w");
552 TEST_ASSERT(file_out != NULL);
553 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000554 fclose(file_out);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100555 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000556
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100557 file_in = fopen(output_file, "r");
558 TEST_ASSERT(file_in != NULL);
559 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000560 fclose(file_in);
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100561 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000562
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100563 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000564
Paul Bakkerbd51b262014-07-10 15:26:12 +0200565exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100566 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000567}
Paul Bakker33b43f12013-08-20 11:48:36 +0200568/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000569
Paul Bakker33b43f12013-08-20 11:48:36 +0200570/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200571void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000572{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 mbedtls_mpi X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100574 mbedtls_mpi_init(&X);
575 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
576 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000577
Paul Bakkerbd51b262014-07-10 15:26:12 +0200578exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100579 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000580}
Paul Bakker33b43f12013-08-20 11:48:36 +0200581/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000582
Paul Bakker33b43f12013-08-20 11:48:36 +0200583/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200584void mpi_set_bit(char *input_X, int pos, int val,
585 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000586{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_mpi X, Y;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100588 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000589
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100590 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
591 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
592 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100593
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100594 if (result == 0) {
595 TEST_ASSERT(sign_is_valid(&X));
596 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100597 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000598
Paul Bakkerbd51b262014-07-10 15:26:12 +0200599exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100600 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000601}
Paul Bakker33b43f12013-08-20 11:48:36 +0200602/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000603
Paul Bakker33b43f12013-08-20 11:48:36 +0200604/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200605void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000606{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_mpi X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100608 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000609
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100610 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
611 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000612
Paul Bakkerbd51b262014-07-10 15:26:12 +0200613exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100614 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000615}
Paul Bakker33b43f12013-08-20 11:48:36 +0200616/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000617
Paul Bakker33b43f12013-08-20 11:48:36 +0200618/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200619void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000620{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_mpi X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100622 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000623
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100624 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
625 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000626
Paul Bakkerbd51b262014-07-10 15:26:12 +0200627exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100628 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000629}
Paul Bakker33b43f12013-08-20 11:48:36 +0200630/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000631
Paul Bakker33b43f12013-08-20 11:48:36 +0200632/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200633void mpi_gcd(char *input_X, char *input_Y,
634 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000635{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_mpi A, X, Y, Z;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100637 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000638
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100639 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
640 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
641 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
642 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
643 TEST_ASSERT(sign_is_valid(&Z));
644 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000645
Paul Bakkerbd51b262014-07-10 15:26:12 +0200646exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100647 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000648}
Paul Bakker33b43f12013-08-20 11:48:36 +0200649/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000650
Paul Bakker33b43f12013-08-20 11:48:36 +0200651/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200652void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000653{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 mbedtls_mpi X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100655 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000656
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100657 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
658 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000659
Paul Bakkerbd51b262014-07-10 15:26:12 +0200660exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100661 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000662}
Paul Bakker33b43f12013-08-20 11:48:36 +0200663/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000664
Paul Bakker33b43f12013-08-20 11:48:36 +0200665/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200666void mpi_cmp_mpi(char *input_X, char *input_Y,
667 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000668{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_mpi X, Y;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100670 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000671
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100672 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
673 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
674 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000675
Paul Bakkerbd51b262014-07-10 15:26:12 +0200676exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100677 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000678}
Paul Bakker33b43f12013-08-20 11:48:36 +0200679/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000680
Paul Bakker33b43f12013-08-20 11:48:36 +0200681/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200682void mpi_lt_mpi_ct(int size_X, char *input_X,
683 int size_Y, char *input_Y,
684 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100685{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200686 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100687 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100688 mbedtls_mpi X, Y;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100689 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100690
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100691 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
692 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100693
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100694 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
695 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100696
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100697 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
698 if (input_err == 0) {
699 TEST_ASSERT(ret == input_uret);
700 }
Janos Follath385d5b82019-09-11 16:07:14 +0100701
702exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100703 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100704}
705/* END_CASE */
706
707/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200708void mpi_cmp_abs(char *input_X, char *input_Y,
709 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000710{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 mbedtls_mpi X, Y;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100712 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000713
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100714 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
715 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
716 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000717
Paul Bakkerbd51b262014-07-10 15:26:12 +0200718exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100719 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000720}
Paul Bakker33b43f12013-08-20 11:48:36 +0200721/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000722
Paul Bakker33b43f12013-08-20 11:48:36 +0200723/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200724void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000725{
Gilles Peskine50231672021-06-10 23:00:33 +0200726 mbedtls_mpi src, dst, ref;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100727 mbedtls_mpi_init(&src);
728 mbedtls_mpi_init(&dst);
729 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000730
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100731 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
732 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskine50231672021-06-10 23:00:33 +0200733
734 /* mbedtls_mpi_copy() */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100735 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
736 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
737 TEST_ASSERT(sign_is_valid(&dst));
738 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000739
Gilles Peskine50231672021-06-10 23:00:33 +0200740 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100741 mbedtls_mpi_free(&dst);
742 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
743 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
744 TEST_ASSERT(sign_is_valid(&dst));
745 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskine50231672021-06-10 23:00:33 +0200746
747 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100748 mbedtls_mpi_free(&dst);
749 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
750 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
751 TEST_ASSERT(sign_is_valid(&dst));
752 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskine50231672021-06-10 23:00:33 +0200753
Paul Bakkerbd51b262014-07-10 15:26:12 +0200754exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100755 mbedtls_mpi_free(&src);
756 mbedtls_mpi_free(&dst);
757 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100758}
759/* END_CASE */
760
761/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100762void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100763{
Gilles Peskine77f55c92021-06-10 15:17:30 +0200764 mbedtls_mpi X, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100765 mbedtls_mpi_init(&A);
766 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000767
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100768 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
769 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine77f55c92021-06-10 15:17:30 +0200770
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100771 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
772 TEST_ASSERT(sign_is_valid(&X));
773 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000774
Paul Bakkerbd51b262014-07-10 15:26:12 +0200775exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100776 mbedtls_mpi_free(&A);
777 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000778}
Paul Bakker33b43f12013-08-20 11:48:36 +0200779/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000780
Paul Bakker33b43f12013-08-20 11:48:36 +0200781/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200782void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskined382c282021-06-10 22:29:57 +0200783{
784 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100785 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
786 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskined382c282021-06-10 22:29:57 +0200787
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100788 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
789 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskined382c282021-06-10 22:29:57 +0200790
Gilles Peskine50231672021-06-10 23:00:33 +0200791 /* mbedtls_mpi_swap() */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100792 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
793 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
794 mbedtls_mpi_swap(&X, &Y);
795 TEST_ASSERT(sign_is_valid(&X));
796 TEST_ASSERT(sign_is_valid(&Y));
797 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
798 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined382c282021-06-10 22:29:57 +0200799
Gilles Peskine50231672021-06-10 23:00:33 +0200800 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100801 mbedtls_mpi_free(&X);
802 mbedtls_mpi_free(&Y);
803 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
804 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
805 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
806 TEST_ASSERT(sign_is_valid(&X));
807 TEST_ASSERT(sign_is_valid(&Y));
808 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
809 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskine50231672021-06-10 23:00:33 +0200810
811 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100812 mbedtls_mpi_free(&X);
813 mbedtls_mpi_free(&Y);
814 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
815 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
816 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
817 TEST_ASSERT(sign_is_valid(&X));
818 TEST_ASSERT(sign_is_valid(&Y));
819 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
820 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskine50231672021-06-10 23:00:33 +0200821
Gilles Peskined382c282021-06-10 22:29:57 +0200822exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100823 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
824 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskined382c282021-06-10 22:29:57 +0200825}
826/* END_CASE */
827
828/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100829void mpi_swap_self(char *X_hex)
Gilles Peskined382c282021-06-10 22:29:57 +0200830{
831 mbedtls_mpi X, X0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100832 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskined382c282021-06-10 22:29:57 +0200833
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100834 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
835 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskined382c282021-06-10 22:29:57 +0200836
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100837 mbedtls_mpi_swap(&X, &X);
838 TEST_ASSERT(sign_is_valid(&X));
839 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskined382c282021-06-10 22:29:57 +0200840
841exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100842 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskined382c282021-06-10 22:29:57 +0200843}
844/* END_CASE */
845
846/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200847void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100848{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_mpi X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100850 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100851
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100852 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
853 if (used > 0) {
854 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
855 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskine399c8fa2021-06-15 21:19:18 +0200856 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100857 TEST_EQUAL(X.n, (size_t) before);
858 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
859 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100860
Paul Bakkerbd51b262014-07-10 15:26:12 +0200861exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100862 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100863}
864/* END_CASE */
865
866/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200867void mpi_add_mpi(char *input_X, char *input_Y,
868 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000869{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_mpi X, Y, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100871 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000872
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100873 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
874 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
875 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
876 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
877 TEST_ASSERT(sign_is_valid(&Z));
878 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000879
Gilles Peskine56f943a2020-07-23 01:18:11 +0200880 /* result == first operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100881 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
882 TEST_ASSERT(sign_is_valid(&X));
883 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
884 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200885
886 /* result == second operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100887 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
888 TEST_ASSERT(sign_is_valid(&Y));
889 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200890
Paul Bakkerbd51b262014-07-10 15:26:12 +0200891exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100892 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000893}
Paul Bakker33b43f12013-08-20 11:48:36 +0200894/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000895
Paul Bakker33b43f12013-08-20 11:48:36 +0200896/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200897void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100898{
899 mbedtls_mpi X, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100900 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100901
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100902 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100903
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100904 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
905 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
906 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
907 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100908
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100909 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
910 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
911 TEST_ASSERT(sign_is_valid(&X));
912 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100913
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100914 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
915 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
916 TEST_ASSERT(sign_is_valid(&X));
917 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100918
919exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100920 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100921}
922/* END_CASE */
923
924
925/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200926void mpi_add_abs(char *input_X, char *input_Y,
927 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000928{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 mbedtls_mpi X, Y, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100930 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000931
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100932 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
933 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
934 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
935 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
936 TEST_ASSERT(sign_is_valid(&Z));
937 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000938
Gilles Peskine56f943a2020-07-23 01:18:11 +0200939 /* result == first operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100940 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
941 TEST_ASSERT(sign_is_valid(&X));
942 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
943 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200944
945 /* result == second operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100946 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
947 TEST_ASSERT(sign_is_valid(&Y));
948 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000949
Paul Bakkerbd51b262014-07-10 15:26:12 +0200950exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100951 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000952}
Paul Bakker33b43f12013-08-20 11:48:36 +0200953/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000954
Paul Bakker33b43f12013-08-20 11:48:36 +0200955/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200956void mpi_add_int(char *input_X, int input_Y,
957 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000958{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 mbedtls_mpi X, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100960 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000961
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100962 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
963 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
964 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
965 TEST_ASSERT(sign_is_valid(&Z));
966 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000967
Paul Bakkerbd51b262014-07-10 15:26:12 +0200968exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100969 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000970}
Paul Bakker33b43f12013-08-20 11:48:36 +0200971/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000972
Paul Bakker33b43f12013-08-20 11:48:36 +0200973/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +0200974void mpi_sub_mpi(char *input_X, char *input_Y,
975 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000976{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_mpi X, Y, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100978 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000979
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100980 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
981 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
982 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
983 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
984 TEST_ASSERT(sign_is_valid(&Z));
985 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000986
Gilles Peskine56f943a2020-07-23 01:18:11 +0200987 /* result == first operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100988 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
989 TEST_ASSERT(sign_is_valid(&X));
990 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
991 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200992
993 /* result == second operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100994 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
995 TEST_ASSERT(sign_is_valid(&Y));
996 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200997
Paul Bakkerbd51b262014-07-10 15:26:12 +0200998exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +0100999 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001000}
Paul Bakker33b43f12013-08-20 11:48:36 +02001001/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001002
Paul Bakker33b43f12013-08-20 11:48:36 +02001003/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001004void mpi_sub_abs(char *input_X, char *input_Y,
1005 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001006{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001008 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001009 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001010
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001011 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1012 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1013 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001014
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001015 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
1016 TEST_ASSERT(res == sub_result);
1017 TEST_ASSERT(sign_is_valid(&Z));
1018 if (res == 0) {
1019 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
1020 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001021
Gilles Peskine56f943a2020-07-23 01:18:11 +02001022 /* result == first operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001023 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
1024 TEST_ASSERT(sign_is_valid(&X));
1025 if (sub_result == 0) {
1026 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
1027 }
1028 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +02001029
1030 /* result == second operand */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001031 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
1032 TEST_ASSERT(sign_is_valid(&Y));
1033 if (sub_result == 0) {
1034 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
1035 }
Gilles Peskine56f943a2020-07-23 01:18:11 +02001036
Paul Bakkerbd51b262014-07-10 15:26:12 +02001037exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001038 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001039}
Paul Bakker33b43f12013-08-20 11:48:36 +02001040/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001041
Paul Bakker33b43f12013-08-20 11:48:36 +02001042/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001043void mpi_sub_int(char *input_X, int input_Y,
1044 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001045{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 mbedtls_mpi X, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001047 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001048
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001049 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1050 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1051 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
1052 TEST_ASSERT(sign_is_valid(&Z));
1053 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001054
Paul Bakkerbd51b262014-07-10 15:26:12 +02001055exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001056 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001057}
Paul Bakker33b43f12013-08-20 11:48:36 +02001058/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001059
Paul Bakker33b43f12013-08-20 11:48:36 +02001060/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001061void mpi_mul_mpi(char *input_X, char *input_Y,
1062 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001063{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 mbedtls_mpi X, Y, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001065 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001066
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001067 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1068 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1069 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1070 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
1071 TEST_ASSERT(sign_is_valid(&Z));
1072 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001073
Paul Bakkerbd51b262014-07-10 15:26:12 +02001074exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001075 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001076}
Paul Bakker33b43f12013-08-20 11:48:36 +02001077/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001078
Paul Bakker33b43f12013-08-20 11:48:36 +02001079/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001080void mpi_mul_int(char *input_X, int input_Y,
1081 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +00001082{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 mbedtls_mpi X, Z, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001084 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001085
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001086 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1087 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1088 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
1089 TEST_ASSERT(sign_is_valid(&Z));
1090 if (strcmp(result_comparison, "==") == 0) {
1091 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
1092 } else if (strcmp(result_comparison, "!=") == 0) {
1093 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
1094 } else {
1095 TEST_ASSERT("unknown operator" == 0);
1096 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001097
Paul Bakkerbd51b262014-07-10 15:26:12 +02001098exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001099 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001100}
Paul Bakker33b43f12013-08-20 11:48:36 +02001101/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001102
Paul Bakker33b43f12013-08-20 11:48:36 +02001103/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001104void mpi_div_mpi(char *input_X, char *input_Y,
1105 char *input_A, char *input_B,
1106 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001107{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001109 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001110 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
1111 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001112
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001113 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1114 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1115 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1116 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
1117 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
1118 TEST_ASSERT(res == div_result);
1119 if (res == 0) {
1120 TEST_ASSERT(sign_is_valid(&Q));
1121 TEST_ASSERT(sign_is_valid(&R));
1122 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
1123 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001124 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001125
Paul Bakkerbd51b262014-07-10 15:26:12 +02001126exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001127 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
1128 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001129}
Paul Bakker33b43f12013-08-20 11:48:36 +02001130/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001131
Paul Bakker33b43f12013-08-20 11:48:36 +02001132/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001133void mpi_div_int(char *input_X, int input_Y,
1134 char *input_A, char *input_B,
1135 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001136{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001138 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001139 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
1140 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001141
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001142 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1143 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1144 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
1145 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
1146 TEST_ASSERT(res == div_result);
1147 if (res == 0) {
1148 TEST_ASSERT(sign_is_valid(&Q));
1149 TEST_ASSERT(sign_is_valid(&R));
1150 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
1151 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001152 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001153
Paul Bakkerbd51b262014-07-10 15:26:12 +02001154exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001155 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
1156 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001157}
Paul Bakker33b43f12013-08-20 11:48:36 +02001158/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001159
Paul Bakker33b43f12013-08-20 11:48:36 +02001160/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001161void mpi_mod_mpi(char *input_X, char *input_Y,
1162 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001163{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001165 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001166 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001167
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001168 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1169 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1170 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1171 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
1172 TEST_ASSERT(res == div_result);
1173 if (res == 0) {
1174 TEST_ASSERT(sign_is_valid(&X));
1175 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001176 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001177
Paul Bakkerbd51b262014-07-10 15:26:12 +02001178exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001179 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001180}
Paul Bakker33b43f12013-08-20 11:48:36 +02001181/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001182
Paul Bakker33b43f12013-08-20 11:48:36 +02001183/* BEGIN_CASE */
Gilles Peskinef599ddf2022-12-04 15:58:48 +01001184void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
1185 mbedtls_mpi_sint a, int mod_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001188 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 mbedtls_mpi_uint r;
Paul Bakker367dae42009-06-28 21:50:27 +00001190
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001191 mbedtls_mpi_init(&X);
Tom Cosgrovec2c6fcb2022-11-09 12:59:33 +00001192
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001193 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrovec2c6fcb2022-11-09 12:59:33 +00001194
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001195 res = mbedtls_mpi_mod_int(&r, &X, y);
1196 TEST_EQUAL(res, mod_result);
1197 if (res == 0) {
1198 TEST_EQUAL(r, a);
Paul Bakker367dae42009-06-28 21:50:27 +00001199 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001200
Paul Bakkerbd51b262014-07-10 15:26:12 +02001201exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001202 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001203}
Paul Bakker33b43f12013-08-20 11:48:36 +02001204/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001205
Paul Bakker33b43f12013-08-20 11:48:36 +02001206/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001207void mpi_exp_mod(char *input_A, char *input_E,
1208 char *input_N, char *input_X,
1209 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001210{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001212 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001213 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1214 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001215
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001216 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1217 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1218 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1219 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001220
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001221 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
1222 TEST_ASSERT(res == exp_result);
1223 if (res == 0) {
1224 TEST_ASSERT(sign_is_valid(&Z));
1225 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine4cc80212021-06-09 18:31:35 +02001226 }
1227
1228 /* Now test again with the speed-up parameter supplied as an output. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001229 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1230 TEST_ASSERT(res == exp_result);
1231 if (res == 0) {
1232 TEST_ASSERT(sign_is_valid(&Z));
1233 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine4cc80212021-06-09 18:31:35 +02001234 }
1235
1236 /* Now test again with the speed-up parameter supplied in calculated form. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001237 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1238 TEST_ASSERT(res == exp_result);
1239 if (res == 0) {
1240 TEST_ASSERT(sign_is_valid(&Z));
1241 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001242 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001243
Paul Bakkerbd51b262014-07-10 15:26:12 +02001244exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001245 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1246 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001247}
Paul Bakker33b43f12013-08-20 11:48:36 +02001248/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001249
Paul Bakker33b43f12013-08-20 11:48:36 +02001250/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001251void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1252 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001253{
1254 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001255 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1256 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001257
Chris Jonesaa850cd2020-12-03 11:35:41 +00001258 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001259 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1260 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1261 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001262
1263 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001264 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1265 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1266 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001267
1268 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001269 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1270 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1271 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001272
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001273 if (strlen(input_RR)) {
1274 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1275 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001276
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001277 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001278
1279exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001280 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1281 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001282}
1283/* END_CASE */
1284
1285/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001286void mpi_inv_mod(char *input_X, char *input_Y,
1287 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001288{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001289 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001290 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001291 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001292
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001293 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1294 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1295 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1296 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1297 TEST_ASSERT(res == div_result);
1298 if (res == 0) {
1299 TEST_ASSERT(sign_is_valid(&Z));
1300 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001301 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001302
Paul Bakkerbd51b262014-07-10 15:26:12 +02001303exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001304 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001305}
Paul Bakker33b43f12013-08-20 11:48:36 +02001306/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001307
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001308/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine366e6852023-04-26 22:43:54 +02001309void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001310{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001311 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001312 int res;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001313 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001314
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001315 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1316 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1317 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001318
Paul Bakkerbd51b262014-07-10 15:26:12 +02001319exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001320 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001321}
Paul Bakker33b43f12013-08-20 11:48:36 +02001322/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001323
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001324/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine366e6852023-04-26 22:43:54 +02001325void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1326 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001327{
1328 mbedtls_mpi X;
1329 int res;
1330 mbedtls_test_mpi_random rand;
1331
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001332 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001333 rand.data = witnesses;
1334 rand.pos = 0;
1335 rand.chunk_len = chunk_len;
1336
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001337 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1338 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1339 mbedtls_test_mpi_miller_rabin_determinizer,
1340 &rand);
1341 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001342
1343 rand.data = witnesses;
1344 rand.pos = 0;
1345 rand.chunk_len = chunk_len;
1346
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001347 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1348 mbedtls_test_mpi_miller_rabin_determinizer,
1349 &rand);
1350 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001351
1352exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001353 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001354}
1355/* END_CASE */
1356
1357/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine366e6852023-04-26 22:43:54 +02001358void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001359{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001360 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001361 int my_ret;
1362
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001363 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001364
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001365 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1366 mbedtls_test_rnd_std_rand, NULL);
1367 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001368
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001369 if (ref_ret == 0) {
1370 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001371
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001372 TEST_ASSERT(actual_bits >= (size_t) bits);
1373 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1374 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001375
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001376 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1377 mbedtls_test_rnd_std_rand,
1378 NULL) == 0);
1379 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001380 /* X = ( X - 1 ) / 2 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001381 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1382 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1383 mbedtls_test_rnd_std_rand,
1384 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001385 }
1386 }
1387
Paul Bakkerbd51b262014-07-10 15:26:12 +02001388exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001389 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001390}
1391/* END_CASE */
1392
Paul Bakker33b43f12013-08-20 11:48:36 +02001393/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001394void mpi_shift_l(char *input_X, int shift_X,
1395 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001396{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397 mbedtls_mpi X, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001398 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001399
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001400 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1401 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1402 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1403 TEST_ASSERT(sign_is_valid(&X));
1404 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001405
Paul Bakkerbd51b262014-07-10 15:26:12 +02001406exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001407 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001408}
Paul Bakker33b43f12013-08-20 11:48:36 +02001409/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001410
Paul Bakker33b43f12013-08-20 11:48:36 +02001411/* BEGIN_CASE */
Gilles Peskine366e6852023-04-26 22:43:54 +02001412void mpi_shift_r(char *input_X, int shift_X,
1413 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001414{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415 mbedtls_mpi X, A;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001416 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001417
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001418 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1419 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1420 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1421 TEST_ASSERT(sign_is_valid(&X));
1422 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001423
Paul Bakkerbd51b262014-07-10 15:26:12 +02001424exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001425 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001426}
Paul Bakker33b43f12013-08-20 11:48:36 +02001427/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001428
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001429/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001430void mpi_fill_random(int wanted_bytes, int rng_bytes,
1431 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001432{
1433 mbedtls_mpi X;
1434 int ret;
1435 size_t bytes_left = rng_bytes;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001436 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001437
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001438 if (before != 0) {
Gilles Peskinef467e1a2021-04-02 00:02:27 +02001439 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001440 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1441 if (before < 0) {
1442 before = -before;
1443 }
1444 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskinef467e1a2021-04-02 00:02:27 +02001445 }
1446
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001447 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1448 f_rng_bytes_left, &bytes_left);
1449 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001450
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001451 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001452 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1453 * as a big-endian representation of the number. We know when
1454 * our RNG function returns null bytes, so we know how many
1455 * leading zero bytes the number has. */
1456 size_t leading_zeros = 0;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001457 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001458 leading_zeros = 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001459 }
1460 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1461 (size_t) wanted_bytes);
1462 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1463 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001464 }
1465
1466exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001467 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001468}
1469/* END_CASE */
1470
Gilles Peskine4699fa42021-03-29 22:02:55 +02001471/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001472void mpi_random_many(int min, data_t *bound_bytes, int iterations)
Gilles Peskine4699fa42021-03-29 22:02:55 +02001473{
1474 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1475 * This function assumes that the value of bound is at least 2 and
1476 * that iterations is large enough that a one-in-2^iterations chance
1477 * effectively never occurs.
1478 */
1479
1480 mbedtls_mpi upper_bound;
1481 size_t n_bits;
1482 mbedtls_mpi result;
1483 size_t b;
1484 /* If upper_bound is small, stats[b] is the number of times the value b
1485 * has been generated. Otherwise stats[b] is the number of times a
1486 * value with bit b set has been generated. */
1487 size_t *stats = NULL;
1488 size_t stats_len;
1489 int full_stats;
1490 size_t i;
1491
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001492 mbedtls_mpi_init(&upper_bound);
1493 mbedtls_mpi_init(&result);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001494
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001495 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound,
1496 bound_bytes->x, bound_bytes->len));
1497 n_bits = mbedtls_mpi_bitlen(&upper_bound);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001498 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1499 * to be small enough that the probability of missing one value is
1500 * negligible given the number of iterations. It must be less than
1501 * 256 because some of the code below assumes that "small" values
1502 * fit in a byte. */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001503 if (n_bits <= 5) {
Gilles Peskine4699fa42021-03-29 22:02:55 +02001504 full_stats = 1;
1505 stats_len = bound_bytes->x[bound_bytes->len - 1];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001506 } else {
Gilles Peskine4699fa42021-03-29 22:02:55 +02001507 full_stats = 0;
1508 stats_len = n_bits;
1509 }
Tom Cosgrove30ceb232023-09-04 11:20:19 +01001510 TEST_CALLOC(stats, stats_len);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001511
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001512 for (i = 0; i < (size_t) iterations; i++) {
1513 mbedtls_test_set_step(i);
1514 TEST_EQUAL(0, mbedtls_mpi_random(&result, min, &upper_bound,
1515 mbedtls_test_rnd_std_rand, NULL));
Gilles Peskine4699fa42021-03-29 22:02:55 +02001516
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001517 TEST_ASSERT(sign_is_valid(&result));
1518 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&result, &upper_bound) < 0);
1519 TEST_ASSERT(mbedtls_mpi_cmp_int(&result, min) >= 0);
1520 if (full_stats) {
Gilles Peskine4699fa42021-03-29 22:02:55 +02001521 uint8_t value;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001522 TEST_EQUAL(0, mbedtls_mpi_write_binary(&result, &value, 1));
1523 TEST_ASSERT(value < stats_len);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001524 ++stats[value];
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001525 } else {
1526 for (b = 0; b < n_bits; b++) {
1527 stats[b] += mbedtls_mpi_get_bit(&result, b);
1528 }
Gilles Peskine4699fa42021-03-29 22:02:55 +02001529 }
1530 }
1531
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001532 if (full_stats) {
1533 for (b = min; b < stats_len; b++) {
1534 mbedtls_test_set_step(1000000 + b);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001535 /* Assert that each value has been reached at least once.
1536 * This is almost guaranteed if the iteration count is large
1537 * enough. This is a very crude way of checking the distribution.
1538 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001539 TEST_ASSERT(stats[b] > 0);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001540 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001541 } else {
Gilles Peskinee4f937f2021-06-02 21:24:04 +02001542 int statistically_safe_all_the_way =
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001543 is_significantly_above_a_power_of_2(bound_bytes);
1544 for (b = 0; b < n_bits; b++) {
1545 mbedtls_test_set_step(1000000 + b);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001546 /* Assert that each bit has been set in at least one result and
1547 * clear in at least one result. Provided that iterations is not
1548 * too small, it would be extremely unlikely for this not to be
1549 * the case if the results are uniformly distributed.
1550 *
1551 * As an exception, the top bit may legitimately never be set
1552 * if bound is a power of 2 or only slightly above.
1553 */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001554 if (statistically_safe_all_the_way || b != n_bits - 1) {
1555 TEST_ASSERT(stats[b] > 0);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001556 }
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001557 TEST_ASSERT(stats[b] < (size_t) iterations);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001558 }
1559 }
1560
1561exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001562 mbedtls_mpi_free(&upper_bound);
1563 mbedtls_mpi_free(&result);
1564 mbedtls_free(stats);
Gilles Peskine4699fa42021-03-29 22:02:55 +02001565}
1566/* END_CASE */
1567
Gilles Peskine9312ba52021-03-29 22:14:51 +02001568/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001569void mpi_random_sizes(int min, data_t *bound_bytes, int nlimbs, int before)
Gilles Peskine8f454702021-04-01 15:57:18 +02001570{
1571 mbedtls_mpi upper_bound;
1572 mbedtls_mpi result;
1573
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001574 mbedtls_mpi_init(&upper_bound);
1575 mbedtls_mpi_init(&result);
Gilles Peskine8f454702021-04-01 15:57:18 +02001576
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001577 if (before != 0) {
Gilles Peskinef467e1a2021-04-02 00:02:27 +02001578 /* Set result to sign(before) * 2^(|before|-1) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001579 TEST_ASSERT(mbedtls_mpi_lset(&result, before > 0 ? 1 : -1) == 0);
1580 if (before < 0) {
1581 before = -before;
1582 }
1583 TEST_ASSERT(mbedtls_mpi_shift_l(&result, before - 1) == 0);
Gilles Peskinef467e1a2021-04-02 00:02:27 +02001584 }
1585
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001586 TEST_EQUAL(0, mbedtls_mpi_grow(&result, nlimbs));
1587 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound,
1588 bound_bytes->x, bound_bytes->len));
1589 TEST_EQUAL(0, mbedtls_mpi_random(&result, min, &upper_bound,
1590 mbedtls_test_rnd_std_rand, NULL));
1591 TEST_ASSERT(sign_is_valid(&result));
1592 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&result, &upper_bound) < 0);
1593 TEST_ASSERT(mbedtls_mpi_cmp_int(&result, min) >= 0);
Gilles Peskine8f454702021-04-01 15:57:18 +02001594
1595exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001596 mbedtls_mpi_free(&upper_bound);
1597 mbedtls_mpi_free(&result);
Gilles Peskine8f454702021-04-01 15:57:18 +02001598}
1599/* END_CASE */
1600
1601/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001602void mpi_random_fail(int min, data_t *bound_bytes, int expected_ret)
Gilles Peskine9312ba52021-03-29 22:14:51 +02001603{
1604 mbedtls_mpi upper_bound;
1605 mbedtls_mpi result;
1606 int actual_ret;
1607
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001608 mbedtls_mpi_init(&upper_bound);
1609 mbedtls_mpi_init(&result);
Gilles Peskine9312ba52021-03-29 22:14:51 +02001610
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001611 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound,
1612 bound_bytes->x, bound_bytes->len));
1613 actual_ret = mbedtls_mpi_random(&result, min, &upper_bound,
1614 mbedtls_test_rnd_std_rand, NULL);
1615 TEST_EQUAL(expected_ret, actual_ret);
Gilles Peskine9312ba52021-03-29 22:14:51 +02001616
1617exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001618 mbedtls_mpi_free(&upper_bound);
1619 mbedtls_mpi_free(&result);
Gilles Peskine9312ba52021-03-29 22:14:51 +02001620}
1621/* END_CASE */
1622
Gilles Peskinede1629a2022-11-15 23:02:14 +01001623/* BEGIN_CASE */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001624void most_negative_mpi_sint()
Gilles Peskinede1629a2022-11-15 23:02:14 +01001625{
1626 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1627 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1628 * is a valid value. However, negating it (`-n`) has undefined behavior
1629 * (although in practice `-n` evaluates to the value n).
1630 *
1631 * This function has ad hoc tests for this value. It's separated from other
1632 * functions because the test framework makes it hard to pass this value
1633 * into test cases.
1634 *
1635 * In the comments here:
1636 * - biL = number of bits in limbs
1637 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1638 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1639 */
1640
1641 mbedtls_mpi A, R, X;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001642 mbedtls_mpi_init(&A);
1643 mbedtls_mpi_init(&R);
1644 mbedtls_mpi_init(&X);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001645
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001646 const size_t biL = 8 * sizeof(mbedtls_mpi_sint);
1647 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001648 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001649 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1650 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1651 (mbedtls_mpi_uint) 1 << (biL - 1));
1652 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001653
1654 /* Test mbedtls_mpi_lset() */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001655 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1656 TEST_EQUAL(A.s, -1);
1657 TEST_EQUAL(A.n, 1);
1658 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001659
1660 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001661 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001662
1663 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1664 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001665 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001666
1667 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1668 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001669 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001670
1671 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001672 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1673 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1674 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001675
1676 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001677 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1678 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1679 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001680
1681 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001682 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1683 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1684 TEST_EQUAL(X.s, -1);
1685 TEST_EQUAL(X.n, 2);
1686 TEST_EQUAL(X.p[0], 0);
1687 TEST_EQUAL(X.p[1], 1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001688
1689 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001690 mbedtls_mpi_free(&X);
1691 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1692 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1693 TEST_EQUAL(X.s, 1);
1694 TEST_EQUAL(X.n, 1);
1695 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001696
1697 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001698 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1699 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1700 TEST_EQUAL(X.s, 1);
1701 TEST_EQUAL(X.n, 1);
1702 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001703
1704 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001705 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1706 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1707 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001708
1709 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001710 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1711 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1712 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1713 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001714
1715 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001716 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1717 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1718 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1719 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001720
1721 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001722 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1723 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1724 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1725 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001726
1727 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001728 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1729 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1730 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1731 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001732
1733 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001734 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1735 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1736 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1737 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001738
1739 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001740 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1741 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1742 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1743 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001744
1745 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001746 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1747 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1748 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1749 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001750
1751 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001752 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1753 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001754
1755 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001756 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1757 mbedtls_test_rnd_std_rand, NULL),
1758 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001759
1760exit:
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001761 mbedtls_mpi_free(&A);
1762 mbedtls_mpi_free(&R);
1763 mbedtls_mpi_free(&X);
Gilles Peskinede1629a2022-11-15 23:02:14 +01001764}
1765/* END_CASE */
1766
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001767/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001768void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001769{
Gilles Peskine1b6c09a2023-01-11 14:52:35 +01001770 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001771}
Paul Bakker33b43f12013-08-20 11:48:36 +02001772/* END_CASE */