blob: 25fcb6c06507b4ba54b26aa95eee805840212ebe [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
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02006# 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 Peskinedffc7102021-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. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020012static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskinedffc7102021-06-10 15:34:15 +020013{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020014 if (X->s != 1 && X->s != -1)
15 return 0; // invalid sign bit, e.g. 0
16 if (mbedtls_mpi_bitlen(X) == 0 && X->s != 1)
17 return 0; // negative zero
18 return 1;
Gilles Peskinedffc7102021-06-10 15:34:15 +020019}
20
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020021typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010022 data_t *data;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020023 size_t pos;
24 size_t chunk_len;
Janos Follath64eca052018-09-05 17:04:49 +010025} mbedtls_test_mpi_random;
26
27/*
28 * This function is called by the Miller-Rabin primality test each time it
29 * chooses a random witness. The witnesses (or non-witnesses as provided by the
30 * test) are stored in the data member of the state structure. Each number is in
31 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
32 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020033int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
34 unsigned char *buf,
35 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010036{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020037 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *)state;
Janos Follath64eca052018-09-05 17:04:49 +010038
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020039 if (random == NULL || random->data->x == NULL || buf == NULL)
40 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010041
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020042 if (random->pos + random->chunk_len > random->data->len ||
43 random->chunk_len > len) {
44 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010045 }
46
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020047 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010048
49 /* The witness is written to the end of the buffer, since the buffer is
50 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
51 * Writing the witness to the start of the buffer would result in the
52 * buffer being 'witness 000...000', which would be treated as
53 * witness * 2^n for some n. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020054 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
55 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010056
57 random->pos += random->chunk_len;
58
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020059 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010060}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010061
62/* Random generator that is told how many bytes to return. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020063static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010064{
65 size_t *bytes_left = state;
66 size_t i;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020067 for (i = 0; i < len; i++) {
68 if (*bytes_left == 0)
69 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010070 buf[i] = *bytes_left & 0xff;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020071 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010072 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020073 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010074}
75
Gilles Peskineeedefa52021-04-13 19:50:04 +020076/* Test whether bytes represents (in big-endian base 256) a number b that
77 * is significantly above a power of 2. That is, b must not have a long run
78 * of unset bits after the most significant bit.
79 *
80 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
81 * This function returns 1 if, when drawing a number between 0 and b,
82 * the probability that this number is at least 2^n is not negligible.
83 * This probability is (b - 2^n) / b and this function checks that this
84 * number is above some threshold A. The threshold value is heuristic and
85 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020086 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020087static int is_significantly_above_a_power_of_2(data_t *bytes)
Gilles Peskine02ac93a2021-03-29 22:02:55 +020088{
89 const uint8_t *p = bytes->x;
90 size_t len = bytes->len;
91 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020092
93 /* Skip leading null bytes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020094 while (len > 0 && p[0] == 0) {
Gilles Peskine02ac93a2021-03-29 22:02:55 +020095 ++p;
96 --len;
97 }
Gilles Peskineeedefa52021-04-13 19:50:04 +020098 /* 0 is not significantly above a power of 2 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020099 if (len == 0)
100 return 0;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200101 /* Extract the (up to) 2 most significant bytes */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200102 if (len == 1)
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200103 x = p[0];
104 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200105 x = (p[0] << 8) | p[1];
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200106
Gilles Peskineeedefa52021-04-13 19:50:04 +0200107 /* Shift the most significant bit of x to position 8 and mask it out */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200108 while ((x & 0xfe00) != 0)
Gilles Peskineeedefa52021-04-13 19:50:04 +0200109 x >>= 1;
110 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200111
Gilles Peskineeedefa52021-04-13 19:50:04 +0200112 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
113 * a power of 2 iff x is significantly above 0 compared to 2^8.
114 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
115 * description above. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 return x >= 0x10;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200117}
118
Paul Bakker33b43f12013-08-20 11:48:36 +0200119/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000120
Paul Bakker33b43f12013-08-20 11:48:36 +0200121/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200122 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200123 * END_DEPENDENCIES
124 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000125
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000126/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200127void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200128{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200129 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200130
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200131 mbedtls_mpi_init(&X);
132 mbedtls_mpi_init(&Y);
133 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200134
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200135 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
136 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
137 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
138 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200139
140exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200141 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200142}
143/* END_CASE */
144
145/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200146void mpi_read_write_string(int radix_X,
147 char *input_X,
148 int radix_A,
149 char *input_A,
150 int output_size,
151 int result_read,
152 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000153{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000155 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100156 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000157
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200158 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000159
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200160 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000161
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200162 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
163 if (result_read == 0) {
164 TEST_ASSERT(sign_is_valid(&X));
165 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size,
166 &len) == result_write);
167 if (result_write == 0) {
168 TEST_ASSERT(strcasecmp(str, input_A) == 0);
169 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000170 }
171 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000172
Paul Bakkerbd51b262014-07-10 15:26:12 +0200173exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200174 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000175}
Paul Bakker33b43f12013-08-20 11:48:36 +0200176/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000177
Paul Bakker33b43f12013-08-20 11:48:36 +0200178/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200179void mbedtls_mpi_read_binary(data_t *buf, int radix_A, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000180{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000182 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100183 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000184
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200185 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000186
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200187 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
188 TEST_ASSERT(sign_is_valid(&X));
189 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, sizeof(str), &len) ==
190 0);
191 TEST_ASSERT(strcmp((char *)str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000192
Paul Bakkerbd51b262014-07-10 15:26:12 +0200193exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200194 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000195}
Paul Bakker33b43f12013-08-20 11:48:36 +0200196/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000197
Paul Bakker33b43f12013-08-20 11:48:36 +0200198/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200199void mbedtls_mpi_read_binary_le(data_t *buf, int radix_A, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000200{
201 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000202 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000203 size_t len;
204
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200205 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000206
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
208 TEST_ASSERT(sign_is_valid(&X));
209 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, sizeof(str), &len) ==
210 0);
211 TEST_ASSERT(strcmp((char *)str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000212
213exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200214 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000215}
216/* END_CASE */
217
218/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219void mbedtls_mpi_write_binary(int radix_X,
220 char *input_X,
221 data_t *input_A,
222 int output_size,
223 int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000224{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000226 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000227 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000228
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200229 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000230
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200231 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000232
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200233 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100234
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200235 buflen = mbedtls_mpi_size(&X);
236 if (buflen > (size_t)output_size)
237 buflen = (size_t)output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000238
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
240 if (result == 0) {
241 TEST_ASSERT(
242 mbedtls_test_hexcmp(buf, input_A->x, buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000243 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000244
Paul Bakkerbd51b262014-07-10 15:26:12 +0200245exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200246 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000247}
Paul Bakker33b43f12013-08-20 11:48:36 +0200248/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000249
Janos Follathe344d0f2019-02-19 16:17:40 +0000250/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200251void mbedtls_mpi_write_binary_le(int radix_X,
252 char *input_X,
253 data_t *input_A,
254 int output_size,
255 int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000256{
257 mbedtls_mpi X;
258 unsigned char buf[1000];
259 size_t buflen;
260
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200261 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000262
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200263 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000264
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200265 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000266
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200267 buflen = mbedtls_mpi_size(&X);
268 if (buflen > (size_t)output_size)
269 buflen = (size_t)output_size;
Janos Follathe344d0f2019-02-19 16:17:40 +0000270
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200271 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
272 if (result == 0) {
273 TEST_ASSERT(
274 mbedtls_test_hexcmp(buf, input_A->x, buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000275 }
276
277exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200278 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000279}
280/* END_CASE */
281
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200283void mbedtls_mpi_read_file(int radix_X,
284 char *input_file,
285 data_t *input_A,
286 int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000287{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000289 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000290 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000291 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000292 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200294 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000295
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200296 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000297
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200298 file = fopen(input_file, "r");
299 TEST_ASSERT(file != NULL);
300 ret = mbedtls_mpi_read_file(&X, radix_X, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000301 fclose(file);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200302 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000303
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200304 if (result == 0) {
305 TEST_ASSERT(sign_is_valid(&X));
306 buflen = mbedtls_mpi_size(&X);
307 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000308
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200309 TEST_ASSERT(
310 mbedtls_test_hexcmp(buf, input_A->x, buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000311 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000312
Paul Bakkerbd51b262014-07-10 15:26:12 +0200313exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200314 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000315}
Paul Bakker33b43f12013-08-20 11:48:36 +0200316/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200319void mbedtls_mpi_write_file(int radix_X,
320 char *input_X,
321 int output_radix,
322 char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000323{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200324 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000325 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200326 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000327
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200328 mbedtls_mpi_init(&X);
329 mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000330
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200331 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000332
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200333 file_out = fopen(output_file, "w");
334 TEST_ASSERT(file_out != NULL);
335 ret = mbedtls_mpi_write_file(NULL, &X, output_radix, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000336 fclose(file_out);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200337 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000338
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200339 file_in = fopen(output_file, "r");
340 TEST_ASSERT(file_in != NULL);
341 ret = mbedtls_mpi_read_file(&Y, output_radix, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000342 fclose(file_in);
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200343 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000344
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200345 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000346
Paul Bakkerbd51b262014-07-10 15:26:12 +0200347exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 mbedtls_mpi_free(&X);
349 mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000350}
Paul Bakker33b43f12013-08-20 11:48:36 +0200351/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000352
Paul Bakker33b43f12013-08-20 11:48:36 +0200353/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200354void mbedtls_mpi_get_bit(int radix_X, char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000355{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 mbedtls_mpi X;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200357 mbedtls_mpi_init(&X);
358 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
359 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000360
Paul Bakkerbd51b262014-07-10 15:26:12 +0200361exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200362 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000363}
Paul Bakker33b43f12013-08-20 11:48:36 +0200364/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000365
Paul Bakker33b43f12013-08-20 11:48:36 +0200366/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367void mbedtls_mpi_set_bit(int radix_X,
368 char *input_X,
369 int pos,
370 int val,
371 int radix_Y,
372 char *output_Y,
373 int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000374{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_mpi X, Y;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200376 mbedtls_mpi_init(&X);
377 mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000378
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200379 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
380 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, output_Y) == 0);
381 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100382
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200383 if (result == 0) {
384 TEST_ASSERT(sign_is_valid(&X));
385 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100386 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000387
Paul Bakkerbd51b262014-07-10 15:26:12 +0200388exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200389 mbedtls_mpi_free(&X);
390 mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000391}
Paul Bakker33b43f12013-08-20 11:48:36 +0200392/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000393
Paul Bakker33b43f12013-08-20 11:48:36 +0200394/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200395void mbedtls_mpi_lsb(int radix_X, char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000396{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_mpi X;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200398 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
401 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t)nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000402
Paul Bakkerbd51b262014-07-10 15:26:12 +0200403exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200404 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000405}
Paul Bakker33b43f12013-08-20 11:48:36 +0200406/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000407
Paul Bakker33b43f12013-08-20 11:48:36 +0200408/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200409void mbedtls_mpi_bitlen(int radix_X, char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000410{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 mbedtls_mpi X;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200412 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000413
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200414 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
415 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t)nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000416
Paul Bakkerbd51b262014-07-10 15:26:12 +0200417exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200418 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000419}
Paul Bakker33b43f12013-08-20 11:48:36 +0200420/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000421
Paul Bakker33b43f12013-08-20 11:48:36 +0200422/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200423void mbedtls_mpi_gcd(int radix_X,
424 char *input_X,
425 int radix_Y,
426 char *input_Y,
427 int radix_A,
428 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000429{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_mpi A, X, Y, Z;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200431 mbedtls_mpi_init(&A);
432 mbedtls_mpi_init(&X);
433 mbedtls_mpi_init(&Y);
434 mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000435
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200436 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
437 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
438 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
439 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
440 TEST_ASSERT(sign_is_valid(&Z));
441 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000442
Paul Bakkerbd51b262014-07-10 15:26:12 +0200443exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200444 mbedtls_mpi_free(&A);
445 mbedtls_mpi_free(&X);
446 mbedtls_mpi_free(&Y);
447 mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000448}
Paul Bakker33b43f12013-08-20 11:48:36 +0200449/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000450
Paul Bakker33b43f12013-08-20 11:48:36 +0200451/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200452void mbedtls_mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000453{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_mpi X;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200455 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000456
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200457 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
458 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000459
Paul Bakkerbd51b262014-07-10 15:26:12 +0200460exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200461 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000462}
Paul Bakker33b43f12013-08-20 11:48:36 +0200463/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000464
Paul Bakker33b43f12013-08-20 11:48:36 +0200465/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200466void mbedtls_mpi_cmp_mpi(int radix_X,
467 char *input_X,
468 int radix_Y,
469 char *input_Y,
470 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000471{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_mpi X, Y;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200473 mbedtls_mpi_init(&X);
474 mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000475
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200476 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
477 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
478 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000479
Paul Bakkerbd51b262014-07-10 15:26:12 +0200480exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200481 mbedtls_mpi_free(&X);
482 mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000483}
Paul Bakker33b43f12013-08-20 11:48:36 +0200484/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000485
Paul Bakker33b43f12013-08-20 11:48:36 +0200486/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200487void mbedtls_mpi_lt_mpi_ct(int size_X,
488 char *input_X,
489 int size_Y,
490 char *input_Y,
491 int input_ret,
492 int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100493{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200494 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100495 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100496 mbedtls_mpi X, Y;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200497 mbedtls_mpi_init(&X);
498 mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100499
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200500 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, input_X) == 0);
501 TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100502
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200503 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
504 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100505
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200506 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
507 if (input_err == 0)
508 TEST_ASSERT(ret == input_uret);
Janos Follath385d5b82019-09-11 16:07:14 +0100509
510exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200511 mbedtls_mpi_free(&X);
512 mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100513}
514/* END_CASE */
515
516/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200517void mbedtls_mpi_cmp_abs(int radix_X,
518 char *input_X,
519 int radix_Y,
520 char *input_Y,
521 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000522{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_mpi X, Y;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200524 mbedtls_mpi_init(&X);
525 mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000526
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200527 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
528 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
529 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000530
Paul Bakkerbd51b262014-07-10 15:26:12 +0200531exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200532 mbedtls_mpi_free(&X);
533 mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000534}
Paul Bakker33b43f12013-08-20 11:48:36 +0200535/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000536
Paul Bakker33b43f12013-08-20 11:48:36 +0200537/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200538void mbedtls_mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000539{
Gilles Peskined0722f82021-06-10 23:00:33 +0200540 mbedtls_mpi src, dst, ref;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200541 mbedtls_mpi_init(&src);
542 mbedtls_mpi_init(&dst);
543 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000544
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200545 TEST_ASSERT(mbedtls_test_read_mpi(&src, 16, src_hex) == 0);
546 TEST_ASSERT(mbedtls_test_read_mpi(&ref, 16, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200547
548 /* mbedtls_mpi_copy() */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200549 TEST_ASSERT(mbedtls_test_read_mpi(&dst, 16, dst_hex) == 0);
550 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
551 TEST_ASSERT(sign_is_valid(&dst));
552 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000553
Gilles Peskined0722f82021-06-10 23:00:33 +0200554 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200555 mbedtls_mpi_free(&dst);
556 TEST_ASSERT(mbedtls_test_read_mpi(&dst, 16, dst_hex) == 0);
557 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
558 TEST_ASSERT(sign_is_valid(&dst));
559 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200560
561 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562 mbedtls_mpi_free(&dst);
563 TEST_ASSERT(mbedtls_test_read_mpi(&dst, 16, dst_hex) == 0);
564 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
565 TEST_ASSERT(sign_is_valid(&dst));
566 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200567
Paul Bakkerbd51b262014-07-10 15:26:12 +0200568exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200569 mbedtls_mpi_free(&src);
570 mbedtls_mpi_free(&dst);
571 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100572}
573/* END_CASE */
574
575/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200576void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100577{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200578 mbedtls_mpi X, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200579 mbedtls_mpi_init(&A);
580 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000581
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200582 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, input_X) == 0);
583 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200584
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200585 TEST_ASSERT(mbedtls_test_read_mpi(&A, 16, input_X) == 0);
586 TEST_ASSERT(sign_is_valid(&X));
587 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000588
Paul Bakkerbd51b262014-07-10 15:26:12 +0200589exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200590 mbedtls_mpi_free(&A);
591 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000592}
Paul Bakker33b43f12013-08-20 11:48:36 +0200593/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000594
Paul Bakker33b43f12013-08-20 11:48:36 +0200595/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200596void mbedtls_mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200597{
598 mbedtls_mpi X, Y, X0, Y0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200599 mbedtls_mpi_init(&X);
600 mbedtls_mpi_init(&Y);
601 mbedtls_mpi_init(&X0);
602 mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200603
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200604 TEST_ASSERT(mbedtls_test_read_mpi(&X0, 16, X_hex) == 0);
605 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, 16, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200606
Gilles Peskined0722f82021-06-10 23:00:33 +0200607 /* mbedtls_mpi_swap() */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200608 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, X_hex) == 0);
609 TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, Y_hex) == 0);
610 mbedtls_mpi_swap(&X, &Y);
611 TEST_ASSERT(sign_is_valid(&X));
612 TEST_ASSERT(sign_is_valid(&Y));
613 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
614 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200615
Gilles Peskined0722f82021-06-10 23:00:33 +0200616 /* mbedtls_mpi_safe_cond_swap(), swap done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200617 mbedtls_mpi_free(&X);
618 mbedtls_mpi_free(&Y);
619 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, X_hex) == 0);
620 TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, Y_hex) == 0);
621 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
622 TEST_ASSERT(sign_is_valid(&X));
623 TEST_ASSERT(sign_is_valid(&Y));
624 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
625 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200626
627 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200628 mbedtls_mpi_free(&X);
629 mbedtls_mpi_free(&Y);
630 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, X_hex) == 0);
631 TEST_ASSERT(mbedtls_test_read_mpi(&Y, 16, Y_hex) == 0);
632 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
633 TEST_ASSERT(sign_is_valid(&X));
634 TEST_ASSERT(sign_is_valid(&Y));
635 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
636 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200637
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200638exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200639 mbedtls_mpi_free(&X);
640 mbedtls_mpi_free(&Y);
641 mbedtls_mpi_free(&X0);
642 mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200643}
644/* END_CASE */
645
646/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200647void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200648{
649 mbedtls_mpi X, X0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200650 mbedtls_mpi_init(&X);
651 mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200652
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200653 TEST_ASSERT(mbedtls_test_read_mpi(&X, 16, X_hex) == 0);
654 TEST_ASSERT(mbedtls_test_read_mpi(&X0, 16, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200655
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200656 mbedtls_mpi_swap(&X, &X);
657 TEST_ASSERT(sign_is_valid(&X));
658 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200659
660exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200661 mbedtls_mpi_free(&X);
662 mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200663}
664/* END_CASE */
665
666/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200667void mbedtls_mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100668{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_mpi X;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200670 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100671
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200672 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
673 if (used > 0) {
674 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
675 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200676 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200677 TEST_EQUAL(X.n, (size_t)before);
678 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
679 TEST_EQUAL(X.n, (size_t)after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100680
Paul Bakkerbd51b262014-07-10 15:26:12 +0200681exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200682 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100683}
684/* END_CASE */
685
686/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200687void mbedtls_mpi_add_mpi(int radix_X,
688 char *input_X,
689 int radix_Y,
690 char *input_Y,
691 int radix_A,
692 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000693{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694 mbedtls_mpi X, Y, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200695 mbedtls_mpi_init(&X);
696 mbedtls_mpi_init(&Y);
697 mbedtls_mpi_init(&Z);
698 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000699
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200700 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
701 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
702 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
703 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
704 TEST_ASSERT(sign_is_valid(&Z));
705 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000706
Gilles Peskine56f943a2020-07-23 01:18:11 +0200707 /* result == first operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200708 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
709 TEST_ASSERT(sign_is_valid(&X));
710 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
711 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200712
713 /* result == second operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200714 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
715 TEST_ASSERT(sign_is_valid(&Y));
716 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200717
Paul Bakkerbd51b262014-07-10 15:26:12 +0200718exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200719 mbedtls_mpi_free(&X);
720 mbedtls_mpi_free(&Y);
721 mbedtls_mpi_free(&Z);
722 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000723}
Paul Bakker33b43f12013-08-20 11:48:36 +0200724/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000725
Paul Bakker33b43f12013-08-20 11:48:36 +0200726/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200727void mbedtls_mpi_add_mpi_inplace(int radix_X,
728 char *input_X,
729 int radix_A,
730 char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100731{
732 mbedtls_mpi X, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200733 mbedtls_mpi_init(&X);
734 mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100735
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200736 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100737
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200738 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
739 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
740 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
741 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100742
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200743 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
744 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
745 TEST_ASSERT(sign_is_valid(&X));
746 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100747
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200748 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
749 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
750 TEST_ASSERT(sign_is_valid(&X));
751 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100752
753exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200754 mbedtls_mpi_free(&X);
755 mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100756}
757/* END_CASE */
758
Janos Follath044a86b2015-10-25 10:58:03 +0100759/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200760void mbedtls_mpi_add_abs(int radix_X,
761 char *input_X,
762 int radix_Y,
763 char *input_Y,
764 int radix_A,
765 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000766{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 mbedtls_mpi X, Y, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200768 mbedtls_mpi_init(&X);
769 mbedtls_mpi_init(&Y);
770 mbedtls_mpi_init(&Z);
771 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000772
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200773 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
774 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
775 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
776 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
777 TEST_ASSERT(sign_is_valid(&Z));
778 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000779
Gilles Peskine56f943a2020-07-23 01:18:11 +0200780 /* result == first operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200781 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
782 TEST_ASSERT(sign_is_valid(&X));
783 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
784 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200785
786 /* result == second operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200787 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
788 TEST_ASSERT(sign_is_valid(&Y));
789 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000790
Paul Bakkerbd51b262014-07-10 15:26:12 +0200791exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200792 mbedtls_mpi_free(&X);
793 mbedtls_mpi_free(&Y);
794 mbedtls_mpi_free(&Z);
795 mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000796}
Paul Bakker33b43f12013-08-20 11:48:36 +0200797/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000798
Paul Bakker33b43f12013-08-20 11:48:36 +0200799/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200800void mbedtls_mpi_add_int(int radix_X,
801 char *input_X,
802 int input_Y,
803 int radix_A,
804 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000805{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 mbedtls_mpi X, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200807 mbedtls_mpi_init(&X);
808 mbedtls_mpi_init(&Z);
809 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000810
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200811 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
812 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
813 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
814 TEST_ASSERT(sign_is_valid(&Z));
815 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000816
Paul Bakkerbd51b262014-07-10 15:26:12 +0200817exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200818 mbedtls_mpi_free(&X);
819 mbedtls_mpi_free(&Z);
820 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000821}
Paul Bakker33b43f12013-08-20 11:48:36 +0200822/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000823
Paul Bakker33b43f12013-08-20 11:48:36 +0200824/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200825void mbedtls_mpi_sub_mpi(int radix_X,
826 char *input_X,
827 int radix_Y,
828 char *input_Y,
829 int radix_A,
830 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000831{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_mpi X, Y, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200833 mbedtls_mpi_init(&X);
834 mbedtls_mpi_init(&Y);
835 mbedtls_mpi_init(&Z);
836 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000837
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200838 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
839 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
840 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
841 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
842 TEST_ASSERT(sign_is_valid(&Z));
843 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000844
Gilles Peskine56f943a2020-07-23 01:18:11 +0200845 /* result == first operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200846 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
847 TEST_ASSERT(sign_is_valid(&X));
848 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
849 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200850
851 /* result == second operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200852 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
853 TEST_ASSERT(sign_is_valid(&Y));
854 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200855
Paul Bakkerbd51b262014-07-10 15:26:12 +0200856exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200857 mbedtls_mpi_free(&X);
858 mbedtls_mpi_free(&Y);
859 mbedtls_mpi_free(&Z);
860 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000861}
Paul Bakker33b43f12013-08-20 11:48:36 +0200862/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000863
Paul Bakker33b43f12013-08-20 11:48:36 +0200864/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200865void mbedtls_mpi_sub_abs(int radix_X,
866 char *input_X,
867 int radix_Y,
868 char *input_Y,
869 int radix_A,
870 char *input_A,
871 int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000872{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000874 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200875 mbedtls_mpi_init(&X);
876 mbedtls_mpi_init(&Y);
877 mbedtls_mpi_init(&Z);
878 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000879
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200880 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
881 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
882 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100883
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200884 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
885 TEST_ASSERT(res == sub_result);
886 TEST_ASSERT(sign_is_valid(&Z));
887 if (res == 0)
888 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000889
Gilles Peskine56f943a2020-07-23 01:18:11 +0200890 /* result == first operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200891 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
892 TEST_ASSERT(sign_is_valid(&X));
893 if (sub_result == 0)
894 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
895 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200896
897 /* result == second operand */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200898 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
899 TEST_ASSERT(sign_is_valid(&Y));
900 if (sub_result == 0)
901 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200902
Paul Bakkerbd51b262014-07-10 15:26:12 +0200903exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200904 mbedtls_mpi_free(&X);
905 mbedtls_mpi_free(&Y);
906 mbedtls_mpi_free(&Z);
907 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000908}
Paul Bakker33b43f12013-08-20 11:48:36 +0200909/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000910
Paul Bakker33b43f12013-08-20 11:48:36 +0200911/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200912void mbedtls_mpi_sub_int(int radix_X,
913 char *input_X,
914 int input_Y,
915 int radix_A,
916 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000917{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_mpi X, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200919 mbedtls_mpi_init(&X);
920 mbedtls_mpi_init(&Z);
921 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000922
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200923 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
924 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
925 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
926 TEST_ASSERT(sign_is_valid(&Z));
927 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000928
Paul Bakkerbd51b262014-07-10 15:26:12 +0200929exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200930 mbedtls_mpi_free(&X);
931 mbedtls_mpi_free(&Z);
932 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000933}
Paul Bakker33b43f12013-08-20 11:48:36 +0200934/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000935
Paul Bakker33b43f12013-08-20 11:48:36 +0200936/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200937void mbedtls_mpi_mul_mpi(int radix_X,
938 char *input_X,
939 int radix_Y,
940 char *input_Y,
941 int radix_A,
942 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000943{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_mpi X, Y, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200945 mbedtls_mpi_init(&X);
946 mbedtls_mpi_init(&Y);
947 mbedtls_mpi_init(&Z);
948 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000949
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200950 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
951 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
952 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
953 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
954 TEST_ASSERT(sign_is_valid(&Z));
955 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000956
Paul Bakkerbd51b262014-07-10 15:26:12 +0200957exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200958 mbedtls_mpi_free(&X);
959 mbedtls_mpi_free(&Y);
960 mbedtls_mpi_free(&Z);
961 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000962}
Paul Bakker33b43f12013-08-20 11:48:36 +0200963/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000964
Paul Bakker33b43f12013-08-20 11:48:36 +0200965/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200966void mbedtls_mpi_mul_int(int radix_X,
967 char *input_X,
968 int input_Y,
969 int radix_A,
970 char *input_A,
971 char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000972{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_mpi X, Z, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200974 mbedtls_mpi_init(&X);
975 mbedtls_mpi_init(&Z);
976 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000977
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200978 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
979 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
980 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
981 TEST_ASSERT(sign_is_valid(&Z));
982 if (strcmp(result_comparison, "==") == 0)
983 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
984 else if (strcmp(result_comparison, "!=") == 0)
985 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200986 else
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200987 TEST_ASSERT("unknown operator" == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000988
Paul Bakkerbd51b262014-07-10 15:26:12 +0200989exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200990 mbedtls_mpi_free(&X);
991 mbedtls_mpi_free(&Z);
992 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000993}
Paul Bakker33b43f12013-08-20 11:48:36 +0200994/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000995
Paul Bakker33b43f12013-08-20 11:48:36 +0200996/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200997void mbedtls_mpi_div_mpi(int radix_X,
998 char *input_X,
999 int radix_Y,
1000 char *input_Y,
1001 int radix_A,
1002 char *input_A,
1003 int radix_B,
1004 char *input_B,
1005 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001006{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001007 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001008 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001009 mbedtls_mpi_init(&X);
1010 mbedtls_mpi_init(&Y);
1011 mbedtls_mpi_init(&Q);
1012 mbedtls_mpi_init(&R);
1013 mbedtls_mpi_init(&A);
1014 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001015
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001016 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1017 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
1018 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1019 TEST_ASSERT(mbedtls_test_read_mpi(&B, radix_B, input_B) == 0);
1020 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
1021 TEST_ASSERT(res == div_result);
1022 if (res == 0) {
1023 TEST_ASSERT(sign_is_valid(&Q));
1024 TEST_ASSERT(sign_is_valid(&R));
1025 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
1026 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001027 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001028
Paul Bakkerbd51b262014-07-10 15:26:12 +02001029exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001030 mbedtls_mpi_free(&X);
1031 mbedtls_mpi_free(&Y);
1032 mbedtls_mpi_free(&Q);
1033 mbedtls_mpi_free(&R);
1034 mbedtls_mpi_free(&A);
1035 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001036}
Paul Bakker33b43f12013-08-20 11:48:36 +02001037/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001038
Paul Bakker33b43f12013-08-20 11:48:36 +02001039/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001040void mbedtls_mpi_div_int(int radix_X,
1041 char *input_X,
1042 int input_Y,
1043 int radix_A,
1044 char *input_A,
1045 int radix_B,
1046 char *input_B,
1047 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001048{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001050 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001051 mbedtls_mpi_init(&X);
1052 mbedtls_mpi_init(&Q);
1053 mbedtls_mpi_init(&R);
1054 mbedtls_mpi_init(&A);
1055 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001056
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001057 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1058 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1059 TEST_ASSERT(mbedtls_test_read_mpi(&B, radix_B, input_B) == 0);
1060 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
1061 TEST_ASSERT(res == div_result);
1062 if (res == 0) {
1063 TEST_ASSERT(sign_is_valid(&Q));
1064 TEST_ASSERT(sign_is_valid(&R));
1065 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
1066 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001067 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001068
Paul Bakkerbd51b262014-07-10 15:26:12 +02001069exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001070 mbedtls_mpi_free(&X);
1071 mbedtls_mpi_free(&Q);
1072 mbedtls_mpi_free(&R);
1073 mbedtls_mpi_free(&A);
1074 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +00001075}
Paul Bakker33b43f12013-08-20 11:48:36 +02001076/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001077
Paul Bakker33b43f12013-08-20 11:48:36 +02001078/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001079void mbedtls_mpi_mod_mpi(int radix_X,
1080 char *input_X,
1081 int radix_Y,
1082 char *input_Y,
1083 int radix_A,
1084 char *input_A,
1085 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001086{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001087 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001088 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001089 mbedtls_mpi_init(&X);
1090 mbedtls_mpi_init(&Y);
1091 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001092
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001093 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1094 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
1095 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1096 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
1097 TEST_ASSERT(res == div_result);
1098 if (res == 0) {
1099 TEST_ASSERT(sign_is_valid(&X));
1100 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001101 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001102
Paul Bakkerbd51b262014-07-10 15:26:12 +02001103exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001104 mbedtls_mpi_free(&X);
1105 mbedtls_mpi_free(&Y);
1106 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001107}
Paul Bakker33b43f12013-08-20 11:48:36 +02001108/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001109
Paul Bakker33b43f12013-08-20 11:48:36 +02001110/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001111void mbedtls_mpi_mod_int(int radix_X,
1112 char *input_X,
1113 int input_Y,
1114 int input_A,
1115 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001116{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001118 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119 mbedtls_mpi_uint r;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001120 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001121
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001122 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1123 res = mbedtls_mpi_mod_int(&r, &X, input_Y);
1124 TEST_ASSERT(res == div_result);
1125 if (res == 0) {
1126 TEST_ASSERT(r == (mbedtls_mpi_uint)input_A);
Paul Bakker367dae42009-06-28 21:50:27 +00001127 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001128
Paul Bakkerbd51b262014-07-10 15:26:12 +02001129exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001130 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001131}
Paul Bakker33b43f12013-08-20 11:48:36 +02001132/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001133
Paul Bakker33b43f12013-08-20 11:48:36 +02001134/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001135void mbedtls_mpi_exp_mod(int radix_A,
1136 char *input_A,
1137 int radix_E,
1138 char *input_E,
1139 int radix_N,
1140 char *input_N,
1141 int radix_X,
1142 char *input_X,
1143 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001144{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001146 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001147 mbedtls_mpi_init(&A);
1148 mbedtls_mpi_init(&E);
1149 mbedtls_mpi_init(&N);
1150 mbedtls_mpi_init(&RR);
1151 mbedtls_mpi_init(&Z);
1152 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001153
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001154 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1155 TEST_ASSERT(mbedtls_test_read_mpi(&E, radix_E, input_E) == 0);
1156 TEST_ASSERT(mbedtls_test_read_mpi(&N, radix_N, input_N) == 0);
1157 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001158
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001159 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
1160 TEST_ASSERT(res == exp_result);
1161 if (res == 0) {
1162 TEST_ASSERT(sign_is_valid(&Z));
1163 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001164 }
1165
1166 /* Now test again with the speed-up parameter supplied as an output. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001167 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1168 TEST_ASSERT(res == exp_result);
1169 if (res == 0) {
1170 TEST_ASSERT(sign_is_valid(&Z));
1171 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001172 }
1173
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001174 /* Now test again with the speed-up parameter supplied in calculated form.
1175 */
1176 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
1177 TEST_ASSERT(res == exp_result);
1178 if (res == 0) {
1179 TEST_ASSERT(sign_is_valid(&Z));
1180 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001181 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001182
Paul Bakkerbd51b262014-07-10 15:26:12 +02001183exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001184 mbedtls_mpi_free(&A);
1185 mbedtls_mpi_free(&E);
1186 mbedtls_mpi_free(&N);
1187 mbedtls_mpi_free(&RR);
1188 mbedtls_mpi_free(&Z);
1189 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001190}
Paul Bakker33b43f12013-08-20 11:48:36 +02001191/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001192
Paul Bakker33b43f12013-08-20 11:48:36 +02001193/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001194void mbedtls_mpi_exp_mod_size(int A_bytes,
1195 int E_bytes,
1196 int N_bytes,
1197 int radix_RR,
1198 char *input_RR,
1199 int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001200{
1201 mbedtls_mpi A, E, N, RR, Z;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001202 mbedtls_mpi_init(&A);
1203 mbedtls_mpi_init(&E);
1204 mbedtls_mpi_init(&N);
1205 mbedtls_mpi_init(&RR);
1206 mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001207
Chris Jonesaa850cd2020-12-03 11:35:41 +00001208 /* Set A to 2^(A_bytes - 1) + 1 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001209 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1210 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1211 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001212
1213 /* Set E to 2^(E_bytes - 1) + 1 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001214 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1215 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1216 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001217
1218 /* Set N to 2^(N_bytes - 1) + 1 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001219 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1220 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1221 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001222
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001223 if (strlen(input_RR))
1224 TEST_ASSERT(mbedtls_test_read_mpi(&RR, radix_RR, input_RR) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001225
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001226 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Chris Jonesd10b3312020-12-02 10:41:50 +00001227
1228exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001229 mbedtls_mpi_free(&A);
1230 mbedtls_mpi_free(&E);
1231 mbedtls_mpi_free(&N);
1232 mbedtls_mpi_free(&RR);
1233 mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001234}
1235/* END_CASE */
1236
1237/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001238void mbedtls_mpi_inv_mod(int radix_X,
1239 char *input_X,
1240 int radix_Y,
1241 char *input_Y,
1242 int radix_A,
1243 char *input_A,
1244 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001245{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001246 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001247 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001248 mbedtls_mpi_init(&X);
1249 mbedtls_mpi_init(&Y);
1250 mbedtls_mpi_init(&Z);
1251 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001252
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001253 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1254 TEST_ASSERT(mbedtls_test_read_mpi(&Y, radix_Y, input_Y) == 0);
1255 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1256 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1257 TEST_ASSERT(res == div_result);
1258 if (res == 0) {
1259 TEST_ASSERT(sign_is_valid(&Z));
1260 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001261 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001262
Paul Bakkerbd51b262014-07-10 15:26:12 +02001263exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001264 mbedtls_mpi_free(&X);
1265 mbedtls_mpi_free(&Y);
1266 mbedtls_mpi_free(&Z);
1267 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001268}
Paul Bakker33b43f12013-08-20 11:48:36 +02001269/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001270
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001271/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001272void mbedtls_mpi_is_prime(int radix_X, char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001273{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001274 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001275 int res;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001276 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001277
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001278 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1279 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1280 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001281
Paul Bakkerbd51b262014-07-10 15:26:12 +02001282exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001283 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001284}
Paul Bakker33b43f12013-08-20 11:48:36 +02001285/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001286
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001287/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001288void mbedtls_mpi_is_prime_det(data_t *input_X,
1289 data_t *witnesses,
1290 int chunk_len,
1291 int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001292{
1293 mbedtls_mpi X;
1294 int res;
1295 mbedtls_test_mpi_random rand;
1296
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001297 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001298 rand.data = witnesses;
1299 rand.pos = 0;
1300 rand.chunk_len = chunk_len;
1301
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001302 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1303 res = mbedtls_mpi_is_prime_ext(
1304 &X, rounds - 1, mbedtls_test_mpi_miller_rabin_determinizer, &rand);
1305 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001306
1307 rand.data = witnesses;
1308 rand.pos = 0;
1309 rand.chunk_len = chunk_len;
1310
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001311 res = mbedtls_mpi_is_prime_ext(
1312 &X, rounds, mbedtls_test_mpi_miller_rabin_determinizer, &rand);
1313 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001314
1315exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001316 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001317}
1318/* END_CASE */
1319
1320/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001321void mbedtls_mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001322{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001323 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001324 int my_ret;
1325
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001326 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001327
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001328 my_ret =
1329 mbedtls_mpi_gen_prime(&X, bits, flags, mbedtls_test_rnd_std_rand, NULL);
1330 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001331
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001332 if (ref_ret == 0) {
1333 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001334
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001335 TEST_ASSERT(actual_bits >= (size_t)bits);
1336 TEST_ASSERT(actual_bits <= (size_t)bits + 1);
1337 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001338
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001339 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand,
1340 NULL) == 0);
1341 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001342 /* X = ( X - 1 ) / 2 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001343 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1344 TEST_ASSERT(mbedtls_mpi_is_prime_ext(
1345 &X, 40, mbedtls_test_rnd_std_rand, NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001346 }
1347 }
1348
Paul Bakkerbd51b262014-07-10 15:26:12 +02001349exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001350 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001351}
1352/* END_CASE */
1353
Paul Bakker33b43f12013-08-20 11:48:36 +02001354/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001355void mbedtls_mpi_shift_l(int radix_X,
1356 char *input_X,
1357 int shift_X,
1358 int radix_A,
1359 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001360{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001361 mbedtls_mpi X, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001362 mbedtls_mpi_init(&X);
1363 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001364
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001365 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1366 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1367 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1368 TEST_ASSERT(sign_is_valid(&X));
1369 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001370
Paul Bakkerbd51b262014-07-10 15:26:12 +02001371exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001372 mbedtls_mpi_free(&X);
1373 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001374}
Paul Bakker33b43f12013-08-20 11:48:36 +02001375/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001376
Paul Bakker33b43f12013-08-20 11:48:36 +02001377/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001378void mbedtls_mpi_shift_r(int radix_X,
1379 char *input_X,
1380 int shift_X,
1381 int radix_A,
1382 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001383{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384 mbedtls_mpi X, A;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001385 mbedtls_mpi_init(&X);
1386 mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001387
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001388 TEST_ASSERT(mbedtls_test_read_mpi(&X, radix_X, input_X) == 0);
1389 TEST_ASSERT(mbedtls_test_read_mpi(&A, radix_A, input_A) == 0);
1390 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1391 TEST_ASSERT(sign_is_valid(&X));
1392 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001393
Paul Bakkerbd51b262014-07-10 15:26:12 +02001394exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001395 mbedtls_mpi_free(&X);
1396 mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001397}
Paul Bakker33b43f12013-08-20 11:48:36 +02001398/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001399
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001400/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001401void mpi_fill_random(int wanted_bytes,
1402 int rng_bytes,
1403 int before,
1404 int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001405{
1406 mbedtls_mpi X;
1407 int ret;
1408 size_t bytes_left = rng_bytes;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001409 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001410
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001411 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001412 /* Set X to sign(before) * 2^(|before|-1) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001413 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1414 if (before < 0)
1415 before = -before;
1416 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001417 }
1418
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001419 ret = mbedtls_mpi_fill_random(&X, wanted_bytes, f_rng_bytes_left,
1420 &bytes_left);
1421 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001422
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001423 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001424 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1425 * as a big-endian representation of the number. We know when
1426 * our RNG function returns null bytes, so we know how many
1427 * leading zero bytes the number has. */
1428 size_t leading_zeros = 0;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001429 if (wanted_bytes > 0 && rng_bytes % 256 == 0)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001430 leading_zeros = 1;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001431 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1432 (size_t)wanted_bytes);
1433 TEST_ASSERT((int)bytes_left == rng_bytes - wanted_bytes);
1434 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001435 }
1436
1437exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001438 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001439}
1440/* END_CASE */
1441
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001442/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001443void mpi_random_many(int min, data_t *bound_bytes, int iterations)
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001444{
1445 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1446 * This function assumes that the value of bound is at least 2 and
1447 * that iterations is large enough that a one-in-2^iterations chance
1448 * effectively never occurs.
1449 */
1450
1451 mbedtls_mpi upper_bound;
1452 size_t n_bits;
1453 mbedtls_mpi result;
1454 size_t b;
1455 /* If upper_bound is small, stats[b] is the number of times the value b
1456 * has been generated. Otherwise stats[b] is the number of times a
1457 * value with bit b set has been generated. */
1458 size_t *stats = NULL;
1459 size_t stats_len;
1460 int full_stats;
1461 size_t i;
1462
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001463 mbedtls_mpi_init(&upper_bound);
1464 mbedtls_mpi_init(&result);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001465
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001466 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound, bound_bytes->x,
1467 bound_bytes->len));
1468 n_bits = mbedtls_mpi_bitlen(&upper_bound);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001469 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1470 * to be small enough that the probability of missing one value is
1471 * negligible given the number of iterations. It must be less than
1472 * 256 because some of the code below assumes that "small" values
1473 * fit in a byte. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001474 if (n_bits <= 5) {
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001475 full_stats = 1;
1476 stats_len = bound_bytes->x[bound_bytes->len - 1];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001477 } else {
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001478 full_stats = 0;
1479 stats_len = n_bits;
1480 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001481 ASSERT_ALLOC(stats, stats_len);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001482
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001483 for (i = 0; i < (size_t)iterations; i++) {
1484 mbedtls_test_set_step(i);
1485 TEST_EQUAL(0, mbedtls_mpi_random(&result, min, &upper_bound,
1486 mbedtls_test_rnd_std_rand, NULL));
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001487
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001488 TEST_ASSERT(sign_is_valid(&result));
1489 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&result, &upper_bound) < 0);
1490 TEST_ASSERT(mbedtls_mpi_cmp_int(&result, min) >= 0);
1491 if (full_stats) {
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001492 uint8_t value;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001493 TEST_EQUAL(0, mbedtls_mpi_write_binary(&result, &value, 1));
1494 TEST_ASSERT(value < stats_len);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001495 ++stats[value];
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001496 } else {
1497 for (b = 0; b < n_bits; b++)
1498 stats[b] += mbedtls_mpi_get_bit(&result, b);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001499 }
1500 }
1501
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001502 if (full_stats) {
1503 for (b = min; b < stats_len; b++) {
1504 mbedtls_test_set_step(1000000 + b);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001505 /* Assert that each value has been reached at least once.
1506 * This is almost guaranteed if the iteration count is large
1507 * enough. This is a very crude way of checking the distribution.
1508 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001509 TEST_ASSERT(stats[b] > 0);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001510 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001511 } else {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001512 int statistically_safe_all_the_way =
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001513 is_significantly_above_a_power_of_2(bound_bytes);
1514 for (b = 0; b < n_bits; b++) {
1515 mbedtls_test_set_step(1000000 + b);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001516 /* Assert that each bit has been set in at least one result and
1517 * clear in at least one result. Provided that iterations is not
1518 * too small, it would be extremely unlikely for this not to be
1519 * the case if the results are uniformly distributed.
1520 *
1521 * As an exception, the top bit may legitimately never be set
1522 * if bound is a power of 2 or only slightly above.
1523 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001524 if (statistically_safe_all_the_way || b != n_bits - 1) {
1525 TEST_ASSERT(stats[b] > 0);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001526 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001527 TEST_ASSERT(stats[b] < (size_t)iterations);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001528 }
1529 }
1530
1531exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001532 mbedtls_mpi_free(&upper_bound);
1533 mbedtls_mpi_free(&result);
1534 mbedtls_free(stats);
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001535}
1536/* END_CASE */
1537
Gilles Peskine1e918f42021-03-29 22:14:51 +02001538/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001539void mpi_random_sizes(int min, data_t *bound_bytes, int nlimbs, int before)
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001540{
1541 mbedtls_mpi upper_bound;
1542 mbedtls_mpi result;
1543
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001544 mbedtls_mpi_init(&upper_bound);
1545 mbedtls_mpi_init(&result);
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001546
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001547 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001548 /* Set result to sign(before) * 2^(|before|-1) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001549 TEST_ASSERT(mbedtls_mpi_lset(&result, before > 0 ? 1 : -1) == 0);
1550 if (before < 0)
1551 before = -before;
1552 TEST_ASSERT(mbedtls_mpi_shift_l(&result, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001553 }
1554
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001555 TEST_EQUAL(0, mbedtls_mpi_grow(&result, nlimbs));
1556 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound, bound_bytes->x,
1557 bound_bytes->len));
1558 TEST_EQUAL(0, mbedtls_mpi_random(&result, min, &upper_bound,
1559 mbedtls_test_rnd_std_rand, NULL));
1560 TEST_ASSERT(sign_is_valid(&result));
1561 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&result, &upper_bound) < 0);
1562 TEST_ASSERT(mbedtls_mpi_cmp_int(&result, min) >= 0);
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001563
1564exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001565 mbedtls_mpi_free(&upper_bound);
1566 mbedtls_mpi_free(&result);
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001567}
1568/* END_CASE */
1569
1570/* BEGIN_CASE */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001571void mpi_random_fail(int min, data_t *bound_bytes, int expected_ret)
Gilles Peskine1e918f42021-03-29 22:14:51 +02001572{
1573 mbedtls_mpi upper_bound;
1574 mbedtls_mpi result;
1575 int actual_ret;
1576
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001577 mbedtls_mpi_init(&upper_bound);
1578 mbedtls_mpi_init(&result);
Gilles Peskine1e918f42021-03-29 22:14:51 +02001579
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001580 TEST_EQUAL(0, mbedtls_mpi_read_binary(&upper_bound, bound_bytes->x,
1581 bound_bytes->len));
1582 actual_ret = mbedtls_mpi_random(&result, min, &upper_bound,
1583 mbedtls_test_rnd_std_rand, NULL);
1584 TEST_EQUAL(expected_ret, actual_ret);
Gilles Peskine1e918f42021-03-29 22:14:51 +02001585
1586exit:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001587 mbedtls_mpi_free(&upper_bound);
1588 mbedtls_mpi_free(&result);
Gilles Peskine1e918f42021-03-29 22:14:51 +02001589}
1590/* END_CASE */
1591
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001592/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001593void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001594{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001595 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001596}
Paul Bakker33b43f12013-08-20 11:48:36 +02001597/* END_CASE */