blob: eaede01b49f68f7358ffb39024d95decac0789a1 [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
9typedef struct mbedtls_test_mpi_random
10{
11 data_t *data;
12 size_t pos;
13 size_t chunk_len;
14} mbedtls_test_mpi_random;
15
16/*
17 * This function is called by the Miller-Rabin primality test each time it
18 * chooses a random witness. The witnesses (or non-witnesses as provided by the
19 * test) are stored in the data member of the state structure. Each number is in
20 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
21 */
22int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
23 unsigned char* buf,
24 size_t len )
25{
26 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
27
28 if( random == NULL || random->data->x == NULL || buf == NULL )
29 return( -1 );
30
31 if( random->pos + random->chunk_len > random->data->len
32 || random->chunk_len > len )
33 {
34 return( -1 );
35 }
36
37 memset( buf, 0, len );
38
39 /* The witness is written to the end of the buffer, since the buffer is
40 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
41 * Writing the witness to the start of the buffer would result in the
42 * buffer being 'witness 000...000', which would be treated as
43 * witness * 2^n for some n. */
44 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
45 random->chunk_len );
46
47 random->pos += random->chunk_len;
48
49 return( 0 );
50}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010051
52/* Random generator that is told how many bytes to return. */
53static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
54{
55 size_t *bytes_left = state;
56 size_t i;
57 for( i = 0; i < len; i++ )
58 {
59 if( *bytes_left == 0 )
60 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
61 buf[i] = *bytes_left & 0xff;
62 --( *bytes_left );
63 }
64 return( 0 );
65}
66
Gilles Peskineeedefa52021-04-13 19:50:04 +020067/* Test whether bytes represents (in big-endian base 256) a number b that
68 * is significantly above a power of 2. That is, b must not have a long run
69 * of unset bits after the most significant bit.
70 *
71 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
72 * This function returns 1 if, when drawing a number between 0 and b,
73 * the probability that this number is at least 2^n is not negligible.
74 * This probability is (b - 2^n) / b and this function checks that this
75 * number is above some threshold A. The threshold value is heuristic and
76 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020077 */
78static int is_significantly_above_a_power_of_2( data_t *bytes )
79{
80 const uint8_t *p = bytes->x;
81 size_t len = bytes->len;
82 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020083
84 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +020085 while( len > 0 && p[0] == 0 )
86 {
87 ++p;
88 --len;
89 }
Gilles Peskineeedefa52021-04-13 19:50:04 +020090 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +020091 if( len == 0 )
92 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +020093 /* Extract the (up to) 2 most significant bytes */
94 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +020095 x = p[0];
96 else
97 x = ( p[0] << 8 ) | p[1];
98
Gilles Peskineeedefa52021-04-13 19:50:04 +020099 /* Shift the most significant bit of x to position 8 and mask it out */
100 while( ( x & 0xfe00 ) != 0 )
101 x >>= 1;
102 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200103
Gilles Peskineeedefa52021-04-13 19:50:04 +0200104 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
105 * a power of 2 iff x is significantly above 0 compared to 2^8.
106 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
107 * description above. */
108 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200109}
110
Paul Bakker33b43f12013-08-20 11:48:36 +0200111/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000112
Paul Bakker33b43f12013-08-20 11:48:36 +0200113/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200115 * END_DEPENDENCIES
116 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000117
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000118/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100119void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200120{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200121 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200122
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200123 mbedtls_mpi_init( &X );
124 mbedtls_mpi_init( &Y );
125 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200126
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200127 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
128 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200129 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200130 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200131
132exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200133 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200134}
135/* END_CASE */
136
137/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100138void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
139 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200140 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000141{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000143 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100144 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000147
Janos Follath04dadb72019-03-06 12:29:37 +0000148 memset( str, '!', sizeof( str ) );
149
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200150 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200151 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000152 {
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100153 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200154 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000155 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200156 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000157 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000158 }
159 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000160
Paul Bakkerbd51b262014-07-10 15:26:12 +0200161exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200162 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000163}
Paul Bakker33b43f12013-08-20 11:48:36 +0200164/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000165
Paul Bakker33b43f12013-08-20 11:48:36 +0200166/* BEGIN_CASE */
Azim Khan5fcca462018-06-29 11:05:32 +0100167void mbedtls_mpi_read_binary( data_t * buf, int radix_A, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000168{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000170 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100171 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000174
Paul Bakkere896fea2009-07-06 06:40:23 +0000175
Azim Khand30ca132017-06-09 04:32:58 +0100176 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Janos Follathe5670f22019-02-25 16:11:58 +0000177 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
Paul Bakker33b43f12013-08-20 11:48:36 +0200178 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000179
Paul Bakkerbd51b262014-07-10 15:26:12 +0200180exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200181 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000182}
Paul Bakker33b43f12013-08-20 11:48:36 +0200183/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000184
Paul Bakker33b43f12013-08-20 11:48:36 +0200185/* BEGIN_CASE */
Janos Follatha778a942019-02-13 10:28:28 +0000186void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A )
187{
188 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000189 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000190 size_t len;
191
192 mbedtls_mpi_init( &X );
193
194
195 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Janos Follathe5670f22019-02-25 16:11:58 +0000196 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000197 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
198
199exit:
200 mbedtls_mpi_free( &X );
201}
202/* END_CASE */
203
204/* BEGIN_CASE */
Azim Khand30ca132017-06-09 04:32:58 +0100205void mbedtls_mpi_write_binary( int radix_X, char * input_X,
Azim Khan5fcca462018-06-29 11:05:32 +0100206 data_t * input_A, int output_size,
Azim Khanf1aaec92017-05-30 14:23:15 +0100207 int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000208{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000210 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000211 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000212
213 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000214
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200215 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000216
Gilles Peskine20edee72021-06-10 23:18:39 +0200217 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100218
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200219 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200220 if( buflen > (size_t) output_size )
221 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000222
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200223 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200224 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000225 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000226
Ronald Cron2dbba992020-06-10 11:42:32 +0200227 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
228 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000229 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000230
Paul Bakkerbd51b262014-07-10 15:26:12 +0200231exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200232 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000233}
Paul Bakker33b43f12013-08-20 11:48:36 +0200234/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000235
Janos Follathe344d0f2019-02-19 16:17:40 +0000236/* BEGIN_CASE */
237void mbedtls_mpi_write_binary_le( int radix_X, char * input_X,
238 data_t * input_A, int output_size,
239 int result )
240{
241 mbedtls_mpi X;
242 unsigned char buf[1000];
243 size_t buflen;
244
245 memset( buf, 0x00, 1000 );
246
247 mbedtls_mpi_init( &X );
248
Gilles Peskine20edee72021-06-10 23:18:39 +0200249 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000250
251 buflen = mbedtls_mpi_size( &X );
252 if( buflen > (size_t) output_size )
253 buflen = (size_t) output_size;
254
255 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
256 if( result == 0)
257 {
258
Ronald Cron2dbba992020-06-10 11:42:32 +0200259 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
260 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000261 }
262
263exit:
264 mbedtls_mpi_free( &X );
265}
266/* END_CASE */
267
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200268/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khand30ca132017-06-09 04:32:58 +0100269void mbedtls_mpi_read_file( int radix_X, char * input_file,
Azim Khan5fcca462018-06-29 11:05:32 +0100270 data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000271{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000273 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000274 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000275 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000276 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000277
278 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000279
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200280 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000281
Paul Bakker33b43f12013-08-20 11:48:36 +0200282 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200283 TEST_ASSERT( file != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200284 ret = mbedtls_mpi_read_file( &X, radix_X, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000285 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000286 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000287
Paul Bakker33b43f12013-08-20 11:48:36 +0200288 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000289 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200290 buflen = mbedtls_mpi_size( &X );
291 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000292
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Ronald Cron2dbba992020-06-10 11:42:32 +0200294 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
295 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000296 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000297
Paul Bakkerbd51b262014-07-10 15:26:12 +0200298exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000300}
Paul Bakker33b43f12013-08-20 11:48:36 +0200301/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200303/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100304void mbedtls_mpi_write_file( int radix_X, char * input_X, int output_radix,
305 char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000306{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200307 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000308 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200309 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000310
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200311 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000312
Gilles Peskine20edee72021-06-10 23:18:39 +0200313 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000314
Paul Bakker33b43f12013-08-20 11:48:36 +0200315 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000316 TEST_ASSERT( file_out != NULL );
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200317 ret = mbedtls_mpi_write_file( NULL, &X, output_radix, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000318 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200319 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000320
Paul Bakker33b43f12013-08-20 11:48:36 +0200321 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000322 TEST_ASSERT( file_in != NULL );
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200323 ret = mbedtls_mpi_read_file( &Y, output_radix, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000324 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200325 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000328
Paul Bakkerbd51b262014-07-10 15:26:12 +0200329exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000331}
Paul Bakker33b43f12013-08-20 11:48:36 +0200332/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000333
Paul Bakker33b43f12013-08-20 11:48:36 +0200334/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100335void mbedtls_mpi_get_bit( int radix_X, char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000336{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 mbedtls_mpi X;
338 mbedtls_mpi_init( &X );
Gilles Peskine20edee72021-06-10 23:18:39 +0200339 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200340 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000341
Paul Bakkerbd51b262014-07-10 15:26:12 +0200342exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000344}
Paul Bakker33b43f12013-08-20 11:48:36 +0200345/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000346
Paul Bakker33b43f12013-08-20 11:48:36 +0200347/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100348void mbedtls_mpi_set_bit( int radix_X, char * input_X, int pos, int val,
349 int radix_Y, char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000350{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 mbedtls_mpi X, Y;
352 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000353
Gilles Peskine20edee72021-06-10 23:18:39 +0200354 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
355 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100356 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
357
358 if( result == 0 )
359 {
360 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
361 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000362
Paul Bakkerbd51b262014-07-10 15:26:12 +0200363exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000365}
Paul Bakker33b43f12013-08-20 11:48:36 +0200366/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000367
Paul Bakker33b43f12013-08-20 11:48:36 +0200368/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100369void mbedtls_mpi_lsb( int radix_X, char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000370{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200371 mbedtls_mpi X;
372 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000373
Gilles Peskine20edee72021-06-10 23:18:39 +0200374 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000376
Paul Bakkerbd51b262014-07-10 15:26:12 +0200377exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000379}
Paul Bakker33b43f12013-08-20 11:48:36 +0200380/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000381
Paul Bakker33b43f12013-08-20 11:48:36 +0200382/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100383void mbedtls_mpi_bitlen( int radix_X, char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000384{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385 mbedtls_mpi X;
386 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000387
Gilles Peskine20edee72021-06-10 23:18:39 +0200388 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200389 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000390
Paul Bakkerbd51b262014-07-10 15:26:12 +0200391exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000393}
Paul Bakker33b43f12013-08-20 11:48:36 +0200394/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000395
Paul Bakker33b43f12013-08-20 11:48:36 +0200396/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100397void mbedtls_mpi_gcd( int radix_X, char * input_X, int radix_Y,
398 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000399{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 mbedtls_mpi A, X, Y, Z;
401 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000402
Gilles Peskine20edee72021-06-10 23:18:39 +0200403 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
404 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
405 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
407 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000408
Paul Bakkerbd51b262014-07-10 15:26:12 +0200409exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000411}
Paul Bakker33b43f12013-08-20 11:48:36 +0200412/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000413
Paul Bakker33b43f12013-08-20 11:48:36 +0200414/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000416{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_mpi X;
418 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
421 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
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( &X );
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 */
Azim Khanf1aaec92017-05-30 14:23:15 +0100429void mbedtls_mpi_cmp_mpi( int radix_X, char * input_X, int radix_Y,
430 char * input_Y, int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000431{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 mbedtls_mpi X, Y;
433 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000434
Gilles Peskine20edee72021-06-10 23:18:39 +0200435 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
436 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000438
Paul Bakkerbd51b262014-07-10 15:26:12 +0200439exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000441}
Paul Bakker33b43f12013-08-20 11:48:36 +0200442/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000443
Paul Bakker33b43f12013-08-20 11:48:36 +0200444/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100445void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
446 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100447 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100448{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200449 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100450 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100451 mbedtls_mpi X, Y;
452 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
453
Gilles Peskine20edee72021-06-10 23:18:39 +0200454 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
455 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100456
Gilles Peskine9018b112020-01-21 16:30:53 +0100457 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
458 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100459
Janos Follath0e5532d2019-10-11 14:21:53 +0100460 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100461 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100462 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100463
464exit:
465 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
466}
467/* END_CASE */
468
469/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100470void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y,
471 char * input_Y, int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000472{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473 mbedtls_mpi X, Y;
474 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000475
Gilles Peskine20edee72021-06-10 23:18:39 +0200476 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
477 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200478 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000479
Paul Bakkerbd51b262014-07-10 15:26:12 +0200480exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000482}
Paul Bakker33b43f12013-08-20 11:48:36 +0200483/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000484
Paul Bakker33b43f12013-08-20 11:48:36 +0200485/* BEGIN_CASE */
Gilles Peskine7428b452020-01-20 21:01:51 +0100486void mbedtls_mpi_copy_sint( int input_X, int input_Y )
Paul Bakker367dae42009-06-28 21:50:27 +0000487{
Gilles Peskine7428b452020-01-20 21:01:51 +0100488 mbedtls_mpi X, Y;
489 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000490
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100492 TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
493
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100495 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
496 TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000497
Paul Bakkerbd51b262014-07-10 15:26:12 +0200498exit:
Gilles Peskine7428b452020-01-20 21:01:51 +0100499 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
500}
501/* END_CASE */
502
503/* BEGIN_CASE */
504void mbedtls_mpi_copy_binary( data_t *input_X, data_t *input_Y )
505{
506 mbedtls_mpi X, Y, X0;
507 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &X0 );
508
Gilles Peskine9a6ecee2020-02-03 16:15:47 +0100509 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
510 TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
511 TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100512 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
513
514 TEST_ASSERT( mbedtls_mpi_copy( &Y, &X ) == 0 );
515 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
516 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
517
518exit:
519 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &X0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000520}
Paul Bakker33b43f12013-08-20 11:48:36 +0200521/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000522
Paul Bakker33b43f12013-08-20 11:48:36 +0200523/* BEGIN_CASE */
524void mpi_copy_self( int input_X )
Paul Bakkere896fea2009-07-06 06:40:23 +0000525{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_mpi X;
527 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000528
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
530 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
531 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000532
Paul Bakkerbd51b262014-07-10 15:26:12 +0200533exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000535}
Paul Bakker33b43f12013-08-20 11:48:36 +0200536/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000537
Paul Bakker33b43f12013-08-20 11:48:36 +0200538/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200539void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100540{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 mbedtls_mpi X;
542 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100543
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100545 TEST_ASSERT( used <= before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200546 memset( X.p, 0x2a, used * sizeof( mbedtls_mpi_uint ) );
547 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100548 TEST_ASSERT( X.n == (size_t) after );
549
Paul Bakkerbd51b262014-07-10 15:26:12 +0200550exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100552}
553/* END_CASE */
554
555/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100556void mbedtls_mpi_safe_cond_assign( int x_sign, char * x_str, int y_sign,
557 char * y_str )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100558{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 mbedtls_mpi X, Y, XX;
560 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &XX );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100561
Gilles Peskine20edee72021-06-10 23:18:39 +0200562 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x_str ) == 0 );
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100563 X.s = x_sign;
Gilles Peskine20edee72021-06-10 23:18:39 +0200564 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y_str ) == 0 );
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100565 Y.s = y_sign;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100567
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200568 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 0 ) == 0 );
569 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100570
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200571 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 1 ) == 0 );
572 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100573
Paul Bakkerbd51b262014-07-10 15:26:12 +0200574exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &XX );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100576}
577/* END_CASE */
578
579/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100580void mbedtls_mpi_safe_cond_swap( int x_sign, char * x_str, int y_sign,
581 char * y_str )
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100582{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_mpi X, Y, XX, YY;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100584
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
586 mbedtls_mpi_init( &XX ); mbedtls_mpi_init( &YY );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100587
Gilles Peskine20edee72021-06-10 23:18:39 +0200588 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x_str ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100589 X.s = x_sign;
Gilles Peskine20edee72021-06-10 23:18:39 +0200590 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y_str ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100591 Y.s = y_sign;
592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
594 TEST_ASSERT( mbedtls_mpi_copy( &YY, &Y ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100595
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200596 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
597 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
598 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &YY ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100599
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
601 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &XX ) == 0 );
602 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &YY ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100603
Paul Bakkerbd51b262014-07-10 15:26:12 +0200604exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
606 mbedtls_mpi_free( &XX ); mbedtls_mpi_free( &YY );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100607}
608/* END_CASE */
609
610/* BEGIN_CASE */
Gilles Peskine7428b452020-01-20 21:01:51 +0100611void mbedtls_mpi_swap_sint( int input_X, int input_Y )
Paul Bakker367dae42009-06-28 21:50:27 +0000612{
Gilles Peskine7428b452020-01-20 21:01:51 +0100613 mbedtls_mpi X, Y;
614 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000615
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200616 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
617 TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100618 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
619 TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
620
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_mpi_swap( &X, &Y );
Gilles Peskine7428b452020-01-20 21:01:51 +0100622 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
623 TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000624
Paul Bakkerbd51b262014-07-10 15:26:12 +0200625exit:
Gilles Peskine7428b452020-01-20 21:01:51 +0100626 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
627}
628/* END_CASE */
629
630/* BEGIN_CASE */
631void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
632{
633 mbedtls_mpi X, Y, X0, Y0;
634 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
635 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
636
Gilles Peskine9a6ecee2020-02-03 16:15:47 +0100637 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
638 TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
639 TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
640 TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100641
642 mbedtls_mpi_swap( &X, &Y );
643 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
644 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
645
646exit:
647 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
648 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
649}
650/* END_CASE */
651
652/* BEGIN_CASE */
653void mpi_swap_self( data_t *input_X )
654{
655 mbedtls_mpi X, X0;
656 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
657
Gilles Peskine9a6ecee2020-02-03 16:15:47 +0100658 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
659 TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100660
661 mbedtls_mpi_swap( &X, &X );
662 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
663
664exit:
665 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000666}
Paul Bakker33b43f12013-08-20 11:48:36 +0200667/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000668
Paul Bakker33b43f12013-08-20 11:48:36 +0200669/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100670void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
671 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000672{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 mbedtls_mpi X, Y, Z, A;
674 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000675
Gilles Peskine20edee72021-06-10 23:18:39 +0200676 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
677 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
678 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
680 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000681
Gilles Peskine56f943a2020-07-23 01:18:11 +0200682 /* result == first operand */
683 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
684 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200685 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200686
687 /* result == second operand */
688 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
689 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
690
Paul Bakkerbd51b262014-07-10 15:26:12 +0200691exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200692 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000693}
Paul Bakker33b43f12013-08-20 11:48:36 +0200694/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000695
Paul Bakker33b43f12013-08-20 11:48:36 +0200696/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100697void mbedtls_mpi_add_mpi_inplace( int radix_X, char * input_X, int radix_A,
698 char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100699{
700 mbedtls_mpi X, A;
701 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
702
Gilles Peskine20edee72021-06-10 23:18:39 +0200703 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100704
Gilles Peskine20edee72021-06-10 23:18:39 +0200705 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100706 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
707 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
708
Gilles Peskine20edee72021-06-10 23:18:39 +0200709 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100710 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
711 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
712
Gilles Peskine20edee72021-06-10 23:18:39 +0200713 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100714 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
715 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
716
717exit:
718 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
719}
720/* END_CASE */
721
722
723/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100724void mbedtls_mpi_add_abs( int radix_X, char * input_X, int radix_Y,
725 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000726{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727 mbedtls_mpi X, Y, Z, A;
728 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000729
Gilles Peskine20edee72021-06-10 23:18:39 +0200730 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
731 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
732 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
734 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000735
Gilles Peskine56f943a2020-07-23 01:18:11 +0200736 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
738 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200739 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200740
741 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
743 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000744
Paul Bakkerbd51b262014-07-10 15:26:12 +0200745exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200746 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000747}
Paul Bakker33b43f12013-08-20 11:48:36 +0200748/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000749
Paul Bakker33b43f12013-08-20 11:48:36 +0200750/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100751void mbedtls_mpi_add_int( int radix_X, char * input_X, int input_Y,
752 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000753{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 mbedtls_mpi X, Z, A;
755 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000756
Gilles Peskine20edee72021-06-10 23:18:39 +0200757 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
758 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
760 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000761
Paul Bakkerbd51b262014-07-10 15:26:12 +0200762exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000764}
Paul Bakker33b43f12013-08-20 11:48:36 +0200765/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000766
Paul Bakker33b43f12013-08-20 11:48:36 +0200767/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100768void mbedtls_mpi_sub_mpi( int radix_X, char * input_X, int radix_Y,
769 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000770{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200771 mbedtls_mpi X, Y, Z, A;
772 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000773
Gilles Peskine20edee72021-06-10 23:18:39 +0200774 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
775 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
776 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200777 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
778 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000779
Gilles Peskine56f943a2020-07-23 01:18:11 +0200780 /* result == first operand */
781 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
782 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200783 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200784
785 /* result == second operand */
786 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
787 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
788
Paul Bakkerbd51b262014-07-10 15:26:12 +0200789exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000791}
Paul Bakker33b43f12013-08-20 11:48:36 +0200792/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000793
Paul Bakker33b43f12013-08-20 11:48:36 +0200794/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100795void mbedtls_mpi_sub_abs( int radix_X, char * input_X, int radix_Y,
796 char * input_Y, int radix_A, char * input_A,
797 int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000798{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000800 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200801 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000802
Gilles Peskine20edee72021-06-10 23:18:39 +0200803 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
804 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
805 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100806
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200807 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200808 TEST_ASSERT( res == sub_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000809 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000811
Gilles Peskine56f943a2020-07-23 01:18:11 +0200812 /* result == first operand */
813 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
814 if( sub_result == 0 )
815 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200816 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200817
818 /* result == second operand */
819 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
820 if( sub_result == 0 )
821 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
822
Paul Bakkerbd51b262014-07-10 15:26:12 +0200823exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200824 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000825}
Paul Bakker33b43f12013-08-20 11:48:36 +0200826/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000827
Paul Bakker33b43f12013-08-20 11:48:36 +0200828/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100829void mbedtls_mpi_sub_int( int radix_X, char * input_X, int input_Y,
830 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000831{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_mpi X, Z, A;
833 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000834
Gilles Peskine20edee72021-06-10 23:18:39 +0200835 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
836 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
838 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000839
Paul Bakkerbd51b262014-07-10 15:26:12 +0200840exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000842}
Paul Bakker33b43f12013-08-20 11:48:36 +0200843/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000844
Paul Bakker33b43f12013-08-20 11:48:36 +0200845/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100846void mbedtls_mpi_mul_mpi( int radix_X, char * input_X, int radix_Y,
847 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000848{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200849 mbedtls_mpi X, Y, Z, A;
850 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000851
Gilles Peskine20edee72021-06-10 23:18:39 +0200852 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
853 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
854 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
856 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000857
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 */
Azim Khanf1aaec92017-05-30 14:23:15 +0100864void mbedtls_mpi_mul_int( int radix_X, char * input_X, int input_Y,
865 int radix_A, char * input_A,
866 char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000867{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 mbedtls_mpi X, Z, A;
869 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000870
Gilles Peskine20edee72021-06-10 23:18:39 +0200871 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
872 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200874 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200876 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200878 else
879 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000880
Paul Bakkerbd51b262014-07-10 15:26:12 +0200881exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200882 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000883}
Paul Bakker33b43f12013-08-20 11:48:36 +0200884/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000885
Paul Bakker33b43f12013-08-20 11:48:36 +0200886/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100887void mbedtls_mpi_div_mpi( int radix_X, char * input_X, int radix_Y,
888 char * input_Y, int radix_A, char * input_A,
889 int radix_B, char * input_B, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000890{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000892 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200893 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
894 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000895
Gilles Peskine20edee72021-06-10 23:18:39 +0200896 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
897 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
898 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
899 TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200901 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000902 if( res == 0 )
903 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
905 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000906 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000907
Paul Bakkerbd51b262014-07-10 15:26:12 +0200908exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
910 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000911}
Paul Bakker33b43f12013-08-20 11:48:36 +0200912/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000913
Paul Bakker33b43f12013-08-20 11:48:36 +0200914/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100915void mbedtls_mpi_div_int( int radix_X, char * input_X, int input_Y,
916 int radix_A, char * input_A, int radix_B,
917 char * input_B, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000918{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200919 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000920 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
922 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000923
Gilles Peskine20edee72021-06-10 23:18:39 +0200924 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
925 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
926 TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200928 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000929 if( res == 0 )
930 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200931 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
932 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000933 }
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( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
937 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000938}
Paul Bakker33b43f12013-08-20 11:48:36 +0200939/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000940
Paul Bakker33b43f12013-08-20 11:48:36 +0200941/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100942void mbedtls_mpi_mod_mpi( int radix_X, char * input_X, int radix_Y,
943 char * input_Y, int radix_A, char * input_A,
944 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000945{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000947 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200948 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000949
Gilles Peskine20edee72021-06-10 23:18:39 +0200950 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
951 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
952 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200953 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200954 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000955 if( res == 0 )
956 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000958 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000959
Paul Bakkerbd51b262014-07-10 15:26:12 +0200960exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000962}
Paul Bakker33b43f12013-08-20 11:48:36 +0200963/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000964
Paul Bakker33b43f12013-08-20 11:48:36 +0200965/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100966void mbedtls_mpi_mod_int( int radix_X, char * input_X, int input_Y,
967 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000968{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200969 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000970 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 mbedtls_mpi_uint r;
972 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000973
Gilles Peskine20edee72021-06-10 23:18:39 +0200974 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200975 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200976 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000977 if( res == 0 )
978 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +0000980 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000981
Paul Bakkerbd51b262014-07-10 15:26:12 +0200982exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200983 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000984}
Paul Bakker33b43f12013-08-20 11:48:36 +0200985/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000986
Paul Bakker33b43f12013-08-20 11:48:36 +0200987/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100988void mbedtls_mpi_exp_mod( int radix_A, char * input_A, int radix_E,
989 char * input_E, int radix_N, char * input_N,
990 int radix_RR, char * input_RR, int radix_X,
991 char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000992{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +0000994 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
996 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000997
Gilles Peskine20edee72021-06-10 23:18:39 +0200998 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
999 TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
1000 TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
1001 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001002
Paul Bakker33b43f12013-08-20 11:48:36 +02001003 if( strlen( input_RR ) )
Gilles Peskine20edee72021-06-10 23:18:39 +02001004 TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001005
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001006 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Paul Bakker33b43f12013-08-20 11:48:36 +02001007 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001008 if( res == 0 )
1009 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001011 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001012
Paul Bakkerbd51b262014-07-10 15:26:12 +02001013exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1015 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001016}
Paul Bakker33b43f12013-08-20 11:48:36 +02001017/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001018
Paul Bakker33b43f12013-08-20 11:48:36 +02001019/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001020void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Chris Jonesaa850cd2020-12-03 11:35:41 +00001021 int radix_RR, char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001022{
1023 mbedtls_mpi A, E, N, RR, Z;
1024 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1025 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1026
Chris Jonesaa850cd2020-12-03 11:35:41 +00001027 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001028 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001029 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001030 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001031
1032 /* Set E to 2^(E_bytes - 1) + 1 */
1033 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1034 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001035 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001036
1037 /* Set N to 2^(N_bytes - 1) + 1 */
1038 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1039 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001040 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1041
1042 if( strlen( input_RR ) )
Gilles Peskine20edee72021-06-10 23:18:39 +02001043 TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001044
Chris Jonesaa850cd2020-12-03 11:35:41 +00001045 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001046
1047exit:
1048 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1049 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1050}
1051/* END_CASE */
1052
1053/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001054void mbedtls_mpi_inv_mod( int radix_X, char * input_X, int radix_Y,
1055 char * input_Y, int radix_A, char * input_A,
1056 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001057{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001059 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001061
Gilles Peskine20edee72021-06-10 23:18:39 +02001062 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1063 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
1064 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001066 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001067 if( res == 0 )
1068 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001070 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001071
Paul Bakkerbd51b262014-07-10 15:26:12 +02001072exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001073 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001074}
Paul Bakker33b43f12013-08-20 11:48:36 +02001075/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001076
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Azim Khanf1aaec92017-05-30 14:23:15 +01001078void mbedtls_mpi_is_prime( int radix_X, char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001079{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001081 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001082 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001083
Gilles Peskine20edee72021-06-10 23:18:39 +02001084 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001085 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001086 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001087
Paul Bakkerbd51b262014-07-10 15:26:12 +02001088exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001090}
Paul Bakker33b43f12013-08-20 11:48:36 +02001091/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001092
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001094void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001095 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001096{
1097 mbedtls_mpi X;
1098 int res;
1099 mbedtls_test_mpi_random rand;
1100
1101 mbedtls_mpi_init( &X );
1102 rand.data = witnesses;
1103 rand.pos = 0;
1104 rand.chunk_len = chunk_len;
1105
1106 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001107 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1108 mbedtls_test_mpi_miller_rabin_determinizer,
1109 &rand );
1110 TEST_ASSERT( res == 0 );
1111
1112 rand.data = witnesses;
1113 rand.pos = 0;
1114 rand.chunk_len = chunk_len;
1115
Janos Follatha0b67c22018-09-18 14:48:23 +01001116 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1117 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001118 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001119 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001120
1121exit:
1122 mbedtls_mpi_free( &X );
1123}
1124/* END_CASE */
1125
1126/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001127void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001128{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001130 int my_ret;
1131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001133
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001134 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1135 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001136 TEST_ASSERT( my_ret == ref_ret );
1137
1138 if( ref_ret == 0 )
1139 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001140 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001141
1142 TEST_ASSERT( actual_bits >= (size_t) bits );
1143 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
1144
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001145 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1146 mbedtls_test_rnd_std_rand,
1147 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001148 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001149 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001150 /* X = ( X - 1 ) / 2 */
1151 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001152 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1153 mbedtls_test_rnd_std_rand,
1154 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001155 }
1156 }
1157
Paul Bakkerbd51b262014-07-10 15:26:12 +02001158exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001160}
1161/* END_CASE */
1162
Paul Bakker33b43f12013-08-20 11:48:36 +02001163/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001164void mbedtls_mpi_shift_l( int radix_X, char * input_X, int shift_X,
1165 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001166{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167 mbedtls_mpi X, A;
1168 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001169
Gilles Peskine20edee72021-06-10 23:18:39 +02001170 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1171 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
1173 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001174
Paul Bakkerbd51b262014-07-10 15:26:12 +02001175exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001177}
Paul Bakker33b43f12013-08-20 11:48:36 +02001178/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001179
Paul Bakker33b43f12013-08-20 11:48:36 +02001180/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001181void mbedtls_mpi_shift_r( int radix_X, char * input_X, int shift_X,
1182 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001183{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184 mbedtls_mpi X, A;
1185 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001186
Gilles Peskine20edee72021-06-10 23:18:39 +02001187 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1188 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
1190 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001191
Paul Bakkerbd51b262014-07-10 15:26:12 +02001192exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001194}
Paul Bakker33b43f12013-08-20 11:48:36 +02001195/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001196
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001197/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001198void mpi_fill_random( int wanted_bytes, int rng_bytes,
1199 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001200{
1201 mbedtls_mpi X;
1202 int ret;
1203 size_t bytes_left = rng_bytes;
1204 mbedtls_mpi_init( &X );
1205
Gilles Peskine422e8672021-04-02 00:02:27 +02001206 if( before != 0 )
1207 {
1208 /* Set X to sign(before) * 2^(|before|-1) */
1209 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1210 if( before < 0 )
1211 before = - before;
1212 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1213 }
1214
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001215 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1216 f_rng_bytes_left, &bytes_left );
1217 TEST_ASSERT( ret == expected_ret );
1218
1219 if( expected_ret == 0 )
1220 {
1221 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1222 * as a big-endian representation of the number. We know when
1223 * our RNG function returns null bytes, so we know how many
1224 * leading zero bytes the number has. */
1225 size_t leading_zeros = 0;
1226 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1227 leading_zeros = 1;
1228 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1229 (size_t) wanted_bytes );
1230 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
1231 }
1232
1233exit:
1234 mbedtls_mpi_free( &X );
1235}
1236/* END_CASE */
1237
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001238/* BEGIN_CASE */
1239void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1240{
1241 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1242 * This function assumes that the value of bound is at least 2 and
1243 * that iterations is large enough that a one-in-2^iterations chance
1244 * effectively never occurs.
1245 */
1246
1247 mbedtls_mpi upper_bound;
1248 size_t n_bits;
1249 mbedtls_mpi result;
1250 size_t b;
1251 /* If upper_bound is small, stats[b] is the number of times the value b
1252 * has been generated. Otherwise stats[b] is the number of times a
1253 * value with bit b set has been generated. */
1254 size_t *stats = NULL;
1255 size_t stats_len;
1256 int full_stats;
1257 size_t i;
1258
1259 mbedtls_mpi_init( &upper_bound );
1260 mbedtls_mpi_init( &result );
1261
1262 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1263 bound_bytes->x, bound_bytes->len ) );
1264 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1265 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1266 * to be small enough that the probability of missing one value is
1267 * negligible given the number of iterations. It must be less than
1268 * 256 because some of the code below assumes that "small" values
1269 * fit in a byte. */
1270 if( n_bits <= 5 )
1271 {
1272 full_stats = 1;
1273 stats_len = bound_bytes->x[bound_bytes->len - 1];
1274 }
1275 else
1276 {
1277 full_stats = 0;
1278 stats_len = n_bits;
1279 }
1280 ASSERT_ALLOC( stats, stats_len );
1281
1282 for( i = 0; i < (size_t) iterations; i++ )
1283 {
1284 mbedtls_test_set_step( i );
1285 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1286 mbedtls_test_rnd_std_rand, NULL ) );
1287
1288 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1289 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1290 if( full_stats )
1291 {
1292 uint8_t value;
1293 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1294 TEST_ASSERT( value < stats_len );
1295 ++stats[value];
1296 }
1297 else
1298 {
1299 for( b = 0; b < n_bits; b++ )
1300 stats[b] += mbedtls_mpi_get_bit( &result, b );
1301 }
1302 }
1303
1304 if( full_stats )
1305 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001306 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001307 {
1308 mbedtls_test_set_step( 1000000 + b );
1309 /* Assert that each value has been reached at least once.
1310 * This is almost guaranteed if the iteration count is large
1311 * enough. This is a very crude way of checking the distribution.
1312 */
1313 TEST_ASSERT( stats[b] > 0 );
1314 }
1315 }
1316 else
1317 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001318 int statistically_safe_all_the_way =
1319 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001320 for( b = 0; b < n_bits; b++ )
1321 {
1322 mbedtls_test_set_step( 1000000 + b );
1323 /* Assert that each bit has been set in at least one result and
1324 * clear in at least one result. Provided that iterations is not
1325 * too small, it would be extremely unlikely for this not to be
1326 * the case if the results are uniformly distributed.
1327 *
1328 * As an exception, the top bit may legitimately never be set
1329 * if bound is a power of 2 or only slightly above.
1330 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001331 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001332 {
1333 TEST_ASSERT( stats[b] > 0 );
1334 }
1335 TEST_ASSERT( stats[b] < (size_t) iterations );
1336 }
1337 }
1338
1339exit:
1340 mbedtls_mpi_free( &upper_bound );
1341 mbedtls_mpi_free( &result );
1342 mbedtls_free( stats );
1343}
1344/* END_CASE */
1345
Gilles Peskine1e918f42021-03-29 22:14:51 +02001346/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001347void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001348{
1349 mbedtls_mpi upper_bound;
1350 mbedtls_mpi result;
1351
1352 mbedtls_mpi_init( &upper_bound );
1353 mbedtls_mpi_init( &result );
1354
Gilles Peskine422e8672021-04-02 00:02:27 +02001355 if( before != 0 )
1356 {
1357 /* Set result to sign(before) * 2^(|before|-1) */
1358 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1359 if( before < 0 )
1360 before = - before;
1361 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1362 }
1363
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001364 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1365 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1366 bound_bytes->x, bound_bytes->len ) );
1367 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1368 mbedtls_test_rnd_std_rand, NULL ) );
1369 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1370 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1371
1372exit:
1373 mbedtls_mpi_free( &upper_bound );
1374 mbedtls_mpi_free( &result );
1375}
1376/* END_CASE */
1377
1378/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001379void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1380{
1381 mbedtls_mpi upper_bound;
1382 mbedtls_mpi result;
1383 int actual_ret;
1384
1385 mbedtls_mpi_init( &upper_bound );
1386 mbedtls_mpi_init( &result );
1387
1388 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1389 bound_bytes->x, bound_bytes->len ) );
1390 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1391 mbedtls_test_rnd_std_rand, NULL );
1392 TEST_EQUAL( expected_ret, actual_ret );
1393
1394exit:
1395 mbedtls_mpi_free( &upper_bound );
1396 mbedtls_mpi_free( &result );
1397}
1398/* END_CASE */
1399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001401void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001402{
Andres AG93012e82016-09-09 09:10:28 +01001403 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001404}
Paul Bakker33b43f12013-08-20 11:48:36 +02001405/* END_CASE */