blob: ff87ea44ac184c9a764e0376e2d0107ec7560094 [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 Follath23bdeca2022-07-22 18:24:06 +01005#include "constant_time_internal.h"
6#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01007
Chris Jonese64a46f2020-12-03 17:44:03 +00008#if MBEDTLS_MPI_MAX_BITS > 792
9#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000010#endif
Janos Follath64eca052018-09-05 17:04:49 +010011
Gilles Peskinedffc7102021-06-10 15:34:15 +020012/* Check the validity of the sign bit in an MPI object. Reject representations
13 * that are not supported by the rest of the library and indicate a bug when
14 * constructing the value. */
15static int sign_is_valid( const mbedtls_mpi *X )
16{
17 if( X->s != 1 && X->s != -1 )
18 return( 0 ); // invalid sign bit, e.g. 0
19 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
20 return( 0 ); // negative zero
21 return( 1 );
22}
23
Janos Follath64eca052018-09-05 17:04:49 +010024typedef struct mbedtls_test_mpi_random
25{
26 data_t *data;
27 size_t pos;
28 size_t chunk_len;
29} mbedtls_test_mpi_random;
30
31/*
32 * This function is called by the Miller-Rabin primality test each time it
33 * chooses a random witness. The witnesses (or non-witnesses as provided by the
34 * test) are stored in the data member of the state structure. Each number is in
35 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
36 */
37int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
38 unsigned char* buf,
39 size_t len )
40{
41 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
42
43 if( random == NULL || random->data->x == NULL || buf == NULL )
44 return( -1 );
45
46 if( random->pos + random->chunk_len > random->data->len
47 || random->chunk_len > len )
48 {
49 return( -1 );
50 }
51
52 memset( buf, 0, len );
53
54 /* The witness is written to the end of the buffer, since the buffer is
55 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
56 * Writing the witness to the start of the buffer would result in the
57 * buffer being 'witness 000...000', which would be treated as
58 * witness * 2^n for some n. */
59 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
60 random->chunk_len );
61
62 random->pos += random->chunk_len;
63
64 return( 0 );
65}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010066
67/* Random generator that is told how many bytes to return. */
68static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
69{
70 size_t *bytes_left = state;
71 size_t i;
72 for( i = 0; i < len; i++ )
73 {
74 if( *bytes_left == 0 )
75 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
76 buf[i] = *bytes_left & 0xff;
77 --( *bytes_left );
78 }
79 return( 0 );
80}
81
Gilles Peskineeedefa52021-04-13 19:50:04 +020082/* Test whether bytes represents (in big-endian base 256) a number b that
83 * is significantly above a power of 2. That is, b must not have a long run
84 * of unset bits after the most significant bit.
85 *
86 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
87 * This function returns 1 if, when drawing a number between 0 and b,
88 * the probability that this number is at least 2^n is not negligible.
89 * This probability is (b - 2^n) / b and this function checks that this
90 * number is above some threshold A. The threshold value is heuristic and
91 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020092 */
93static int is_significantly_above_a_power_of_2( data_t *bytes )
94{
95 const uint8_t *p = bytes->x;
96 size_t len = bytes->len;
97 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020098
99 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200100 while( len > 0 && p[0] == 0 )
101 {
102 ++p;
103 --len;
104 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200105 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200106 if( len == 0 )
107 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200108 /* Extract the (up to) 2 most significant bytes */
109 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200110 x = p[0];
111 else
112 x = ( p[0] << 8 ) | p[1];
113
Gilles Peskineeedefa52021-04-13 19:50:04 +0200114 /* Shift the most significant bit of x to position 8 and mask it out */
115 while( ( x & 0xfe00 ) != 0 )
116 x >>= 1;
117 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200118
Gilles Peskineeedefa52021-04-13 19:50:04 +0200119 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
120 * a power of 2 iff x is significantly above 0 compared to 2^8.
121 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
122 * description above. */
123 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200124}
125
Paul Bakker33b43f12013-08-20 11:48:36 +0200126/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000127
Paul Bakker33b43f12013-08-20 11:48:36 +0200128/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200129 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200130 * END_DEPENDENCIES
131 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000132
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000133/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100134void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200135{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200136 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200137
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200138 mbedtls_mpi_init( &X );
139 mbedtls_mpi_init( &Y );
140 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200141
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200142 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
143 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200144 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200145 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200146
147exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200148 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200149}
150/* END_CASE */
151
152/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100153void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
154 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200155 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000156{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000158 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100159 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000160
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200161 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000162
Janos Follath04dadb72019-03-06 12:29:37 +0000163 memset( str, '!', sizeof( str ) );
164
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200166 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000167 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200168 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100169 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200170 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000171 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200172 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000173 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000174 }
175 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000176
Paul Bakkerbd51b262014-07-10 15:26:12 +0200177exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200178 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000179}
Paul Bakker33b43f12013-08-20 11:48:36 +0200180/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000181
Paul Bakker33b43f12013-08-20 11:48:36 +0200182/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100183void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000184{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200185 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000186 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100187 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000188
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000190
Paul Bakkere896fea2009-07-06 06:40:23 +0000191
Azim Khand30ca132017-06-09 04:32:58 +0100192 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200193 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100194 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100195 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000196
Paul Bakkerbd51b262014-07-10 15:26:12 +0200197exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200198 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000199}
Paul Bakker33b43f12013-08-20 11:48:36 +0200200/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000201
Paul Bakker33b43f12013-08-20 11:48:36 +0200202/* BEGIN_CASE */
Janos Follath91dc67d2022-07-22 14:24:58 +0100203void mbedtls_mpi_core_io_null()
204{
205 mbedtls_mpi_uint X = 0;
206 int ret;
207
208 ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
209 TEST_ASSERT( ret == 0 );
210 ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
211 TEST_ASSERT( ret == 0 );
212
213 ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
214 TEST_ASSERT( ret == 0 );
215 ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
216 TEST_ASSERT( ret == 0 );
217
218 ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
219 TEST_ASSERT( ret == 0 );
220 ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
221 TEST_ASSERT( ret == 0 );
222
223 ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
224 TEST_ASSERT( ret == 0 );
225 ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
226 TEST_ASSERT( ret == 0 );
227
228exit:
229 ;
230}
231/* END_CASE */
232
233/* BEGIN_CASE */
Janos Follathf1d617d2022-07-21 09:29:32 +0100234void mbedtls_mpi_core_io_be( data_t *input, int nb_int, int nx_64_int, int iret,
235 int oret )
236{
237 #define BMAX 1024
238 unsigned char buf[BMAX];
239 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
240 mbedtls_mpi_uint X[XMAX];
241 size_t nx, nb;
242 int ret;
243
244 if( iret != 0 )
245 TEST_ASSERT( oret == 0 );
246
247 TEST_ASSERT( 0 <= nb_int );
248 nb = nb_int;
249 TEST_ASSERT( nb <= BMAX );
250
251 TEST_ASSERT( 0 <= nx_64_int );
252 nx = nx_64_int;
253 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
254 * to double the number of limbs to have the same size. */
255 if( sizeof( mbedtls_mpi_uint ) == 4 )
256 nx *= 2;
257 TEST_ASSERT( nx <= XMAX );
258
259 ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
260 TEST_ASSERT( ret == iret );
261
262 if( iret == 0 )
263 {
264 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
265 TEST_ASSERT( ret == oret );
266 }
267
268 if( ( iret == 0 ) && ( oret == 0 ) )
269 {
270 if( nb > input->len )
271 {
272 size_t leading_zeroes = nb - input->len;
273 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
274 for( size_t i = 0; i < leading_zeroes; i++ )
275 TEST_ASSERT( buf[i] == 0 );
276 }
277 else
278 {
279 size_t leading_zeroes = input->len - nb;
280 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
281 for( size_t i = 0; i < leading_zeroes; i++ )
282 TEST_ASSERT( input->x[i] == 0 );
283 }
284 }
285
286exit:
287 ;
288
289 #undef BMAX
290 #undef XMAX
291}
292/* END_CASE */
293
294/* BEGIN_CASE */
Janos Follath6ff35362022-07-21 15:27:21 +0100295void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_64_int, int iret,
296 int oret )
297{
298 #define BMAX 1024
299 unsigned char buf[BMAX];
300 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
301 mbedtls_mpi_uint X[XMAX];
302 size_t nx, nb;
303 int ret;
304
305 if( iret != 0 )
306 TEST_ASSERT( oret == 0 );
307
308 TEST_ASSERT( 0 <= nb_int );
309 nb = nb_int;
310 TEST_ASSERT( nb <= BMAX );
311
312 TEST_ASSERT( 0 <= nx_64_int );
313 nx = nx_64_int;
314 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
315 * to double the number of limbs to have the same size. */
316 if( sizeof( mbedtls_mpi_uint ) == 4 )
317 nx *= 2;
318 TEST_ASSERT( nx <= XMAX );
319
320 ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
321 TEST_ASSERT( ret == iret );
322
323 if( iret == 0 )
324 {
325 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
326 TEST_ASSERT( ret == oret );
327 }
328
329 if( ( iret == 0 ) && ( oret == 0 ) )
330 {
331 if( nb > input->len )
332 {
333 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
334 for( size_t i = input->len; i < nb; i++ )
335 TEST_ASSERT( buf[i] == 0 );
336 }
337 else
338 {
339 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
340 for( size_t i = nb; i < input->len; i++ )
341 TEST_ASSERT( input->x[i] == 0 );
342 }
343 }
344
345exit:
346 ;
347
348 #undef BMAX
349 #undef XMAX
350}
351/* END_CASE */
352
353/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100354void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000355{
356 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000357 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000358 size_t len;
359
360 mbedtls_mpi_init( &X );
361
362
363 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200364 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100365 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100366 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000367
368exit:
369 mbedtls_mpi_free( &X );
370}
371/* END_CASE */
372
373/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100374void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
375 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000376{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000378 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000379 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000380
381 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000384
Werner Lewis19b4cd82022-07-07 11:02:27 +0100385 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100386
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200388 if( buflen > (size_t) output_size )
389 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200392 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000393 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000394
Ronald Cron2dbba992020-06-10 11:42:32 +0200395 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
396 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000397 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000398
Paul Bakkerbd51b262014-07-10 15:26:12 +0200399exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000401}
Paul Bakker33b43f12013-08-20 11:48:36 +0200402/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000403
Janos Follathe344d0f2019-02-19 16:17:40 +0000404/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100405void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
406 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000407{
408 mbedtls_mpi X;
409 unsigned char buf[1000];
410 size_t buflen;
411
412 memset( buf, 0x00, 1000 );
413
414 mbedtls_mpi_init( &X );
415
Werner Lewis19b4cd82022-07-07 11:02:27 +0100416 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000417
418 buflen = mbedtls_mpi_size( &X );
419 if( buflen > (size_t) output_size )
420 buflen = (size_t) output_size;
421
422 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
423 if( result == 0)
424 {
425
Ronald Cron2dbba992020-06-10 11:42:32 +0200426 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
427 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000428 }
429
430exit:
431 mbedtls_mpi_free( &X );
432}
433/* END_CASE */
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100436void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000437{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000439 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000440 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000441 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000442 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000443
444 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000445
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000447
Paul Bakker33b43f12013-08-20 11:48:36 +0200448 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200449 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100450 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000451 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000452 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000453
Paul Bakker33b43f12013-08-20 11:48:36 +0200454 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000455 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200456 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 buflen = mbedtls_mpi_size( &X );
458 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000459
Paul Bakkere896fea2009-07-06 06:40:23 +0000460
Ronald Cron2dbba992020-06-10 11:42:32 +0200461 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
462 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000463 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000464
Paul Bakkerbd51b262014-07-10 15:26:12 +0200465exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000467}
Paul Bakker33b43f12013-08-20 11:48:36 +0200468/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100471void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000472{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000474 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200475 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000478
Werner Lewis19b4cd82022-07-07 11:02:27 +0100479 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000480
Paul Bakker33b43f12013-08-20 11:48:36 +0200481 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000482 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100483 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000484 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200485 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000486
Paul Bakker33b43f12013-08-20 11:48:36 +0200487 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000488 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100489 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000490 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200491 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000492
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200493 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000494
Paul Bakkerbd51b262014-07-10 15:26:12 +0200495exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000497}
Paul Bakker33b43f12013-08-20 11:48:36 +0200498/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000499
Paul Bakker33b43f12013-08-20 11:48:36 +0200500/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100501void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000502{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 mbedtls_mpi X;
504 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100505 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000507
Paul Bakkerbd51b262014-07-10 15:26:12 +0200508exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000510}
Paul Bakker33b43f12013-08-20 11:48:36 +0200511/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000512
Paul Bakker33b43f12013-08-20 11:48:36 +0200513/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100514void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
515 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000516{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 mbedtls_mpi X, Y;
518 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000519
Werner Lewis19b4cd82022-07-07 11:02:27 +0100520 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
521 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100522 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
523
524 if( result == 0 )
525 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200526 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100527 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
528 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000529
Paul Bakkerbd51b262014-07-10 15:26:12 +0200530exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000532}
Paul Bakker33b43f12013-08-20 11:48:36 +0200533/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000534
Paul Bakker33b43f12013-08-20 11:48:36 +0200535/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100536void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000537{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200538 mbedtls_mpi X;
539 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000540
Werner Lewis19b4cd82022-07-07 11:02:27 +0100541 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000543
Paul Bakkerbd51b262014-07-10 15:26:12 +0200544exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000546}
Paul Bakker33b43f12013-08-20 11:48:36 +0200547/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000548
Paul Bakker33b43f12013-08-20 11:48:36 +0200549/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100550void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000551{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 mbedtls_mpi X;
553 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000554
Werner Lewis19b4cd82022-07-07 11:02:27 +0100555 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200556 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000557
Paul Bakkerbd51b262014-07-10 15:26:12 +0200558exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000560}
Paul Bakker33b43f12013-08-20 11:48:36 +0200561/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000562
Paul Bakker33b43f12013-08-20 11:48:36 +0200563/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100564void mbedtls_mpi_gcd( char * input_X, char * input_Y,
565 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000566{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_mpi A, X, Y, Z;
568 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000569
Werner Lewis19b4cd82022-07-07 11:02:27 +0100570 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
571 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
572 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200573 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200574 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000576
Paul Bakkerbd51b262014-07-10 15:26:12 +0200577exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000579}
Paul Bakker33b43f12013-08-20 11:48:36 +0200580/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000581
Paul Bakker33b43f12013-08-20 11:48:36 +0200582/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000584{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_mpi X;
586 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
589 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000590
Paul Bakkerbd51b262014-07-10 15:26:12 +0200591exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200592 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000593}
Paul Bakker33b43f12013-08-20 11:48:36 +0200594/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000595
Paul Bakker33b43f12013-08-20 11:48:36 +0200596/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100597void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
598 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000599{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_mpi X, Y;
601 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000602
Werner Lewis19b4cd82022-07-07 11:02:27 +0100603 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
604 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000606
Paul Bakkerbd51b262014-07-10 15:26:12 +0200607exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000609}
Paul Bakker33b43f12013-08-20 11:48:36 +0200610/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000611
Paul Bakker33b43f12013-08-20 11:48:36 +0200612/* BEGIN_CASE */
Janos Follath23bdeca2022-07-22 18:24:06 +0100613void mbedtls_mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
614{
615 #define MAX_LEN 64
616 mbedtls_mpi_uint X[MAX_LEN];
617 mbedtls_mpi_uint Y[MAX_LEN];
618 unsigned exp_ret = input_ret;
619 unsigned ret;
620 size_t len = CHARS_TO_LIMBS(
621 input_X->len > input_Y->len ? input_X->len : input_Y->len );
622
623 TEST_ASSERT( len <= MAX_LEN );
624
625 TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
626 == 0 );
627 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
628 == 0 );
629
630 TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
631 TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
632
633 ret = mbedtls_mpi_core_lt_ct( X, Y, len );
634
635 TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
636 TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
637 TEST_CF_PUBLIC( &ret, sizeof( ret ) );
638
639 TEST_ASSERT( ret == exp_ret );
640
641exit:
642 ;
643
644 #undef MAX_LEN
645}
646/* END_CASE */
647
648/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100649void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
650 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100651 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100652{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200653 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100654 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100655 mbedtls_mpi X, Y;
656 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
657
Werner Lewis19b4cd82022-07-07 11:02:27 +0100658 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
659 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100660
Gilles Peskine9018b112020-01-21 16:30:53 +0100661 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
662 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100663
Janos Follath0e5532d2019-10-11 14:21:53 +0100664 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100665 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100666 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100667
668exit:
669 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
670}
671/* END_CASE */
672
673/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100674void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
675 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000676{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200677 mbedtls_mpi X, Y;
678 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000679
Werner Lewis19b4cd82022-07-07 11:02:27 +0100680 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
681 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000683
Paul Bakkerbd51b262014-07-10 15:26:12 +0200684exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000686}
Paul Bakker33b43f12013-08-20 11:48:36 +0200687/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000688
Paul Bakker33b43f12013-08-20 11:48:36 +0200689/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200690void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000691{
Gilles Peskined0722f82021-06-10 23:00:33 +0200692 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200693 mbedtls_mpi_init( &src );
694 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200695 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000696
Werner Lewis19b4cd82022-07-07 11:02:27 +0100697 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
698 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200699
700 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100701 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200702 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200703 TEST_ASSERT( sign_is_valid( &dst ) );
704 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000705
Gilles Peskined0722f82021-06-10 23:00:33 +0200706 /* mbedtls_mpi_safe_cond_assign(), assignment done */
707 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100708 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200709 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
710 TEST_ASSERT( sign_is_valid( &dst ) );
711 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
712
713 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
714 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100715 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200716 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
717 TEST_ASSERT( sign_is_valid( &dst ) );
718 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
719
Paul Bakkerbd51b262014-07-10 15:26:12 +0200720exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200721 mbedtls_mpi_free( &src );
722 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200723 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100724}
725/* END_CASE */
726
727/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200728void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100729{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200730 mbedtls_mpi X, A;
731 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000733
Werner Lewis19b4cd82022-07-07 11:02:27 +0100734 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200735 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200736
Werner Lewis19b4cd82022-07-07 11:02:27 +0100737 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200738 TEST_ASSERT( sign_is_valid( &X ) );
739 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000740
Paul Bakkerbd51b262014-07-10 15:26:12 +0200741exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200742 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000744}
Paul Bakker33b43f12013-08-20 11:48:36 +0200745/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000746
Paul Bakker33b43f12013-08-20 11:48:36 +0200747/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200748void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
749{
750 mbedtls_mpi X, Y, X0, Y0;
751 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
752 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
753
Werner Lewis19b4cd82022-07-07 11:02:27 +0100754 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
755 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200756
Gilles Peskined0722f82021-06-10 23:00:33 +0200757 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100758 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
759 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200760 mbedtls_mpi_swap( &X, &Y );
761 TEST_ASSERT( sign_is_valid( &X ) );
762 TEST_ASSERT( sign_is_valid( &Y ) );
763 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
764 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
765
Gilles Peskined0722f82021-06-10 23:00:33 +0200766 /* mbedtls_mpi_safe_cond_swap(), swap done */
767 mbedtls_mpi_free( &X );
768 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100769 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
770 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200771 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
772 TEST_ASSERT( sign_is_valid( &X ) );
773 TEST_ASSERT( sign_is_valid( &Y ) );
774 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
775 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
776
777 /* mbedtls_mpi_safe_cond_swap(), swap not done */
778 mbedtls_mpi_free( &X );
779 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100780 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
781 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200782 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
783 TEST_ASSERT( sign_is_valid( &X ) );
784 TEST_ASSERT( sign_is_valid( &Y ) );
785 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
786 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
787
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200788exit:
789 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
790 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
791}
792/* END_CASE */
793
794/* BEGIN_CASE */
795void mpi_swap_self( char *X_hex )
796{
797 mbedtls_mpi X, X0;
798 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
799
Werner Lewis19b4cd82022-07-07 11:02:27 +0100800 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
801 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200802
803 mbedtls_mpi_swap( &X, &X );
804 TEST_ASSERT( sign_is_valid( &X ) );
805 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
806
807exit:
808 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
809}
810/* END_CASE */
811
812/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100814{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200815 mbedtls_mpi X;
816 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100817
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200819 if( used > 0 )
820 {
821 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
822 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
823 }
824 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200826 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100827
Paul Bakkerbd51b262014-07-10 15:26:12 +0200828exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100830}
831/* END_CASE */
832
833/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100834void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
835 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000836{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 mbedtls_mpi X, Y, Z, A;
838 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000839
Werner Lewis19b4cd82022-07-07 11:02:27 +0100840 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
841 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
842 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200844 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200845 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000846
Gilles Peskine56f943a2020-07-23 01:18:11 +0200847 /* result == first operand */
848 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200849 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200850 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100851 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200852
853 /* result == second operand */
854 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200855 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200856 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
857
Paul Bakkerbd51b262014-07-10 15:26:12 +0200858exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000860}
Paul Bakker33b43f12013-08-20 11:48:36 +0200861/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000862
Paul Bakker33b43f12013-08-20 11:48:36 +0200863/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100864void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100865{
866 mbedtls_mpi X, A;
867 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
868
Werner Lewis19b4cd82022-07-07 11:02:27 +0100869 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100870
Werner Lewis19b4cd82022-07-07 11:02:27 +0100871 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100872 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
873 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200874 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100875
Werner Lewis19b4cd82022-07-07 11:02:27 +0100876 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100877 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200878 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100879 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
880
Werner Lewis19b4cd82022-07-07 11:02:27 +0100881 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100882 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200883 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100884 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
885
886exit:
887 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
888}
889/* END_CASE */
890
891
892/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100893void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
894 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000895{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 mbedtls_mpi X, Y, Z, A;
897 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000898
Werner Lewis19b4cd82022-07-07 11:02:27 +0100899 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
900 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
901 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200902 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200903 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000905
Gilles Peskine56f943a2020-07-23 01:18:11 +0200906 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200907 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200908 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100910 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200911
912 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200914 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000916
Paul Bakkerbd51b262014-07-10 15:26:12 +0200917exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200918 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000919}
Paul Bakker33b43f12013-08-20 11:48:36 +0200920/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000921
Paul Bakker33b43f12013-08-20 11:48:36 +0200922/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100923void mbedtls_mpi_add_int( char * input_X, int input_Y,
924 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000925{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 mbedtls_mpi X, Z, A;
927 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000928
Werner Lewis19b4cd82022-07-07 11:02:27 +0100929 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
930 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200932 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000934
Paul Bakkerbd51b262014-07-10 15:26:12 +0200935exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000937}
Paul Bakker33b43f12013-08-20 11:48:36 +0200938/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000939
Paul Bakker33b43f12013-08-20 11:48:36 +0200940/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100941void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
942 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000943{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_mpi X, Y, Z, A;
945 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000946
Werner Lewis19b4cd82022-07-07 11:02:27 +0100947 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
948 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
949 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200950 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200951 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000953
Gilles Peskine56f943a2020-07-23 01:18:11 +0200954 /* result == first operand */
955 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200956 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200957 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100958 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200959
960 /* result == second operand */
961 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200962 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200963 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
964
Paul Bakkerbd51b262014-07-10 15:26:12 +0200965exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000967}
Paul Bakker33b43f12013-08-20 11:48:36 +0200968/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000969
Paul Bakker33b43f12013-08-20 11:48:36 +0200970/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100971void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
972 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000973{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000975 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000977
Werner Lewis19b4cd82022-07-07 11:02:27 +0100978 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
979 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
980 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200982 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200983 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200984 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000985 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000987
Gilles Peskine56f943a2020-07-23 01:18:11 +0200988 /* result == first operand */
989 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200990 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200991 if( sub_result == 0 )
992 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100993 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200994
995 /* result == second operand */
996 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200997 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200998 if( sub_result == 0 )
999 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1000
Paul Bakkerbd51b262014-07-10 15:26:12 +02001001exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001003}
Paul Bakker33b43f12013-08-20 11:48:36 +02001004/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001005
Paul Bakker33b43f12013-08-20 11:48:36 +02001006/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001007void mbedtls_mpi_sub_int( char * input_X, int input_Y,
1008 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001009{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_mpi X, Z, A;
1011 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001012
Werner Lewis19b4cd82022-07-07 11:02:27 +01001013 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1014 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001015 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001016 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001018
Paul Bakkerbd51b262014-07-10 15:26:12 +02001019exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001021}
Paul Bakker33b43f12013-08-20 11:48:36 +02001022/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001023
Paul Bakker33b43f12013-08-20 11:48:36 +02001024/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001025void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
1026 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001027{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001028 mbedtls_mpi X, Y, Z, A;
1029 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001030
Werner Lewis19b4cd82022-07-07 11:02:27 +01001031 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1032 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1033 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001035 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001037
Paul Bakkerbd51b262014-07-10 15:26:12 +02001038exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001039 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001040}
Paul Bakker33b43f12013-08-20 11:48:36 +02001041/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001042
Paul Bakker33b43f12013-08-20 11:48:36 +02001043/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001044void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001045 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001046{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 mbedtls_mpi X, Z, A;
1048 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001049
Werner Lewis19b4cd82022-07-07 11:02:27 +01001050 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1051 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001053 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001054 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001055 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001056 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001058 else
1059 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001060
Paul Bakkerbd51b262014-07-10 15:26:12 +02001061exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001063}
Paul Bakker33b43f12013-08-20 11:48:36 +02001064/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001065
Paul Bakker33b43f12013-08-20 11:48:36 +02001066/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001067void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1068 char * input_A, char * input_B,
1069 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001070{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001072 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1074 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001075
Werner Lewis19b4cd82022-07-07 11:02:27 +01001076 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1077 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1078 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1079 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001081 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001082 if( res == 0 )
1083 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001084 TEST_ASSERT( sign_is_valid( &Q ) );
1085 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1087 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001088 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001089
Paul Bakkerbd51b262014-07-10 15:26:12 +02001090exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1092 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001093}
Paul Bakker33b43f12013-08-20 11:48:36 +02001094/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001095
Paul Bakker33b43f12013-08-20 11:48:36 +02001096/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001097void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001098 char * input_A, char * input_B,
1099 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001100{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001102 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1104 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001105
Werner Lewis19b4cd82022-07-07 11:02:27 +01001106 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1107 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1108 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001109 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001110 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001111 if( res == 0 )
1112 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001113 TEST_ASSERT( sign_is_valid( &Q ) );
1114 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1116 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001117 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001118
Paul Bakkerbd51b262014-07-10 15:26:12 +02001119exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1121 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001122}
Paul Bakker33b43f12013-08-20 11:48:36 +02001123/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001124
Paul Bakker33b43f12013-08-20 11:48:36 +02001125/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001126void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1127 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001128{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001130 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001131 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001132
Werner Lewis19b4cd82022-07-07 11:02:27 +01001133 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1134 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1135 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001137 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001138 if( res == 0 )
1139 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001140 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001142 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001143
Paul Bakkerbd51b262014-07-10 15:26:12 +02001144exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001146}
Paul Bakker33b43f12013-08-20 11:48:36 +02001147/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001148
Paul Bakker33b43f12013-08-20 11:48:36 +02001149/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001150void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001151 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001152{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001154 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001155 mbedtls_mpi_uint r;
1156 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001157
Werner Lewis19b4cd82022-07-07 11:02:27 +01001158 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001160 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001161 if( res == 0 )
1162 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001163 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001164 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001165
Paul Bakkerbd51b262014-07-10 15:26:12 +02001166exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001168}
Paul Bakker33b43f12013-08-20 11:48:36 +02001169/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001170
Paul Bakker33b43f12013-08-20 11:48:36 +02001171/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001172void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1173 char * input_N, char * input_X,
1174 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001175{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001177 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1179 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001180
Werner Lewis19b4cd82022-07-07 11:02:27 +01001181 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1182 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1183 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1184 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001185
Gilles Peskine342f71b2021-06-09 18:31:35 +02001186 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001187 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001188 if( res == 0 )
1189 {
1190 TEST_ASSERT( sign_is_valid( &Z ) );
1191 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1192 }
1193
1194 /* Now test again with the speed-up parameter supplied as an output. */
1195 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001196 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001197 if( res == 0 )
1198 {
1199 TEST_ASSERT( sign_is_valid( &Z ) );
1200 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1201 }
1202
1203 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001205 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001206 if( res == 0 )
1207 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001208 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001210 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001211
Paul Bakkerbd51b262014-07-10 15:26:12 +02001212exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1214 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001215}
Paul Bakker33b43f12013-08-20 11:48:36 +02001216/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001217
Paul Bakker33b43f12013-08-20 11:48:36 +02001218/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001219void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001220 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001221{
1222 mbedtls_mpi A, E, N, RR, Z;
1223 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1224 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1225
Chris Jonesaa850cd2020-12-03 11:35:41 +00001226 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001227 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001228 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001229 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001230
1231 /* Set E to 2^(E_bytes - 1) + 1 */
1232 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1233 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001234 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001235
1236 /* Set N to 2^(N_bytes - 1) + 1 */
1237 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1238 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001239 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1240
1241 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001242 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001243
Chris Jonesaa850cd2020-12-03 11:35:41 +00001244 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001245
1246exit:
1247 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1248 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1249}
1250/* END_CASE */
1251
1252/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001253void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1254 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001255{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001257 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001258 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001259
Werner Lewis19b4cd82022-07-07 11:02:27 +01001260 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1261 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1262 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001264 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001265 if( res == 0 )
1266 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001267 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001268 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001269 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001270
Paul Bakkerbd51b262014-07-10 15:26:12 +02001271exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001273}
Paul Bakker33b43f12013-08-20 11:48:36 +02001274/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001275
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001276/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001277void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001278{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001279 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001280 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001281 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001282
Werner Lewis19b4cd82022-07-07 11:02:27 +01001283 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001284 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001285 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001286
Paul Bakkerbd51b262014-07-10 15:26:12 +02001287exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001289}
Paul Bakker33b43f12013-08-20 11:48:36 +02001290/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001293void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001294 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001295{
1296 mbedtls_mpi X;
1297 int res;
1298 mbedtls_test_mpi_random rand;
1299
1300 mbedtls_mpi_init( &X );
1301 rand.data = witnesses;
1302 rand.pos = 0;
1303 rand.chunk_len = chunk_len;
1304
1305 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001306 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1307 mbedtls_test_mpi_miller_rabin_determinizer,
1308 &rand );
1309 TEST_ASSERT( res == 0 );
1310
1311 rand.data = witnesses;
1312 rand.pos = 0;
1313 rand.chunk_len = chunk_len;
1314
Janos Follatha0b67c22018-09-18 14:48:23 +01001315 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1316 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001317 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001318 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001319
1320exit:
1321 mbedtls_mpi_free( &X );
1322}
1323/* END_CASE */
1324
1325/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001326void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001327{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001328 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001329 int my_ret;
1330
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001331 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001332
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001333 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1334 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001335 TEST_ASSERT( my_ret == ref_ret );
1336
1337 if( ref_ret == 0 )
1338 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001339 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001340
1341 TEST_ASSERT( actual_bits >= (size_t) bits );
1342 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001343 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001344
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001345 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1346 mbedtls_test_rnd_std_rand,
1347 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001348 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001349 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001350 /* X = ( X - 1 ) / 2 */
1351 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001352 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1353 mbedtls_test_rnd_std_rand,
1354 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001355 }
1356 }
1357
Paul Bakkerbd51b262014-07-10 15:26:12 +02001358exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001360}
1361/* END_CASE */
1362
Paul Bakker33b43f12013-08-20 11:48:36 +02001363/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001364void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1365 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001366{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001367 mbedtls_mpi X, A;
1368 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001369
Werner Lewis19b4cd82022-07-07 11:02:27 +01001370 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1371 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001372 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001373 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001374 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001375
Paul Bakkerbd51b262014-07-10 15:26:12 +02001376exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001378}
Paul Bakker33b43f12013-08-20 11:48:36 +02001379/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001380
Paul Bakker33b43f12013-08-20 11:48:36 +02001381/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001382void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1383 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001384{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001385 mbedtls_mpi X, A;
1386 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001387
Werner Lewis19b4cd82022-07-07 11:02:27 +01001388 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1389 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001391 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001393
Paul Bakkerbd51b262014-07-10 15:26:12 +02001394exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001395 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001396}
Paul Bakker33b43f12013-08-20 11:48:36 +02001397/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001398
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001399/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001400void mpi_fill_random( int wanted_bytes, int rng_bytes,
1401 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001402{
1403 mbedtls_mpi X;
1404 int ret;
1405 size_t bytes_left = rng_bytes;
1406 mbedtls_mpi_init( &X );
1407
Gilles Peskine422e8672021-04-02 00:02:27 +02001408 if( before != 0 )
1409 {
1410 /* Set X to sign(before) * 2^(|before|-1) */
1411 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1412 if( before < 0 )
1413 before = - before;
1414 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1415 }
1416
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001417 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1418 f_rng_bytes_left, &bytes_left );
1419 TEST_ASSERT( ret == expected_ret );
1420
1421 if( expected_ret == 0 )
1422 {
1423 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1424 * as a big-endian representation of the number. We know when
1425 * our RNG function returns null bytes, so we know how many
1426 * leading zero bytes the number has. */
1427 size_t leading_zeros = 0;
1428 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1429 leading_zeros = 1;
1430 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1431 (size_t) wanted_bytes );
1432 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001433 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001434 }
1435
1436exit:
1437 mbedtls_mpi_free( &X );
1438}
1439/* END_CASE */
1440
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001441/* BEGIN_CASE */
1442void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1443{
1444 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1445 * This function assumes that the value of bound is at least 2 and
1446 * that iterations is large enough that a one-in-2^iterations chance
1447 * effectively never occurs.
1448 */
1449
1450 mbedtls_mpi upper_bound;
1451 size_t n_bits;
1452 mbedtls_mpi result;
1453 size_t b;
1454 /* If upper_bound is small, stats[b] is the number of times the value b
1455 * has been generated. Otherwise stats[b] is the number of times a
1456 * value with bit b set has been generated. */
1457 size_t *stats = NULL;
1458 size_t stats_len;
1459 int full_stats;
1460 size_t i;
1461
1462 mbedtls_mpi_init( &upper_bound );
1463 mbedtls_mpi_init( &result );
1464
1465 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1466 bound_bytes->x, bound_bytes->len ) );
1467 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1468 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1469 * to be small enough that the probability of missing one value is
1470 * negligible given the number of iterations. It must be less than
1471 * 256 because some of the code below assumes that "small" values
1472 * fit in a byte. */
1473 if( n_bits <= 5 )
1474 {
1475 full_stats = 1;
1476 stats_len = bound_bytes->x[bound_bytes->len - 1];
1477 }
1478 else
1479 {
1480 full_stats = 0;
1481 stats_len = n_bits;
1482 }
1483 ASSERT_ALLOC( stats, stats_len );
1484
1485 for( i = 0; i < (size_t) iterations; i++ )
1486 {
1487 mbedtls_test_set_step( i );
1488 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1489 mbedtls_test_rnd_std_rand, NULL ) );
1490
Gilles Peskinedffc7102021-06-10 15:34:15 +02001491 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001492 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1493 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1494 if( full_stats )
1495 {
1496 uint8_t value;
1497 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1498 TEST_ASSERT( value < stats_len );
1499 ++stats[value];
1500 }
1501 else
1502 {
1503 for( b = 0; b < n_bits; b++ )
1504 stats[b] += mbedtls_mpi_get_bit( &result, b );
1505 }
1506 }
1507
1508 if( full_stats )
1509 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001510 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001511 {
1512 mbedtls_test_set_step( 1000000 + b );
1513 /* Assert that each value has been reached at least once.
1514 * This is almost guaranteed if the iteration count is large
1515 * enough. This is a very crude way of checking the distribution.
1516 */
1517 TEST_ASSERT( stats[b] > 0 );
1518 }
1519 }
1520 else
1521 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001522 int statistically_safe_all_the_way =
1523 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001524 for( b = 0; b < n_bits; b++ )
1525 {
1526 mbedtls_test_set_step( 1000000 + b );
1527 /* Assert that each bit has been set in at least one result and
1528 * clear in at least one result. Provided that iterations is not
1529 * too small, it would be extremely unlikely for this not to be
1530 * the case if the results are uniformly distributed.
1531 *
1532 * As an exception, the top bit may legitimately never be set
1533 * if bound is a power of 2 or only slightly above.
1534 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001535 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001536 {
1537 TEST_ASSERT( stats[b] > 0 );
1538 }
1539 TEST_ASSERT( stats[b] < (size_t) iterations );
1540 }
1541 }
1542
1543exit:
1544 mbedtls_mpi_free( &upper_bound );
1545 mbedtls_mpi_free( &result );
1546 mbedtls_free( stats );
1547}
1548/* END_CASE */
1549
Gilles Peskine1e918f42021-03-29 22:14:51 +02001550/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001551void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001552{
1553 mbedtls_mpi upper_bound;
1554 mbedtls_mpi result;
1555
1556 mbedtls_mpi_init( &upper_bound );
1557 mbedtls_mpi_init( &result );
1558
Gilles Peskine422e8672021-04-02 00:02:27 +02001559 if( before != 0 )
1560 {
1561 /* Set result to sign(before) * 2^(|before|-1) */
1562 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1563 if( before < 0 )
1564 before = - before;
1565 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1566 }
1567
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001568 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1569 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1570 bound_bytes->x, bound_bytes->len ) );
1571 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1572 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001573 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001574 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1575 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1576
1577exit:
1578 mbedtls_mpi_free( &upper_bound );
1579 mbedtls_mpi_free( &result );
1580}
1581/* END_CASE */
1582
1583/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001584void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1585{
1586 mbedtls_mpi upper_bound;
1587 mbedtls_mpi result;
1588 int actual_ret;
1589
1590 mbedtls_mpi_init( &upper_bound );
1591 mbedtls_mpi_init( &result );
1592
1593 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1594 bound_bytes->x, bound_bytes->len ) );
1595 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1596 mbedtls_test_rnd_std_rand, NULL );
1597 TEST_EQUAL( expected_ret, actual_ret );
1598
1599exit:
1600 mbedtls_mpi_free( &upper_bound );
1601 mbedtls_mpi_free( &result );
1602}
1603/* END_CASE */
1604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001605/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001606void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001607{
Andres AG93012e82016-09-09 09:10:28 +01001608 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001609}
Paul Bakker33b43f12013-08-20 11:48:36 +02001610/* END_CASE */