blob: eb91db4fa122ca58e7c2917b3b0d31b1d25dd409 [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 Follathf1d617d2022-07-21 09:29:32 +01004#include "bignum_core.h"
Gabor Mezei23a1ce92022-08-02 11:54:44 +02005#include "bignum_mod.h"
6#include "bignum_mod_raw.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01007#include "constant_time_internal.h"
8#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01009
Chris Jonese64a46f2020-12-03 17:44:03 +000010#if MBEDTLS_MPI_MAX_BITS > 792
11#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000012#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020013
Gilles Peskinedffc7102021-06-10 15:34:15 +020014/* Check the validity of the sign bit in an MPI object. Reject representations
15 * that are not supported by the rest of the library and indicate a bug when
16 * constructing the value. */
17static int sign_is_valid( const mbedtls_mpi *X )
18{
19 if( X->s != 1 && X->s != -1 )
20 return( 0 ); // invalid sign bit, e.g. 0
21 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
22 return( 0 ); // negative zero
23 return( 1 );
24}
25
Janos Follath64eca052018-09-05 17:04:49 +010026typedef struct mbedtls_test_mpi_random
27{
28 data_t *data;
29 size_t pos;
30 size_t chunk_len;
31} mbedtls_test_mpi_random;
32
33/*
34 * This function is called by the Miller-Rabin primality test each time it
35 * chooses a random witness. The witnesses (or non-witnesses as provided by the
36 * test) are stored in the data member of the state structure. Each number is in
37 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
38 */
39int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
40 unsigned char* buf,
41 size_t len )
42{
43 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
44
45 if( random == NULL || random->data->x == NULL || buf == NULL )
46 return( -1 );
47
48 if( random->pos + random->chunk_len > random->data->len
49 || random->chunk_len > len )
50 {
51 return( -1 );
52 }
53
54 memset( buf, 0, len );
55
56 /* The witness is written to the end of the buffer, since the buffer is
57 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
58 * Writing the witness to the start of the buffer would result in the
59 * buffer being 'witness 000...000', which would be treated as
60 * witness * 2^n for some n. */
61 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
62 random->chunk_len );
63
64 random->pos += random->chunk_len;
65
66 return( 0 );
67}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010068
69/* Random generator that is told how many bytes to return. */
70static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
71{
72 size_t *bytes_left = state;
73 size_t i;
74 for( i = 0; i < len; i++ )
75 {
76 if( *bytes_left == 0 )
77 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
78 buf[i] = *bytes_left & 0xff;
79 --( *bytes_left );
80 }
81 return( 0 );
82}
83
Gilles Peskineeedefa52021-04-13 19:50:04 +020084/* Test whether bytes represents (in big-endian base 256) a number b that
85 * is significantly above a power of 2. That is, b must not have a long run
86 * of unset bits after the most significant bit.
87 *
88 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
89 * This function returns 1 if, when drawing a number between 0 and b,
90 * the probability that this number is at least 2^n is not negligible.
91 * This probability is (b - 2^n) / b and this function checks that this
92 * number is above some threshold A. The threshold value is heuristic and
93 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020094 */
95static int is_significantly_above_a_power_of_2( data_t *bytes )
96{
97 const uint8_t *p = bytes->x;
98 size_t len = bytes->len;
99 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200100
101 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200102 while( len > 0 && p[0] == 0 )
103 {
104 ++p;
105 --len;
106 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200107 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200108 if( len == 0 )
109 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200110 /* Extract the (up to) 2 most significant bytes */
111 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200112 x = p[0];
113 else
114 x = ( p[0] << 8 ) | p[1];
115
Gilles Peskineeedefa52021-04-13 19:50:04 +0200116 /* Shift the most significant bit of x to position 8 and mask it out */
117 while( ( x & 0xfe00 ) != 0 )
118 x >>= 1;
119 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200120
Gilles Peskineeedefa52021-04-13 19:50:04 +0200121 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
122 * a power of 2 iff x is significantly above 0 compared to 2^8.
123 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
124 * description above. */
125 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200126}
127
Paul Bakker33b43f12013-08-20 11:48:36 +0200128/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000129
Paul Bakker33b43f12013-08-20 11:48:36 +0200130/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200132 * END_DEPENDENCIES
133 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000134
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000135/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100136void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200137{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200138 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200139
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200140 mbedtls_mpi_init( &X );
141 mbedtls_mpi_init( &Y );
142 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200143
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200144 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
145 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200146 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200147 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200148
149exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200150 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200151}
152/* END_CASE */
153
154/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100155void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
156 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200157 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000160 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100161 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000164
Janos Follath04dadb72019-03-06 12:29:37 +0000165 memset( str, '!', sizeof( str ) );
166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200168 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000169 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200170 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100171 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200172 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000173 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200174 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000175 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000176 }
177 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000178
Paul Bakkerbd51b262014-07-10 15:26:12 +0200179exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000181}
Paul Bakker33b43f12013-08-20 11:48:36 +0200182/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000183
Paul Bakker33b43f12013-08-20 11:48:36 +0200184/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100185void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000188 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100189 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000192
Paul Bakkere896fea2009-07-06 06:40:23 +0000193
Azim Khand30ca132017-06-09 04:32:58 +0100194 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200195 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100196 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100197 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000198
Paul Bakkerbd51b262014-07-10 15:26:12 +0200199exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000201}
Paul Bakker33b43f12013-08-20 11:48:36 +0200202/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000203
Paul Bakker33b43f12013-08-20 11:48:36 +0200204/* BEGIN_CASE */
Janos Follath91dc67d2022-07-22 14:24:58 +0100205void mbedtls_mpi_core_io_null()
206{
207 mbedtls_mpi_uint X = 0;
208 int ret;
209
210 ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
211 TEST_ASSERT( ret == 0 );
212 ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
213 TEST_ASSERT( ret == 0 );
214
215 ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
216 TEST_ASSERT( ret == 0 );
217 ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
218 TEST_ASSERT( ret == 0 );
219
220 ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
221 TEST_ASSERT( ret == 0 );
222 ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
223 TEST_ASSERT( ret == 0 );
224
225 ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
226 TEST_ASSERT( ret == 0 );
227 ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
228 TEST_ASSERT( ret == 0 );
229
230exit:
231 ;
232}
233/* END_CASE */
234
235/* BEGIN_CASE */
Janos Follath1cb3b972022-08-11 10:50:04 +0100236void mbedtls_mpi_core_io_be( data_t *input, int nb_int, int nx_32_int, int iret,
Janos Follathf1d617d2022-07-21 09:29:32 +0100237 int oret )
238{
Gabor Mezei89e31462022-08-12 15:36:56 +0200239#define BMAX 1024
240#define XMAX BMAX / sizeof( mbedtls_mpi_uint )
241
Janos Follathf1d617d2022-07-21 09:29:32 +0100242 unsigned char buf[BMAX];
Janos Follathf1d617d2022-07-21 09:29:32 +0100243 mbedtls_mpi_uint X[XMAX];
244 size_t nx, nb;
245 int ret;
246
247 if( iret != 0 )
248 TEST_ASSERT( oret == 0 );
249
250 TEST_ASSERT( 0 <= nb_int );
251 nb = nb_int;
252 TEST_ASSERT( nb <= BMAX );
253
Janos Follath1cb3b972022-08-11 10:50:04 +0100254 TEST_ASSERT( 0 <= nx_32_int );
255 nx = nx_32_int;
256 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
257 * to halve the number of limbs to have the same size. */
258 if( sizeof( mbedtls_mpi_uint ) == 8 )
259 nx = nx / 2 + nx % 2;
Janos Follathf1d617d2022-07-21 09:29:32 +0100260 TEST_ASSERT( nx <= XMAX );
261
262 ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
263 TEST_ASSERT( ret == iret );
264
265 if( iret == 0 )
266 {
267 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
268 TEST_ASSERT( ret == oret );
269 }
270
271 if( ( iret == 0 ) && ( oret == 0 ) )
272 {
273 if( nb > input->len )
274 {
275 size_t leading_zeroes = nb - input->len;
276 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
277 for( size_t i = 0; i < leading_zeroes; i++ )
278 TEST_ASSERT( buf[i] == 0 );
279 }
280 else
281 {
282 size_t leading_zeroes = input->len - nb;
283 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
284 for( size_t i = 0; i < leading_zeroes; i++ )
285 TEST_ASSERT( input->x[i] == 0 );
286 }
287 }
288
289exit:
290 ;
291
Gabor Mezei89e31462022-08-12 15:36:56 +0200292#undef BMAX
293#undef XMAX
Janos Follathf1d617d2022-07-21 09:29:32 +0100294}
295/* END_CASE */
296
297/* BEGIN_CASE */
Janos Follath9dfb5622022-08-11 12:15:55 +0100298void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_32_int, int iret,
Janos Follath6ff35362022-07-21 15:27:21 +0100299 int oret )
300{
Gabor Mezei89e31462022-08-12 15:36:56 +0200301#define BMAX 1024
302#define XMAX BMAX / sizeof( mbedtls_mpi_uint )
303
Janos Follath6ff35362022-07-21 15:27:21 +0100304 unsigned char buf[BMAX];
Janos Follath6ff35362022-07-21 15:27:21 +0100305 mbedtls_mpi_uint X[XMAX];
306 size_t nx, nb;
307 int ret;
308
309 if( iret != 0 )
310 TEST_ASSERT( oret == 0 );
311
312 TEST_ASSERT( 0 <= nb_int );
313 nb = nb_int;
314 TEST_ASSERT( nb <= BMAX );
315
Janos Follath9dfb5622022-08-11 12:15:55 +0100316 TEST_ASSERT( 0 <= nx_32_int );
317 nx = nx_32_int;
318 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
319 * to halve the number of limbs to have the same size. */
320 if( sizeof( mbedtls_mpi_uint ) == 8 )
321 nx = nx / 2 + nx % 2;
Janos Follath6ff35362022-07-21 15:27:21 +0100322 TEST_ASSERT( nx <= XMAX );
323
324 ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
325 TEST_ASSERT( ret == iret );
326
327 if( iret == 0 )
328 {
329 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
330 TEST_ASSERT( ret == oret );
331 }
332
333 if( ( iret == 0 ) && ( oret == 0 ) )
334 {
335 if( nb > input->len )
336 {
337 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
338 for( size_t i = input->len; i < nb; i++ )
339 TEST_ASSERT( buf[i] == 0 );
340 }
341 else
342 {
343 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
344 for( size_t i = nb; i < input->len; i++ )
345 TEST_ASSERT( input->x[i] == 0 );
346 }
347 }
348
349exit:
350 ;
351
Gabor Mezei89e31462022-08-12 15:36:56 +0200352#undef BMAX
353#undef XMAX
Janos Follath6ff35362022-07-21 15:27:21 +0100354}
355/* END_CASE */
356
357/* BEGIN_CASE */
Janos Follath16949692022-08-08 13:37:20 +0100358void mbedtls_mpi_mod_setup( int ext_rep, int int_rep, int iret )
359{
360 #define MLIMBS 8
361 mbedtls_mpi_uint mp[MLIMBS];
362 mbedtls_mpi_mod_modulus m;
363 int ret;
364
365 memset( mp, 0xFF, sizeof(mp) );
366
367 mbedtls_mpi_mod_modulus_init( &m );
368 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
369 TEST_ASSERT( ret == iret );
370
371 /* Address sanitiser should catch if we try to free mp */
372 mbedtls_mpi_mod_modulus_free( &m );
373
374 /* Make sure that the modulus doesn't have reference to mp anymore */
375 TEST_ASSERT( m.p != mp );
376
377exit:
378 /* It should be safe to call an mbedtls free several times */
379 mbedtls_mpi_mod_modulus_free( &m );
380
381 #undef MLIMBS
382}
383/* END_CASE */
384
385
386/* BEGIN_CASE */
Gabor Mezei7f081782022-08-12 18:00:33 +0200387void mbedtls_mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int,
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200388 int iendian, int iret, int oret )
389{
Gabor Mezei89e31462022-08-12 15:36:56 +0200390#define BMAX 1024
391#define XMAX BMAX / sizeof( mbedtls_mpi_uint )
392
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200393 unsigned char buf[BMAX];
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200394 mbedtls_mpi_uint X[XMAX];
395 mbedtls_mpi_uint init[XMAX];
396 mbedtls_mpi_mod_modulus m;
397 size_t nx, nb;
398 int ret;
399 int endian;
400
401 if( iret != 0 )
402 TEST_ASSERT( oret == 0 );
403
404 TEST_ASSERT( 0 <= nb_int );
405 nb = nb_int;
406 TEST_ASSERT( nb <= BMAX );
407
Gabor Mezei7f081782022-08-12 18:00:33 +0200408 TEST_ASSERT( 0 <= nx_32_int );
409 nx = nx_32_int;
410 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
411 * to halve the number of limbs to have the same size. */
412 if( sizeof( mbedtls_mpi_uint ) == 8 )
413 nx = nx / 2 + nx % 2;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200414 TEST_ASSERT( nx <= XMAX );
415
416 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
417 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
418 else
419 endian = iendian;
420
421 mbedtls_mpi_mod_modulus_init( &m );
422 TEST_ASSERT( memset( init, 0xFF, sizeof( init ) ) );
423
424 ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
425 MBEDTLS_MPI_MOD_REP_MONTGOMERY );
426 TEST_ASSERT( ret == 0 );
427
428 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
429 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
430
431 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
432 TEST_ASSERT( ret == iret );
433
434 if( iret == 0 )
435 {
436 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
437 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
438
439 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
440 TEST_ASSERT( ret == oret );
441 }
442
443 if( ( iret == 0 ) && ( oret == 0 ) )
444 {
445 if( nb > input->len )
446 {
447 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
448 {
449 size_t leading_zeroes = nb - input->len;
450 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
451 for( size_t i = 0; i < leading_zeroes; i++ )
452 TEST_ASSERT( buf[i] == 0 );
453 }
454 else
455 {
456 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
457 for( size_t i = input->len; i < nb; i++ )
458 TEST_ASSERT( buf[i] == 0 );
459 }
460 }
461 else
462 {
463 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
464 {
465 size_t leading_zeroes = input->len - nb;
466 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
467 for( size_t i = 0; i < leading_zeroes; i++ )
468 TEST_ASSERT( input->x[i] == 0 );
469 }
470 else
471 {
472 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
473 for( size_t i = nb; i < input->len; i++ )
474 TEST_ASSERT( input->x[i] == 0 );
475 }
476 }
477 }
478
479exit:
480 mbedtls_mpi_mod_modulus_free( &m );
481
Gabor Mezei89e31462022-08-12 15:36:56 +0200482#undef BMAX
483#undef XMAX
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200484}
485/* END_CASE */
486
487/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100488void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000489{
490 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000491 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000492 size_t len;
493
494 mbedtls_mpi_init( &X );
495
496
497 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200498 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100499 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100500 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000501
502exit:
503 mbedtls_mpi_free( &X );
504}
505/* END_CASE */
506
507/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100508void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
509 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000510{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000512 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000513 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000514
515 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000516
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200517 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000518
Werner Lewis19b4cd82022-07-07 11:02:27 +0100519 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100520
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200522 if( buflen > (size_t) output_size )
523 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000524
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200525 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200526 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000527 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000528
Ronald Cron2dbba992020-06-10 11:42:32 +0200529 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
530 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000531 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000532
Paul Bakkerbd51b262014-07-10 15:26:12 +0200533exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000535}
Paul Bakker33b43f12013-08-20 11:48:36 +0200536/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000537
Janos Follathe344d0f2019-02-19 16:17:40 +0000538/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100539void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
540 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000541{
542 mbedtls_mpi X;
543 unsigned char buf[1000];
544 size_t buflen;
545
546 memset( buf, 0x00, 1000 );
547
548 mbedtls_mpi_init( &X );
549
Werner Lewis19b4cd82022-07-07 11:02:27 +0100550 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000551
552 buflen = mbedtls_mpi_size( &X );
553 if( buflen > (size_t) output_size )
554 buflen = (size_t) output_size;
555
556 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
557 if( result == 0)
558 {
559
Ronald Cron2dbba992020-06-10 11:42:32 +0200560 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
561 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000562 }
563
564exit:
565 mbedtls_mpi_free( &X );
566}
567/* END_CASE */
568
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100570void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000571{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200572 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000573 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000574 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000575 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000576 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000577
578 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000579
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200580 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000581
Paul Bakker33b43f12013-08-20 11:48:36 +0200582 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200583 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100584 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000585 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000586 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000587
Paul Bakker33b43f12013-08-20 11:48:36 +0200588 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000589 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200590 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 buflen = mbedtls_mpi_size( &X );
592 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000593
Paul Bakkere896fea2009-07-06 06:40:23 +0000594
Ronald Cron2dbba992020-06-10 11:42:32 +0200595 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
596 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000597 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000598
Paul Bakkerbd51b262014-07-10 15:26:12 +0200599exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200600 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000601}
Paul Bakker33b43f12013-08-20 11:48:36 +0200602/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000603
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100605void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000606{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000608 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200609 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000612
Werner Lewis19b4cd82022-07-07 11:02:27 +0100613 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000614
Paul Bakker33b43f12013-08-20 11:48:36 +0200615 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000616 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100617 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000618 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200619 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000620
Paul Bakker33b43f12013-08-20 11:48:36 +0200621 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000622 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100623 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000624 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200625 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000626
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000628
Paul Bakkerbd51b262014-07-10 15:26:12 +0200629exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000631}
Paul Bakker33b43f12013-08-20 11:48:36 +0200632/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000633
Paul Bakker33b43f12013-08-20 11:48:36 +0200634/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100635void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000636{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 mbedtls_mpi X;
638 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100639 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000641
Paul Bakkerbd51b262014-07-10 15:26:12 +0200642exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000644}
Paul Bakker33b43f12013-08-20 11:48:36 +0200645/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000646
Paul Bakker33b43f12013-08-20 11:48:36 +0200647/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100648void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
649 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000650{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200651 mbedtls_mpi X, Y;
652 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000653
Werner Lewis19b4cd82022-07-07 11:02:27 +0100654 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
655 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100656 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
657
658 if( result == 0 )
659 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200660 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100661 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
662 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000663
Paul Bakkerbd51b262014-07-10 15:26:12 +0200664exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200665 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000666}
Paul Bakker33b43f12013-08-20 11:48:36 +0200667/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000668
Paul Bakker33b43f12013-08-20 11:48:36 +0200669/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100670void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000671{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 mbedtls_mpi X;
673 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000674
Werner Lewis19b4cd82022-07-07 11:02:27 +0100675 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000677
Paul Bakkerbd51b262014-07-10 15:26:12 +0200678exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000680}
Paul Bakker33b43f12013-08-20 11:48:36 +0200681/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000682
Paul Bakker33b43f12013-08-20 11:48:36 +0200683/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100684void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000685{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686 mbedtls_mpi X;
687 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000688
Werner Lewis19b4cd82022-07-07 11:02:27 +0100689 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200690 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000691
Paul Bakkerbd51b262014-07-10 15:26:12 +0200692exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000694}
Paul Bakker33b43f12013-08-20 11:48:36 +0200695/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000696
Paul Bakker33b43f12013-08-20 11:48:36 +0200697/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100698void mbedtls_mpi_gcd( char * input_X, char * input_Y,
699 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000700{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200701 mbedtls_mpi A, X, Y, Z;
702 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000703
Werner Lewis19b4cd82022-07-07 11:02:27 +0100704 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
705 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
706 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200708 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000710
Paul Bakkerbd51b262014-07-10 15:26:12 +0200711exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000713}
Paul Bakker33b43f12013-08-20 11:48:36 +0200714/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000715
Paul Bakker33b43f12013-08-20 11:48:36 +0200716/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000718{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 mbedtls_mpi X;
720 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200722 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
723 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000724
Paul Bakkerbd51b262014-07-10 15:26:12 +0200725exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000727}
Paul Bakker33b43f12013-08-20 11:48:36 +0200728/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000729
Paul Bakker33b43f12013-08-20 11:48:36 +0200730/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100731void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
732 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000733{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200734 mbedtls_mpi X, Y;
735 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000736
Werner Lewis19b4cd82022-07-07 11:02:27 +0100737 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
738 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000740
Paul Bakkerbd51b262014-07-10 15:26:12 +0200741exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200742 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000743}
Paul Bakker33b43f12013-08-20 11:48:36 +0200744/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000745
Paul Bakker33b43f12013-08-20 11:48:36 +0200746/* BEGIN_CASE */
Janos Follath23bdeca2022-07-22 18:24:06 +0100747void mbedtls_mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
748{
749 #define MAX_LEN 64
750 mbedtls_mpi_uint X[MAX_LEN];
751 mbedtls_mpi_uint Y[MAX_LEN];
752 unsigned exp_ret = input_ret;
753 unsigned ret;
754 size_t len = CHARS_TO_LIMBS(
755 input_X->len > input_Y->len ? input_X->len : input_Y->len );
756
757 TEST_ASSERT( len <= MAX_LEN );
758
759 TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
760 == 0 );
761 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
762 == 0 );
763
764 TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
765 TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
766
767 ret = mbedtls_mpi_core_lt_ct( X, Y, len );
768
769 TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
770 TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
771 TEST_CF_PUBLIC( &ret, sizeof( ret ) );
772
773 TEST_ASSERT( ret == exp_ret );
774
775exit:
776 ;
777
778 #undef MAX_LEN
779}
780/* END_CASE */
781
782/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100783void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
784 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100785 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100786{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200787 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100788 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100789 mbedtls_mpi X, Y;
790 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
791
Werner Lewis19b4cd82022-07-07 11:02:27 +0100792 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
793 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100794
Gilles Peskine9018b112020-01-21 16:30:53 +0100795 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
796 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100797
Janos Follath0e5532d2019-10-11 14:21:53 +0100798 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100799 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100800 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100801
802exit:
803 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
804}
805/* END_CASE */
806
807/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100808void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
809 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000810{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200811 mbedtls_mpi X, Y;
812 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000813
Werner Lewis19b4cd82022-07-07 11:02:27 +0100814 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
815 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
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 );
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 */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200824void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000825{
Gilles Peskined0722f82021-06-10 23:00:33 +0200826 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200827 mbedtls_mpi_init( &src );
828 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200829 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000830
Werner Lewis19b4cd82022-07-07 11:02:27 +0100831 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
832 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200833
834 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100835 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200836 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200837 TEST_ASSERT( sign_is_valid( &dst ) );
838 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000839
Gilles Peskined0722f82021-06-10 23:00:33 +0200840 /* mbedtls_mpi_safe_cond_assign(), assignment done */
841 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100842 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200843 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
844 TEST_ASSERT( sign_is_valid( &dst ) );
845 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
846
847 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
848 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100849 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200850 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
851 TEST_ASSERT( sign_is_valid( &dst ) );
852 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
853
Paul Bakkerbd51b262014-07-10 15:26:12 +0200854exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200855 mbedtls_mpi_free( &src );
856 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200857 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100858}
859/* END_CASE */
860
861/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200862void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100863{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200864 mbedtls_mpi X, A;
865 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000867
Werner Lewis19b4cd82022-07-07 11:02:27 +0100868 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200869 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200870
Werner Lewis19b4cd82022-07-07 11:02:27 +0100871 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200872 TEST_ASSERT( sign_is_valid( &X ) );
873 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000874
Paul Bakkerbd51b262014-07-10 15:26:12 +0200875exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200876 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200877 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000878}
Paul Bakker33b43f12013-08-20 11:48:36 +0200879/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000880
Paul Bakker33b43f12013-08-20 11:48:36 +0200881/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200882void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
883{
884 mbedtls_mpi X, Y, X0, Y0;
885 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
886 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
887
Werner Lewis19b4cd82022-07-07 11:02:27 +0100888 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
889 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200890
Gilles Peskined0722f82021-06-10 23:00:33 +0200891 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100892 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
893 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200894 mbedtls_mpi_swap( &X, &Y );
895 TEST_ASSERT( sign_is_valid( &X ) );
896 TEST_ASSERT( sign_is_valid( &Y ) );
897 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
898 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
899
Gilles Peskined0722f82021-06-10 23:00:33 +0200900 /* mbedtls_mpi_safe_cond_swap(), swap done */
901 mbedtls_mpi_free( &X );
902 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100903 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
904 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200905 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
906 TEST_ASSERT( sign_is_valid( &X ) );
907 TEST_ASSERT( sign_is_valid( &Y ) );
908 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
909 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
910
911 /* mbedtls_mpi_safe_cond_swap(), swap not done */
912 mbedtls_mpi_free( &X );
913 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100914 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
915 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200916 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
917 TEST_ASSERT( sign_is_valid( &X ) );
918 TEST_ASSERT( sign_is_valid( &Y ) );
919 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
920 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
921
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200922exit:
923 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
924 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
925}
926/* END_CASE */
927
928/* BEGIN_CASE */
929void mpi_swap_self( char *X_hex )
930{
931 mbedtls_mpi X, X0;
932 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
933
Werner Lewis19b4cd82022-07-07 11:02:27 +0100934 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
935 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200936
937 mbedtls_mpi_swap( &X, &X );
938 TEST_ASSERT( sign_is_valid( &X ) );
939 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
940
941exit:
942 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
943}
944/* END_CASE */
945
946/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200947void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100948{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_mpi X;
950 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100951
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200952 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200953 if( used > 0 )
954 {
955 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
956 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
957 }
958 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200960 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100961
Paul Bakkerbd51b262014-07-10 15:26:12 +0200962exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200963 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100964}
965/* END_CASE */
966
967/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100968void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
969 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000970{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 mbedtls_mpi X, Y, Z, A;
972 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000973
Werner Lewis19b4cd82022-07-07 11:02:27 +0100974 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
975 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
976 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200977 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200978 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200979 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000980
Gilles Peskine56f943a2020-07-23 01:18:11 +0200981 /* result == first operand */
982 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200983 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200984 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100985 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200986
987 /* result == second operand */
988 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200989 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200990 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
991
Paul Bakkerbd51b262014-07-10 15:26:12 +0200992exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200993 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000994}
Paul Bakker33b43f12013-08-20 11:48:36 +0200995/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000996
Paul Bakker33b43f12013-08-20 11:48:36 +0200997/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100998void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100999{
1000 mbedtls_mpi X, A;
1001 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1002
Werner Lewis19b4cd82022-07-07 11:02:27 +01001003 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001004
Werner Lewis19b4cd82022-07-07 11:02:27 +01001005 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001006 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
1007 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001008 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001009
Werner Lewis19b4cd82022-07-07 11:02:27 +01001010 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001011 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001012 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001013 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1014
Werner Lewis19b4cd82022-07-07 11:02:27 +01001015 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +01001016 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001017 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +01001018 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1019
1020exit:
1021 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1022}
1023/* END_CASE */
1024
1025
1026/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001027void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
1028 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001029{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001030 mbedtls_mpi X, Y, Z, A;
1031 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001032
Werner Lewis19b4cd82022-07-07 11:02:27 +01001033 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1034 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1035 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001037 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001039
Gilles Peskine56f943a2020-07-23 01:18:11 +02001040 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001041 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001042 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001044 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001045
1046 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001047 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001048 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001049 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001050
Paul Bakkerbd51b262014-07-10 15:26:12 +02001051exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001052 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001053}
Paul Bakker33b43f12013-08-20 11:48:36 +02001054/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001055
Paul Bakker33b43f12013-08-20 11:48:36 +02001056/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001057void mbedtls_mpi_add_int( char * input_X, int input_Y,
1058 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001059{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001060 mbedtls_mpi X, Z, A;
1061 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001062
Werner Lewis19b4cd82022-07-07 11:02:27 +01001063 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1064 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001065 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001066 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
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( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001071}
Paul Bakker33b43f12013-08-20 11:48:36 +02001072/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001073
Paul Bakker33b43f12013-08-20 11:48:36 +02001074/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001075void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
1076 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001077{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_mpi X, Y, Z, A;
1079 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001080
Werner Lewis19b4cd82022-07-07 11:02:27 +01001081 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1082 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1083 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001084 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001085 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001087
Gilles Peskine56f943a2020-07-23 01:18:11 +02001088 /* result == first operand */
1089 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001090 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001091 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001092 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001093
1094 /* result == second operand */
1095 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001096 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001097 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1098
Paul Bakkerbd51b262014-07-10 15:26:12 +02001099exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001100 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001101}
Paul Bakker33b43f12013-08-20 11:48:36 +02001102/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001103
Paul Bakker33b43f12013-08-20 11:48:36 +02001104/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001105void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
1106 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001107{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001108 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001109 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001111
Werner Lewis19b4cd82022-07-07 11:02:27 +01001112 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1113 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1114 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001116 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001117 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001118 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001119 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001120 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001121
Gilles Peskine56f943a2020-07-23 01:18:11 +02001122 /* result == first operand */
1123 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001124 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001125 if( sub_result == 0 )
1126 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001127 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001128
1129 /* result == second operand */
1130 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001131 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001132 if( sub_result == 0 )
1133 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1134
Paul Bakkerbd51b262014-07-10 15:26:12 +02001135exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001136 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001137}
Paul Bakker33b43f12013-08-20 11:48:36 +02001138/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001139
Paul Bakker33b43f12013-08-20 11:48:36 +02001140/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001141void mbedtls_mpi_sub_int( char * input_X, int input_Y,
1142 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001143{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001144 mbedtls_mpi X, Z, A;
1145 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001146
Werner Lewis19b4cd82022-07-07 11:02:27 +01001147 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1148 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001149 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001150 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001152
Paul Bakkerbd51b262014-07-10 15:26:12 +02001153exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001154 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001155}
Paul Bakker33b43f12013-08-20 11:48:36 +02001156/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001157
Paul Bakker33b43f12013-08-20 11:48:36 +02001158/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001159void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
1160 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001161{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001162 mbedtls_mpi X, Y, Z, A;
1163 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001164
Werner Lewis19b4cd82022-07-07 11:02:27 +01001165 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1166 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1167 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001169 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001171
Paul Bakkerbd51b262014-07-10 15:26:12 +02001172exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001173 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001174}
Paul Bakker33b43f12013-08-20 11:48:36 +02001175/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001176
Paul Bakker33b43f12013-08-20 11:48:36 +02001177/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001178void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001179 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001180{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001181 mbedtls_mpi X, Z, A;
1182 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001183
Werner Lewis19b4cd82022-07-07 11:02:27 +01001184 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1185 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001186 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001187 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001188 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001189 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001190 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001191 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001192 else
1193 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001194
Paul Bakkerbd51b262014-07-10 15:26:12 +02001195exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001196 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001197}
Paul Bakker33b43f12013-08-20 11:48:36 +02001198/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001199
Paul Bakker33b43f12013-08-20 11:48:36 +02001200/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001201void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1202 char * input_A, char * input_B,
1203 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001204{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001205 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001206 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001207 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1208 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001209
Werner Lewis19b4cd82022-07-07 11:02:27 +01001210 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1211 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1212 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1213 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001215 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001216 if( res == 0 )
1217 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001218 TEST_ASSERT( sign_is_valid( &Q ) );
1219 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001220 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1221 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001222 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001223
Paul Bakkerbd51b262014-07-10 15:26:12 +02001224exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001225 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1226 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001227}
Paul Bakker33b43f12013-08-20 11:48:36 +02001228/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001229
Paul Bakker33b43f12013-08-20 11:48:36 +02001230/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001231void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001232 char * input_A, char * input_B,
1233 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001234{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001235 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001236 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001237 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1238 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001239
Werner Lewis19b4cd82022-07-07 11:02:27 +01001240 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1241 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1242 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001244 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001245 if( res == 0 )
1246 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001247 TEST_ASSERT( sign_is_valid( &Q ) );
1248 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001249 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1250 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001251 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001252
Paul Bakkerbd51b262014-07-10 15:26:12 +02001253exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001254 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1255 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001256}
Paul Bakker33b43f12013-08-20 11:48:36 +02001257/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001258
Paul Bakker33b43f12013-08-20 11:48:36 +02001259/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001260void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1261 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001262{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001263 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001264 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001265 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001266
Werner Lewis19b4cd82022-07-07 11:02:27 +01001267 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1268 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1269 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001271 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001272 if( res == 0 )
1273 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001274 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001276 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001277
Paul Bakkerbd51b262014-07-10 15:26:12 +02001278exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001279 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001280}
Paul Bakker33b43f12013-08-20 11:48:36 +02001281/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001282
Paul Bakker33b43f12013-08-20 11:48:36 +02001283/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001284void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001285 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001286{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001287 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001288 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001289 mbedtls_mpi_uint r;
1290 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001291
Werner Lewis19b4cd82022-07-07 11:02:27 +01001292 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001293 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001294 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001295 if( res == 0 )
1296 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001297 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001298 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001299
Paul Bakkerbd51b262014-07-10 15:26:12 +02001300exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001301 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001302}
Paul Bakker33b43f12013-08-20 11:48:36 +02001303/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001304
Paul Bakker33b43f12013-08-20 11:48:36 +02001305/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001306void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1307 char * input_N, char * input_X,
1308 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001309{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001310 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001311 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001312 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1313 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001314
Werner Lewis19b4cd82022-07-07 11:02:27 +01001315 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1316 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1317 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1318 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001319
Gilles Peskine342f71b2021-06-09 18:31:35 +02001320 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001321 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001322 if( res == 0 )
1323 {
1324 TEST_ASSERT( sign_is_valid( &Z ) );
1325 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1326 }
1327
1328 /* Now test again with the speed-up parameter supplied as an output. */
1329 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001330 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001331 if( res == 0 )
1332 {
1333 TEST_ASSERT( sign_is_valid( &Z ) );
1334 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1335 }
1336
1337 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001338 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001339 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001340 if( res == 0 )
1341 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001342 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001343 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001344 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001345
Paul Bakkerbd51b262014-07-10 15:26:12 +02001346exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001347 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1348 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001349}
Paul Bakker33b43f12013-08-20 11:48:36 +02001350/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001351
Paul Bakker33b43f12013-08-20 11:48:36 +02001352/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001353void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001354 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001355{
1356 mbedtls_mpi A, E, N, RR, Z;
1357 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1358 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1359
Chris Jonesaa850cd2020-12-03 11:35:41 +00001360 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001361 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001362 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001363 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001364
1365 /* Set E to 2^(E_bytes - 1) + 1 */
1366 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1367 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001368 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001369
1370 /* Set N to 2^(N_bytes - 1) + 1 */
1371 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1372 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001373 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1374
1375 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001376 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001377
Chris Jonesaa850cd2020-12-03 11:35:41 +00001378 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001379
1380exit:
1381 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1382 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1383}
1384/* END_CASE */
1385
1386/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001387void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1388 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001389{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001390 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001391 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001392 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001393
Werner Lewis19b4cd82022-07-07 11:02:27 +01001394 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1395 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1396 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001398 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001399 if( res == 0 )
1400 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001401 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001402 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001403 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001404
Paul Bakkerbd51b262014-07-10 15:26:12 +02001405exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001406 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001407}
Paul Bakker33b43f12013-08-20 11:48:36 +02001408/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001409
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001411void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001412{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001413 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001414 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001416
Werner Lewis19b4cd82022-07-07 11:02:27 +01001417 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001418 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001419 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001420
Paul Bakkerbd51b262014-07-10 15:26:12 +02001421exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001423}
Paul Bakker33b43f12013-08-20 11:48:36 +02001424/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001425
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001426/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001427void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001428 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001429{
1430 mbedtls_mpi X;
1431 int res;
1432 mbedtls_test_mpi_random rand;
1433
1434 mbedtls_mpi_init( &X );
1435 rand.data = witnesses;
1436 rand.pos = 0;
1437 rand.chunk_len = chunk_len;
1438
1439 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001440 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1441 mbedtls_test_mpi_miller_rabin_determinizer,
1442 &rand );
1443 TEST_ASSERT( res == 0 );
1444
1445 rand.data = witnesses;
1446 rand.pos = 0;
1447 rand.chunk_len = chunk_len;
1448
Janos Follatha0b67c22018-09-18 14:48:23 +01001449 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1450 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001451 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001452 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001453
1454exit:
1455 mbedtls_mpi_free( &X );
1456}
1457/* END_CASE */
1458
1459/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001460void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001461{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001463 int my_ret;
1464
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001465 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001466
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001467 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1468 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001469 TEST_ASSERT( my_ret == ref_ret );
1470
1471 if( ref_ret == 0 )
1472 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001473 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001474
1475 TEST_ASSERT( actual_bits >= (size_t) bits );
1476 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001477 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001478
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001479 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1480 mbedtls_test_rnd_std_rand,
1481 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001482 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001483 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001484 /* X = ( X - 1 ) / 2 */
1485 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001486 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1487 mbedtls_test_rnd_std_rand,
1488 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001489 }
1490 }
1491
Paul Bakkerbd51b262014-07-10 15:26:12 +02001492exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001493 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001494}
1495/* END_CASE */
1496
Paul Bakker33b43f12013-08-20 11:48:36 +02001497/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001498void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1499 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001500{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001501 mbedtls_mpi X, A;
1502 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001503
Werner Lewis19b4cd82022-07-07 11:02:27 +01001504 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1505 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001507 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001509
Paul Bakkerbd51b262014-07-10 15:26:12 +02001510exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001511 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001512}
Paul Bakker33b43f12013-08-20 11:48:36 +02001513/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001514
Paul Bakker33b43f12013-08-20 11:48:36 +02001515/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001516void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1517 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001518{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519 mbedtls_mpi X, A;
1520 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001521
Werner Lewis19b4cd82022-07-07 11:02:27 +01001522 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1523 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001525 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001527
Paul Bakkerbd51b262014-07-10 15:26:12 +02001528exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001529 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001530}
Paul Bakker33b43f12013-08-20 11:48:36 +02001531/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001532
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001533/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001534void mpi_fill_random( int wanted_bytes, int rng_bytes,
1535 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001536{
1537 mbedtls_mpi X;
1538 int ret;
1539 size_t bytes_left = rng_bytes;
1540 mbedtls_mpi_init( &X );
1541
Gilles Peskine422e8672021-04-02 00:02:27 +02001542 if( before != 0 )
1543 {
1544 /* Set X to sign(before) * 2^(|before|-1) */
1545 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1546 if( before < 0 )
1547 before = - before;
1548 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1549 }
1550
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001551 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1552 f_rng_bytes_left, &bytes_left );
1553 TEST_ASSERT( ret == expected_ret );
1554
1555 if( expected_ret == 0 )
1556 {
1557 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1558 * as a big-endian representation of the number. We know when
1559 * our RNG function returns null bytes, so we know how many
1560 * leading zero bytes the number has. */
1561 size_t leading_zeros = 0;
1562 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1563 leading_zeros = 1;
1564 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1565 (size_t) wanted_bytes );
1566 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001567 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001568 }
1569
1570exit:
1571 mbedtls_mpi_free( &X );
1572}
1573/* END_CASE */
1574
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001575/* BEGIN_CASE */
1576void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1577{
1578 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1579 * This function assumes that the value of bound is at least 2 and
1580 * that iterations is large enough that a one-in-2^iterations chance
1581 * effectively never occurs.
1582 */
1583
1584 mbedtls_mpi upper_bound;
1585 size_t n_bits;
1586 mbedtls_mpi result;
1587 size_t b;
1588 /* If upper_bound is small, stats[b] is the number of times the value b
1589 * has been generated. Otherwise stats[b] is the number of times a
1590 * value with bit b set has been generated. */
1591 size_t *stats = NULL;
1592 size_t stats_len;
1593 int full_stats;
1594 size_t i;
1595
1596 mbedtls_mpi_init( &upper_bound );
1597 mbedtls_mpi_init( &result );
1598
1599 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1600 bound_bytes->x, bound_bytes->len ) );
1601 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1602 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1603 * to be small enough that the probability of missing one value is
1604 * negligible given the number of iterations. It must be less than
1605 * 256 because some of the code below assumes that "small" values
1606 * fit in a byte. */
1607 if( n_bits <= 5 )
1608 {
1609 full_stats = 1;
1610 stats_len = bound_bytes->x[bound_bytes->len - 1];
1611 }
1612 else
1613 {
1614 full_stats = 0;
1615 stats_len = n_bits;
1616 }
1617 ASSERT_ALLOC( stats, stats_len );
1618
1619 for( i = 0; i < (size_t) iterations; i++ )
1620 {
1621 mbedtls_test_set_step( i );
1622 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1623 mbedtls_test_rnd_std_rand, NULL ) );
1624
Gilles Peskinedffc7102021-06-10 15:34:15 +02001625 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001626 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1627 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1628 if( full_stats )
1629 {
1630 uint8_t value;
1631 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1632 TEST_ASSERT( value < stats_len );
1633 ++stats[value];
1634 }
1635 else
1636 {
1637 for( b = 0; b < n_bits; b++ )
1638 stats[b] += mbedtls_mpi_get_bit( &result, b );
1639 }
1640 }
1641
1642 if( full_stats )
1643 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001644 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001645 {
1646 mbedtls_test_set_step( 1000000 + b );
1647 /* Assert that each value has been reached at least once.
1648 * This is almost guaranteed if the iteration count is large
1649 * enough. This is a very crude way of checking the distribution.
1650 */
1651 TEST_ASSERT( stats[b] > 0 );
1652 }
1653 }
1654 else
1655 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001656 int statistically_safe_all_the_way =
1657 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001658 for( b = 0; b < n_bits; b++ )
1659 {
1660 mbedtls_test_set_step( 1000000 + b );
1661 /* Assert that each bit has been set in at least one result and
1662 * clear in at least one result. Provided that iterations is not
1663 * too small, it would be extremely unlikely for this not to be
1664 * the case if the results are uniformly distributed.
1665 *
1666 * As an exception, the top bit may legitimately never be set
1667 * if bound is a power of 2 or only slightly above.
1668 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001669 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001670 {
1671 TEST_ASSERT( stats[b] > 0 );
1672 }
1673 TEST_ASSERT( stats[b] < (size_t) iterations );
1674 }
1675 }
1676
1677exit:
1678 mbedtls_mpi_free( &upper_bound );
1679 mbedtls_mpi_free( &result );
1680 mbedtls_free( stats );
1681}
1682/* END_CASE */
1683
Gilles Peskine1e918f42021-03-29 22:14:51 +02001684/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001685void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001686{
1687 mbedtls_mpi upper_bound;
1688 mbedtls_mpi result;
1689
1690 mbedtls_mpi_init( &upper_bound );
1691 mbedtls_mpi_init( &result );
1692
Gilles Peskine422e8672021-04-02 00:02:27 +02001693 if( before != 0 )
1694 {
1695 /* Set result to sign(before) * 2^(|before|-1) */
1696 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1697 if( before < 0 )
1698 before = - before;
1699 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1700 }
1701
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001702 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1703 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1704 bound_bytes->x, bound_bytes->len ) );
1705 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1706 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001707 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001708 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1709 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1710
1711exit:
1712 mbedtls_mpi_free( &upper_bound );
1713 mbedtls_mpi_free( &result );
1714}
1715/* END_CASE */
1716
1717/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001718void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1719{
1720 mbedtls_mpi upper_bound;
1721 mbedtls_mpi result;
1722 int actual_ret;
1723
1724 mbedtls_mpi_init( &upper_bound );
1725 mbedtls_mpi_init( &result );
1726
1727 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1728 bound_bytes->x, bound_bytes->len ) );
1729 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1730 mbedtls_test_rnd_std_rand, NULL );
1731 TEST_EQUAL( expected_ret, actual_ret );
1732
1733exit:
1734 mbedtls_mpi_free( &upper_bound );
1735 mbedtls_mpi_free( &result );
1736}
1737/* END_CASE */
1738
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001739/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001740void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001741{
Andres AG93012e82016-09-09 09:10:28 +01001742 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001743}
Paul Bakker33b43f12013-08-20 11:48:36 +02001744/* END_CASE */