blob: cf5492058384779fba687d1a4bcba5224d9c760c [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"
Gilles Peskine34e8a2c2022-09-27 22:04:51 +02005#include "bignum_core.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01006#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01007
Chris Jonese64a46f2020-12-03 17:44:03 +00008#if MBEDTLS_MPI_MAX_BITS > 792
9#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000010#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020011
Gilles Peskinedffc7102021-06-10 15:34:15 +020012/* Check the validity of the sign bit in an MPI object. Reject representations
13 * that are not supported by the rest of the library and indicate a bug when
14 * constructing the value. */
15static int sign_is_valid( const mbedtls_mpi *X )
16{
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010017 /* Only +1 and -1 are valid sign bits, not e.g. 0 */
Gilles Peskinedffc7102021-06-10 15:34:15 +020018 if( X->s != 1 && X->s != -1 )
Gilles Peskineca6e8aa2022-11-09 21:08:44 +010019 return( 0 );
20
21 /* The value 0 must be represented with the sign +1. A "negative zero"
22 * with s=-1 is an invalid representation. Forbid that. As an exception,
23 * we sometimes test the robustness of library functions when given
24 * a negative zero input. If a test case has a negative zero as input,
25 * we don't mind if the function has a negative zero output. */
26 if( ! mbedtls_test_case_uses_negative_0 &&
27 mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
28 {
29 return( 0 );
30 }
31
Gilles Peskinedffc7102021-06-10 15:34:15 +020032 return( 1 );
33}
34
Janos Follath64eca052018-09-05 17:04:49 +010035typedef struct mbedtls_test_mpi_random
36{
37 data_t *data;
38 size_t pos;
39 size_t chunk_len;
40} mbedtls_test_mpi_random;
41
42/*
43 * This function is called by the Miller-Rabin primality test each time it
44 * chooses a random witness. The witnesses (or non-witnesses as provided by the
45 * test) are stored in the data member of the state structure. Each number is in
46 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
47 */
48int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
49 unsigned char* buf,
50 size_t len )
51{
52 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
53
54 if( random == NULL || random->data->x == NULL || buf == NULL )
55 return( -1 );
56
57 if( random->pos + random->chunk_len > random->data->len
58 || random->chunk_len > len )
59 {
60 return( -1 );
61 }
62
63 memset( buf, 0, len );
64
65 /* The witness is written to the end of the buffer, since the buffer is
66 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
67 * Writing the witness to the start of the buffer would result in the
68 * buffer being 'witness 000...000', which would be treated as
69 * witness * 2^n for some n. */
70 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
71 random->chunk_len );
72
73 random->pos += random->chunk_len;
74
75 return( 0 );
76}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010077
78/* Random generator that is told how many bytes to return. */
79static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
80{
81 size_t *bytes_left = state;
82 size_t i;
83 for( i = 0; i < len; i++ )
84 {
85 if( *bytes_left == 0 )
86 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
87 buf[i] = *bytes_left & 0xff;
88 --( *bytes_left );
89 }
90 return( 0 );
91}
92
Gilles Peskineeedefa52021-04-13 19:50:04 +020093/* Test whether bytes represents (in big-endian base 256) a number b that
94 * is significantly above a power of 2. That is, b must not have a long run
95 * of unset bits after the most significant bit.
96 *
97 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
98 * This function returns 1 if, when drawing a number between 0 and b,
99 * the probability that this number is at least 2^n is not negligible.
100 * This probability is (b - 2^n) / b and this function checks that this
101 * number is above some threshold A. The threshold value is heuristic and
102 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200103 */
104static int is_significantly_above_a_power_of_2( data_t *bytes )
105{
106 const uint8_t *p = bytes->x;
107 size_t len = bytes->len;
108 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200109
110 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200111 while( len > 0 && p[0] == 0 )
112 {
113 ++p;
114 --len;
115 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200116 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200117 if( len == 0 )
118 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200119 /* Extract the (up to) 2 most significant bytes */
120 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200121 x = p[0];
122 else
123 x = ( p[0] << 8 ) | p[1];
124
Gilles Peskineeedefa52021-04-13 19:50:04 +0200125 /* Shift the most significant bit of x to position 8 and mask it out */
126 while( ( x & 0xfe00 ) != 0 )
127 x >>= 1;
128 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200129
Gilles Peskineeedefa52021-04-13 19:50:04 +0200130 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
131 * a power of 2 iff x is significantly above 0 compared to 2^8.
132 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
133 * description above. */
134 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200135}
136
Paul Bakker33b43f12013-08-20 11:48:36 +0200137/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000138
Paul Bakker33b43f12013-08-20 11:48:36 +0200139/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200140 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200141 * END_DEPENDENCIES
142 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000143
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000144/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100145void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200146{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200147 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200148
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200149 mbedtls_mpi_init( &X );
150 mbedtls_mpi_init( &Y );
151 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200152
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200153 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
154 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200155 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200156 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200157
158exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200159 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200160}
161/* END_CASE */
162
163/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100164void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
165 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200166 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000167{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200168 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000169 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100170 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000171
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200172 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000173
Janos Follath04dadb72019-03-06 12:29:37 +0000174 memset( str, '!', sizeof( str ) );
175
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200176 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200177 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000178 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200179 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100180 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200181 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000182 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200183 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000184 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000185 }
186 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000187
Paul Bakkerbd51b262014-07-10 15:26:12 +0200188exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200189 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000190}
Paul Bakker33b43f12013-08-20 11:48:36 +0200191/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000192
Paul Bakker33b43f12013-08-20 11:48:36 +0200193/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100194void mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000195{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200196 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000197 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100198 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000199
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000201
Paul Bakkere896fea2009-07-06 06:40:23 +0000202
Azim Khand30ca132017-06-09 04:32:58 +0100203 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200204 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100205 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100206 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000207
Paul Bakkerbd51b262014-07-10 15:26:12 +0200208exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200209 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000210}
Paul Bakker33b43f12013-08-20 11:48:36 +0200211/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000212
Paul Bakker33b43f12013-08-20 11:48:36 +0200213/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100214void mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000215{
216 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000217 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000218 size_t len;
219
220 mbedtls_mpi_init( &X );
221
222
223 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200224 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100225 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100226 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000227
228exit:
229 mbedtls_mpi_free( &X );
230}
231/* END_CASE */
232
233/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100234void mpi_write_binary( char * input_X, data_t * input_A,
235 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000236{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200237 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000238 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000239 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000240
241 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200243 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000244
Werner Lewis19b4cd82022-07-07 11:02:27 +0100245 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100246
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200248 if( buflen > (size_t) output_size )
249 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200252 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000253 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000254
Ronald Cron2dbba992020-06-10 11:42:32 +0200255 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
256 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000257 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000258
Paul Bakkerbd51b262014-07-10 15:26:12 +0200259exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000261}
Paul Bakker33b43f12013-08-20 11:48:36 +0200262/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000263
Janos Follathe344d0f2019-02-19 16:17:40 +0000264/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100265void mpi_write_binary_le( char * input_X, data_t * input_A,
266 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000267{
268 mbedtls_mpi X;
269 unsigned char buf[1000];
270 size_t buflen;
271
272 memset( buf, 0x00, 1000 );
273
274 mbedtls_mpi_init( &X );
275
Werner Lewis19b4cd82022-07-07 11:02:27 +0100276 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000277
278 buflen = mbedtls_mpi_size( &X );
279 if( buflen > (size_t) output_size )
280 buflen = (size_t) output_size;
281
282 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
283 if( result == 0)
284 {
285
Ronald Cron2dbba992020-06-10 11:42:32 +0200286 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
287 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000288 }
289
290exit:
291 mbedtls_mpi_free( &X );
292}
293/* END_CASE */
294
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200295/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100296void mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000297{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200298 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000299 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000300 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000301 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000302 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000303
304 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200306 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000307
Paul Bakker33b43f12013-08-20 11:48:36 +0200308 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200309 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100310 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000311 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000312 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000313
Paul Bakker33b43f12013-08-20 11:48:36 +0200314 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000315 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200316 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200317 buflen = mbedtls_mpi_size( &X );
318 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000319
Paul Bakkere896fea2009-07-06 06:40:23 +0000320
Ronald Cron2dbba992020-06-10 11:42:32 +0200321 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
322 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000323 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000324
Paul Bakkerbd51b262014-07-10 15:26:12 +0200325exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200326 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000327}
Paul Bakker33b43f12013-08-20 11:48:36 +0200328/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000329
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200330/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100331void mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000332{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000334 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200335 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000336
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000338
Werner Lewis19b4cd82022-07-07 11:02:27 +0100339 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000340
Paul Bakker33b43f12013-08-20 11:48:36 +0200341 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000342 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100343 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000344 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200345 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000346
Paul Bakker33b43f12013-08-20 11:48:36 +0200347 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000348 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100349 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000350 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200351 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000354
Paul Bakkerbd51b262014-07-10 15:26:12 +0200355exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000357}
Paul Bakker33b43f12013-08-20 11:48:36 +0200358/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000359
Paul Bakker33b43f12013-08-20 11:48:36 +0200360/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100361void mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000362{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_mpi X;
364 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100365 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000367
Paul Bakkerbd51b262014-07-10 15:26:12 +0200368exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200369 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000370}
Paul Bakker33b43f12013-08-20 11:48:36 +0200371/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000372
Paul Bakker33b43f12013-08-20 11:48:36 +0200373/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100374void mpi_set_bit( char * input_X, int pos, int val,
375 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000376{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_mpi X, Y;
378 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000379
Werner Lewis19b4cd82022-07-07 11:02:27 +0100380 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
381 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100382 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
383
384 if( result == 0 )
385 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200386 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100387 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
388 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000389
Paul Bakkerbd51b262014-07-10 15:26:12 +0200390exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000392}
Paul Bakker33b43f12013-08-20 11:48:36 +0200393/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000394
Paul Bakker33b43f12013-08-20 11:48:36 +0200395/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100396void mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000397{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398 mbedtls_mpi X;
399 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000400
Werner Lewis19b4cd82022-07-07 11:02:27 +0100401 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000403
Paul Bakkerbd51b262014-07-10 15:26:12 +0200404exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000406}
Paul Bakker33b43f12013-08-20 11:48:36 +0200407/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000408
Paul Bakker33b43f12013-08-20 11:48:36 +0200409/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100410void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000411{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200412 mbedtls_mpi X;
413 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000414
Werner Lewis19b4cd82022-07-07 11:02:27 +0100415 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200416 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000417
Paul Bakkerbd51b262014-07-10 15:26:12 +0200418exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200419 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000420}
Paul Bakker33b43f12013-08-20 11:48:36 +0200421/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000422
Paul Bakker33b43f12013-08-20 11:48:36 +0200423/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100424void mpi_gcd( char * input_X, char * input_Y,
425 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000426{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_mpi A, X, Y, Z;
428 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000429
Werner Lewis19b4cd82022-07-07 11:02:27 +0100430 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
431 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
432 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200433 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200434 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000436
Paul Bakkerbd51b262014-07-10 15:26:12 +0200437exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000439}
Paul Bakker33b43f12013-08-20 11:48:36 +0200440/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000441
Paul Bakker33b43f12013-08-20 11:48:36 +0200442/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100443void mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000444{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200445 mbedtls_mpi X;
446 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000447
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200448 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
449 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000450
Paul Bakkerbd51b262014-07-10 15:26:12 +0200451exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000453}
Paul Bakker33b43f12013-08-20 11:48:36 +0200454/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000455
Paul Bakker33b43f12013-08-20 11:48:36 +0200456/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100457void mpi_cmp_mpi( char * input_X, char * input_Y,
458 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000459{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200460 mbedtls_mpi X, Y;
461 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000462
Werner Lewis19b4cd82022-07-07 11:02:27 +0100463 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
464 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000466
Paul Bakkerbd51b262014-07-10 15:26:12 +0200467exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000469}
Paul Bakker33b43f12013-08-20 11:48:36 +0200470/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000471
Paul Bakker33b43f12013-08-20 11:48:36 +0200472/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100473void mpi_lt_mpi_ct( int size_X, char * input_X,
474 int size_Y, char * input_Y,
475 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100476{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200477 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100478 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100479 mbedtls_mpi X, Y;
480 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
481
Werner Lewis19b4cd82022-07-07 11:02:27 +0100482 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
483 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100484
Gilles Peskine9018b112020-01-21 16:30:53 +0100485 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
486 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100487
Janos Follath0e5532d2019-10-11 14:21:53 +0100488 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100489 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100490 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100491
492exit:
493 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
494}
495/* END_CASE */
496
497/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100498void mpi_cmp_abs( char * input_X, char * input_Y,
499 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000500{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_mpi X, Y;
502 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000503
Werner Lewis19b4cd82022-07-07 11:02:27 +0100504 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
505 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200506 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000507
Paul Bakkerbd51b262014-07-10 15:26:12 +0200508exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000510}
Paul Bakker33b43f12013-08-20 11:48:36 +0200511/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000512
Paul Bakker33b43f12013-08-20 11:48:36 +0200513/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100514void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000515{
Gilles Peskined0722f82021-06-10 23:00:33 +0200516 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200517 mbedtls_mpi_init( &src );
518 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200519 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000520
Werner Lewis19b4cd82022-07-07 11:02:27 +0100521 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
522 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200523
524 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100525 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200526 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200527 TEST_ASSERT( sign_is_valid( &dst ) );
528 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000529
Gilles Peskined0722f82021-06-10 23:00:33 +0200530 /* mbedtls_mpi_safe_cond_assign(), assignment done */
531 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100532 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200533 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
534 TEST_ASSERT( sign_is_valid( &dst ) );
535 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
536
537 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
538 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100539 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200540 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
541 TEST_ASSERT( sign_is_valid( &dst ) );
542 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
543
Paul Bakkerbd51b262014-07-10 15:26:12 +0200544exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200545 mbedtls_mpi_free( &src );
546 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200547 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100548}
549/* END_CASE */
550
551/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200552void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100553{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200554 mbedtls_mpi X, A;
555 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000557
Werner Lewis19b4cd82022-07-07 11:02:27 +0100558 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200559 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200560
Werner Lewis19b4cd82022-07-07 11:02:27 +0100561 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200562 TEST_ASSERT( sign_is_valid( &X ) );
563 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000564
Paul Bakkerbd51b262014-07-10 15:26:12 +0200565exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200566 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200567 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000568}
Paul Bakker33b43f12013-08-20 11:48:36 +0200569/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000570
Paul Bakker33b43f12013-08-20 11:48:36 +0200571/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100572void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200573{
574 mbedtls_mpi X, Y, X0, Y0;
575 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
576 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
577
Werner Lewis19b4cd82022-07-07 11:02:27 +0100578 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
579 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200580
Gilles Peskined0722f82021-06-10 23:00:33 +0200581 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100582 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
583 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200584 mbedtls_mpi_swap( &X, &Y );
585 TEST_ASSERT( sign_is_valid( &X ) );
586 TEST_ASSERT( sign_is_valid( &Y ) );
587 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
588 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
589
Gilles Peskined0722f82021-06-10 23:00:33 +0200590 /* mbedtls_mpi_safe_cond_swap(), swap done */
591 mbedtls_mpi_free( &X );
592 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100593 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
594 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200595 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
596 TEST_ASSERT( sign_is_valid( &X ) );
597 TEST_ASSERT( sign_is_valid( &Y ) );
598 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
599 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
600
601 /* mbedtls_mpi_safe_cond_swap(), swap not done */
602 mbedtls_mpi_free( &X );
603 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100604 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
605 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200606 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
607 TEST_ASSERT( sign_is_valid( &X ) );
608 TEST_ASSERT( sign_is_valid( &Y ) );
609 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
610 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
611
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200612exit:
613 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
614 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
615}
616/* END_CASE */
617
618/* BEGIN_CASE */
619void mpi_swap_self( char *X_hex )
620{
621 mbedtls_mpi X, X0;
622 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
623
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100624 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100625 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200626
627 mbedtls_mpi_swap( &X, &X );
628 TEST_ASSERT( sign_is_valid( &X ) );
629 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
630
631exit:
632 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
633}
634/* END_CASE */
635
636/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100637void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100638{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_mpi X;
640 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100641
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200642 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200643 if( used > 0 )
644 {
645 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
646 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
647 }
648 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200650 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100651
Paul Bakkerbd51b262014-07-10 15:26:12 +0200652exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200653 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100654}
655/* END_CASE */
656
657/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100658void mpi_add_mpi( char * input_X, char * input_Y,
659 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000660{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200661 mbedtls_mpi X, Y, Z, A;
662 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000663
Werner Lewis19b4cd82022-07-07 11:02:27 +0100664 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
665 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
666 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200667 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200668 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000670
Gilles Peskine56f943a2020-07-23 01:18:11 +0200671 /* result == first operand */
672 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200673 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200674 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100675 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200676
677 /* result == second operand */
678 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200679 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200680 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
681
Paul Bakkerbd51b262014-07-10 15:26:12 +0200682exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000684}
Paul Bakker33b43f12013-08-20 11:48:36 +0200685/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000686
Paul Bakker33b43f12013-08-20 11:48:36 +0200687/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100688void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100689{
690 mbedtls_mpi X, A;
691 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
692
Werner Lewis19b4cd82022-07-07 11:02:27 +0100693 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100694
Werner Lewis19b4cd82022-07-07 11:02:27 +0100695 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100696 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
697 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200698 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100699
Werner Lewis19b4cd82022-07-07 11:02:27 +0100700 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100701 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200702 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100703 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
704
Werner Lewis19b4cd82022-07-07 11:02:27 +0100705 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100706 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200707 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100708 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
709
710exit:
711 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
712}
713/* END_CASE */
714
715
716/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100717void mpi_add_abs( char * input_X, char * input_Y,
718 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000719{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720 mbedtls_mpi X, Y, Z, A;
721 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000722
Werner Lewis19b4cd82022-07-07 11:02:27 +0100723 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
724 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
725 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200727 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200728 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000729
Gilles Peskine56f943a2020-07-23 01:18:11 +0200730 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200732 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100734 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200735
736 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200738 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000740
Paul Bakkerbd51b262014-07-10 15:26:12 +0200741exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200742 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000743}
Paul Bakker33b43f12013-08-20 11:48:36 +0200744/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000745
Paul Bakker33b43f12013-08-20 11:48:36 +0200746/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100747void mpi_add_int( char * input_X, int input_Y,
748 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000749{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200750 mbedtls_mpi X, Z, A;
751 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000752
Werner Lewis19b4cd82022-07-07 11:02:27 +0100753 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
754 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200755 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200756 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200757 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000758
Paul Bakkerbd51b262014-07-10 15:26:12 +0200759exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200760 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000761}
Paul Bakker33b43f12013-08-20 11:48:36 +0200762/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000763
Paul Bakker33b43f12013-08-20 11:48:36 +0200764/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100765void mpi_sub_mpi( char * input_X, char * input_Y,
766 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000767{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200768 mbedtls_mpi X, Y, Z, A;
769 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000770
Werner Lewis19b4cd82022-07-07 11:02:27 +0100771 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
772 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
773 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200774 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200775 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200776 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000777
Gilles Peskine56f943a2020-07-23 01:18:11 +0200778 /* result == first operand */
779 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200780 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200781 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100782 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200783
784 /* result == second operand */
785 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200786 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200787 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
788
Paul Bakkerbd51b262014-07-10 15:26:12 +0200789exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000791}
Paul Bakker33b43f12013-08-20 11:48:36 +0200792/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000793
Paul Bakker33b43f12013-08-20 11:48:36 +0200794/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100795void mpi_sub_abs( char * input_X, char * input_Y,
796 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000797{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200798 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000799 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000801
Werner Lewis19b4cd82022-07-07 11:02:27 +0100802 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
803 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
804 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100805
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200806 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200807 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200808 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000809 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200810 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000811
Gilles Peskine56f943a2020-07-23 01:18:11 +0200812 /* result == first operand */
813 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200814 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200815 if( sub_result == 0 )
816 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100817 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200818
819 /* result == second operand */
820 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200821 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200822 if( sub_result == 0 )
823 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
824
Paul Bakkerbd51b262014-07-10 15:26:12 +0200825exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000827}
Paul Bakker33b43f12013-08-20 11:48:36 +0200828/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000829
Paul Bakker33b43f12013-08-20 11:48:36 +0200830/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100831void mpi_sub_int( char * input_X, int input_Y,
832 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000833{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200834 mbedtls_mpi X, Z, A;
835 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000836
Werner Lewis19b4cd82022-07-07 11:02:27 +0100837 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
838 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200839 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200840 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200841 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000842
Paul Bakkerbd51b262014-07-10 15:26:12 +0200843exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000845}
Paul Bakker33b43f12013-08-20 11:48:36 +0200846/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000847
Paul Bakker33b43f12013-08-20 11:48:36 +0200848/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100849void mpi_mul_mpi( char * input_X, char * input_Y,
850 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000851{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200852 mbedtls_mpi X, Y, Z, A;
853 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000854
Werner Lewis19b4cd82022-07-07 11:02:27 +0100855 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
856 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
857 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200858 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200859 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000861
Paul Bakkerbd51b262014-07-10 15:26:12 +0200862exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000864}
Paul Bakker33b43f12013-08-20 11:48:36 +0200865/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000866
Paul Bakker33b43f12013-08-20 11:48:36 +0200867/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100868void mpi_mul_int( char * input_X, int input_Y,
869 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000870{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 mbedtls_mpi X, Z, A;
872 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000873
Werner Lewis19b4cd82022-07-07 11:02:27 +0100874 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
875 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200877 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200878 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200879 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200880 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200882 else
883 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000884
Paul Bakkerbd51b262014-07-10 15:26:12 +0200885exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200886 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000887}
Paul Bakker33b43f12013-08-20 11:48:36 +0200888/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000889
Paul Bakker33b43f12013-08-20 11:48:36 +0200890/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100891void mpi_div_mpi( char * input_X, char * input_Y,
892 char * input_A, char * input_B,
893 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000894{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000896 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200897 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
898 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000899
Werner Lewis19b4cd82022-07-07 11:02:27 +0100900 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
901 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
902 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
903 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200904 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200905 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000906 if( res == 0 )
907 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200908 TEST_ASSERT( sign_is_valid( &Q ) );
909 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200910 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
911 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000912 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000913
Paul Bakkerbd51b262014-07-10 15:26:12 +0200914exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200915 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
916 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000917}
Paul Bakker33b43f12013-08-20 11:48:36 +0200918/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000919
Paul Bakker33b43f12013-08-20 11:48:36 +0200920/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100921void mpi_div_int( char * input_X, int input_Y,
922 char * input_A, char * input_B,
923 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000924{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000926 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
928 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000929
Werner Lewis19b4cd82022-07-07 11:02:27 +0100930 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
931 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
932 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200933 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200934 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000935 if( res == 0 )
936 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200937 TEST_ASSERT( sign_is_valid( &Q ) );
938 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200939 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
940 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000941 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000942
Paul Bakkerbd51b262014-07-10 15:26:12 +0200943exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
945 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000946}
Paul Bakker33b43f12013-08-20 11:48:36 +0200947/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000948
Paul Bakker33b43f12013-08-20 11:48:36 +0200949/* BEGIN_CASE */
Werner Lewis6baf12b2022-10-19 12:46:35 +0100950void mpi_mod_mpi( char * input_X, char * input_Y,
951 char * input_A, int div_result )
952{
953 mbedtls_mpi X, Y, A;
954 int res;
955 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
956
957 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
958 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
959 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
960 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
961 TEST_ASSERT( res == div_result );
962 if( res == 0 )
963 {
964 TEST_ASSERT( sign_is_valid( &X ) );
965 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
966 }
967
968exit:
969 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
970}
971/* END_CASE */
972
973/* BEGIN_CASE */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000974void mpi_mod_int( char * input_X, char * input_Y,
975 char * input_A, int mod_result )
Werner Lewis6baf12b2022-10-19 12:46:35 +0100976{
977 mbedtls_mpi X;
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000978 mbedtls_mpi Y;
979 mbedtls_mpi A;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100980 int res;
981 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100982
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000983 mbedtls_mpi_init( &X );
984 mbedtls_mpi_init( &Y );
985 mbedtls_mpi_init( &A );
986
987 /* We use MPIs to read Y and A since the test framework limits us to
988 * ints, so we can't have 64-bit values */
989 TEST_EQUAL( mbedtls_test_read_mpi( &X, input_X ), 0 );
990 TEST_EQUAL( mbedtls_test_read_mpi( &Y, input_Y ), 0 );
991 TEST_EQUAL( mbedtls_test_read_mpi( &A, input_A ), 0 );
992
993 TEST_EQUAL( Y.n, 1 );
994 TEST_EQUAL( A.n, 1 );
995
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000996 /* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
997
998 /* Since we're converting sign+magnitude to two's complement, we lose one
999 * bit of value in the output. This means there are some values we can't
1000 * represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
1001 * invalid test cases, so could be considered "won't happen", but they are
1002 * easy to test for, and this helps guard against human error. */
1003
1004 mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
1005 TEST_ASSERT( y >= 0 ); /* If y < 0 here, we can't make negative y */
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001006 if( Y.s == -1 )
1007 y = -y;
Tom Cosgrove9feb19f2022-11-10 12:05:55 +00001008
1009 mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
1010 TEST_ASSERT( a >= 0 ); /* Same goes for a */
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001011 if( A.s == -1 )
1012 a = -a;
1013
1014 res = mbedtls_mpi_mod_int( &r, &X, y );
1015 TEST_EQUAL( res, mod_result );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001016 if( res == 0 )
1017 {
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001018 TEST_EQUAL( r, a );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001019 }
1020
1021exit:
1022 mbedtls_mpi_free( &X );
Tom Cosgrove91e35e32022-11-09 11:45:29 +00001023 mbedtls_mpi_free( &Y );
1024 mbedtls_mpi_free( &A );
Werner Lewis6baf12b2022-10-19 12:46:35 +01001025}
1026/* END_CASE */
1027
1028/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001029void mpi_exp_mod( char * input_A, char * input_E,
1030 char * input_N, char * input_X,
1031 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001032{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001034 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1036 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001037
Werner Lewis19b4cd82022-07-07 11:02:27 +01001038 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1039 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1040 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1041 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001042
Gilles Peskine342f71b2021-06-09 18:31:35 +02001043 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001044 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001045 if( res == 0 )
1046 {
1047 TEST_ASSERT( sign_is_valid( &Z ) );
1048 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1049 }
1050
1051 /* Now test again with the speed-up parameter supplied as an output. */
1052 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001053 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001054 if( res == 0 )
1055 {
1056 TEST_ASSERT( sign_is_valid( &Z ) );
1057 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1058 }
1059
1060 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001061 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001062 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001063 if( res == 0 )
1064 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001065 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001066 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001067 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001068
Paul Bakkerbd51b262014-07-10 15:26:12 +02001069exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001070 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1071 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001072}
Paul Bakker33b43f12013-08-20 11:48:36 +02001073/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001074
Paul Bakker33b43f12013-08-20 11:48:36 +02001075/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001076void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1077 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001078{
1079 mbedtls_mpi A, E, N, RR, Z;
1080 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1081 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1082
Chris Jonesaa850cd2020-12-03 11:35:41 +00001083 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001084 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001085 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001086 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001087
1088 /* Set E to 2^(E_bytes - 1) + 1 */
1089 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1090 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001091 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001092
1093 /* Set N to 2^(N_bytes - 1) + 1 */
1094 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1095 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001096 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1097
1098 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001099 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001100
Chris Jonesaa850cd2020-12-03 11:35:41 +00001101 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001102
1103exit:
1104 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1105 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1106}
1107/* END_CASE */
1108
1109/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001110void mpi_inv_mod( char * input_X, char * input_Y,
1111 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001112{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001114 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001116
Werner Lewis19b4cd82022-07-07 11:02:27 +01001117 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1118 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1119 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001121 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001122 if( res == 0 )
1123 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001124 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001125 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001126 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001127
Paul Bakkerbd51b262014-07-10 15:26:12 +02001128exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001130}
Paul Bakker33b43f12013-08-20 11:48:36 +02001131/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001132
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001134void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001135{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001137 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001138 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001139
Werner Lewis19b4cd82022-07-07 11:02:27 +01001140 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001141 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001142 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001143
Paul Bakkerbd51b262014-07-10 15:26:12 +02001144exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001145 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001146}
Paul Bakker33b43f12013-08-20 11:48:36 +02001147/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001148
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001149/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001150void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1151 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001152{
1153 mbedtls_mpi X;
1154 int res;
1155 mbedtls_test_mpi_random rand;
1156
1157 mbedtls_mpi_init( &X );
1158 rand.data = witnesses;
1159 rand.pos = 0;
1160 rand.chunk_len = chunk_len;
1161
1162 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001163 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1164 mbedtls_test_mpi_miller_rabin_determinizer,
1165 &rand );
1166 TEST_ASSERT( res == 0 );
1167
1168 rand.data = witnesses;
1169 rand.pos = 0;
1170 rand.chunk_len = chunk_len;
1171
Janos Follatha0b67c22018-09-18 14:48:23 +01001172 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1173 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001174 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001175 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001176
1177exit:
1178 mbedtls_mpi_free( &X );
1179}
1180/* END_CASE */
1181
1182/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001183void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001184{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001185 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001186 int my_ret;
1187
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001189
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001190 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1191 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001192 TEST_ASSERT( my_ret == ref_ret );
1193
1194 if( ref_ret == 0 )
1195 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001196 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001197
1198 TEST_ASSERT( actual_bits >= (size_t) bits );
1199 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001200 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001201
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001202 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1203 mbedtls_test_rnd_std_rand,
1204 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001205 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001206 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001207 /* X = ( X - 1 ) / 2 */
1208 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001209 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1210 mbedtls_test_rnd_std_rand,
1211 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001212 }
1213 }
1214
Paul Bakkerbd51b262014-07-10 15:26:12 +02001215exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001216 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001217}
1218/* END_CASE */
1219
Paul Bakker33b43f12013-08-20 11:48:36 +02001220/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001221void mpi_shift_l( char * input_X, int shift_X,
1222 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001223{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001224 mbedtls_mpi X, A;
1225 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001226
Werner Lewis19b4cd82022-07-07 11:02:27 +01001227 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1228 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001229 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001230 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001231 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001232
Paul Bakkerbd51b262014-07-10 15:26:12 +02001233exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001235}
Paul Bakker33b43f12013-08-20 11:48:36 +02001236/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001237
Paul Bakker33b43f12013-08-20 11:48:36 +02001238/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001239void mpi_shift_r( char * input_X, int shift_X,
1240 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001241{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242 mbedtls_mpi X, A;
1243 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001244
Werner Lewis19b4cd82022-07-07 11:02:27 +01001245 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1246 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001247 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001248 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001249 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001250
Paul Bakkerbd51b262014-07-10 15:26:12 +02001251exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001252 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001253}
Paul Bakker33b43f12013-08-20 11:48:36 +02001254/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001255
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001256/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001257void mpi_fill_random( int wanted_bytes, int rng_bytes,
1258 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001259{
1260 mbedtls_mpi X;
1261 int ret;
1262 size_t bytes_left = rng_bytes;
1263 mbedtls_mpi_init( &X );
1264
Gilles Peskine422e8672021-04-02 00:02:27 +02001265 if( before != 0 )
1266 {
1267 /* Set X to sign(before) * 2^(|before|-1) */
1268 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1269 if( before < 0 )
1270 before = - before;
1271 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1272 }
1273
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001274 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1275 f_rng_bytes_left, &bytes_left );
1276 TEST_ASSERT( ret == expected_ret );
1277
1278 if( expected_ret == 0 )
1279 {
1280 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1281 * as a big-endian representation of the number. We know when
1282 * our RNG function returns null bytes, so we know how many
1283 * leading zero bytes the number has. */
1284 size_t leading_zeros = 0;
1285 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1286 leading_zeros = 1;
1287 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1288 (size_t) wanted_bytes );
1289 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001290 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001291 }
1292
1293exit:
1294 mbedtls_mpi_free( &X );
1295}
1296/* END_CASE */
1297
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001298/* BEGIN_CASE */
Gilles Peskine34e8a2c2022-09-27 22:04:51 +02001299void mpi_random_values( int min, char *max_hex )
1300{
1301 mbedtls_test_rnd_pseudo_info rnd_core = {
1302 {'T', 'h', 'i', 's', ' ', 'i', ',', 'a',
1303 's', 'e', 'e', 'd', '!', 0},
1304 0, 0};
1305 mbedtls_test_rnd_pseudo_info rnd_legacy;
1306 memcpy( &rnd_legacy, &rnd_core, sizeof( rnd_core ) );
1307 mbedtls_mpi max_legacy;
1308 mbedtls_mpi_init( &max_legacy );
1309 mbedtls_mpi_uint *R_core = NULL;
1310 mbedtls_mpi R_legacy;
1311 mbedtls_mpi_init( &R_legacy );
1312
1313 TEST_EQUAL( 0, mbedtls_test_read_mpi( &max_legacy, max_hex ) );
1314 size_t limbs = max_legacy.n;
1315 ASSERT_ALLOC( R_core, limbs * ciL );
1316
1317 /* Call the legacy function and the core function with the same random
1318 * stream. */
1319 int core_ret = mbedtls_mpi_core_random( R_core, min, max_legacy.p, limbs,
1320 mbedtls_test_rnd_pseudo_rand,
1321 &rnd_core );
1322 int legacy_ret = mbedtls_mpi_random( &R_legacy, min, &max_legacy,
1323 mbedtls_test_rnd_pseudo_rand,
1324 &rnd_legacy );
1325
1326 /* They must return the same status, and, on success, output the
1327 * same number, with the same limb count. */
1328 TEST_EQUAL( core_ret, legacy_ret );
1329 if( core_ret == 0 )
1330 {
1331 ASSERT_COMPARE( R_core, limbs * ciL,
1332 R_legacy.p, R_legacy.n * ciL );
1333 }
1334
1335 /* Also check that they have consumed the RNG in the same way. */
1336 /* This may theoretically fail on rare platforms with padding in
1337 * the structure! If this is a problem in practice, change to a
1338 * field-by-field comparison. */
1339 ASSERT_COMPARE( &rnd_core, sizeof( rnd_core ),
1340 &rnd_legacy, sizeof( rnd_legacy ) );
1341
1342exit:
1343 mbedtls_mpi_free( &max_legacy );
1344 mbedtls_free( R_core );
1345 mbedtls_mpi_free( &R_legacy );
1346}
1347/* END_CASE */
1348
1349/* BEGIN_CASE */
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001350void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1351{
1352 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1353 * This function assumes that the value of bound is at least 2 and
1354 * that iterations is large enough that a one-in-2^iterations chance
1355 * effectively never occurs.
1356 */
1357
1358 mbedtls_mpi upper_bound;
1359 size_t n_bits;
1360 mbedtls_mpi result;
1361 size_t b;
1362 /* If upper_bound is small, stats[b] is the number of times the value b
1363 * has been generated. Otherwise stats[b] is the number of times a
1364 * value with bit b set has been generated. */
1365 size_t *stats = NULL;
1366 size_t stats_len;
1367 int full_stats;
1368 size_t i;
1369
1370 mbedtls_mpi_init( &upper_bound );
1371 mbedtls_mpi_init( &result );
1372
1373 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1374 bound_bytes->x, bound_bytes->len ) );
1375 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1376 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1377 * to be small enough that the probability of missing one value is
1378 * negligible given the number of iterations. It must be less than
1379 * 256 because some of the code below assumes that "small" values
1380 * fit in a byte. */
1381 if( n_bits <= 5 )
1382 {
1383 full_stats = 1;
1384 stats_len = bound_bytes->x[bound_bytes->len - 1];
1385 }
1386 else
1387 {
1388 full_stats = 0;
1389 stats_len = n_bits;
1390 }
1391 ASSERT_ALLOC( stats, stats_len );
1392
1393 for( i = 0; i < (size_t) iterations; i++ )
1394 {
1395 mbedtls_test_set_step( i );
1396 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1397 mbedtls_test_rnd_std_rand, NULL ) );
1398
Gilles Peskinedffc7102021-06-10 15:34:15 +02001399 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001400 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1401 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1402 if( full_stats )
1403 {
1404 uint8_t value;
1405 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1406 TEST_ASSERT( value < stats_len );
1407 ++stats[value];
1408 }
1409 else
1410 {
1411 for( b = 0; b < n_bits; b++ )
1412 stats[b] += mbedtls_mpi_get_bit( &result, b );
1413 }
1414 }
1415
1416 if( full_stats )
1417 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001418 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001419 {
1420 mbedtls_test_set_step( 1000000 + b );
1421 /* Assert that each value has been reached at least once.
1422 * This is almost guaranteed if the iteration count is large
1423 * enough. This is a very crude way of checking the distribution.
1424 */
1425 TEST_ASSERT( stats[b] > 0 );
1426 }
1427 }
1428 else
1429 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001430 int statistically_safe_all_the_way =
1431 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001432 for( b = 0; b < n_bits; b++ )
1433 {
1434 mbedtls_test_set_step( 1000000 + b );
1435 /* Assert that each bit has been set in at least one result and
1436 * clear in at least one result. Provided that iterations is not
1437 * too small, it would be extremely unlikely for this not to be
1438 * the case if the results are uniformly distributed.
1439 *
1440 * As an exception, the top bit may legitimately never be set
1441 * if bound is a power of 2 or only slightly above.
1442 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001443 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001444 {
1445 TEST_ASSERT( stats[b] > 0 );
1446 }
1447 TEST_ASSERT( stats[b] < (size_t) iterations );
1448 }
1449 }
1450
1451exit:
1452 mbedtls_mpi_free( &upper_bound );
1453 mbedtls_mpi_free( &result );
1454 mbedtls_free( stats );
1455}
1456/* END_CASE */
1457
Gilles Peskine1e918f42021-03-29 22:14:51 +02001458/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001459void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001460{
1461 mbedtls_mpi upper_bound;
1462 mbedtls_mpi result;
1463
1464 mbedtls_mpi_init( &upper_bound );
1465 mbedtls_mpi_init( &result );
1466
Gilles Peskine422e8672021-04-02 00:02:27 +02001467 if( before != 0 )
1468 {
1469 /* Set result to sign(before) * 2^(|before|-1) */
1470 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1471 if( before < 0 )
1472 before = - before;
1473 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1474 }
1475
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001476 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1477 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1478 bound_bytes->x, bound_bytes->len ) );
1479 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1480 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001481 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001482 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1483 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1484
1485exit:
1486 mbedtls_mpi_free( &upper_bound );
1487 mbedtls_mpi_free( &result );
1488}
1489/* END_CASE */
1490
1491/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001492void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1493{
1494 mbedtls_mpi upper_bound;
1495 mbedtls_mpi result;
1496 int actual_ret;
1497
1498 mbedtls_mpi_init( &upper_bound );
1499 mbedtls_mpi_init( &result );
1500
1501 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1502 bound_bytes->x, bound_bytes->len ) );
1503 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1504 mbedtls_test_rnd_std_rand, NULL );
1505 TEST_EQUAL( expected_ret, actual_ret );
1506
1507exit:
1508 mbedtls_mpi_free( &upper_bound );
1509 mbedtls_mpi_free( &result );
1510}
1511/* END_CASE */
1512
Gilles Peskineaf601f92022-11-15 23:02:14 +01001513/* BEGIN_CASE */
1514void most_negative_mpi_sint( )
1515{
1516 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1517 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1518 * is a valid value. However, negating it (`-n`) has undefined behavior
1519 * (although in practice `-n` evaluates to the value n).
1520 *
1521 * This function has ad hoc tests for this value. It's separated from other
1522 * functions because the test framework makes it hard to pass this value
1523 * into test cases.
1524 *
1525 * In the comments here:
1526 * - biL = number of bits in limbs
1527 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1528 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1529 */
1530
1531 mbedtls_mpi A, R, X;
1532 mbedtls_mpi_init( &A );
1533 mbedtls_mpi_init( &R );
1534 mbedtls_mpi_init( &X );
1535
Gilles Peskineaf601f92022-11-15 23:02:14 +01001536 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << ( biL - 1 );
1537 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
1538 const mbedtls_mpi_sint most_negative = - most_positive - 1;
1539 TEST_EQUAL( (mbedtls_mpi_uint) most_negative,
1540 (mbedtls_mpi_uint) 1 << ( biL - 1 ) );
1541 TEST_EQUAL( (mbedtls_mpi_uint) most_negative << 1, 0 );
1542
1543 /* Test mbedtls_mpi_lset() */
1544 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1545 TEST_EQUAL( A.s, -1 );
1546 TEST_EQUAL( A.n, 1 );
1547 TEST_EQUAL( A.p[0], most_positive_plus_1 );
1548
1549 /* Test mbedtls_mpi_cmp_int(): -p == -p */
1550 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 0 );
1551
1552 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1553 A.p[0] = most_positive_plus_1 + 1;
1554 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), -1 );
1555
1556 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1557 A.p[0] = most_positive_plus_1 - 1;
1558 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 1 );
1559
1560 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
1561 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1562 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1563 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
1564
1565 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
1566 TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
1567 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1568 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, most_negative ), 0 );
1569
1570 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
1571 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1572 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1573 TEST_EQUAL( X.s, -1 );
1574 TEST_EQUAL( X.n, 2 );
1575 TEST_EQUAL( X.p[0], 0 );
1576 TEST_EQUAL( X.p[1], 1 );
1577
1578 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
1579 mbedtls_mpi_free( &X );
1580 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1581 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1582 TEST_EQUAL( X.s, 1 );
1583 TEST_EQUAL( X.n, 1 );
1584 TEST_EQUAL( X.p[0], ~(mbedtls_mpi_uint)0 );
1585
1586 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
1587 TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
1588 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1589 TEST_EQUAL( X.s, 1 );
1590 TEST_EQUAL( X.n, 1 );
1591 TEST_EQUAL( X.p[0], most_positive_plus_1 );
1592
1593 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
1594 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1595 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1596 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1597
1598 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
1599 TEST_EQUAL( mbedtls_mpi_lset( &A, -most_positive ), 0 );
1600 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1601 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1602 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
1603
1604 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
1605 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1606 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1607 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
1608 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1609
1610 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
1611 TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
1612 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1613 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 2 ), 0 );
1614 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1615
1616 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
1617 TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
1618 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1619 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
1620 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
1621
1622 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
1623 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1624 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1625 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1626 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, most_positive ), 0 );
1627
1628 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
1629 TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
1630 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1631 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
1632 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1633
1634 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
1635 TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
1636 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1637 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -2 ), 0 );
1638 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1639
1640 /* Test mbedtls_mpi_mod_int(): never valid */
1641 TEST_EQUAL( mbedtls_mpi_mod_int( X.p, &A, most_negative ),
1642 MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1643
1644 /* Test mbedtls_mpi_random(): never valid */
1645 TEST_EQUAL( mbedtls_mpi_random( &X, most_negative, &A,
1646 mbedtls_test_rnd_std_rand, NULL ),
1647 MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1648
1649exit:
1650 mbedtls_mpi_free( &A );
1651 mbedtls_mpi_free( &R );
1652 mbedtls_mpi_free( &X );
1653}
1654/* END_CASE */
1655
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001656/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001657void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001658{
Andres AG93012e82016-09-09 09:10:28 +01001659 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001660}
Paul Bakker33b43f12013-08-20 11:48:36 +02001661/* END_CASE */