blob: 5c3d776f09bf6095033306bb636295341c748014 [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 Follath23bdeca2022-07-22 18:24:06 +01004#include "constant_time_internal.h"
5#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01006
Chris Jonese64a46f2020-12-03 17:44:03 +00007#if MBEDTLS_MPI_MAX_BITS > 792
8#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +00009#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020010
Gilles Peskinedffc7102021-06-10 15:34:15 +020011/* Check the validity of the sign bit in an MPI object. Reject representations
12 * that are not supported by the rest of the library and indicate a bug when
13 * constructing the value. */
14static int sign_is_valid( const mbedtls_mpi *X )
15{
16 if( X->s != 1 && X->s != -1 )
17 return( 0 ); // invalid sign bit, e.g. 0
18 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
19 return( 0 ); // negative zero
20 return( 1 );
21}
22
Janos Follath64eca052018-09-05 17:04:49 +010023typedef struct mbedtls_test_mpi_random
24{
25 data_t *data;
26 size_t pos;
27 size_t chunk_len;
28} mbedtls_test_mpi_random;
29
30/*
31 * This function is called by the Miller-Rabin primality test each time it
32 * chooses a random witness. The witnesses (or non-witnesses as provided by the
33 * test) are stored in the data member of the state structure. Each number is in
34 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
35 */
36int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
37 unsigned char* buf,
38 size_t len )
39{
40 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
41
42 if( random == NULL || random->data->x == NULL || buf == NULL )
43 return( -1 );
44
45 if( random->pos + random->chunk_len > random->data->len
46 || random->chunk_len > len )
47 {
48 return( -1 );
49 }
50
51 memset( buf, 0, len );
52
53 /* The witness is written to the end of the buffer, since the buffer is
54 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
55 * Writing the witness to the start of the buffer would result in the
56 * buffer being 'witness 000...000', which would be treated as
57 * witness * 2^n for some n. */
58 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
59 random->chunk_len );
60
61 random->pos += random->chunk_len;
62
63 return( 0 );
64}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010065
66/* Random generator that is told how many bytes to return. */
67static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
68{
69 size_t *bytes_left = state;
70 size_t i;
71 for( i = 0; i < len; i++ )
72 {
73 if( *bytes_left == 0 )
74 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
75 buf[i] = *bytes_left & 0xff;
76 --( *bytes_left );
77 }
78 return( 0 );
79}
80
Gilles Peskineeedefa52021-04-13 19:50:04 +020081/* Test whether bytes represents (in big-endian base 256) a number b that
82 * is significantly above a power of 2. That is, b must not have a long run
83 * of unset bits after the most significant bit.
84 *
85 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
86 * This function returns 1 if, when drawing a number between 0 and b,
87 * the probability that this number is at least 2^n is not negligible.
88 * This probability is (b - 2^n) / b and this function checks that this
89 * number is above some threshold A. The threshold value is heuristic and
90 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020091 */
92static int is_significantly_above_a_power_of_2( data_t *bytes )
93{
94 const uint8_t *p = bytes->x;
95 size_t len = bytes->len;
96 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +020097
98 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +020099 while( len > 0 && p[0] == 0 )
100 {
101 ++p;
102 --len;
103 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200104 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200105 if( len == 0 )
106 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200107 /* Extract the (up to) 2 most significant bytes */
108 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200109 x = p[0];
110 else
111 x = ( p[0] << 8 ) | p[1];
112
Gilles Peskineeedefa52021-04-13 19:50:04 +0200113 /* Shift the most significant bit of x to position 8 and mask it out */
114 while( ( x & 0xfe00 ) != 0 )
115 x >>= 1;
116 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200117
Gilles Peskineeedefa52021-04-13 19:50:04 +0200118 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
119 * a power of 2 iff x is significantly above 0 compared to 2^8.
120 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
121 * description above. */
122 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200123}
124
Paul Bakker33b43f12013-08-20 11:48:36 +0200125/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000126
Paul Bakker33b43f12013-08-20 11:48:36 +0200127/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200129 * END_DEPENDENCIES
130 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000131
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000132/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100133void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200134{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200135 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200136
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200137 mbedtls_mpi_init( &X );
138 mbedtls_mpi_init( &Y );
139 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200140
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200141 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
142 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200143 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200144 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200145
146exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200147 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200148}
149/* END_CASE */
150
151/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100152void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
153 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200154 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000155{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000157 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100158 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200160 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000161
Janos Follath04dadb72019-03-06 12:29:37 +0000162 memset( str, '!', sizeof( str ) );
163
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200164 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200165 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000166 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200167 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100168 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200169 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000170 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200171 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000172 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000173 }
174 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000175
Paul Bakkerbd51b262014-07-10 15:26:12 +0200176exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000178}
Paul Bakker33b43f12013-08-20 11:48:36 +0200179/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000180
Paul Bakker33b43f12013-08-20 11:48:36 +0200181/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100182void mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000183{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200184 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000185 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100186 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000189
Paul Bakkere896fea2009-07-06 06:40:23 +0000190
Azim Khand30ca132017-06-09 04:32:58 +0100191 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200192 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100193 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100194 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000195
Paul Bakkerbd51b262014-07-10 15:26:12 +0200196exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000198}
Paul Bakker33b43f12013-08-20 11:48:36 +0200199/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000200
Paul Bakker33b43f12013-08-20 11:48:36 +0200201/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100202void mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000203{
204 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000205 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000206 size_t len;
207
208 mbedtls_mpi_init( &X );
209
210
211 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200212 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100213 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100214 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000215
216exit:
217 mbedtls_mpi_free( &X );
218}
219/* END_CASE */
220
221/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100222void mpi_write_binary( char * input_X, data_t * input_A,
223 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000224{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200225 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000226 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000227 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000228
229 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000230
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200231 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000232
Werner Lewis19b4cd82022-07-07 11:02:27 +0100233 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100234
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200236 if( buflen > (size_t) output_size )
237 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000238
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200240 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000241 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000242
Ronald Cron2dbba992020-06-10 11:42:32 +0200243 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
244 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000245 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000246
Paul Bakkerbd51b262014-07-10 15:26:12 +0200247exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000249}
Paul Bakker33b43f12013-08-20 11:48:36 +0200250/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000251
Janos Follathe344d0f2019-02-19 16:17:40 +0000252/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100253void mpi_write_binary_le( char * input_X, data_t * input_A,
254 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000255{
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
Werner Lewis19b4cd82022-07-07 11:02:27 +0100264 TEST_ASSERT( mbedtls_test_read_mpi( &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 */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100284void mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000285{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000287 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000288 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000289 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000290 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000291
292 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000295
Paul Bakker33b43f12013-08-20 11:48:36 +0200296 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200297 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100298 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000299 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000300 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000301
Paul Bakker33b43f12013-08-20 11:48:36 +0200302 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000303 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200304 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 buflen = mbedtls_mpi_size( &X );
306 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000307
Paul Bakkere896fea2009-07-06 06:40:23 +0000308
Ronald Cron2dbba992020-06-10 11:42:32 +0200309 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
310 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000311 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000312
Paul Bakkerbd51b262014-07-10 15:26:12 +0200313exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200314 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000315}
Paul Bakker33b43f12013-08-20 11:48:36 +0200316/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000317
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100319void mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000320{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000322 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200323 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000324
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000326
Werner Lewis19b4cd82022-07-07 11:02:27 +0100327 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000328
Paul Bakker33b43f12013-08-20 11:48:36 +0200329 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000330 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100331 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000332 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200333 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000334
Paul Bakker33b43f12013-08-20 11:48:36 +0200335 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000336 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100337 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000338 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200339 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000340
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000342
Paul Bakkerbd51b262014-07-10 15:26:12 +0200343exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000345}
Paul Bakker33b43f12013-08-20 11:48:36 +0200346/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000347
Paul Bakker33b43f12013-08-20 11:48:36 +0200348/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100349void mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000350{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200351 mbedtls_mpi X;
352 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100353 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000355
Paul Bakkerbd51b262014-07-10 15:26:12 +0200356exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200357 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000358}
Paul Bakker33b43f12013-08-20 11:48:36 +0200359/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000360
Paul Bakker33b43f12013-08-20 11:48:36 +0200361/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100362void mpi_set_bit( char * input_X, int pos, int val,
363 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000364{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 mbedtls_mpi X, Y;
366 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000367
Werner Lewis19b4cd82022-07-07 11:02:27 +0100368 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
369 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100370 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
371
372 if( result == 0 )
373 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200374 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100375 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
376 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000377
Paul Bakkerbd51b262014-07-10 15:26:12 +0200378exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000380}
Paul Bakker33b43f12013-08-20 11:48:36 +0200381/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000382
Paul Bakker33b43f12013-08-20 11:48:36 +0200383/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100384void mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000385{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_mpi X;
387 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000388
Werner Lewis19b4cd82022-07-07 11:02:27 +0100389 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000391
Paul Bakkerbd51b262014-07-10 15:26:12 +0200392exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000394}
Paul Bakker33b43f12013-08-20 11:48:36 +0200395/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000396
Paul Bakker33b43f12013-08-20 11:48:36 +0200397/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100398void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000399{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 mbedtls_mpi X;
401 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000402
Werner Lewis19b4cd82022-07-07 11:02:27 +0100403 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200404 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000405
Paul Bakkerbd51b262014-07-10 15:26:12 +0200406exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200407 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000408}
Paul Bakker33b43f12013-08-20 11:48:36 +0200409/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000410
Paul Bakker33b43f12013-08-20 11:48:36 +0200411/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100412void mpi_gcd( char * input_X, char * input_Y,
413 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000414{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_mpi A, X, Y, Z;
416 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000417
Werner Lewis19b4cd82022-07-07 11:02:27 +0100418 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
419 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
420 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200422 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000424
Paul Bakkerbd51b262014-07-10 15:26:12 +0200425exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000427}
Paul Bakker33b43f12013-08-20 11:48:36 +0200428/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000429
Paul Bakker33b43f12013-08-20 11:48:36 +0200430/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100431void mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000432{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 mbedtls_mpi X;
434 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000435
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200436 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
437 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
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 );
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 */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100445void mpi_cmp_mpi( char * input_X, char * input_Y,
446 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000447{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 mbedtls_mpi X, Y;
449 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000450
Werner Lewis19b4cd82022-07-07 11:02:27 +0100451 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
452 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200453 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000454
Paul Bakkerbd51b262014-07-10 15:26:12 +0200455exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000457}
Paul Bakker33b43f12013-08-20 11:48:36 +0200458/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000459
Paul Bakker33b43f12013-08-20 11:48:36 +0200460/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100461void mpi_lt_mpi_ct( int size_X, char * input_X,
462 int size_Y, char * input_Y,
463 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100464{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200465 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100466 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100467 mbedtls_mpi X, Y;
468 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
469
Werner Lewis19b4cd82022-07-07 11:02:27 +0100470 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
471 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100472
Gilles Peskine9018b112020-01-21 16:30:53 +0100473 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
474 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100475
Janos Follath0e5532d2019-10-11 14:21:53 +0100476 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100477 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100478 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100479
480exit:
481 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
482}
483/* END_CASE */
484
485/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100486void mpi_cmp_abs( char * input_X, char * input_Y,
487 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000488{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 mbedtls_mpi X, Y;
490 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000491
Werner Lewis19b4cd82022-07-07 11:02:27 +0100492 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
493 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000495
Paul Bakkerbd51b262014-07-10 15:26:12 +0200496exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000498}
Paul Bakker33b43f12013-08-20 11:48:36 +0200499/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000500
Paul Bakker33b43f12013-08-20 11:48:36 +0200501/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100502void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000503{
Gilles Peskined0722f82021-06-10 23:00:33 +0200504 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200505 mbedtls_mpi_init( &src );
506 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200507 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000508
Werner Lewis19b4cd82022-07-07 11:02:27 +0100509 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
510 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200511
512 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100513 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200514 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200515 TEST_ASSERT( sign_is_valid( &dst ) );
516 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000517
Gilles Peskined0722f82021-06-10 23:00:33 +0200518 /* mbedtls_mpi_safe_cond_assign(), assignment done */
519 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100520 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200521 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
522 TEST_ASSERT( sign_is_valid( &dst ) );
523 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
524
525 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
526 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100527 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200528 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
529 TEST_ASSERT( sign_is_valid( &dst ) );
530 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
531
Paul Bakkerbd51b262014-07-10 15:26:12 +0200532exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200533 mbedtls_mpi_free( &src );
534 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200535 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100536}
537/* END_CASE */
538
539/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200540void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100541{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200542 mbedtls_mpi X, A;
543 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200544 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000545
Werner Lewis19b4cd82022-07-07 11:02:27 +0100546 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200548
Werner Lewis19b4cd82022-07-07 11:02:27 +0100549 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200550 TEST_ASSERT( sign_is_valid( &X ) );
551 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000552
Paul Bakkerbd51b262014-07-10 15:26:12 +0200553exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200554 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000556}
Paul Bakker33b43f12013-08-20 11:48:36 +0200557/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000558
Paul Bakker33b43f12013-08-20 11:48:36 +0200559/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100560void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200561{
562 mbedtls_mpi X, Y, X0, Y0;
563 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
564 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
565
Werner Lewis19b4cd82022-07-07 11:02:27 +0100566 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
567 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200568
Gilles Peskined0722f82021-06-10 23:00:33 +0200569 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100570 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
571 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200572 mbedtls_mpi_swap( &X, &Y );
573 TEST_ASSERT( sign_is_valid( &X ) );
574 TEST_ASSERT( sign_is_valid( &Y ) );
575 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
576 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
577
Gilles Peskined0722f82021-06-10 23:00:33 +0200578 /* mbedtls_mpi_safe_cond_swap(), swap done */
579 mbedtls_mpi_free( &X );
580 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100581 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
582 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200583 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
584 TEST_ASSERT( sign_is_valid( &X ) );
585 TEST_ASSERT( sign_is_valid( &Y ) );
586 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
587 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
588
589 /* mbedtls_mpi_safe_cond_swap(), swap not done */
590 mbedtls_mpi_free( &X );
591 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100592 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
593 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200594 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
595 TEST_ASSERT( sign_is_valid( &X ) );
596 TEST_ASSERT( sign_is_valid( &Y ) );
597 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
598 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
599
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200600exit:
601 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
602 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
603}
604/* END_CASE */
605
606/* BEGIN_CASE */
607void mpi_swap_self( char *X_hex )
608{
609 mbedtls_mpi X, X0;
610 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
611
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100612 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100613 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200614
615 mbedtls_mpi_swap( &X, &X );
616 TEST_ASSERT( sign_is_valid( &X ) );
617 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
618
619exit:
620 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
621}
622/* END_CASE */
623
624/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100625void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100626{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_mpi X;
628 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100629
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200631 if( used > 0 )
632 {
633 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
634 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
635 }
636 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200638 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100639
Paul Bakkerbd51b262014-07-10 15:26:12 +0200640exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100642}
643/* END_CASE */
644
645/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100646void mpi_add_mpi( char * input_X, char * input_Y,
647 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000648{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_mpi X, Y, Z, A;
650 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000651
Werner Lewis19b4cd82022-07-07 11:02:27 +0100652 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
653 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
654 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200655 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200656 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000658
Gilles Peskine56f943a2020-07-23 01:18:11 +0200659 /* result == first operand */
660 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200661 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200662 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100663 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200664
665 /* result == second operand */
666 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200667 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200668 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
669
Paul Bakkerbd51b262014-07-10 15:26:12 +0200670exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000672}
Paul Bakker33b43f12013-08-20 11:48:36 +0200673/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000674
Paul Bakker33b43f12013-08-20 11:48:36 +0200675/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100676void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100677{
678 mbedtls_mpi X, A;
679 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
680
Werner Lewis19b4cd82022-07-07 11:02:27 +0100681 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100682
Werner Lewis19b4cd82022-07-07 11:02:27 +0100683 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100684 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
685 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200686 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100687
Werner Lewis19b4cd82022-07-07 11:02:27 +0100688 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100689 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200690 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100691 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
692
Werner Lewis19b4cd82022-07-07 11:02:27 +0100693 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100694 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200695 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100696 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
697
698exit:
699 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
700}
701/* END_CASE */
702
703
704/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100705void mpi_add_abs( char * input_X, char * input_Y,
706 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000707{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 mbedtls_mpi X, Y, Z, A;
709 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000710
Werner Lewis19b4cd82022-07-07 11:02:27 +0100711 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
712 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
713 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200715 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000717
Gilles Peskine56f943a2020-07-23 01:18:11 +0200718 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200720 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100722 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200723
724 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200726 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000728
Paul Bakkerbd51b262014-07-10 15:26:12 +0200729exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200730 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000731}
Paul Bakker33b43f12013-08-20 11:48:36 +0200732/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000733
Paul Bakker33b43f12013-08-20 11:48:36 +0200734/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100735void mpi_add_int( char * input_X, int input_Y,
736 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000737{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 mbedtls_mpi X, Z, A;
739 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000740
Werner Lewis19b4cd82022-07-07 11:02:27 +0100741 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
742 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200743 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200744 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000746
Paul Bakkerbd51b262014-07-10 15:26:12 +0200747exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200748 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000749}
Paul Bakker33b43f12013-08-20 11:48:36 +0200750/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000751
Paul Bakker33b43f12013-08-20 11:48:36 +0200752/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100753void mpi_sub_mpi( char * input_X, char * input_Y,
754 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000755{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 mbedtls_mpi X, Y, Z, A;
757 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000758
Werner Lewis19b4cd82022-07-07 11:02:27 +0100759 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
760 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
761 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200763 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200764 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000765
Gilles Peskine56f943a2020-07-23 01:18:11 +0200766 /* result == first operand */
767 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200768 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200769 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100770 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200771
772 /* result == second operand */
773 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200774 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200775 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
776
Paul Bakkerbd51b262014-07-10 15:26:12 +0200777exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200778 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000779}
Paul Bakker33b43f12013-08-20 11:48:36 +0200780/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000781
Paul Bakker33b43f12013-08-20 11:48:36 +0200782/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100783void mpi_sub_abs( char * input_X, char * input_Y,
784 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000785{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200786 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000787 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200788 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000789
Werner Lewis19b4cd82022-07-07 11:02:27 +0100790 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
791 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
792 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100793
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200795 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200796 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000797 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000799
Gilles Peskine56f943a2020-07-23 01:18:11 +0200800 /* result == first operand */
801 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200802 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200803 if( sub_result == 0 )
804 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100805 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200806
807 /* result == second operand */
808 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200809 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200810 if( sub_result == 0 )
811 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
812
Paul Bakkerbd51b262014-07-10 15:26:12 +0200813exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000815}
Paul Bakker33b43f12013-08-20 11:48:36 +0200816/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000817
Paul Bakker33b43f12013-08-20 11:48:36 +0200818/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100819void mpi_sub_int( char * input_X, int input_Y,
820 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000821{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200822 mbedtls_mpi X, Z, A;
823 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000824
Werner Lewis19b4cd82022-07-07 11:02:27 +0100825 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
826 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200828 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200829 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000830
Paul Bakkerbd51b262014-07-10 15:26:12 +0200831exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000833}
Paul Bakker33b43f12013-08-20 11:48:36 +0200834/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000835
Paul Bakker33b43f12013-08-20 11:48:36 +0200836/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100837void mpi_mul_mpi( char * input_X, char * input_Y,
838 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000839{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840 mbedtls_mpi X, Y, Z, A;
841 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000842
Werner Lewis19b4cd82022-07-07 11:02:27 +0100843 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
844 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
845 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200846 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200847 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200848 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000849
Paul Bakkerbd51b262014-07-10 15:26:12 +0200850exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000852}
Paul Bakker33b43f12013-08-20 11:48:36 +0200853/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000854
Paul Bakker33b43f12013-08-20 11:48:36 +0200855/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100856void mpi_mul_int( char * input_X, int input_Y,
857 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000858{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 mbedtls_mpi X, Z, A;
860 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000861
Werner Lewis19b4cd82022-07-07 11:02:27 +0100862 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
863 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200864 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200865 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200866 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200867 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200868 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200870 else
871 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000872
Paul Bakkerbd51b262014-07-10 15:26:12 +0200873exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000875}
Paul Bakker33b43f12013-08-20 11:48:36 +0200876/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000877
Paul Bakker33b43f12013-08-20 11:48:36 +0200878/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100879void mpi_div_mpi( char * input_X, char * input_Y,
880 char * input_A, char * input_B,
881 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000882{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000884 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
886 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000887
Werner Lewis19b4cd82022-07-07 11:02:27 +0100888 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
889 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
890 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
891 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200892 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200893 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000894 if( res == 0 )
895 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200896 TEST_ASSERT( sign_is_valid( &Q ) );
897 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200898 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
899 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000900 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000901
Paul Bakkerbd51b262014-07-10 15:26:12 +0200902exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
904 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000905}
Paul Bakker33b43f12013-08-20 11:48:36 +0200906/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000907
Paul Bakker33b43f12013-08-20 11:48:36 +0200908/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100909void mpi_div_int( char * input_X, int input_Y,
910 char * input_A, char * input_B,
911 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000912{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200913 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000914 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
916 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000917
Werner Lewis19b4cd82022-07-07 11:02:27 +0100918 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
919 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
920 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200921 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200922 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000923 if( res == 0 )
924 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200925 TEST_ASSERT( sign_is_valid( &Q ) );
926 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
928 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000929 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000930
Paul Bakkerbd51b262014-07-10 15:26:12 +0200931exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
933 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000934}
Paul Bakker33b43f12013-08-20 11:48:36 +0200935/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000936
Paul Bakker33b43f12013-08-20 11:48:36 +0200937/* BEGIN_CASE */
Werner Lewis6baf12b2022-10-19 12:46:35 +0100938void mpi_mod_mpi( char * input_X, char * input_Y,
939 char * input_A, int div_result )
940{
941 mbedtls_mpi X, Y, A;
942 int res;
943 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
944
945 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
946 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
947 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
948 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
949 TEST_ASSERT( res == div_result );
950 if( res == 0 )
951 {
952 TEST_ASSERT( sign_is_valid( &X ) );
953 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
954 }
955
956exit:
957 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
958}
959/* END_CASE */
960
961/* BEGIN_CASE */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000962void mpi_mod_int( char * input_X, char * input_Y,
963 char * input_A, int mod_result )
Werner Lewis6baf12b2022-10-19 12:46:35 +0100964{
965 mbedtls_mpi X;
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000966 mbedtls_mpi Y;
967 mbedtls_mpi A;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100968 int res;
969 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100970
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000971 mbedtls_mpi_init( &X );
972 mbedtls_mpi_init( &Y );
973 mbedtls_mpi_init( &A );
974
975 /* We use MPIs to read Y and A since the test framework limits us to
976 * ints, so we can't have 64-bit values */
977 TEST_EQUAL( mbedtls_test_read_mpi( &X, input_X ), 0 );
978 TEST_EQUAL( mbedtls_test_read_mpi( &Y, input_Y ), 0 );
979 TEST_EQUAL( mbedtls_test_read_mpi( &A, input_A ), 0 );
980
981 TEST_EQUAL( Y.n, 1 );
982 TEST_EQUAL( A.n, 1 );
983
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000984 /* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
985
986 /* Since we're converting sign+magnitude to two's complement, we lose one
987 * bit of value in the output. This means there are some values we can't
988 * represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
989 * invalid test cases, so could be considered "won't happen", but they are
990 * easy to test for, and this helps guard against human error. */
991
992 mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
993 TEST_ASSERT( y >= 0 ); /* If y < 0 here, we can't make negative y */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000994 if( Y.s == -1 )
995 y = -y;
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000996
997 mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
998 TEST_ASSERT( a >= 0 ); /* Same goes for a */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000999 if( A.s == -1 )
1000 a = -a;
1001
1002 res = mbedtls_mpi_mod_int( &r, &X, y );
1003 TEST_EQUAL( res, mod_result );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001004 if( res == 0 )
1005 {
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001006 TEST_EQUAL( r, a );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001007 }
1008
1009exit:
1010 mbedtls_mpi_free( &X );
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001011 mbedtls_mpi_free( &Y );
1012 mbedtls_mpi_free( &A );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001013}
1014/* END_CASE */
1015
1016/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001017void mpi_exp_mod( char * input_A, char * input_E,
1018 char * input_N, char * input_X,
1019 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001020{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001022 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001023 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1024 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001025
Werner Lewis19b4cd82022-07-07 11:02:27 +01001026 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1027 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1028 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1029 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001030
Gilles Peskine342f71b2021-06-09 18:31:35 +02001031 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001032 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001033 if( res == 0 )
1034 {
1035 TEST_ASSERT( sign_is_valid( &Z ) );
1036 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1037 }
1038
1039 /* Now test again with the speed-up parameter supplied as an output. */
1040 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001041 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001042 if( res == 0 )
1043 {
1044 TEST_ASSERT( sign_is_valid( &Z ) );
1045 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1046 }
1047
1048 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001050 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001051 if( res == 0 )
1052 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001053 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001055 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001056
Paul Bakkerbd51b262014-07-10 15:26:12 +02001057exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001058 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1059 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001060}
Paul Bakker33b43f12013-08-20 11:48:36 +02001061/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001062
Paul Bakker33b43f12013-08-20 11:48:36 +02001063/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001064void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1065 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001066{
1067 mbedtls_mpi A, E, N, RR, Z;
1068 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1069 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1070
Chris Jonesaa850cd2020-12-03 11:35:41 +00001071 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001072 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001073 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001074 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001075
1076 /* Set E to 2^(E_bytes - 1) + 1 */
1077 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1078 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001079 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001080
1081 /* Set N to 2^(N_bytes - 1) + 1 */
1082 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1083 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001084 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1085
1086 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001087 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001088
Chris Jonesaa850cd2020-12-03 11:35:41 +00001089 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001090
1091exit:
1092 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1093 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1094}
1095/* END_CASE */
1096
1097/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001098void mpi_inv_mod( char * input_X, char * input_Y,
1099 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001100{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001102 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001103 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001104
Werner Lewis19b4cd82022-07-07 11:02:27 +01001105 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1106 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1107 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001109 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001110 if( res == 0 )
1111 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001112 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001114 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001115
Paul Bakkerbd51b262014-07-10 15:26:12 +02001116exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001118}
Paul Bakker33b43f12013-08-20 11:48:36 +02001119/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001121/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001122void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001123{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001125 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001126 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001127
Werner Lewis19b4cd82022-07-07 11:02:27 +01001128 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001129 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001130 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001131
Paul Bakkerbd51b262014-07-10 15:26:12 +02001132exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001134}
Paul Bakker33b43f12013-08-20 11:48:36 +02001135/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001136
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001138void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1139 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001140{
1141 mbedtls_mpi X;
1142 int res;
1143 mbedtls_test_mpi_random rand;
1144
1145 mbedtls_mpi_init( &X );
1146 rand.data = witnesses;
1147 rand.pos = 0;
1148 rand.chunk_len = chunk_len;
1149
1150 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001151 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1152 mbedtls_test_mpi_miller_rabin_determinizer,
1153 &rand );
1154 TEST_ASSERT( res == 0 );
1155
1156 rand.data = witnesses;
1157 rand.pos = 0;
1158 rand.chunk_len = chunk_len;
1159
Janos Follatha0b67c22018-09-18 14:48:23 +01001160 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1161 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001162 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001163 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001164
1165exit:
1166 mbedtls_mpi_free( &X );
1167}
1168/* END_CASE */
1169
1170/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001171void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001172{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001174 int my_ret;
1175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001177
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001178 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1179 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001180 TEST_ASSERT( my_ret == ref_ret );
1181
1182 if( ref_ret == 0 )
1183 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001184 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001185
1186 TEST_ASSERT( actual_bits >= (size_t) bits );
1187 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001188 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001189
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001190 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1191 mbedtls_test_rnd_std_rand,
1192 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001193 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001194 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001195 /* X = ( X - 1 ) / 2 */
1196 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001197 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1198 mbedtls_test_rnd_std_rand,
1199 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001200 }
1201 }
1202
Paul Bakkerbd51b262014-07-10 15:26:12 +02001203exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001205}
1206/* END_CASE */
1207
Paul Bakker33b43f12013-08-20 11:48:36 +02001208/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001209void mpi_shift_l( char * input_X, int shift_X,
1210 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001211{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212 mbedtls_mpi X, A;
1213 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001214
Werner Lewis19b4cd82022-07-07 11:02:27 +01001215 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1216 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001217 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001218 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001219 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001220
Paul Bakkerbd51b262014-07-10 15:26:12 +02001221exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001223}
Paul Bakker33b43f12013-08-20 11:48:36 +02001224/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001225
Paul Bakker33b43f12013-08-20 11:48:36 +02001226/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001227void mpi_shift_r( char * input_X, int shift_X,
1228 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001229{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230 mbedtls_mpi X, A;
1231 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001232
Werner Lewis19b4cd82022-07-07 11:02:27 +01001233 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1234 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001235 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001236 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001238
Paul Bakkerbd51b262014-07-10 15:26:12 +02001239exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001240 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001241}
Paul Bakker33b43f12013-08-20 11:48:36 +02001242/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001243
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001244/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001245void mpi_fill_random( int wanted_bytes, int rng_bytes,
1246 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001247{
1248 mbedtls_mpi X;
1249 int ret;
1250 size_t bytes_left = rng_bytes;
1251 mbedtls_mpi_init( &X );
1252
Gilles Peskine422e8672021-04-02 00:02:27 +02001253 if( before != 0 )
1254 {
1255 /* Set X to sign(before) * 2^(|before|-1) */
1256 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1257 if( before < 0 )
1258 before = - before;
1259 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1260 }
1261
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001262 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1263 f_rng_bytes_left, &bytes_left );
1264 TEST_ASSERT( ret == expected_ret );
1265
1266 if( expected_ret == 0 )
1267 {
1268 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1269 * as a big-endian representation of the number. We know when
1270 * our RNG function returns null bytes, so we know how many
1271 * leading zero bytes the number has. */
1272 size_t leading_zeros = 0;
1273 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1274 leading_zeros = 1;
1275 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1276 (size_t) wanted_bytes );
1277 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001278 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001279 }
1280
1281exit:
1282 mbedtls_mpi_free( &X );
1283}
1284/* END_CASE */
1285
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001286/* BEGIN_CASE */
1287void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1288{
1289 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1290 * This function assumes that the value of bound is at least 2 and
1291 * that iterations is large enough that a one-in-2^iterations chance
1292 * effectively never occurs.
1293 */
1294
1295 mbedtls_mpi upper_bound;
1296 size_t n_bits;
1297 mbedtls_mpi result;
1298 size_t b;
1299 /* If upper_bound is small, stats[b] is the number of times the value b
1300 * has been generated. Otherwise stats[b] is the number of times a
1301 * value with bit b set has been generated. */
1302 size_t *stats = NULL;
1303 size_t stats_len;
1304 int full_stats;
1305 size_t i;
1306
1307 mbedtls_mpi_init( &upper_bound );
1308 mbedtls_mpi_init( &result );
1309
1310 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1311 bound_bytes->x, bound_bytes->len ) );
1312 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1313 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1314 * to be small enough that the probability of missing one value is
1315 * negligible given the number of iterations. It must be less than
1316 * 256 because some of the code below assumes that "small" values
1317 * fit in a byte. */
1318 if( n_bits <= 5 )
1319 {
1320 full_stats = 1;
1321 stats_len = bound_bytes->x[bound_bytes->len - 1];
1322 }
1323 else
1324 {
1325 full_stats = 0;
1326 stats_len = n_bits;
1327 }
1328 ASSERT_ALLOC( stats, stats_len );
1329
1330 for( i = 0; i < (size_t) iterations; i++ )
1331 {
1332 mbedtls_test_set_step( i );
1333 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1334 mbedtls_test_rnd_std_rand, NULL ) );
1335
Gilles Peskinedffc7102021-06-10 15:34:15 +02001336 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001337 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1338 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1339 if( full_stats )
1340 {
1341 uint8_t value;
1342 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1343 TEST_ASSERT( value < stats_len );
1344 ++stats[value];
1345 }
1346 else
1347 {
1348 for( b = 0; b < n_bits; b++ )
1349 stats[b] += mbedtls_mpi_get_bit( &result, b );
1350 }
1351 }
1352
1353 if( full_stats )
1354 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001355 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001356 {
1357 mbedtls_test_set_step( 1000000 + b );
1358 /* Assert that each value has been reached at least once.
1359 * This is almost guaranteed if the iteration count is large
1360 * enough. This is a very crude way of checking the distribution.
1361 */
1362 TEST_ASSERT( stats[b] > 0 );
1363 }
1364 }
1365 else
1366 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001367 int statistically_safe_all_the_way =
1368 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001369 for( b = 0; b < n_bits; b++ )
1370 {
1371 mbedtls_test_set_step( 1000000 + b );
1372 /* Assert that each bit has been set in at least one result and
1373 * clear in at least one result. Provided that iterations is not
1374 * too small, it would be extremely unlikely for this not to be
1375 * the case if the results are uniformly distributed.
1376 *
1377 * As an exception, the top bit may legitimately never be set
1378 * if bound is a power of 2 or only slightly above.
1379 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001380 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001381 {
1382 TEST_ASSERT( stats[b] > 0 );
1383 }
1384 TEST_ASSERT( stats[b] < (size_t) iterations );
1385 }
1386 }
1387
1388exit:
1389 mbedtls_mpi_free( &upper_bound );
1390 mbedtls_mpi_free( &result );
1391 mbedtls_free( stats );
1392}
1393/* END_CASE */
1394
Gilles Peskine1e918f42021-03-29 22:14:51 +02001395/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001396void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001397{
1398 mbedtls_mpi upper_bound;
1399 mbedtls_mpi result;
1400
1401 mbedtls_mpi_init( &upper_bound );
1402 mbedtls_mpi_init( &result );
1403
Gilles Peskine422e8672021-04-02 00:02:27 +02001404 if( before != 0 )
1405 {
1406 /* Set result to sign(before) * 2^(|before|-1) */
1407 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1408 if( before < 0 )
1409 before = - before;
1410 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1411 }
1412
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001413 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1414 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1415 bound_bytes->x, bound_bytes->len ) );
1416 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1417 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001418 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001419 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1420 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1421
1422exit:
1423 mbedtls_mpi_free( &upper_bound );
1424 mbedtls_mpi_free( &result );
1425}
1426/* END_CASE */
1427
1428/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001429void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1430{
1431 mbedtls_mpi upper_bound;
1432 mbedtls_mpi result;
1433 int actual_ret;
1434
1435 mbedtls_mpi_init( &upper_bound );
1436 mbedtls_mpi_init( &result );
1437
1438 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1439 bound_bytes->x, bound_bytes->len ) );
1440 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1441 mbedtls_test_rnd_std_rand, NULL );
1442 TEST_EQUAL( expected_ret, actual_ret );
1443
1444exit:
1445 mbedtls_mpi_free( &upper_bound );
1446 mbedtls_mpi_free( &result );
1447}
1448/* END_CASE */
1449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001451void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001452{
Andres AG93012e82016-09-09 09:10:28 +01001453 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001454}
Paul Bakker33b43f12013-08-20 11:48:36 +02001455/* END_CASE */