blob: cd901d17c76d99af912349004c504d199c349bf2 [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 Follathd0895702022-08-10 13:32:16 +010013#
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{
239 #define BMAX 1024
240 unsigned char buf[BMAX];
241 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
242 mbedtls_mpi_uint X[XMAX];
243 size_t nx, nb;
244 int ret;
245
246 if( iret != 0 )
247 TEST_ASSERT( oret == 0 );
248
249 TEST_ASSERT( 0 <= nb_int );
250 nb = nb_int;
251 TEST_ASSERT( nb <= BMAX );
252
Janos Follath1cb3b972022-08-11 10:50:04 +0100253 TEST_ASSERT( 0 <= nx_32_int );
254 nx = nx_32_int;
255 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
256 * to halve the number of limbs to have the same size. */
257 if( sizeof( mbedtls_mpi_uint ) == 8 )
258 nx = nx / 2 + nx % 2;
Janos Follathf1d617d2022-07-21 09:29:32 +0100259 TEST_ASSERT( nx <= XMAX );
260
261 ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
262 TEST_ASSERT( ret == iret );
263
264 if( iret == 0 )
265 {
266 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
267 TEST_ASSERT( ret == oret );
268 }
269
270 if( ( iret == 0 ) && ( oret == 0 ) )
271 {
272 if( nb > input->len )
273 {
274 size_t leading_zeroes = nb - input->len;
275 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
276 for( size_t i = 0; i < leading_zeroes; i++ )
277 TEST_ASSERT( buf[i] == 0 );
278 }
279 else
280 {
281 size_t leading_zeroes = input->len - nb;
282 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
283 for( size_t i = 0; i < leading_zeroes; i++ )
284 TEST_ASSERT( input->x[i] == 0 );
285 }
286 }
287
288exit:
289 ;
290
291 #undef BMAX
292 #undef XMAX
293}
294/* END_CASE */
295
296/* BEGIN_CASE */
Janos Follath6ff35362022-07-21 15:27:21 +0100297void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_64_int, int iret,
298 int oret )
299{
300 #define BMAX 1024
301 unsigned char buf[BMAX];
302 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
303 mbedtls_mpi_uint X[XMAX];
304 size_t nx, nb;
305 int ret;
306
307 if( iret != 0 )
308 TEST_ASSERT( oret == 0 );
309
310 TEST_ASSERT( 0 <= nb_int );
311 nb = nb_int;
312 TEST_ASSERT( nb <= BMAX );
313
314 TEST_ASSERT( 0 <= nx_64_int );
315 nx = nx_64_int;
316 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
317 * to double the number of limbs to have the same size. */
318 if( sizeof( mbedtls_mpi_uint ) == 4 )
319 nx *= 2;
320 TEST_ASSERT( nx <= XMAX );
321
322 ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
323 TEST_ASSERT( ret == iret );
324
325 if( iret == 0 )
326 {
327 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
328 TEST_ASSERT( ret == oret );
329 }
330
331 if( ( iret == 0 ) && ( oret == 0 ) )
332 {
333 if( nb > input->len )
334 {
335 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
336 for( size_t i = input->len; i < nb; i++ )
337 TEST_ASSERT( buf[i] == 0 );
338 }
339 else
340 {
341 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
342 for( size_t i = nb; i < input->len; i++ )
343 TEST_ASSERT( input->x[i] == 0 );
344 }
345 }
346
347exit:
348 ;
349
350 #undef BMAX
351 #undef XMAX
352}
353/* END_CASE */
354
355/* BEGIN_CASE */
Janos Follath16949692022-08-08 13:37:20 +0100356void mbedtls_mpi_mod_setup( int ext_rep, int int_rep, int iret )
357{
358 #define MLIMBS 8
359 mbedtls_mpi_uint mp[MLIMBS];
360 mbedtls_mpi_mod_modulus m;
361 int ret;
362
363 memset( mp, 0xFF, sizeof(mp) );
364
365 mbedtls_mpi_mod_modulus_init( &m );
366 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
367 TEST_ASSERT( ret == iret );
368
369 /* Address sanitiser should catch if we try to free mp */
370 mbedtls_mpi_mod_modulus_free( &m );
371
372 /* Make sure that the modulus doesn't have reference to mp anymore */
373 TEST_ASSERT( m.p != mp );
374
375exit:
376 /* It should be safe to call an mbedtls free several times */
377 mbedtls_mpi_mod_modulus_free( &m );
378
379 #undef MLIMBS
380}
381/* END_CASE */
382
383
384/* BEGIN_CASE */
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200385void mbedtls_mpi_mod_raw_io( data_t *input, int nb_int, int nx_64_int,
386 int iendian, int iret, int oret )
387{
388 #define BMAX 1024
389 unsigned char buf[BMAX];
390 #define XMAX BMAX / sizeof( mbedtls_mpi_uint )
391 mbedtls_mpi_uint X[XMAX];
392 mbedtls_mpi_uint init[XMAX];
393 mbedtls_mpi_mod_modulus m;
394 size_t nx, nb;
395 int ret;
396 int endian;
397
398 if( iret != 0 )
399 TEST_ASSERT( oret == 0 );
400
401 TEST_ASSERT( 0 <= nb_int );
402 nb = nb_int;
403 TEST_ASSERT( nb <= BMAX );
404
405 TEST_ASSERT( 0 <= nx_64_int );
406 nx = nx_64_int;
407 /* nx_64_int is the number of 64 bit limbs, if we have 32 bit limbs we need
408 * to double the number of limbs to have the same size. */
409 if( sizeof( mbedtls_mpi_uint ) == 4 )
410 nx *= 2;
411 TEST_ASSERT( nx <= XMAX );
412
413 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
414 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
415 else
416 endian = iendian;
417
418 mbedtls_mpi_mod_modulus_init( &m );
419 TEST_ASSERT( memset( init, 0xFF, sizeof( init ) ) );
420
421 ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
422 MBEDTLS_MPI_MOD_REP_MONTGOMERY );
423 TEST_ASSERT( ret == 0 );
424
425 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
426 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
427
428 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
429 TEST_ASSERT( ret == iret );
430
431 if( iret == 0 )
432 {
433 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
434 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
435
436 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
437 TEST_ASSERT( ret == oret );
438 }
439
440 if( ( iret == 0 ) && ( oret == 0 ) )
441 {
442 if( nb > input->len )
443 {
444 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
445 {
446 size_t leading_zeroes = nb - input->len;
447 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
448 for( size_t i = 0; i < leading_zeroes; i++ )
449 TEST_ASSERT( buf[i] == 0 );
450 }
451 else
452 {
453 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
454 for( size_t i = input->len; i < nb; i++ )
455 TEST_ASSERT( buf[i] == 0 );
456 }
457 }
458 else
459 {
460 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
461 {
462 size_t leading_zeroes = input->len - nb;
463 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
464 for( size_t i = 0; i < leading_zeroes; i++ )
465 TEST_ASSERT( input->x[i] == 0 );
466 }
467 else
468 {
469 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
470 for( size_t i = nb; i < input->len; i++ )
471 TEST_ASSERT( input->x[i] == 0 );
472 }
473 }
474 }
475
476exit:
477 mbedtls_mpi_mod_modulus_free( &m );
478
479 #undef BMAX
480 #undef XMAX
481}
482/* END_CASE */
483
484/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100485void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000486{
487 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000488 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000489 size_t len;
490
491 mbedtls_mpi_init( &X );
492
493
494 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200495 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100496 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100497 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000498
499exit:
500 mbedtls_mpi_free( &X );
501}
502/* END_CASE */
503
504/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100505void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
506 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000507{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200508 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000509 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000510 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000511
512 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000513
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200514 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000515
Werner Lewis19b4cd82022-07-07 11:02:27 +0100516 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100517
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200519 if( buflen > (size_t) output_size )
520 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000521
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200522 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200523 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000524 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000525
Ronald Cron2dbba992020-06-10 11:42:32 +0200526 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
527 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000528 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000529
Paul Bakkerbd51b262014-07-10 15:26:12 +0200530exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200531 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000532}
Paul Bakker33b43f12013-08-20 11:48:36 +0200533/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000534
Janos Follathe344d0f2019-02-19 16:17:40 +0000535/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100536void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
537 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000538{
539 mbedtls_mpi X;
540 unsigned char buf[1000];
541 size_t buflen;
542
543 memset( buf, 0x00, 1000 );
544
545 mbedtls_mpi_init( &X );
546
Werner Lewis19b4cd82022-07-07 11:02:27 +0100547 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000548
549 buflen = mbedtls_mpi_size( &X );
550 if( buflen > (size_t) output_size )
551 buflen = (size_t) output_size;
552
553 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
554 if( result == 0)
555 {
556
Ronald Cron2dbba992020-06-10 11:42:32 +0200557 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
558 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000559 }
560
561exit:
562 mbedtls_mpi_free( &X );
563}
564/* END_CASE */
565
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100567void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000568{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000570 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000571 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000572 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000573 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000574
575 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000578
Paul Bakker33b43f12013-08-20 11:48:36 +0200579 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200580 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100581 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000582 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000583 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000584
Paul Bakker33b43f12013-08-20 11:48:36 +0200585 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000586 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200587 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588 buflen = mbedtls_mpi_size( &X );
589 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000590
Paul Bakkere896fea2009-07-06 06:40:23 +0000591
Ronald Cron2dbba992020-06-10 11:42:32 +0200592 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
593 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000594 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000595
Paul Bakkerbd51b262014-07-10 15:26:12 +0200596exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200597 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000598}
Paul Bakker33b43f12013-08-20 11:48:36 +0200599/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000600
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200601/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100602void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000603{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200604 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000605 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200606 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000607
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000609
Werner Lewis19b4cd82022-07-07 11:02:27 +0100610 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000611
Paul Bakker33b43f12013-08-20 11:48:36 +0200612 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000613 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100614 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000615 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200616 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000617
Paul Bakker33b43f12013-08-20 11:48:36 +0200618 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000619 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100620 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000621 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200622 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000623
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000625
Paul Bakkerbd51b262014-07-10 15:26:12 +0200626exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000628}
Paul Bakker33b43f12013-08-20 11:48:36 +0200629/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000630
Paul Bakker33b43f12013-08-20 11:48:36 +0200631/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100632void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000633{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200634 mbedtls_mpi X;
635 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100636 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200637 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000638
Paul Bakkerbd51b262014-07-10 15:26:12 +0200639exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200640 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000641}
Paul Bakker33b43f12013-08-20 11:48:36 +0200642/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000643
Paul Bakker33b43f12013-08-20 11:48:36 +0200644/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100645void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
646 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000647{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200648 mbedtls_mpi X, Y;
649 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000650
Werner Lewis19b4cd82022-07-07 11:02:27 +0100651 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
652 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100653 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
654
655 if( result == 0 )
656 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200657 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100658 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
659 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000660
Paul Bakkerbd51b262014-07-10 15:26:12 +0200661exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200662 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000663}
Paul Bakker33b43f12013-08-20 11:48:36 +0200664/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000665
Paul Bakker33b43f12013-08-20 11:48:36 +0200666/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100667void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000668{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200669 mbedtls_mpi X;
670 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000671
Werner Lewis19b4cd82022-07-07 11:02:27 +0100672 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200673 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000674
Paul Bakkerbd51b262014-07-10 15:26:12 +0200675exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200676 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000677}
Paul Bakker33b43f12013-08-20 11:48:36 +0200678/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000679
Paul Bakker33b43f12013-08-20 11:48:36 +0200680/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100681void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000682{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200683 mbedtls_mpi X;
684 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000685
Werner Lewis19b4cd82022-07-07 11:02:27 +0100686 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200687 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000688
Paul Bakkerbd51b262014-07-10 15:26:12 +0200689exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000691}
Paul Bakker33b43f12013-08-20 11:48:36 +0200692/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000693
Paul Bakker33b43f12013-08-20 11:48:36 +0200694/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100695void mbedtls_mpi_gcd( char * input_X, char * input_Y,
696 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000697{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200698 mbedtls_mpi A, X, Y, Z;
699 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000700
Werner Lewis19b4cd82022-07-07 11:02:27 +0100701 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
702 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
703 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200705 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200706 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000707
Paul Bakkerbd51b262014-07-10 15:26:12 +0200708exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200709 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000710}
Paul Bakker33b43f12013-08-20 11:48:36 +0200711/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000712
Paul Bakker33b43f12013-08-20 11:48:36 +0200713/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000715{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200716 mbedtls_mpi X;
717 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200719 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
720 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000721
Paul Bakkerbd51b262014-07-10 15:26:12 +0200722exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200723 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000724}
Paul Bakker33b43f12013-08-20 11:48:36 +0200725/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000726
Paul Bakker33b43f12013-08-20 11:48:36 +0200727/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100728void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
729 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000730{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 mbedtls_mpi X, Y;
732 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000733
Werner Lewis19b4cd82022-07-07 11:02:27 +0100734 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
735 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200736 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000737
Paul Bakkerbd51b262014-07-10 15:26:12 +0200738exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200739 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000740}
Paul Bakker33b43f12013-08-20 11:48:36 +0200741/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000742
Paul Bakker33b43f12013-08-20 11:48:36 +0200743/* BEGIN_CASE */
Janos Follath23bdeca2022-07-22 18:24:06 +0100744void mbedtls_mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
745{
746 #define MAX_LEN 64
747 mbedtls_mpi_uint X[MAX_LEN];
748 mbedtls_mpi_uint Y[MAX_LEN];
749 unsigned exp_ret = input_ret;
750 unsigned ret;
751 size_t len = CHARS_TO_LIMBS(
752 input_X->len > input_Y->len ? input_X->len : input_Y->len );
753
754 TEST_ASSERT( len <= MAX_LEN );
755
756 TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
757 == 0 );
758 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
759 == 0 );
760
761 TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
762 TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
763
764 ret = mbedtls_mpi_core_lt_ct( X, Y, len );
765
766 TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
767 TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
768 TEST_CF_PUBLIC( &ret, sizeof( ret ) );
769
770 TEST_ASSERT( ret == exp_ret );
771
772exit:
773 ;
774
775 #undef MAX_LEN
776}
777/* END_CASE */
778
779/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100780void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
781 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100782 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100783{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200784 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100785 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100786 mbedtls_mpi X, Y;
787 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
788
Werner Lewis19b4cd82022-07-07 11:02:27 +0100789 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
790 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100791
Gilles Peskine9018b112020-01-21 16:30:53 +0100792 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
793 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100794
Janos Follath0e5532d2019-10-11 14:21:53 +0100795 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100796 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100797 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100798
799exit:
800 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
801}
802/* END_CASE */
803
804/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100805void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
806 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000807{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200808 mbedtls_mpi X, Y;
809 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000810
Werner Lewis19b4cd82022-07-07 11:02:27 +0100811 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
812 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200813 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000814
Paul Bakkerbd51b262014-07-10 15:26:12 +0200815exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200816 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000817}
Paul Bakker33b43f12013-08-20 11:48:36 +0200818/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000819
Paul Bakker33b43f12013-08-20 11:48:36 +0200820/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200821void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000822{
Gilles Peskined0722f82021-06-10 23:00:33 +0200823 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200824 mbedtls_mpi_init( &src );
825 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200826 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000827
Werner Lewis19b4cd82022-07-07 11:02:27 +0100828 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
829 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200830
831 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100832 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200833 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200834 TEST_ASSERT( sign_is_valid( &dst ) );
835 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000836
Gilles Peskined0722f82021-06-10 23:00:33 +0200837 /* mbedtls_mpi_safe_cond_assign(), assignment done */
838 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100839 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200840 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
841 TEST_ASSERT( sign_is_valid( &dst ) );
842 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
843
844 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
845 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100846 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200847 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
848 TEST_ASSERT( sign_is_valid( &dst ) );
849 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
850
Paul Bakkerbd51b262014-07-10 15:26:12 +0200851exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200852 mbedtls_mpi_free( &src );
853 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200854 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100855}
856/* END_CASE */
857
858/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200859void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100860{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200861 mbedtls_mpi X, A;
862 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200863 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000864
Werner Lewis19b4cd82022-07-07 11:02:27 +0100865 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200866 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200867
Werner Lewis19b4cd82022-07-07 11:02:27 +0100868 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200869 TEST_ASSERT( sign_is_valid( &X ) );
870 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000871
Paul Bakkerbd51b262014-07-10 15:26:12 +0200872exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200873 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200874 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000875}
Paul Bakker33b43f12013-08-20 11:48:36 +0200876/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000877
Paul Bakker33b43f12013-08-20 11:48:36 +0200878/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200879void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
880{
881 mbedtls_mpi X, Y, X0, Y0;
882 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
883 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
884
Werner Lewis19b4cd82022-07-07 11:02:27 +0100885 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
886 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200887
Gilles Peskined0722f82021-06-10 23:00:33 +0200888 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100889 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
890 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200891 mbedtls_mpi_swap( &X, &Y );
892 TEST_ASSERT( sign_is_valid( &X ) );
893 TEST_ASSERT( sign_is_valid( &Y ) );
894 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
895 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
896
Gilles Peskined0722f82021-06-10 23:00:33 +0200897 /* mbedtls_mpi_safe_cond_swap(), swap done */
898 mbedtls_mpi_free( &X );
899 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100900 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
901 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200902 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
903 TEST_ASSERT( sign_is_valid( &X ) );
904 TEST_ASSERT( sign_is_valid( &Y ) );
905 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
906 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
907
908 /* mbedtls_mpi_safe_cond_swap(), swap not done */
909 mbedtls_mpi_free( &X );
910 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100911 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
912 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200913 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
914 TEST_ASSERT( sign_is_valid( &X ) );
915 TEST_ASSERT( sign_is_valid( &Y ) );
916 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
917 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
918
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200919exit:
920 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
921 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
922}
923/* END_CASE */
924
925/* BEGIN_CASE */
926void mpi_swap_self( char *X_hex )
927{
928 mbedtls_mpi X, X0;
929 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
930
Werner Lewis19b4cd82022-07-07 11:02:27 +0100931 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
932 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200933
934 mbedtls_mpi_swap( &X, &X );
935 TEST_ASSERT( sign_is_valid( &X ) );
936 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
937
938exit:
939 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
940}
941/* END_CASE */
942
943/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200944void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100945{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200946 mbedtls_mpi X;
947 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100948
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200950 if( used > 0 )
951 {
952 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
953 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
954 }
955 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200956 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200957 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100958
Paul Bakkerbd51b262014-07-10 15:26:12 +0200959exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200960 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100961}
962/* END_CASE */
963
964/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100965void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
966 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000967{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200968 mbedtls_mpi X, Y, Z, A;
969 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000970
Werner Lewis19b4cd82022-07-07 11:02:27 +0100971 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
972 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
973 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200974 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200975 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200976 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000977
Gilles Peskine56f943a2020-07-23 01:18:11 +0200978 /* result == first operand */
979 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200980 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200981 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100982 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200983
984 /* result == second operand */
985 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200986 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200987 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
988
Paul Bakkerbd51b262014-07-10 15:26:12 +0200989exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200990 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000991}
Paul Bakker33b43f12013-08-20 11:48:36 +0200992/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000993
Paul Bakker33b43f12013-08-20 11:48:36 +0200994/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100995void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100996{
997 mbedtls_mpi X, A;
998 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
999
Werner Lewis19b4cd82022-07-07 11:02:27 +01001000 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001001
Werner Lewis19b4cd82022-07-07 11:02:27 +01001002 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001003 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
1004 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001005 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001006
Werner Lewis19b4cd82022-07-07 11:02:27 +01001007 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001008 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001009 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001010 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1011
Werner Lewis19b4cd82022-07-07 11:02:27 +01001012 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +01001013 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001014 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +01001015 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1016
1017exit:
1018 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1019}
1020/* END_CASE */
1021
1022
1023/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001024void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
1025 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001026{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 mbedtls_mpi X, Y, Z, A;
1028 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001029
Werner Lewis19b4cd82022-07-07 11:02:27 +01001030 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1031 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1032 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001033 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001034 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001035 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001036
Gilles Peskine56f943a2020-07-23 01:18:11 +02001037 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001039 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001040 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001041 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001042
1043 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001044 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001045 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001046 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001047
Paul Bakkerbd51b262014-07-10 15:26:12 +02001048exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001049 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001050}
Paul Bakker33b43f12013-08-20 11:48:36 +02001051/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001052
Paul Bakker33b43f12013-08-20 11:48:36 +02001053/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001054void mbedtls_mpi_add_int( char * input_X, int input_Y,
1055 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001056{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001057 mbedtls_mpi X, Z, A;
1058 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001059
Werner Lewis19b4cd82022-07-07 11:02:27 +01001060 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1061 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001062 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001063 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001064 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001065
Paul Bakkerbd51b262014-07-10 15:26:12 +02001066exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001067 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001068}
Paul Bakker33b43f12013-08-20 11:48:36 +02001069/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001070
Paul Bakker33b43f12013-08-20 11:48:36 +02001071/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001072void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
1073 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001074{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001075 mbedtls_mpi X, Y, Z, A;
1076 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001077
Werner Lewis19b4cd82022-07-07 11:02:27 +01001078 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1079 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1080 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001081 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001082 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001084
Gilles Peskine56f943a2020-07-23 01:18:11 +02001085 /* result == first operand */
1086 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001087 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001088 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001089 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001090
1091 /* result == second operand */
1092 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001093 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001094 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1095
Paul Bakkerbd51b262014-07-10 15:26:12 +02001096exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001097 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001098}
Paul Bakker33b43f12013-08-20 11:48:36 +02001099/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001100
Paul Bakker33b43f12013-08-20 11:48:36 +02001101/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001102void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
1103 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001104{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001105 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001106 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001107 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001108
Werner Lewis19b4cd82022-07-07 11:02:27 +01001109 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1110 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1111 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001113 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001114 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001115 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001116 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001117 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001118
Gilles Peskine56f943a2020-07-23 01:18:11 +02001119 /* result == first operand */
1120 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001121 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001122 if( sub_result == 0 )
1123 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001124 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001125
1126 /* result == second operand */
1127 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001128 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001129 if( sub_result == 0 )
1130 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1131
Paul Bakkerbd51b262014-07-10 15:26:12 +02001132exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001133 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001134}
Paul Bakker33b43f12013-08-20 11:48:36 +02001135/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001136
Paul Bakker33b43f12013-08-20 11:48:36 +02001137/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001138void mbedtls_mpi_sub_int( char * input_X, int input_Y,
1139 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001140{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001141 mbedtls_mpi X, Z, A;
1142 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001143
Werner Lewis19b4cd82022-07-07 11:02:27 +01001144 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1145 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001146 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001147 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001148 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001149
Paul Bakkerbd51b262014-07-10 15:26:12 +02001150exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001151 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001152}
Paul Bakker33b43f12013-08-20 11:48:36 +02001153/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001154
Paul Bakker33b43f12013-08-20 11:48:36 +02001155/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001156void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
1157 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159 mbedtls_mpi X, Y, Z, A;
1160 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001161
Werner Lewis19b4cd82022-07-07 11:02:27 +01001162 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1163 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1164 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001166 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001168
Paul Bakkerbd51b262014-07-10 15:26:12 +02001169exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001170 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001171}
Paul Bakker33b43f12013-08-20 11:48:36 +02001172/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001173
Paul Bakker33b43f12013-08-20 11:48:36 +02001174/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001175void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001176 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001177{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001178 mbedtls_mpi X, Z, A;
1179 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001180
Werner Lewis19b4cd82022-07-07 11:02:27 +01001181 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1182 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001184 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001185 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001186 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001187 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001188 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001189 else
1190 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001191
Paul Bakkerbd51b262014-07-10 15:26:12 +02001192exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001193 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001194}
Paul Bakker33b43f12013-08-20 11:48:36 +02001195/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001196
Paul Bakker33b43f12013-08-20 11:48:36 +02001197/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001198void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1199 char * input_A, char * input_B,
1200 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001201{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001202 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001203 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001204 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1205 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001206
Werner Lewis19b4cd82022-07-07 11:02:27 +01001207 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1208 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1209 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1210 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001211 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001212 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001213 if( res == 0 )
1214 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001215 TEST_ASSERT( sign_is_valid( &Q ) );
1216 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001217 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1218 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001219 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001220
Paul Bakkerbd51b262014-07-10 15:26:12 +02001221exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001222 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1223 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001224}
Paul Bakker33b43f12013-08-20 11:48:36 +02001225/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001226
Paul Bakker33b43f12013-08-20 11:48:36 +02001227/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001228void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001229 char * input_A, char * input_B,
1230 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001231{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001232 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001233 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001234 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1235 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001236
Werner Lewis19b4cd82022-07-07 11:02:27 +01001237 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1238 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1239 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001240 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001241 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001242 if( res == 0 )
1243 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001244 TEST_ASSERT( sign_is_valid( &Q ) );
1245 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001246 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1247 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001248 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001249
Paul Bakkerbd51b262014-07-10 15:26:12 +02001250exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1252 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001253}
Paul Bakker33b43f12013-08-20 11:48:36 +02001254/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001255
Paul Bakker33b43f12013-08-20 11:48:36 +02001256/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001257void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1258 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001259{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001260 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001261 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001262 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001263
Werner Lewis19b4cd82022-07-07 11:02:27 +01001264 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1265 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1266 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001268 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001269 if( res == 0 )
1270 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001271 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001272 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001273 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001274
Paul Bakkerbd51b262014-07-10 15:26:12 +02001275exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001276 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001277}
Paul Bakker33b43f12013-08-20 11:48:36 +02001278/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001279
Paul Bakker33b43f12013-08-20 11:48:36 +02001280/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001281void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001282 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001283{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001284 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001285 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001286 mbedtls_mpi_uint r;
1287 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001288
Werner Lewis19b4cd82022-07-07 11:02:27 +01001289 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001291 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001292 if( res == 0 )
1293 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001294 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001295 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001296
Paul Bakkerbd51b262014-07-10 15:26:12 +02001297exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001298 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001299}
Paul Bakker33b43f12013-08-20 11:48:36 +02001300/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001301
Paul Bakker33b43f12013-08-20 11:48:36 +02001302/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001303void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1304 char * input_N, char * input_X,
1305 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001306{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001307 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001308 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001309 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1310 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001311
Werner Lewis19b4cd82022-07-07 11:02:27 +01001312 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1313 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1314 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1315 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001316
Gilles Peskine342f71b2021-06-09 18:31:35 +02001317 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001318 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001319 if( res == 0 )
1320 {
1321 TEST_ASSERT( sign_is_valid( &Z ) );
1322 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1323 }
1324
1325 /* Now test again with the speed-up parameter supplied as an output. */
1326 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001327 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001328 if( res == 0 )
1329 {
1330 TEST_ASSERT( sign_is_valid( &Z ) );
1331 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1332 }
1333
1334 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001335 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001336 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001337 if( res == 0 )
1338 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001339 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001340 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001341 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001342
Paul Bakkerbd51b262014-07-10 15:26:12 +02001343exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001344 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1345 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001346}
Paul Bakker33b43f12013-08-20 11:48:36 +02001347/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001348
Paul Bakker33b43f12013-08-20 11:48:36 +02001349/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001350void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001351 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001352{
1353 mbedtls_mpi A, E, N, RR, Z;
1354 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1355 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1356
Chris Jonesaa850cd2020-12-03 11:35:41 +00001357 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001358 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001359 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001360 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001361
1362 /* Set E to 2^(E_bytes - 1) + 1 */
1363 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1364 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001365 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001366
1367 /* Set N to 2^(N_bytes - 1) + 1 */
1368 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1369 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001370 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1371
1372 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001373 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001374
Chris Jonesaa850cd2020-12-03 11:35:41 +00001375 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001376
1377exit:
1378 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1379 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1380}
1381/* END_CASE */
1382
1383/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001384void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1385 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001386{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001387 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001388 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001389 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001390
Werner Lewis19b4cd82022-07-07 11:02:27 +01001391 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1392 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1393 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001394 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001395 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001396 if( res == 0 )
1397 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001398 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001400 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001401
Paul Bakkerbd51b262014-07-10 15:26:12 +02001402exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001403 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001404}
Paul Bakker33b43f12013-08-20 11:48:36 +02001405/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001406
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001408void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001409{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001410 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001411 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001412 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001413
Werner Lewis19b4cd82022-07-07 11:02:27 +01001414 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001415 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001416 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001417
Paul Bakkerbd51b262014-07-10 15:26:12 +02001418exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001420}
Paul Bakker33b43f12013-08-20 11:48:36 +02001421/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001423/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001424void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001425 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001426{
1427 mbedtls_mpi X;
1428 int res;
1429 mbedtls_test_mpi_random rand;
1430
1431 mbedtls_mpi_init( &X );
1432 rand.data = witnesses;
1433 rand.pos = 0;
1434 rand.chunk_len = chunk_len;
1435
1436 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001437 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1438 mbedtls_test_mpi_miller_rabin_determinizer,
1439 &rand );
1440 TEST_ASSERT( res == 0 );
1441
1442 rand.data = witnesses;
1443 rand.pos = 0;
1444 rand.chunk_len = chunk_len;
1445
Janos Follatha0b67c22018-09-18 14:48:23 +01001446 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1447 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001448 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001449 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001450
1451exit:
1452 mbedtls_mpi_free( &X );
1453}
1454/* END_CASE */
1455
1456/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001457void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001458{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001459 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001460 int my_ret;
1461
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001462 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001463
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001464 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1465 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001466 TEST_ASSERT( my_ret == ref_ret );
1467
1468 if( ref_ret == 0 )
1469 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001470 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001471
1472 TEST_ASSERT( actual_bits >= (size_t) bits );
1473 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001474 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001475
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001476 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1477 mbedtls_test_rnd_std_rand,
1478 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001479 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001480 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001481 /* X = ( X - 1 ) / 2 */
1482 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001483 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1484 mbedtls_test_rnd_std_rand,
1485 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001486 }
1487 }
1488
Paul Bakkerbd51b262014-07-10 15:26:12 +02001489exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001491}
1492/* END_CASE */
1493
Paul Bakker33b43f12013-08-20 11:48:36 +02001494/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001495void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1496 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001497{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001498 mbedtls_mpi X, A;
1499 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001500
Werner Lewis19b4cd82022-07-07 11:02:27 +01001501 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1502 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001503 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001504 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001506
Paul Bakkerbd51b262014-07-10 15:26:12 +02001507exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001508 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001509}
Paul Bakker33b43f12013-08-20 11:48:36 +02001510/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001511
Paul Bakker33b43f12013-08-20 11:48:36 +02001512/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001513void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1514 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001515{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001516 mbedtls_mpi X, A;
1517 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001518
Werner Lewis19b4cd82022-07-07 11:02:27 +01001519 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1520 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001521 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001522 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001523 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001524
Paul Bakkerbd51b262014-07-10 15:26:12 +02001525exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001526 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001527}
Paul Bakker33b43f12013-08-20 11:48:36 +02001528/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001529
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001530/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001531void mpi_fill_random( int wanted_bytes, int rng_bytes,
1532 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001533{
1534 mbedtls_mpi X;
1535 int ret;
1536 size_t bytes_left = rng_bytes;
1537 mbedtls_mpi_init( &X );
1538
Gilles Peskine422e8672021-04-02 00:02:27 +02001539 if( before != 0 )
1540 {
1541 /* Set X to sign(before) * 2^(|before|-1) */
1542 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1543 if( before < 0 )
1544 before = - before;
1545 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1546 }
1547
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001548 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1549 f_rng_bytes_left, &bytes_left );
1550 TEST_ASSERT( ret == expected_ret );
1551
1552 if( expected_ret == 0 )
1553 {
1554 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1555 * as a big-endian representation of the number. We know when
1556 * our RNG function returns null bytes, so we know how many
1557 * leading zero bytes the number has. */
1558 size_t leading_zeros = 0;
1559 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1560 leading_zeros = 1;
1561 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1562 (size_t) wanted_bytes );
1563 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001564 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001565 }
1566
1567exit:
1568 mbedtls_mpi_free( &X );
1569}
1570/* END_CASE */
1571
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001572/* BEGIN_CASE */
1573void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1574{
1575 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1576 * This function assumes that the value of bound is at least 2 and
1577 * that iterations is large enough that a one-in-2^iterations chance
1578 * effectively never occurs.
1579 */
1580
1581 mbedtls_mpi upper_bound;
1582 size_t n_bits;
1583 mbedtls_mpi result;
1584 size_t b;
1585 /* If upper_bound is small, stats[b] is the number of times the value b
1586 * has been generated. Otherwise stats[b] is the number of times a
1587 * value with bit b set has been generated. */
1588 size_t *stats = NULL;
1589 size_t stats_len;
1590 int full_stats;
1591 size_t i;
1592
1593 mbedtls_mpi_init( &upper_bound );
1594 mbedtls_mpi_init( &result );
1595
1596 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1597 bound_bytes->x, bound_bytes->len ) );
1598 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1599 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1600 * to be small enough that the probability of missing one value is
1601 * negligible given the number of iterations. It must be less than
1602 * 256 because some of the code below assumes that "small" values
1603 * fit in a byte. */
1604 if( n_bits <= 5 )
1605 {
1606 full_stats = 1;
1607 stats_len = bound_bytes->x[bound_bytes->len - 1];
1608 }
1609 else
1610 {
1611 full_stats = 0;
1612 stats_len = n_bits;
1613 }
1614 ASSERT_ALLOC( stats, stats_len );
1615
1616 for( i = 0; i < (size_t) iterations; i++ )
1617 {
1618 mbedtls_test_set_step( i );
1619 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1620 mbedtls_test_rnd_std_rand, NULL ) );
1621
Gilles Peskinedffc7102021-06-10 15:34:15 +02001622 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001623 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1624 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1625 if( full_stats )
1626 {
1627 uint8_t value;
1628 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1629 TEST_ASSERT( value < stats_len );
1630 ++stats[value];
1631 }
1632 else
1633 {
1634 for( b = 0; b < n_bits; b++ )
1635 stats[b] += mbedtls_mpi_get_bit( &result, b );
1636 }
1637 }
1638
1639 if( full_stats )
1640 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001641 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001642 {
1643 mbedtls_test_set_step( 1000000 + b );
1644 /* Assert that each value has been reached at least once.
1645 * This is almost guaranteed if the iteration count is large
1646 * enough. This is a very crude way of checking the distribution.
1647 */
1648 TEST_ASSERT( stats[b] > 0 );
1649 }
1650 }
1651 else
1652 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001653 int statistically_safe_all_the_way =
1654 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001655 for( b = 0; b < n_bits; b++ )
1656 {
1657 mbedtls_test_set_step( 1000000 + b );
1658 /* Assert that each bit has been set in at least one result and
1659 * clear in at least one result. Provided that iterations is not
1660 * too small, it would be extremely unlikely for this not to be
1661 * the case if the results are uniformly distributed.
1662 *
1663 * As an exception, the top bit may legitimately never be set
1664 * if bound is a power of 2 or only slightly above.
1665 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001666 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001667 {
1668 TEST_ASSERT( stats[b] > 0 );
1669 }
1670 TEST_ASSERT( stats[b] < (size_t) iterations );
1671 }
1672 }
1673
1674exit:
1675 mbedtls_mpi_free( &upper_bound );
1676 mbedtls_mpi_free( &result );
1677 mbedtls_free( stats );
1678}
1679/* END_CASE */
1680
Gilles Peskine1e918f42021-03-29 22:14:51 +02001681/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001682void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001683{
1684 mbedtls_mpi upper_bound;
1685 mbedtls_mpi result;
1686
1687 mbedtls_mpi_init( &upper_bound );
1688 mbedtls_mpi_init( &result );
1689
Gilles Peskine422e8672021-04-02 00:02:27 +02001690 if( before != 0 )
1691 {
1692 /* Set result to sign(before) * 2^(|before|-1) */
1693 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1694 if( before < 0 )
1695 before = - before;
1696 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1697 }
1698
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001699 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1700 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1701 bound_bytes->x, bound_bytes->len ) );
1702 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1703 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001704 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001705 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1706 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1707
1708exit:
1709 mbedtls_mpi_free( &upper_bound );
1710 mbedtls_mpi_free( &result );
1711}
1712/* END_CASE */
1713
1714/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001715void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1716{
1717 mbedtls_mpi upper_bound;
1718 mbedtls_mpi result;
1719 int actual_ret;
1720
1721 mbedtls_mpi_init( &upper_bound );
1722 mbedtls_mpi_init( &result );
1723
1724 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1725 bound_bytes->x, bound_bytes->len ) );
1726 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1727 mbedtls_test_rnd_std_rand, NULL );
1728 TEST_EQUAL( expected_ret, actual_ret );
1729
1730exit:
1731 mbedtls_mpi_free( &upper_bound );
1732 mbedtls_mpi_free( &result );
1733}
1734/* END_CASE */
1735
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001736/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001737void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001738{
Andres AG93012e82016-09-09 09:10:28 +01001739 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001740}
Paul Bakker33b43f12013-08-20 11:48:36 +02001741/* END_CASE */