blob: b75f534f469584116066186b58b2793d13b49d35 [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{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010016 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskinedffc7102021-06-10 15:34:15 +020017 if( X->s != 1 && X->s != -1 )
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010018 return( 0 );
19
20 /* The value 0 must be represented with the sign +1. A "negative zero"
21 * with s=-1 is an invalid representation. Forbid that. As an exception,
22 * we sometimes test the robustness of library functions when given
23 * a negative zero input. If a test case has a negative zero as input,
24 * we don't mind if the function has a negative zero output. */
25 if( ! mbedtls_test_case_uses_negative_0 &&
26 mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
27 {
28 return( 0 );
29 }
30
Gilles Peskinedffc7102021-06-10 15:34:15 +020031 return( 1 );
32}
33
Janos Follath64eca052018-09-05 17:04:49 +010034typedef struct mbedtls_test_mpi_random
35{
36 data_t *data;
37 size_t pos;
38 size_t chunk_len;
39} mbedtls_test_mpi_random;
40
41/*
42 * This function is called by the Miller-Rabin primality test each time it
43 * chooses a random witness. The witnesses (or non-witnesses as provided by the
44 * test) are stored in the data member of the state structure. Each number is in
45 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
46 */
47int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
48 unsigned char* buf,
49 size_t len )
50{
51 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
52
53 if( random == NULL || random->data->x == NULL || buf == NULL )
54 return( -1 );
55
56 if( random->pos + random->chunk_len > random->data->len
57 || random->chunk_len > len )
58 {
59 return( -1 );
60 }
61
62 memset( buf, 0, len );
63
64 /* The witness is written to the end of the buffer, since the buffer is
65 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
66 * Writing the witness to the start of the buffer would result in the
67 * buffer being 'witness 000...000', which would be treated as
68 * witness * 2^n for some n. */
69 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
70 random->chunk_len );
71
72 random->pos += random->chunk_len;
73
74 return( 0 );
75}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010076
77/* Random generator that is told how many bytes to return. */
78static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
79{
80 size_t *bytes_left = state;
81 size_t i;
82 for( i = 0; i < len; i++ )
83 {
84 if( *bytes_left == 0 )
85 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
86 buf[i] = *bytes_left & 0xff;
87 --( *bytes_left );
88 }
89 return( 0 );
90}
91
Gilles Peskineeedefa52021-04-13 19:50:04 +020092/* Test whether bytes represents (in big-endian base 256) a number b that
93 * is significantly above a power of 2. That is, b must not have a long run
94 * of unset bits after the most significant bit.
95 *
96 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
97 * This function returns 1 if, when drawing a number between 0 and b,
98 * the probability that this number is at least 2^n is not negligible.
99 * This probability is (b - 2^n) / b and this function checks that this
100 * number is above some threshold A. The threshold value is heuristic and
101 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200102 */
103static int is_significantly_above_a_power_of_2( data_t *bytes )
104{
105 const uint8_t *p = bytes->x;
106 size_t len = bytes->len;
107 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200108
109 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200110 while( len > 0 && p[0] == 0 )
111 {
112 ++p;
113 --len;
114 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200115 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200116 if( len == 0 )
117 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200118 /* Extract the (up to) 2 most significant bytes */
119 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200120 x = p[0];
121 else
122 x = ( p[0] << 8 ) | p[1];
123
Gilles Peskineeedefa52021-04-13 19:50:04 +0200124 /* Shift the most significant bit of x to position 8 and mask it out */
125 while( ( x & 0xfe00 ) != 0 )
126 x >>= 1;
127 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200128
Gilles Peskineeedefa52021-04-13 19:50:04 +0200129 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
130 * a power of 2 iff x is significantly above 0 compared to 2^8.
131 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
132 * description above. */
133 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200134}
135
Paul Bakker33b43f12013-08-20 11:48:36 +0200136/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000137
Paul Bakker33b43f12013-08-20 11:48:36 +0200138/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200139 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200140 * END_DEPENDENCIES
141 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000142
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000143/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100144void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200145{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200146 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200147
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200148 mbedtls_mpi_init( &X );
149 mbedtls_mpi_init( &Y );
150 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200151
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200152 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
153 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200154 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200155 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200156
157exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200158 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200159}
160/* END_CASE */
161
162/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100163void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
164 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200165 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000166{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000168 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100169 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000170
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200171 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000172
Janos Follath04dadb72019-03-06 12:29:37 +0000173 memset( str, '!', sizeof( str ) );
174
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200176 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000177 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200178 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100179 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200180 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000181 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200182 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000183 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000184 }
185 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000186
Paul Bakkerbd51b262014-07-10 15:26:12 +0200187exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200188 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000189}
Paul Bakker33b43f12013-08-20 11:48:36 +0200190/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000191
Paul Bakker33b43f12013-08-20 11:48:36 +0200192/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100193void mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000194{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200195 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000196 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100197 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000198
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200199 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000200
Paul Bakkere896fea2009-07-06 06:40:23 +0000201
Azim Khand30ca132017-06-09 04:32:58 +0100202 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200203 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100204 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100205 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000206
Paul Bakkerbd51b262014-07-10 15:26:12 +0200207exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000209}
Paul Bakker33b43f12013-08-20 11:48:36 +0200210/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000211
Paul Bakker33b43f12013-08-20 11:48:36 +0200212/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100213void mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000214{
215 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000216 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000217 size_t len;
218
219 mbedtls_mpi_init( &X );
220
221
222 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200223 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100224 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100225 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000226
227exit:
228 mbedtls_mpi_free( &X );
229}
230/* END_CASE */
231
232/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100233void mpi_write_binary( char * input_X, data_t * input_A,
234 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000235{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200236 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000237 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000238 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000239
240 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000241
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000243
Werner Lewis19b4cd82022-07-07 11:02:27 +0100244 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100245
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200246 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200247 if( buflen > (size_t) output_size )
248 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000249
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200251 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000252 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000253
Ronald Cron2dbba992020-06-10 11:42:32 +0200254 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
255 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000256 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000257
Paul Bakkerbd51b262014-07-10 15:26:12 +0200258exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200259 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000260}
Paul Bakker33b43f12013-08-20 11:48:36 +0200261/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000262
Janos Follathe344d0f2019-02-19 16:17:40 +0000263/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100264void mpi_write_binary_le( char * input_X, data_t * input_A,
265 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000266{
267 mbedtls_mpi X;
268 unsigned char buf[1000];
269 size_t buflen;
270
271 memset( buf, 0x00, 1000 );
272
273 mbedtls_mpi_init( &X );
274
Werner Lewis19b4cd82022-07-07 11:02:27 +0100275 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000276
277 buflen = mbedtls_mpi_size( &X );
278 if( buflen > (size_t) output_size )
279 buflen = (size_t) output_size;
280
281 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
282 if( result == 0)
283 {
284
Ronald Cron2dbba992020-06-10 11:42:32 +0200285 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
286 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000287 }
288
289exit:
290 mbedtls_mpi_free( &X );
291}
292/* END_CASE */
293
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200294/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100295void mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000296{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000298 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000299 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000300 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000301 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
303 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000304
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200305 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000306
Paul Bakker33b43f12013-08-20 11:48:36 +0200307 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200308 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100309 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000310 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000311 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000312
Paul Bakker33b43f12013-08-20 11:48:36 +0200313 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000314 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200315 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200316 buflen = mbedtls_mpi_size( &X );
317 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000318
Paul Bakkere896fea2009-07-06 06:40:23 +0000319
Ronald Cron2dbba992020-06-10 11:42:32 +0200320 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
321 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000322 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000323
Paul Bakkerbd51b262014-07-10 15:26:12 +0200324exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000326}
Paul Bakker33b43f12013-08-20 11:48:36 +0200327/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100330void mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000331{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200332 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000333 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200334 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000337
Werner Lewis19b4cd82022-07-07 11:02:27 +0100338 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000339
Paul Bakker33b43f12013-08-20 11:48:36 +0200340 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000341 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100342 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000343 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200344 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000345
Paul Bakker33b43f12013-08-20 11:48:36 +0200346 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000347 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100348 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000349 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200350 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000351
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200352 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000353
Paul Bakkerbd51b262014-07-10 15:26:12 +0200354exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000356}
Paul Bakker33b43f12013-08-20 11:48:36 +0200357/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000358
Paul Bakker33b43f12013-08-20 11:48:36 +0200359/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100360void mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000361{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_mpi X;
363 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100364 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000366
Paul Bakkerbd51b262014-07-10 15:26:12 +0200367exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000369}
Paul Bakker33b43f12013-08-20 11:48:36 +0200370/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000371
Paul Bakker33b43f12013-08-20 11:48:36 +0200372/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100373void mpi_set_bit( char * input_X, int pos, int val,
374 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000375{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 mbedtls_mpi X, Y;
377 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000378
Werner Lewis19b4cd82022-07-07 11:02:27 +0100379 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
380 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100381 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
382
383 if( result == 0 )
384 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200385 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100386 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
387 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000388
Paul Bakkerbd51b262014-07-10 15:26:12 +0200389exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000391}
Paul Bakker33b43f12013-08-20 11:48:36 +0200392/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000393
Paul Bakker33b43f12013-08-20 11:48:36 +0200394/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100395void mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000396{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_mpi X;
398 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000399
Werner Lewis19b4cd82022-07-07 11:02:27 +0100400 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000402
Paul Bakkerbd51b262014-07-10 15:26:12 +0200403exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000405}
Paul Bakker33b43f12013-08-20 11:48:36 +0200406/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000407
Paul Bakker33b43f12013-08-20 11:48:36 +0200408/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100409void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000410{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200411 mbedtls_mpi X;
412 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000413
Werner Lewis19b4cd82022-07-07 11:02:27 +0100414 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200415 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000416
Paul Bakkerbd51b262014-07-10 15:26:12 +0200417exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000419}
Paul Bakker33b43f12013-08-20 11:48:36 +0200420/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000421
Paul Bakker33b43f12013-08-20 11:48:36 +0200422/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100423void mpi_gcd( char * input_X, char * input_Y,
424 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000425{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_mpi A, X, Y, Z;
427 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000428
Werner Lewis19b4cd82022-07-07 11:02:27 +0100429 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
430 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
431 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200433 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000435
Paul Bakkerbd51b262014-07-10 15:26:12 +0200436exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000438}
Paul Bakker33b43f12013-08-20 11:48:36 +0200439/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000440
Paul Bakker33b43f12013-08-20 11:48:36 +0200441/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100442void mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000443{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444 mbedtls_mpi X;
445 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000446
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
448 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000449
Paul Bakkerbd51b262014-07-10 15:26:12 +0200450exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000452}
Paul Bakker33b43f12013-08-20 11:48:36 +0200453/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000454
Paul Bakker33b43f12013-08-20 11:48:36 +0200455/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100456void mpi_cmp_mpi( char * input_X, char * input_Y,
457 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000458{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_mpi X, Y;
460 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000461
Werner Lewis19b4cd82022-07-07 11:02:27 +0100462 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
463 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000465
Paul Bakkerbd51b262014-07-10 15:26:12 +0200466exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000468}
Paul Bakker33b43f12013-08-20 11:48:36 +0200469/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000470
Paul Bakker33b43f12013-08-20 11:48:36 +0200471/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100472void mpi_lt_mpi_ct( int size_X, char * input_X,
473 int size_Y, char * input_Y,
474 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100475{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200476 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100477 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100478 mbedtls_mpi X, Y;
479 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
480
Werner Lewis19b4cd82022-07-07 11:02:27 +0100481 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
482 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100483
Gilles Peskine9018b112020-01-21 16:30:53 +0100484 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
485 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100486
Janos Follath0e5532d2019-10-11 14:21:53 +0100487 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100488 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100489 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100490
491exit:
492 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
493}
494/* END_CASE */
495
496/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100497void mpi_cmp_abs( char * input_X, char * input_Y,
498 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000499{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200500 mbedtls_mpi X, Y;
501 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000502
Werner Lewis19b4cd82022-07-07 11:02:27 +0100503 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
504 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000506
Paul Bakkerbd51b262014-07-10 15:26:12 +0200507exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000509}
Paul Bakker33b43f12013-08-20 11:48:36 +0200510/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000511
Paul Bakker33b43f12013-08-20 11:48:36 +0200512/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100513void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000514{
Gilles Peskined0722f82021-06-10 23:00:33 +0200515 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200516 mbedtls_mpi_init( &src );
517 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200518 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000519
Werner Lewis19b4cd82022-07-07 11:02:27 +0100520 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
521 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200522
523 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100524 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200525 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200526 TEST_ASSERT( sign_is_valid( &dst ) );
527 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000528
Gilles Peskined0722f82021-06-10 23:00:33 +0200529 /* mbedtls_mpi_safe_cond_assign(), assignment done */
530 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100531 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200532 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
533 TEST_ASSERT( sign_is_valid( &dst ) );
534 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
535
536 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
537 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100538 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200539 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
540 TEST_ASSERT( sign_is_valid( &dst ) );
541 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
542
Paul Bakkerbd51b262014-07-10 15:26:12 +0200543exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200544 mbedtls_mpi_free( &src );
545 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200546 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100547}
548/* END_CASE */
549
550/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200551void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100552{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200553 mbedtls_mpi X, A;
554 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200555 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000556
Werner Lewis19b4cd82022-07-07 11:02:27 +0100557 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200559
Werner Lewis19b4cd82022-07-07 11:02:27 +0100560 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200561 TEST_ASSERT( sign_is_valid( &X ) );
562 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000563
Paul Bakkerbd51b262014-07-10 15:26:12 +0200564exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200565 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000567}
Paul Bakker33b43f12013-08-20 11:48:36 +0200568/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000569
Paul Bakker33b43f12013-08-20 11:48:36 +0200570/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100571void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200572{
573 mbedtls_mpi X, Y, X0, Y0;
574 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
575 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
576
Werner Lewis19b4cd82022-07-07 11:02:27 +0100577 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
578 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200579
Gilles Peskined0722f82021-06-10 23:00:33 +0200580 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100581 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
582 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200583 mbedtls_mpi_swap( &X, &Y );
584 TEST_ASSERT( sign_is_valid( &X ) );
585 TEST_ASSERT( sign_is_valid( &Y ) );
586 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
587 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
588
Gilles Peskined0722f82021-06-10 23:00:33 +0200589 /* mbedtls_mpi_safe_cond_swap(), swap done */
590 mbedtls_mpi_free( &X );
591 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100592 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
593 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200594 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
595 TEST_ASSERT( sign_is_valid( &X ) );
596 TEST_ASSERT( sign_is_valid( &Y ) );
597 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
598 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
599
600 /* mbedtls_mpi_safe_cond_swap(), swap not done */
601 mbedtls_mpi_free( &X );
602 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100603 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
604 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200605 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
606 TEST_ASSERT( sign_is_valid( &X ) );
607 TEST_ASSERT( sign_is_valid( &Y ) );
608 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
609 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
610
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200611exit:
612 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
613 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
614}
615/* END_CASE */
616
617/* BEGIN_CASE */
618void mpi_swap_self( char *X_hex )
619{
620 mbedtls_mpi X, X0;
621 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
622
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100623 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100624 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200625
626 mbedtls_mpi_swap( &X, &X );
627 TEST_ASSERT( sign_is_valid( &X ) );
628 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
629
630exit:
631 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
632}
633/* END_CASE */
634
635/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100636void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100637{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200638 mbedtls_mpi X;
639 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100640
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200641 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200642 if( used > 0 )
643 {
644 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
645 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
646 }
647 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200649 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100650
Paul Bakkerbd51b262014-07-10 15:26:12 +0200651exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200652 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100653}
654/* END_CASE */
655
656/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100657void mpi_add_mpi( char * input_X, char * input_Y,
658 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000659{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 mbedtls_mpi X, Y, Z, A;
661 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000662
Werner Lewis19b4cd82022-07-07 11:02:27 +0100663 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
664 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
665 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200666 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200667 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200668 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000669
Gilles Peskine56f943a2020-07-23 01:18:11 +0200670 /* result == first operand */
671 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200672 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200673 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100674 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200675
676 /* result == second operand */
677 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200678 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200679 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
680
Paul Bakkerbd51b262014-07-10 15:26:12 +0200681exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000683}
Paul Bakker33b43f12013-08-20 11:48:36 +0200684/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000685
Paul Bakker33b43f12013-08-20 11:48:36 +0200686/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100687void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100688{
689 mbedtls_mpi X, A;
690 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
691
Werner Lewis19b4cd82022-07-07 11:02:27 +0100692 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100693
Werner Lewis19b4cd82022-07-07 11:02:27 +0100694 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100695 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
696 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200697 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100698
Werner Lewis19b4cd82022-07-07 11:02:27 +0100699 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100700 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200701 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100702 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
703
Werner Lewis19b4cd82022-07-07 11:02:27 +0100704 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100705 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200706 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100707 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
708
709exit:
710 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
711}
712/* END_CASE */
713
714
715/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100716void mpi_add_abs( char * input_X, char * input_Y,
717 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000718{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 mbedtls_mpi X, Y, Z, A;
720 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000721
Werner Lewis19b4cd82022-07-07 11:02:27 +0100722 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
723 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
724 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200725 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200726 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200727 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000728
Gilles Peskine56f943a2020-07-23 01:18:11 +0200729 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200731 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100733 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200734
735 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200737 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200738 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000739
Paul Bakkerbd51b262014-07-10 15:26:12 +0200740exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200741 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000742}
Paul Bakker33b43f12013-08-20 11:48:36 +0200743/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000744
Paul Bakker33b43f12013-08-20 11:48:36 +0200745/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100746void mpi_add_int( char * input_X, int input_Y,
747 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000748{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_mpi X, Z, A;
750 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000751
Werner Lewis19b4cd82022-07-07 11:02:27 +0100752 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
753 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200755 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000757
Paul Bakkerbd51b262014-07-10 15:26:12 +0200758exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000760}
Paul Bakker33b43f12013-08-20 11:48:36 +0200761/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000762
Paul Bakker33b43f12013-08-20 11:48:36 +0200763/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100764void mpi_sub_mpi( char * input_X, char * input_Y,
765 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000766{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200767 mbedtls_mpi X, Y, Z, A;
768 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000769
Werner Lewis19b4cd82022-07-07 11:02:27 +0100770 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
771 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
772 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200773 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200774 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200775 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000776
Gilles Peskine56f943a2020-07-23 01:18:11 +0200777 /* result == first operand */
778 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200779 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200780 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100781 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200782
783 /* result == second operand */
784 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200785 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200786 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
787
Paul Bakkerbd51b262014-07-10 15:26:12 +0200788exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000790}
Paul Bakker33b43f12013-08-20 11:48:36 +0200791/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000792
Paul Bakker33b43f12013-08-20 11:48:36 +0200793/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100794void mpi_sub_abs( char * input_X, char * input_Y,
795 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000796{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000798 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200799 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000800
Werner Lewis19b4cd82022-07-07 11:02:27 +0100801 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
802 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
803 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100804
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200805 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200806 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200807 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000808 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200809 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000810
Gilles Peskine56f943a2020-07-23 01:18:11 +0200811 /* result == first operand */
812 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200813 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200814 if( sub_result == 0 )
815 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100816 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200817
818 /* result == second operand */
819 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200820 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200821 if( sub_result == 0 )
822 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
823
Paul Bakkerbd51b262014-07-10 15:26:12 +0200824exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200825 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000826}
Paul Bakker33b43f12013-08-20 11:48:36 +0200827/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000828
Paul Bakker33b43f12013-08-20 11:48:36 +0200829/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100830void mpi_sub_int( char * input_X, int input_Y,
831 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000832{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200833 mbedtls_mpi X, Z, A;
834 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000835
Werner Lewis19b4cd82022-07-07 11:02:27 +0100836 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
837 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200838 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200839 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200840 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000841
Paul Bakkerbd51b262014-07-10 15:26:12 +0200842exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200843 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000844}
Paul Bakker33b43f12013-08-20 11:48:36 +0200845/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000846
Paul Bakker33b43f12013-08-20 11:48:36 +0200847/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100848void mpi_mul_mpi( char * input_X, char * input_Y,
849 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000850{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_mpi X, Y, Z, A;
852 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000853
Werner Lewis19b4cd82022-07-07 11:02:27 +0100854 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
855 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
856 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200857 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200858 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200859 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000860
Paul Bakkerbd51b262014-07-10 15:26:12 +0200861exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200862 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000863}
Paul Bakker33b43f12013-08-20 11:48:36 +0200864/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000865
Paul Bakker33b43f12013-08-20 11:48:36 +0200866/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100867void mpi_mul_int( char * input_X, int input_Y,
868 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000869{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200870 mbedtls_mpi X, Z, A;
871 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000872
Werner Lewis19b4cd82022-07-07 11:02:27 +0100873 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
874 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200875 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200876 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200877 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200878 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200879 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200880 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200881 else
882 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000883
Paul Bakkerbd51b262014-07-10 15:26:12 +0200884exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200885 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000886}
Paul Bakker33b43f12013-08-20 11:48:36 +0200887/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000888
Paul Bakker33b43f12013-08-20 11:48:36 +0200889/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100890void mpi_div_mpi( char * input_X, char * input_Y,
891 char * input_A, char * input_B,
892 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000893{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200894 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000895 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200896 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
897 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000898
Werner Lewis19b4cd82022-07-07 11:02:27 +0100899 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
900 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
901 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
902 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200903 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200904 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000905 if( res == 0 )
906 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200907 TEST_ASSERT( sign_is_valid( &Q ) );
908 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200909 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
910 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000911 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000912
Paul Bakkerbd51b262014-07-10 15:26:12 +0200913exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200914 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
915 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000916}
Paul Bakker33b43f12013-08-20 11:48:36 +0200917/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000918
Paul Bakker33b43f12013-08-20 11:48:36 +0200919/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100920void mpi_div_int( char * input_X, int input_Y,
921 char * input_A, char * input_B,
922 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000923{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200924 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000925 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200926 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
927 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000928
Werner Lewis19b4cd82022-07-07 11:02:27 +0100929 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
930 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
931 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200932 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200933 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000934 if( res == 0 )
935 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200936 TEST_ASSERT( sign_is_valid( &Q ) );
937 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200938 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
939 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000940 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000941
Paul Bakkerbd51b262014-07-10 15:26:12 +0200942exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200943 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
944 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000945}
Paul Bakker33b43f12013-08-20 11:48:36 +0200946/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000947
Paul Bakker33b43f12013-08-20 11:48:36 +0200948/* BEGIN_CASE */
Werner Lewis6baf12b2022-10-19 12:46:35 +0100949void mpi_mod_mpi( char * input_X, char * input_Y,
950 char * input_A, int div_result )
951{
952 mbedtls_mpi X, Y, A;
953 int res;
954 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
955
956 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
957 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
958 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
959 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
960 TEST_ASSERT( res == div_result );
961 if( res == 0 )
962 {
963 TEST_ASSERT( sign_is_valid( &X ) );
964 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
965 }
966
967exit:
968 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
969}
970/* END_CASE */
971
972/* BEGIN_CASE */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000973void mpi_mod_int( char * input_X, char * input_Y,
974 char * input_A, int mod_result )
Werner Lewis6baf12b2022-10-19 12:46:35 +0100975{
976 mbedtls_mpi X;
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000977 mbedtls_mpi Y;
978 mbedtls_mpi A;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100979 int res;
980 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100981
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000982 mbedtls_mpi_init( &X );
983 mbedtls_mpi_init( &Y );
984 mbedtls_mpi_init( &A );
985
986 /* We use MPIs to read Y and A since the test framework limits us to
987 * ints, so we can't have 64-bit values */
988 TEST_EQUAL( mbedtls_test_read_mpi( &X, input_X ), 0 );
989 TEST_EQUAL( mbedtls_test_read_mpi( &Y, input_Y ), 0 );
990 TEST_EQUAL( mbedtls_test_read_mpi( &A, input_A ), 0 );
991
992 TEST_EQUAL( Y.n, 1 );
993 TEST_EQUAL( A.n, 1 );
994
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000995 /* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
996
997 /* Since we're converting sign+magnitude to two's complement, we lose one
998 * bit of value in the output. This means there are some values we can't
999 * represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
1000 * invalid test cases, so could be considered "won't happen", but they are
1001 * easy to test for, and this helps guard against human error. */
1002
1003 mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
1004 TEST_ASSERT( y >= 0 ); /* If y < 0 here, we can't make negative y */
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001005 if( Y.s == -1 )
1006 y = -y;
Tom Cosgrove9feb19f2022-11-10 12:05:55 +00001007
1008 mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
1009 TEST_ASSERT( a >= 0 ); /* Same goes for a */
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001010 if( A.s == -1 )
1011 a = -a;
1012
1013 res = mbedtls_mpi_mod_int( &r, &X, y );
1014 TEST_EQUAL( res, mod_result );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001015 if( res == 0 )
1016 {
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001017 TEST_EQUAL( r, a );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001018 }
1019
1020exit:
1021 mbedtls_mpi_free( &X );
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001022 mbedtls_mpi_free( &Y );
1023 mbedtls_mpi_free( &A );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001024}
1025/* END_CASE */
1026
1027/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001028void mpi_exp_mod( char * input_A, char * input_E,
1029 char * input_N, char * input_X,
1030 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001031{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001033 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001034 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1035 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001036
Werner Lewis19b4cd82022-07-07 11:02:27 +01001037 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1038 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1039 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1040 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001041
Gilles Peskine342f71b2021-06-09 18:31:35 +02001042 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001043 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001044 if( res == 0 )
1045 {
1046 TEST_ASSERT( sign_is_valid( &Z ) );
1047 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1048 }
1049
1050 /* Now test again with the speed-up parameter supplied as an output. */
1051 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001052 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001053 if( res == 0 )
1054 {
1055 TEST_ASSERT( sign_is_valid( &Z ) );
1056 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1057 }
1058
1059 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001061 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001062 if( res == 0 )
1063 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001064 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001066 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001067
Paul Bakkerbd51b262014-07-10 15:26:12 +02001068exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1070 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001071}
Paul Bakker33b43f12013-08-20 11:48:36 +02001072/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001073
Paul Bakker33b43f12013-08-20 11:48:36 +02001074/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001075void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1076 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001077{
1078 mbedtls_mpi A, E, N, RR, Z;
1079 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1080 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1081
Chris Jonesaa850cd2020-12-03 11:35:41 +00001082 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001083 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001084 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001085 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001086
1087 /* Set E to 2^(E_bytes - 1) + 1 */
1088 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1089 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001090 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001091
1092 /* Set N to 2^(N_bytes - 1) + 1 */
1093 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1094 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001095 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1096
1097 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001098 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001099
Chris Jonesaa850cd2020-12-03 11:35:41 +00001100 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001101
1102exit:
1103 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1104 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1105}
1106/* END_CASE */
1107
1108/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001109void mpi_inv_mod( char * input_X, char * input_Y,
1110 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001111{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001112 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001113 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001115
Werner Lewis19b4cd82022-07-07 11:02:27 +01001116 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1117 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1118 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001119 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001120 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001121 if( res == 0 )
1122 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001123 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001124 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001125 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001126
Paul Bakkerbd51b262014-07-10 15:26:12 +02001127exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001128 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001129}
Paul Bakker33b43f12013-08-20 11:48:36 +02001130/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001133void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001134{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001135 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001136 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001137 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001138
Werner Lewis19b4cd82022-07-07 11:02:27 +01001139 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001140 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001141 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001142
Paul Bakkerbd51b262014-07-10 15:26:12 +02001143exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001145}
Paul Bakker33b43f12013-08-20 11:48:36 +02001146/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001149void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1150 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001151{
1152 mbedtls_mpi X;
1153 int res;
1154 mbedtls_test_mpi_random rand;
1155
1156 mbedtls_mpi_init( &X );
1157 rand.data = witnesses;
1158 rand.pos = 0;
1159 rand.chunk_len = chunk_len;
1160
1161 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001162 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1163 mbedtls_test_mpi_miller_rabin_determinizer,
1164 &rand );
1165 TEST_ASSERT( res == 0 );
1166
1167 rand.data = witnesses;
1168 rand.pos = 0;
1169 rand.chunk_len = chunk_len;
1170
Janos Follatha0b67c22018-09-18 14:48:23 +01001171 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1172 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001173 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001174 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001175
1176exit:
1177 mbedtls_mpi_free( &X );
1178}
1179/* END_CASE */
1180
1181/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001182void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001183{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001184 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001185 int my_ret;
1186
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001188
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001189 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1190 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001191 TEST_ASSERT( my_ret == ref_ret );
1192
1193 if( ref_ret == 0 )
1194 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001195 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001196
1197 TEST_ASSERT( actual_bits >= (size_t) bits );
1198 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001199 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001200
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001201 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1202 mbedtls_test_rnd_std_rand,
1203 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001204 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001205 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001206 /* X = ( X - 1 ) / 2 */
1207 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001208 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1209 mbedtls_test_rnd_std_rand,
1210 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001211 }
1212 }
1213
Paul Bakkerbd51b262014-07-10 15:26:12 +02001214exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001216}
1217/* END_CASE */
1218
Paul Bakker33b43f12013-08-20 11:48:36 +02001219/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001220void mpi_shift_l( char * input_X, int shift_X,
1221 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001222{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001223 mbedtls_mpi X, A;
1224 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001225
Werner Lewis19b4cd82022-07-07 11:02:27 +01001226 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1227 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001228 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001229 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001230 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001231
Paul Bakkerbd51b262014-07-10 15:26:12 +02001232exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001233 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001234}
Paul Bakker33b43f12013-08-20 11:48:36 +02001235/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001236
Paul Bakker33b43f12013-08-20 11:48:36 +02001237/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001238void mpi_shift_r( char * input_X, int shift_X,
1239 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi X, A;
1242 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001243
Werner Lewis19b4cd82022-07-07 11:02:27 +01001244 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1245 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001246 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001247 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001249
Paul Bakkerbd51b262014-07-10 15:26:12 +02001250exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001252}
Paul Bakker33b43f12013-08-20 11:48:36 +02001253/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001254
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001255/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001256void mpi_fill_random( int wanted_bytes, int rng_bytes,
1257 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001258{
1259 mbedtls_mpi X;
1260 int ret;
1261 size_t bytes_left = rng_bytes;
1262 mbedtls_mpi_init( &X );
1263
Gilles Peskine422e8672021-04-02 00:02:27 +02001264 if( before != 0 )
1265 {
1266 /* Set X to sign(before) * 2^(|before|-1) */
1267 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1268 if( before < 0 )
1269 before = - before;
1270 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1271 }
1272
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001273 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1274 f_rng_bytes_left, &bytes_left );
1275 TEST_ASSERT( ret == expected_ret );
1276
1277 if( expected_ret == 0 )
1278 {
1279 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1280 * as a big-endian representation of the number. We know when
1281 * our RNG function returns null bytes, so we know how many
1282 * leading zero bytes the number has. */
1283 size_t leading_zeros = 0;
1284 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1285 leading_zeros = 1;
1286 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1287 (size_t) wanted_bytes );
1288 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001289 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001290 }
1291
1292exit:
1293 mbedtls_mpi_free( &X );
1294}
1295/* END_CASE */
1296
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001297/* BEGIN_CASE */
1298void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1299{
1300 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1301 * This function assumes that the value of bound is at least 2 and
1302 * that iterations is large enough that a one-in-2^iterations chance
1303 * effectively never occurs.
1304 */
1305
1306 mbedtls_mpi upper_bound;
1307 size_t n_bits;
1308 mbedtls_mpi result;
1309 size_t b;
1310 /* If upper_bound is small, stats[b] is the number of times the value b
1311 * has been generated. Otherwise stats[b] is the number of times a
1312 * value with bit b set has been generated. */
1313 size_t *stats = NULL;
1314 size_t stats_len;
1315 int full_stats;
1316 size_t i;
1317
1318 mbedtls_mpi_init( &upper_bound );
1319 mbedtls_mpi_init( &result );
1320
1321 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1322 bound_bytes->x, bound_bytes->len ) );
1323 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1324 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1325 * to be small enough that the probability of missing one value is
1326 * negligible given the number of iterations. It must be less than
1327 * 256 because some of the code below assumes that "small" values
1328 * fit in a byte. */
1329 if( n_bits <= 5 )
1330 {
1331 full_stats = 1;
1332 stats_len = bound_bytes->x[bound_bytes->len - 1];
1333 }
1334 else
1335 {
1336 full_stats = 0;
1337 stats_len = n_bits;
1338 }
1339 ASSERT_ALLOC( stats, stats_len );
1340
1341 for( i = 0; i < (size_t) iterations; i++ )
1342 {
1343 mbedtls_test_set_step( i );
1344 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1345 mbedtls_test_rnd_std_rand, NULL ) );
1346
Gilles Peskinedffc7102021-06-10 15:34:15 +02001347 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001348 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1349 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1350 if( full_stats )
1351 {
1352 uint8_t value;
1353 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1354 TEST_ASSERT( value < stats_len );
1355 ++stats[value];
1356 }
1357 else
1358 {
1359 for( b = 0; b < n_bits; b++ )
1360 stats[b] += mbedtls_mpi_get_bit( &result, b );
1361 }
1362 }
1363
1364 if( full_stats )
1365 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001366 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001367 {
1368 mbedtls_test_set_step( 1000000 + b );
1369 /* Assert that each value has been reached at least once.
1370 * This is almost guaranteed if the iteration count is large
1371 * enough. This is a very crude way of checking the distribution.
1372 */
1373 TEST_ASSERT( stats[b] > 0 );
1374 }
1375 }
1376 else
1377 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001378 int statistically_safe_all_the_way =
1379 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001380 for( b = 0; b < n_bits; b++ )
1381 {
1382 mbedtls_test_set_step( 1000000 + b );
1383 /* Assert that each bit has been set in at least one result and
1384 * clear in at least one result. Provided that iterations is not
1385 * too small, it would be extremely unlikely for this not to be
1386 * the case if the results are uniformly distributed.
1387 *
1388 * As an exception, the top bit may legitimately never be set
1389 * if bound is a power of 2 or only slightly above.
1390 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001391 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001392 {
1393 TEST_ASSERT( stats[b] > 0 );
1394 }
1395 TEST_ASSERT( stats[b] < (size_t) iterations );
1396 }
1397 }
1398
1399exit:
1400 mbedtls_mpi_free( &upper_bound );
1401 mbedtls_mpi_free( &result );
1402 mbedtls_free( stats );
1403}
1404/* END_CASE */
1405
Gilles Peskine1e918f42021-03-29 22:14:51 +02001406/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001407void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001408{
1409 mbedtls_mpi upper_bound;
1410 mbedtls_mpi result;
1411
1412 mbedtls_mpi_init( &upper_bound );
1413 mbedtls_mpi_init( &result );
1414
Gilles Peskine422e8672021-04-02 00:02:27 +02001415 if( before != 0 )
1416 {
1417 /* Set result to sign(before) * 2^(|before|-1) */
1418 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1419 if( before < 0 )
1420 before = - before;
1421 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1422 }
1423
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001424 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1425 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1426 bound_bytes->x, bound_bytes->len ) );
1427 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1428 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001429 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001430 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1431 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1432
1433exit:
1434 mbedtls_mpi_free( &upper_bound );
1435 mbedtls_mpi_free( &result );
1436}
1437/* END_CASE */
1438
1439/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001440void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1441{
1442 mbedtls_mpi upper_bound;
1443 mbedtls_mpi result;
1444 int actual_ret;
1445
1446 mbedtls_mpi_init( &upper_bound );
1447 mbedtls_mpi_init( &result );
1448
1449 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1450 bound_bytes->x, bound_bytes->len ) );
1451 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1452 mbedtls_test_rnd_std_rand, NULL );
1453 TEST_EQUAL( expected_ret, actual_ret );
1454
1455exit:
1456 mbedtls_mpi_free( &upper_bound );
1457 mbedtls_mpi_free( &result );
1458}
1459/* END_CASE */
1460
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001462void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001463{
Andres AG93012e82016-09-09 09:10:28 +01001464 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001465}
Paul Bakker33b43f12013-08-20 11:48:36 +02001466/* END_CASE */