blob: 07bd03892aad22a7d53103b9662893fa60792a3d [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
Janos Follath64eca052018-09-05 17:04:49 +010013
Gabor Mezeia200f6f2022-08-03 12:59:57 +020014#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
15#define biL (ciL << 3) /* bits in limb */
16
17/*
18 * Convert between bits/chars and number of limbs
19 * Divide first in order to avoid potential overflows
20 */
21#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
22#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
23
Gilles Peskinedffc7102021-06-10 15:34:15 +020024/* Check the validity of the sign bit in an MPI object. Reject representations
25 * that are not supported by the rest of the library and indicate a bug when
26 * constructing the value. */
27static int sign_is_valid( const mbedtls_mpi *X )
28{
29 if( X->s != 1 && X->s != -1 )
30 return( 0 ); // invalid sign bit, e.g. 0
31 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
32 return( 0 ); // negative zero
33 return( 1 );
34}
35
Janos Follath64eca052018-09-05 17:04:49 +010036typedef struct mbedtls_test_mpi_random
37{
38 data_t *data;
39 size_t pos;
40 size_t chunk_len;
41} mbedtls_test_mpi_random;
42
43/*
44 * This function is called by the Miller-Rabin primality test each time it
45 * chooses a random witness. The witnesses (or non-witnesses as provided by the
46 * test) are stored in the data member of the state structure. Each number is in
47 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
48 */
49int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
50 unsigned char* buf,
51 size_t len )
52{
53 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
54
55 if( random == NULL || random->data->x == NULL || buf == NULL )
56 return( -1 );
57
58 if( random->pos + random->chunk_len > random->data->len
59 || random->chunk_len > len )
60 {
61 return( -1 );
62 }
63
64 memset( buf, 0, len );
65
66 /* The witness is written to the end of the buffer, since the buffer is
67 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
68 * Writing the witness to the start of the buffer would result in the
69 * buffer being 'witness 000...000', which would be treated as
70 * witness * 2^n for some n. */
71 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
72 random->chunk_len );
73
74 random->pos += random->chunk_len;
75
76 return( 0 );
77}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010078
79/* Random generator that is told how many bytes to return. */
80static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
81{
82 size_t *bytes_left = state;
83 size_t i;
84 for( i = 0; i < len; i++ )
85 {
86 if( *bytes_left == 0 )
87 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
88 buf[i] = *bytes_left & 0xff;
89 --( *bytes_left );
90 }
91 return( 0 );
92}
93
Gilles Peskineeedefa52021-04-13 19:50:04 +020094/* Test whether bytes represents (in big-endian base 256) a number b that
95 * is significantly above a power of 2. That is, b must not have a long run
96 * of unset bits after the most significant bit.
97 *
98 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
99 * This function returns 1 if, when drawing a number between 0 and b,
100 * the probability that this number is at least 2^n is not negligible.
101 * This probability is (b - 2^n) / b and this function checks that this
102 * number is above some threshold A. The threshold value is heuristic and
103 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200104 */
105static int is_significantly_above_a_power_of_2( data_t *bytes )
106{
107 const uint8_t *p = bytes->x;
108 size_t len = bytes->len;
109 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200110
111 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200112 while( len > 0 && p[0] == 0 )
113 {
114 ++p;
115 --len;
116 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200117 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200118 if( len == 0 )
119 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200120 /* Extract the (up to) 2 most significant bytes */
121 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200122 x = p[0];
123 else
124 x = ( p[0] << 8 ) | p[1];
125
Gilles Peskineeedefa52021-04-13 19:50:04 +0200126 /* Shift the most significant bit of x to position 8 and mask it out */
127 while( ( x & 0xfe00 ) != 0 )
128 x >>= 1;
129 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200130
Gilles Peskineeedefa52021-04-13 19:50:04 +0200131 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
132 * a power of 2 iff x is significantly above 0 compared to 2^8.
133 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
134 * description above. */
135 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200136}
137
Paul Bakker33b43f12013-08-20 11:48:36 +0200138/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000139
Paul Bakker33b43f12013-08-20 11:48:36 +0200140/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200141 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200142 * END_DEPENDENCIES
143 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000144
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000145/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100146void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200147{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200148 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200149
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200150 mbedtls_mpi_init( &X );
151 mbedtls_mpi_init( &Y );
152 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200153
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200154 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
155 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200156 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200157 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200158
159exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200160 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200161}
162/* END_CASE */
163
164/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100165void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
166 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200167 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000168{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200169 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000170 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100171 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000172
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200173 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000174
Janos Follath04dadb72019-03-06 12:29:37 +0000175 memset( str, '!', sizeof( str ) );
176
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200177 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200178 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000179 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200180 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100181 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200182 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000183 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200184 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000185 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000186 }
187 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000188
Paul Bakkerbd51b262014-07-10 15:26:12 +0200189exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000191}
Paul Bakker33b43f12013-08-20 11:48:36 +0200192/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000193
Paul Bakker33b43f12013-08-20 11:48:36 +0200194/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100195void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000196{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200197 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000198 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100199 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000200
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200201 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000202
Paul Bakkere896fea2009-07-06 06:40:23 +0000203
Azim Khand30ca132017-06-09 04:32:58 +0100204 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200205 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100206 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100207 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000208
Paul Bakkerbd51b262014-07-10 15:26:12 +0200209exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200210 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000211}
Paul Bakker33b43f12013-08-20 11:48:36 +0200212/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000213
Paul Bakker33b43f12013-08-20 11:48:36 +0200214/* BEGIN_CASE */
Janos Follath91dc67d2022-07-22 14:24:58 +0100215void mbedtls_mpi_core_io_null()
216{
217 mbedtls_mpi_uint X = 0;
218 int ret;
219
220 ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
221 TEST_ASSERT( ret == 0 );
222 ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
223 TEST_ASSERT( ret == 0 );
224
225 ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
226 TEST_ASSERT( ret == 0 );
227 ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
228 TEST_ASSERT( ret == 0 );
229
230 ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
231 TEST_ASSERT( ret == 0 );
232 ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
233 TEST_ASSERT( ret == 0 );
234
235 ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
236 TEST_ASSERT( ret == 0 );
237 ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
238 TEST_ASSERT( ret == 0 );
239
240exit:
241 ;
242}
243/* END_CASE */
244
245/* BEGIN_CASE */
Janos Follathf1d617d2022-07-21 09:29:32 +0100246void mbedtls_mpi_core_io_be( data_t *input, int nb_int, int nx_64_int, int iret,
247 int oret )
248{
249 #define BMAX 1024
250 unsigned char buf[BMAX];
251 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
252 mbedtls_mpi_uint X[XMAX];
253 size_t nx, nb;
254 int ret;
255
256 if( iret != 0 )
257 TEST_ASSERT( oret == 0 );
258
259 TEST_ASSERT( 0 <= nb_int );
260 nb = nb_int;
261 TEST_ASSERT( nb <= BMAX );
262
263 TEST_ASSERT( 0 <= nx_64_int );
264 nx = nx_64_int;
265 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
266 * to double the number of limbs to have the same size. */
267 if( sizeof( mbedtls_mpi_uint ) == 4 )
268 nx *= 2;
269 TEST_ASSERT( nx <= XMAX );
270
271 ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
272 TEST_ASSERT( ret == iret );
273
274 if( iret == 0 )
275 {
276 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
277 TEST_ASSERT( ret == oret );
278 }
279
280 if( ( iret == 0 ) && ( oret == 0 ) )
281 {
282 if( nb > input->len )
283 {
284 size_t leading_zeroes = nb - input->len;
285 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
286 for( size_t i = 0; i < leading_zeroes; i++ )
287 TEST_ASSERT( buf[i] == 0 );
288 }
289 else
290 {
291 size_t leading_zeroes = input->len - nb;
292 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
293 for( size_t i = 0; i < leading_zeroes; i++ )
294 TEST_ASSERT( input->x[i] == 0 );
295 }
296 }
297
298exit:
299 ;
300
301 #undef BMAX
302 #undef XMAX
303}
304/* END_CASE */
305
306/* BEGIN_CASE */
Janos Follath6ff35362022-07-21 15:27:21 +0100307void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_64_int, int iret,
308 int oret )
309{
310 #define BMAX 1024
311 unsigned char buf[BMAX];
312 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
313 mbedtls_mpi_uint X[XMAX];
314 size_t nx, nb;
315 int ret;
316
317 if( iret != 0 )
318 TEST_ASSERT( oret == 0 );
319
320 TEST_ASSERT( 0 <= nb_int );
321 nb = nb_int;
322 TEST_ASSERT( nb <= BMAX );
323
324 TEST_ASSERT( 0 <= nx_64_int );
325 nx = nx_64_int;
326 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
327 * to double the number of limbs to have the same size. */
328 if( sizeof( mbedtls_mpi_uint ) == 4 )
329 nx *= 2;
330 TEST_ASSERT( nx <= XMAX );
331
332 ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
333 TEST_ASSERT( ret == iret );
334
335 if( iret == 0 )
336 {
337 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
338 TEST_ASSERT( ret == oret );
339 }
340
341 if( ( iret == 0 ) && ( oret == 0 ) )
342 {
343 if( nb > input->len )
344 {
345 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
346 for( size_t i = input->len; i < nb; i++ )
347 TEST_ASSERT( buf[i] == 0 );
348 }
349 else
350 {
351 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
352 for( size_t i = nb; i < input->len; i++ )
353 TEST_ASSERT( input->x[i] == 0 );
354 }
355 }
356
357exit:
358 ;
359
360 #undef BMAX
361 #undef XMAX
362}
363/* END_CASE */
364
365/* BEGIN_CASE */
Janos Follath16949692022-08-08 13:37:20 +0100366void mbedtls_mpi_mod_setup( int ext_rep, int int_rep, int iret )
367{
368 #define MLIMBS 8
369 mbedtls_mpi_uint mp[MLIMBS];
370 mbedtls_mpi_mod_modulus m;
371 int ret;
372
373 memset( mp, 0xFF, sizeof(mp) );
374
375 mbedtls_mpi_mod_modulus_init( &m );
376 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
377 TEST_ASSERT( ret == iret );
378
379 /* Address sanitiser should catch if we try to free mp */
380 mbedtls_mpi_mod_modulus_free( &m );
381
382 /* Make sure that the modulus doesn't have reference to mp anymore */
383 TEST_ASSERT( m.p != mp );
384
385exit:
386 /* It should be safe to call an mbedtls free several times */
387 mbedtls_mpi_mod_modulus_free( &m );
388
389 #undef MLIMBS
390}
391/* END_CASE */
392
393
394/* BEGIN_CASE */
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200395void mbedtls_mpi_mod_raw_io( data_t *input, int nb_int, int nx_64_int,
396 int iendian, int iret, int oret )
397{
398 #define BMAX 1024
399 unsigned char buf[BMAX];
400 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
401 mbedtls_mpi_uint X[XMAX];
402 mbedtls_mpi_uint init[XMAX];
403 mbedtls_mpi_mod_modulus m;
404 size_t nx, nb;
405 int ret;
406 int endian;
407
408 if( iret != 0 )
409 TEST_ASSERT( oret == 0 );
410
411 TEST_ASSERT( 0 <= nb_int );
412 nb = nb_int;
413 TEST_ASSERT( nb <= BMAX );
414
415 TEST_ASSERT( 0 <= nx_64_int );
416 nx = nx_64_int;
417 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
418 * to double the number of limbs to have the same size. */
419 if( sizeof( mbedtls_mpi_uint ) == 4 )
420 nx *= 2;
421 TEST_ASSERT( nx <= XMAX );
422
423 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
424 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
425 else
426 endian = iendian;
427
428 mbedtls_mpi_mod_modulus_init( &m );
429 TEST_ASSERT( memset( init, 0xFF, sizeof( init ) ) );
430
431 ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
432 MBEDTLS_MPI_MOD_REP_MONTGOMERY );
433 TEST_ASSERT( ret == 0 );
434
435 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
436 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
437
438 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
439 TEST_ASSERT( ret == iret );
440
441 if( iret == 0 )
442 {
443 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
444 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
445
446 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
447 TEST_ASSERT( ret == oret );
448 }
449
450 if( ( iret == 0 ) && ( oret == 0 ) )
451 {
452 if( nb > input->len )
453 {
454 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
455 {
456 size_t leading_zeroes = nb - input->len;
457 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
458 for( size_t i = 0; i < leading_zeroes; i++ )
459 TEST_ASSERT( buf[i] == 0 );
460 }
461 else
462 {
463 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
464 for( size_t i = input->len; i < nb; i++ )
465 TEST_ASSERT( buf[i] == 0 );
466 }
467 }
468 else
469 {
470 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
471 {
472 size_t leading_zeroes = input->len - nb;
473 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
474 for( size_t i = 0; i < leading_zeroes; i++ )
475 TEST_ASSERT( input->x[i] == 0 );
476 }
477 else
478 {
479 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
480 for( size_t i = nb; i < input->len; i++ )
481 TEST_ASSERT( input->x[i] == 0 );
482 }
483 }
484 }
485
486exit:
487 mbedtls_mpi_mod_modulus_free( &m );
488
489 #undef BMAX
490 #undef XMAX
491}
492/* END_CASE */
493
494/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100495void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000496{
497 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000498 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000499 size_t len;
500
501 mbedtls_mpi_init( &X );
502
503
504 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200505 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100506 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100507 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000508
509exit:
510 mbedtls_mpi_free( &X );
511}
512/* END_CASE */
513
514/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100515void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
516 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000517{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000519 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000520 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000521
522 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000523
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200524 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000525
Werner Lewis19b4cd82022-07-07 11:02:27 +0100526 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100527
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200528 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200529 if( buflen > (size_t) output_size )
530 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000531
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200532 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200533 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000534 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000535
Ronald Cron2dbba992020-06-10 11:42:32 +0200536 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
537 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000538 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000539
Paul Bakkerbd51b262014-07-10 15:26:12 +0200540exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200541 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000542}
Paul Bakker33b43f12013-08-20 11:48:36 +0200543/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000544
Janos Follathe344d0f2019-02-19 16:17:40 +0000545/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100546void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
547 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000548{
549 mbedtls_mpi X;
550 unsigned char buf[1000];
551 size_t buflen;
552
553 memset( buf, 0x00, 1000 );
554
555 mbedtls_mpi_init( &X );
556
Werner Lewis19b4cd82022-07-07 11:02:27 +0100557 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000558
559 buflen = mbedtls_mpi_size( &X );
560 if( buflen > (size_t) output_size )
561 buflen = (size_t) output_size;
562
563 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
564 if( result == 0)
565 {
566
Ronald Cron2dbba992020-06-10 11:42:32 +0200567 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
568 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000569 }
570
571exit:
572 mbedtls_mpi_free( &X );
573}
574/* END_CASE */
575
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200576/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100577void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000578{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200579 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000580 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000581 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000582 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000583 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000584
585 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000586
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200587 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000588
Paul Bakker33b43f12013-08-20 11:48:36 +0200589 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200590 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100591 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000592 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000593 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000594
Paul Bakker33b43f12013-08-20 11:48:36 +0200595 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000596 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200597 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200598 buflen = mbedtls_mpi_size( &X );
599 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000600
Paul Bakkere896fea2009-07-06 06:40:23 +0000601
Ronald Cron2dbba992020-06-10 11:42:32 +0200602 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
603 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000604 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000605
Paul Bakkerbd51b262014-07-10 15:26:12 +0200606exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200607 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000608}
Paul Bakker33b43f12013-08-20 11:48:36 +0200609/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100612void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000613{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000615 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200616 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000617
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000619
Werner Lewis19b4cd82022-07-07 11:02:27 +0100620 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000621
Paul Bakker33b43f12013-08-20 11:48:36 +0200622 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000623 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100624 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000625 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200626 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000627
Paul Bakker33b43f12013-08-20 11:48:36 +0200628 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000629 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100630 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000631 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200632 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000633
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000635
Paul Bakkerbd51b262014-07-10 15:26:12 +0200636exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000638}
Paul Bakker33b43f12013-08-20 11:48:36 +0200639/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000640
Paul Bakker33b43f12013-08-20 11:48:36 +0200641/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100642void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000643{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200644 mbedtls_mpi X;
645 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100646 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200647 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000648
Paul Bakkerbd51b262014-07-10 15:26:12 +0200649exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000651}
Paul Bakker33b43f12013-08-20 11:48:36 +0200652/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000653
Paul Bakker33b43f12013-08-20 11:48:36 +0200654/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100655void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
656 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000657{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200658 mbedtls_mpi X, Y;
659 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000660
Werner Lewis19b4cd82022-07-07 11:02:27 +0100661 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
662 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100663 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
664
665 if( result == 0 )
666 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200667 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100668 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
669 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000670
Paul Bakkerbd51b262014-07-10 15:26:12 +0200671exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200672 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000673}
Paul Bakker33b43f12013-08-20 11:48:36 +0200674/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000675
Paul Bakker33b43f12013-08-20 11:48:36 +0200676/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100677void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000678{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_mpi X;
680 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000681
Werner Lewis19b4cd82022-07-07 11:02:27 +0100682 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000684
Paul Bakkerbd51b262014-07-10 15:26:12 +0200685exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200686 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000687}
Paul Bakker33b43f12013-08-20 11:48:36 +0200688/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000689
Paul Bakker33b43f12013-08-20 11:48:36 +0200690/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100691void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000692{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200693 mbedtls_mpi X;
694 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000695
Werner Lewis19b4cd82022-07-07 11:02:27 +0100696 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200697 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000698
Paul Bakkerbd51b262014-07-10 15:26:12 +0200699exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000701}
Paul Bakker33b43f12013-08-20 11:48:36 +0200702/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000703
Paul Bakker33b43f12013-08-20 11:48:36 +0200704/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100705void mbedtls_mpi_gcd( char * input_X, char * input_Y,
706 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000707{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708 mbedtls_mpi A, X, Y, Z;
709 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000710
Werner Lewis19b4cd82022-07-07 11:02:27 +0100711 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
712 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
713 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200715 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000717
Paul Bakkerbd51b262014-07-10 15:26:12 +0200718exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000720}
Paul Bakker33b43f12013-08-20 11:48:36 +0200721/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000722
Paul Bakker33b43f12013-08-20 11:48:36 +0200723/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000725{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200726 mbedtls_mpi X;
727 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000728
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200729 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
730 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000731
Paul Bakkerbd51b262014-07-10 15:26:12 +0200732exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200733 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000734}
Paul Bakker33b43f12013-08-20 11:48:36 +0200735/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000736
Paul Bakker33b43f12013-08-20 11:48:36 +0200737/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100738void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
739 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000740{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200741 mbedtls_mpi X, Y;
742 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000743
Werner Lewis19b4cd82022-07-07 11:02:27 +0100744 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
745 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200746 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000747
Paul Bakkerbd51b262014-07-10 15:26:12 +0200748exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200749 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000750}
Paul Bakker33b43f12013-08-20 11:48:36 +0200751/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000752
Paul Bakker33b43f12013-08-20 11:48:36 +0200753/* BEGIN_CASE */
Janos Follath23bdeca2022-07-22 18:24:06 +0100754void mbedtls_mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
755{
756 #define MAX_LEN 64
757 mbedtls_mpi_uint X[MAX_LEN];
758 mbedtls_mpi_uint Y[MAX_LEN];
759 unsigned exp_ret = input_ret;
760 unsigned ret;
761 size_t len = CHARS_TO_LIMBS(
762 input_X->len > input_Y->len ? input_X->len : input_Y->len );
763
764 TEST_ASSERT( len <= MAX_LEN );
765
766 TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
767 == 0 );
768 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
769 == 0 );
770
771 TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
772 TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
773
774 ret = mbedtls_mpi_core_lt_ct( X, Y, len );
775
776 TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
777 TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
778 TEST_CF_PUBLIC( &ret, sizeof( ret ) );
779
780 TEST_ASSERT( ret == exp_ret );
781
782exit:
783 ;
784
785 #undef MAX_LEN
786}
787/* END_CASE */
788
789/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100790void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
791 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100792 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100793{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200794 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100795 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100796 mbedtls_mpi X, Y;
797 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
798
Werner Lewis19b4cd82022-07-07 11:02:27 +0100799 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
800 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100801
Gilles Peskine9018b112020-01-21 16:30:53 +0100802 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
803 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100804
Janos Follath0e5532d2019-10-11 14:21:53 +0100805 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100806 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100807 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100808
809exit:
810 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
811}
812/* END_CASE */
813
814/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100815void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
816 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000817{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200818 mbedtls_mpi X, Y;
819 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000820
Werner Lewis19b4cd82022-07-07 11:02:27 +0100821 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
822 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200823 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000824
Paul Bakkerbd51b262014-07-10 15:26:12 +0200825exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200826 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000827}
Paul Bakker33b43f12013-08-20 11:48:36 +0200828/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000829
Paul Bakker33b43f12013-08-20 11:48:36 +0200830/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200831void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000832{
Gilles Peskined0722f82021-06-10 23:00:33 +0200833 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200834 mbedtls_mpi_init( &src );
835 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200836 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000837
Werner Lewis19b4cd82022-07-07 11:02:27 +0100838 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
839 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200840
841 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100842 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200843 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200844 TEST_ASSERT( sign_is_valid( &dst ) );
845 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000846
Gilles Peskined0722f82021-06-10 23:00:33 +0200847 /* mbedtls_mpi_safe_cond_assign(), assignment 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, 1 ) == 0 );
851 TEST_ASSERT( sign_is_valid( &dst ) );
852 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
853
854 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
855 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100856 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200857 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
858 TEST_ASSERT( sign_is_valid( &dst ) );
859 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
860
Paul Bakkerbd51b262014-07-10 15:26:12 +0200861exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200862 mbedtls_mpi_free( &src );
863 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200864 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100865}
866/* END_CASE */
867
868/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200869void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100870{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200871 mbedtls_mpi X, A;
872 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200873 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000874
Werner Lewis19b4cd82022-07-07 11:02:27 +0100875 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200876 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200877
Werner Lewis19b4cd82022-07-07 11:02:27 +0100878 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200879 TEST_ASSERT( sign_is_valid( &X ) );
880 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000881
Paul Bakkerbd51b262014-07-10 15:26:12 +0200882exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200883 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200884 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000885}
Paul Bakker33b43f12013-08-20 11:48:36 +0200886/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000887
Paul Bakker33b43f12013-08-20 11:48:36 +0200888/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200889void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
890{
891 mbedtls_mpi X, Y, X0, Y0;
892 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
893 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
894
Werner Lewis19b4cd82022-07-07 11:02:27 +0100895 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
896 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200897
Gilles Peskined0722f82021-06-10 23:00:33 +0200898 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100899 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
900 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200901 mbedtls_mpi_swap( &X, &Y );
902 TEST_ASSERT( sign_is_valid( &X ) );
903 TEST_ASSERT( sign_is_valid( &Y ) );
904 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
905 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
906
Gilles Peskined0722f82021-06-10 23:00:33 +0200907 /* mbedtls_mpi_safe_cond_swap(), swap done */
908 mbedtls_mpi_free( &X );
909 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100910 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
911 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200912 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
913 TEST_ASSERT( sign_is_valid( &X ) );
914 TEST_ASSERT( sign_is_valid( &Y ) );
915 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
916 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
917
918 /* mbedtls_mpi_safe_cond_swap(), swap not done */
919 mbedtls_mpi_free( &X );
920 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100921 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
922 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200923 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
924 TEST_ASSERT( sign_is_valid( &X ) );
925 TEST_ASSERT( sign_is_valid( &Y ) );
926 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
927 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
928
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200929exit:
930 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
931 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
932}
933/* END_CASE */
934
935/* BEGIN_CASE */
936void mpi_swap_self( char *X_hex )
937{
938 mbedtls_mpi X, X0;
939 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
940
Werner Lewis19b4cd82022-07-07 11:02:27 +0100941 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
942 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200943
944 mbedtls_mpi_swap( &X, &X );
945 TEST_ASSERT( sign_is_valid( &X ) );
946 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
947
948exit:
949 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
950}
951/* END_CASE */
952
953/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200954void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100955{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 mbedtls_mpi X;
957 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100958
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200959 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200960 if( used > 0 )
961 {
962 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
963 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
964 }
965 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200966 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200967 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100968
Paul Bakkerbd51b262014-07-10 15:26:12 +0200969exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200970 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100971}
972/* END_CASE */
973
974/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100975void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
976 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000977{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200978 mbedtls_mpi X, Y, Z, A;
979 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000980
Werner Lewis19b4cd82022-07-07 11:02:27 +0100981 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
982 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
983 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200984 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200985 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200986 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000987
Gilles Peskine56f943a2020-07-23 01:18:11 +0200988 /* result == first operand */
989 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200990 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200991 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100992 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200993
994 /* result == second operand */
995 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200996 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200997 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
998
Paul Bakkerbd51b262014-07-10 15:26:12 +0200999exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001000 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001001}
Paul Bakker33b43f12013-08-20 11:48:36 +02001002/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001003
Paul Bakker33b43f12013-08-20 11:48:36 +02001004/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001005void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +01001006{
1007 mbedtls_mpi X, A;
1008 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1009
Werner Lewis19b4cd82022-07-07 11:02:27 +01001010 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001011
Werner Lewis19b4cd82022-07-07 11:02:27 +01001012 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001013 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
1014 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001015 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001016
Werner Lewis19b4cd82022-07-07 11:02:27 +01001017 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001018 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001019 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001020 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1021
Werner Lewis19b4cd82022-07-07 11:02:27 +01001022 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +01001023 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001024 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +01001025 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1026
1027exit:
1028 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1029}
1030/* END_CASE */
1031
1032
1033/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001034void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
1035 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001036{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001037 mbedtls_mpi X, Y, Z, A;
1038 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001039
Werner Lewis19b4cd82022-07-07 11:02:27 +01001040 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1041 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1042 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001043 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001044 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001046
Gilles Peskine56f943a2020-07-23 01:18:11 +02001047 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001049 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001050 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001051 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001052
1053 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001054 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001055 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001057
Paul Bakkerbd51b262014-07-10 15:26:12 +02001058exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001059 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001060}
Paul Bakker33b43f12013-08-20 11:48:36 +02001061/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001062
Paul Bakker33b43f12013-08-20 11:48:36 +02001063/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001064void mbedtls_mpi_add_int( char * input_X, int input_Y,
1065 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001066{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_mpi X, Z, A;
1068 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001069
Werner Lewis19b4cd82022-07-07 11:02:27 +01001070 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1071 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001072 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001073 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001074 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001075
Paul Bakkerbd51b262014-07-10 15:26:12 +02001076exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001077 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001078}
Paul Bakker33b43f12013-08-20 11:48:36 +02001079/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001080
Paul Bakker33b43f12013-08-20 11:48:36 +02001081/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001082void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
1083 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001084{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001085 mbedtls_mpi X, Y, Z, A;
1086 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001087
Werner Lewis19b4cd82022-07-07 11:02:27 +01001088 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1089 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1090 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001091 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001092 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001094
Gilles Peskine56f943a2020-07-23 01:18:11 +02001095 /* result == first operand */
1096 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001097 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001098 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001099 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001100
1101 /* result == second operand */
1102 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001103 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001104 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1105
Paul Bakkerbd51b262014-07-10 15:26:12 +02001106exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001108}
Paul Bakker33b43f12013-08-20 11:48:36 +02001109/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001110
Paul Bakker33b43f12013-08-20 11:48:36 +02001111/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001112void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
1113 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001114{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001116 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001118
Werner Lewis19b4cd82022-07-07 11:02:27 +01001119 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1120 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1121 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001122
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001123 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001124 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001125 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001126 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001127 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001128
Gilles Peskine56f943a2020-07-23 01:18:11 +02001129 /* result == first operand */
1130 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001131 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001132 if( sub_result == 0 )
1133 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001134 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001135
1136 /* result == second operand */
1137 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001138 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001139 if( sub_result == 0 )
1140 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1141
Paul Bakkerbd51b262014-07-10 15:26:12 +02001142exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001143 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001144}
Paul Bakker33b43f12013-08-20 11:48:36 +02001145/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001146
Paul Bakker33b43f12013-08-20 11:48:36 +02001147/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001148void mbedtls_mpi_sub_int( char * input_X, int input_Y,
1149 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001150{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 mbedtls_mpi X, Z, A;
1152 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001153
Werner Lewis19b4cd82022-07-07 11:02:27 +01001154 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1155 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001156 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001157 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001158 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001159
Paul Bakkerbd51b262014-07-10 15:26:12 +02001160exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001161 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001162}
Paul Bakker33b43f12013-08-20 11:48:36 +02001163/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001164
Paul Bakker33b43f12013-08-20 11:48:36 +02001165/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001166void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
1167 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001168{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169 mbedtls_mpi X, Y, Z, A;
1170 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001171
Werner Lewis19b4cd82022-07-07 11:02:27 +01001172 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1173 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1174 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001175 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001176 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001177 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001178
Paul Bakkerbd51b262014-07-10 15:26:12 +02001179exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001180 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001181}
Paul Bakker33b43f12013-08-20 11:48:36 +02001182/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001183
Paul Bakker33b43f12013-08-20 11:48:36 +02001184/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001185void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001186 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001187{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188 mbedtls_mpi X, Z, A;
1189 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001190
Werner Lewis19b4cd82022-07-07 11:02:27 +01001191 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1192 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001194 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001195 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001196 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001197 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001199 else
1200 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001201
Paul Bakkerbd51b262014-07-10 15:26:12 +02001202exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001203 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001204}
Paul Bakker33b43f12013-08-20 11:48:36 +02001205/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001206
Paul Bakker33b43f12013-08-20 11:48:36 +02001207/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001208void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1209 char * input_A, char * input_B,
1210 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001211{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001212 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001213 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001214 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1215 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001216
Werner Lewis19b4cd82022-07-07 11:02:27 +01001217 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1218 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1219 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1220 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001221 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001222 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001223 if( res == 0 )
1224 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001225 TEST_ASSERT( sign_is_valid( &Q ) );
1226 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001227 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1228 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001229 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001230
Paul Bakkerbd51b262014-07-10 15:26:12 +02001231exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1233 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001234}
Paul Bakker33b43f12013-08-20 11:48:36 +02001235/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001236
Paul Bakker33b43f12013-08-20 11:48:36 +02001237/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001238void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001239 char * input_A, char * input_B,
1240 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001241{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001242 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001243 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001244 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1245 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001246
Werner Lewis19b4cd82022-07-07 11:02:27 +01001247 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1248 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1249 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001250 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001251 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001252 if( res == 0 )
1253 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001254 TEST_ASSERT( sign_is_valid( &Q ) );
1255 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001256 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1257 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001258 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001259
Paul Bakkerbd51b262014-07-10 15:26:12 +02001260exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001261 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1262 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001263}
Paul Bakker33b43f12013-08-20 11:48:36 +02001264/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001265
Paul Bakker33b43f12013-08-20 11:48:36 +02001266/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001267void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1268 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001269{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001271 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001273
Werner Lewis19b4cd82022-07-07 11:02:27 +01001274 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1275 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1276 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001277 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001278 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001279 if( res == 0 )
1280 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001281 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001282 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001283 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001284
Paul Bakkerbd51b262014-07-10 15:26:12 +02001285exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001287}
Paul Bakker33b43f12013-08-20 11:48:36 +02001288/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001289
Paul Bakker33b43f12013-08-20 11:48:36 +02001290/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001291void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001292 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001293{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001295 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001296 mbedtls_mpi_uint r;
1297 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001298
Werner Lewis19b4cd82022-07-07 11:02:27 +01001299 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001300 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001301 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001302 if( res == 0 )
1303 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001304 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001305 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001306
Paul Bakkerbd51b262014-07-10 15:26:12 +02001307exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001308 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001309}
Paul Bakker33b43f12013-08-20 11:48:36 +02001310/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001311
Paul Bakker33b43f12013-08-20 11:48:36 +02001312/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001313void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1314 char * input_N, char * input_X,
1315 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001316{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001317 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001318 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001319 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1320 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001321
Werner Lewis19b4cd82022-07-07 11:02:27 +01001322 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1323 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1324 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1325 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001326
Gilles Peskine342f71b2021-06-09 18:31:35 +02001327 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001328 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001329 if( res == 0 )
1330 {
1331 TEST_ASSERT( sign_is_valid( &Z ) );
1332 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1333 }
1334
1335 /* Now test again with the speed-up parameter supplied as an output. */
1336 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001337 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001338 if( res == 0 )
1339 {
1340 TEST_ASSERT( sign_is_valid( &Z ) );
1341 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1342 }
1343
1344 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001345 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001346 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001347 if( res == 0 )
1348 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001349 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001350 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001351 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001352
Paul Bakkerbd51b262014-07-10 15:26:12 +02001353exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001354 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1355 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001356}
Paul Bakker33b43f12013-08-20 11:48:36 +02001357/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001358
Paul Bakker33b43f12013-08-20 11:48:36 +02001359/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001360void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001361 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001362{
1363 mbedtls_mpi A, E, N, RR, Z;
1364 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1365 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1366
Chris Jonesaa850cd2020-12-03 11:35:41 +00001367 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001368 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001369 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001370 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001371
1372 /* Set E to 2^(E_bytes - 1) + 1 */
1373 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1374 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001375 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001376
1377 /* Set N to 2^(N_bytes - 1) + 1 */
1378 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1379 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001380 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1381
1382 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001383 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001384
Chris Jonesaa850cd2020-12-03 11:35:41 +00001385 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001386
1387exit:
1388 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1389 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1390}
1391/* END_CASE */
1392
1393/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001394void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1395 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001396{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001397 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001398 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001400
Werner Lewis19b4cd82022-07-07 11:02:27 +01001401 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1402 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1403 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001405 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001406 if( res == 0 )
1407 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001408 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001410 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001411
Paul Bakkerbd51b262014-07-10 15:26:12 +02001412exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001413 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001414}
Paul Bakker33b43f12013-08-20 11:48:36 +02001415/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001416
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001417/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001418void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001419{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001420 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001421 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001422 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001423
Werner Lewis19b4cd82022-07-07 11:02:27 +01001424 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001425 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001426 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001427
Paul Bakkerbd51b262014-07-10 15:26:12 +02001428exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001429 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001430}
Paul Bakker33b43f12013-08-20 11:48:36 +02001431/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001432
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001433/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001434void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001435 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001436{
1437 mbedtls_mpi X;
1438 int res;
1439 mbedtls_test_mpi_random rand;
1440
1441 mbedtls_mpi_init( &X );
1442 rand.data = witnesses;
1443 rand.pos = 0;
1444 rand.chunk_len = chunk_len;
1445
1446 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001447 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1448 mbedtls_test_mpi_miller_rabin_determinizer,
1449 &rand );
1450 TEST_ASSERT( res == 0 );
1451
1452 rand.data = witnesses;
1453 rand.pos = 0;
1454 rand.chunk_len = chunk_len;
1455
Janos Follatha0b67c22018-09-18 14:48:23 +01001456 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1457 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001458 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001459 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001460
1461exit:
1462 mbedtls_mpi_free( &X );
1463}
1464/* END_CASE */
1465
1466/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001467void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001468{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001470 int my_ret;
1471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001473
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001474 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1475 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001476 TEST_ASSERT( my_ret == ref_ret );
1477
1478 if( ref_ret == 0 )
1479 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001480 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001481
1482 TEST_ASSERT( actual_bits >= (size_t) bits );
1483 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001484 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001485
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 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001489 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001490 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001491 /* X = ( X - 1 ) / 2 */
1492 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001493 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1494 mbedtls_test_rnd_std_rand,
1495 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001496 }
1497 }
1498
Paul Bakkerbd51b262014-07-10 15:26:12 +02001499exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001500 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001501}
1502/* END_CASE */
1503
Paul Bakker33b43f12013-08-20 11:48:36 +02001504/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001505void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1506 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001507{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508 mbedtls_mpi X, A;
1509 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001510
Werner Lewis19b4cd82022-07-07 11:02:27 +01001511 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1512 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001514 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001515 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001516
Paul Bakkerbd51b262014-07-10 15:26:12 +02001517exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001519}
Paul Bakker33b43f12013-08-20 11:48:36 +02001520/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001521
Paul Bakker33b43f12013-08-20 11:48:36 +02001522/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001523void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1524 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001525{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 mbedtls_mpi X, A;
1527 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001528
Werner Lewis19b4cd82022-07-07 11:02:27 +01001529 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1530 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001531 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001532 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001533 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001534
Paul Bakkerbd51b262014-07-10 15:26:12 +02001535exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001537}
Paul Bakker33b43f12013-08-20 11:48:36 +02001538/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001539
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001540/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001541void mpi_fill_random( int wanted_bytes, int rng_bytes,
1542 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001543{
1544 mbedtls_mpi X;
1545 int ret;
1546 size_t bytes_left = rng_bytes;
1547 mbedtls_mpi_init( &X );
1548
Gilles Peskine422e8672021-04-02 00:02:27 +02001549 if( before != 0 )
1550 {
1551 /* Set X to sign(before) * 2^(|before|-1) */
1552 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1553 if( before < 0 )
1554 before = - before;
1555 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1556 }
1557
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001558 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1559 f_rng_bytes_left, &bytes_left );
1560 TEST_ASSERT( ret == expected_ret );
1561
1562 if( expected_ret == 0 )
1563 {
1564 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1565 * as a big-endian representation of the number. We know when
1566 * our RNG function returns null bytes, so we know how many
1567 * leading zero bytes the number has. */
1568 size_t leading_zeros = 0;
1569 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1570 leading_zeros = 1;
1571 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1572 (size_t) wanted_bytes );
1573 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001574 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001575 }
1576
1577exit:
1578 mbedtls_mpi_free( &X );
1579}
1580/* END_CASE */
1581
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001582/* BEGIN_CASE */
1583void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1584{
1585 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1586 * This function assumes that the value of bound is at least 2 and
1587 * that iterations is large enough that a one-in-2^iterations chance
1588 * effectively never occurs.
1589 */
1590
1591 mbedtls_mpi upper_bound;
1592 size_t n_bits;
1593 mbedtls_mpi result;
1594 size_t b;
1595 /* If upper_bound is small, stats[b] is the number of times the value b
1596 * has been generated. Otherwise stats[b] is the number of times a
1597 * value with bit b set has been generated. */
1598 size_t *stats = NULL;
1599 size_t stats_len;
1600 int full_stats;
1601 size_t i;
1602
1603 mbedtls_mpi_init( &upper_bound );
1604 mbedtls_mpi_init( &result );
1605
1606 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1607 bound_bytes->x, bound_bytes->len ) );
1608 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1609 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1610 * to be small enough that the probability of missing one value is
1611 * negligible given the number of iterations. It must be less than
1612 * 256 because some of the code below assumes that "small" values
1613 * fit in a byte. */
1614 if( n_bits <= 5 )
1615 {
1616 full_stats = 1;
1617 stats_len = bound_bytes->x[bound_bytes->len - 1];
1618 }
1619 else
1620 {
1621 full_stats = 0;
1622 stats_len = n_bits;
1623 }
1624 ASSERT_ALLOC( stats, stats_len );
1625
1626 for( i = 0; i < (size_t) iterations; i++ )
1627 {
1628 mbedtls_test_set_step( i );
1629 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1630 mbedtls_test_rnd_std_rand, NULL ) );
1631
Gilles Peskinedffc7102021-06-10 15:34:15 +02001632 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001633 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1634 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1635 if( full_stats )
1636 {
1637 uint8_t value;
1638 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1639 TEST_ASSERT( value < stats_len );
1640 ++stats[value];
1641 }
1642 else
1643 {
1644 for( b = 0; b < n_bits; b++ )
1645 stats[b] += mbedtls_mpi_get_bit( &result, b );
1646 }
1647 }
1648
1649 if( full_stats )
1650 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001651 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001652 {
1653 mbedtls_test_set_step( 1000000 + b );
1654 /* Assert that each value has been reached at least once.
1655 * This is almost guaranteed if the iteration count is large
1656 * enough. This is a very crude way of checking the distribution.
1657 */
1658 TEST_ASSERT( stats[b] > 0 );
1659 }
1660 }
1661 else
1662 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001663 int statistically_safe_all_the_way =
1664 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001665 for( b = 0; b < n_bits; b++ )
1666 {
1667 mbedtls_test_set_step( 1000000 + b );
1668 /* Assert that each bit has been set in at least one result and
1669 * clear in at least one result. Provided that iterations is not
1670 * too small, it would be extremely unlikely for this not to be
1671 * the case if the results are uniformly distributed.
1672 *
1673 * As an exception, the top bit may legitimately never be set
1674 * if bound is a power of 2 or only slightly above.
1675 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001676 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001677 {
1678 TEST_ASSERT( stats[b] > 0 );
1679 }
1680 TEST_ASSERT( stats[b] < (size_t) iterations );
1681 }
1682 }
1683
1684exit:
1685 mbedtls_mpi_free( &upper_bound );
1686 mbedtls_mpi_free( &result );
1687 mbedtls_free( stats );
1688}
1689/* END_CASE */
1690
Gilles Peskine1e918f42021-03-29 22:14:51 +02001691/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001692void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001693{
1694 mbedtls_mpi upper_bound;
1695 mbedtls_mpi result;
1696
1697 mbedtls_mpi_init( &upper_bound );
1698 mbedtls_mpi_init( &result );
1699
Gilles Peskine422e8672021-04-02 00:02:27 +02001700 if( before != 0 )
1701 {
1702 /* Set result to sign(before) * 2^(|before|-1) */
1703 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1704 if( before < 0 )
1705 before = - before;
1706 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1707 }
1708
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001709 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1710 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1711 bound_bytes->x, bound_bytes->len ) );
1712 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1713 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001714 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001715 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1716 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1717
1718exit:
1719 mbedtls_mpi_free( &upper_bound );
1720 mbedtls_mpi_free( &result );
1721}
1722/* END_CASE */
1723
1724/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001725void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1726{
1727 mbedtls_mpi upper_bound;
1728 mbedtls_mpi result;
1729 int actual_ret;
1730
1731 mbedtls_mpi_init( &upper_bound );
1732 mbedtls_mpi_init( &result );
1733
1734 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1735 bound_bytes->x, bound_bytes->len ) );
1736 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1737 mbedtls_test_rnd_std_rand, NULL );
1738 TEST_EQUAL( expected_ret, actual_ret );
1739
1740exit:
1741 mbedtls_mpi_free( &upper_bound );
1742 mbedtls_mpi_free( &result );
1743}
1744/* END_CASE */
1745
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001746/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001747void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001748{
Andres AG93012e82016-09-09 09:10:28 +01001749 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001750}
Paul Bakker33b43f12013-08-20 11:48:36 +02001751/* END_CASE */