blob: 36f1476d76c5153ad6142837e732ed88d3800bf6 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/bignum.h"
Gilles Peskine3cb1e292020-11-25 15:37:20 +01003#include "mbedtls/entropy.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01004#include "constant_time_internal.h"
Gilles Peskine34e8a2c2022-09-27 22:04:51 +02005#include "bignum_core.h"
Janos Follath5f316972024-08-22 14:53:13 +01006#include "bignum_internal.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01007#include "test/constant_flow.h"
Janos Follath96cfd7a2024-08-22 18:30:06 +01008#include "test/bignum_codepath_check.h"
Janos Follath64eca052018-09-05 17:04:49 +01009
Chris Jonese64a46f2020-12-03 17:44:03 +000010#if MBEDTLS_MPI_MAX_BITS > 792
11#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000012#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020013
Gilles Peskinedffc7102021-06-10 15:34:15 +020014/* Check the validity of the sign bit in an MPI object. Reject representations
15 * that are not supported by the rest of the library and indicate a bug when
16 * constructing the value. */
Gilles Peskine449bd832023-01-11 14:50:10 +010017static int sign_is_valid(const mbedtls_mpi *X)
Gilles Peskinedffc7102021-06-10 15:34:15 +020018{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010019 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskine449bd832023-01-11 14:50:10 +010020 if (X->s != 1 && X->s != -1) {
21 return 0;
22 }
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010023
24 /* The value 0 must be represented with the sign +1. A "negative zero"
25 * with s=-1 is an invalid representation. Forbid that. As an exception,
26 * we sometimes test the robustness of library functions when given
27 * a negative zero input. If a test case has a negative zero as input,
28 * we don't mind if the function has a negative zero output. */
Paul Elliottc7a1e992023-11-03 18:44:57 +000029 if (!mbedtls_test_get_case_uses_negative_0() &&
Gilles Peskine449bd832023-01-11 14:50:10 +010030 mbedtls_mpi_bitlen(X) == 0 && X->s != 1) {
31 return 0;
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010032 }
33
Gilles Peskine449bd832023-01-11 14:50:10 +010034 return 1;
Gilles Peskinedffc7102021-06-10 15:34:15 +020035}
36
Michael Schuster275b6982024-06-07 01:51:54 +020037#if defined(MBEDTLS_GENPRIME)
Gilles Peskine449bd832023-01-11 14:50:10 +010038typedef struct mbedtls_test_mpi_random {
Janos Follath64eca052018-09-05 17:04:49 +010039 data_t *data;
40 size_t pos;
41 size_t chunk_len;
42} mbedtls_test_mpi_random;
43
44/*
45 * This function is called by the Miller-Rabin primality test each time it
46 * chooses a random witness. The witnesses (or non-witnesses as provided by the
47 * test) are stored in the data member of the state structure. Each number is in
48 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
49 */
Michael Schusterb1e33fb2024-06-04 02:30:22 +020050static int mbedtls_test_mpi_miller_rabin_determinizer(void *state,
Michael Schuster31b1cb82024-06-04 02:41:10 +020051 unsigned char *buf,
52 size_t len)
Janos Follath64eca052018-09-05 17:04:49 +010053{
Gilles Peskine449bd832023-01-11 14:50:10 +010054 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random *) state;
Janos Follath64eca052018-09-05 17:04:49 +010055
Gilles Peskine449bd832023-01-11 14:50:10 +010056 if (random == NULL || random->data->x == NULL || buf == NULL) {
57 return -1;
Janos Follath64eca052018-09-05 17:04:49 +010058 }
59
Gilles Peskine449bd832023-01-11 14:50:10 +010060 if (random->pos + random->chunk_len > random->data->len
61 || random->chunk_len > len) {
62 return -1;
63 }
64
65 memset(buf, 0, len);
Janos Follath64eca052018-09-05 17:04:49 +010066
67 /* The witness is written to the end of the buffer, since the buffer is
68 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
69 * Writing the witness to the start of the buffer would result in the
70 * buffer being 'witness 000...000', which would be treated as
71 * witness * 2^n for some n. */
Gilles Peskine449bd832023-01-11 14:50:10 +010072 memcpy(buf + len - random->chunk_len, &random->data->x[random->pos],
73 random->chunk_len);
Janos Follath64eca052018-09-05 17:04:49 +010074
75 random->pos += random->chunk_len;
76
Gilles Peskine449bd832023-01-11 14:50:10 +010077 return 0;
Janos Follath64eca052018-09-05 17:04:49 +010078}
Michael Schuster275b6982024-06-07 01:51:54 +020079#endif /* MBEDTLS_GENPRIME */
Gilles Peskine3cb1e292020-11-25 15:37:20 +010080
81/* Random generator that is told how many bytes to return. */
Gilles Peskine449bd832023-01-11 14:50:10 +010082static int f_rng_bytes_left(void *state, unsigned char *buf, size_t len)
Gilles Peskine3cb1e292020-11-25 15:37:20 +010083{
84 size_t *bytes_left = state;
85 size_t i;
Gilles Peskine449bd832023-01-11 14:50:10 +010086 for (i = 0; i < len; i++) {
87 if (*bytes_left == 0) {
88 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
89 }
Gilles Peskine3cb1e292020-11-25 15:37:20 +010090 buf[i] = *bytes_left & 0xff;
Gilles Peskine449bd832023-01-11 14:50:10 +010091 --(*bytes_left);
Gilles Peskine3cb1e292020-11-25 15:37:20 +010092 }
Gilles Peskine449bd832023-01-11 14:50:10 +010093 return 0;
Gilles Peskine3cb1e292020-11-25 15:37:20 +010094}
95
Paul Bakker33b43f12013-08-20 11:48:36 +020096/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000097
Paul Bakker33b43f12013-08-20 11:48:36 +020098/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200100 * END_DEPENDENCIES
101 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000102
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000103/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100104void mpi_null()
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200105{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200106 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200107
Gilles Peskine449bd832023-01-11 14:50:10 +0100108 mbedtls_mpi_init(&X);
109 mbedtls_mpi_init(&Y);
110 mbedtls_mpi_init(&Z);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200111
Gilles Peskine449bd832023-01-11 14:50:10 +0100112 TEST_ASSERT(mbedtls_mpi_get_bit(&X, 42) == 0);
113 TEST_ASSERT(mbedtls_mpi_lsb(&X) == 0);
114 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == 0);
115 TEST_ASSERT(mbedtls_mpi_size(&X) == 0);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200116
117exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100118 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200119}
120/* END_CASE */
121
122/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100123void mpi_read_write_string(int radix_X, char *input_X, int radix_A,
124 char *input_A, int output_size, int result_read,
125 int result_write)
Paul Bakker367dae42009-06-28 21:50:27 +0000126{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000128 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100129 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000130
Gilles Peskine449bd832023-01-11 14:50:10 +0100131 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000132
Gilles Peskine449bd832023-01-11 14:50:10 +0100133 memset(str, '!', sizeof(str));
Janos Follath04dadb72019-03-06 12:29:37 +0000134
Gilles Peskine449bd832023-01-11 14:50:10 +0100135 TEST_ASSERT(mbedtls_mpi_read_string(&X, radix_X, input_X) == result_read);
136 if (result_read == 0) {
137 TEST_ASSERT(sign_is_valid(&X));
138 TEST_ASSERT(mbedtls_mpi_write_string(&X, radix_A, str, output_size, &len) == result_write);
139 if (result_write == 0) {
Gilles Peskine017f0b72022-12-04 13:29:20 +0100140 TEST_ASSERT(strcmp(str, input_A) == 0);
Gilles Peskine449bd832023-01-11 14:50:10 +0100141 TEST_ASSERT(str[len] == '!');
Paul Bakkerba48cb22009-07-12 11:01:32 +0000142 }
143 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000144
Paul Bakkerbd51b262014-07-10 15:26:12 +0200145exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100146 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000147}
Paul Bakker33b43f12013-08-20 11:48:36 +0200148/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000149
Paul Bakker33b43f12013-08-20 11:48:36 +0200150/* BEGIN_CASE */
Valerio Settif988f952024-01-30 14:40:31 +0100151void mpi_zero_length_buffer_is_null()
152{
153 mbedtls_mpi X;
154 size_t olen;
155
156 mbedtls_mpi_init(&X);
157
158 /* Simply test that the following functions do not crash when a NULL buffer
159 * pointer and 0 length is passed. We don't care much about the return value. */
160 TEST_EQUAL(mbedtls_mpi_read_binary(&X, NULL, 0), 0);
161 TEST_EQUAL(mbedtls_mpi_read_binary_le(&X, NULL, 0), 0);
162 TEST_EQUAL(mbedtls_mpi_write_string(&X, 16, NULL, 0, &olen), MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
163 TEST_EQUAL(mbedtls_mpi_write_binary(&X, NULL, 0), 0);
164
165exit:
166 mbedtls_mpi_free(&X);
167}
168/* END_CASE */
169
170/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100171void mpi_read_binary(data_t *buf, char *input_A)
Paul Bakkere896fea2009-07-06 06:40:23 +0000172{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000174 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100175 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000176
Gilles Peskine449bd832023-01-11 14:50:10 +0100177 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000178
Paul Bakkere896fea2009-07-06 06:40:23 +0000179
Gilles Peskine449bd832023-01-11 14:50:10 +0100180 TEST_ASSERT(mbedtls_mpi_read_binary(&X, buf->x, buf->len) == 0);
181 TEST_ASSERT(sign_is_valid(&X));
182 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
183 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000184
Paul Bakkerbd51b262014-07-10 15:26:12 +0200185exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100186 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000187}
Paul Bakker33b43f12013-08-20 11:48:36 +0200188/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000189
Paul Bakker33b43f12013-08-20 11:48:36 +0200190/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100191void mpi_read_binary_le(data_t *buf, char *input_A)
Janos Follatha778a942019-02-13 10:28:28 +0000192{
193 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000194 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000195 size_t len;
196
Gilles Peskine449bd832023-01-11 14:50:10 +0100197 mbedtls_mpi_init(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000198
199
Gilles Peskine449bd832023-01-11 14:50:10 +0100200 TEST_ASSERT(mbedtls_mpi_read_binary_le(&X, buf->x, buf->len) == 0);
201 TEST_ASSERT(sign_is_valid(&X));
202 TEST_ASSERT(mbedtls_mpi_write_string(&X, 16, str, sizeof(str), &len) == 0);
203 TEST_ASSERT(strcmp((char *) str, input_A) == 0);
Janos Follatha778a942019-02-13 10:28:28 +0000204
205exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100206 mbedtls_mpi_free(&X);
Janos Follatha778a942019-02-13 10:28:28 +0000207}
208/* END_CASE */
209
210/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100211void mpi_write_binary(char *input_X, data_t *input_A,
212 int output_size, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000213{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200214 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100215 mbedtls_mpi_init(&X);
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200216 unsigned char *buf = NULL;
Paul Bakkere896fea2009-07-06 06:40:23 +0000217
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200218 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100219
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200220 TEST_CALLOC(buf, output_size);
Paul Bakkere896fea2009-07-06 06:40:23 +0000221
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200222 TEST_EQUAL(mbedtls_mpi_write_binary(&X, buf, output_size), result);
223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 if (result == 0) {
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200225 TEST_EQUAL(mbedtls_test_hexcmp(buf, input_A->x,
226 output_size, input_A->len), 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000227 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000228
Paul Bakkerbd51b262014-07-10 15:26:12 +0200229exit:
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200230 mbedtls_free(buf);
Gilles Peskine449bd832023-01-11 14:50:10 +0100231 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000232}
Paul Bakker33b43f12013-08-20 11:48:36 +0200233/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000234
Janos Follathe344d0f2019-02-19 16:17:40 +0000235/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100236void mpi_write_binary_le(char *input_X, data_t *input_A,
237 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000238{
239 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100240 mbedtls_mpi_init(&X);
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200241 unsigned char *buf = NULL;
Janos Follathe344d0f2019-02-19 16:17:40 +0000242
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200243 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000244
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200245 TEST_CALLOC(buf, output_size);
Janos Follathe344d0f2019-02-19 16:17:40 +0000246
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200247 TEST_EQUAL(mbedtls_mpi_write_binary_le(&X, buf, output_size), result);
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 if (result == 0) {
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200250 TEST_EQUAL(mbedtls_test_hexcmp(buf, input_A->x,
251 output_size, input_A->len), 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000252 }
253
254exit:
Gilles Peskine4eafc9c2024-10-04 18:07:55 +0200255 mbedtls_free(buf);
Gilles Peskine449bd832023-01-11 14:50:10 +0100256 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000257}
258/* END_CASE */
259
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100261void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000262{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200263 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000264 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000265 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000266 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000267 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000268
Gilles Peskine449bd832023-01-11 14:50:10 +0100269 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000270
Gilles Peskine449bd832023-01-11 14:50:10 +0100271 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000272
Gilles Peskine449bd832023-01-11 14:50:10 +0100273 file = fopen(input_file, "r");
274 TEST_ASSERT(file != NULL);
275 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000276 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100277 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000278
Gilles Peskine449bd832023-01-11 14:50:10 +0100279 if (result == 0) {
280 TEST_ASSERT(sign_is_valid(&X));
281 buflen = mbedtls_mpi_size(&X);
282 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000283
Paul Bakkere896fea2009-07-06 06:40:23 +0000284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
286 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000287 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000288
Paul Bakkerbd51b262014-07-10 15:26:12 +0200289exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100290 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000291}
Paul Bakker33b43f12013-08-20 11:48:36 +0200292/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100295void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000296{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000298 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200299 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000300
Gilles Peskine449bd832023-01-11 14:50:10 +0100301 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
Gilles Peskine449bd832023-01-11 14:50:10 +0100303 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000304
Gilles Peskine449bd832023-01-11 14:50:10 +0100305 file_out = fopen(output_file, "w");
306 TEST_ASSERT(file_out != NULL);
307 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000308 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100309 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000310
Gilles Peskine449bd832023-01-11 14:50:10 +0100311 file_in = fopen(output_file, "r");
312 TEST_ASSERT(file_in != NULL);
313 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000314 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000318
Paul Bakkerbd51b262014-07-10 15:26:12 +0200319exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100320 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000321}
Paul Bakker33b43f12013-08-20 11:48:36 +0200322/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000323
Paul Bakker33b43f12013-08-20 11:48:36 +0200324/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100325void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000326{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100328 mbedtls_mpi_init(&X);
329 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
330 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000331
Paul Bakkerbd51b262014-07-10 15:26:12 +0200332exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100333 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000334}
Paul Bakker33b43f12013-08-20 11:48:36 +0200335/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000336
Paul Bakker33b43f12013-08-20 11:48:36 +0200337/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100338void mpi_set_bit(char *input_X, int pos, int val,
339 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000340{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100342 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000343
Gilles Peskine449bd832023-01-11 14:50:10 +0100344 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
345 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
346 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100347
Gilles Peskine449bd832023-01-11 14:50:10 +0100348 if (result == 0) {
349 TEST_ASSERT(sign_is_valid(&X));
350 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100351 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000352
Paul Bakkerbd51b262014-07-10 15:26:12 +0200353exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000355}
Paul Bakker33b43f12013-08-20 11:48:36 +0200356/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000357
Paul Bakker33b43f12013-08-20 11:48:36 +0200358/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100359void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000360{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100362 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000363
Gilles Peskine449bd832023-01-11 14:50:10 +0100364 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
365 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000366
Paul Bakkerbd51b262014-07-10 15:26:12 +0200367exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100368 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000369}
Paul Bakker33b43f12013-08-20 11:48:36 +0200370/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000371
Paul Bakker33b43f12013-08-20 11:48:36 +0200372/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100373void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000374{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000377
Gilles Peskine449bd832023-01-11 14:50:10 +0100378 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
379 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000380
Paul Bakkerbd51b262014-07-10 15:26:12 +0200381exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100382 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000383}
Paul Bakker33b43f12013-08-20 11:48:36 +0200384/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000385
Paul Bakker33b43f12013-08-20 11:48:36 +0200386/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100387void mpi_gcd(char *input_X, char *input_Y,
388 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000389{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100391 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000392
Gilles Peskine449bd832023-01-11 14:50:10 +0100393 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
394 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
395 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
396 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
397 TEST_ASSERT(sign_is_valid(&Z));
398 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000399
Paul Bakkerbd51b262014-07-10 15:26:12 +0200400exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100401 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000402}
Paul Bakker33b43f12013-08-20 11:48:36 +0200403/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000404
Paul Bakker33b43f12013-08-20 11:48:36 +0200405/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100406void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000407{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100409 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000410
Gilles Peskine449bd832023-01-11 14:50:10 +0100411 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
412 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000413
Paul Bakkerbd51b262014-07-10 15:26:12 +0200414exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100415 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000416}
Paul Bakker33b43f12013-08-20 11:48:36 +0200417/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000418
Paul Bakker33b43f12013-08-20 11:48:36 +0200419/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100420void mpi_cmp_mpi(char *input_X, char *input_Y,
421 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000422{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100424 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000425
Gilles Peskine449bd832023-01-11 14:50:10 +0100426 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
427 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
428 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000429
Paul Bakkerbd51b262014-07-10 15:26:12 +0200430exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100431 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000432}
Paul Bakker33b43f12013-08-20 11:48:36 +0200433/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000434
Paul Bakker33b43f12013-08-20 11:48:36 +0200435/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100436void mpi_lt_mpi_ct(int size_X, char *input_X,
437 int size_Y, char *input_Y,
438 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100439{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200440 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100441 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100442 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100444
Gilles Peskine449bd832023-01-11 14:50:10 +0100445 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
446 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100447
Gilles Peskine449bd832023-01-11 14:50:10 +0100448 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
449 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100450
Gilles Peskine449bd832023-01-11 14:50:10 +0100451 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
452 if (input_err == 0) {
Dave Rodgman14bec142023-05-11 16:19:27 +0100453 TEST_EQUAL(ret, input_uret);
Gilles Peskine449bd832023-01-11 14:50:10 +0100454 }
Janos Follath385d5b82019-09-11 16:07:14 +0100455
456exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100458}
459/* END_CASE */
460
461/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100462void mpi_cmp_abs(char *input_X, char *input_Y,
463 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000464{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000467
Gilles Peskine449bd832023-01-11 14:50:10 +0100468 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
469 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
470 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000471
Paul Bakkerbd51b262014-07-10 15:26:12 +0200472exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100473 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000474}
Paul Bakker33b43f12013-08-20 11:48:36 +0200475/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000476
Paul Bakker33b43f12013-08-20 11:48:36 +0200477/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100478void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000479{
Gilles Peskined0722f82021-06-10 23:00:33 +0200480 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100481 mbedtls_mpi_init(&src);
482 mbedtls_mpi_init(&dst);
483 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000484
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
486 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200487
488 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100489 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
490 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
491 TEST_ASSERT(sign_is_valid(&dst));
492 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000493
Gilles Peskined0722f82021-06-10 23:00:33 +0200494 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100495 mbedtls_mpi_free(&dst);
496 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
497 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
498 TEST_ASSERT(sign_is_valid(&dst));
499 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200500
501 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100502 mbedtls_mpi_free(&dst);
503 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
504 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
505 TEST_ASSERT(sign_is_valid(&dst));
506 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200507
Paul Bakkerbd51b262014-07-10 15:26:12 +0200508exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100509 mbedtls_mpi_free(&src);
510 mbedtls_mpi_free(&dst);
511 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100512}
513/* END_CASE */
514
515/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100516void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100517{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200518 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100519 mbedtls_mpi_init(&A);
520 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000521
Gilles Peskine449bd832023-01-11 14:50:10 +0100522 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
523 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200524
Gilles Peskine449bd832023-01-11 14:50:10 +0100525 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
526 TEST_ASSERT(sign_is_valid(&X));
527 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000528
Paul Bakkerbd51b262014-07-10 15:26:12 +0200529exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100530 mbedtls_mpi_free(&A);
531 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000532}
Paul Bakker33b43f12013-08-20 11:48:36 +0200533/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000534
Paul Bakker33b43f12013-08-20 11:48:36 +0200535/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100536void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200537{
538 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100539 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
540 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200541
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
543 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200544
Gilles Peskined0722f82021-06-10 23:00:33 +0200545 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100546 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
547 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
548 mbedtls_mpi_swap(&X, &Y);
549 TEST_ASSERT(sign_is_valid(&X));
550 TEST_ASSERT(sign_is_valid(&Y));
551 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
552 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200553
Gilles Peskined0722f82021-06-10 23:00:33 +0200554 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100555 mbedtls_mpi_free(&X);
556 mbedtls_mpi_free(&Y);
557 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
558 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
559 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
560 TEST_ASSERT(sign_is_valid(&X));
561 TEST_ASSERT(sign_is_valid(&Y));
562 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
563 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200564
565 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100566 mbedtls_mpi_free(&X);
567 mbedtls_mpi_free(&Y);
568 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
569 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
570 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
571 TEST_ASSERT(sign_is_valid(&X));
572 TEST_ASSERT(sign_is_valid(&Y));
573 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
574 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200575
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200576exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100577 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
578 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200579}
580/* END_CASE */
581
582/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100583void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200584{
585 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100586 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200587
Gilles Peskine449bd832023-01-11 14:50:10 +0100588 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
589 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200590
Gilles Peskine449bd832023-01-11 14:50:10 +0100591 mbedtls_mpi_swap(&X, &X);
592 TEST_ASSERT(sign_is_valid(&X));
593 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200594
595exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100596 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200597}
598/* END_CASE */
599
600/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100601void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100602{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100604 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100605
Gilles Peskine449bd832023-01-11 14:50:10 +0100606 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
607 if (used > 0) {
608 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
609 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200610 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100611 TEST_EQUAL(X.n, (size_t) before);
612 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
613 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100614
Paul Bakkerbd51b262014-07-10 15:26:12 +0200615exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100617}
618/* END_CASE */
619
620/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100621void mpi_add_mpi(char *input_X, char *input_Y,
622 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000623{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100625 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000626
Gilles Peskine449bd832023-01-11 14:50:10 +0100627 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
628 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
629 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
630 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
631 TEST_ASSERT(sign_is_valid(&Z));
632 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000633
Gilles Peskine56f943a2020-07-23 01:18:11 +0200634 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100635 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
636 TEST_ASSERT(sign_is_valid(&X));
637 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
638 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200639
640 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100641 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
642 TEST_ASSERT(sign_is_valid(&Y));
643 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200644
Paul Bakkerbd51b262014-07-10 15:26:12 +0200645exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100646 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000647}
Paul Bakker33b43f12013-08-20 11:48:36 +0200648/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000649
Paul Bakker33b43f12013-08-20 11:48:36 +0200650/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100651void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100652{
653 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100654 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100655
Gilles Peskine449bd832023-01-11 14:50:10 +0100656 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100657
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
659 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
660 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
661 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100662
Gilles Peskine449bd832023-01-11 14:50:10 +0100663 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
664 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
665 TEST_ASSERT(sign_is_valid(&X));
666 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
669 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
670 TEST_ASSERT(sign_is_valid(&X));
671 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100672
673exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100674 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100675}
676/* END_CASE */
677
678
679/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100680void mpi_add_abs(char *input_X, char *input_Y,
681 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000682{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100684 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000685
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
687 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
688 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
689 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
690 TEST_ASSERT(sign_is_valid(&Z));
691 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000692
Gilles Peskine56f943a2020-07-23 01:18:11 +0200693 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100694 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
695 TEST_ASSERT(sign_is_valid(&X));
696 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
697 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200698
699 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100700 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
701 TEST_ASSERT(sign_is_valid(&Y));
702 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000703
Paul Bakkerbd51b262014-07-10 15:26:12 +0200704exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100705 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000706}
Paul Bakker33b43f12013-08-20 11:48:36 +0200707/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000708
Paul Bakker33b43f12013-08-20 11:48:36 +0200709/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100710void mpi_add_int(char *input_X, int input_Y,
711 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000712{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100714 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000715
Gilles Peskine449bd832023-01-11 14:50:10 +0100716 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
717 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
718 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
719 TEST_ASSERT(sign_is_valid(&Z));
720 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000721
Paul Bakkerbd51b262014-07-10 15:26:12 +0200722exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100723 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000724}
Paul Bakker33b43f12013-08-20 11:48:36 +0200725/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000726
Paul Bakker33b43f12013-08-20 11:48:36 +0200727/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100728void mpi_sub_mpi(char *input_X, char *input_Y,
729 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000730{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100732 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000733
Gilles Peskine449bd832023-01-11 14:50:10 +0100734 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
735 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
736 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
737 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
738 TEST_ASSERT(sign_is_valid(&Z));
739 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000740
Gilles Peskine56f943a2020-07-23 01:18:11 +0200741 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100742 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
743 TEST_ASSERT(sign_is_valid(&X));
744 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
745 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200746
747 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100748 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
749 TEST_ASSERT(sign_is_valid(&Y));
750 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200751
Paul Bakkerbd51b262014-07-10 15:26:12 +0200752exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100753 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000754}
Paul Bakker33b43f12013-08-20 11:48:36 +0200755/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000756
Paul Bakker33b43f12013-08-20 11:48:36 +0200757/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100758void mpi_sub_abs(char *input_X, char *input_Y,
759 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000760{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000762 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100763 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000764
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
766 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
767 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100768
Gilles Peskine449bd832023-01-11 14:50:10 +0100769 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
770 TEST_ASSERT(res == sub_result);
771 TEST_ASSERT(sign_is_valid(&Z));
772 if (res == 0) {
773 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
774 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000775
Gilles Peskine56f943a2020-07-23 01:18:11 +0200776 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
778 TEST_ASSERT(sign_is_valid(&X));
779 if (sub_result == 0) {
780 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
781 }
782 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200783
784 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100785 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
786 TEST_ASSERT(sign_is_valid(&Y));
787 if (sub_result == 0) {
788 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
789 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200790
Paul Bakkerbd51b262014-07-10 15:26:12 +0200791exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100792 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000793}
Paul Bakker33b43f12013-08-20 11:48:36 +0200794/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000795
Paul Bakker33b43f12013-08-20 11:48:36 +0200796/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100797void mpi_sub_int(char *input_X, int input_Y,
798 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000799{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100801 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000802
Gilles Peskine449bd832023-01-11 14:50:10 +0100803 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
804 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
805 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
806 TEST_ASSERT(sign_is_valid(&Z));
807 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000808
Paul Bakkerbd51b262014-07-10 15:26:12 +0200809exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100810 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000811}
Paul Bakker33b43f12013-08-20 11:48:36 +0200812/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000813
Paul Bakker33b43f12013-08-20 11:48:36 +0200814/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100815void mpi_mul_mpi(char *input_X, char *input_Y,
816 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000817{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100819 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000820
Gilles Peskine449bd832023-01-11 14:50:10 +0100821 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
822 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
823 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
824 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
825 TEST_ASSERT(sign_is_valid(&Z));
826 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000827
Paul Bakkerbd51b262014-07-10 15:26:12 +0200828exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100829 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000830}
Paul Bakker33b43f12013-08-20 11:48:36 +0200831/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000832
Paul Bakker33b43f12013-08-20 11:48:36 +0200833/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100834void mpi_mul_int(char *input_X, int input_Y,
835 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000836{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100838 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000839
Gilles Peskine449bd832023-01-11 14:50:10 +0100840 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
841 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
842 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
843 TEST_ASSERT(sign_is_valid(&Z));
844 if (strcmp(result_comparison, "==") == 0) {
845 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
846 } else if (strcmp(result_comparison, "!=") == 0) {
847 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
848 } else {
Agathiyan Bragadeesh763b3532023-07-27 13:52:31 +0100849 TEST_FAIL("unknown operator");
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000851
Paul Bakkerbd51b262014-07-10 15:26:12 +0200852exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100853 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000854}
Paul Bakker33b43f12013-08-20 11:48:36 +0200855/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000856
Paul Bakker33b43f12013-08-20 11:48:36 +0200857/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100858void mpi_div_mpi(char *input_X, char *input_Y,
859 char *input_A, char *input_B,
860 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000861{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000863 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100864 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
865 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000866
Gilles Peskine449bd832023-01-11 14:50:10 +0100867 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
868 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
869 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
870 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
871 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
872 TEST_ASSERT(res == div_result);
873 if (res == 0) {
874 TEST_ASSERT(sign_is_valid(&Q));
875 TEST_ASSERT(sign_is_valid(&R));
876 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
877 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000878 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000879
Paul Bakkerbd51b262014-07-10 15:26:12 +0200880exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100881 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
882 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000883}
Paul Bakker33b43f12013-08-20 11:48:36 +0200884/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000885
Paul Bakker33b43f12013-08-20 11:48:36 +0200886/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100887void mpi_div_int(char *input_X, int input_Y,
888 char *input_A, char *input_B,
889 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000890{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000892 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
894 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000895
Gilles Peskine449bd832023-01-11 14:50:10 +0100896 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
897 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
898 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
899 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
900 TEST_ASSERT(res == div_result);
901 if (res == 0) {
902 TEST_ASSERT(sign_is_valid(&Q));
903 TEST_ASSERT(sign_is_valid(&R));
904 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
905 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000906 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000907
Paul Bakkerbd51b262014-07-10 15:26:12 +0200908exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100909 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
910 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000911}
Paul Bakker33b43f12013-08-20 11:48:36 +0200912/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000913
Paul Bakker33b43f12013-08-20 11:48:36 +0200914/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100915void mpi_mod_mpi(char *input_X, char *input_Y,
916 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100917{
918 mbedtls_mpi X, Y, A;
919 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100920 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100921
Gilles Peskine449bd832023-01-11 14:50:10 +0100922 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
923 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
924 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
925 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
926 TEST_ASSERT(res == div_result);
927 if (res == 0) {
928 TEST_ASSERT(sign_is_valid(&X));
929 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100930 }
931
932exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100933 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100934}
935/* END_CASE */
936
937/* BEGIN_CASE */
Gilles Peskine7768a8e2022-12-04 15:58:48 +0100938void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
939 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100940{
941 mbedtls_mpi X;
942 int res;
943 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100944
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000946
Gilles Peskine449bd832023-01-11 14:50:10 +0100947 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000948
Gilles Peskine449bd832023-01-11 14:50:10 +0100949 res = mbedtls_mpi_mod_int(&r, &X, y);
950 TEST_EQUAL(res, mod_result);
951 if (res == 0) {
952 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100953 }
954
955exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100956 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100957}
958/* END_CASE */
959
960/* BEGIN_CASE */
Janos Follath0512d172024-02-20 14:30:46 +0000961void mpi_exp_mod_min_RR(char *input_A, char *input_E,
Janos Follath09025722024-02-21 11:50:25 +0000962 char *input_N, char *input_X,
963 int exp_result)
Janos Follath0512d172024-02-20 14:30:46 +0000964{
965 mbedtls_mpi A, E, N, RR, Z, X;
966 int res;
967 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
968 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
969
Janos Follathfdab7862024-02-22 15:19:13 +0000970 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
971 TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
972 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
973 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000974
Janos Follathfdab7862024-02-22 15:19:13 +0000975 TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
976 TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
Gilles Peskine673461c2024-02-21 16:03:04 +0100977 /* The objective of this test is to check that exp_mod defends
978 * against a smaller RR. */
979 TEST_LE_U(RR.n, N.n - 1);
Janos Follath0512d172024-02-20 14:30:46 +0000980
Janos Follath5fc20fc2024-08-21 13:15:13 +0100981#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +0100982 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +0100983#endif
Janos Follath0512d172024-02-20 14:30:46 +0000984 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +0100985#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +0100986 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +0100987#endif
Gilles Peskine673461c2024-02-21 16:03:04 +0100988 /* We know that exp_mod internally needs RR to be as large as N.
989 * Validate that it is the case now, otherwise there was probably
990 * a buffer overread. */
991 TEST_EQUAL(RR.n, N.n);
992
Janos Follathfdab7862024-02-22 15:19:13 +0000993 TEST_EQUAL(res, exp_result);
Janos Follath0512d172024-02-20 14:30:46 +0000994 if (res == 0) {
Janos Follathfdab7862024-02-22 15:19:13 +0000995 TEST_EQUAL(sign_is_valid(&Z), 1);
996 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000997 }
998
999exit:
1000 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1001 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
1002}
1003/* END_CASE */
1004
1005/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001006void mpi_exp_mod(char *input_A, char *input_E,
1007 char *input_N, char *input_X,
1008 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001009{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001011 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001012 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1013 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001014
Gilles Peskine449bd832023-01-11 14:50:10 +01001015 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1016 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1017 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1018 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001019
Janos Follath5fc20fc2024-08-21 13:15:13 +01001020#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001021 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001022#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001023 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001024#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001025 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001026#endif
1027 TEST_ASSERT(res == exp_result);
1028 if (res == 0) {
1029 TEST_ASSERT(sign_is_valid(&Z));
1030 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
1031 }
1032
1033#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001034 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001035#endif
1036 res = mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, NULL);
1037#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001038 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, res, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001039#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001040 TEST_ASSERT(res == exp_result);
1041 if (res == 0) {
1042 TEST_ASSERT(sign_is_valid(&Z));
1043 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001044 }
1045
1046 /* Now test again with the speed-up parameter supplied as an output. */
Janos Follath5fc20fc2024-08-21 13:15:13 +01001047#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001048 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001049#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001050 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001051#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001052 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001053#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001054 TEST_ASSERT(res == exp_result);
1055 if (res == 0) {
1056 TEST_ASSERT(sign_is_valid(&Z));
1057 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001058 }
1059
1060 /* Now test again with the speed-up parameter supplied in calculated form. */
Janos Follath5fc20fc2024-08-21 13:15:13 +01001061#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001062 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001063#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001064 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001065#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001066 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, res, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001067#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001068 TEST_ASSERT(res == exp_result);
1069 if (res == 0) {
1070 TEST_ASSERT(sign_is_valid(&Z));
1071 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001072 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001073
Paul Bakkerbd51b262014-07-10 15:26:12 +02001074exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001075 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1076 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001077}
Paul Bakker33b43f12013-08-20 11:48:36 +02001078/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001079
Paul Bakker33b43f12013-08-20 11:48:36 +02001080/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001081void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1082 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001083{
1084 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001085 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1086 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001087
Chris Jonesaa850cd2020-12-03 11:35:41 +00001088 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001089 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1090 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1091 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001092
1093 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001094 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1095 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1096 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001097
1098 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001099 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1100 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1101 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001102
Gilles Peskine449bd832023-01-11 14:50:10 +01001103 if (strlen(input_RR)) {
1104 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1105 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001106
Janos Follath5fc20fc2024-08-21 13:15:13 +01001107#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001108 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001109#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001110 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001111#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001112 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_SECRET, exp_result, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001113#endif
1114
1115#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001116 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001117#endif
1118 TEST_ASSERT(mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, &RR) == exp_result);
1119#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath0a75adc2024-08-22 20:00:23 +01001120 ASSERT_BIGNUM_CODEPATH(MBEDTLS_MPI_IS_PUBLIC, exp_result, E);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001121#endif
Chris Jonesd10b3312020-12-02 10:41:50 +00001122
1123exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001124 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1125 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001126}
1127/* END_CASE */
1128
1129/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001130void mpi_inv_mod(char *input_X, char *input_Y,
1131 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001132{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001134 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001135 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001136
Gilles Peskine449bd832023-01-11 14:50:10 +01001137 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1138 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1139 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1140 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1141 TEST_ASSERT(res == div_result);
1142 if (res == 0) {
1143 TEST_ASSERT(sign_is_valid(&Z));
1144 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001145 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001146
Paul Bakkerbd51b262014-07-10 15:26:12 +02001147exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001148 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001149}
Paul Bakker33b43f12013-08-20 11:48:36 +02001150/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001151
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001152/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001153void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001154{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001156 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001157 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001158
Gilles Peskine449bd832023-01-11 14:50:10 +01001159 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1160 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1161 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001162
Paul Bakkerbd51b262014-07-10 15:26:12 +02001163exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001164 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001165}
Paul Bakker33b43f12013-08-20 11:48:36 +02001166/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001167
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001169void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1170 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001171{
1172 mbedtls_mpi X;
1173 int res;
1174 mbedtls_test_mpi_random rand;
1175
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001177 rand.data = witnesses;
1178 rand.pos = 0;
1179 rand.chunk_len = chunk_len;
1180
Gilles Peskine449bd832023-01-11 14:50:10 +01001181 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1182 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1183 mbedtls_test_mpi_miller_rabin_determinizer,
1184 &rand);
1185 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001186
1187 rand.data = witnesses;
1188 rand.pos = 0;
1189 rand.chunk_len = chunk_len;
1190
Gilles Peskine449bd832023-01-11 14:50:10 +01001191 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1192 mbedtls_test_mpi_miller_rabin_determinizer,
1193 &rand);
1194 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001195
1196exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001197 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001198}
1199/* END_CASE */
1200
1201/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001202void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001203{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001205 int my_ret;
1206
Gilles Peskine449bd832023-01-11 14:50:10 +01001207 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001208
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1210 mbedtls_test_rnd_std_rand, NULL);
1211 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001212
Gilles Peskine449bd832023-01-11 14:50:10 +01001213 if (ref_ret == 0) {
1214 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001215
Gilles Peskine449bd832023-01-11 14:50:10 +01001216 TEST_ASSERT(actual_bits >= (size_t) bits);
1217 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1218 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001219
Gilles Peskine449bd832023-01-11 14:50:10 +01001220 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1221 mbedtls_test_rnd_std_rand,
1222 NULL) == 0);
1223 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001224 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1226 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1227 mbedtls_test_rnd_std_rand,
1228 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001229 }
1230 }
1231
Paul Bakkerbd51b262014-07-10 15:26:12 +02001232exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001233 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001234}
1235/* END_CASE */
1236
Paul Bakker33b43f12013-08-20 11:48:36 +02001237/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001238void mpi_shift_l(char *input_X, int shift_X,
1239 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001242 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001243
Gilles Peskine449bd832023-01-11 14:50:10 +01001244 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1245 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1246 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1247 TEST_ASSERT(sign_is_valid(&X));
1248 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001249
Paul Bakkerbd51b262014-07-10 15:26:12 +02001250exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001251 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001252}
Paul Bakker33b43f12013-08-20 11:48:36 +02001253/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001254
Paul Bakker33b43f12013-08-20 11:48:36 +02001255/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001256void mpi_shift_r(char *input_X, int shift_X,
1257 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001258{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001259 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001260 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001261
Gilles Peskine449bd832023-01-11 14:50:10 +01001262 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1263 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1264 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1265 TEST_ASSERT(sign_is_valid(&X));
1266 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001267
Paul Bakkerbd51b262014-07-10 15:26:12 +02001268exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001269 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001270}
Paul Bakker33b43f12013-08-20 11:48:36 +02001271/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001272
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001273/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001274void mpi_fill_random(int wanted_bytes, int rng_bytes,
1275 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001276{
1277 mbedtls_mpi X;
1278 int ret;
1279 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001280 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001281
Gilles Peskine449bd832023-01-11 14:50:10 +01001282 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001283 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001284 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1285 if (before < 0) {
1286 before = -before;
1287 }
1288 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001289 }
1290
Gilles Peskine449bd832023-01-11 14:50:10 +01001291 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1292 f_rng_bytes_left, &bytes_left);
1293 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001294
Gilles Peskine449bd832023-01-11 14:50:10 +01001295 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001296 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1297 * as a big-endian representation of the number. We know when
1298 * our RNG function returns null bytes, so we know how many
1299 * leading zero bytes the number has. */
1300 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001301 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001302 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 }
1304 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1305 (size_t) wanted_bytes);
1306 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1307 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001308 }
1309
1310exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001311 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001312}
1313/* END_CASE */
1314
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001315/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001316void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001317{
1318 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1319 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1320 * is a valid value. However, negating it (`-n`) has undefined behavior
1321 * (although in practice `-n` evaluates to the value n).
1322 *
1323 * This function has ad hoc tests for this value. It's separated from other
1324 * functions because the test framework makes it hard to pass this value
1325 * into test cases.
1326 *
1327 * In the comments here:
1328 * - biL = number of bits in limbs
1329 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1330 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1331 */
1332
1333 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001334 mbedtls_mpi_init(&A);
1335 mbedtls_mpi_init(&R);
1336 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001337
Gilles Peskine449bd832023-01-11 14:50:10 +01001338 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001339 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001340 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1341 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1342 (mbedtls_mpi_uint) 1 << (biL - 1));
1343 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001344
1345 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1347 TEST_EQUAL(A.s, -1);
1348 TEST_EQUAL(A.n, 1);
1349 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001350
1351 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001353
1354 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1355 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001356 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001357
1358 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1359 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001360 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001361
1362 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001363 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1364 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1365 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001366
1367 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1369 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1370 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001371
1372 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001373 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1374 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1375 TEST_EQUAL(X.s, -1);
1376 TEST_EQUAL(X.n, 2);
1377 TEST_EQUAL(X.p[0], 0);
1378 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001379
1380 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001381 mbedtls_mpi_free(&X);
1382 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1383 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1384 TEST_EQUAL(X.s, 1);
1385 TEST_EQUAL(X.n, 1);
1386 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001387
1388 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001389 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1390 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1391 TEST_EQUAL(X.s, 1);
1392 TEST_EQUAL(X.n, 1);
1393 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001394
1395 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001396 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1397 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1398 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001399
1400 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1402 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1403 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1404 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001405
1406 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001407 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1408 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1409 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1410 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001411
1412 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1414 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1415 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1416 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001417
1418 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1420 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1421 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 1), 0);
1422 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001423
1424 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1426 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1427 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1428 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001429
1430 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001431 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1432 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1433 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1434 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001435
1436 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1438 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1439 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1440 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001441
1442 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001443 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1444 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001445
1446 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001447 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1448 mbedtls_test_rnd_std_rand, NULL),
1449 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001450
1451exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001452 mbedtls_mpi_free(&A);
1453 mbedtls_mpi_free(&R);
1454 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001455}
1456/* END_CASE */
1457
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001458/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001459void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001460{
Gilles Peskine449bd832023-01-11 14:50:10 +01001461 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001462}
Paul Bakker33b43f12013-08-20 11:48:36 +02001463/* END_CASE */