blob: c71f3c8bb10d844e91d5eff0d3551bb3a11b63ab [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;
Paul Bakkere896fea2009-07-06 06:40:23 +0000215 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000216 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000217
Gilles Peskine449bd832023-01-11 14:50:10 +0100218 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000219
Gilles Peskine449bd832023-01-11 14:50:10 +0100220 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000221
Gilles Peskine449bd832023-01-11 14:50:10 +0100222 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100223
Gilles Peskine449bd832023-01-11 14:50:10 +0100224 buflen = mbedtls_mpi_size(&X);
225 if (buflen > (size_t) output_size) {
Paul Bakker33b43f12013-08-20 11:48:36 +0200226 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100227 }
Paul Bakkere896fea2009-07-06 06:40:23 +0000228
Gilles Peskine449bd832023-01-11 14:50:10 +0100229 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == result);
230 if (result == 0) {
Paul Bakkere896fea2009-07-06 06:40:23 +0000231
Gilles Peskine449bd832023-01-11 14:50:10 +0100232 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
233 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000234 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000235
Paul Bakkerbd51b262014-07-10 15:26:12 +0200236exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100237 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000238}
Paul Bakker33b43f12013-08-20 11:48:36 +0200239/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000240
Janos Follathe344d0f2019-02-19 16:17:40 +0000241/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100242void mpi_write_binary_le(char *input_X, data_t *input_A,
243 int output_size, int result)
Janos Follathe344d0f2019-02-19 16:17:40 +0000244{
245 mbedtls_mpi X;
246 unsigned char buf[1000];
247 size_t buflen;
248
Gilles Peskine449bd832023-01-11 14:50:10 +0100249 memset(buf, 0x00, 1000);
Janos Follathe344d0f2019-02-19 16:17:40 +0000250
Gilles Peskine449bd832023-01-11 14:50:10 +0100251 mbedtls_mpi_init(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000252
Gilles Peskine449bd832023-01-11 14:50:10 +0100253 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000254
Gilles Peskine449bd832023-01-11 14:50:10 +0100255 buflen = mbedtls_mpi_size(&X);
256 if (buflen > (size_t) output_size) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000257 buflen = (size_t) output_size;
Gilles Peskine449bd832023-01-11 14:50:10 +0100258 }
Janos Follathe344d0f2019-02-19 16:17:40 +0000259
Gilles Peskine449bd832023-01-11 14:50:10 +0100260 TEST_ASSERT(mbedtls_mpi_write_binary_le(&X, buf, buflen) == result);
261 if (result == 0) {
Janos Follathe344d0f2019-02-19 16:17:40 +0000262
Gilles Peskine449bd832023-01-11 14:50:10 +0100263 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
264 buflen, input_A->len) == 0);
Janos Follathe344d0f2019-02-19 16:17:40 +0000265 }
266
267exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100268 mbedtls_mpi_free(&X);
Janos Follathe344d0f2019-02-19 16:17:40 +0000269}
270/* END_CASE */
271
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100273void mpi_read_file(char *input_file, data_t *input_A, int result)
Paul Bakkere896fea2009-07-06 06:40:23 +0000274{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200275 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000276 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000277 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000278 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000279 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000280
Gilles Peskine449bd832023-01-11 14:50:10 +0100281 memset(buf, 0x00, 1000);
Paul Bakkere896fea2009-07-06 06:40:23 +0000282
Gilles Peskine449bd832023-01-11 14:50:10 +0100283 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000284
Gilles Peskine449bd832023-01-11 14:50:10 +0100285 file = fopen(input_file, "r");
286 TEST_ASSERT(file != NULL);
287 ret = mbedtls_mpi_read_file(&X, 16, file);
Paul Bakkere896fea2009-07-06 06:40:23 +0000288 fclose(file);
Gilles Peskine449bd832023-01-11 14:50:10 +0100289 TEST_ASSERT(ret == result);
Paul Bakkere896fea2009-07-06 06:40:23 +0000290
Gilles Peskine449bd832023-01-11 14:50:10 +0100291 if (result == 0) {
292 TEST_ASSERT(sign_is_valid(&X));
293 buflen = mbedtls_mpi_size(&X);
294 TEST_ASSERT(mbedtls_mpi_write_binary(&X, buf, buflen) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000295
Paul Bakkere896fea2009-07-06 06:40:23 +0000296
Gilles Peskine449bd832023-01-11 14:50:10 +0100297 TEST_ASSERT(mbedtls_test_hexcmp(buf, input_A->x,
298 buflen, input_A->len) == 0);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000299 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000300
Paul Bakkerbd51b262014-07-10 15:26:12 +0200301exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100302 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000303}
Paul Bakker33b43f12013-08-20 11:48:36 +0200304/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Gilles Peskine449bd832023-01-11 14:50:10 +0100307void mpi_write_file(char *input_X, char *output_file)
Paul Bakkere896fea2009-07-06 06:40:23 +0000308{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000310 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200311 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000312
Gilles Peskine449bd832023-01-11 14:50:10 +0100313 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000314
Gilles Peskine449bd832023-01-11 14:50:10 +0100315 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000316
Gilles Peskine449bd832023-01-11 14:50:10 +0100317 file_out = fopen(output_file, "w");
318 TEST_ASSERT(file_out != NULL);
319 ret = mbedtls_mpi_write_file(NULL, &X, 16, file_out);
Paul Bakkere896fea2009-07-06 06:40:23 +0000320 fclose(file_out);
Gilles Peskine449bd832023-01-11 14:50:10 +0100321 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000322
Gilles Peskine449bd832023-01-11 14:50:10 +0100323 file_in = fopen(output_file, "r");
324 TEST_ASSERT(file_in != NULL);
325 ret = mbedtls_mpi_read_file(&Y, 16, file_in);
Paul Bakkere896fea2009-07-06 06:40:23 +0000326 fclose(file_in);
Gilles Peskine449bd832023-01-11 14:50:10 +0100327 TEST_ASSERT(ret == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +0000328
Gilles Peskine449bd832023-01-11 14:50:10 +0100329 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000330
Paul Bakkerbd51b262014-07-10 15:26:12 +0200331exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100332 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakkere896fea2009-07-06 06:40:23 +0000333}
Paul Bakker33b43f12013-08-20 11:48:36 +0200334/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000335
Paul Bakker33b43f12013-08-20 11:48:36 +0200336/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100337void mpi_get_bit(char *input_X, int pos, int val)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000338{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100340 mbedtls_mpi_init(&X);
341 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
342 TEST_ASSERT(mbedtls_mpi_get_bit(&X, pos) == val);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000343
Paul Bakkerbd51b262014-07-10 15:26:12 +0200344exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100345 mbedtls_mpi_free(&X);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000346}
Paul Bakker33b43f12013-08-20 11:48:36 +0200347/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000348
Paul Bakker33b43f12013-08-20 11:48:36 +0200349/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100350void mpi_set_bit(char *input_X, int pos, int val,
351 char *output_Y, int result)
Paul Bakker2f5947e2011-05-18 15:47:11 +0000352{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100354 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000355
Gilles Peskine449bd832023-01-11 14:50:10 +0100356 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
357 TEST_ASSERT(mbedtls_test_read_mpi(&Y, output_Y) == 0);
358 TEST_ASSERT(mbedtls_mpi_set_bit(&X, pos, val) == result);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100359
Gilles Peskine449bd832023-01-11 14:50:10 +0100360 if (result == 0) {
361 TEST_ASSERT(sign_is_valid(&X));
362 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == 0);
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100363 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000364
Paul Bakkerbd51b262014-07-10 15:26:12 +0200365exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100366 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker2f5947e2011-05-18 15:47:11 +0000367}
Paul Bakker33b43f12013-08-20 11:48:36 +0200368/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000369
Paul Bakker33b43f12013-08-20 11:48:36 +0200370/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100371void mpi_lsb(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000372{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100374 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000375
Gilles Peskine449bd832023-01-11 14:50:10 +0100376 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
377 TEST_ASSERT(mbedtls_mpi_lsb(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000378
Paul Bakkerbd51b262014-07-10 15:26:12 +0200379exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100380 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000381}
Paul Bakker33b43f12013-08-20 11:48:36 +0200382/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000383
Paul Bakker33b43f12013-08-20 11:48:36 +0200384/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100385void mpi_bitlen(char *input_X, int nr_bits)
Paul Bakkere896fea2009-07-06 06:40:23 +0000386{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100388 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000389
Gilles Peskine449bd832023-01-11 14:50:10 +0100390 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
391 TEST_ASSERT(mbedtls_mpi_bitlen(&X) == (size_t) nr_bits);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000392
Paul Bakkerbd51b262014-07-10 15:26:12 +0200393exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100394 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000395}
Paul Bakker33b43f12013-08-20 11:48:36 +0200396/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000397
Paul Bakker33b43f12013-08-20 11:48:36 +0200398/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100399void mpi_gcd(char *input_X, char *input_Y,
400 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000401{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_mpi A, X, Y, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +0100403 mbedtls_mpi_init(&A); mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000404
Gilles Peskine449bd832023-01-11 14:50:10 +0100405 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
406 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
407 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
408 TEST_ASSERT(mbedtls_mpi_gcd(&Z, &X, &Y) == 0);
409 TEST_ASSERT(sign_is_valid(&Z));
410 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000411
Paul Bakkerbd51b262014-07-10 15:26:12 +0200412exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100413 mbedtls_mpi_free(&A); mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
Paul Bakker367dae42009-06-28 21:50:27 +0000414}
Paul Bakker33b43f12013-08-20 11:48:36 +0200415/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000416
Paul Bakker33b43f12013-08-20 11:48:36 +0200417/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100418void mpi_cmp_int(int input_X, int input_A, int result_CMP)
Paul Bakker367dae42009-06-28 21:50:27 +0000419{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100421 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000422
Gilles Peskine449bd832023-01-11 14:50:10 +0100423 TEST_ASSERT(mbedtls_mpi_lset(&X, input_X) == 0);
424 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, input_A) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000425
Paul Bakkerbd51b262014-07-10 15:26:12 +0200426exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100427 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +0000428}
Paul Bakker33b43f12013-08-20 11:48:36 +0200429/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000430
Paul Bakker33b43f12013-08-20 11:48:36 +0200431/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100432void mpi_cmp_mpi(char *input_X, char *input_Y,
433 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000434{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100436 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000437
Gilles Peskine449bd832023-01-11 14:50:10 +0100438 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
439 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
440 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000441
Paul Bakkerbd51b262014-07-10 15:26:12 +0200442exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100443 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000444}
Paul Bakker33b43f12013-08-20 11:48:36 +0200445/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000446
Paul Bakker33b43f12013-08-20 11:48:36 +0200447/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100448void mpi_lt_mpi_ct(int size_X, char *input_X,
449 int size_Y, char *input_Y,
450 int input_ret, int input_err)
Janos Follath385d5b82019-09-11 16:07:14 +0100451{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200452 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100453 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100454 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100455 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100456
Gilles Peskine449bd832023-01-11 14:50:10 +0100457 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
458 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100459
Gilles Peskine449bd832023-01-11 14:50:10 +0100460 TEST_ASSERT(mbedtls_mpi_grow(&X, size_X) == 0);
461 TEST_ASSERT(mbedtls_mpi_grow(&Y, size_Y) == 0);
Janos Follath385d5b82019-09-11 16:07:14 +0100462
Gilles Peskine449bd832023-01-11 14:50:10 +0100463 TEST_ASSERT(mbedtls_mpi_lt_mpi_ct(&X, &Y, &ret) == input_err);
464 if (input_err == 0) {
Dave Rodgman14bec142023-05-11 16:19:27 +0100465 TEST_EQUAL(ret, input_uret);
Gilles Peskine449bd832023-01-11 14:50:10 +0100466 }
Janos Follath385d5b82019-09-11 16:07:14 +0100467
468exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100469 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Janos Follath385d5b82019-09-11 16:07:14 +0100470}
471/* END_CASE */
472
473/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100474void mpi_cmp_abs(char *input_X, char *input_Y,
475 int input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000476{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 mbedtls_mpi X, Y;
Gilles Peskine449bd832023-01-11 14:50:10 +0100478 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000479
Gilles Peskine449bd832023-01-11 14:50:10 +0100480 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
481 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
482 TEST_ASSERT(mbedtls_mpi_cmp_abs(&X, &Y) == input_A);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000483
Paul Bakkerbd51b262014-07-10 15:26:12 +0200484exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100485 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
Paul Bakker367dae42009-06-28 21:50:27 +0000486}
Paul Bakker33b43f12013-08-20 11:48:36 +0200487/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000488
Paul Bakker33b43f12013-08-20 11:48:36 +0200489/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100490void mpi_copy(char *src_hex, char *dst_hex)
Paul Bakker367dae42009-06-28 21:50:27 +0000491{
Gilles Peskined0722f82021-06-10 23:00:33 +0200492 mbedtls_mpi src, dst, ref;
Gilles Peskine449bd832023-01-11 14:50:10 +0100493 mbedtls_mpi_init(&src);
494 mbedtls_mpi_init(&dst);
495 mbedtls_mpi_init(&ref);
Paul Bakker367dae42009-06-28 21:50:27 +0000496
Gilles Peskine449bd832023-01-11 14:50:10 +0100497 TEST_ASSERT(mbedtls_test_read_mpi(&src, src_hex) == 0);
498 TEST_ASSERT(mbedtls_test_read_mpi(&ref, dst_hex) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200499
500 /* mbedtls_mpi_copy() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100501 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
502 TEST_ASSERT(mbedtls_mpi_copy(&dst, &src) == 0);
503 TEST_ASSERT(sign_is_valid(&dst));
504 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000505
Gilles Peskined0722f82021-06-10 23:00:33 +0200506 /* mbedtls_mpi_safe_cond_assign(), assignment done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100507 mbedtls_mpi_free(&dst);
508 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
509 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 1) == 0);
510 TEST_ASSERT(sign_is_valid(&dst));
511 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &src) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200512
513 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100514 mbedtls_mpi_free(&dst);
515 TEST_ASSERT(mbedtls_test_read_mpi(&dst, dst_hex) == 0);
516 TEST_ASSERT(mbedtls_mpi_safe_cond_assign(&dst, &src, 0) == 0);
517 TEST_ASSERT(sign_is_valid(&dst));
518 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&dst, &ref) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200519
Paul Bakkerbd51b262014-07-10 15:26:12 +0200520exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100521 mbedtls_mpi_free(&src);
522 mbedtls_mpi_free(&dst);
523 mbedtls_mpi_free(&ref);
Gilles Peskine7428b452020-01-20 21:01:51 +0100524}
525/* END_CASE */
526
527/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100528void mpi_copy_self(char *input_X)
Gilles Peskine7428b452020-01-20 21:01:51 +0100529{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200530 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100531 mbedtls_mpi_init(&A);
532 mbedtls_mpi_init(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000533
Gilles Peskine449bd832023-01-11 14:50:10 +0100534 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
535 TEST_ASSERT(mbedtls_mpi_copy(&X, &X) == 0);
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200536
Gilles Peskine449bd832023-01-11 14:50:10 +0100537 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_X) == 0);
538 TEST_ASSERT(sign_is_valid(&X));
539 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000540
Paul Bakkerbd51b262014-07-10 15:26:12 +0200541exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100542 mbedtls_mpi_free(&A);
543 mbedtls_mpi_free(&X);
Paul Bakkere896fea2009-07-06 06:40:23 +0000544}
Paul Bakker33b43f12013-08-20 11:48:36 +0200545/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000546
Paul Bakker33b43f12013-08-20 11:48:36 +0200547/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100548void mpi_swap(char *X_hex, char *Y_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200549{
550 mbedtls_mpi X, Y, X0, Y0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100551 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y);
552 mbedtls_mpi_init(&X0); mbedtls_mpi_init(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200553
Gilles Peskine449bd832023-01-11 14:50:10 +0100554 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
555 TEST_ASSERT(mbedtls_test_read_mpi(&Y0, Y_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200556
Gilles Peskined0722f82021-06-10 23:00:33 +0200557 /* mbedtls_mpi_swap() */
Gilles Peskine449bd832023-01-11 14:50:10 +0100558 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
559 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
560 mbedtls_mpi_swap(&X, &Y);
561 TEST_ASSERT(sign_is_valid(&X));
562 TEST_ASSERT(sign_is_valid(&Y));
563 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
564 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200565
Gilles Peskined0722f82021-06-10 23:00:33 +0200566 /* mbedtls_mpi_safe_cond_swap(), swap done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100567 mbedtls_mpi_free(&X);
568 mbedtls_mpi_free(&Y);
569 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
570 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
571 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 1) == 0);
572 TEST_ASSERT(sign_is_valid(&X));
573 TEST_ASSERT(sign_is_valid(&Y));
574 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &Y0) == 0);
575 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &X0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200576
577 /* mbedtls_mpi_safe_cond_swap(), swap not done */
Gilles Peskine449bd832023-01-11 14:50:10 +0100578 mbedtls_mpi_free(&X);
579 mbedtls_mpi_free(&Y);
580 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
581 TEST_ASSERT(mbedtls_test_read_mpi(&Y, Y_hex) == 0);
582 TEST_ASSERT(mbedtls_mpi_safe_cond_swap(&X, &Y, 0) == 0);
583 TEST_ASSERT(sign_is_valid(&X));
584 TEST_ASSERT(sign_is_valid(&Y));
585 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
586 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &Y0) == 0);
Gilles Peskined0722f82021-06-10 23:00:33 +0200587
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200588exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100589 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y);
590 mbedtls_mpi_free(&X0); mbedtls_mpi_free(&Y0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200591}
592/* END_CASE */
593
594/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100595void mpi_swap_self(char *X_hex)
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200596{
597 mbedtls_mpi X, X0;
Gilles Peskine449bd832023-01-11 14:50:10 +0100598 mbedtls_mpi_init(&X); mbedtls_mpi_init(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200599
Gilles Peskine449bd832023-01-11 14:50:10 +0100600 TEST_ASSERT(mbedtls_test_read_mpi(&X, X_hex) == 0);
601 TEST_ASSERT(mbedtls_test_read_mpi(&X0, X_hex) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200602
Gilles Peskine449bd832023-01-11 14:50:10 +0100603 mbedtls_mpi_swap(&X, &X);
604 TEST_ASSERT(sign_is_valid(&X));
605 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &X0) == 0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200606
607exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100608 mbedtls_mpi_free(&X); mbedtls_mpi_free(&X0);
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200609}
610/* END_CASE */
611
612/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100613void mpi_shrink(int before, int used, int min, int after)
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100614{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_mpi X;
Gilles Peskine449bd832023-01-11 14:50:10 +0100616 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100617
Gilles Peskine449bd832023-01-11 14:50:10 +0100618 TEST_ASSERT(mbedtls_mpi_grow(&X, before) == 0);
619 if (used > 0) {
620 size_t used_bit_count = used * 8 * sizeof(mbedtls_mpi_uint);
621 TEST_ASSERT(mbedtls_mpi_set_bit(&X, used_bit_count - 1, 1) == 0);
Gilles Peskinee1091752021-06-15 21:19:18 +0200622 }
Gilles Peskine449bd832023-01-11 14:50:10 +0100623 TEST_EQUAL(X.n, (size_t) before);
624 TEST_ASSERT(mbedtls_mpi_shrink(&X, min) == 0);
625 TEST_EQUAL(X.n, (size_t) after);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100626
Paul Bakkerbd51b262014-07-10 15:26:12 +0200627exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100628 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100629}
630/* END_CASE */
631
632/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100633void mpi_add_mpi(char *input_X, char *input_Y,
634 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000635{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200636 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100637 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000638
Gilles Peskine449bd832023-01-11 14:50:10 +0100639 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
640 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
641 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
642 TEST_ASSERT(mbedtls_mpi_add_mpi(&Z, &X, &Y) == 0);
643 TEST_ASSERT(sign_is_valid(&Z));
644 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000645
Gilles Peskine56f943a2020-07-23 01:18:11 +0200646 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100647 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &Y) == 0);
648 TEST_ASSERT(sign_is_valid(&X));
649 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
650 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200651
652 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100653 TEST_ASSERT(mbedtls_mpi_add_mpi(&Y, &X, &Y) == 0);
654 TEST_ASSERT(sign_is_valid(&Y));
655 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200656
Paul Bakkerbd51b262014-07-10 15:26:12 +0200657exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100658 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000659}
Paul Bakker33b43f12013-08-20 11:48:36 +0200660/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000661
Paul Bakker33b43f12013-08-20 11:48:36 +0200662/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100663void mpi_add_mpi_inplace(char *input_X, char *input_A)
Janos Follath044a86b2015-10-25 10:58:03 +0100664{
665 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100666 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100667
Gilles Peskine449bd832023-01-11 14:50:10 +0100668 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100669
Gilles Peskine449bd832023-01-11 14:50:10 +0100670 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
671 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &X) == 0);
672 TEST_ASSERT(mbedtls_mpi_cmp_int(&X, 0) == 0);
673 TEST_ASSERT(sign_is_valid(&X));
Janos Follath6cbacec2015-10-25 12:29:13 +0100674
Gilles Peskine449bd832023-01-11 14:50:10 +0100675 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
676 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &X) == 0);
677 TEST_ASSERT(sign_is_valid(&X));
678 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath6cbacec2015-10-25 12:29:13 +0100679
Gilles Peskine449bd832023-01-11 14:50:10 +0100680 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
681 TEST_ASSERT(mbedtls_mpi_add_mpi(&X, &X, &X) == 0);
682 TEST_ASSERT(sign_is_valid(&X));
683 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Janos Follath044a86b2015-10-25 10:58:03 +0100684
685exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100686 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Janos Follath044a86b2015-10-25 10:58:03 +0100687}
688/* END_CASE */
689
690
691/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100692void mpi_add_abs(char *input_X, char *input_Y,
693 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000694{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100696 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000697
Gilles Peskine449bd832023-01-11 14:50:10 +0100698 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
699 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
700 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
701 TEST_ASSERT(mbedtls_mpi_add_abs(&Z, &X, &Y) == 0);
702 TEST_ASSERT(sign_is_valid(&Z));
703 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000704
Gilles Peskine56f943a2020-07-23 01:18:11 +0200705 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100706 TEST_ASSERT(mbedtls_mpi_add_abs(&X, &X, &Y) == 0);
707 TEST_ASSERT(sign_is_valid(&X));
708 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
709 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200710
711 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100712 TEST_ASSERT(mbedtls_mpi_add_abs(&Y, &X, &Y) == 0);
713 TEST_ASSERT(sign_is_valid(&Y));
714 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000715
Paul Bakkerbd51b262014-07-10 15:26:12 +0200716exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100717 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakkerba48cb22009-07-12 11:01:32 +0000718}
Paul Bakker33b43f12013-08-20 11:48:36 +0200719/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000720
Paul Bakker33b43f12013-08-20 11:48:36 +0200721/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100722void mpi_add_int(char *input_X, int input_Y,
723 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000724{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100726 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000727
Gilles Peskine449bd832023-01-11 14:50:10 +0100728 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
729 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
730 TEST_ASSERT(mbedtls_mpi_add_int(&Z, &X, input_Y) == 0);
731 TEST_ASSERT(sign_is_valid(&Z));
732 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000733
Paul Bakkerbd51b262014-07-10 15:26:12 +0200734exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100735 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000736}
Paul Bakker33b43f12013-08-20 11:48:36 +0200737/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000738
Paul Bakker33b43f12013-08-20 11:48:36 +0200739/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100740void mpi_sub_mpi(char *input_X, char *input_Y,
741 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000742{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100744 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000745
Gilles Peskine449bd832023-01-11 14:50:10 +0100746 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
747 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
748 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
749 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Z, &X, &Y) == 0);
750 TEST_ASSERT(sign_is_valid(&Z));
751 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000752
Gilles Peskine56f943a2020-07-23 01:18:11 +0200753 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100754 TEST_ASSERT(mbedtls_mpi_sub_mpi(&X, &X, &Y) == 0);
755 TEST_ASSERT(sign_is_valid(&X));
756 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
757 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200758
759 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100760 TEST_ASSERT(mbedtls_mpi_sub_mpi(&Y, &X, &Y) == 0);
761 TEST_ASSERT(sign_is_valid(&Y));
762 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200763
Paul Bakkerbd51b262014-07-10 15:26:12 +0200764exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100765 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000766}
Paul Bakker33b43f12013-08-20 11:48:36 +0200767/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000768
Paul Bakker33b43f12013-08-20 11:48:36 +0200769/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100770void mpi_sub_abs(char *input_X, char *input_Y,
771 char *input_A, int sub_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000772{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000774 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100775 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000776
Gilles Peskine449bd832023-01-11 14:50:10 +0100777 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
778 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
779 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100780
Gilles Peskine449bd832023-01-11 14:50:10 +0100781 res = mbedtls_mpi_sub_abs(&Z, &X, &Y);
782 TEST_ASSERT(res == sub_result);
783 TEST_ASSERT(sign_is_valid(&Z));
784 if (res == 0) {
785 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
786 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000787
Gilles Peskine56f943a2020-07-23 01:18:11 +0200788 /* result == first operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100789 TEST_ASSERT(mbedtls_mpi_sub_abs(&X, &X, &Y) == sub_result);
790 TEST_ASSERT(sign_is_valid(&X));
791 if (sub_result == 0) {
792 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
793 }
794 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Gilles Peskine56f943a2020-07-23 01:18:11 +0200795
796 /* result == second operand */
Gilles Peskine449bd832023-01-11 14:50:10 +0100797 TEST_ASSERT(mbedtls_mpi_sub_abs(&Y, &X, &Y) == sub_result);
798 TEST_ASSERT(sign_is_valid(&Y));
799 if (sub_result == 0) {
800 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Y, &A) == 0);
801 }
Gilles Peskine56f943a2020-07-23 01:18:11 +0200802
Paul Bakkerbd51b262014-07-10 15:26:12 +0200803exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100804 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000805}
Paul Bakker33b43f12013-08-20 11:48:36 +0200806/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000807
Paul Bakker33b43f12013-08-20 11:48:36 +0200808/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100809void mpi_sub_int(char *input_X, int input_Y,
810 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000811{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100813 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000814
Gilles Peskine449bd832023-01-11 14:50:10 +0100815 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
816 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
817 TEST_ASSERT(mbedtls_mpi_sub_int(&Z, &X, input_Y) == 0);
818 TEST_ASSERT(sign_is_valid(&Z));
819 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000820
Paul Bakkerbd51b262014-07-10 15:26:12 +0200821exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100822 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000823}
Paul Bakker33b43f12013-08-20 11:48:36 +0200824/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000825
Paul Bakker33b43f12013-08-20 11:48:36 +0200826/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100827void mpi_mul_mpi(char *input_X, char *input_Y,
828 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +0000829{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 mbedtls_mpi X, Y, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100831 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000832
Gilles Peskine449bd832023-01-11 14:50:10 +0100833 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
834 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
835 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
836 TEST_ASSERT(mbedtls_mpi_mul_mpi(&Z, &X, &Y) == 0);
837 TEST_ASSERT(sign_is_valid(&Z));
838 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000839
Paul Bakkerbd51b262014-07-10 15:26:12 +0200840exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100841 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000842}
Paul Bakker33b43f12013-08-20 11:48:36 +0200843/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000844
Paul Bakker33b43f12013-08-20 11:48:36 +0200845/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100846void mpi_mul_int(char *input_X, int input_Y,
847 char *input_A, char *result_comparison)
Paul Bakker367dae42009-06-28 21:50:27 +0000848{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_mpi X, Z, A;
Gilles Peskine449bd832023-01-11 14:50:10 +0100850 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000851
Gilles Peskine449bd832023-01-11 14:50:10 +0100852 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
853 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
854 TEST_ASSERT(mbedtls_mpi_mul_int(&Z, &X, input_Y) == 0);
855 TEST_ASSERT(sign_is_valid(&Z));
856 if (strcmp(result_comparison, "==") == 0) {
857 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
858 } else if (strcmp(result_comparison, "!=") == 0) {
859 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) != 0);
860 } else {
Agathiyan Bragadeesh763b3532023-07-27 13:52:31 +0100861 TEST_FAIL("unknown operator");
Gilles Peskine449bd832023-01-11 14:50:10 +0100862 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000863
Paul Bakkerbd51b262014-07-10 15:26:12 +0200864exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100865 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +0000866}
Paul Bakker33b43f12013-08-20 11:48:36 +0200867/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000868
Paul Bakker33b43f12013-08-20 11:48:36 +0200869/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100870void mpi_div_mpi(char *input_X, char *input_Y,
871 char *input_A, char *input_B,
872 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000873{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000875 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100876 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R);
877 mbedtls_mpi_init(&A); mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000878
Gilles Peskine449bd832023-01-11 14:50:10 +0100879 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
880 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
881 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
882 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
883 res = mbedtls_mpi_div_mpi(&Q, &R, &X, &Y);
884 TEST_ASSERT(res == div_result);
885 if (res == 0) {
886 TEST_ASSERT(sign_is_valid(&Q));
887 TEST_ASSERT(sign_is_valid(&R));
888 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
889 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000890 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000891
Paul Bakkerbd51b262014-07-10 15:26:12 +0200892exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100893 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R);
894 mbedtls_mpi_free(&A); mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000895}
Paul Bakker33b43f12013-08-20 11:48:36 +0200896/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000897
Paul Bakker33b43f12013-08-20 11:48:36 +0200898/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100899void mpi_div_int(char *input_X, int input_Y,
900 char *input_A, char *input_B,
901 int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +0000902{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000904 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100905 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Q); mbedtls_mpi_init(&R); mbedtls_mpi_init(&A);
906 mbedtls_mpi_init(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000907
Gilles Peskine449bd832023-01-11 14:50:10 +0100908 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
909 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
910 TEST_ASSERT(mbedtls_test_read_mpi(&B, input_B) == 0);
911 res = mbedtls_mpi_div_int(&Q, &R, &X, input_Y);
912 TEST_ASSERT(res == div_result);
913 if (res == 0) {
914 TEST_ASSERT(sign_is_valid(&Q));
915 TEST_ASSERT(sign_is_valid(&R));
916 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Q, &A) == 0);
917 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&R, &B) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +0000918 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000919
Paul Bakkerbd51b262014-07-10 15:26:12 +0200920exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100921 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Q); mbedtls_mpi_free(&R); mbedtls_mpi_free(&A);
922 mbedtls_mpi_free(&B);
Paul Bakker367dae42009-06-28 21:50:27 +0000923}
Paul Bakker33b43f12013-08-20 11:48:36 +0200924/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000925
Paul Bakker33b43f12013-08-20 11:48:36 +0200926/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +0100927void mpi_mod_mpi(char *input_X, char *input_Y,
928 char *input_A, int div_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100929{
930 mbedtls_mpi X, Y, A;
931 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +0100932 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100933
Gilles Peskine449bd832023-01-11 14:50:10 +0100934 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
935 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
936 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
937 res = mbedtls_mpi_mod_mpi(&X, &X, &Y);
938 TEST_ASSERT(res == div_result);
939 if (res == 0) {
940 TEST_ASSERT(sign_is_valid(&X));
941 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100942 }
943
944exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100945 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&A);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100946}
947/* END_CASE */
948
949/* BEGIN_CASE */
Gilles Peskine7768a8e2022-12-04 15:58:48 +0100950void mpi_mod_int(char *input_X, mbedtls_mpi_sint y,
951 mbedtls_mpi_sint a, int mod_result)
Werner Lewis6baf12b2022-10-19 12:46:35 +0100952{
953 mbedtls_mpi X;
954 int res;
955 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100956
Gilles Peskine449bd832023-01-11 14:50:10 +0100957 mbedtls_mpi_init(&X);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000958
Gilles Peskine449bd832023-01-11 14:50:10 +0100959 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000960
Gilles Peskine449bd832023-01-11 14:50:10 +0100961 res = mbedtls_mpi_mod_int(&r, &X, y);
962 TEST_EQUAL(res, mod_result);
963 if (res == 0) {
964 TEST_EQUAL(r, a);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100965 }
966
967exit:
Gilles Peskine449bd832023-01-11 14:50:10 +0100968 mbedtls_mpi_free(&X);
Werner Lewis6baf12b2022-10-19 12:46:35 +0100969}
970/* END_CASE */
971
972/* BEGIN_CASE */
Janos Follath0512d172024-02-20 14:30:46 +0000973void mpi_exp_mod_min_RR(char *input_A, char *input_E,
Janos Follath09025722024-02-21 11:50:25 +0000974 char *input_N, char *input_X,
975 int exp_result)
Janos Follath0512d172024-02-20 14:30:46 +0000976{
977 mbedtls_mpi A, E, N, RR, Z, X;
978 int res;
979 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
980 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
981
Janos Follathfdab7862024-02-22 15:19:13 +0000982 TEST_EQUAL(mbedtls_test_read_mpi(&A, input_A), 0);
983 TEST_EQUAL(mbedtls_test_read_mpi(&E, input_E), 0);
984 TEST_EQUAL(mbedtls_test_read_mpi(&N, input_N), 0);
985 TEST_EQUAL(mbedtls_test_read_mpi(&X, input_X), 0);
Janos Follath0512d172024-02-20 14:30:46 +0000986
Janos Follathfdab7862024-02-22 15:19:13 +0000987 TEST_EQUAL(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, &N), 0);
988 TEST_EQUAL(mbedtls_mpi_shrink(&RR, 0), 0);
Gilles Peskine673461c2024-02-21 16:03:04 +0100989 /* The objective of this test is to check that exp_mod defends
990 * against a smaller RR. */
991 TEST_LE_U(RR.n, N.n - 1);
Janos Follath0512d172024-02-20 14:30:46 +0000992
Janos Follath5fc20fc2024-08-21 13:15:13 +0100993#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +0100994 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +0100995#endif
Janos Follath0512d172024-02-20 14:30:46 +0000996 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +0100997#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +0100998 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +0100999#endif
Gilles Peskine673461c2024-02-21 16:03:04 +01001000 /* We know that exp_mod internally needs RR to be as large as N.
1001 * Validate that it is the case now, otherwise there was probably
1002 * a buffer overread. */
1003 TEST_EQUAL(RR.n, N.n);
1004
Janos Follathfdab7862024-02-22 15:19:13 +00001005 TEST_EQUAL(res, exp_result);
Janos Follath0512d172024-02-20 14:30:46 +00001006 if (res == 0) {
Janos Follathfdab7862024-02-22 15:19:13 +00001007 TEST_EQUAL(sign_is_valid(&Z), 1);
1008 TEST_EQUAL(mbedtls_mpi_cmp_mpi(&Z, &X), 0);
Janos Follath0512d172024-02-20 14:30:46 +00001009 }
1010
1011exit:
1012 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1013 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
1014}
1015/* END_CASE */
1016
1017/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001018void mpi_exp_mod(char *input_A, char *input_E,
1019 char *input_N, char *input_X,
1020 int exp_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001021{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001023 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001024 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1025 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001026
Gilles Peskine449bd832023-01-11 14:50:10 +01001027 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1028 TEST_ASSERT(mbedtls_test_read_mpi(&E, input_E) == 0);
1029 TEST_ASSERT(mbedtls_test_read_mpi(&N, input_N) == 0);
1030 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001031
Janos Follath5fc20fc2024-08-21 13:15:13 +01001032#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001033 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001034#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001035 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, NULL);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001036#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001037 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001038#endif
1039 TEST_ASSERT(res == exp_result);
1040 if (res == 0) {
1041 TEST_ASSERT(sign_is_valid(&Z));
1042 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
1043 }
1044
1045#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001046 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001047#endif
1048 res = mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, NULL);
1049#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001050 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_PUBLIC);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001051#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001052 TEST_ASSERT(res == exp_result);
1053 if (res == 0) {
1054 TEST_ASSERT(sign_is_valid(&Z));
1055 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001056 }
1057
1058 /* Now test again with the speed-up parameter supplied as an output. */
Janos Follath5fc20fc2024-08-21 13:15:13 +01001059#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001060 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001061#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001062 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001063#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001064 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001065#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001066 TEST_ASSERT(res == exp_result);
1067 if (res == 0) {
1068 TEST_ASSERT(sign_is_valid(&Z));
1069 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Gilles Peskine342f71b2021-06-09 18:31:35 +02001070 }
1071
1072 /* Now test again with the speed-up parameter supplied in calculated form. */
Janos Follath5fc20fc2024-08-21 13:15:13 +01001073#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001074 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001075#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001076 res = mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001077#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001078 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001079#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001080 TEST_ASSERT(res == exp_result);
1081 if (res == 0) {
1082 TEST_ASSERT(sign_is_valid(&Z));
1083 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &X) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001084 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001085
Paul Bakkerbd51b262014-07-10 15:26:12 +02001086exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001087 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1088 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001089}
Paul Bakker33b43f12013-08-20 11:48:36 +02001090/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001091
Paul Bakker33b43f12013-08-20 11:48:36 +02001092/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001093void mpi_exp_mod_size(int A_bytes, int E_bytes, int N_bytes,
1094 char *input_RR, int exp_result)
Chris Jonesd10b3312020-12-02 10:41:50 +00001095{
1096 mbedtls_mpi A, E, N, RR, Z;
Gilles Peskine449bd832023-01-11 14:50:10 +01001097 mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N);
1098 mbedtls_mpi_init(&RR); mbedtls_mpi_init(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001099
Chris Jonesaa850cd2020-12-03 11:35:41 +00001100 /* Set A to 2^(A_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001101 TEST_ASSERT(mbedtls_mpi_lset(&A, 1) == 0);
1102 TEST_ASSERT(mbedtls_mpi_shift_l(&A, (A_bytes * 8) - 1) == 0);
1103 TEST_ASSERT(mbedtls_mpi_set_bit(&A, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001104
1105 /* Set E to 2^(E_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001106 TEST_ASSERT(mbedtls_mpi_lset(&E, 1) == 0);
1107 TEST_ASSERT(mbedtls_mpi_shift_l(&E, (E_bytes * 8) - 1) == 0);
1108 TEST_ASSERT(mbedtls_mpi_set_bit(&E, 0, 1) == 0);
Chris Jonesaa850cd2020-12-03 11:35:41 +00001109
1110 /* Set N to 2^(N_bytes - 1) + 1 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001111 TEST_ASSERT(mbedtls_mpi_lset(&N, 1) == 0);
1112 TEST_ASSERT(mbedtls_mpi_shift_l(&N, (N_bytes * 8) - 1) == 0);
1113 TEST_ASSERT(mbedtls_mpi_set_bit(&N, 0, 1) == 0);
Chris Jonesd10b3312020-12-02 10:41:50 +00001114
Gilles Peskine449bd832023-01-11 14:50:10 +01001115 if (strlen(input_RR)) {
1116 TEST_ASSERT(mbedtls_test_read_mpi(&RR, input_RR) == 0);
1117 }
Chris Jonesd10b3312020-12-02 10:41:50 +00001118
Janos Follath5fc20fc2024-08-21 13:15:13 +01001119#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001120 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001121#endif
Gilles Peskine449bd832023-01-11 14:50:10 +01001122 TEST_ASSERT(mbedtls_mpi_exp_mod(&Z, &A, &E, &N, &RR) == exp_result);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001123#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001124 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001125#endif
1126
1127#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001128 mbedtls_codepath_reset();
Janos Follath5fc20fc2024-08-21 13:15:13 +01001129#endif
1130 TEST_ASSERT(mbedtls_mpi_exp_mod_unsafe(&Z, &A, &E, &N, &RR) == exp_result);
1131#if defined(MBEDTLS_TEST_HOOKS) && !defined(MBEDTLS_THREADING_C)
Janos Follath96cfd7a2024-08-22 18:30:06 +01001132 TEST_EQUAL(mbedtls_codepath_check, MBEDTLS_MPI_IS_SECRET);
Janos Follath5fc20fc2024-08-21 13:15:13 +01001133#endif
Chris Jonesd10b3312020-12-02 10:41:50 +00001134
1135exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001136 mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N);
1137 mbedtls_mpi_free(&RR); mbedtls_mpi_free(&Z);
Chris Jonesd10b3312020-12-02 10:41:50 +00001138}
1139/* END_CASE */
1140
1141/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001142void mpi_inv_mod(char *input_X, char *input_Y,
1143 char *input_A, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001144{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001146 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001147 mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001148
Gilles Peskine449bd832023-01-11 14:50:10 +01001149 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1150 TEST_ASSERT(mbedtls_test_read_mpi(&Y, input_Y) == 0);
1151 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1152 res = mbedtls_mpi_inv_mod(&Z, &X, &Y);
1153 TEST_ASSERT(res == div_result);
1154 if (res == 0) {
1155 TEST_ASSERT(sign_is_valid(&Z));
1156 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&Z, &A) == 0);
Paul Bakker367dae42009-06-28 21:50:27 +00001157 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001158
Paul Bakkerbd51b262014-07-10 15:26:12 +02001159exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001160 mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001161}
Paul Bakker33b43f12013-08-20 11:48:36 +02001162/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001165void mpi_is_prime(char *input_X, int div_result)
Paul Bakker367dae42009-06-28 21:50:27 +00001166{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001168 int res;
Gilles Peskine449bd832023-01-11 14:50:10 +01001169 mbedtls_mpi_init(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001170
Gilles Peskine449bd832023-01-11 14:50:10 +01001171 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1172 res = mbedtls_mpi_is_prime_ext(&X, 40, mbedtls_test_rnd_std_rand, NULL);
1173 TEST_ASSERT(res == div_result);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001174
Paul Bakkerbd51b262014-07-10 15:26:12 +02001175exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001176 mbedtls_mpi_free(&X);
Paul Bakker367dae42009-06-28 21:50:27 +00001177}
Paul Bakker33b43f12013-08-20 11:48:36 +02001178/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001179
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001181void mpi_is_prime_det(data_t *input_X, data_t *witnesses,
1182 int chunk_len, int rounds)
Janos Follath64eca052018-09-05 17:04:49 +01001183{
1184 mbedtls_mpi X;
1185 int res;
1186 mbedtls_test_mpi_random rand;
1187
Gilles Peskine449bd832023-01-11 14:50:10 +01001188 mbedtls_mpi_init(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001189 rand.data = witnesses;
1190 rand.pos = 0;
1191 rand.chunk_len = chunk_len;
1192
Gilles Peskine449bd832023-01-11 14:50:10 +01001193 TEST_ASSERT(mbedtls_mpi_read_binary(&X, input_X->x, input_X->len) == 0);
1194 res = mbedtls_mpi_is_prime_ext(&X, rounds - 1,
1195 mbedtls_test_mpi_miller_rabin_determinizer,
1196 &rand);
1197 TEST_ASSERT(res == 0);
Darryl Greenac2ead02018-10-02 15:30:39 +01001198
1199 rand.data = witnesses;
1200 rand.pos = 0;
1201 rand.chunk_len = chunk_len;
1202
Gilles Peskine449bd832023-01-11 14:50:10 +01001203 res = mbedtls_mpi_is_prime_ext(&X, rounds,
1204 mbedtls_test_mpi_miller_rabin_determinizer,
1205 &rand);
1206 TEST_ASSERT(res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
Janos Follath64eca052018-09-05 17:04:49 +01001207
1208exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001209 mbedtls_mpi_free(&X);
Janos Follath64eca052018-09-05 17:04:49 +01001210}
1211/* END_CASE */
1212
1213/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Gilles Peskine449bd832023-01-11 14:50:10 +01001214void mpi_gen_prime(int bits, int flags, int ref_ret)
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001215{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001217 int my_ret;
1218
Gilles Peskine449bd832023-01-11 14:50:10 +01001219 mbedtls_mpi_init(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001220
Gilles Peskine449bd832023-01-11 14:50:10 +01001221 my_ret = mbedtls_mpi_gen_prime(&X, bits, flags,
1222 mbedtls_test_rnd_std_rand, NULL);
1223 TEST_ASSERT(my_ret == ref_ret);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001224
Gilles Peskine449bd832023-01-11 14:50:10 +01001225 if (ref_ret == 0) {
1226 size_t actual_bits = mbedtls_mpi_bitlen(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001227
Gilles Peskine449bd832023-01-11 14:50:10 +01001228 TEST_ASSERT(actual_bits >= (size_t) bits);
1229 TEST_ASSERT(actual_bits <= (size_t) bits + 1);
1230 TEST_ASSERT(sign_is_valid(&X));
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001231
Gilles Peskine449bd832023-01-11 14:50:10 +01001232 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1233 mbedtls_test_rnd_std_rand,
1234 NULL) == 0);
1235 if (flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001236 /* X = ( X - 1 ) / 2 */
Gilles Peskine449bd832023-01-11 14:50:10 +01001237 TEST_ASSERT(mbedtls_mpi_shift_r(&X, 1) == 0);
1238 TEST_ASSERT(mbedtls_mpi_is_prime_ext(&X, 40,
1239 mbedtls_test_rnd_std_rand,
1240 NULL) == 0);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001241 }
1242 }
1243
Paul Bakkerbd51b262014-07-10 15:26:12 +02001244exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001245 mbedtls_mpi_free(&X);
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001246}
1247/* END_CASE */
1248
Paul Bakker33b43f12013-08-20 11:48:36 +02001249/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001250void mpi_shift_l(char *input_X, int shift_X,
1251 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001252{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001253 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001254 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001255
Gilles Peskine449bd832023-01-11 14:50:10 +01001256 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1257 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1258 TEST_ASSERT(mbedtls_mpi_shift_l(&X, shift_X) == 0);
1259 TEST_ASSERT(sign_is_valid(&X));
1260 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001261
Paul Bakkerbd51b262014-07-10 15:26:12 +02001262exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001263 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001264}
Paul Bakker33b43f12013-08-20 11:48:36 +02001265/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001266
Paul Bakker33b43f12013-08-20 11:48:36 +02001267/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001268void mpi_shift_r(char *input_X, int shift_X,
1269 char *input_A)
Paul Bakker367dae42009-06-28 21:50:27 +00001270{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001271 mbedtls_mpi X, A;
Gilles Peskine449bd832023-01-11 14:50:10 +01001272 mbedtls_mpi_init(&X); mbedtls_mpi_init(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001273
Gilles Peskine449bd832023-01-11 14:50:10 +01001274 TEST_ASSERT(mbedtls_test_read_mpi(&X, input_X) == 0);
1275 TEST_ASSERT(mbedtls_test_read_mpi(&A, input_A) == 0);
1276 TEST_ASSERT(mbedtls_mpi_shift_r(&X, shift_X) == 0);
1277 TEST_ASSERT(sign_is_valid(&X));
1278 TEST_ASSERT(mbedtls_mpi_cmp_mpi(&X, &A) == 0);
Paul Bakker6c591fa2011-05-05 11:49:20 +00001279
Paul Bakkerbd51b262014-07-10 15:26:12 +02001280exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001281 mbedtls_mpi_free(&X); mbedtls_mpi_free(&A);
Paul Bakker367dae42009-06-28 21:50:27 +00001282}
Paul Bakker33b43f12013-08-20 11:48:36 +02001283/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001284
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001285/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001286void mpi_fill_random(int wanted_bytes, int rng_bytes,
1287 int before, int expected_ret)
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001288{
1289 mbedtls_mpi X;
1290 int ret;
1291 size_t bytes_left = rng_bytes;
Gilles Peskine449bd832023-01-11 14:50:10 +01001292 mbedtls_mpi_init(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001293
Gilles Peskine449bd832023-01-11 14:50:10 +01001294 if (before != 0) {
Gilles Peskine422e8672021-04-02 00:02:27 +02001295 /* Set X to sign(before) * 2^(|before|-1) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001296 TEST_ASSERT(mbedtls_mpi_lset(&X, before > 0 ? 1 : -1) == 0);
1297 if (before < 0) {
1298 before = -before;
1299 }
1300 TEST_ASSERT(mbedtls_mpi_shift_l(&X, before - 1) == 0);
Gilles Peskine422e8672021-04-02 00:02:27 +02001301 }
1302
Gilles Peskine449bd832023-01-11 14:50:10 +01001303 ret = mbedtls_mpi_fill_random(&X, wanted_bytes,
1304 f_rng_bytes_left, &bytes_left);
1305 TEST_ASSERT(ret == expected_ret);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001306
Gilles Peskine449bd832023-01-11 14:50:10 +01001307 if (expected_ret == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001308 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1309 * as a big-endian representation of the number. We know when
1310 * our RNG function returns null bytes, so we know how many
1311 * leading zero bytes the number has. */
1312 size_t leading_zeros = 0;
Gilles Peskine449bd832023-01-11 14:50:10 +01001313 if (wanted_bytes > 0 && rng_bytes % 256 == 0) {
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001314 leading_zeros = 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001315 }
1316 TEST_ASSERT(mbedtls_mpi_size(&X) + leading_zeros ==
1317 (size_t) wanted_bytes);
1318 TEST_ASSERT((int) bytes_left == rng_bytes - wanted_bytes);
1319 TEST_ASSERT(sign_is_valid(&X));
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001320 }
1321
1322exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001323 mbedtls_mpi_free(&X);
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001324}
1325/* END_CASE */
1326
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001327/* BEGIN_CASE */
Gilles Peskine449bd832023-01-11 14:50:10 +01001328void most_negative_mpi_sint()
Gilles Peskineaf601f92022-11-15 23:02:14 +01001329{
1330 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1331 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1332 * is a valid value. However, negating it (`-n`) has undefined behavior
1333 * (although in practice `-n` evaluates to the value n).
1334 *
1335 * This function has ad hoc tests for this value. It's separated from other
1336 * functions because the test framework makes it hard to pass this value
1337 * into test cases.
1338 *
1339 * In the comments here:
1340 * - biL = number of bits in limbs
1341 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1342 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1343 */
1344
1345 mbedtls_mpi A, R, X;
Gilles Peskine449bd832023-01-11 14:50:10 +01001346 mbedtls_mpi_init(&A);
1347 mbedtls_mpi_init(&R);
1348 mbedtls_mpi_init(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001349
Gilles Peskine449bd832023-01-11 14:50:10 +01001350 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << (biL - 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001351 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001352 const mbedtls_mpi_sint most_negative = -most_positive - 1;
1353 TEST_EQUAL((mbedtls_mpi_uint) most_negative,
1354 (mbedtls_mpi_uint) 1 << (biL - 1));
1355 TEST_EQUAL((mbedtls_mpi_uint) most_negative << 1, 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001356
1357 /* Test mbedtls_mpi_lset() */
Gilles Peskine449bd832023-01-11 14:50:10 +01001358 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1359 TEST_EQUAL(A.s, -1);
1360 TEST_EQUAL(A.n, 1);
1361 TEST_EQUAL(A.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001362
1363 /* Test mbedtls_mpi_cmp_int(): -p == -p */
Gilles Peskine449bd832023-01-11 14:50:10 +01001364 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001365
1366 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1367 A.p[0] = most_positive_plus_1 + 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001368 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), -1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001369
1370 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1371 A.p[0] = most_positive_plus_1 - 1;
Gilles Peskine449bd832023-01-11 14:50:10 +01001372 TEST_EQUAL(mbedtls_mpi_cmp_int(&A, most_negative), 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001373
1374 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001375 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1376 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1377 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001378
1379 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001380 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1381 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1382 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, most_negative), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001383
1384 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001385 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1386 TEST_EQUAL(mbedtls_mpi_add_int(&X, &A, most_negative), 0);
1387 TEST_EQUAL(X.s, -1);
1388 TEST_EQUAL(X.n, 2);
1389 TEST_EQUAL(X.p[0], 0);
1390 TEST_EQUAL(X.p[1], 1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001391
1392 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001393 mbedtls_mpi_free(&X);
1394 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1395 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1396 TEST_EQUAL(X.s, 1);
1397 TEST_EQUAL(X.n, 1);
1398 TEST_EQUAL(X.p[0], ~(mbedtls_mpi_uint) 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001399
1400 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001401 TEST_EQUAL(mbedtls_mpi_lset(&A, 0), 0);
1402 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1403 TEST_EQUAL(X.s, 1);
1404 TEST_EQUAL(X.n, 1);
1405 TEST_EQUAL(X.p[0], most_positive_plus_1);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001406
1407 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001408 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 0);
1409 TEST_EQUAL(mbedtls_mpi_sub_int(&X, &A, most_negative), 0);
1410 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001411
1412 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001413 TEST_EQUAL(mbedtls_mpi_lset(&A, -most_positive), 0);
1414 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1415 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1416 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001417
1418 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001419 TEST_EQUAL(mbedtls_mpi_lset(&A, most_negative), 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, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001423
1424 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001425 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1426 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1427 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 2), 0);
1428 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001429
1430 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-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, -most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001435
1436 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001437 TEST_EQUAL(mbedtls_mpi_lset(&A, most_positive), 0);
1438 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1439 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, 0), 0);
1440 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, most_positive), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001441
1442 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001443 TEST_EQUAL(mbedtls_mpi_add_int(&A, &A, 1), 0);
1444 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1445 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -1), 0);
1446 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001447
1448 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
Gilles Peskine449bd832023-01-11 14:50:10 +01001449 TEST_EQUAL(mbedtls_mpi_shift_l(&A, 1), 0);
1450 TEST_EQUAL(mbedtls_mpi_div_int(&X, &R, &A, most_negative), 0);
1451 TEST_EQUAL(mbedtls_mpi_cmp_int(&X, -2), 0);
1452 TEST_EQUAL(mbedtls_mpi_cmp_int(&R, 0), 0);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001453
1454 /* Test mbedtls_mpi_mod_int(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001455 TEST_EQUAL(mbedtls_mpi_mod_int(X.p, &A, most_negative),
1456 MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001457
1458 /* Test mbedtls_mpi_random(): never valid */
Gilles Peskine449bd832023-01-11 14:50:10 +01001459 TEST_EQUAL(mbedtls_mpi_random(&X, most_negative, &A,
1460 mbedtls_test_rnd_std_rand, NULL),
1461 MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001462
1463exit:
Gilles Peskine449bd832023-01-11 14:50:10 +01001464 mbedtls_mpi_free(&A);
1465 mbedtls_mpi_free(&R);
1466 mbedtls_mpi_free(&X);
Gilles Peskineaf601f92022-11-15 23:02:14 +01001467}
1468/* END_CASE */
1469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Gilles Peskine449bd832023-01-11 14:50:10 +01001471void mpi_selftest()
Paul Bakkere896fea2009-07-06 06:40:23 +00001472{
Gilles Peskine449bd832023-01-11 14:50:10 +01001473 TEST_ASSERT(mbedtls_mpi_self_test(1) == 0);
Paul Bakkere896fea2009-07-06 06:40:23 +00001474}
Paul Bakker33b43f12013-08-20 11:48:36 +02001475/* END_CASE */