blob: 01af2ffc06cefef4234c61c8affa4ef3a7240ff5 [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
Paul Bakker33b43f12013-08-20 11:48:36 +020093/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +000094
Paul Bakker33b43f12013-08-20 11:48:36 +020095/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +020097 * END_DEPENDENCIES
98 */
Paul Bakker5690efc2011-05-26 13:16:06 +000099
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000100/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100101void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200102{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200103 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200104
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200105 mbedtls_mpi_init( &X );
106 mbedtls_mpi_init( &Y );
107 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200108
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200109 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
110 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200111 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200112 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200113
114exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200115 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200116}
117/* END_CASE */
118
119/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100120void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
121 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200122 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000123{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200124 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000125 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100126 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000127
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200128 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000129
Janos Follath04dadb72019-03-06 12:29:37 +0000130 memset( str, '!', sizeof( str ) );
131
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200133 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000134 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200135 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100136 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200137 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000138 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200139 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000140 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000141 }
142 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000143
Paul Bakkerbd51b262014-07-10 15:26:12 +0200144exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200145 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000146}
Paul Bakker33b43f12013-08-20 11:48:36 +0200147/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000148
Paul Bakker33b43f12013-08-20 11:48:36 +0200149/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100150void mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000151{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000153 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100154 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000155
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200156 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000157
Paul Bakkere896fea2009-07-06 06:40:23 +0000158
Azim Khand30ca132017-06-09 04:32:58 +0100159 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200160 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100161 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100162 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000163
Paul Bakkerbd51b262014-07-10 15:26:12 +0200164exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200165 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000166}
Paul Bakker33b43f12013-08-20 11:48:36 +0200167/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000168
Paul Bakker33b43f12013-08-20 11:48:36 +0200169/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100170void mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000171{
172 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000173 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000174 size_t len;
175
176 mbedtls_mpi_init( &X );
177
178
179 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200180 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100181 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100182 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000183
184exit:
185 mbedtls_mpi_free( &X );
186}
187/* END_CASE */
188
189/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100190void mpi_write_binary( char * input_X, data_t * input_A,
191 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000192{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200193 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000194 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000195 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000196
197 memset( buf, 0x00, 1000 );
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
Werner Lewis19b4cd82022-07-07 11:02:27 +0100201 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100202
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200203 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200204 if( buflen > (size_t) output_size )
205 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000206
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200207 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200208 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000209 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000210
Ronald Cron2dbba992020-06-10 11:42:32 +0200211 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
212 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000213 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000214
Paul Bakkerbd51b262014-07-10 15:26:12 +0200215exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200216 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000217}
Paul Bakker33b43f12013-08-20 11:48:36 +0200218/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000219
Janos Follathe344d0f2019-02-19 16:17:40 +0000220/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100221void mpi_write_binary_le( char * input_X, data_t * input_A,
222 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000223{
224 mbedtls_mpi X;
225 unsigned char buf[1000];
226 size_t buflen;
227
228 memset( buf, 0x00, 1000 );
229
230 mbedtls_mpi_init( &X );
231
Werner Lewis19b4cd82022-07-07 11:02:27 +0100232 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000233
234 buflen = mbedtls_mpi_size( &X );
235 if( buflen > (size_t) output_size )
236 buflen = (size_t) output_size;
237
238 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
239 if( result == 0)
240 {
241
Ronald Cron2dbba992020-06-10 11:42:32 +0200242 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
243 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000244 }
245
246exit:
247 mbedtls_mpi_free( &X );
248}
249/* END_CASE */
250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200251/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100252void mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000253{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000255 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000256 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000257 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000258 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000259
260 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000261
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000263
Paul Bakker33b43f12013-08-20 11:48:36 +0200264 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200265 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100266 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000267 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000268 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000269
Paul Bakker33b43f12013-08-20 11:48:36 +0200270 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000271 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200272 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200273 buflen = mbedtls_mpi_size( &X );
274 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000275
Paul Bakkere896fea2009-07-06 06:40:23 +0000276
Ronald Cron2dbba992020-06-10 11:42:32 +0200277 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
278 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000279 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000280
Paul Bakkerbd51b262014-07-10 15:26:12 +0200281exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200282 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000283}
Paul Bakker33b43f12013-08-20 11:48:36 +0200284/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000285
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200286/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100287void mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000288{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200289 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000290 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200291 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000292
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200293 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000294
Werner Lewis19b4cd82022-07-07 11:02:27 +0100295 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000296
Paul Bakker33b43f12013-08-20 11:48:36 +0200297 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000298 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100299 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000300 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200301 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000302
Paul Bakker33b43f12013-08-20 11:48:36 +0200303 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000304 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100305 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000306 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200307 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000308
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200309 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000310
Paul Bakkerbd51b262014-07-10 15:26:12 +0200311exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200312 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000313}
Paul Bakker33b43f12013-08-20 11:48:36 +0200314/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000315
Paul Bakker33b43f12013-08-20 11:48:36 +0200316/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100317void mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000318{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200319 mbedtls_mpi X;
320 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100321 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000323
Paul Bakkerbd51b262014-07-10 15:26:12 +0200324exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200325 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000326}
Paul Bakker33b43f12013-08-20 11:48:36 +0200327/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000328
Paul Bakker33b43f12013-08-20 11:48:36 +0200329/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100330void mpi_set_bit( char * input_X, int pos, int val,
331 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000332{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_mpi X, Y;
334 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000335
Werner Lewis19b4cd82022-07-07 11:02:27 +0100336 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
337 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100338 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
339
340 if( result == 0 )
341 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200342 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100343 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
344 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000345
Paul Bakkerbd51b262014-07-10 15:26:12 +0200346exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000348}
Paul Bakker33b43f12013-08-20 11:48:36 +0200349/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000350
Paul Bakker33b43f12013-08-20 11:48:36 +0200351/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100352void mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000353{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200354 mbedtls_mpi X;
355 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000356
Werner Lewis19b4cd82022-07-07 11:02:27 +0100357 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000359
Paul Bakkerbd51b262014-07-10 15:26:12 +0200360exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000362}
Paul Bakker33b43f12013-08-20 11:48:36 +0200363/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000364
Paul Bakker33b43f12013-08-20 11:48:36 +0200365/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100366void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000367{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200368 mbedtls_mpi X;
369 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000370
Werner Lewis19b4cd82022-07-07 11:02:27 +0100371 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200372 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000373
Paul Bakkerbd51b262014-07-10 15:26:12 +0200374exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000376}
Paul Bakker33b43f12013-08-20 11:48:36 +0200377/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000378
Paul Bakker33b43f12013-08-20 11:48:36 +0200379/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100380void mpi_gcd( char * input_X, char * input_Y,
381 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000382{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 mbedtls_mpi A, X, Y, Z;
384 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000385
Werner Lewis19b4cd82022-07-07 11:02:27 +0100386 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
387 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
388 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200390 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000392
Paul Bakkerbd51b262014-07-10 15:26:12 +0200393exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200394 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000395}
Paul Bakker33b43f12013-08-20 11:48:36 +0200396/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000397
Paul Bakker33b43f12013-08-20 11:48:36 +0200398/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100399void mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000400{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_mpi X;
402 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
405 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000406
Paul Bakkerbd51b262014-07-10 15:26:12 +0200407exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200408 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000409}
Paul Bakker33b43f12013-08-20 11:48:36 +0200410/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000411
Paul Bakker33b43f12013-08-20 11:48:36 +0200412/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100413void mpi_cmp_mpi( char * input_X, char * input_Y,
414 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000415{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 mbedtls_mpi X, Y;
417 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000418
Werner Lewis19b4cd82022-07-07 11:02:27 +0100419 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
420 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000422
Paul Bakkerbd51b262014-07-10 15:26:12 +0200423exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000425}
Paul Bakker33b43f12013-08-20 11:48:36 +0200426/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000427
Paul Bakker33b43f12013-08-20 11:48:36 +0200428/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100429void mpi_lt_mpi_ct( int size_X, char * input_X,
430 int size_Y, char * input_Y,
431 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100432{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200433 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100434 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100435 mbedtls_mpi X, Y;
436 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
437
Werner Lewis19b4cd82022-07-07 11:02:27 +0100438 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
439 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100440
Gilles Peskine9018b112020-01-21 16:30:53 +0100441 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
442 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100443
Janos Follath0e5532d2019-10-11 14:21:53 +0100444 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100445 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100446 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100447
448exit:
449 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
450}
451/* END_CASE */
452
453/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100454void mpi_cmp_abs( char * input_X, char * input_Y,
455 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000456{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200457 mbedtls_mpi X, Y;
458 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000459
Werner Lewis19b4cd82022-07-07 11:02:27 +0100460 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
461 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000463
Paul Bakkerbd51b262014-07-10 15:26:12 +0200464exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200465 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000466}
Paul Bakker33b43f12013-08-20 11:48:36 +0200467/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000468
Paul Bakker33b43f12013-08-20 11:48:36 +0200469/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100470void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000471{
Gilles Peskined0722f82021-06-10 23:00:33 +0200472 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200473 mbedtls_mpi_init( &src );
474 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200475 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000476
Werner Lewis19b4cd82022-07-07 11:02:27 +0100477 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
478 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200479
480 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100481 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200482 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200483 TEST_ASSERT( sign_is_valid( &dst ) );
484 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000485
Gilles Peskined0722f82021-06-10 23:00:33 +0200486 /* mbedtls_mpi_safe_cond_assign(), assignment done */
487 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100488 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200489 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
490 TEST_ASSERT( sign_is_valid( &dst ) );
491 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
492
493 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
494 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100495 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200496 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
497 TEST_ASSERT( sign_is_valid( &dst ) );
498 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
499
Paul Bakkerbd51b262014-07-10 15:26:12 +0200500exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200501 mbedtls_mpi_free( &src );
502 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200503 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100504}
505/* END_CASE */
506
507/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200508void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100509{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200510 mbedtls_mpi X, A;
511 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000513
Werner Lewis19b4cd82022-07-07 11:02:27 +0100514 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200515 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200516
Werner Lewis19b4cd82022-07-07 11:02:27 +0100517 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200518 TEST_ASSERT( sign_is_valid( &X ) );
519 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000520
Paul Bakkerbd51b262014-07-10 15:26:12 +0200521exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200522 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200523 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000524}
Paul Bakker33b43f12013-08-20 11:48:36 +0200525/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000526
Paul Bakker33b43f12013-08-20 11:48:36 +0200527/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100528void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200529{
530 mbedtls_mpi X, Y, X0, Y0;
531 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
532 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
533
Werner Lewis19b4cd82022-07-07 11:02:27 +0100534 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
535 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200536
Gilles Peskined0722f82021-06-10 23:00:33 +0200537 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100538 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
539 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200540 mbedtls_mpi_swap( &X, &Y );
541 TEST_ASSERT( sign_is_valid( &X ) );
542 TEST_ASSERT( sign_is_valid( &Y ) );
543 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
544 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
545
Gilles Peskined0722f82021-06-10 23:00:33 +0200546 /* mbedtls_mpi_safe_cond_swap(), swap done */
547 mbedtls_mpi_free( &X );
548 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100549 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
550 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200551 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
552 TEST_ASSERT( sign_is_valid( &X ) );
553 TEST_ASSERT( sign_is_valid( &Y ) );
554 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
555 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
556
557 /* mbedtls_mpi_safe_cond_swap(), swap not done */
558 mbedtls_mpi_free( &X );
559 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100560 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
561 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200562 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
563 TEST_ASSERT( sign_is_valid( &X ) );
564 TEST_ASSERT( sign_is_valid( &Y ) );
565 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
566 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
567
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200568exit:
569 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
570 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
571}
572/* END_CASE */
573
574/* BEGIN_CASE */
575void mpi_swap_self( char *X_hex )
576{
577 mbedtls_mpi X, X0;
578 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
579
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +0100580 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100581 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200582
583 mbedtls_mpi_swap( &X, &X );
584 TEST_ASSERT( sign_is_valid( &X ) );
585 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
586
587exit:
588 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
589}
590/* END_CASE */
591
592/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100593void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100594{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_mpi X;
596 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100597
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200599 if( used > 0 )
600 {
601 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
602 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
603 }
604 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200606 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100607
Paul Bakkerbd51b262014-07-10 15:26:12 +0200608exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200609 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100610}
611/* END_CASE */
612
613/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100614void mpi_add_mpi( char * input_X, char * input_Y,
615 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000616{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200617 mbedtls_mpi X, Y, Z, A;
618 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000619
Werner Lewis19b4cd82022-07-07 11:02:27 +0100620 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
621 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
622 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200623 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200624 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200625 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000626
Gilles Peskine56f943a2020-07-23 01:18:11 +0200627 /* result == first operand */
628 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200629 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200630 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100631 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200632
633 /* result == second operand */
634 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200635 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200636 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
637
Paul Bakkerbd51b262014-07-10 15:26:12 +0200638exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200639 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000640}
Paul Bakker33b43f12013-08-20 11:48:36 +0200641/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000642
Paul Bakker33b43f12013-08-20 11:48:36 +0200643/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100644void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100645{
646 mbedtls_mpi X, A;
647 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
648
Werner Lewis19b4cd82022-07-07 11:02:27 +0100649 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100650
Werner Lewis19b4cd82022-07-07 11:02:27 +0100651 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100652 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
653 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200654 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100655
Werner Lewis19b4cd82022-07-07 11:02:27 +0100656 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100657 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200658 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100659 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
660
Werner Lewis19b4cd82022-07-07 11:02:27 +0100661 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100662 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200663 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100664 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
665
666exit:
667 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
668}
669/* END_CASE */
670
671
672/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100673void mpi_add_abs( char * input_X, char * input_Y,
674 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000675{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 mbedtls_mpi X, Y, Z, A;
677 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000678
Werner Lewis19b4cd82022-07-07 11:02:27 +0100679 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
680 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
681 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200682 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200683 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000685
Gilles Peskine56f943a2020-07-23 01:18:11 +0200686 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200688 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200689 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100690 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200691
692 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200694 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000696
Paul Bakkerbd51b262014-07-10 15:26:12 +0200697exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +0200698 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000699}
Paul Bakker33b43f12013-08-20 11:48:36 +0200700/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +0000701
Paul Bakker33b43f12013-08-20 11:48:36 +0200702/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100703void mpi_add_int( char * input_X, int input_Y,
704 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000705{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 mbedtls_mpi X, Z, A;
707 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000708
Werner Lewis19b4cd82022-07-07 11:02:27 +0100709 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
710 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200711 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200712 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200713 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000714
Paul Bakkerbd51b262014-07-10 15:26:12 +0200715exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000717}
Paul Bakker33b43f12013-08-20 11:48:36 +0200718/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000719
Paul Bakker33b43f12013-08-20 11:48:36 +0200720/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100721void mpi_sub_mpi( char * input_X, char * input_Y,
722 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000723{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_mpi X, Y, Z, A;
725 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000726
Werner Lewis19b4cd82022-07-07 11:02:27 +0100727 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
728 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
729 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200730 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200731 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000733
Gilles Peskine56f943a2020-07-23 01:18:11 +0200734 /* result == first operand */
735 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200736 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200737 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100738 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200739
740 /* result == second operand */
741 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200742 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200743 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
744
Paul Bakkerbd51b262014-07-10 15:26:12 +0200745exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000747}
Paul Bakker33b43f12013-08-20 11:48:36 +0200748/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000749
Paul Bakker33b43f12013-08-20 11:48:36 +0200750/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100751void mpi_sub_abs( char * input_X, char * input_Y,
752 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000753{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200754 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +0000755 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200756 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000757
Werner Lewis19b4cd82022-07-07 11:02:27 +0100758 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
759 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
760 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100761
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200762 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200763 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200764 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +0000765 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200766 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000767
Gilles Peskine56f943a2020-07-23 01:18:11 +0200768 /* result == first operand */
769 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200770 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200771 if( sub_result == 0 )
772 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100773 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200774
775 /* result == second operand */
776 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200777 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200778 if( sub_result == 0 )
779 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
780
Paul Bakkerbd51b262014-07-10 15:26:12 +0200781exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200782 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000783}
Paul Bakker33b43f12013-08-20 11:48:36 +0200784/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000785
Paul Bakker33b43f12013-08-20 11:48:36 +0200786/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100787void mpi_sub_int( char * input_X, int input_Y,
788 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000789{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200790 mbedtls_mpi X, Z, A;
791 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000792
Werner Lewis19b4cd82022-07-07 11:02:27 +0100793 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
794 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200795 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200796 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000798
Paul Bakkerbd51b262014-07-10 15:26:12 +0200799exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200800 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000801}
Paul Bakker33b43f12013-08-20 11:48:36 +0200802/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000803
Paul Bakker33b43f12013-08-20 11:48:36 +0200804/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100805void mpi_mul_mpi( char * input_X, char * input_Y,
806 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000807{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 mbedtls_mpi X, Y, Z, A;
809 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000810
Werner Lewis19b4cd82022-07-07 11:02:27 +0100811 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
812 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
813 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200814 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200815 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000817
Paul Bakkerbd51b262014-07-10 15:26:12 +0200818exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200819 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000820}
Paul Bakker33b43f12013-08-20 11:48:36 +0200821/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000822
Paul Bakker33b43f12013-08-20 11:48:36 +0200823/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100824void mpi_mul_int( char * input_X, int input_Y,
825 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +0000826{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200827 mbedtls_mpi X, Z, A;
828 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000829
Werner Lewis19b4cd82022-07-07 11:02:27 +0100830 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
831 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200832 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200833 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200834 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200835 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200836 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200837 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +0200838 else
839 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000840
Paul Bakkerbd51b262014-07-10 15:26:12 +0200841exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200842 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000843}
Paul Bakker33b43f12013-08-20 11:48:36 +0200844/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000845
Paul Bakker33b43f12013-08-20 11:48:36 +0200846/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100847void mpi_div_mpi( char * input_X, char * input_Y,
848 char * input_A, char * input_B,
849 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000850{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200851 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000852 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200853 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
854 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000855
Werner Lewis19b4cd82022-07-07 11:02:27 +0100856 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
857 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
858 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
859 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200860 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200861 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000862 if( res == 0 )
863 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200864 TEST_ASSERT( sign_is_valid( &Q ) );
865 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
867 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000868 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000869
Paul Bakkerbd51b262014-07-10 15:26:12 +0200870exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200871 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
872 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000873}
Paul Bakker33b43f12013-08-20 11:48:36 +0200874/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000875
Paul Bakker33b43f12013-08-20 11:48:36 +0200876/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100877void mpi_div_int( char * input_X, int input_Y,
878 char * input_A, char * input_B,
879 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000880{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200881 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +0000882 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200883 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
884 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000885
Werner Lewis19b4cd82022-07-07 11:02:27 +0100886 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
887 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
888 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200889 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +0200890 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +0000891 if( res == 0 )
892 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200893 TEST_ASSERT( sign_is_valid( &Q ) );
894 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200895 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
896 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000897 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000898
Paul Bakkerbd51b262014-07-10 15:26:12 +0200899exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200900 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
901 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +0000902}
Paul Bakker33b43f12013-08-20 11:48:36 +0200903/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000904
Paul Bakker33b43f12013-08-20 11:48:36 +0200905/* BEGIN_CASE */
Werner Lewis6baf12b2022-10-19 12:46:35 +0100906void mpi_mod_mpi( char * input_X, char * input_Y,
907 char * input_A, int div_result )
908{
909 mbedtls_mpi X, Y, A;
910 int res;
911 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
912
913 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
914 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
915 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
916 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
917 TEST_ASSERT( res == div_result );
918 if( res == 0 )
919 {
920 TEST_ASSERT( sign_is_valid( &X ) );
921 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
922 }
923
924exit:
925 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
926}
927/* END_CASE */
928
929/* BEGIN_CASE */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000930void mpi_mod_int( char * input_X, char * input_Y,
931 char * input_A, int mod_result )
Werner Lewis6baf12b2022-10-19 12:46:35 +0100932{
933 mbedtls_mpi X;
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000934 mbedtls_mpi Y;
935 mbedtls_mpi A;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100936 int res;
937 mbedtls_mpi_uint r;
Werner Lewis6baf12b2022-10-19 12:46:35 +0100938
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000939 mbedtls_mpi_init( &X );
940 mbedtls_mpi_init( &Y );
941 mbedtls_mpi_init( &A );
942
943 /* We use MPIs to read Y and A since the test framework limits us to
944 * ints, so we can't have 64-bit values */
945 TEST_EQUAL( mbedtls_test_read_mpi( &X, input_X ), 0 );
946 TEST_EQUAL( mbedtls_test_read_mpi( &Y, input_Y ), 0 );
947 TEST_EQUAL( mbedtls_test_read_mpi( &A, input_A ), 0 );
948
949 TEST_EQUAL( Y.n, 1 );
950 TEST_EQUAL( A.n, 1 );
951
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000952 /* Convert the MPIs for Y and A to (signed) mbedtls_mpi_sints */
953
954 /* Since we're converting sign+magnitude to two's complement, we lose one
955 * bit of value in the output. This means there are some values we can't
956 * represent, e.g. (hex) -A0000000 on 32-bit systems. These are technically
957 * invalid test cases, so could be considered "won't happen", but they are
958 * easy to test for, and this helps guard against human error. */
959
960 mbedtls_mpi_sint y = (mbedtls_mpi_sint) Y.p[0];
961 TEST_ASSERT( y >= 0 ); /* If y < 0 here, we can't make negative y */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000962 if( Y.s == -1 )
963 y = -y;
Tom Cosgrove9feb19f2022-11-10 12:05:55 +0000964
965 mbedtls_mpi_sint a = (mbedtls_mpi_sint) A.p[0];
966 TEST_ASSERT( a >= 0 ); /* Same goes for a */
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000967 if( A.s == -1 )
968 a = -a;
969
970 res = mbedtls_mpi_mod_int( &r, &X, y );
971 TEST_EQUAL( res, mod_result );
Werner Lewis6baf12b2022-10-19 12:46:35 +0100972 if( res == 0 )
973 {
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000974 TEST_EQUAL( r, a );
Werner Lewis6baf12b2022-10-19 12:46:35 +0100975 }
976
977exit:
978 mbedtls_mpi_free( &X );
Tom Cosgrove91e35e32022-11-09 11:45:29 +0000979 mbedtls_mpi_free( &Y );
980 mbedtls_mpi_free( &A );
Werner Lewis6baf12b2022-10-19 12:46:35 +0100981}
982/* END_CASE */
983
984/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100985void mpi_exp_mod( char * input_A, char * input_E,
986 char * input_N, char * input_X,
987 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +0000988{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200989 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +0000990 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200991 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
992 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000993
Werner Lewis19b4cd82022-07-07 11:02:27 +0100994 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
995 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
996 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
997 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +0000998
Gilles Peskine342f71b2021-06-09 18:31:35 +0200999 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001000 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001001 if( res == 0 )
1002 {
1003 TEST_ASSERT( sign_is_valid( &Z ) );
1004 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1005 }
1006
1007 /* Now test again with the speed-up parameter supplied as an output. */
1008 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001009 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001010 if( res == 0 )
1011 {
1012 TEST_ASSERT( sign_is_valid( &Z ) );
1013 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1014 }
1015
1016 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001017 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001018 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001019 if( res == 0 )
1020 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001021 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001022 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001023 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001024
Paul Bakkerbd51b262014-07-10 15:26:12 +02001025exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001026 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1027 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001028}
Paul Bakker33b43f12013-08-20 11:48:36 +02001029/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001030
Paul Bakker33b43f12013-08-20 11:48:36 +02001031/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001032void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1033 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001034{
1035 mbedtls_mpi A, E, N, RR, Z;
1036 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1037 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1038
Chris Jonesaa850cd2020-12-03 11:35:41 +00001039 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001040 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001041 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001042 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001043
1044 /* Set E to 2^(E_bytes - 1) + 1 */
1045 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1046 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001047 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001048
1049 /* Set N to 2^(N_bytes - 1) + 1 */
1050 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1051 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001052 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1053
1054 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001055 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001056
Chris Jonesaa850cd2020-12-03 11:35:41 +00001057 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001058
1059exit:
1060 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1061 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1062}
1063/* END_CASE */
1064
1065/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001066void mpi_inv_mod( char * input_X, char * input_Y,
1067 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001068{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001069 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001070 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001071 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001072
Werner Lewis19b4cd82022-07-07 11:02:27 +01001073 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1074 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1075 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001076 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001077 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001078 if( res == 0 )
1079 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001080 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001082 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001083
Paul Bakkerbd51b262014-07-10 15:26:12 +02001084exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001086}
Paul Bakker33b43f12013-08-20 11:48:36 +02001087/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001088
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001089/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001090void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001091{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001092 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001093 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001095
Werner Lewis19b4cd82022-07-07 11:02:27 +01001096 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001097 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001098 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001099
Paul Bakkerbd51b262014-07-10 15:26:12 +02001100exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001101 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001102}
Paul Bakker33b43f12013-08-20 11:48:36 +02001103/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001106void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1107 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001108{
1109 mbedtls_mpi X;
1110 int res;
1111 mbedtls_test_mpi_random rand;
1112
1113 mbedtls_mpi_init( &X );
1114 rand.data = witnesses;
1115 rand.pos = 0;
1116 rand.chunk_len = chunk_len;
1117
1118 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001119 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1120 mbedtls_test_mpi_miller_rabin_determinizer,
1121 &rand );
1122 TEST_ASSERT( res == 0 );
1123
1124 rand.data = witnesses;
1125 rand.pos = 0;
1126 rand.chunk_len = chunk_len;
1127
Janos Follatha0b67c22018-09-18 14:48:23 +01001128 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1129 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001130 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001131 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001132
1133exit:
1134 mbedtls_mpi_free( &X );
1135}
1136/* END_CASE */
1137
1138/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001139void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001140{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001142 int my_ret;
1143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001145
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001146 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1147 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001148 TEST_ASSERT( my_ret == ref_ret );
1149
1150 if( ref_ret == 0 )
1151 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001152 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001153
1154 TEST_ASSERT( actual_bits >= (size_t) bits );
1155 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001156 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001157
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001158 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1159 mbedtls_test_rnd_std_rand,
1160 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001161 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001162 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001163 /* X = ( X - 1 ) / 2 */
1164 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001165 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1166 mbedtls_test_rnd_std_rand,
1167 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001168 }
1169 }
1170
Paul Bakkerbd51b262014-07-10 15:26:12 +02001171exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001172 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001173}
1174/* END_CASE */
1175
Paul Bakker33b43f12013-08-20 11:48:36 +02001176/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001177void mpi_shift_l( char * input_X, int shift_X,
1178 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001179{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 mbedtls_mpi X, A;
1181 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001182
Werner Lewis19b4cd82022-07-07 11:02:27 +01001183 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1184 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001185 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001186 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001187 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001188
Paul Bakkerbd51b262014-07-10 15:26:12 +02001189exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001190 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001191}
Paul Bakker33b43f12013-08-20 11:48:36 +02001192/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001193
Paul Bakker33b43f12013-08-20 11:48:36 +02001194/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001195void mpi_shift_r( char * input_X, int shift_X,
1196 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001197{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 mbedtls_mpi X, A;
1199 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001200
Werner Lewis19b4cd82022-07-07 11:02:27 +01001201 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1202 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001204 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001206
Paul Bakkerbd51b262014-07-10 15:26:12 +02001207exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001208 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001209}
Paul Bakker33b43f12013-08-20 11:48:36 +02001210/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001211
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001212/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001213void mpi_fill_random( int wanted_bytes, int rng_bytes,
1214 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001215{
1216 mbedtls_mpi X;
1217 int ret;
1218 size_t bytes_left = rng_bytes;
1219 mbedtls_mpi_init( &X );
1220
Gilles Peskine422e8672021-04-02 00:02:27 +02001221 if( before != 0 )
1222 {
1223 /* Set X to sign(before) * 2^(|before|-1) */
1224 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1225 if( before < 0 )
1226 before = - before;
1227 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1228 }
1229
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001230 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1231 f_rng_bytes_left, &bytes_left );
1232 TEST_ASSERT( ret == expected_ret );
1233
1234 if( expected_ret == 0 )
1235 {
1236 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1237 * as a big-endian representation of the number. We know when
1238 * our RNG function returns null bytes, so we know how many
1239 * leading zero bytes the number has. */
1240 size_t leading_zeros = 0;
1241 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1242 leading_zeros = 1;
1243 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1244 (size_t) wanted_bytes );
1245 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001246 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001247 }
1248
1249exit:
1250 mbedtls_mpi_free( &X );
1251}
1252/* END_CASE */
1253
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001254/* BEGIN_CASE */
Gilles Peskineaf601f92022-11-15 23:02:14 +01001255void most_negative_mpi_sint( )
1256{
1257 /* Ad hoc tests for n = -p = -2^(biL-1) as a mbedtls_mpi_sint. We
1258 * guarantee that mbedtls_mpi_sint is a two's complement type, so this
1259 * is a valid value. However, negating it (`-n`) has undefined behavior
1260 * (although in practice `-n` evaluates to the value n).
1261 *
1262 * This function has ad hoc tests for this value. It's separated from other
1263 * functions because the test framework makes it hard to pass this value
1264 * into test cases.
1265 *
1266 * In the comments here:
1267 * - biL = number of bits in limbs
1268 * - p = 2^(biL-1) (smallest positive value not in mbedtls_mpi_sint range)
1269 * - n = -2^(biL-1) (largest negative value in mbedtls_mpi_sint range)
1270 */
1271
1272 mbedtls_mpi A, R, X;
1273 mbedtls_mpi_init( &A );
1274 mbedtls_mpi_init( &R );
1275 mbedtls_mpi_init( &X );
1276
Gilles Peskineaf601f92022-11-15 23:02:14 +01001277 mbedtls_mpi_uint most_positive_plus_1 = (mbedtls_mpi_uint) 1 << ( biL - 1 );
1278 const mbedtls_mpi_sint most_positive = most_positive_plus_1 - 1;
1279 const mbedtls_mpi_sint most_negative = - most_positive - 1;
1280 TEST_EQUAL( (mbedtls_mpi_uint) most_negative,
1281 (mbedtls_mpi_uint) 1 << ( biL - 1 ) );
1282 TEST_EQUAL( (mbedtls_mpi_uint) most_negative << 1, 0 );
1283
1284 /* Test mbedtls_mpi_lset() */
1285 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1286 TEST_EQUAL( A.s, -1 );
1287 TEST_EQUAL( A.n, 1 );
1288 TEST_EQUAL( A.p[0], most_positive_plus_1 );
1289
1290 /* Test mbedtls_mpi_cmp_int(): -p == -p */
1291 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 0 );
1292
1293 /* Test mbedtls_mpi_cmp_int(): -(p+1) < -p */
1294 A.p[0] = most_positive_plus_1 + 1;
1295 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), -1 );
1296
1297 /* Test mbedtls_mpi_cmp_int(): -(p-1) > -p */
1298 A.p[0] = most_positive_plus_1 - 1;
1299 TEST_EQUAL( mbedtls_mpi_cmp_int( &A, most_negative ), 1 );
1300
1301 /* Test mbedtls_mpi_add_int(): (p-1) + (-p) */
1302 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1303 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1304 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
1305
1306 /* Test mbedtls_mpi_add_int(): (0) + (-p) */
1307 TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
1308 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1309 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, most_negative ), 0 );
1310
1311 /* Test mbedtls_mpi_add_int(): (-p) + (-p) */
1312 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1313 TEST_EQUAL( mbedtls_mpi_add_int( &X, &A, most_negative ), 0 );
1314 TEST_EQUAL( X.s, -1 );
1315 TEST_EQUAL( X.n, 2 );
1316 TEST_EQUAL( X.p[0], 0 );
1317 TEST_EQUAL( X.p[1], 1 );
1318
1319 /* Test mbedtls_mpi_sub_int(): (p) - (-p) */
1320 mbedtls_mpi_free( &X );
1321 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1322 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1323 TEST_EQUAL( X.s, 1 );
1324 TEST_EQUAL( X.n, 1 );
1325 TEST_EQUAL( X.p[0], ~(mbedtls_mpi_uint)0 );
1326
1327 /* Test mbedtls_mpi_sub_int(): (0) - (-p) */
1328 TEST_EQUAL( mbedtls_mpi_lset( &A, 0 ), 0 );
1329 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1330 TEST_EQUAL( X.s, 1 );
1331 TEST_EQUAL( X.n, 1 );
1332 TEST_EQUAL( X.p[0], most_positive_plus_1 );
1333
1334 /* Test mbedtls_mpi_sub_int(): (-p) - (-p) */
1335 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1336 TEST_EQUAL( mbedtls_mpi_sub_int( &X, &A, most_negative ), 0 );
1337 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1338
1339 /* Test mbedtls_mpi_div_int(): (-p+1) / (-p) */
1340 TEST_EQUAL( mbedtls_mpi_lset( &A, -most_positive ), 0 );
1341 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1342 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1343 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
1344
1345 /* Test mbedtls_mpi_div_int(): (-p) / (-p) */
1346 TEST_EQUAL( mbedtls_mpi_lset( &A, most_negative ), 0 );
1347 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1348 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
1349 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1350
1351 /* Test mbedtls_mpi_div_int(): (-2*p) / (-p) */
1352 TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
1353 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1354 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 2 ), 0 );
1355 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1356
1357 /* Test mbedtls_mpi_div_int(): (-2*p+1) / (-p) */
1358 TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
1359 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1360 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 1 ), 0 );
1361 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, -most_positive ), 0 );
1362
1363 /* Test mbedtls_mpi_div_int(): (p-1) / (-p) */
1364 TEST_EQUAL( mbedtls_mpi_lset( &A, most_positive ), 0 );
1365 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1366 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, 0 ), 0 );
1367 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, most_positive ), 0 );
1368
1369 /* Test mbedtls_mpi_div_int(): (p) / (-p) */
1370 TEST_EQUAL( mbedtls_mpi_add_int( &A, &A, 1 ), 0 );
1371 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1372 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -1 ), 0 );
1373 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1374
1375 /* Test mbedtls_mpi_div_int(): (2*p) / (-p) */
1376 TEST_EQUAL( mbedtls_mpi_shift_l( &A, 1 ), 0 );
1377 TEST_EQUAL( mbedtls_mpi_div_int( &X, &R, &A, most_negative ), 0 );
1378 TEST_EQUAL( mbedtls_mpi_cmp_int( &X, -2 ), 0 );
1379 TEST_EQUAL( mbedtls_mpi_cmp_int( &R, 0 ), 0 );
1380
1381 /* Test mbedtls_mpi_mod_int(): never valid */
1382 TEST_EQUAL( mbedtls_mpi_mod_int( X.p, &A, most_negative ),
1383 MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1384
1385 /* Test mbedtls_mpi_random(): never valid */
1386 TEST_EQUAL( mbedtls_mpi_random( &X, most_negative, &A,
1387 mbedtls_test_rnd_std_rand, NULL ),
1388 MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1389
1390exit:
1391 mbedtls_mpi_free( &A );
1392 mbedtls_mpi_free( &R );
1393 mbedtls_mpi_free( &X );
1394}
1395/* END_CASE */
1396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001398void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001399{
Andres AG93012e82016-09-09 09:10:28 +01001400 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001401}
Paul Bakker33b43f12013-08-20 11:48:36 +02001402/* END_CASE */