blob: 42dbafa2d7d2e7e87f79ed00b17f18d04a223387 [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 */
Azim Khan5fcca462018-06-29 11:05:32 +0100180void mbedtls_mpi_read_binary( data_t * buf, int radix_A, 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 ) );
Janos Follathe5670f22019-02-25 16:11:58 +0000191 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
Paul Bakker33b43f12013-08-20 11:48:36 +0200192 TEST_ASSERT( strcmp( (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 */
Janos Follatha778a942019-02-13 10:28:28 +0000200void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A )
201{
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 ) );
Janos Follathe5670f22019-02-25 16:11:58 +0000211 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000212 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
213
214exit:
215 mbedtls_mpi_free( &X );
216}
217/* END_CASE */
218
219/* BEGIN_CASE */
Azim Khand30ca132017-06-09 04:32:58 +0100220void mbedtls_mpi_write_binary( int radix_X, char * input_X,
Azim Khan5fcca462018-06-29 11:05:32 +0100221 data_t * input_A, int output_size,
Azim Khanf1aaec92017-05-30 14:23:15 +0100222 int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000223{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200224 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000225 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000226 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000227
228 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000229
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200230 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000231
Gilles Peskine20edee72021-06-10 23:18:39 +0200232 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200235 if( buflen > (size_t) output_size )
236 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000237
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200239 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000240 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000241
Ronald Cron2dbba992020-06-10 11:42:32 +0200242 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
243 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000244 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000245
Paul Bakkerbd51b262014-07-10 15:26:12 +0200246exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000248}
Paul Bakker33b43f12013-08-20 11:48:36 +0200249/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000250
Janos Follathe344d0f2019-02-19 16:17:40 +0000251/* BEGIN_CASE */
252void mbedtls_mpi_write_binary_le( int radix_X, char * input_X,
253 data_t * input_A, int output_size,
254 int result )
255{
256 mbedtls_mpi X;
257 unsigned char buf[1000];
258 size_t buflen;
259
260 memset( buf, 0x00, 1000 );
261
262 mbedtls_mpi_init( &X );
263
Gilles Peskine20edee72021-06-10 23:18:39 +0200264 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000265
266 buflen = mbedtls_mpi_size( &X );
267 if( buflen > (size_t) output_size )
268 buflen = (size_t) output_size;
269
270 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
271 if( result == 0)
272 {
273
Ronald Cron2dbba992020-06-10 11:42:32 +0200274 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
275 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000276 }
277
278exit:
279 mbedtls_mpi_free( &X );
280}
281/* END_CASE */
282
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200283/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khand30ca132017-06-09 04:32:58 +0100284void mbedtls_mpi_read_file( int radix_X, char * input_file,
Azim Khan5fcca462018-06-29 11:05:32 +0100285 data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000286{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200287 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000288 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000289 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000290 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000291 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000292
293 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000296
Paul Bakker33b43f12013-08-20 11:48:36 +0200297 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200298 TEST_ASSERT( file != NULL );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200299 ret = mbedtls_mpi_read_file( &X, radix_X, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000300 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000301 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
Paul Bakker33b43f12013-08-20 11:48:36 +0200303 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000304 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200305 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 buflen = mbedtls_mpi_size( &X );
307 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000308
Paul Bakkere896fea2009-07-06 06:40:23 +0000309
Ronald Cron2dbba992020-06-10 11:42:32 +0200310 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
311 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000312 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000313
Paul Bakkerbd51b262014-07-10 15:26:12 +0200314exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200315 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000316}
Paul Bakker33b43f12013-08-20 11:48:36 +0200317/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000318
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Azim Khanf1aaec92017-05-30 14:23:15 +0100320void mbedtls_mpi_write_file( int radix_X, char * input_X, int output_radix,
321 char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000322{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000324 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200325 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000326
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200327 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000328
Gilles Peskine20edee72021-06-10 23:18:39 +0200329 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000330
Paul Bakker33b43f12013-08-20 11:48:36 +0200331 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000332 TEST_ASSERT( file_out != NULL );
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200333 ret = mbedtls_mpi_write_file( NULL, &X, output_radix, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000334 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200335 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000336
Paul Bakker33b43f12013-08-20 11:48:36 +0200337 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000338 TEST_ASSERT( file_in != NULL );
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200339 ret = mbedtls_mpi_read_file( &Y, output_radix, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000340 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200341 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000344
Paul Bakkerbd51b262014-07-10 15:26:12 +0200345exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000347}
Paul Bakker33b43f12013-08-20 11:48:36 +0200348/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000349
Paul Bakker33b43f12013-08-20 11:48:36 +0200350/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100351void mbedtls_mpi_get_bit( int radix_X, char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000352{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 mbedtls_mpi X;
354 mbedtls_mpi_init( &X );
Gilles Peskine20edee72021-06-10 23:18:39 +0200355 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000357
Paul Bakkerbd51b262014-07-10 15:26:12 +0200358exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000360}
Paul Bakker33b43f12013-08-20 11:48:36 +0200361/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000362
Paul Bakker33b43f12013-08-20 11:48:36 +0200363/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100364void mbedtls_mpi_set_bit( int radix_X, char * input_X, int pos, int val,
365 int radix_Y, char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000366{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367 mbedtls_mpi X, Y;
368 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000369
Gilles Peskine20edee72021-06-10 23:18:39 +0200370 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
371 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100372 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
373
374 if( result == 0 )
375 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200376 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100377 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
378 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000379
Paul Bakkerbd51b262014-07-10 15:26:12 +0200380exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200381 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000382}
Paul Bakker33b43f12013-08-20 11:48:36 +0200383/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000384
Paul Bakker33b43f12013-08-20 11:48:36 +0200385/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100386void mbedtls_mpi_lsb( int radix_X, char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000387{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 mbedtls_mpi X;
389 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000390
Gilles Peskine20edee72021-06-10 23:18:39 +0200391 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000393
Paul Bakkerbd51b262014-07-10 15:26:12 +0200394exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000396}
Paul Bakker33b43f12013-08-20 11:48:36 +0200397/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000398
Paul Bakker33b43f12013-08-20 11:48:36 +0200399/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100400void mbedtls_mpi_bitlen( int radix_X, char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000401{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_mpi X;
403 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000404
Gilles Peskine20edee72021-06-10 23:18:39 +0200405 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200406 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000407
Paul Bakkerbd51b262014-07-10 15:26:12 +0200408exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000410}
Paul Bakker33b43f12013-08-20 11:48:36 +0200411/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000412
Paul Bakker33b43f12013-08-20 11:48:36 +0200413/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100414void mbedtls_mpi_gcd( int radix_X, char * input_X, int radix_Y,
415 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000416{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200417 mbedtls_mpi A, X, Y, Z;
418 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000419
Gilles Peskine20edee72021-06-10 23:18:39 +0200420 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
421 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
422 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200424 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200425 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000426
Paul Bakkerbd51b262014-07-10 15:26:12 +0200427exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000429}
Paul Bakker33b43f12013-08-20 11:48:36 +0200430/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000431
Paul Bakker33b43f12013-08-20 11:48:36 +0200432/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000434{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 mbedtls_mpi X;
436 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
439 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000440
Paul Bakkerbd51b262014-07-10 15:26:12 +0200441exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000443}
Paul Bakker33b43f12013-08-20 11:48:36 +0200444/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000445
Paul Bakker33b43f12013-08-20 11:48:36 +0200446/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100447void mbedtls_mpi_cmp_mpi( int radix_X, char * input_X, int radix_Y,
448 char * input_Y, int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000449{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 mbedtls_mpi X, Y;
451 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000452
Gilles Peskine20edee72021-06-10 23:18:39 +0200453 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
454 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000456
Paul Bakkerbd51b262014-07-10 15:26:12 +0200457exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200458 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000459}
Paul Bakker33b43f12013-08-20 11:48:36 +0200460/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000461
Paul Bakker33b43f12013-08-20 11:48:36 +0200462/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100463void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
464 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100465 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100466{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200467 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100468 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100469 mbedtls_mpi X, Y;
470 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
471
Gilles Peskine20edee72021-06-10 23:18:39 +0200472 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
473 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100474
Gilles Peskine9018b112020-01-21 16:30:53 +0100475 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
476 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100477
Janos Follath0e5532d2019-10-11 14:21:53 +0100478 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100479 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100480 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100481
482exit:
483 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
484}
485/* END_CASE */
486
487/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100488void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y,
489 char * input_Y, int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000490{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 mbedtls_mpi X, Y;
492 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000493
Gilles Peskine20edee72021-06-10 23:18:39 +0200494 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
495 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000497
Paul Bakkerbd51b262014-07-10 15:26:12 +0200498exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000500}
Paul Bakker33b43f12013-08-20 11:48:36 +0200501/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000502
Paul Bakker33b43f12013-08-20 11:48:36 +0200503/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200504void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000505{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200506 mbedtls_mpi src, dst;
507 mbedtls_mpi_init( &src );
508 mbedtls_mpi_init( &dst );
Paul Bakker367dae42009-06-28 21:50:27 +0000509
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200510 TEST_ASSERT( mbedtls_test_read_mpi( &src, 16, src_hex ) == 0 );
511 TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100512
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200513 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
514
515 TEST_ASSERT( sign_is_valid( &dst ) );
516 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000517
Paul Bakkerbd51b262014-07-10 15:26:12 +0200518exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200519 mbedtls_mpi_free( &src );
520 mbedtls_mpi_free( &dst );
Gilles Peskine7428b452020-01-20 21:01:51 +0100521}
522/* END_CASE */
523
524/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200525void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100526{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200527 mbedtls_mpi X, A;
528 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200529 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000530
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200531 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200533
534 TEST_ASSERT( mbedtls_test_read_mpi( &A, 16, input_X ) == 0 );
535 TEST_ASSERT( sign_is_valid( &X ) );
536 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000537
Paul Bakkerbd51b262014-07-10 15:26:12 +0200538exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200539 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200540 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000541}
Paul Bakker33b43f12013-08-20 11:48:36 +0200542/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000543
Paul Bakker33b43f12013-08-20 11:48:36 +0200544/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200545void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100546{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 mbedtls_mpi X;
548 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100549
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100551 TEST_ASSERT( used <= before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200552 memset( X.p, 0x2a, used * sizeof( mbedtls_mpi_uint ) );
553 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100554 TEST_ASSERT( X.n == (size_t) after );
555
Paul Bakkerbd51b262014-07-10 15:26:12 +0200556exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200557 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100558}
559/* END_CASE */
560
561/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100562void mbedtls_mpi_safe_cond_assign( int x_sign, char * x_str, int y_sign,
563 char * y_str )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100564{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200565 mbedtls_mpi X, Y, XX;
566 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &XX );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100567
Gilles Peskine20edee72021-06-10 23:18:39 +0200568 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x_str ) == 0 );
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100569 X.s = x_sign;
Gilles Peskine20edee72021-06-10 23:18:39 +0200570 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y_str ) == 0 );
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100571 Y.s = y_sign;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100573
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200574 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200575 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100577
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &X, &Y, 1 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200579 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100581
Paul Bakkerbd51b262014-07-10 15:26:12 +0200582exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200583 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &XX );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100584}
585/* END_CASE */
586
587/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100588void mbedtls_mpi_safe_cond_swap( int x_sign, char * x_str, int y_sign,
589 char * y_str )
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100590{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_mpi X, Y, XX, YY;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100592
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200593 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
594 mbedtls_mpi_init( &XX ); mbedtls_mpi_init( &YY );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100595
Gilles Peskine20edee72021-06-10 23:18:39 +0200596 TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, x_str ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100597 X.s = x_sign;
Gilles Peskine20edee72021-06-10 23:18:39 +0200598 TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, y_str ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100599 Y.s = y_sign;
600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601 TEST_ASSERT( mbedtls_mpi_copy( &XX, &X ) == 0 );
602 TEST_ASSERT( mbedtls_mpi_copy( &YY, &Y ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100603
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200605 TEST_ASSERT( sign_is_valid( &X ) );
606 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &XX ) == 0 );
608 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &YY ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100609
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200610 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200611 TEST_ASSERT( sign_is_valid( &X ) );
612 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200613 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &XX ) == 0 );
614 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &YY ) == 0 );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100615
Paul Bakkerbd51b262014-07-10 15:26:12 +0200616exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
618 mbedtls_mpi_free( &XX ); mbedtls_mpi_free( &YY );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100619}
620/* END_CASE */
621
622/* BEGIN_CASE */
Gilles Peskine7428b452020-01-20 21:01:51 +0100623void mbedtls_mpi_swap_sint( int input_X, int input_Y )
Paul Bakker367dae42009-06-28 21:50:27 +0000624{
Gilles Peskine7428b452020-01-20 21:01:51 +0100625 mbedtls_mpi X, Y;
626 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000627
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200628 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0 );
629 TEST_ASSERT( mbedtls_mpi_lset( &Y, input_Y ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100630 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_X ) == 0 );
631 TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_Y ) == 0 );
632
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200633 mbedtls_mpi_swap( &X, &Y );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200634 TEST_ASSERT( sign_is_valid( &X ) );
635 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine7428b452020-01-20 21:01:51 +0100636 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_Y ) == 0 );
637 TEST_ASSERT( mbedtls_mpi_cmp_int( &Y, input_X ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000638
Paul Bakkerbd51b262014-07-10 15:26:12 +0200639exit:
Gilles Peskine7428b452020-01-20 21:01:51 +0100640 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
641}
642/* END_CASE */
643
644/* BEGIN_CASE */
645void mbedtls_mpi_swap_binary( data_t *input_X, data_t *input_Y )
646{
647 mbedtls_mpi X, Y, X0, Y0;
648 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
649 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
650
Gilles Peskine9a6ecee2020-02-03 16:15:47 +0100651 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
652 TEST_ASSERT( mbedtls_mpi_read_binary( &Y, input_Y->x, input_Y->len ) == 0 );
653 TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
654 TEST_ASSERT( mbedtls_mpi_read_binary( &Y0, input_Y->x, input_Y->len ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100655
656 mbedtls_mpi_swap( &X, &Y );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200657 TEST_ASSERT( sign_is_valid( &X ) );
658 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine7428b452020-01-20 21:01:51 +0100659 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
660 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
661
662exit:
663 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
664 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
665}
666/* END_CASE */
667
668/* BEGIN_CASE */
669void mpi_swap_self( data_t *input_X )
670{
671 mbedtls_mpi X, X0;
672 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
673
Gilles Peskine9a6ecee2020-02-03 16:15:47 +0100674 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
675 TEST_ASSERT( mbedtls_mpi_read_binary( &X0, input_X->x, input_X->len ) == 0 );
Gilles Peskine7428b452020-01-20 21:01:51 +0100676
677 mbedtls_mpi_swap( &X, &X );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200678 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine7428b452020-01-20 21:01:51 +0100679 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
680
681exit:
682 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000683}
Paul Bakker33b43f12013-08-20 11:48:36 +0200684/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000685
Paul Bakker33b43f12013-08-20 11:48:36 +0200686/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100687void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
688 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000689{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 mbedtls_mpi X, Y, Z, A;
691 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000692
Gilles Peskine20edee72021-06-10 23:18:39 +0200693 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
694 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
695 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200696 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200697 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000699
Gilles Peskine56f943a2020-07-23 01:18:11 +0200700 /* result == first operand */
701 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200702 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200703 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200704 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200705
706 /* result == second operand */
707 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200708 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200709 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
710
Paul Bakkerbd51b262014-07-10 15:26:12 +0200711exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000713}
Paul Bakker33b43f12013-08-20 11:48:36 +0200714/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000715
Paul Bakker33b43f12013-08-20 11:48:36 +0200716/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100717void mbedtls_mpi_add_mpi_inplace( int radix_X, char * input_X, int radix_A,
718 char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100719{
720 mbedtls_mpi X, A;
721 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
722
Gilles Peskine20edee72021-06-10 23:18:39 +0200723 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100724
Gilles Peskine20edee72021-06-10 23:18:39 +0200725 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100726 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
727 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200728 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100729
Gilles Peskine20edee72021-06-10 23:18:39 +0200730 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100731 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200732 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100733 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
734
Gilles Peskine20edee72021-06-10 23:18:39 +0200735 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100736 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200737 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100738 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
739
740exit:
741 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
742}
743/* END_CASE */
744
745
746/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100747void mbedtls_mpi_add_abs( int radix_X, char * input_X, int radix_Y,
748 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000749{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750 mbedtls_mpi X, Y, Z, A;
751 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000752
Gilles Peskine20edee72021-06-10 23:18:39 +0200753 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
754 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
755 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200757 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200758 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000759
Gilles Peskine56f943a2020-07-23 01:18:11 +0200760 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200761 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200762 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200763 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200764 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200765
766 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200768 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200769 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000770
Paul Bakkerbd51b262014-07-10 15:26:12 +0200771exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200772 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000773}
Paul Bakker33b43f12013-08-20 11:48:36 +0200774/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000775
Paul Bakker33b43f12013-08-20 11:48:36 +0200776/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100777void mbedtls_mpi_add_int( int radix_X, char * input_X, int input_Y,
778 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000779{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780 mbedtls_mpi X, Z, A;
781 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000782
Gilles Peskine20edee72021-06-10 23:18:39 +0200783 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
784 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200785 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200786 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200787 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000788
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( &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_mpi( int radix_X, char * input_X, int radix_Y,
796 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000797{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 mbedtls_mpi X, Y, Z, A;
799 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000800
Gilles Peskine20edee72021-06-10 23:18:39 +0200801 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
802 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
803 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200804 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200805 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000807
Gilles Peskine56f943a2020-07-23 01:18:11 +0200808 /* result == first operand */
809 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200810 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200811 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200812 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200813
814 /* result == second operand */
815 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200816 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200817 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
818
Paul Bakkerbd51b262014-07-10 15:26:12 +0200819exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200820 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000821}
Paul Bakker33b43f12013-08-20 11:48:36 +0200822/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000823
Paul Bakker33b43f12013-08-20 11:48:36 +0200824/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100825void mbedtls_mpi_sub_abs( int radix_X, char * input_X, int radix_Y,
826 char * input_Y, int radix_A, char * input_A,
827 int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000828{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000830 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200831 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000832
Gilles Peskine20edee72021-06-10 23:18:39 +0200833 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
834 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
835 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100836
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200838 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200839 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000840 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000842
Gilles Peskine56f943a2020-07-23 01:18:11 +0200843 /* result == first operand */
844 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200845 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200846 if( sub_result == 0 )
847 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Gilles Peskine20edee72021-06-10 23:18:39 +0200848 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200849
850 /* result == second operand */
851 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200852 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200853 if( sub_result == 0 )
854 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
855
Paul Bakkerbd51b262014-07-10 15:26:12 +0200856exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000858}
Paul Bakker33b43f12013-08-20 11:48:36 +0200859/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000860
Paul Bakker33b43f12013-08-20 11:48:36 +0200861/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100862void mbedtls_mpi_sub_int( int radix_X, char * input_X, int input_Y,
863 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000864{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200865 mbedtls_mpi X, Z, A;
866 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000867
Gilles Peskine20edee72021-06-10 23:18:39 +0200868 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
869 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200871 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200872 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000873
Paul Bakkerbd51b262014-07-10 15:26:12 +0200874exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000876}
Paul Bakker33b43f12013-08-20 11:48:36 +0200877/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000878
Paul Bakker33b43f12013-08-20 11:48:36 +0200879/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100880void mbedtls_mpi_mul_mpi( int radix_X, char * input_X, int radix_Y,
881 char * input_Y, int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000882{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_mpi X, Y, Z, A;
884 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000885
Gilles Peskine20edee72021-06-10 23:18:39 +0200886 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
887 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
888 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200890 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200891 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000892
Paul Bakkerbd51b262014-07-10 15:26:12 +0200893exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000895}
Paul Bakker33b43f12013-08-20 11:48:36 +0200896/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000897
Paul Bakker33b43f12013-08-20 11:48:36 +0200898/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100899void mbedtls_mpi_mul_int( int radix_X, char * input_X, int input_Y,
900 int radix_A, char * input_A,
901 char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000902{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_mpi X, Z, A;
904 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000905
Gilles Peskine20edee72021-06-10 23:18:39 +0200906 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
907 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200908 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200909 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200910 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200912 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200914 else
915 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000916
Paul Bakkerbd51b262014-07-10 15:26:12 +0200917exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200918 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000919}
Paul Bakker33b43f12013-08-20 11:48:36 +0200920/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000921
Paul Bakker33b43f12013-08-20 11:48:36 +0200922/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100923void mbedtls_mpi_div_mpi( int radix_X, char * input_X, int radix_Y,
924 char * input_Y, int radix_A, char * input_A,
925 int radix_B, char * input_B, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000926{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000928 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200929 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
930 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000931
Gilles Peskine20edee72021-06-10 23:18:39 +0200932 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
933 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
934 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
935 TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200936 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200937 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000938 if( res == 0 )
939 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200940 TEST_ASSERT( sign_is_valid( &Q ) );
941 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200942 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
943 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000944 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000945
Paul Bakkerbd51b262014-07-10 15:26:12 +0200946exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
948 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000949}
Paul Bakker33b43f12013-08-20 11:48:36 +0200950/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000951
Paul Bakker33b43f12013-08-20 11:48:36 +0200952/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100953void mbedtls_mpi_div_int( int radix_X, char * input_X, int input_Y,
954 int radix_A, char * input_A, int radix_B,
955 char * input_B, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000956{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000958 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
960 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000961
Gilles Peskine20edee72021-06-10 23:18:39 +0200962 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
963 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
964 TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200966 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000967 if( res == 0 )
968 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200969 TEST_ASSERT( sign_is_valid( &Q ) );
970 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
972 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000973 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000974
Paul Bakkerbd51b262014-07-10 15:26:12 +0200975exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
977 mbedtls_mpi_free( &B );
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 */
Azim Khanf1aaec92017-05-30 14:23:15 +0100982void mbedtls_mpi_mod_mpi( int radix_X, char * input_X, int radix_Y,
983 char * input_Y, int radix_A, char * input_A,
984 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000985{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000987 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200988 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000989
Gilles Peskine20edee72021-06-10 23:18:39 +0200990 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
991 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
992 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200994 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000995 if( res == 0 )
996 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200997 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200998 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000999 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001000
Paul Bakkerbd51b262014-07-10 15:26:12 +02001001exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001002 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001003}
Paul Bakker33b43f12013-08-20 11:48:36 +02001004/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001005
Paul Bakker33b43f12013-08-20 11:48:36 +02001006/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001007void mbedtls_mpi_mod_int( int radix_X, char * input_X, int input_Y,
1008 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001009{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001010 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001011 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001012 mbedtls_mpi_uint r;
1013 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001014
Gilles Peskine20edee72021-06-10 23:18:39 +02001015 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001017 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001018 if( res == 0 )
1019 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001020 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001021 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001022
Paul Bakkerbd51b262014-07-10 15:26:12 +02001023exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001024 mbedtls_mpi_free( &X );
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 */
Azim Khanf1aaec92017-05-30 14:23:15 +01001029void mbedtls_mpi_exp_mod( int radix_A, char * input_A, int radix_E,
1030 char * input_E, int radix_N, char * input_N,
1031 int radix_RR, char * input_RR, int radix_X,
1032 char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001033{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001035 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1037 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001038
Gilles Peskine20edee72021-06-10 23:18:39 +02001039 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
1040 TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
1041 TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
1042 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001043
Paul Bakker33b43f12013-08-20 11:48:36 +02001044 if( strlen( input_RR ) )
Gilles Peskine20edee72021-06-10 23:18:39 +02001045 TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001046
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Paul Bakker33b43f12013-08-20 11:48:36 +02001048 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001049 if( res == 0 )
1050 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001051 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001052 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001053 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001054
Paul Bakkerbd51b262014-07-10 15:26:12 +02001055exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1057 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001058}
Paul Bakker33b43f12013-08-20 11:48:36 +02001059/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001060
Paul Bakker33b43f12013-08-20 11:48:36 +02001061/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001062void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Chris Jonesaa850cd2020-12-03 11:35:41 +00001063 int radix_RR, char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001064{
1065 mbedtls_mpi A, E, N, RR, Z;
1066 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1067 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1068
Chris Jonesaa850cd2020-12-03 11:35:41 +00001069 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001070 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001071 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001072 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001073
1074 /* Set E to 2^(E_bytes - 1) + 1 */
1075 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1076 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001077 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001078
1079 /* Set N to 2^(N_bytes - 1) + 1 */
1080 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1081 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001082 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1083
1084 if( strlen( input_RR ) )
Gilles Peskine20edee72021-06-10 23:18:39 +02001085 TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001086
Chris Jonesaa850cd2020-12-03 11:35:41 +00001087 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001088
1089exit:
1090 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1091 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1092}
1093/* END_CASE */
1094
1095/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001096void mbedtls_mpi_inv_mod( int radix_X, char * input_X, int radix_Y,
1097 char * input_Y, int radix_A, char * input_A,
1098 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001099{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001101 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001103
Gilles Peskine20edee72021-06-10 23:18:39 +02001104 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1105 TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
1106 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001108 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001109 if( res == 0 )
1110 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001111 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001113 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001114
Paul Bakkerbd51b262014-07-10 15:26:12 +02001115exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001117}
Paul Bakker33b43f12013-08-20 11:48:36 +02001118/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Azim Khanf1aaec92017-05-30 14:23:15 +01001121void mbedtls_mpi_is_prime( int radix_X, char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001122{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001123 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001124 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001126
Gilles Peskine20edee72021-06-10 23:18:39 +02001127 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001128 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001129 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001130
Paul Bakkerbd51b262014-07-10 15:26:12 +02001131exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001133}
Paul Bakker33b43f12013-08-20 11:48:36 +02001134/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001137void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001138 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001139{
1140 mbedtls_mpi X;
1141 int res;
1142 mbedtls_test_mpi_random rand;
1143
1144 mbedtls_mpi_init( &X );
1145 rand.data = witnesses;
1146 rand.pos = 0;
1147 rand.chunk_len = chunk_len;
1148
1149 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001150 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1151 mbedtls_test_mpi_miller_rabin_determinizer,
1152 &rand );
1153 TEST_ASSERT( res == 0 );
1154
1155 rand.data = witnesses;
1156 rand.pos = 0;
1157 rand.chunk_len = chunk_len;
1158
Janos Follatha0b67c22018-09-18 14:48:23 +01001159 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1160 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001161 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001162 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001163
1164exit:
1165 mbedtls_mpi_free( &X );
1166}
1167/* END_CASE */
1168
1169/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001170void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001171{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001173 int my_ret;
1174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001176
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001177 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1178 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001179 TEST_ASSERT( my_ret == ref_ret );
1180
1181 if( ref_ret == 0 )
1182 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001183 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001184
1185 TEST_ASSERT( actual_bits >= (size_t) bits );
1186 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001187 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001188
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001189 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1190 mbedtls_test_rnd_std_rand,
1191 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001192 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001193 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001194 /* X = ( X - 1 ) / 2 */
1195 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001196 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1197 mbedtls_test_rnd_std_rand,
1198 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001199 }
1200 }
1201
Paul Bakkerbd51b262014-07-10 15:26:12 +02001202exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001204}
1205/* END_CASE */
1206
Paul Bakker33b43f12013-08-20 11:48:36 +02001207/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001208void mbedtls_mpi_shift_l( int radix_X, char * input_X, int shift_X,
1209 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001210{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211 mbedtls_mpi X, A;
1212 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001213
Gilles Peskine20edee72021-06-10 23:18:39 +02001214 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1215 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001217 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001218 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001219
Paul Bakkerbd51b262014-07-10 15:26:12 +02001220exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001221 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001222}
Paul Bakker33b43f12013-08-20 11:48:36 +02001223/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001224
Paul Bakker33b43f12013-08-20 11:48:36 +02001225/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +01001226void mbedtls_mpi_shift_r( int radix_X, char * input_X, int shift_X,
1227 int radix_A, char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001228{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001229 mbedtls_mpi X, A;
1230 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001231
Gilles Peskine20edee72021-06-10 23:18:39 +02001232 TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1233 TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001235 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001236 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001237
Paul Bakkerbd51b262014-07-10 15:26:12 +02001238exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001239 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001240}
Paul Bakker33b43f12013-08-20 11:48:36 +02001241/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001242
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001243/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001244void mpi_fill_random( int wanted_bytes, int rng_bytes,
1245 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001246{
1247 mbedtls_mpi X;
1248 int ret;
1249 size_t bytes_left = rng_bytes;
1250 mbedtls_mpi_init( &X );
1251
Gilles Peskine422e8672021-04-02 00:02:27 +02001252 if( before != 0 )
1253 {
1254 /* Set X to sign(before) * 2^(|before|-1) */
1255 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1256 if( before < 0 )
1257 before = - before;
1258 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1259 }
1260
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001261 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1262 f_rng_bytes_left, &bytes_left );
1263 TEST_ASSERT( ret == expected_ret );
1264
1265 if( expected_ret == 0 )
1266 {
1267 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1268 * as a big-endian representation of the number. We know when
1269 * our RNG function returns null bytes, so we know how many
1270 * leading zero bytes the number has. */
1271 size_t leading_zeros = 0;
1272 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1273 leading_zeros = 1;
1274 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1275 (size_t) wanted_bytes );
1276 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001277 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001278 }
1279
1280exit:
1281 mbedtls_mpi_free( &X );
1282}
1283/* END_CASE */
1284
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001285/* BEGIN_CASE */
1286void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1287{
1288 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1289 * This function assumes that the value of bound is at least 2 and
1290 * that iterations is large enough that a one-in-2^iterations chance
1291 * effectively never occurs.
1292 */
1293
1294 mbedtls_mpi upper_bound;
1295 size_t n_bits;
1296 mbedtls_mpi result;
1297 size_t b;
1298 /* If upper_bound is small, stats[b] is the number of times the value b
1299 * has been generated. Otherwise stats[b] is the number of times a
1300 * value with bit b set has been generated. */
1301 size_t *stats = NULL;
1302 size_t stats_len;
1303 int full_stats;
1304 size_t i;
1305
1306 mbedtls_mpi_init( &upper_bound );
1307 mbedtls_mpi_init( &result );
1308
1309 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1310 bound_bytes->x, bound_bytes->len ) );
1311 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1312 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1313 * to be small enough that the probability of missing one value is
1314 * negligible given the number of iterations. It must be less than
1315 * 256 because some of the code below assumes that "small" values
1316 * fit in a byte. */
1317 if( n_bits <= 5 )
1318 {
1319 full_stats = 1;
1320 stats_len = bound_bytes->x[bound_bytes->len - 1];
1321 }
1322 else
1323 {
1324 full_stats = 0;
1325 stats_len = n_bits;
1326 }
1327 ASSERT_ALLOC( stats, stats_len );
1328
1329 for( i = 0; i < (size_t) iterations; i++ )
1330 {
1331 mbedtls_test_set_step( i );
1332 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1333 mbedtls_test_rnd_std_rand, NULL ) );
1334
Gilles Peskinedffc7102021-06-10 15:34:15 +02001335 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001336 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1337 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1338 if( full_stats )
1339 {
1340 uint8_t value;
1341 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1342 TEST_ASSERT( value < stats_len );
1343 ++stats[value];
1344 }
1345 else
1346 {
1347 for( b = 0; b < n_bits; b++ )
1348 stats[b] += mbedtls_mpi_get_bit( &result, b );
1349 }
1350 }
1351
1352 if( full_stats )
1353 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001354 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001355 {
1356 mbedtls_test_set_step( 1000000 + b );
1357 /* Assert that each value has been reached at least once.
1358 * This is almost guaranteed if the iteration count is large
1359 * enough. This is a very crude way of checking the distribution.
1360 */
1361 TEST_ASSERT( stats[b] > 0 );
1362 }
1363 }
1364 else
1365 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001366 int statistically_safe_all_the_way =
1367 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001368 for( b = 0; b < n_bits; b++ )
1369 {
1370 mbedtls_test_set_step( 1000000 + b );
1371 /* Assert that each bit has been set in at least one result and
1372 * clear in at least one result. Provided that iterations is not
1373 * too small, it would be extremely unlikely for this not to be
1374 * the case if the results are uniformly distributed.
1375 *
1376 * As an exception, the top bit may legitimately never be set
1377 * if bound is a power of 2 or only slightly above.
1378 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001379 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001380 {
1381 TEST_ASSERT( stats[b] > 0 );
1382 }
1383 TEST_ASSERT( stats[b] < (size_t) iterations );
1384 }
1385 }
1386
1387exit:
1388 mbedtls_mpi_free( &upper_bound );
1389 mbedtls_mpi_free( &result );
1390 mbedtls_free( stats );
1391}
1392/* END_CASE */
1393
Gilles Peskine1e918f42021-03-29 22:14:51 +02001394/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001395void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001396{
1397 mbedtls_mpi upper_bound;
1398 mbedtls_mpi result;
1399
1400 mbedtls_mpi_init( &upper_bound );
1401 mbedtls_mpi_init( &result );
1402
Gilles Peskine422e8672021-04-02 00:02:27 +02001403 if( before != 0 )
1404 {
1405 /* Set result to sign(before) * 2^(|before|-1) */
1406 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1407 if( before < 0 )
1408 before = - before;
1409 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1410 }
1411
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001412 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1413 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1414 bound_bytes->x, bound_bytes->len ) );
1415 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1416 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001417 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001418 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1419 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1420
1421exit:
1422 mbedtls_mpi_free( &upper_bound );
1423 mbedtls_mpi_free( &result );
1424}
1425/* END_CASE */
1426
1427/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001428void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1429{
1430 mbedtls_mpi upper_bound;
1431 mbedtls_mpi result;
1432 int actual_ret;
1433
1434 mbedtls_mpi_init( &upper_bound );
1435 mbedtls_mpi_init( &result );
1436
1437 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1438 bound_bytes->x, bound_bytes->len ) );
1439 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1440 mbedtls_test_rnd_std_rand, NULL );
1441 TEST_EQUAL( expected_ret, actual_ret );
1442
1443exit:
1444 mbedtls_mpi_free( &upper_bound );
1445 mbedtls_mpi_free( &result );
1446}
1447/* END_CASE */
1448
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001450void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001451{
Andres AG93012e82016-09-09 09:10:28 +01001452 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001453}
Paul Bakker33b43f12013-08-20 11:48:36 +02001454/* END_CASE */