blob: 76affd6add9a5a45fd27a5d0945b3dbe14b68418 [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/bignum.h"
Gilles Peskine3cb1e292020-11-25 15:37:20 +01003#include "mbedtls/entropy.h"
Janos Follath64eca052018-09-05 17:04:49 +01004
Chris Jonese64a46f2020-12-03 17:44:03 +00005#if MBEDTLS_MPI_MAX_BITS > 792
6#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +00007#endif
Janos Follath64eca052018-09-05 17:04:49 +01008
Gilles Peskinedffc7102021-06-10 15:34:15 +02009/* Check the validity of the sign bit in an MPI object. Reject representations
10 * that are not supported by the rest of the library and indicate a bug when
11 * constructing the value. */
12static int sign_is_valid( const mbedtls_mpi *X )
13{
14 if( X->s != 1 && X->s != -1 )
15 return( 0 ); // invalid sign bit, e.g. 0
16 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
17 return( 0 ); // negative zero
18 return( 1 );
19}
20
Janos Follath64eca052018-09-05 17:04:49 +010021typedef struct mbedtls_test_mpi_random
22{
23 data_t *data;
24 size_t pos;
25 size_t chunk_len;
26} mbedtls_test_mpi_random;
27
28/*
29 * This function is called by the Miller-Rabin primality test each time it
30 * chooses a random witness. The witnesses (or non-witnesses as provided by the
31 * test) are stored in the data member of the state structure. Each number is in
32 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
33 */
34int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
35 unsigned char* buf,
36 size_t len )
37{
38 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
39
40 if( random == NULL || random->data->x == NULL || buf == NULL )
41 return( -1 );
42
43 if( random->pos + random->chunk_len > random->data->len
44 || random->chunk_len > len )
45 {
46 return( -1 );
47 }
48
49 memset( buf, 0, len );
50
51 /* The witness is written to the end of the buffer, since the buffer is
52 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
53 * Writing the witness to the start of the buffer would result in the
54 * buffer being 'witness 000...000', which would be treated as
55 * witness * 2^n for some n. */
56 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
57 random->chunk_len );
58
59 random->pos += random->chunk_len;
60
61 return( 0 );
62}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010063
64/* Random generator that is told how many bytes to return. */
65static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
66{
67 size_t *bytes_left = state;
68 size_t i;
69 for( i = 0; i < len; i++ )
70 {
71 if( *bytes_left == 0 )
72 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
73 buf[i] = *bytes_left & 0xff;
74 --( *bytes_left );
75 }
76 return( 0 );
77}
78
Gilles Peskineeedefa52021-04-13 19:50:04 +020079/* Test whether bytes represents (in big-endian base 256) a number b that
80 * is significantly above a power of 2. That is, b must not have a long run
81 * of unset bits after the most significant bit.
82 *
83 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
84 * This function returns 1 if, when drawing a number between 0 and b,
85 * the probability that this number is at least 2^n is not negligible.
86 * This probability is (b - 2^n) / b and this function checks that this
87 * number is above some threshold A. The threshold value is heuristic and
88 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020089 */
90static int is_significantly_above_a_power_of_2( data_t *bytes )
91{
92 const uint8_t *p = bytes->x;
93 size_t len = bytes->len;
94 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020095
96 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +020097 while( len > 0 && p[0] == 0 )
98 {
99 ++p;
100 --len;
101 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200102 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200103 if( len == 0 )
104 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200105 /* Extract the (up to) 2 most significant bytes */
106 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200107 x = p[0];
108 else
109 x = ( p[0] << 8 ) | p[1];
110
Gilles Peskineeedefa52021-04-13 19:50:04 +0200111 /* Shift the most significant bit of x to position 8 and mask it out */
112 while( ( x & 0xfe00 ) != 0 )
113 x >>= 1;
114 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200115
Gilles Peskineeedefa52021-04-13 19:50:04 +0200116 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
117 * a power of 2 iff x is significantly above 0 compared to 2^8.
118 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
119 * description above. */
120 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200121}
122
Paul Bakker33b43f12013-08-20 11:48:36 +0200123/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000124
Paul Bakker33b43f12013-08-20 11:48:36 +0200125/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200126 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200127 * END_DEPENDENCIES
128 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000129
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000130/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100131void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200132{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200133 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200134
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200135 mbedtls_mpi_init( &X );
136 mbedtls_mpi_init( &Y );
137 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200138
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200139 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
140 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200141 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200142 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200143
144exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200145 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200146}
147/* END_CASE */
148
149/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100150void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
151 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200152 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000153{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200154 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000155 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100156 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000157
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200158 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000159
Janos Follath04dadb72019-03-06 12:29:37 +0000160 memset( str, '!', sizeof( str ) );
161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200163 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000164 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200165 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100166 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200167 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000168 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200169 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000170 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000171 }
172 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000173
Paul Bakkerbd51b262014-07-10 15:26:12 +0200174exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000176}
Paul Bakker33b43f12013-08-20 11:48:36 +0200177/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000178
Paul Bakker33b43f12013-08-20 11:48:36 +0200179/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100180void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000181{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200182 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000183 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100184 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000185
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200186 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000187
Paul Bakkere896fea2009-07-06 06:40:23 +0000188
Azim Khand30ca132017-06-09 04:32:58 +0100189 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200190 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100191 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
192 TEST_ASSERT( strcasecmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000193
Paul Bakkerbd51b262014-07-10 15:26:12 +0200194exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000196}
Paul Bakker33b43f12013-08-20 11:48:36 +0200197/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000198
Paul Bakker33b43f12013-08-20 11:48:36 +0200199/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100200void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000201{
202 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000203 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000204 size_t len;
205
206 mbedtls_mpi_init( &X );
207
208
209 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200210 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100211 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
212 TEST_ASSERT( strcasecmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000213
214exit:
215 mbedtls_mpi_free( &X );
216}
217/* END_CASE */
218
219/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100220void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
221 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000222{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000224 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000225 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000226
227 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000228
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200229 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000230
Werner Lewis19b4cd82022-07-07 11:02:27 +0100231 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100232
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200234 if( buflen > (size_t) output_size )
235 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000236
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200238 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000239 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000240
Ronald Cron2dbba992020-06-10 11:42:32 +0200241 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
242 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000243 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000244
Paul Bakkerbd51b262014-07-10 15:26:12 +0200245exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000247}
Paul Bakker33b43f12013-08-20 11:48:36 +0200248/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000249
Janos Follathe344d0f2019-02-19 16:17:40 +0000250/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100251void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
252 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000253{
254 mbedtls_mpi X;
255 unsigned char buf[1000];
256 size_t buflen;
257
258 memset( buf, 0x00, 1000 );
259
260 mbedtls_mpi_init( &X );
261
Werner Lewis19b4cd82022-07-07 11:02:27 +0100262 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000263
264 buflen = mbedtls_mpi_size( &X );
265 if( buflen > (size_t) output_size )
266 buflen = (size_t) output_size;
267
268 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
269 if( result == 0)
270 {
271
Ronald Cron2dbba992020-06-10 11:42:32 +0200272 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
273 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000274 }
275
276exit:
277 mbedtls_mpi_free( &X );
278}
279/* END_CASE */
280
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200281/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100282void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000283{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000285 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000286 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000287 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000288 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000289
290 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000291
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200292 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Paul Bakker33b43f12013-08-20 11:48:36 +0200294 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200295 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100296 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000297 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000298 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000299
Paul Bakker33b43f12013-08-20 11:48:36 +0200300 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000301 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200302 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303 buflen = mbedtls_mpi_size( &X );
304 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000305
Paul Bakkere896fea2009-07-06 06:40:23 +0000306
Ronald Cron2dbba992020-06-10 11:42:32 +0200307 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
308 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000309 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000310
Paul Bakkerbd51b262014-07-10 15:26:12 +0200311exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000313}
Paul Bakker33b43f12013-08-20 11:48:36 +0200314/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000315
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100317void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000318{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000320 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200321 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000324
Werner Lewis19b4cd82022-07-07 11:02:27 +0100325 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000326
Paul Bakker33b43f12013-08-20 11:48:36 +0200327 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000328 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100329 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000330 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200331 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000332
Paul Bakker33b43f12013-08-20 11:48:36 +0200333 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000334 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100335 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000336 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200337 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000338
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200339 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000340
Paul Bakkerbd51b262014-07-10 15:26:12 +0200341exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000343}
Paul Bakker33b43f12013-08-20 11:48:36 +0200344/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000345
Paul Bakker33b43f12013-08-20 11:48:36 +0200346/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100347void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000348{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 mbedtls_mpi X;
350 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100351 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000353
Paul Bakkerbd51b262014-07-10 15:26:12 +0200354exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000356}
Paul Bakker33b43f12013-08-20 11:48:36 +0200357/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000358
Paul Bakker33b43f12013-08-20 11:48:36 +0200359/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100360void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
361 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000362{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_mpi X, Y;
364 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000365
Werner Lewis19b4cd82022-07-07 11:02:27 +0100366 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
367 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100368 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
369
370 if( result == 0 )
371 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200372 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100373 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
374 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000375
Paul Bakkerbd51b262014-07-10 15:26:12 +0200376exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000378}
Paul Bakker33b43f12013-08-20 11:48:36 +0200379/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000380
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100382void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000383{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 mbedtls_mpi X;
385 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000386
Werner Lewis19b4cd82022-07-07 11:02:27 +0100387 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000389
Paul Bakkerbd51b262014-07-10 15:26:12 +0200390exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000392}
Paul Bakker33b43f12013-08-20 11:48:36 +0200393/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000394
Paul Bakker33b43f12013-08-20 11:48:36 +0200395/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100396void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000397{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_mpi X;
399 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000400
Werner Lewis19b4cd82022-07-07 11:02:27 +0100401 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200402 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000403
Paul Bakkerbd51b262014-07-10 15:26:12 +0200404exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000406}
Paul Bakker33b43f12013-08-20 11:48:36 +0200407/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000408
Paul Bakker33b43f12013-08-20 11:48:36 +0200409/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100410void mbedtls_mpi_gcd( char * input_X, char * input_Y,
411 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000412{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 mbedtls_mpi A, X, Y, Z;
414 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000415
Werner Lewis19b4cd82022-07-07 11:02:27 +0100416 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
417 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
418 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200420 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000422
Paul Bakkerbd51b262014-07-10 15:26:12 +0200423exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000425}
Paul Bakker33b43f12013-08-20 11:48:36 +0200426/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000427
Paul Bakker33b43f12013-08-20 11:48:36 +0200428/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000430{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_mpi X;
432 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000433
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
435 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000436
Paul Bakkerbd51b262014-07-10 15:26:12 +0200437exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000439}
Paul Bakker33b43f12013-08-20 11:48:36 +0200440/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000441
Paul Bakker33b43f12013-08-20 11:48:36 +0200442/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100443void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
444 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000445{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446 mbedtls_mpi X, Y;
447 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000448
Werner Lewis19b4cd82022-07-07 11:02:27 +0100449 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
450 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000452
Paul Bakkerbd51b262014-07-10 15:26:12 +0200453exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000455}
Paul Bakker33b43f12013-08-20 11:48:36 +0200456/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000457
Paul Bakker33b43f12013-08-20 11:48:36 +0200458/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100459void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
460 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100461 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100462{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200463 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100464 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100465 mbedtls_mpi X, Y;
466 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
467
Werner Lewis19b4cd82022-07-07 11:02:27 +0100468 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
469 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100470
Gilles Peskine9018b112020-01-21 16:30:53 +0100471 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
472 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100473
Janos Follath0e5532d2019-10-11 14:21:53 +0100474 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100475 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100476 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100477
478exit:
479 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
480}
481/* END_CASE */
482
483/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100484void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
485 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000486{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 mbedtls_mpi X, Y;
488 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000489
Werner Lewis19b4cd82022-07-07 11:02:27 +0100490 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
491 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000493
Paul Bakkerbd51b262014-07-10 15:26:12 +0200494exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000496}
Paul Bakker33b43f12013-08-20 11:48:36 +0200497/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000498
Paul Bakker33b43f12013-08-20 11:48:36 +0200499/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200500void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000501{
Gilles Peskined0722f82021-06-10 23:00:33 +0200502 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200503 mbedtls_mpi_init( &src );
504 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200505 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000506
Werner Lewis19b4cd82022-07-07 11:02:27 +0100507 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
508 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200509
510 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100511 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200512 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200513 TEST_ASSERT( sign_is_valid( &dst ) );
514 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000515
Gilles Peskined0722f82021-06-10 23:00:33 +0200516 /* mbedtls_mpi_safe_cond_assign(), assignment done */
517 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100518 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200519 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
520 TEST_ASSERT( sign_is_valid( &dst ) );
521 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
522
523 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
524 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100525 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200526 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
527 TEST_ASSERT( sign_is_valid( &dst ) );
528 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
529
Paul Bakkerbd51b262014-07-10 15:26:12 +0200530exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200531 mbedtls_mpi_free( &src );
532 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200533 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100534}
535/* END_CASE */
536
537/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200538void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100539{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200540 mbedtls_mpi X, A;
541 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200542 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000543
Werner Lewis19b4cd82022-07-07 11:02:27 +0100544 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200546
Werner Lewis19b4cd82022-07-07 11:02:27 +0100547 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200548 TEST_ASSERT( sign_is_valid( &X ) );
549 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000550
Paul Bakkerbd51b262014-07-10 15:26:12 +0200551exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200552 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000554}
Paul Bakker33b43f12013-08-20 11:48:36 +0200555/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000556
Paul Bakker33b43f12013-08-20 11:48:36 +0200557/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200558void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
559{
560 mbedtls_mpi X, Y, X0, Y0;
561 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
562 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
563
Werner Lewis19b4cd82022-07-07 11:02:27 +0100564 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
565 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200566
Gilles Peskined0722f82021-06-10 23:00:33 +0200567 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100568 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
569 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200570 mbedtls_mpi_swap( &X, &Y );
571 TEST_ASSERT( sign_is_valid( &X ) );
572 TEST_ASSERT( sign_is_valid( &Y ) );
573 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
574 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
575
Gilles Peskined0722f82021-06-10 23:00:33 +0200576 /* mbedtls_mpi_safe_cond_swap(), swap done */
577 mbedtls_mpi_free( &X );
578 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100579 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
580 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200581 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
582 TEST_ASSERT( sign_is_valid( &X ) );
583 TEST_ASSERT( sign_is_valid( &Y ) );
584 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
585 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
586
587 /* mbedtls_mpi_safe_cond_swap(), swap not done */
588 mbedtls_mpi_free( &X );
589 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100590 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
591 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200592 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
593 TEST_ASSERT( sign_is_valid( &X ) );
594 TEST_ASSERT( sign_is_valid( &Y ) );
595 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
596 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
597
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200598exit:
599 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
600 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
601}
602/* END_CASE */
603
604/* BEGIN_CASE */
605void mpi_swap_self( char *X_hex )
606{
607 mbedtls_mpi X, X0;
608 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
609
Werner Lewis19b4cd82022-07-07 11:02:27 +0100610 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
611 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200612
613 mbedtls_mpi_swap( &X, &X );
614 TEST_ASSERT( sign_is_valid( &X ) );
615 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
616
617exit:
618 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
619}
620/* END_CASE */
621
622/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100624{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 mbedtls_mpi X;
626 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200629 if( used > 0 )
630 {
631 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
632 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
633 }
634 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200636 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100637
Paul Bakkerbd51b262014-07-10 15:26:12 +0200638exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100640}
641/* END_CASE */
642
643/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100644void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
645 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000646{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 mbedtls_mpi X, Y, Z, A;
648 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000649
Werner Lewis19b4cd82022-07-07 11:02:27 +0100650 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
651 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
652 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200654 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000656
Gilles Peskine56f943a2020-07-23 01:18:11 +0200657 /* result == first operand */
658 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200659 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200660 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100661 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200662
663 /* result == second operand */
664 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200665 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200666 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
667
Paul Bakkerbd51b262014-07-10 15:26:12 +0200668exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000670}
Paul Bakker33b43f12013-08-20 11:48:36 +0200671/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000672
Paul Bakker33b43f12013-08-20 11:48:36 +0200673/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100674void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100675{
676 mbedtls_mpi X, A;
677 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
678
Werner Lewis19b4cd82022-07-07 11:02:27 +0100679 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100680
Werner Lewis19b4cd82022-07-07 11:02:27 +0100681 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100682 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
683 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200684 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100685
Werner Lewis19b4cd82022-07-07 11:02:27 +0100686 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100687 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200688 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100689 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
690
Werner Lewis19b4cd82022-07-07 11:02:27 +0100691 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100692 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200693 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100694 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
695
696exit:
697 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
698}
699/* END_CASE */
700
701
702/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100703void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
704 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000705{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_mpi X, Y, Z, A;
707 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000708
Werner Lewis19b4cd82022-07-07 11:02:27 +0100709 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
710 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
711 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200713 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000715
Gilles Peskine56f943a2020-07-23 01:18:11 +0200716 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200718 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100720 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200721
722 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200724 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000726
Paul Bakkerbd51b262014-07-10 15:26:12 +0200727exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200728 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000729}
Paul Bakker33b43f12013-08-20 11:48:36 +0200730/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000731
Paul Bakker33b43f12013-08-20 11:48:36 +0200732/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100733void mbedtls_mpi_add_int( char * input_X, int input_Y,
734 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000735{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 mbedtls_mpi X, Z, A;
737 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000738
Werner Lewis19b4cd82022-07-07 11:02:27 +0100739 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
740 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200742 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000744
Paul Bakkerbd51b262014-07-10 15:26:12 +0200745exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000747}
Paul Bakker33b43f12013-08-20 11:48:36 +0200748/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000749
Paul Bakker33b43f12013-08-20 11:48:36 +0200750/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100751void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
752 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000753{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 mbedtls_mpi X, Y, Z, A;
755 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000756
Werner Lewis19b4cd82022-07-07 11:02:27 +0100757 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
758 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
759 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200761 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000763
Gilles Peskine56f943a2020-07-23 01:18:11 +0200764 /* result == first operand */
765 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200766 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200767 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100768 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200769
770 /* result == second operand */
771 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200772 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200773 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
774
Paul Bakkerbd51b262014-07-10 15:26:12 +0200775exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000777}
Paul Bakker33b43f12013-08-20 11:48:36 +0200778/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000779
Paul Bakker33b43f12013-08-20 11:48:36 +0200780/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100781void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
782 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000783{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200784 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000785 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000787
Werner Lewis19b4cd82022-07-07 11:02:27 +0100788 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
789 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
790 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100791
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200792 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200793 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200794 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000795 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200796 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000797
Gilles Peskine56f943a2020-07-23 01:18:11 +0200798 /* result == first operand */
799 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200800 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200801 if( sub_result == 0 )
802 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100803 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200804
805 /* result == second operand */
806 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200807 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200808 if( sub_result == 0 )
809 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
810
Paul Bakkerbd51b262014-07-10 15:26:12 +0200811exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200812 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000813}
Paul Bakker33b43f12013-08-20 11:48:36 +0200814/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000815
Paul Bakker33b43f12013-08-20 11:48:36 +0200816/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100817void mbedtls_mpi_sub_int( char * input_X, int input_Y,
818 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000819{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_mpi X, Z, A;
821 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000822
Werner Lewis19b4cd82022-07-07 11:02:27 +0100823 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
824 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200826 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000828
Paul Bakkerbd51b262014-07-10 15:26:12 +0200829exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200830 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000831}
Paul Bakker33b43f12013-08-20 11:48:36 +0200832/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000833
Paul Bakker33b43f12013-08-20 11:48:36 +0200834/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100835void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
836 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000837{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 mbedtls_mpi X, Y, Z, A;
839 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000840
Werner Lewis19b4cd82022-07-07 11:02:27 +0100841 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
842 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
843 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200845 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000847
Paul Bakkerbd51b262014-07-10 15:26:12 +0200848exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000850}
Paul Bakker33b43f12013-08-20 11:48:36 +0200851/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000852
Paul Bakker33b43f12013-08-20 11:48:36 +0200853/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100854void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +0100855 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000856{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_mpi X, Z, A;
858 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000859
Werner Lewis19b4cd82022-07-07 11:02:27 +0100860 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
861 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200863 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200864 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200866 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200868 else
869 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000870
Paul Bakkerbd51b262014-07-10 15:26:12 +0200871exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000873}
Paul Bakker33b43f12013-08-20 11:48:36 +0200874/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000875
Paul Bakker33b43f12013-08-20 11:48:36 +0200876/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100877void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
878 char * input_A, char * input_B,
879 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000880{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000882 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
884 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000885
Werner Lewis19b4cd82022-07-07 11:02:27 +0100886 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
887 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
888 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
889 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200890 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200891 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000892 if( res == 0 )
893 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200894 TEST_ASSERT( sign_is_valid( &Q ) );
895 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
897 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000898 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000899
Paul Bakkerbd51b262014-07-10 15:26:12 +0200900exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200901 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
902 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000903}
Paul Bakker33b43f12013-08-20 11:48:36 +0200904/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000905
Paul Bakker33b43f12013-08-20 11:48:36 +0200906/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100907void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +0100908 char * input_A, char * input_B,
909 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000910{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000912 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
914 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000915
Werner Lewis19b4cd82022-07-07 11:02:27 +0100916 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
917 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
918 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200920 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000921 if( res == 0 )
922 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200923 TEST_ASSERT( sign_is_valid( &Q ) );
924 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
926 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000927 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000928
Paul Bakkerbd51b262014-07-10 15:26:12 +0200929exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
931 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000932}
Paul Bakker33b43f12013-08-20 11:48:36 +0200933/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000934
Paul Bakker33b43f12013-08-20 11:48:36 +0200935/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100936void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
937 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000938{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000940 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000942
Werner Lewis19b4cd82022-07-07 11:02:27 +0100943 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
944 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
945 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200947 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000948 if( res == 0 )
949 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200950 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000952 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000953
Paul Bakkerbd51b262014-07-10 15:26:12 +0200954exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000956}
Paul Bakker33b43f12013-08-20 11:48:36 +0200957/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000958
Paul Bakker33b43f12013-08-20 11:48:36 +0200959/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100960void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +0100961 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000962{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000964 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_mpi_uint r;
966 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000967
Werner Lewis19b4cd82022-07-07 11:02:27 +0100968 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200970 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000971 if( res == 0 )
972 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +0000974 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000975
Paul Bakkerbd51b262014-07-10 15:26:12 +0200976exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000978}
Paul Bakker33b43f12013-08-20 11:48:36 +0200979/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000980
Paul Bakker33b43f12013-08-20 11:48:36 +0200981/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100982void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
983 char * input_N, char * input_X,
984 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000985{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +0000987 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
989 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000990
Werner Lewis19b4cd82022-07-07 11:02:27 +0100991 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
992 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
993 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
994 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000995
Gilles Peskine342f71b2021-06-09 18:31:35 +0200996 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +0200997 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +0200998 if( res == 0 )
999 {
1000 TEST_ASSERT( sign_is_valid( &Z ) );
1001 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1002 }
1003
1004 /* Now test again with the speed-up parameter supplied as an output. */
1005 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001006 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001007 if( res == 0 )
1008 {
1009 TEST_ASSERT( sign_is_valid( &Z ) );
1010 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1011 }
1012
1013 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001015 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001016 if( res == 0 )
1017 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001018 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001020 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001021
Paul Bakkerbd51b262014-07-10 15:26:12 +02001022exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1024 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
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 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001029void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001030 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001031{
1032 mbedtls_mpi A, E, N, RR, Z;
1033 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1034 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1035
Chris Jonesaa850cd2020-12-03 11:35:41 +00001036 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001037 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001038 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001039 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001040
1041 /* Set E to 2^(E_bytes - 1) + 1 */
1042 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1043 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001044 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001045
1046 /* Set N to 2^(N_bytes - 1) + 1 */
1047 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1048 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001049 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1050
1051 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001052 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001053
Chris Jonesaa850cd2020-12-03 11:35:41 +00001054 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001055
1056exit:
1057 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1058 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1059}
1060/* END_CASE */
1061
1062/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001063void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1064 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001065{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001067 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001068 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001069
Werner Lewis19b4cd82022-07-07 11:02:27 +01001070 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1071 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1072 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001074 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001075 if( res == 0 )
1076 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001077 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 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( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001083}
Paul Bakker33b43f12013-08-20 11:48:36 +02001084/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001085
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001087void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001088{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001090 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001092
Werner Lewis19b4cd82022-07-07 11:02:27 +01001093 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001094 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001095 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001096
Paul Bakkerbd51b262014-07-10 15:26:12 +02001097exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001099}
Paul Bakker33b43f12013-08-20 11:48:36 +02001100/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001103void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001104 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001105{
1106 mbedtls_mpi X;
1107 int res;
1108 mbedtls_test_mpi_random rand;
1109
1110 mbedtls_mpi_init( &X );
1111 rand.data = witnesses;
1112 rand.pos = 0;
1113 rand.chunk_len = chunk_len;
1114
1115 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001116 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1117 mbedtls_test_mpi_miller_rabin_determinizer,
1118 &rand );
1119 TEST_ASSERT( res == 0 );
1120
1121 rand.data = witnesses;
1122 rand.pos = 0;
1123 rand.chunk_len = chunk_len;
1124
Janos Follatha0b67c22018-09-18 14:48:23 +01001125 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1126 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001127 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001128 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001129
1130exit:
1131 mbedtls_mpi_free( &X );
1132}
1133/* END_CASE */
1134
1135/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001136void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001137{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001139 int my_ret;
1140
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001142
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001143 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1144 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001145 TEST_ASSERT( my_ret == ref_ret );
1146
1147 if( ref_ret == 0 )
1148 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001149 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001150
1151 TEST_ASSERT( actual_bits >= (size_t) bits );
1152 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001153 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001154
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001155 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1156 mbedtls_test_rnd_std_rand,
1157 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001158 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001159 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001160 /* X = ( X - 1 ) / 2 */
1161 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001162 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1163 mbedtls_test_rnd_std_rand,
1164 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001165 }
1166 }
1167
Paul Bakkerbd51b262014-07-10 15:26:12 +02001168exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001170}
1171/* END_CASE */
1172
Paul Bakker33b43f12013-08-20 11:48:36 +02001173/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001174void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1175 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001176{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177 mbedtls_mpi X, A;
1178 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001179
Werner Lewis19b4cd82022-07-07 11:02:27 +01001180 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1181 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001182 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001183 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001185
Paul Bakkerbd51b262014-07-10 15:26:12 +02001186exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001188}
Paul Bakker33b43f12013-08-20 11:48:36 +02001189/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001190
Paul Bakker33b43f12013-08-20 11:48:36 +02001191/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001192void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1193 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001194{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001195 mbedtls_mpi X, A;
1196 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001197
Werner Lewis19b4cd82022-07-07 11:02:27 +01001198 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1199 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001200 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001201 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001202 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001203
Paul Bakkerbd51b262014-07-10 15:26:12 +02001204exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001206}
Paul Bakker33b43f12013-08-20 11:48:36 +02001207/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001208
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001209/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001210void mpi_fill_random( int wanted_bytes, int rng_bytes,
1211 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001212{
1213 mbedtls_mpi X;
1214 int ret;
1215 size_t bytes_left = rng_bytes;
1216 mbedtls_mpi_init( &X );
1217
Gilles Peskine422e8672021-04-02 00:02:27 +02001218 if( before != 0 )
1219 {
1220 /* Set X to sign(before) * 2^(|before|-1) */
1221 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1222 if( before < 0 )
1223 before = - before;
1224 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1225 }
1226
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001227 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1228 f_rng_bytes_left, &bytes_left );
1229 TEST_ASSERT( ret == expected_ret );
1230
1231 if( expected_ret == 0 )
1232 {
1233 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1234 * as a big-endian representation of the number. We know when
1235 * our RNG function returns null bytes, so we know how many
1236 * leading zero bytes the number has. */
1237 size_t leading_zeros = 0;
1238 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1239 leading_zeros = 1;
1240 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1241 (size_t) wanted_bytes );
1242 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001243 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001244 }
1245
1246exit:
1247 mbedtls_mpi_free( &X );
1248}
1249/* END_CASE */
1250
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001251/* BEGIN_CASE */
1252void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1253{
1254 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1255 * This function assumes that the value of bound is at least 2 and
1256 * that iterations is large enough that a one-in-2^iterations chance
1257 * effectively never occurs.
1258 */
1259
1260 mbedtls_mpi upper_bound;
1261 size_t n_bits;
1262 mbedtls_mpi result;
1263 size_t b;
1264 /* If upper_bound is small, stats[b] is the number of times the value b
1265 * has been generated. Otherwise stats[b] is the number of times a
1266 * value with bit b set has been generated. */
1267 size_t *stats = NULL;
1268 size_t stats_len;
1269 int full_stats;
1270 size_t i;
1271
1272 mbedtls_mpi_init( &upper_bound );
1273 mbedtls_mpi_init( &result );
1274
1275 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1276 bound_bytes->x, bound_bytes->len ) );
1277 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1278 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1279 * to be small enough that the probability of missing one value is
1280 * negligible given the number of iterations. It must be less than
1281 * 256 because some of the code below assumes that "small" values
1282 * fit in a byte. */
1283 if( n_bits <= 5 )
1284 {
1285 full_stats = 1;
1286 stats_len = bound_bytes->x[bound_bytes->len - 1];
1287 }
1288 else
1289 {
1290 full_stats = 0;
1291 stats_len = n_bits;
1292 }
1293 ASSERT_ALLOC( stats, stats_len );
1294
1295 for( i = 0; i < (size_t) iterations; i++ )
1296 {
1297 mbedtls_test_set_step( i );
1298 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1299 mbedtls_test_rnd_std_rand, NULL ) );
1300
Gilles Peskinedffc7102021-06-10 15:34:15 +02001301 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001302 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1303 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1304 if( full_stats )
1305 {
1306 uint8_t value;
1307 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1308 TEST_ASSERT( value < stats_len );
1309 ++stats[value];
1310 }
1311 else
1312 {
1313 for( b = 0; b < n_bits; b++ )
1314 stats[b] += mbedtls_mpi_get_bit( &result, b );
1315 }
1316 }
1317
1318 if( full_stats )
1319 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001320 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001321 {
1322 mbedtls_test_set_step( 1000000 + b );
1323 /* Assert that each value has been reached at least once.
1324 * This is almost guaranteed if the iteration count is large
1325 * enough. This is a very crude way of checking the distribution.
1326 */
1327 TEST_ASSERT( stats[b] > 0 );
1328 }
1329 }
1330 else
1331 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001332 int statistically_safe_all_the_way =
1333 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001334 for( b = 0; b < n_bits; b++ )
1335 {
1336 mbedtls_test_set_step( 1000000 + b );
1337 /* Assert that each bit has been set in at least one result and
1338 * clear in at least one result. Provided that iterations is not
1339 * too small, it would be extremely unlikely for this not to be
1340 * the case if the results are uniformly distributed.
1341 *
1342 * As an exception, the top bit may legitimately never be set
1343 * if bound is a power of 2 or only slightly above.
1344 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001345 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001346 {
1347 TEST_ASSERT( stats[b] > 0 );
1348 }
1349 TEST_ASSERT( stats[b] < (size_t) iterations );
1350 }
1351 }
1352
1353exit:
1354 mbedtls_mpi_free( &upper_bound );
1355 mbedtls_mpi_free( &result );
1356 mbedtls_free( stats );
1357}
1358/* END_CASE */
1359
Gilles Peskine1e918f42021-03-29 22:14:51 +02001360/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001361void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001362{
1363 mbedtls_mpi upper_bound;
1364 mbedtls_mpi result;
1365
1366 mbedtls_mpi_init( &upper_bound );
1367 mbedtls_mpi_init( &result );
1368
Gilles Peskine422e8672021-04-02 00:02:27 +02001369 if( before != 0 )
1370 {
1371 /* Set result to sign(before) * 2^(|before|-1) */
1372 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1373 if( before < 0 )
1374 before = - before;
1375 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1376 }
1377
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001378 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1379 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1380 bound_bytes->x, bound_bytes->len ) );
1381 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1382 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001383 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001384 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1385 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1386
1387exit:
1388 mbedtls_mpi_free( &upper_bound );
1389 mbedtls_mpi_free( &result );
1390}
1391/* END_CASE */
1392
1393/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001394void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1395{
1396 mbedtls_mpi upper_bound;
1397 mbedtls_mpi result;
1398 int actual_ret;
1399
1400 mbedtls_mpi_init( &upper_bound );
1401 mbedtls_mpi_init( &result );
1402
1403 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1404 bound_bytes->x, bound_bytes->len ) );
1405 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1406 mbedtls_test_rnd_std_rand, NULL );
1407 TEST_EQUAL( expected_ret, actual_ret );
1408
1409exit:
1410 mbedtls_mpi_free( &upper_bound );
1411 mbedtls_mpi_free( &result );
1412}
1413/* END_CASE */
1414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001416void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001417{
Andres AG93012e82016-09-09 09:10:28 +01001418 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001419}
Paul Bakker33b43f12013-08-20 11:48:36 +02001420/* END_CASE */