blob: c26766b2ccaf56c266c3c7bc5bf4523665c18380 [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 */
Gilles Peskineb50e4332022-10-09 21:17:26 +0200398void mpi_core_bitlen( char *input_X, int nr_bits )
399{
400 mbedtls_mpi_uint *X = NULL;
401 size_t limbs;
402
403 TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs, input_X ), 0 );
404 TEST_EQUAL( mbedtls_mpi_core_bitlen( X, limbs ), nr_bits );
405
406exit:
407 mbedtls_free( X );
408}
409/* END_CASE */
410
411/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100412void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000413{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_mpi X;
415 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000416
Werner Lewis19b4cd82022-07-07 11:02:27 +0100417 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200418 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000419
Paul Bakkerbd51b262014-07-10 15:26:12 +0200420exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000422}
Paul Bakker33b43f12013-08-20 11:48:36 +0200423/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000424
Paul Bakker33b43f12013-08-20 11:48:36 +0200425/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100426void mpi_gcd( char * input_X, char * input_Y,
427 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000428{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 mbedtls_mpi A, X, Y, Z;
430 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000431
Werner Lewis19b4cd82022-07-07 11:02:27 +0100432 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
433 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
434 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200436 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
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( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
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_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000446{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 mbedtls_mpi X;
448 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000449
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200450 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
451 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000452
Paul Bakkerbd51b262014-07-10 15:26:12 +0200453exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000455}
Paul Bakker33b43f12013-08-20 11:48:36 +0200456/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000457
Paul Bakker33b43f12013-08-20 11:48:36 +0200458/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100459void mpi_cmp_mpi( char * input_X, char * input_Y,
460 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000461{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 mbedtls_mpi X, Y;
463 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000464
Werner Lewis19b4cd82022-07-07 11:02:27 +0100465 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
466 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000468
Paul Bakkerbd51b262014-07-10 15:26:12 +0200469exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000471}
Paul Bakker33b43f12013-08-20 11:48:36 +0200472/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000473
Paul Bakker33b43f12013-08-20 11:48:36 +0200474/* BEGIN_CASE */
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200475void mpi_core_cond_assign( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200476 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200477 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200478{
Gabor Mezeia7584882022-09-27 13:18:02 +0200479 mbedtls_mpi_uint *X = NULL;
480 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200481 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
482 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200483 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200484 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
485 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
486 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200487
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200488 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200489 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200490
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200491 ASSERT_ALLOC( X, limbs );
492 ASSERT_ALLOC( Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200493
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200494 TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs, input_X->x, input_X->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200495 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200496
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200497 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs, input_Y->x, input_Y->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200498 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200499
Gabor Mezei821d1512022-09-27 12:41:28 +0200500 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200501 TEST_CF_SECRET( X, bytes );
502 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200503
Gabor Mezei02e5d432022-10-03 16:45:11 +0200504 mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200505
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200506 TEST_CF_PUBLIC( X, bytes );
507 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200508
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200509 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200510
Gabor Mezei821d1512022-09-27 12:41:28 +0200511 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200512 TEST_CF_SECRET( X, bytes );
513 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200514
Gabor Mezei02e5d432022-10-03 16:45:11 +0200515 mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 1 );
Gabor Mezei821d1512022-09-27 12:41:28 +0200516
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200517 TEST_CF_PUBLIC( X, bytes );
518 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200519
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200520 /* Check if the given length is copied even it is smaller
Gabor Mezei4dceede2022-10-18 16:44:17 +0200521 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200522 if( copy_limbs < limbs )
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200523 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200524 ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
525 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200526 }
Gabor Mezei02e5d432022-10-03 16:45:11 +0200527 else
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200528 ASSERT_COMPARE( X, bytes, Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200529
530exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200531 mbedtls_free( X );
532 mbedtls_free( Y );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200533}
534/* END_CASE */
535
536/* BEGIN_CASE */
537void mpi_core_cond_swap( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200538 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200539 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200540{
Gabor Mezeia7584882022-09-27 13:18:02 +0200541 mbedtls_mpi_uint *tmp_X = NULL;
542 mbedtls_mpi_uint *tmp_Y = NULL;
543 mbedtls_mpi_uint *X = NULL;
544 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200545 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
546 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200547 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200548 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
549 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
550 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200551
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200552 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200553 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200554
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200555 ASSERT_ALLOC( tmp_X, limbs );
556 ASSERT_ALLOC( tmp_Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200557
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200558 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200559 input_X->x, input_X->len )
560 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200561 ASSERT_ALLOC( X, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200562 memcpy( X, tmp_X, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200563
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200564 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200565 input_Y->x, input_Y->len )
566 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200567 ASSERT_ALLOC( Y, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200568 memcpy( Y, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200569
Gabor Mezei821d1512022-09-27 12:41:28 +0200570 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200571 TEST_CF_SECRET( X, bytes );
572 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200573
Gabor Mezei02e5d432022-10-03 16:45:11 +0200574 mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200575
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200576 TEST_CF_PUBLIC( X, bytes );
577 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200578
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200579 ASSERT_COMPARE( X, bytes, tmp_X, bytes );
580 ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200581
Gabor Mezei821d1512022-09-27 12:41:28 +0200582 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200583 TEST_CF_SECRET( X, bytes );
584 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200585
Gabor Mezei02e5d432022-10-03 16:45:11 +0200586 mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 1 );
Gabor Mezei821d1512022-09-27 12:41:28 +0200587
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200588 TEST_CF_PUBLIC( X, bytes );
589 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200590
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200591 /* Check if the given length is copied even it is smaller
592 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200593 if( copy_limbs < limbs )
Gabor Mezei02e5d432022-10-03 16:45:11 +0200594 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200595 ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
596 ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
597 TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
598 TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
599 TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
600 TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200601 }
602 else
603 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200604 ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
605 ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200606 }
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200607
608exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200609 mbedtls_free( tmp_X );
610 mbedtls_free( tmp_Y );
611 mbedtls_free( X );
612 mbedtls_free( Y );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200613}
614/* END_CASE */
615
616/* BEGIN_CASE */
617void mpi_mod_raw_cond_assign( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200618 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200619 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200620{
Gabor Mezeia7584882022-09-27 13:18:02 +0200621 mbedtls_mpi_uint *X = NULL;
622 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200623 mbedtls_mpi_uint *buff_m = NULL;
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200624 mbedtls_mpi_mod_modulus m;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200625 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
626 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200627 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200628 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
629 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
630 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200631
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200632 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200633 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200634
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200635 ASSERT_ALLOC( X, limbs );
636 ASSERT_ALLOC( Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200637
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200638 ASSERT_ALLOC( buff_m, limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200639 mbedtls_mpi_mod_modulus_init( &m );
640 TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
Gabor Mezei02e5d432022-10-03 16:45:11 +0200641 &m, buff_m, copy_limbs,
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200642 MBEDTLS_MPI_MOD_EXT_REP_BE,
643 MBEDTLS_MPI_MOD_REP_MONTGOMERY )
644 == 0 );
645
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200646 TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200647 input_X->x, input_X->len )
648 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200649
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200650 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200651 input_Y->x, input_Y->len )
652 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200653
Gabor Mezei821d1512022-09-27 12:41:28 +0200654 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200655 TEST_CF_SECRET( X, bytes );
656 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200657
Gabor Mezei821d1512022-09-27 12:41:28 +0200658 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200659
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200660 TEST_CF_PUBLIC( X, bytes );
661 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200662
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200663 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200664
Gabor Mezei821d1512022-09-27 12:41:28 +0200665 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200666 TEST_CF_SECRET( X, bytes );
667 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200668
669 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 1 );
670
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200671 TEST_CF_PUBLIC( X, bytes );
672 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200673
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200674 /* Check if the given length is copied even it is smaller
675 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200676 if( copy_limbs <limbs )
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200677 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200678 ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
679 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200680 }
Gabor Mezei02e5d432022-10-03 16:45:11 +0200681 else
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200682 ASSERT_COMPARE( X, bytes, Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200683
684exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200685 mbedtls_free( X );
686 mbedtls_free( Y );
687
688 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200689 mbedtls_free( buff_m );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200690}
691/* END_CASE */
692
693/* BEGIN_CASE */
694void mpi_mod_raw_cond_swap( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200695 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200696 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200697{
Gabor Mezeia7584882022-09-27 13:18:02 +0200698 mbedtls_mpi_uint *tmp_X = NULL;
699 mbedtls_mpi_uint *tmp_Y = NULL;
700 mbedtls_mpi_uint *X = NULL;
701 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200702 mbedtls_mpi_uint *buff_m = NULL;
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200703 mbedtls_mpi_mod_modulus m;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200704 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
705 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200706 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200707 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
708 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
709 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200710
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200711 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200712 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200713
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200714 ASSERT_ALLOC( tmp_X, limbs );
715 ASSERT_ALLOC( tmp_Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200716
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200717 ASSERT_ALLOC( buff_m, copy_limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200718 mbedtls_mpi_mod_modulus_init( &m );
719 TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
Gabor Mezei02e5d432022-10-03 16:45:11 +0200720 &m, buff_m, copy_limbs,
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200721 MBEDTLS_MPI_MOD_EXT_REP_BE,
722 MBEDTLS_MPI_MOD_REP_MONTGOMERY )
723 == 0 );
724
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200725 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs, input_X->x, input_X->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200726 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200727 ASSERT_ALLOC( X, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200728 memcpy( X, tmp_X, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200729
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200730 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs, input_Y->x, input_Y->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200731 == 0 );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200732 ASSERT_ALLOC( Y, bytes );
733 memcpy( Y, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200734
Gabor Mezei821d1512022-09-27 12:41:28 +0200735 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200736 TEST_CF_SECRET( X, bytes );
737 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200738
Gabor Mezei821d1512022-09-27 12:41:28 +0200739 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200740
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200741 TEST_CF_PUBLIC( X, bytes );
742 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200743
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200744 ASSERT_COMPARE( X, bytes, tmp_X, bytes );
745 ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200746
Gabor Mezei821d1512022-09-27 12:41:28 +0200747 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200748 TEST_CF_SECRET( X, bytes );
749 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200750
751 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 1 );
752
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200753 TEST_CF_PUBLIC( X, bytes );
754 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200755
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200756 /* Check if the given length is copied even it is smaller
757 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200758 if( copy_limbs < limbs )
Gabor Mezei02e5d432022-10-03 16:45:11 +0200759 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200760 ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
761 ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
762 TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
763 TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
764 TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
765 TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200766 }
767 else
768 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200769 ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
770 ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200771 }
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200772
773exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200774 mbedtls_free( tmp_X );
775 mbedtls_free( tmp_Y );
776 mbedtls_free( X );
777 mbedtls_free( Y );
778
779 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200780 mbedtls_free( buff_m );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200781}
782/* END_CASE */
783
784/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100785void mpi_lt_mpi_ct( int size_X, char * input_X,
786 int size_Y, char * input_Y,
787 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100788{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200789 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100790 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100791 mbedtls_mpi X, Y;
792 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
793
Werner Lewis19b4cd82022-07-07 11:02:27 +0100794 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
795 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100796
Gilles Peskine9018b112020-01-21 16:30:53 +0100797 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
798 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100799
Janos Follath0e5532d2019-10-11 14:21:53 +0100800 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100801 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100802 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100803
804exit:
805 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
806}
807/* END_CASE */
808
809/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100810void mpi_cmp_abs( char * input_X, char * input_Y,
811 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000812{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813 mbedtls_mpi X, Y;
814 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000815
Werner Lewis19b4cd82022-07-07 11:02:27 +0100816 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
817 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000819
Paul Bakkerbd51b262014-07-10 15:26:12 +0200820exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200821 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000822}
Paul Bakker33b43f12013-08-20 11:48:36 +0200823/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000824
Paul Bakker33b43f12013-08-20 11:48:36 +0200825/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100826void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000827{
Gilles Peskined0722f82021-06-10 23:00:33 +0200828 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200829 mbedtls_mpi_init( &src );
830 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200831 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000832
Werner Lewis19b4cd82022-07-07 11:02:27 +0100833 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
834 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200835
836 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100837 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200838 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200839 TEST_ASSERT( sign_is_valid( &dst ) );
840 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000841
Gilles Peskined0722f82021-06-10 23:00:33 +0200842 /* mbedtls_mpi_safe_cond_assign(), assignment done */
843 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100844 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200845 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
846 TEST_ASSERT( sign_is_valid( &dst ) );
847 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
848
849 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
850 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100851 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200852 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
853 TEST_ASSERT( sign_is_valid( &dst ) );
854 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
855
Paul Bakkerbd51b262014-07-10 15:26:12 +0200856exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200857 mbedtls_mpi_free( &src );
858 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200859 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100860}
861/* END_CASE */
862
863/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200864void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100865{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200866 mbedtls_mpi X, A;
867 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200868 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000869
Werner Lewis19b4cd82022-07-07 11:02:27 +0100870 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200872
Werner Lewis19b4cd82022-07-07 11:02:27 +0100873 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200874 TEST_ASSERT( sign_is_valid( &X ) );
875 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000876
Paul Bakkerbd51b262014-07-10 15:26:12 +0200877exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200878 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000880}
Paul Bakker33b43f12013-08-20 11:48:36 +0200881/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000882
Paul Bakker33b43f12013-08-20 11:48:36 +0200883/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100884void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200885{
886 mbedtls_mpi X, Y, X0, Y0;
887 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
888 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
889
Werner Lewis19b4cd82022-07-07 11:02:27 +0100890 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
891 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200892
Gilles Peskined0722f82021-06-10 23:00:33 +0200893 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100894 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
895 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200896 mbedtls_mpi_swap( &X, &Y );
897 TEST_ASSERT( sign_is_valid( &X ) );
898 TEST_ASSERT( sign_is_valid( &Y ) );
899 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
900 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
901
Gilles Peskined0722f82021-06-10 23:00:33 +0200902 /* mbedtls_mpi_safe_cond_swap(), swap done */
903 mbedtls_mpi_free( &X );
904 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100905 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
906 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200907 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
908 TEST_ASSERT( sign_is_valid( &X ) );
909 TEST_ASSERT( sign_is_valid( &Y ) );
910 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
911 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
912
913 /* mbedtls_mpi_safe_cond_swap(), swap not done */
914 mbedtls_mpi_free( &X );
915 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100916 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
917 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200918 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
919 TEST_ASSERT( sign_is_valid( &X ) );
920 TEST_ASSERT( sign_is_valid( &Y ) );
921 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
922 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
923
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200924exit:
925 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
926 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
927}
928/* END_CASE */
929
930/* BEGIN_CASE */
931void mpi_swap_self( char *X_hex )
932{
933 mbedtls_mpi X, X0;
934 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
935
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100936 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100937 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200938
939 mbedtls_mpi_swap( &X, &X );
940 TEST_ASSERT( sign_is_valid( &X ) );
941 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
942
943exit:
944 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
945}
946/* END_CASE */
947
948/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100949void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100950{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200951 mbedtls_mpi X;
952 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100953
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200955 if( used > 0 )
956 {
957 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
958 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
959 }
960 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200961 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200962 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100963
Paul Bakkerbd51b262014-07-10 15:26:12 +0200964exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200965 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100966}
967/* END_CASE */
968
969/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100970void mpi_add_mpi( char * input_X, char * input_Y,
971 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000972{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200973 mbedtls_mpi X, Y, Z, A;
974 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000975
Werner Lewis19b4cd82022-07-07 11:02:27 +0100976 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
977 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
978 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200980 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200981 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000982
Gilles Peskine56f943a2020-07-23 01:18:11 +0200983 /* result == first operand */
984 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200985 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200986 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100987 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200988
989 /* result == second operand */
990 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200991 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200992 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
993
Paul Bakkerbd51b262014-07-10 15:26:12 +0200994exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200995 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000996}
Paul Bakker33b43f12013-08-20 11:48:36 +0200997/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000998
Paul Bakker33b43f12013-08-20 11:48:36 +0200999/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001000void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +01001001{
1002 mbedtls_mpi X, A;
1003 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1004
Werner Lewis19b4cd82022-07-07 11:02:27 +01001005 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001006
Werner Lewis19b4cd82022-07-07 11:02:27 +01001007 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001008 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
1009 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001010 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001011
Werner Lewis19b4cd82022-07-07 11:02:27 +01001012 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001013 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001014 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001015 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1016
Werner Lewis19b4cd82022-07-07 11:02:27 +01001017 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +01001018 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001019 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +01001020 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1021
1022exit:
1023 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1024}
1025/* END_CASE */
1026
1027
1028/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001029void mpi_add_abs( char * input_X, char * input_Y,
1030 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001031{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_mpi X, Y, Z, A;
1033 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001034
Werner Lewis19b4cd82022-07-07 11:02:27 +01001035 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1036 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1037 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001039 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001041
Gilles Peskine56f943a2020-07-23 01:18:11 +02001042 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001044 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001046 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001047
1048 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001050 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001051 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001052
Paul Bakkerbd51b262014-07-10 15:26:12 +02001053exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001054 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001055}
Paul Bakker33b43f12013-08-20 11:48:36 +02001056/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001057
Paul Bakker33b43f12013-08-20 11:48:36 +02001058/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001059void mpi_add_int( char * input_X, int input_Y,
1060 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001061{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 mbedtls_mpi X, Z, A;
1063 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001064
Werner Lewis19b4cd82022-07-07 11:02:27 +01001065 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1066 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001068 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001070
Paul Bakkerbd51b262014-07-10 15:26:12 +02001071exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001073}
Paul Bakker33b43f12013-08-20 11:48:36 +02001074/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001075
Paul Bakker33b43f12013-08-20 11:48:36 +02001076/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001077void mpi_sub_mpi( char * input_X, char * input_Y,
1078 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001079{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001080 mbedtls_mpi X, Y, Z, A;
1081 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001082
Werner Lewis19b4cd82022-07-07 11:02:27 +01001083 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1084 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1085 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001087 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001089
Gilles Peskine56f943a2020-07-23 01:18:11 +02001090 /* result == first operand */
1091 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001092 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001093 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001094 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001095
1096 /* result == second operand */
1097 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001098 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001099 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1100
Paul Bakkerbd51b262014-07-10 15:26:12 +02001101exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001102 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001103}
Paul Bakker33b43f12013-08-20 11:48:36 +02001104/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001105
Paul Bakker33b43f12013-08-20 11:48:36 +02001106/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001107void mpi_sub_abs( char * input_X, char * input_Y,
1108 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001109{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001111 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001113
Werner Lewis19b4cd82022-07-07 11:02:27 +01001114 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1115 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1116 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001119 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001120 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001121 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001122 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001123
Gilles Peskine56f943a2020-07-23 01:18:11 +02001124 /* result == first operand */
1125 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001126 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001127 if( sub_result == 0 )
1128 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001129 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001130
1131 /* result == second operand */
1132 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001133 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001134 if( sub_result == 0 )
1135 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1136
Paul Bakkerbd51b262014-07-10 15:26:12 +02001137exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001139}
Paul Bakker33b43f12013-08-20 11:48:36 +02001140/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001141
Paul Bakker33b43f12013-08-20 11:48:36 +02001142/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001143void mpi_sub_int( char * input_X, int input_Y,
1144 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001145{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146 mbedtls_mpi X, Z, A;
1147 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001148
Werner Lewis19b4cd82022-07-07 11:02:27 +01001149 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1150 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001152 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001153 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001154
Paul Bakkerbd51b262014-07-10 15:26:12 +02001155exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001156 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001157}
Paul Bakker33b43f12013-08-20 11:48:36 +02001158/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001159
Paul Bakker33b43f12013-08-20 11:48:36 +02001160/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001161void mpi_mul_mpi( char * input_X, char * input_Y,
1162 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001163{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 mbedtls_mpi X, Y, Z, A;
1165 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001166
Werner Lewis19b4cd82022-07-07 11:02:27 +01001167 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1168 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1169 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001171 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001173
Paul Bakkerbd51b262014-07-10 15:26:12 +02001174exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001176}
Paul Bakker33b43f12013-08-20 11:48:36 +02001177/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001178
Paul Bakker33b43f12013-08-20 11:48:36 +02001179/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001180void mpi_mul_int( char * input_X, int input_Y,
1181 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001182{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183 mbedtls_mpi X, Z, A;
1184 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001185
Werner Lewis19b4cd82022-07-07 11:02:27 +01001186 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1187 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001189 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001190 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001191 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001192 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001194 else
1195 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001196
Paul Bakkerbd51b262014-07-10 15:26:12 +02001197exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001199}
Paul Bakker33b43f12013-08-20 11:48:36 +02001200/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001201
Paul Bakker33b43f12013-08-20 11:48:36 +02001202/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001203void mpi_div_mpi( char * input_X, char * input_Y,
1204 char * input_A, char * input_B,
1205 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001206{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001208 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001209 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1210 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001211
Werner Lewis19b4cd82022-07-07 11:02:27 +01001212 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1213 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1214 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1215 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001217 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001218 if( res == 0 )
1219 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001220 TEST_ASSERT( sign_is_valid( &Q ) );
1221 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1223 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001224 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001225
Paul Bakkerbd51b262014-07-10 15:26:12 +02001226exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001227 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1228 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001229}
Paul Bakker33b43f12013-08-20 11:48:36 +02001230/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001231
Paul Bakker33b43f12013-08-20 11:48:36 +02001232/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001233void mpi_div_int( char * input_X, int input_Y,
1234 char * input_A, char * input_B,
1235 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001236{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001238 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001239 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1240 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001241
Werner Lewis19b4cd82022-07-07 11:02:27 +01001242 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1243 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1244 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001245 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001246 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001247 if( res == 0 )
1248 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001249 TEST_ASSERT( sign_is_valid( &Q ) );
1250 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1252 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001253 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001254
Paul Bakkerbd51b262014-07-10 15:26:12 +02001255exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1257 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001258}
Paul Bakker33b43f12013-08-20 11:48:36 +02001259/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001260
Paul Bakker33b43f12013-08-20 11:48:36 +02001261/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001262void mpi_exp_mod( char * input_A, char * input_E,
1263 char * input_N, char * input_X,
1264 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001265{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001266 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001267 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001268 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1269 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001270
Werner Lewis19b4cd82022-07-07 11:02:27 +01001271 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1272 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1273 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1274 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001275
Gilles Peskine342f71b2021-06-09 18:31:35 +02001276 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001277 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001278 if( res == 0 )
1279 {
1280 TEST_ASSERT( sign_is_valid( &Z ) );
1281 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1282 }
1283
1284 /* Now test again with the speed-up parameter supplied as an output. */
1285 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001286 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001287 if( res == 0 )
1288 {
1289 TEST_ASSERT( sign_is_valid( &Z ) );
1290 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1291 }
1292
1293 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001295 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001296 if( res == 0 )
1297 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001298 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001299 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001300 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001301
Paul Bakkerbd51b262014-07-10 15:26:12 +02001302exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001303 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1304 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001305}
Paul Bakker33b43f12013-08-20 11:48:36 +02001306/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001307
Paul Bakker33b43f12013-08-20 11:48:36 +02001308/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001309void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1310 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001311{
1312 mbedtls_mpi A, E, N, RR, Z;
1313 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1314 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1315
Chris Jonesaa850cd2020-12-03 11:35:41 +00001316 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001317 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001318 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001319 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001320
1321 /* Set E to 2^(E_bytes - 1) + 1 */
1322 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1323 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001324 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001325
1326 /* Set N to 2^(N_bytes - 1) + 1 */
1327 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1328 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001329 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1330
1331 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001332 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001333
Chris Jonesaa850cd2020-12-03 11:35:41 +00001334 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001335
1336exit:
1337 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1338 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1339}
1340/* END_CASE */
1341
1342/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001343void mpi_inv_mod( char * input_X, char * input_Y,
1344 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001345{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001347 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001348 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001349
Werner Lewis19b4cd82022-07-07 11:02:27 +01001350 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1351 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1352 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001353 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001354 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001355 if( res == 0 )
1356 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001357 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001358 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001359 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001360
Paul Bakkerbd51b262014-07-10 15:26:12 +02001361exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001362 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001363}
Paul Bakker33b43f12013-08-20 11:48:36 +02001364/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001366/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001367void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001368{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001370 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001371 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001372
Werner Lewis19b4cd82022-07-07 11:02:27 +01001373 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001374 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001375 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001376
Paul Bakkerbd51b262014-07-10 15:26:12 +02001377exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001378 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001379}
Paul Bakker33b43f12013-08-20 11:48:36 +02001380/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001381
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001382/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001383void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1384 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001385{
1386 mbedtls_mpi X;
1387 int res;
1388 mbedtls_test_mpi_random rand;
1389
1390 mbedtls_mpi_init( &X );
1391 rand.data = witnesses;
1392 rand.pos = 0;
1393 rand.chunk_len = chunk_len;
1394
1395 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001396 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1397 mbedtls_test_mpi_miller_rabin_determinizer,
1398 &rand );
1399 TEST_ASSERT( res == 0 );
1400
1401 rand.data = witnesses;
1402 rand.pos = 0;
1403 rand.chunk_len = chunk_len;
1404
Janos Follatha0b67c22018-09-18 14:48:23 +01001405 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1406 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001407 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001408 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001409
1410exit:
1411 mbedtls_mpi_free( &X );
1412}
1413/* END_CASE */
1414
1415/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001416void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001417{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001418 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001419 int my_ret;
1420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001421 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001422
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001423 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1424 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001425 TEST_ASSERT( my_ret == ref_ret );
1426
1427 if( ref_ret == 0 )
1428 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001429 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001430
1431 TEST_ASSERT( actual_bits >= (size_t) bits );
1432 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001433 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001434
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001435 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1436 mbedtls_test_rnd_std_rand,
1437 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001438 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001439 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001440 /* X = ( X - 1 ) / 2 */
1441 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001442 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1443 mbedtls_test_rnd_std_rand,
1444 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001445 }
1446 }
1447
Paul Bakkerbd51b262014-07-10 15:26:12 +02001448exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001449 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001450}
1451/* END_CASE */
1452
Paul Bakker33b43f12013-08-20 11:48:36 +02001453/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001454void mpi_shift_l( char * input_X, int shift_X,
1455 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001456{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001457 mbedtls_mpi X, A;
1458 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001459
Werner Lewis19b4cd82022-07-07 11:02:27 +01001460 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1461 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001463 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001464 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001465
Paul Bakkerbd51b262014-07-10 15:26:12 +02001466exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001468}
Paul Bakker33b43f12013-08-20 11:48:36 +02001469/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001470
Paul Bakker33b43f12013-08-20 11:48:36 +02001471/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001472void mpi_shift_r( char * input_X, int shift_X,
1473 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001474{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001475 mbedtls_mpi X, A;
1476 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001477
Werner Lewis19b4cd82022-07-07 11:02:27 +01001478 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1479 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001481 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001482 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001483
Paul Bakkerbd51b262014-07-10 15:26:12 +02001484exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001486}
Paul Bakker33b43f12013-08-20 11:48:36 +02001487/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001488
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001489/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001490void mpi_fill_random( int wanted_bytes, int rng_bytes,
1491 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001492{
1493 mbedtls_mpi X;
1494 int ret;
1495 size_t bytes_left = rng_bytes;
1496 mbedtls_mpi_init( &X );
1497
Gilles Peskine422e8672021-04-02 00:02:27 +02001498 if( before != 0 )
1499 {
1500 /* Set X to sign(before) * 2^(|before|-1) */
1501 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1502 if( before < 0 )
1503 before = - before;
1504 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1505 }
1506
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001507 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1508 f_rng_bytes_left, &bytes_left );
1509 TEST_ASSERT( ret == expected_ret );
1510
1511 if( expected_ret == 0 )
1512 {
1513 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1514 * as a big-endian representation of the number. We know when
1515 * our RNG function returns null bytes, so we know how many
1516 * leading zero bytes the number has. */
1517 size_t leading_zeros = 0;
1518 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1519 leading_zeros = 1;
1520 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1521 (size_t) wanted_bytes );
1522 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001523 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001524 }
1525
1526exit:
1527 mbedtls_mpi_free( &X );
1528}
1529/* END_CASE */
1530
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001531/* BEGIN_CASE */
1532void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1533{
1534 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1535 * This function assumes that the value of bound is at least 2 and
1536 * that iterations is large enough that a one-in-2^iterations chance
1537 * effectively never occurs.
1538 */
1539
1540 mbedtls_mpi upper_bound;
1541 size_t n_bits;
1542 mbedtls_mpi result;
1543 size_t b;
1544 /* If upper_bound is small, stats[b] is the number of times the value b
1545 * has been generated. Otherwise stats[b] is the number of times a
1546 * value with bit b set has been generated. */
1547 size_t *stats = NULL;
1548 size_t stats_len;
1549 int full_stats;
1550 size_t i;
1551
1552 mbedtls_mpi_init( &upper_bound );
1553 mbedtls_mpi_init( &result );
1554
1555 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1556 bound_bytes->x, bound_bytes->len ) );
1557 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1558 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1559 * to be small enough that the probability of missing one value is
1560 * negligible given the number of iterations. It must be less than
1561 * 256 because some of the code below assumes that "small" values
1562 * fit in a byte. */
1563 if( n_bits <= 5 )
1564 {
1565 full_stats = 1;
1566 stats_len = bound_bytes->x[bound_bytes->len - 1];
1567 }
1568 else
1569 {
1570 full_stats = 0;
1571 stats_len = n_bits;
1572 }
1573 ASSERT_ALLOC( stats, stats_len );
1574
1575 for( i = 0; i < (size_t) iterations; i++ )
1576 {
1577 mbedtls_test_set_step( i );
1578 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1579 mbedtls_test_rnd_std_rand, NULL ) );
1580
Gilles Peskinedffc7102021-06-10 15:34:15 +02001581 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001582 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1583 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1584 if( full_stats )
1585 {
1586 uint8_t value;
1587 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1588 TEST_ASSERT( value < stats_len );
1589 ++stats[value];
1590 }
1591 else
1592 {
1593 for( b = 0; b < n_bits; b++ )
1594 stats[b] += mbedtls_mpi_get_bit( &result, b );
1595 }
1596 }
1597
1598 if( full_stats )
1599 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001600 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001601 {
1602 mbedtls_test_set_step( 1000000 + b );
1603 /* Assert that each value has been reached at least once.
1604 * This is almost guaranteed if the iteration count is large
1605 * enough. This is a very crude way of checking the distribution.
1606 */
1607 TEST_ASSERT( stats[b] > 0 );
1608 }
1609 }
1610 else
1611 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001612 int statistically_safe_all_the_way =
1613 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001614 for( b = 0; b < n_bits; b++ )
1615 {
1616 mbedtls_test_set_step( 1000000 + b );
1617 /* Assert that each bit has been set in at least one result and
1618 * clear in at least one result. Provided that iterations is not
1619 * too small, it would be extremely unlikely for this not to be
1620 * the case if the results are uniformly distributed.
1621 *
1622 * As an exception, the top bit may legitimately never be set
1623 * if bound is a power of 2 or only slightly above.
1624 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001625 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001626 {
1627 TEST_ASSERT( stats[b] > 0 );
1628 }
1629 TEST_ASSERT( stats[b] < (size_t) iterations );
1630 }
1631 }
1632
1633exit:
1634 mbedtls_mpi_free( &upper_bound );
1635 mbedtls_mpi_free( &result );
1636 mbedtls_free( stats );
1637}
1638/* END_CASE */
1639
Gilles Peskine1e918f42021-03-29 22:14:51 +02001640/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001641void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001642{
1643 mbedtls_mpi upper_bound;
1644 mbedtls_mpi result;
1645
1646 mbedtls_mpi_init( &upper_bound );
1647 mbedtls_mpi_init( &result );
1648
Gilles Peskine422e8672021-04-02 00:02:27 +02001649 if( before != 0 )
1650 {
1651 /* Set result to sign(before) * 2^(|before|-1) */
1652 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1653 if( before < 0 )
1654 before = - before;
1655 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1656 }
1657
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001658 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1659 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1660 bound_bytes->x, bound_bytes->len ) );
1661 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1662 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001663 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001664 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1665 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1666
1667exit:
1668 mbedtls_mpi_free( &upper_bound );
1669 mbedtls_mpi_free( &result );
1670}
1671/* END_CASE */
1672
1673/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001674void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1675{
1676 mbedtls_mpi upper_bound;
1677 mbedtls_mpi result;
1678 int actual_ret;
1679
1680 mbedtls_mpi_init( &upper_bound );
1681 mbedtls_mpi_init( &result );
1682
1683 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1684 bound_bytes->x, bound_bytes->len ) );
1685 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1686 mbedtls_test_rnd_std_rand, NULL );
1687 TEST_EQUAL( expected_ret, actual_ret );
1688
1689exit:
1690 mbedtls_mpi_free( &upper_bound );
1691 mbedtls_mpi_free( &result );
1692}
1693/* END_CASE */
1694
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001695/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001696void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001697{
Andres AG93012e82016-09-09 09:10:28 +01001698 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001699}
Paul Bakker33b43f12013-08-20 11:48:36 +02001700/* END_CASE */