blob: b0d947c9db7aecdac6822508a1de78dac5cf9ea9 [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 Follathf1d617d2022-07-21 09:29:32 +01004#include "bignum_core.h"
Janos Follath64eca052018-09-05 17:04:49 +01005
Chris Jonese64a46f2020-12-03 17:44:03 +00006#if MBEDTLS_MPI_MAX_BITS > 792
7#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +00008#endif
Janos Follath64eca052018-09-05 17:04:49 +01009
Gilles Peskinedffc7102021-06-10 15:34:15 +020010/* Check the validity of the sign bit in an MPI object. Reject representations
11 * that are not supported by the rest of the library and indicate a bug when
12 * constructing the value. */
13static int sign_is_valid( const mbedtls_mpi *X )
14{
15 if( X->s != 1 && X->s != -1 )
16 return( 0 ); // invalid sign bit, e.g. 0
17 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
18 return( 0 ); // negative zero
19 return( 1 );
20}
21
Janos Follath64eca052018-09-05 17:04:49 +010022typedef struct mbedtls_test_mpi_random
23{
24 data_t *data;
25 size_t pos;
26 size_t chunk_len;
27} mbedtls_test_mpi_random;
28
29/*
30 * This function is called by the Miller-Rabin primality test each time it
31 * chooses a random witness. The witnesses (or non-witnesses as provided by the
32 * test) are stored in the data member of the state structure. Each number is in
33 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
34 */
35int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
36 unsigned char* buf,
37 size_t len )
38{
39 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
40
41 if( random == NULL || random->data->x == NULL || buf == NULL )
42 return( -1 );
43
44 if( random->pos + random->chunk_len > random->data->len
45 || random->chunk_len > len )
46 {
47 return( -1 );
48 }
49
50 memset( buf, 0, len );
51
52 /* The witness is written to the end of the buffer, since the buffer is
53 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
54 * Writing the witness to the start of the buffer would result in the
55 * buffer being 'witness 000...000', which would be treated as
56 * witness * 2^n for some n. */
57 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
58 random->chunk_len );
59
60 random->pos += random->chunk_len;
61
62 return( 0 );
63}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010064
65/* Random generator that is told how many bytes to return. */
66static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
67{
68 size_t *bytes_left = state;
69 size_t i;
70 for( i = 0; i < len; i++ )
71 {
72 if( *bytes_left == 0 )
73 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
74 buf[i] = *bytes_left & 0xff;
75 --( *bytes_left );
76 }
77 return( 0 );
78}
79
Gilles Peskineeedefa52021-04-13 19:50:04 +020080/* Test whether bytes represents (in big-endian base 256) a number b that
81 * is significantly above a power of 2. That is, b must not have a long run
82 * of unset bits after the most significant bit.
83 *
84 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
85 * This function returns 1 if, when drawing a number between 0 and b,
86 * the probability that this number is at least 2^n is not negligible.
87 * This probability is (b - 2^n) / b and this function checks that this
88 * number is above some threshold A. The threshold value is heuristic and
89 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020090 */
91static int is_significantly_above_a_power_of_2( data_t *bytes )
92{
93 const uint8_t *p = bytes->x;
94 size_t len = bytes->len;
95 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020096
97 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +020098 while( len > 0 && p[0] == 0 )
99 {
100 ++p;
101 --len;
102 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200103 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200104 if( len == 0 )
105 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200106 /* Extract the (up to) 2 most significant bytes */
107 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200108 x = p[0];
109 else
110 x = ( p[0] << 8 ) | p[1];
111
Gilles Peskineeedefa52021-04-13 19:50:04 +0200112 /* Shift the most significant bit of x to position 8 and mask it out */
113 while( ( x & 0xfe00 ) != 0 )
114 x >>= 1;
115 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200116
Gilles Peskineeedefa52021-04-13 19:50:04 +0200117 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
118 * a power of 2 iff x is significantly above 0 compared to 2^8.
119 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
120 * description above. */
121 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200122}
123
Paul Bakker33b43f12013-08-20 11:48:36 +0200124/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000125
Paul Bakker33b43f12013-08-20 11:48:36 +0200126/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200127 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200128 * END_DEPENDENCIES
129 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000130
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000131/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100132void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200133{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200134 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200135
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200136 mbedtls_mpi_init( &X );
137 mbedtls_mpi_init( &Y );
138 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200139
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200140 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
141 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200142 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200143 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200144
145exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200146 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200147}
148/* END_CASE */
149
150/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100151void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
152 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200153 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000154{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200155 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000156 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100157 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000158
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000160
Janos Follath04dadb72019-03-06 12:29:37 +0000161 memset( str, '!', sizeof( str ) );
162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200164 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000165 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200166 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100167 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200168 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000169 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200170 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000171 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000172 }
173 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000174
Paul Bakkerbd51b262014-07-10 15:26:12 +0200175exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000177}
Paul Bakker33b43f12013-08-20 11:48:36 +0200178/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000179
Paul Bakker33b43f12013-08-20 11:48:36 +0200180/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100181void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000182{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200183 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000184 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100185 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000188
Paul Bakkere896fea2009-07-06 06:40:23 +0000189
Azim Khand30ca132017-06-09 04:32:58 +0100190 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200191 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100192 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100193 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000194
Paul Bakkerbd51b262014-07-10 15:26:12 +0200195exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000197}
Paul Bakker33b43f12013-08-20 11:48:36 +0200198/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000199
Paul Bakker33b43f12013-08-20 11:48:36 +0200200/* BEGIN_CASE */
Janos Follath91dc67d2022-07-22 14:24:58 +0100201void mbedtls_mpi_core_io_null()
202{
203 mbedtls_mpi_uint X = 0;
204 int ret;
205
206 ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
207 TEST_ASSERT( ret == 0 );
208 ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
209 TEST_ASSERT( ret == 0 );
210
211 ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
212 TEST_ASSERT( ret == 0 );
213 ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
214 TEST_ASSERT( ret == 0 );
215
216 ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
217 TEST_ASSERT( ret == 0 );
218 ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
219 TEST_ASSERT( ret == 0 );
220
221 ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
222 TEST_ASSERT( ret == 0 );
223 ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
224 TEST_ASSERT( ret == 0 );
225
226exit:
227 ;
228}
229/* END_CASE */
230
231/* BEGIN_CASE */
Janos Follathf1d617d2022-07-21 09:29:32 +0100232void mbedtls_mpi_core_io_be( data_t *input, int nb_int, int nx_64_int, int iret,
233 int oret )
234{
235 #define BMAX 1024
236 unsigned char buf[BMAX];
237 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
238 mbedtls_mpi_uint X[XMAX];
239 size_t nx, nb;
240 int ret;
241
242 if( iret != 0 )
243 TEST_ASSERT( oret == 0 );
244
245 TEST_ASSERT( 0 <= nb_int );
246 nb = nb_int;
247 TEST_ASSERT( nb <= BMAX );
248
249 TEST_ASSERT( 0 <= nx_64_int );
250 nx = nx_64_int;
251 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
252 * to double the number of limbs to have the same size. */
253 if( sizeof( mbedtls_mpi_uint ) == 4 )
254 nx *= 2;
255 TEST_ASSERT( nx <= XMAX );
256
257 ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
258 TEST_ASSERT( ret == iret );
259
260 if( iret == 0 )
261 {
262 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
263 TEST_ASSERT( ret == oret );
264 }
265
266 if( ( iret == 0 ) && ( oret == 0 ) )
267 {
268 if( nb > input->len )
269 {
270 size_t leading_zeroes = nb - input->len;
271 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
272 for( size_t i = 0; i < leading_zeroes; i++ )
273 TEST_ASSERT( buf[i] == 0 );
274 }
275 else
276 {
277 size_t leading_zeroes = input->len - nb;
278 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
279 for( size_t i = 0; i < leading_zeroes; i++ )
280 TEST_ASSERT( input->x[i] == 0 );
281 }
282 }
283
284exit:
285 ;
286
287 #undef BMAX
288 #undef XMAX
289}
290/* END_CASE */
291
292/* BEGIN_CASE */
Janos Follath6ff35362022-07-21 15:27:21 +0100293void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_64_int, int iret,
294 int oret )
295{
296 #define BMAX 1024
297 unsigned char buf[BMAX];
298 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
299 mbedtls_mpi_uint X[XMAX];
300 size_t nx, nb;
301 int ret;
302
303 if( iret != 0 )
304 TEST_ASSERT( oret == 0 );
305
306 TEST_ASSERT( 0 <= nb_int );
307 nb = nb_int;
308 TEST_ASSERT( nb <= BMAX );
309
310 TEST_ASSERT( 0 <= nx_64_int );
311 nx = nx_64_int;
312 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
313 * to double the number of limbs to have the same size. */
314 if( sizeof( mbedtls_mpi_uint ) == 4 )
315 nx *= 2;
316 TEST_ASSERT( nx <= XMAX );
317
318 ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
319 TEST_ASSERT( ret == iret );
320
321 if( iret == 0 )
322 {
323 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
324 TEST_ASSERT( ret == oret );
325 }
326
327 if( ( iret == 0 ) && ( oret == 0 ) )
328 {
329 if( nb > input->len )
330 {
331 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
332 for( size_t i = input->len; i < nb; i++ )
333 TEST_ASSERT( buf[i] == 0 );
334 }
335 else
336 {
337 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
338 for( size_t i = nb; i < input->len; i++ )
339 TEST_ASSERT( input->x[i] == 0 );
340 }
341 }
342
343exit:
344 ;
345
346 #undef BMAX
347 #undef XMAX
348}
349/* END_CASE */
350
351/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100352void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000353{
354 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000355 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000356 size_t len;
357
358 mbedtls_mpi_init( &X );
359
360
361 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200362 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100363 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100364 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000365
366exit:
367 mbedtls_mpi_free( &X );
368}
369/* END_CASE */
370
371/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100372void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
373 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000374{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000376 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000377 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000378
379 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000380
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000382
Werner Lewis19b4cd82022-07-07 11:02:27 +0100383 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200386 if( buflen > (size_t) output_size )
387 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000388
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200390 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000391 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000392
Ronald Cron2dbba992020-06-10 11:42:32 +0200393 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
394 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000395 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000396
Paul Bakkerbd51b262014-07-10 15:26:12 +0200397exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000399}
Paul Bakker33b43f12013-08-20 11:48:36 +0200400/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000401
Janos Follathe344d0f2019-02-19 16:17:40 +0000402/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100403void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
404 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000405{
406 mbedtls_mpi X;
407 unsigned char buf[1000];
408 size_t buflen;
409
410 memset( buf, 0x00, 1000 );
411
412 mbedtls_mpi_init( &X );
413
Werner Lewis19b4cd82022-07-07 11:02:27 +0100414 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000415
416 buflen = mbedtls_mpi_size( &X );
417 if( buflen > (size_t) output_size )
418 buflen = (size_t) output_size;
419
420 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
421 if( result == 0)
422 {
423
Ronald Cron2dbba992020-06-10 11:42:32 +0200424 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
425 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000426 }
427
428exit:
429 mbedtls_mpi_free( &X );
430}
431/* END_CASE */
432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100434void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000435{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000437 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000438 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000439 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000440 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000441
442 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000445
Paul Bakker33b43f12013-08-20 11:48:36 +0200446 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200447 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100448 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000449 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000450 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000451
Paul Bakker33b43f12013-08-20 11:48:36 +0200452 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000453 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200454 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 buflen = mbedtls_mpi_size( &X );
456 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000457
Paul Bakkere896fea2009-07-06 06:40:23 +0000458
Ronald Cron2dbba992020-06-10 11:42:32 +0200459 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
460 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000461 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000462
Paul Bakkerbd51b262014-07-10 15:26:12 +0200463exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000465}
Paul Bakker33b43f12013-08-20 11:48:36 +0200466/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000467
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100469void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000470{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000472 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200473 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000474
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200475 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000476
Werner Lewis19b4cd82022-07-07 11:02:27 +0100477 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000478
Paul Bakker33b43f12013-08-20 11:48:36 +0200479 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000480 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100481 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000482 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200483 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000484
Paul Bakker33b43f12013-08-20 11:48:36 +0200485 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000486 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100487 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000488 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200489 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000492
Paul Bakkerbd51b262014-07-10 15:26:12 +0200493exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000495}
Paul Bakker33b43f12013-08-20 11:48:36 +0200496/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000497
Paul Bakker33b43f12013-08-20 11:48:36 +0200498/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100499void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000500{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_mpi X;
502 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100503 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000505
Paul Bakkerbd51b262014-07-10 15:26:12 +0200506exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000508}
Paul Bakker33b43f12013-08-20 11:48:36 +0200509/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000510
Paul Bakker33b43f12013-08-20 11:48:36 +0200511/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100512void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
513 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000514{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 mbedtls_mpi X, Y;
516 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000517
Werner Lewis19b4cd82022-07-07 11:02:27 +0100518 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
519 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100520 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
521
522 if( result == 0 )
523 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200524 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100525 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
526 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000527
Paul Bakkerbd51b262014-07-10 15:26:12 +0200528exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000530}
Paul Bakker33b43f12013-08-20 11:48:36 +0200531/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000532
Paul Bakker33b43f12013-08-20 11:48:36 +0200533/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100534void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000535{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200536 mbedtls_mpi X;
537 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000538
Werner Lewis19b4cd82022-07-07 11:02:27 +0100539 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000541
Paul Bakkerbd51b262014-07-10 15:26:12 +0200542exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200543 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 */
Werner Lewis9802d362022-07-07 11:37:24 +0100548void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000549{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 mbedtls_mpi X;
551 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000552
Werner Lewis19b4cd82022-07-07 11:02:27 +0100553 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200554 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000555
Paul Bakkerbd51b262014-07-10 15:26:12 +0200556exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000558}
Paul Bakker33b43f12013-08-20 11:48:36 +0200559/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000560
Paul Bakker33b43f12013-08-20 11:48:36 +0200561/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100562void mbedtls_mpi_gcd( char * input_X, char * input_Y,
563 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000564{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 mbedtls_mpi A, X, Y, Z;
566 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000567
Werner Lewis19b4cd82022-07-07 11:02:27 +0100568 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
569 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
570 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200572 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000574
Paul Bakkerbd51b262014-07-10 15:26:12 +0200575exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000577}
Paul Bakker33b43f12013-08-20 11:48:36 +0200578/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000579
Paul Bakker33b43f12013-08-20 11:48:36 +0200580/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200581void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000582{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_mpi X;
584 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000585
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200586 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
587 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000588
Paul Bakkerbd51b262014-07-10 15:26:12 +0200589exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200590 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000591}
Paul Bakker33b43f12013-08-20 11:48:36 +0200592/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000593
Paul Bakker33b43f12013-08-20 11:48:36 +0200594/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100595void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
596 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000597{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 mbedtls_mpi X, Y;
599 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000600
Werner Lewis19b4cd82022-07-07 11:02:27 +0100601 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
602 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200603 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000604
Paul Bakkerbd51b262014-07-10 15:26:12 +0200605exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200606 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000607}
Paul Bakker33b43f12013-08-20 11:48:36 +0200608/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000609
Paul Bakker33b43f12013-08-20 11:48:36 +0200610/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100611void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
612 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100613 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100614{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200615 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100616 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100617 mbedtls_mpi X, Y;
618 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
619
Werner Lewis19b4cd82022-07-07 11:02:27 +0100620 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
621 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100622
Gilles Peskine9018b112020-01-21 16:30:53 +0100623 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
624 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100625
Janos Follath0e5532d2019-10-11 14:21:53 +0100626 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100627 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100628 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100629
630exit:
631 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
632}
633/* END_CASE */
634
635/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100636void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
637 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000638{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_mpi X, Y;
640 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000641
Werner Lewis19b4cd82022-07-07 11:02:27 +0100642 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
643 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000645
Paul Bakkerbd51b262014-07-10 15:26:12 +0200646exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000648}
Paul Bakker33b43f12013-08-20 11:48:36 +0200649/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000650
Paul Bakker33b43f12013-08-20 11:48:36 +0200651/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200652void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000653{
Gilles Peskined0722f82021-06-10 23:00:33 +0200654 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200655 mbedtls_mpi_init( &src );
656 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200657 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000658
Werner Lewis19b4cd82022-07-07 11:02:27 +0100659 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
660 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200661
662 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100663 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200664 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200665 TEST_ASSERT( sign_is_valid( &dst ) );
666 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000667
Gilles Peskined0722f82021-06-10 23:00:33 +0200668 /* mbedtls_mpi_safe_cond_assign(), assignment done */
669 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100670 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200671 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
672 TEST_ASSERT( sign_is_valid( &dst ) );
673 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
674
675 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
676 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100677 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200678 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
679 TEST_ASSERT( sign_is_valid( &dst ) );
680 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
681
Paul Bakkerbd51b262014-07-10 15:26:12 +0200682exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200683 mbedtls_mpi_free( &src );
684 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200685 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100686}
687/* END_CASE */
688
689/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200690void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100691{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200692 mbedtls_mpi X, A;
693 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200694 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000695
Werner Lewis19b4cd82022-07-07 11:02:27 +0100696 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200698
Werner Lewis19b4cd82022-07-07 11:02:27 +0100699 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200700 TEST_ASSERT( sign_is_valid( &X ) );
701 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000702
Paul Bakkerbd51b262014-07-10 15:26:12 +0200703exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200704 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000706}
Paul Bakker33b43f12013-08-20 11:48:36 +0200707/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000708
Paul Bakker33b43f12013-08-20 11:48:36 +0200709/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200710void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
711{
712 mbedtls_mpi X, Y, X0, Y0;
713 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
714 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
715
Werner Lewis19b4cd82022-07-07 11:02:27 +0100716 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
717 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200718
Gilles Peskined0722f82021-06-10 23:00:33 +0200719 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100720 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
721 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200722 mbedtls_mpi_swap( &X, &Y );
723 TEST_ASSERT( sign_is_valid( &X ) );
724 TEST_ASSERT( sign_is_valid( &Y ) );
725 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
726 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
727
Gilles Peskined0722f82021-06-10 23:00:33 +0200728 /* mbedtls_mpi_safe_cond_swap(), swap done */
729 mbedtls_mpi_free( &X );
730 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100731 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
732 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200733 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
734 TEST_ASSERT( sign_is_valid( &X ) );
735 TEST_ASSERT( sign_is_valid( &Y ) );
736 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
737 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
738
739 /* mbedtls_mpi_safe_cond_swap(), swap not done */
740 mbedtls_mpi_free( &X );
741 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100742 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
743 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200744 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
745 TEST_ASSERT( sign_is_valid( &X ) );
746 TEST_ASSERT( sign_is_valid( &Y ) );
747 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
748 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
749
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200750exit:
751 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
752 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
753}
754/* END_CASE */
755
756/* BEGIN_CASE */
757void mpi_swap_self( char *X_hex )
758{
759 mbedtls_mpi X, X0;
760 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
761
Werner Lewis19b4cd82022-07-07 11:02:27 +0100762 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
763 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200764
765 mbedtls_mpi_swap( &X, &X );
766 TEST_ASSERT( sign_is_valid( &X ) );
767 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
768
769exit:
770 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
771}
772/* END_CASE */
773
774/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100776{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777 mbedtls_mpi X;
778 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100779
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200781 if( used > 0 )
782 {
783 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
784 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
785 }
786 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200788 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100789
Paul Bakkerbd51b262014-07-10 15:26:12 +0200790exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200791 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100792}
793/* END_CASE */
794
795/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100796void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
797 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000798{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_mpi X, Y, Z, A;
800 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000801
Werner Lewis19b4cd82022-07-07 11:02:27 +0100802 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
803 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
804 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200806 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000808
Gilles Peskine56f943a2020-07-23 01:18:11 +0200809 /* result == first operand */
810 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200811 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200812 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100813 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200814
815 /* result == second operand */
816 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200817 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200818 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
819
Paul Bakkerbd51b262014-07-10 15:26:12 +0200820exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000822}
Paul Bakker33b43f12013-08-20 11:48:36 +0200823/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000824
Paul Bakker33b43f12013-08-20 11:48:36 +0200825/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100826void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100827{
828 mbedtls_mpi X, A;
829 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
830
Werner Lewis19b4cd82022-07-07 11:02:27 +0100831 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100832
Werner Lewis19b4cd82022-07-07 11:02:27 +0100833 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100834 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
835 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200836 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100837
Werner Lewis19b4cd82022-07-07 11:02:27 +0100838 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100839 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200840 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100841 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
842
Werner Lewis19b4cd82022-07-07 11:02:27 +0100843 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100844 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200845 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100846 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
847
848exit:
849 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
850}
851/* END_CASE */
852
853
854/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100855void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
856 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000857{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 mbedtls_mpi X, Y, Z, A;
859 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000860
Werner Lewis19b4cd82022-07-07 11:02:27 +0100861 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
862 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
863 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200865 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000867
Gilles Peskine56f943a2020-07-23 01:18:11 +0200868 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200870 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100872 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200873
874 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200876 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000878
Paul Bakkerbd51b262014-07-10 15:26:12 +0200879exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200880 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000881}
Paul Bakker33b43f12013-08-20 11:48:36 +0200882/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000883
Paul Bakker33b43f12013-08-20 11:48:36 +0200884/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100885void mbedtls_mpi_add_int( char * input_X, int input_Y,
886 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000887{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200888 mbedtls_mpi X, Z, A;
889 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000890
Werner Lewis19b4cd82022-07-07 11:02:27 +0100891 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
892 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200894 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000896
Paul Bakkerbd51b262014-07-10 15:26:12 +0200897exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000899}
Paul Bakker33b43f12013-08-20 11:48:36 +0200900/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000901
Paul Bakker33b43f12013-08-20 11:48:36 +0200902/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100903void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
904 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000905{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200906 mbedtls_mpi X, Y, Z, A;
907 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000908
Werner Lewis19b4cd82022-07-07 11:02:27 +0100909 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
910 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
911 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200912 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200913 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000915
Gilles Peskine56f943a2020-07-23 01:18:11 +0200916 /* result == first operand */
917 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200918 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200919 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100920 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200921
922 /* result == second operand */
923 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200924 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200925 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
926
Paul Bakkerbd51b262014-07-10 15:26:12 +0200927exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200928 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000929}
Paul Bakker33b43f12013-08-20 11:48:36 +0200930/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000931
Paul Bakker33b43f12013-08-20 11:48:36 +0200932/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100933void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
934 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000935{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000937 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000939
Werner Lewis19b4cd82022-07-07 11:02:27 +0100940 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
941 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
942 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100943
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200945 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200946 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000947 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000949
Gilles Peskine56f943a2020-07-23 01:18:11 +0200950 /* result == first operand */
951 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200952 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200953 if( sub_result == 0 )
954 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100955 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200956
957 /* result == second operand */
958 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200959 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200960 if( sub_result == 0 )
961 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
962
Paul Bakkerbd51b262014-07-10 15:26:12 +0200963exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200964 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000965}
Paul Bakker33b43f12013-08-20 11:48:36 +0200966/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000967
Paul Bakker33b43f12013-08-20 11:48:36 +0200968/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100969void mbedtls_mpi_sub_int( char * input_X, int input_Y,
970 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000971{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200972 mbedtls_mpi X, Z, A;
973 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000974
Werner Lewis19b4cd82022-07-07 11:02:27 +0100975 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
976 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200978 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000980
Paul Bakkerbd51b262014-07-10 15:26:12 +0200981exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000983}
Paul Bakker33b43f12013-08-20 11:48:36 +0200984/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000985
Paul Bakker33b43f12013-08-20 11:48:36 +0200986/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100987void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
988 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000989{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 mbedtls_mpi X, Y, Z, A;
991 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000992
Werner Lewis19b4cd82022-07-07 11:02:27 +0100993 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
994 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
995 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200996 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200997 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000999
Paul Bakkerbd51b262014-07-10 15:26:12 +02001000exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001001 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001002}
Paul Bakker33b43f12013-08-20 11:48:36 +02001003/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001004
Paul Bakker33b43f12013-08-20 11:48:36 +02001005/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001006void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001007 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001008{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001009 mbedtls_mpi X, Z, A;
1010 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001011
Werner Lewis19b4cd82022-07-07 11:02:27 +01001012 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1013 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001015 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001016 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001018 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001020 else
1021 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001022
Paul Bakkerbd51b262014-07-10 15:26:12 +02001023exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001025}
Paul Bakker33b43f12013-08-20 11:48:36 +02001026/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001027
Paul Bakker33b43f12013-08-20 11:48:36 +02001028/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001029void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1030 char * input_A, char * input_B,
1031 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001032{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001034 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1036 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001037
Werner Lewis19b4cd82022-07-07 11:02:27 +01001038 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1039 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1040 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1041 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001042 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001043 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001044 if( res == 0 )
1045 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001046 TEST_ASSERT( sign_is_valid( &Q ) );
1047 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1049 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001050 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001051
Paul Bakkerbd51b262014-07-10 15:26:12 +02001052exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001053 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1054 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001055}
Paul Bakker33b43f12013-08-20 11:48:36 +02001056/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001057
Paul Bakker33b43f12013-08-20 11:48:36 +02001058/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001059void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001060 char * input_A, char * input_B,
1061 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001062{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001063 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001064 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1066 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001067
Werner Lewis19b4cd82022-07-07 11:02:27 +01001068 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1069 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1070 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001072 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001073 if( res == 0 )
1074 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001075 TEST_ASSERT( sign_is_valid( &Q ) );
1076 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1078 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001079 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001080
Paul Bakkerbd51b262014-07-10 15:26:12 +02001081exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1083 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001084}
Paul Bakker33b43f12013-08-20 11:48:36 +02001085/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001086
Paul Bakker33b43f12013-08-20 11:48:36 +02001087/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001088void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1089 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001090{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001092 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001094
Werner Lewis19b4cd82022-07-07 11:02:27 +01001095 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1096 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1097 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001099 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001100 if( res == 0 )
1101 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001102 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001104 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001105
Paul Bakkerbd51b262014-07-10 15:26:12 +02001106exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001108}
Paul Bakker33b43f12013-08-20 11:48:36 +02001109/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001110
Paul Bakker33b43f12013-08-20 11:48:36 +02001111/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001112void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001113 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001114{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001116 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 mbedtls_mpi_uint r;
1118 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001119
Werner Lewis19b4cd82022-07-07 11:02:27 +01001120 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001122 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001123 if( res == 0 )
1124 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001126 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001127
Paul Bakkerbd51b262014-07-10 15:26:12 +02001128exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001130}
Paul Bakker33b43f12013-08-20 11:48:36 +02001131/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001132
Paul Bakker33b43f12013-08-20 11:48:36 +02001133/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001134void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1135 char * input_N, char * input_X,
1136 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001137{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001139 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1141 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001142
Werner Lewis19b4cd82022-07-07 11:02:27 +01001143 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1144 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1145 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1146 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001147
Gilles Peskine342f71b2021-06-09 18:31:35 +02001148 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001149 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001150 if( res == 0 )
1151 {
1152 TEST_ASSERT( sign_is_valid( &Z ) );
1153 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1154 }
1155
1156 /* Now test again with the speed-up parameter supplied as an output. */
1157 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001158 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001159 if( res == 0 )
1160 {
1161 TEST_ASSERT( sign_is_valid( &Z ) );
1162 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1163 }
1164
1165 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001166 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001167 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001168 if( res == 0 )
1169 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001170 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001171 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001172 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001173
Paul Bakkerbd51b262014-07-10 15:26:12 +02001174exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1176 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); 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
Paul Bakker33b43f12013-08-20 11:48:36 +02001180/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001181void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001182 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001183{
1184 mbedtls_mpi A, E, N, RR, Z;
1185 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1186 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1187
Chris Jonesaa850cd2020-12-03 11:35:41 +00001188 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001189 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001190 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001191 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001192
1193 /* Set E to 2^(E_bytes - 1) + 1 */
1194 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1195 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001196 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001197
1198 /* Set N to 2^(N_bytes - 1) + 1 */
1199 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1200 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001201 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1202
1203 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001204 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001205
Chris Jonesaa850cd2020-12-03 11:35:41 +00001206 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001207
1208exit:
1209 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1210 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1211}
1212/* END_CASE */
1213
1214/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001215void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1216 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001217{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001219 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001220 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001221
Werner Lewis19b4cd82022-07-07 11:02:27 +01001222 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1223 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1224 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001225 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001226 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001227 if( res == 0 )
1228 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001229 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001231 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001232
Paul Bakkerbd51b262014-07-10 15:26:12 +02001233exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001235}
Paul Bakker33b43f12013-08-20 11:48:36 +02001236/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001238/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001239void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001242 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001244
Werner Lewis19b4cd82022-07-07 11:02:27 +01001245 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001246 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001247 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001248
Paul Bakkerbd51b262014-07-10 15:26:12 +02001249exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001250 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001251}
Paul Bakker33b43f12013-08-20 11:48:36 +02001252/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001253
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001254/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001255void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001256 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001257{
1258 mbedtls_mpi X;
1259 int res;
1260 mbedtls_test_mpi_random rand;
1261
1262 mbedtls_mpi_init( &X );
1263 rand.data = witnesses;
1264 rand.pos = 0;
1265 rand.chunk_len = chunk_len;
1266
1267 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001268 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1269 mbedtls_test_mpi_miller_rabin_determinizer,
1270 &rand );
1271 TEST_ASSERT( res == 0 );
1272
1273 rand.data = witnesses;
1274 rand.pos = 0;
1275 rand.chunk_len = chunk_len;
1276
Janos Follatha0b67c22018-09-18 14:48:23 +01001277 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1278 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001279 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001280 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001281
1282exit:
1283 mbedtls_mpi_free( &X );
1284}
1285/* END_CASE */
1286
1287/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001288void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001289{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001291 int my_ret;
1292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001294
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001295 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1296 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001297 TEST_ASSERT( my_ret == ref_ret );
1298
1299 if( ref_ret == 0 )
1300 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001301 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001302
1303 TEST_ASSERT( actual_bits >= (size_t) bits );
1304 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001305 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001306
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001307 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1308 mbedtls_test_rnd_std_rand,
1309 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001310 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001311 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001312 /* X = ( X - 1 ) / 2 */
1313 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001314 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1315 mbedtls_test_rnd_std_rand,
1316 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001317 }
1318 }
1319
Paul Bakkerbd51b262014-07-10 15:26:12 +02001320exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001322}
1323/* END_CASE */
1324
Paul Bakker33b43f12013-08-20 11:48:36 +02001325/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001326void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1327 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001328{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 mbedtls_mpi X, A;
1330 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001331
Werner Lewis19b4cd82022-07-07 11:02:27 +01001332 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1333 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001334 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001335 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001336 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001337
Paul Bakkerbd51b262014-07-10 15:26:12 +02001338exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001339 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001340}
Paul Bakker33b43f12013-08-20 11:48:36 +02001341/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001342
Paul Bakker33b43f12013-08-20 11:48:36 +02001343/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001344void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1345 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001346{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 mbedtls_mpi X, A;
1348 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001349
Werner Lewis19b4cd82022-07-07 11:02:27 +01001350 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1351 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001352 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001353 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001354 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001355
Paul Bakkerbd51b262014-07-10 15:26:12 +02001356exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001357 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001358}
Paul Bakker33b43f12013-08-20 11:48:36 +02001359/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001360
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001361/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001362void mpi_fill_random( int wanted_bytes, int rng_bytes,
1363 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001364{
1365 mbedtls_mpi X;
1366 int ret;
1367 size_t bytes_left = rng_bytes;
1368 mbedtls_mpi_init( &X );
1369
Gilles Peskine422e8672021-04-02 00:02:27 +02001370 if( before != 0 )
1371 {
1372 /* Set X to sign(before) * 2^(|before|-1) */
1373 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1374 if( before < 0 )
1375 before = - before;
1376 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1377 }
1378
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001379 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1380 f_rng_bytes_left, &bytes_left );
1381 TEST_ASSERT( ret == expected_ret );
1382
1383 if( expected_ret == 0 )
1384 {
1385 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1386 * as a big-endian representation of the number. We know when
1387 * our RNG function returns null bytes, so we know how many
1388 * leading zero bytes the number has. */
1389 size_t leading_zeros = 0;
1390 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1391 leading_zeros = 1;
1392 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1393 (size_t) wanted_bytes );
1394 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001395 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001396 }
1397
1398exit:
1399 mbedtls_mpi_free( &X );
1400}
1401/* END_CASE */
1402
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001403/* BEGIN_CASE */
1404void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1405{
1406 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1407 * This function assumes that the value of bound is at least 2 and
1408 * that iterations is large enough that a one-in-2^iterations chance
1409 * effectively never occurs.
1410 */
1411
1412 mbedtls_mpi upper_bound;
1413 size_t n_bits;
1414 mbedtls_mpi result;
1415 size_t b;
1416 /* If upper_bound is small, stats[b] is the number of times the value b
1417 * has been generated. Otherwise stats[b] is the number of times a
1418 * value with bit b set has been generated. */
1419 size_t *stats = NULL;
1420 size_t stats_len;
1421 int full_stats;
1422 size_t i;
1423
1424 mbedtls_mpi_init( &upper_bound );
1425 mbedtls_mpi_init( &result );
1426
1427 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1428 bound_bytes->x, bound_bytes->len ) );
1429 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1430 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1431 * to be small enough that the probability of missing one value is
1432 * negligible given the number of iterations. It must be less than
1433 * 256 because some of the code below assumes that "small" values
1434 * fit in a byte. */
1435 if( n_bits <= 5 )
1436 {
1437 full_stats = 1;
1438 stats_len = bound_bytes->x[bound_bytes->len - 1];
1439 }
1440 else
1441 {
1442 full_stats = 0;
1443 stats_len = n_bits;
1444 }
1445 ASSERT_ALLOC( stats, stats_len );
1446
1447 for( i = 0; i < (size_t) iterations; i++ )
1448 {
1449 mbedtls_test_set_step( i );
1450 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1451 mbedtls_test_rnd_std_rand, NULL ) );
1452
Gilles Peskinedffc7102021-06-10 15:34:15 +02001453 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001454 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1455 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1456 if( full_stats )
1457 {
1458 uint8_t value;
1459 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1460 TEST_ASSERT( value < stats_len );
1461 ++stats[value];
1462 }
1463 else
1464 {
1465 for( b = 0; b < n_bits; b++ )
1466 stats[b] += mbedtls_mpi_get_bit( &result, b );
1467 }
1468 }
1469
1470 if( full_stats )
1471 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001472 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001473 {
1474 mbedtls_test_set_step( 1000000 + b );
1475 /* Assert that each value has been reached at least once.
1476 * This is almost guaranteed if the iteration count is large
1477 * enough. This is a very crude way of checking the distribution.
1478 */
1479 TEST_ASSERT( stats[b] > 0 );
1480 }
1481 }
1482 else
1483 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001484 int statistically_safe_all_the_way =
1485 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001486 for( b = 0; b < n_bits; b++ )
1487 {
1488 mbedtls_test_set_step( 1000000 + b );
1489 /* Assert that each bit has been set in at least one result and
1490 * clear in at least one result. Provided that iterations is not
1491 * too small, it would be extremely unlikely for this not to be
1492 * the case if the results are uniformly distributed.
1493 *
1494 * As an exception, the top bit may legitimately never be set
1495 * if bound is a power of 2 or only slightly above.
1496 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001497 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001498 {
1499 TEST_ASSERT( stats[b] > 0 );
1500 }
1501 TEST_ASSERT( stats[b] < (size_t) iterations );
1502 }
1503 }
1504
1505exit:
1506 mbedtls_mpi_free( &upper_bound );
1507 mbedtls_mpi_free( &result );
1508 mbedtls_free( stats );
1509}
1510/* END_CASE */
1511
Gilles Peskine1e918f42021-03-29 22:14:51 +02001512/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001513void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001514{
1515 mbedtls_mpi upper_bound;
1516 mbedtls_mpi result;
1517
1518 mbedtls_mpi_init( &upper_bound );
1519 mbedtls_mpi_init( &result );
1520
Gilles Peskine422e8672021-04-02 00:02:27 +02001521 if( before != 0 )
1522 {
1523 /* Set result to sign(before) * 2^(|before|-1) */
1524 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1525 if( before < 0 )
1526 before = - before;
1527 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1528 }
1529
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001530 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1531 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1532 bound_bytes->x, bound_bytes->len ) );
1533 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1534 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001535 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001536 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1537 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1538
1539exit:
1540 mbedtls_mpi_free( &upper_bound );
1541 mbedtls_mpi_free( &result );
1542}
1543/* END_CASE */
1544
1545/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001546void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1547{
1548 mbedtls_mpi upper_bound;
1549 mbedtls_mpi result;
1550 int actual_ret;
1551
1552 mbedtls_mpi_init( &upper_bound );
1553 mbedtls_mpi_init( &result );
1554
1555 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1556 bound_bytes->x, bound_bytes->len ) );
1557 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1558 mbedtls_test_rnd_std_rand, NULL );
1559 TEST_EQUAL( expected_ret, actual_ret );
1560
1561exit:
1562 mbedtls_mpi_free( &upper_bound );
1563 mbedtls_mpi_free( &result );
1564}
1565/* END_CASE */
1566
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001567/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001568void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001569{
Andres AG93012e82016-09-09 09:10:28 +01001570 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001571}
Paul Bakker33b43f12013-08-20 11:48:36 +02001572/* END_CASE */