blob: 8c40b229a9c9078297b89a0752f8cb3f60c3988f [file] [log] [blame]
Paul Bakker33b43f12013-08-20 11:48:36 +02001/* BEGIN_HEADER */
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +00002#include "mbedtls/bignum.h"
Gilles Peskine3cb1e292020-11-25 15:37:20 +01003#include "mbedtls/entropy.h"
Janos Follathf1d617d2022-07-21 09:29:32 +01004#include "bignum_core.h"
Gabor Mezei23a1ce92022-08-02 11:54:44 +02005#include "bignum_mod.h"
6#include "bignum_mod_raw.h"
Janos Follath23bdeca2022-07-22 18:24:06 +01007#include "constant_time_internal.h"
8#include "test/constant_flow.h"
Janos Follath64eca052018-09-05 17:04:49 +01009
Chris Jonese64a46f2020-12-03 17:44:03 +000010#if MBEDTLS_MPI_MAX_BITS > 792
11#define MPI_MAX_BITS_LARGER_THAN_792
Chris Jones4592bd82020-12-03 14:24:33 +000012#endif
Gabor Mezei89e31462022-08-12 15:36:56 +020013
Gilles Peskinedffc7102021-06-10 15:34:15 +020014/* Check the validity of the sign bit in an MPI object. Reject representations
15 * that are not supported by the rest of the library and indicate a bug when
16 * constructing the value. */
17static int sign_is_valid( const mbedtls_mpi *X )
18{
19 if( X->s != 1 && X->s != -1 )
20 return( 0 ); // invalid sign bit, e.g. 0
21 if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
22 return( 0 ); // negative zero
23 return( 1 );
24}
25
Janos Follath64eca052018-09-05 17:04:49 +010026typedef struct mbedtls_test_mpi_random
27{
28 data_t *data;
29 size_t pos;
30 size_t chunk_len;
31} mbedtls_test_mpi_random;
32
33/*
34 * This function is called by the Miller-Rabin primality test each time it
35 * chooses a random witness. The witnesses (or non-witnesses as provided by the
36 * test) are stored in the data member of the state structure. Each number is in
37 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
38 */
39int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
40 unsigned char* buf,
41 size_t len )
42{
43 mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
44
45 if( random == NULL || random->data->x == NULL || buf == NULL )
46 return( -1 );
47
48 if( random->pos + random->chunk_len > random->data->len
49 || random->chunk_len > len )
50 {
51 return( -1 );
52 }
53
54 memset( buf, 0, len );
55
56 /* The witness is written to the end of the buffer, since the buffer is
57 * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
58 * Writing the witness to the start of the buffer would result in the
59 * buffer being 'witness 000...000', which would be treated as
60 * witness * 2^n for some n. */
61 memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
62 random->chunk_len );
63
64 random->pos += random->chunk_len;
65
66 return( 0 );
67}
Gilles Peskine3cb1e292020-11-25 15:37:20 +010068
69/* Random generator that is told how many bytes to return. */
70static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
71{
72 size_t *bytes_left = state;
73 size_t i;
74 for( i = 0; i < len; i++ )
75 {
76 if( *bytes_left == 0 )
77 return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
78 buf[i] = *bytes_left & 0xff;
79 --( *bytes_left );
80 }
81 return( 0 );
82}
83
Gilles Peskineeedefa52021-04-13 19:50:04 +020084/* Test whether bytes represents (in big-endian base 256) a number b that
85 * is significantly above a power of 2. That is, b must not have a long run
86 * of unset bits after the most significant bit.
87 *
88 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
89 * This function returns 1 if, when drawing a number between 0 and b,
90 * the probability that this number is at least 2^n is not negligible.
91 * This probability is (b - 2^n) / b and this function checks that this
92 * number is above some threshold A. The threshold value is heuristic and
93 * based on the needs of mpi_random_many().
Gilles Peskine02ac93a2021-03-29 22:02:55 +020094 */
95static int is_significantly_above_a_power_of_2( data_t *bytes )
96{
97 const uint8_t *p = bytes->x;
98 size_t len = bytes->len;
99 unsigned x;
Gilles Peskineeedefa52021-04-13 19:50:04 +0200100
101 /* Skip leading null bytes */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200102 while( len > 0 && p[0] == 0 )
103 {
104 ++p;
105 --len;
106 }
Gilles Peskineeedefa52021-04-13 19:50:04 +0200107 /* 0 is not significantly above a power of 2 */
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200108 if( len == 0 )
109 return( 0 );
Gilles Peskineeedefa52021-04-13 19:50:04 +0200110 /* Extract the (up to) 2 most significant bytes */
111 if( len == 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200112 x = p[0];
113 else
114 x = ( p[0] << 8 ) | p[1];
115
Gilles Peskineeedefa52021-04-13 19:50:04 +0200116 /* Shift the most significant bit of x to position 8 and mask it out */
117 while( ( x & 0xfe00 ) != 0 )
118 x >>= 1;
119 x &= 0x00ff;
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200120
Gilles Peskineeedefa52021-04-13 19:50:04 +0200121 /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
122 * a power of 2 iff x is significantly above 0 compared to 2^8.
123 * Testing x >= 2^4 amounts to picking A = 1/16 in the function
124 * description above. */
125 return( x >= 0x10 );
Gilles Peskine02ac93a2021-03-29 22:02:55 +0200126}
127
Paul Bakker33b43f12013-08-20 11:48:36 +0200128/* END_HEADER */
Paul Bakker367dae42009-06-28 21:50:27 +0000129
Paul Bakker33b43f12013-08-20 11:48:36 +0200130/* BEGIN_DEPENDENCIES
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200131 * depends_on:MBEDTLS_BIGNUM_C
Paul Bakker33b43f12013-08-20 11:48:36 +0200132 * END_DEPENDENCIES
133 */
Paul Bakker5690efc2011-05-26 13:16:06 +0000134
Hanno Beckerb48e1aa2018-12-18 23:25:01 +0000135/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100136void mpi_null( )
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200137{
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200138 mbedtls_mpi X, Y, Z;
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200139
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200140 mbedtls_mpi_init( &X );
141 mbedtls_mpi_init( &Y );
142 mbedtls_mpi_init( &Z );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200143
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200144 TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
145 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200146 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200147 TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200148
149exit:
Manuel Pégourié-Gonnardda61ed32015-04-30 10:28:51 +0200150 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200151}
152/* END_CASE */
153
154/* BEGIN_CASE */
Azim Khanf1aaec92017-05-30 14:23:15 +0100155void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
156 char * input_A, int output_size, int result_read,
Paul Bakker33b43f12013-08-20 11:48:36 +0200157 int result_write )
Paul Bakker367dae42009-06-28 21:50:27 +0000158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200159 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +0000160 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100161 size_t len;
Paul Bakker367dae42009-06-28 21:50:27 +0000162
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200163 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000164
Janos Follath04dadb72019-03-06 12:29:37 +0000165 memset( str, '!', sizeof( str ) );
166
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200167 TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
Paul Bakker33b43f12013-08-20 11:48:36 +0200168 if( result_read == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000169 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200170 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100171 TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
Paul Bakker33b43f12013-08-20 11:48:36 +0200172 if( result_write == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000173 {
Paul Bakker33b43f12013-08-20 11:48:36 +0200174 TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
Janos Follath04dadb72019-03-06 12:29:37 +0000175 TEST_ASSERT( str[len] == '!' );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000176 }
177 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000178
Paul Bakkerbd51b262014-07-10 15:26:12 +0200179exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200180 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000181}
Paul Bakker33b43f12013-08-20 11:48:36 +0200182/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000183
Paul Bakker33b43f12013-08-20 11:48:36 +0200184/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100185void mbedtls_mpi_read_binary( data_t * buf, char * input_A )
Paul Bakkere896fea2009-07-06 06:40:23 +0000186{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200187 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000188 char str[1000];
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100189 size_t len;
Paul Bakkere896fea2009-07-06 06:40:23 +0000190
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200191 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000192
Paul Bakkere896fea2009-07-06 06:40:23 +0000193
Azim Khand30ca132017-06-09 04:32:58 +0100194 TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200195 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100196 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100197 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000198
Paul Bakkerbd51b262014-07-10 15:26:12 +0200199exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200200 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000201}
Paul Bakker33b43f12013-08-20 11:48:36 +0200202/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000203
Paul Bakker33b43f12013-08-20 11:48:36 +0200204/* BEGIN_CASE */
Janos Follath91dc67d2022-07-22 14:24:58 +0100205void mbedtls_mpi_core_io_null()
206{
207 mbedtls_mpi_uint X = 0;
208 int ret;
209
210 ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100211 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100212 ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100213 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100214
215 ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100216 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100217 ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100218 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100219
220 ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100221 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100222 ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100223 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100224
225 ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100226 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100227 ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
Janos Follath494a6d22022-08-22 09:36:17 +0100228 TEST_EQUAL( ret, 0 );
Janos Follath91dc67d2022-07-22 14:24:58 +0100229
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{
Janos Follathf1d617d2022-07-21 09:29:32 +0100239 if( iret != 0 )
240 TEST_ASSERT( oret == 0 );
241
242 TEST_ASSERT( 0 <= nb_int );
Janos Follath81620642022-08-15 11:13:38 +0100243 size_t nb = nb_int;
Janos Follathf1d617d2022-07-21 09:29:32 +0100244
Janos Follath81620642022-08-15 11:13:38 +0100245 unsigned char buf[1024];
246 TEST_ASSERT( nb <= sizeof( buf ) );
247
Janos Follath1cb3b972022-08-11 10:50:04 +0100248 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
249 * to halve the number of limbs to have the same size. */
250 if( sizeof( mbedtls_mpi_uint ) == 8 )
Janos Follath81620642022-08-15 11:13:38 +0100251 nx_32_int = nx_32_int / 2 + nx_32_int % 2;
252 TEST_ASSERT( 0 <= nx_32_int );
253 size_t nx = nx_32_int;
Janos Follathf1d617d2022-07-21 09:29:32 +0100254
Janos Follath81620642022-08-15 11:13:38 +0100255 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
256 TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
257
258 int ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100259 TEST_EQUAL( ret, iret );
Janos Follathf1d617d2022-07-21 09:29:32 +0100260
261 if( iret == 0 )
262 {
263 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100264 TEST_EQUAL( ret, oret );
Janos Follathf1d617d2022-07-21 09:29:32 +0100265 }
266
267 if( ( iret == 0 ) && ( oret == 0 ) )
268 {
269 if( nb > input->len )
270 {
271 size_t leading_zeroes = nb - input->len;
272 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
273 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100274 TEST_EQUAL( buf[i], 0 );
Janos Follathf1d617d2022-07-21 09:29:32 +0100275 }
276 else
277 {
278 size_t leading_zeroes = input->len - nb;
279 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
280 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100281 TEST_EQUAL( input->x[i], 0 );
Janos Follathf1d617d2022-07-21 09:29:32 +0100282 }
283 }
284
285exit:
286 ;
Janos Follathf1d617d2022-07-21 09:29:32 +0100287}
288/* END_CASE */
289
290/* BEGIN_CASE */
Janos Follath9dfb5622022-08-11 12:15:55 +0100291void mbedtls_mpi_core_io_le( data_t *input, int nb_int, int nx_32_int, int iret,
Janos Follath6ff35362022-07-21 15:27:21 +0100292 int oret )
293{
Janos Follath6ff35362022-07-21 15:27:21 +0100294 if( iret != 0 )
295 TEST_ASSERT( oret == 0 );
296
297 TEST_ASSERT( 0 <= nb_int );
Janos Follath81620642022-08-15 11:13:38 +0100298 size_t nb = nb_int;
Janos Follath6ff35362022-07-21 15:27:21 +0100299
Janos Follath81620642022-08-15 11:13:38 +0100300 unsigned char buf[1024];
301 TEST_ASSERT( nb <= sizeof( buf ) );
302
Janos Follath9dfb5622022-08-11 12:15:55 +0100303 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
304 * to halve the number of limbs to have the same size. */
305 if( sizeof( mbedtls_mpi_uint ) == 8 )
Janos Follath81620642022-08-15 11:13:38 +0100306 nx_32_int = nx_32_int / 2 + nx_32_int % 2;
307 TEST_ASSERT( 0 <= nx_32_int );
308 size_t nx = nx_32_int;
Janos Follath6ff35362022-07-21 15:27:21 +0100309
Janos Follath81620642022-08-15 11:13:38 +0100310 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
311 TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
312
313 int ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100314 TEST_EQUAL( ret, iret );
Janos Follath6ff35362022-07-21 15:27:21 +0100315
316 if( iret == 0 )
317 {
318 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100319 TEST_EQUAL( ret, oret );
Janos Follath6ff35362022-07-21 15:27:21 +0100320 }
321
322 if( ( iret == 0 ) && ( oret == 0 ) )
323 {
324 if( nb > input->len )
325 {
326 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
327 for( size_t i = input->len; i < nb; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100328 TEST_EQUAL( buf[i], 0 );
Janos Follath6ff35362022-07-21 15:27:21 +0100329 }
330 else
331 {
332 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
333 for( size_t i = nb; i < input->len; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100334 TEST_EQUAL( input->x[i], 0 );
Janos Follath6ff35362022-07-21 15:27:21 +0100335 }
336 }
337
338exit:
339 ;
Janos Follath6ff35362022-07-21 15:27:21 +0100340}
341/* END_CASE */
342
343/* BEGIN_CASE */
Janos Follath16949692022-08-08 13:37:20 +0100344void mbedtls_mpi_mod_setup( int ext_rep, int int_rep, int iret )
345{
346 #define MLIMBS 8
347 mbedtls_mpi_uint mp[MLIMBS];
348 mbedtls_mpi_mod_modulus m;
349 int ret;
350
351 memset( mp, 0xFF, sizeof(mp) );
352
353 mbedtls_mpi_mod_modulus_init( &m );
354 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
Janos Follath494a6d22022-08-22 09:36:17 +0100355 TEST_EQUAL( ret, iret );
Janos Follath16949692022-08-08 13:37:20 +0100356
357 /* Address sanitiser should catch if we try to free mp */
358 mbedtls_mpi_mod_modulus_free( &m );
359
360 /* Make sure that the modulus doesn't have reference to mp anymore */
361 TEST_ASSERT( m.p != mp );
362
363exit:
364 /* It should be safe to call an mbedtls free several times */
365 mbedtls_mpi_mod_modulus_free( &m );
366
367 #undef MLIMBS
368}
369/* END_CASE */
370
371
372/* BEGIN_CASE */
Gabor Mezei7f081782022-08-12 18:00:33 +0200373void mbedtls_mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int,
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200374 int iendian, int iret, int oret )
375{
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200376 if( iret != 0 )
377 TEST_ASSERT( oret == 0 );
378
379 TEST_ASSERT( 0 <= nb_int );
Janos Follath81620642022-08-15 11:13:38 +0100380 size_t nb = nb_int;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200381
Janos Follath81620642022-08-15 11:13:38 +0100382 unsigned char buf[1024];
383 TEST_ASSERT( nb <= sizeof( buf ) );
384
Gabor Mezei7f081782022-08-12 18:00:33 +0200385 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
386 * to halve the number of limbs to have the same size. */
387 if( sizeof( mbedtls_mpi_uint ) == 8 )
Janos Follath81620642022-08-15 11:13:38 +0100388 nx_32_int = nx_32_int / 2 + nx_32_int % 2;
389 TEST_ASSERT( 0 <= nx_32_int );
390 size_t nx = nx_32_int;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200391
Janos Follath81620642022-08-15 11:13:38 +0100392 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
393 TEST_ASSERT( nx <= sizeof( X ) / sizeof( X[0] ) );
394
395 int endian;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200396 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
397 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
398 else
399 endian = iendian;
400
Janos Follath81620642022-08-15 11:13:38 +0100401 mbedtls_mpi_mod_modulus m;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200402 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath81620642022-08-15 11:13:38 +0100403 mbedtls_mpi_uint init[sizeof( X ) / sizeof( X[0] )];
404 memset( init, 0xFF, sizeof( init ) );
405 int ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
406 MBEDTLS_MPI_MOD_REP_MONTGOMERY );
Janos Follath494a6d22022-08-22 09:36:17 +0100407 TEST_EQUAL( ret, 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200408
409 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
410 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
411
412 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100413 TEST_EQUAL( ret, iret );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200414
415 if( iret == 0 )
416 {
417 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
418 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
419
420 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100421 TEST_EQUAL( ret, oret );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200422 }
423
424 if( ( iret == 0 ) && ( oret == 0 ) )
425 {
426 if( nb > input->len )
427 {
428 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
429 {
430 size_t leading_zeroes = nb - input->len;
431 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
432 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100433 TEST_EQUAL( buf[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200434 }
435 else
436 {
437 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
438 for( size_t i = input->len; i < nb; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100439 TEST_EQUAL( buf[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200440 }
441 }
442 else
443 {
444 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
445 {
446 size_t leading_zeroes = input->len - nb;
447 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
448 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100449 TEST_EQUAL( input->x[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200450 }
451 else
452 {
453 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
454 for( size_t i = nb; i < input->len; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100455 TEST_EQUAL( input->x[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200456 }
457 }
458 }
459
460exit:
461 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200462}
463/* END_CASE */
464
465/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100466void mbedtls_mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000467{
468 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000469 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000470 size_t len;
471
472 mbedtls_mpi_init( &X );
473
474
475 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200476 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100477 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100478 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000479
480exit:
481 mbedtls_mpi_free( &X );
482}
483/* END_CASE */
484
485/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100486void mbedtls_mpi_write_binary( char * input_X, data_t * input_A,
487 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000488{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200489 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000490 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000491 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000492
493 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000496
Werner Lewis19b4cd82022-07-07 11:02:27 +0100497 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200500 if( buflen > (size_t) output_size )
501 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000502
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200503 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200504 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000505 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000506
Ronald Cron2dbba992020-06-10 11:42:32 +0200507 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
508 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000509 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000510
Paul Bakkerbd51b262014-07-10 15:26:12 +0200511exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000513}
Paul Bakker33b43f12013-08-20 11:48:36 +0200514/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000515
Janos Follathe344d0f2019-02-19 16:17:40 +0000516/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100517void mbedtls_mpi_write_binary_le( char * input_X, data_t * input_A,
518 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000519{
520 mbedtls_mpi X;
521 unsigned char buf[1000];
522 size_t buflen;
523
524 memset( buf, 0x00, 1000 );
525
526 mbedtls_mpi_init( &X );
527
Werner Lewis19b4cd82022-07-07 11:02:27 +0100528 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000529
530 buflen = mbedtls_mpi_size( &X );
531 if( buflen > (size_t) output_size )
532 buflen = (size_t) output_size;
533
534 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
535 if( result == 0)
536 {
537
Ronald Cron2dbba992020-06-10 11:42:32 +0200538 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
539 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000540 }
541
542exit:
543 mbedtls_mpi_free( &X );
544}
545/* END_CASE */
546
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200547/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100548void mbedtls_mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000549{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200550 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000551 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000552 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000553 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000554 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000555
556 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000557
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200558 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000559
Paul Bakker33b43f12013-08-20 11:48:36 +0200560 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200561 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100562 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000563 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000564 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000565
Paul Bakker33b43f12013-08-20 11:48:36 +0200566 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000567 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200568 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200569 buflen = mbedtls_mpi_size( &X );
570 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000571
Paul Bakkere896fea2009-07-06 06:40:23 +0000572
Ronald Cron2dbba992020-06-10 11:42:32 +0200573 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
574 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000575 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000576
Paul Bakkerbd51b262014-07-10 15:26:12 +0200577exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200578 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000579}
Paul Bakker33b43f12013-08-20 11:48:36 +0200580/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000581
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200582/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Werner Lewisefda01f2022-07-06 13:03:36 +0100583void mbedtls_mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000584{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200585 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000586 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200587 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000588
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000590
Werner Lewis19b4cd82022-07-07 11:02:27 +0100591 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000592
Paul Bakker33b43f12013-08-20 11:48:36 +0200593 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000594 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100595 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000596 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200597 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000598
Paul Bakker33b43f12013-08-20 11:48:36 +0200599 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000600 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100601 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000602 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200603 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000604
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200605 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000606
Paul Bakkerbd51b262014-07-10 15:26:12 +0200607exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200608 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000609}
Paul Bakker33b43f12013-08-20 11:48:36 +0200610/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000611
Paul Bakker33b43f12013-08-20 11:48:36 +0200612/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100613void mbedtls_mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000614{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200615 mbedtls_mpi X;
616 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100617 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200618 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000619
Paul Bakkerbd51b262014-07-10 15:26:12 +0200620exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000622}
Paul Bakker33b43f12013-08-20 11:48:36 +0200623/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000624
Paul Bakker33b43f12013-08-20 11:48:36 +0200625/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100626void mbedtls_mpi_set_bit( char * input_X, int pos, int val,
627 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000628{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200629 mbedtls_mpi X, Y;
630 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000631
Werner Lewis19b4cd82022-07-07 11:02:27 +0100632 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
633 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100634 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
635
636 if( result == 0 )
637 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200638 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100639 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
640 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000641
Paul Bakkerbd51b262014-07-10 15:26:12 +0200642exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200643 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000644}
Paul Bakker33b43f12013-08-20 11:48:36 +0200645/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000646
Paul Bakker33b43f12013-08-20 11:48:36 +0200647/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100648void mbedtls_mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000649{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200650 mbedtls_mpi X;
651 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000652
Werner Lewis19b4cd82022-07-07 11:02:27 +0100653 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200654 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000655
Paul Bakkerbd51b262014-07-10 15:26:12 +0200656exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200657 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000658}
Paul Bakker33b43f12013-08-20 11:48:36 +0200659/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000660
Paul Bakker33b43f12013-08-20 11:48:36 +0200661/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +0100662void mbedtls_mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000663{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200664 mbedtls_mpi X;
665 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000666
Werner Lewis19b4cd82022-07-07 11:02:27 +0100667 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200668 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000669
Paul Bakkerbd51b262014-07-10 15:26:12 +0200670exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200671 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000672}
Paul Bakker33b43f12013-08-20 11:48:36 +0200673/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000674
Paul Bakker33b43f12013-08-20 11:48:36 +0200675/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100676void mbedtls_mpi_gcd( char * input_X, char * input_Y,
677 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000678{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200679 mbedtls_mpi A, X, Y, Z;
680 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000681
Werner Lewis19b4cd82022-07-07 11:02:27 +0100682 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
683 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
684 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200685 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200686 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200687 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
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( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200695void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000696{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200697 mbedtls_mpi X;
698 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000699
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200700 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
701 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000702
Paul Bakkerbd51b262014-07-10 15:26:12 +0200703exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200704 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000705}
Paul Bakker33b43f12013-08-20 11:48:36 +0200706/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000707
Paul Bakker33b43f12013-08-20 11:48:36 +0200708/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100709void mbedtls_mpi_cmp_mpi( char * input_X, char * input_Y,
710 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000711{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712 mbedtls_mpi X, Y;
713 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000714
Werner Lewis19b4cd82022-07-07 11:02:27 +0100715 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
716 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000718
Paul Bakkerbd51b262014-07-10 15:26:12 +0200719exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000721}
Paul Bakker33b43f12013-08-20 11:48:36 +0200722/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000723
Paul Bakker33b43f12013-08-20 11:48:36 +0200724/* BEGIN_CASE */
Janos Follathdeb80302022-08-19 13:32:17 +0100725void mpi_core_lt_ct( data_t * input_X, data_t * input_Y, int input_ret )
Janos Follath23bdeca2022-07-22 18:24:06 +0100726{
727 #define MAX_LEN 64
728 mbedtls_mpi_uint X[MAX_LEN];
729 mbedtls_mpi_uint Y[MAX_LEN];
730 unsigned exp_ret = input_ret;
731 unsigned ret;
732 size_t len = CHARS_TO_LIMBS(
733 input_X->len > input_Y->len ? input_X->len : input_Y->len );
734
735 TEST_ASSERT( len <= MAX_LEN );
736
737 TEST_ASSERT( mbedtls_mpi_core_read_be( X, len, input_X->x, input_X->len )
738 == 0 );
739 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, len, input_Y->x, input_Y->len )
740 == 0 );
741
742 TEST_CF_SECRET( X, len * sizeof( mbedtls_mpi_uint ) );
743 TEST_CF_SECRET( Y, len * sizeof( mbedtls_mpi_uint ) );
744
745 ret = mbedtls_mpi_core_lt_ct( X, Y, len );
746
747 TEST_CF_PUBLIC( X, len * sizeof( mbedtls_mpi_uint ) );
748 TEST_CF_PUBLIC( Y, len * sizeof( mbedtls_mpi_uint ) );
749 TEST_CF_PUBLIC( &ret, sizeof( ret ) );
750
Janos Follath494a6d22022-08-22 09:36:17 +0100751 TEST_EQUAL( ret, exp_ret );
Janos Follath23bdeca2022-07-22 18:24:06 +0100752
753exit:
754 ;
755
756 #undef MAX_LEN
757}
758/* END_CASE */
759
760/* BEGIN_CASE */
Janos Follathb7e1b492019-10-14 09:21:49 +0100761void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
762 int size_Y, char * input_Y,
Janos Follath0e5532d2019-10-11 14:21:53 +0100763 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +0100764{
Gilles Peskine0deccf12020-09-02 15:18:07 +0200765 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +0100766 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +0100767 mbedtls_mpi X, Y;
768 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
769
Werner Lewis19b4cd82022-07-07 11:02:27 +0100770 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
771 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100772
Gilles Peskine9018b112020-01-21 16:30:53 +0100773 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
774 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +0100775
Janos Follath0e5532d2019-10-11 14:21:53 +0100776 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +0100777 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +0100778 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +0100779
780exit:
781 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
782}
783/* END_CASE */
784
785/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100786void mbedtls_mpi_cmp_abs( char * input_X, char * input_Y,
787 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000788{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789 mbedtls_mpi X, Y;
790 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000791
Werner Lewis19b4cd82022-07-07 11:02:27 +0100792 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
793 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200794 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000795
Paul Bakkerbd51b262014-07-10 15:26:12 +0200796exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200797 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000798}
Paul Bakker33b43f12013-08-20 11:48:36 +0200799/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000800
Paul Bakker33b43f12013-08-20 11:48:36 +0200801/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200802void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +0000803{
Gilles Peskined0722f82021-06-10 23:00:33 +0200804 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200805 mbedtls_mpi_init( &src );
806 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200807 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +0000808
Werner Lewis19b4cd82022-07-07 11:02:27 +0100809 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
810 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200811
812 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100813 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200814 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200815 TEST_ASSERT( sign_is_valid( &dst ) );
816 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000817
Gilles Peskined0722f82021-06-10 23:00:33 +0200818 /* mbedtls_mpi_safe_cond_assign(), assignment done */
819 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100820 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200821 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
822 TEST_ASSERT( sign_is_valid( &dst ) );
823 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
824
825 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
826 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100827 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200828 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
829 TEST_ASSERT( sign_is_valid( &dst ) );
830 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
831
Paul Bakkerbd51b262014-07-10 15:26:12 +0200832exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200833 mbedtls_mpi_free( &src );
834 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +0200835 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +0100836}
837/* END_CASE */
838
839/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200840void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +0100841{
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200842 mbedtls_mpi X, A;
843 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200844 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000845
Werner Lewis19b4cd82022-07-07 11:02:27 +0100846 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200847 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200848
Werner Lewis19b4cd82022-07-07 11:02:27 +0100849 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200850 TEST_ASSERT( sign_is_valid( &X ) );
851 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000852
Paul Bakkerbd51b262014-07-10 15:26:12 +0200853exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +0200854 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200855 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000856}
Paul Bakker33b43f12013-08-20 11:48:36 +0200857/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000858
Paul Bakker33b43f12013-08-20 11:48:36 +0200859/* BEGIN_CASE */
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200860void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
861{
862 mbedtls_mpi X, Y, X0, Y0;
863 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
864 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
865
Werner Lewis19b4cd82022-07-07 11:02:27 +0100866 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
867 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200868
Gilles Peskined0722f82021-06-10 23:00:33 +0200869 /* mbedtls_mpi_swap() */
Werner Lewis19b4cd82022-07-07 11:02:27 +0100870 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
871 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200872 mbedtls_mpi_swap( &X, &Y );
873 TEST_ASSERT( sign_is_valid( &X ) );
874 TEST_ASSERT( sign_is_valid( &Y ) );
875 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
876 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
877
Gilles Peskined0722f82021-06-10 23:00:33 +0200878 /* mbedtls_mpi_safe_cond_swap(), swap done */
879 mbedtls_mpi_free( &X );
880 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100881 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
882 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200883 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
884 TEST_ASSERT( sign_is_valid( &X ) );
885 TEST_ASSERT( sign_is_valid( &Y ) );
886 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
887 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
888
889 /* mbedtls_mpi_safe_cond_swap(), swap not done */
890 mbedtls_mpi_free( &X );
891 mbedtls_mpi_free( &Y );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100892 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
893 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +0200894 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
895 TEST_ASSERT( sign_is_valid( &X ) );
896 TEST_ASSERT( sign_is_valid( &Y ) );
897 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
898 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
899
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200900exit:
901 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
902 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
903}
904/* END_CASE */
905
906/* BEGIN_CASE */
907void mpi_swap_self( char *X_hex )
908{
909 mbedtls_mpi X, X0;
910 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
911
Werner Lewis19b4cd82022-07-07 11:02:27 +0100912 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
913 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +0200914
915 mbedtls_mpi_swap( &X, &X );
916 TEST_ASSERT( sign_is_valid( &X ) );
917 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
918
919exit:
920 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
921}
922/* END_CASE */
923
924/* BEGIN_CASE */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200925void mbedtls_mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100926{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200927 mbedtls_mpi X;
928 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100929
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200930 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200931 if( used > 0 )
932 {
933 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
934 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
935 }
936 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200937 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +0200938 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100939
Paul Bakkerbd51b262014-07-10 15:26:12 +0200940exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200941 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100942}
943/* END_CASE */
944
945/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100946void mbedtls_mpi_add_mpi( char * input_X, char * input_Y,
947 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000948{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200949 mbedtls_mpi X, Y, Z, A;
950 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000951
Werner Lewis19b4cd82022-07-07 11:02:27 +0100952 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
953 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
954 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200955 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200956 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200957 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000958
Gilles Peskine56f943a2020-07-23 01:18:11 +0200959 /* result == first operand */
960 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200961 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200962 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100963 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200964
965 /* result == second operand */
966 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200967 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +0200968 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
969
Paul Bakkerbd51b262014-07-10 15:26:12 +0200970exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200971 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +0000972}
Paul Bakker33b43f12013-08-20 11:48:36 +0200973/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000974
Paul Bakker33b43f12013-08-20 11:48:36 +0200975/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +0100976void mbedtls_mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +0100977{
978 mbedtls_mpi X, A;
979 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
980
Werner Lewis19b4cd82022-07-07 11:02:27 +0100981 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100982
Werner Lewis19b4cd82022-07-07 11:02:27 +0100983 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100984 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
985 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200986 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100987
Werner Lewis19b4cd82022-07-07 11:02:27 +0100988 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +0100989 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200990 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +0100991 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
992
Werner Lewis19b4cd82022-07-07 11:02:27 +0100993 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +0100994 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200995 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +0100996 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
997
998exit:
999 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1000}
1001/* END_CASE */
1002
1003
1004/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001005void mbedtls_mpi_add_abs( char * input_X, char * input_Y,
1006 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001007{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001008 mbedtls_mpi X, Y, Z, A;
1009 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001010
Werner Lewis19b4cd82022-07-07 11:02:27 +01001011 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1012 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1013 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001014 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001015 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001016 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001017
Gilles Peskine56f943a2020-07-23 01:18:11 +02001018 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001019 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001020 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001021 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001022 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001023
1024 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001025 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001026 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001027 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001028
Paul Bakkerbd51b262014-07-10 15:26:12 +02001029exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001030 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001031}
Paul Bakker33b43f12013-08-20 11:48:36 +02001032/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001033
Paul Bakker33b43f12013-08-20 11:48:36 +02001034/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001035void mbedtls_mpi_add_int( char * input_X, int input_Y,
1036 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001037{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001038 mbedtls_mpi X, Z, A;
1039 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001040
Werner Lewis19b4cd82022-07-07 11:02:27 +01001041 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 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_int( &Z, &X, input_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
Paul Bakkerbd51b262014-07-10 15:26:12 +02001047exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001048 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001049}
Paul Bakker33b43f12013-08-20 11:48:36 +02001050/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001051
Paul Bakker33b43f12013-08-20 11:48:36 +02001052/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001053void mbedtls_mpi_sub_mpi( char * input_X, char * input_Y,
1054 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001055{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001056 mbedtls_mpi X, Y, Z, A;
1057 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001058
Werner Lewis19b4cd82022-07-07 11:02:27 +01001059 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1060 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 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_sub_mpi( &Z, &X, &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
Gilles Peskine56f943a2020-07-23 01:18:11 +02001066 /* result == first operand */
1067 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001068 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001069 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001070 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001071
1072 /* result == second operand */
1073 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001074 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001075 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1076
Paul Bakkerbd51b262014-07-10 15:26:12 +02001077exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001078 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001079}
Paul Bakker33b43f12013-08-20 11:48:36 +02001080/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001081
Paul Bakker33b43f12013-08-20 11:48:36 +02001082/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001083void mbedtls_mpi_sub_abs( char * input_X, char * input_Y,
1084 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001085{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001087 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001088 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001089
Werner Lewis19b4cd82022-07-07 11:02:27 +01001090 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1091 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1092 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001093
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001094 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001095 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001096 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001097 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001098 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001099
Gilles Peskine56f943a2020-07-23 01:18:11 +02001100 /* result == first operand */
1101 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001102 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001103 if( sub_result == 0 )
1104 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001105 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001106
1107 /* result == second operand */
1108 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001109 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001110 if( sub_result == 0 )
1111 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1112
Paul Bakkerbd51b262014-07-10 15:26:12 +02001113exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001114 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001115}
Paul Bakker33b43f12013-08-20 11:48:36 +02001116/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001117
Paul Bakker33b43f12013-08-20 11:48:36 +02001118/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001119void mbedtls_mpi_sub_int( char * input_X, int input_Y,
1120 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001121{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001122 mbedtls_mpi X, Z, A;
1123 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001124
Werner Lewis19b4cd82022-07-07 11:02:27 +01001125 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1126 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001127 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001128 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001129 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001130
Paul Bakkerbd51b262014-07-10 15:26:12 +02001131exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001132 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001133}
Paul Bakker33b43f12013-08-20 11:48:36 +02001134/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001135
Paul Bakker33b43f12013-08-20 11:48:36 +02001136/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001137void mbedtls_mpi_mul_mpi( char * input_X, char * input_Y,
1138 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001139{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001140 mbedtls_mpi X, Y, Z, A;
1141 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001142
Werner Lewis19b4cd82022-07-07 11:02:27 +01001143 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1144 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 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_mul_mpi( &Z, &X, &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( &Y ); 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 Lewis9802d362022-07-07 11:37:24 +01001156void mbedtls_mpi_mul_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001157 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001158{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159 mbedtls_mpi X, Z, A;
1160 mbedtls_mpi_init( &X ); 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( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001164 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001165 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001166 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001167 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001168 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001169 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001170 else
1171 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001172
Paul Bakkerbd51b262014-07-10 15:26:12 +02001173exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001174 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001175}
Paul Bakker33b43f12013-08-20 11:48:36 +02001176/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001177
Paul Bakker33b43f12013-08-20 11:48:36 +02001178/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001179void mbedtls_mpi_div_mpi( char * input_X, char * input_Y,
1180 char * input_A, char * input_B,
1181 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001182{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001183 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001184 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001185 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1186 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001187
Werner Lewis19b4cd82022-07-07 11:02:27 +01001188 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1189 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1190 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1191 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001192 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001193 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001194 if( res == 0 )
1195 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001196 TEST_ASSERT( sign_is_valid( &Q ) );
1197 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001198 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1199 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001200 }
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( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1204 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001205}
Paul Bakker33b43f12013-08-20 11:48:36 +02001206/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001207
Paul Bakker33b43f12013-08-20 11:48:36 +02001208/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001209void mbedtls_mpi_div_int( char * input_X, int input_Y,
Werner Lewisefda01f2022-07-06 13:03:36 +01001210 char * input_A, char * input_B,
1211 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001212{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001213 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001214 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001215 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1216 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001217
Werner Lewis19b4cd82022-07-07 11:02:27 +01001218 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 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_int( &Q, &R, &X, input_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( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1233 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 Lewisefda01f2022-07-06 13:03:36 +01001238void mbedtls_mpi_mod_mpi( char * input_X, char * input_Y,
1239 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001240{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001241 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001242 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001243 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001244
Werner Lewis19b4cd82022-07-07 11:02:27 +01001245 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1246 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1247 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001249 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001250 if( res == 0 )
1251 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001252 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001253 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001254 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001255
Paul Bakkerbd51b262014-07-10 15:26:12 +02001256exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001257 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001258}
Paul Bakker33b43f12013-08-20 11:48:36 +02001259/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001260
Paul Bakker33b43f12013-08-20 11:48:36 +02001261/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001262void mbedtls_mpi_mod_int( char * input_X, int input_Y,
Azim Khanf1aaec92017-05-30 14:23:15 +01001263 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001264{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001265 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001266 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001267 mbedtls_mpi_uint r;
1268 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001269
Werner Lewis19b4cd82022-07-07 11:02:27 +01001270 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001271 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001272 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001273 if( res == 0 )
1274 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001275 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001276 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001277
Paul Bakkerbd51b262014-07-10 15:26:12 +02001278exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001279 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001280}
Paul Bakker33b43f12013-08-20 11:48:36 +02001281/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001282
Paul Bakker33b43f12013-08-20 11:48:36 +02001283/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001284void mbedtls_mpi_exp_mod( char * input_A, char * input_E,
1285 char * input_N, char * input_X,
1286 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001287{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001288 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001289 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001290 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1291 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001292
Werner Lewis19b4cd82022-07-07 11:02:27 +01001293 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1294 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1295 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1296 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001297
Gilles Peskine342f71b2021-06-09 18:31:35 +02001298 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001299 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001300 if( res == 0 )
1301 {
1302 TEST_ASSERT( sign_is_valid( &Z ) );
1303 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1304 }
1305
1306 /* Now test again with the speed-up parameter supplied as an output. */
1307 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001308 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001309 if( res == 0 )
1310 {
1311 TEST_ASSERT( sign_is_valid( &Z ) );
1312 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1313 }
1314
1315 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001316 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001317 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001318 if( res == 0 )
1319 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001320 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001321 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001322 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001323
Paul Bakkerbd51b262014-07-10 15:26:12 +02001324exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001325 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1326 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001327}
Paul Bakker33b43f12013-08-20 11:48:36 +02001328/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001329
Paul Bakker33b43f12013-08-20 11:48:36 +02001330/* BEGIN_CASE */
Chris Jonesd10b3312020-12-02 10:41:50 +00001331void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
Werner Lewis9802d362022-07-07 11:37:24 +01001332 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001333{
1334 mbedtls_mpi A, E, N, RR, Z;
1335 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1336 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1337
Chris Jonesaa850cd2020-12-03 11:35:41 +00001338 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001339 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001340 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001341 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001342
1343 /* Set E to 2^(E_bytes - 1) + 1 */
1344 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1345 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001346 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001347
1348 /* Set N to 2^(N_bytes - 1) + 1 */
1349 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1350 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001351 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1352
1353 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001354 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001355
Chris Jonesaa850cd2020-12-03 11:35:41 +00001356 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001357
1358exit:
1359 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1360 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1361}
1362/* END_CASE */
1363
1364/* BEGIN_CASE */
Werner Lewisefda01f2022-07-06 13:03:36 +01001365void mbedtls_mpi_inv_mod( char * input_X, char * input_Y,
1366 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001367{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001368 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001369 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001370 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001371
Werner Lewis19b4cd82022-07-07 11:02:27 +01001372 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1373 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1374 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001375 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001376 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001377 if( res == 0 )
1378 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001379 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001380 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001381 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001382
Paul Bakkerbd51b262014-07-10 15:26:12 +02001383exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001384 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001385}
Paul Bakker33b43f12013-08-20 11:48:36 +02001386/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001387
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001388/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Werner Lewis9802d362022-07-07 11:37:24 +01001389void mbedtls_mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001390{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001391 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001392 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001393 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001394
Werner Lewis19b4cd82022-07-07 11:02:27 +01001395 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001396 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001397 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001398
Paul Bakkerbd51b262014-07-10 15:26:12 +02001399exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001400 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001401}
Paul Bakker33b43f12013-08-20 11:48:36 +02001402/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001404/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follath64eca052018-09-05 17:04:49 +01001405void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
Darryl Greenac2ead02018-10-02 15:30:39 +01001406 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001407{
1408 mbedtls_mpi X;
1409 int res;
1410 mbedtls_test_mpi_random rand;
1411
1412 mbedtls_mpi_init( &X );
1413 rand.data = witnesses;
1414 rand.pos = 0;
1415 rand.chunk_len = chunk_len;
1416
1417 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001418 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1419 mbedtls_test_mpi_miller_rabin_determinizer,
1420 &rand );
1421 TEST_ASSERT( res == 0 );
1422
1423 rand.data = witnesses;
1424 rand.pos = 0;
1425 rand.chunk_len = chunk_len;
1426
Janos Follatha0b67c22018-09-18 14:48:23 +01001427 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1428 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001429 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001430 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001431
1432exit:
1433 mbedtls_mpi_free( &X );
1434}
1435/* END_CASE */
1436
1437/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001438void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001439{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001440 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001441 int my_ret;
1442
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001444
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001445 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1446 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001447 TEST_ASSERT( my_ret == ref_ret );
1448
1449 if( ref_ret == 0 )
1450 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001451 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001452
1453 TEST_ASSERT( actual_bits >= (size_t) bits );
1454 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001455 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001456
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001457 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1458 mbedtls_test_rnd_std_rand,
1459 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001460 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001461 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001462 /* X = ( X - 1 ) / 2 */
1463 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001464 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1465 mbedtls_test_rnd_std_rand,
1466 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001467 }
1468 }
1469
Paul Bakkerbd51b262014-07-10 15:26:12 +02001470exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001471 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001472}
1473/* END_CASE */
1474
Paul Bakker33b43f12013-08-20 11:48:36 +02001475/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001476void mbedtls_mpi_shift_l( char * input_X, int shift_X,
1477 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001478{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001479 mbedtls_mpi X, A;
1480 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001481
Werner Lewis19b4cd82022-07-07 11:02:27 +01001482 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1483 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001484 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001485 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001486 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001487
Paul Bakkerbd51b262014-07-10 15:26:12 +02001488exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001489 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001490}
Paul Bakker33b43f12013-08-20 11:48:36 +02001491/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001492
Paul Bakker33b43f12013-08-20 11:48:36 +02001493/* BEGIN_CASE */
Werner Lewis9802d362022-07-07 11:37:24 +01001494void mbedtls_mpi_shift_r( char * input_X, int shift_X,
1495 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001496{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001497 mbedtls_mpi X, A;
1498 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001499
Werner Lewis19b4cd82022-07-07 11:02:27 +01001500 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1501 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001502 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001503 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001505
Paul Bakkerbd51b262014-07-10 15:26:12 +02001506exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001508}
Paul Bakker33b43f12013-08-20 11:48:36 +02001509/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001510
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001511/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001512void mpi_fill_random( int wanted_bytes, int rng_bytes,
1513 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001514{
1515 mbedtls_mpi X;
1516 int ret;
1517 size_t bytes_left = rng_bytes;
1518 mbedtls_mpi_init( &X );
1519
Gilles Peskine422e8672021-04-02 00:02:27 +02001520 if( before != 0 )
1521 {
1522 /* Set X to sign(before) * 2^(|before|-1) */
1523 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1524 if( before < 0 )
1525 before = - before;
1526 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1527 }
1528
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001529 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1530 f_rng_bytes_left, &bytes_left );
1531 TEST_ASSERT( ret == expected_ret );
1532
1533 if( expected_ret == 0 )
1534 {
1535 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1536 * as a big-endian representation of the number. We know when
1537 * our RNG function returns null bytes, so we know how many
1538 * leading zero bytes the number has. */
1539 size_t leading_zeros = 0;
1540 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1541 leading_zeros = 1;
1542 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1543 (size_t) wanted_bytes );
1544 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001545 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001546 }
1547
1548exit:
1549 mbedtls_mpi_free( &X );
1550}
1551/* END_CASE */
1552
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001553/* BEGIN_CASE */
1554void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1555{
1556 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1557 * This function assumes that the value of bound is at least 2 and
1558 * that iterations is large enough that a one-in-2^iterations chance
1559 * effectively never occurs.
1560 */
1561
1562 mbedtls_mpi upper_bound;
1563 size_t n_bits;
1564 mbedtls_mpi result;
1565 size_t b;
1566 /* If upper_bound is small, stats[b] is the number of times the value b
1567 * has been generated. Otherwise stats[b] is the number of times a
1568 * value with bit b set has been generated. */
1569 size_t *stats = NULL;
1570 size_t stats_len;
1571 int full_stats;
1572 size_t i;
1573
1574 mbedtls_mpi_init( &upper_bound );
1575 mbedtls_mpi_init( &result );
1576
1577 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1578 bound_bytes->x, bound_bytes->len ) );
1579 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1580 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1581 * to be small enough that the probability of missing one value is
1582 * negligible given the number of iterations. It must be less than
1583 * 256 because some of the code below assumes that "small" values
1584 * fit in a byte. */
1585 if( n_bits <= 5 )
1586 {
1587 full_stats = 1;
1588 stats_len = bound_bytes->x[bound_bytes->len - 1];
1589 }
1590 else
1591 {
1592 full_stats = 0;
1593 stats_len = n_bits;
1594 }
1595 ASSERT_ALLOC( stats, stats_len );
1596
1597 for( i = 0; i < (size_t) iterations; i++ )
1598 {
1599 mbedtls_test_set_step( i );
1600 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1601 mbedtls_test_rnd_std_rand, NULL ) );
1602
Gilles Peskinedffc7102021-06-10 15:34:15 +02001603 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001604 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1605 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1606 if( full_stats )
1607 {
1608 uint8_t value;
1609 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1610 TEST_ASSERT( value < stats_len );
1611 ++stats[value];
1612 }
1613 else
1614 {
1615 for( b = 0; b < n_bits; b++ )
1616 stats[b] += mbedtls_mpi_get_bit( &result, b );
1617 }
1618 }
1619
1620 if( full_stats )
1621 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001622 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001623 {
1624 mbedtls_test_set_step( 1000000 + b );
1625 /* Assert that each value has been reached at least once.
1626 * This is almost guaranteed if the iteration count is large
1627 * enough. This is a very crude way of checking the distribution.
1628 */
1629 TEST_ASSERT( stats[b] > 0 );
1630 }
1631 }
1632 else
1633 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001634 int statistically_safe_all_the_way =
1635 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001636 for( b = 0; b < n_bits; b++ )
1637 {
1638 mbedtls_test_set_step( 1000000 + b );
1639 /* Assert that each bit has been set in at least one result and
1640 * clear in at least one result. Provided that iterations is not
1641 * too small, it would be extremely unlikely for this not to be
1642 * the case if the results are uniformly distributed.
1643 *
1644 * As an exception, the top bit may legitimately never be set
1645 * if bound is a power of 2 or only slightly above.
1646 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001647 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001648 {
1649 TEST_ASSERT( stats[b] > 0 );
1650 }
1651 TEST_ASSERT( stats[b] < (size_t) iterations );
1652 }
1653 }
1654
1655exit:
1656 mbedtls_mpi_free( &upper_bound );
1657 mbedtls_mpi_free( &result );
1658 mbedtls_free( stats );
1659}
1660/* END_CASE */
1661
Gilles Peskine1e918f42021-03-29 22:14:51 +02001662/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001663void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001664{
1665 mbedtls_mpi upper_bound;
1666 mbedtls_mpi result;
1667
1668 mbedtls_mpi_init( &upper_bound );
1669 mbedtls_mpi_init( &result );
1670
Gilles Peskine422e8672021-04-02 00:02:27 +02001671 if( before != 0 )
1672 {
1673 /* Set result to sign(before) * 2^(|before|-1) */
1674 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1675 if( before < 0 )
1676 before = - before;
1677 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1678 }
1679
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001680 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1681 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1682 bound_bytes->x, bound_bytes->len ) );
1683 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1684 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001685 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001686 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1687 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1688
1689exit:
1690 mbedtls_mpi_free( &upper_bound );
1691 mbedtls_mpi_free( &result );
1692}
1693/* END_CASE */
1694
1695/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02001696void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1697{
1698 mbedtls_mpi upper_bound;
1699 mbedtls_mpi result;
1700 int actual_ret;
1701
1702 mbedtls_mpi_init( &upper_bound );
1703 mbedtls_mpi_init( &result );
1704
1705 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1706 bound_bytes->x, bound_bytes->len ) );
1707 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1708 mbedtls_test_rnd_std_rand, NULL );
1709 TEST_EQUAL( expected_ret, actual_ret );
1710
1711exit:
1712 mbedtls_mpi_free( &upper_bound );
1713 mbedtls_mpi_free( &result );
1714}
1715/* END_CASE */
1716
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001717/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01001718void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00001719{
Andres AG93012e82016-09-09 09:10:28 +01001720 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00001721}
Paul Bakker33b43f12013-08-20 11:48:36 +02001722/* END_CASE */