blob: b699f9c04647d084a19379eeda332d9350692e8f [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 */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100185void 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 */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100205void mpi_core_io_null()
Janos Follath91dc67d2022-07-22 14:24:58 +0100206{
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 */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100236void mpi_core_io_be( data_t *input, int nb_int, int nx_32_int, int iret,
237 int oret )
Janos Follathf1d617d2022-07-21 09:29:32 +0100238{
Janos Follathf1d617d2022-07-21 09:29:32 +0100239 if( iret != 0 )
240 TEST_ASSERT( oret == 0 );
241
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100242 TEST_LE_S( 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];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100246 TEST_LE_U( nb, sizeof( buf ) );
Janos Follath81620642022-08-15 11:13:38 +0100247
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. */
Janos Follath6b8e0c22022-08-22 09:54:25 +0100250 size_t nx;
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100251 TEST_LE_S( 0, nx_32_int );
Janos Follath6b8e0c22022-08-22 09:54:25 +0100252 if( sizeof( mbedtls_mpi_uint ) == 8 )
253 nx = nx_32_int / 2 + nx_32_int % 2;
254 else
255 nx = nx_32_int;
Janos Follathf1d617d2022-07-21 09:29:32 +0100256
Janos Follath81620642022-08-15 11:13:38 +0100257 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100258 TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
Janos Follath81620642022-08-15 11:13:38 +0100259
260 int ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100261 TEST_EQUAL( ret, iret );
Janos Follathf1d617d2022-07-21 09:29:32 +0100262
263 if( iret == 0 )
264 {
265 ret = mbedtls_mpi_core_write_be( X, nx, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100266 TEST_EQUAL( ret, oret );
Janos Follathf1d617d2022-07-21 09:29:32 +0100267 }
268
269 if( ( iret == 0 ) && ( oret == 0 ) )
270 {
271 if( nb > input->len )
272 {
273 size_t leading_zeroes = nb - input->len;
274 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
275 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100276 TEST_EQUAL( buf[i], 0 );
Janos Follathf1d617d2022-07-21 09:29:32 +0100277 }
278 else
279 {
280 size_t leading_zeroes = input->len - nb;
281 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
282 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100283 TEST_EQUAL( input->x[i], 0 );
Janos Follathf1d617d2022-07-21 09:29:32 +0100284 }
285 }
286
287exit:
288 ;
Janos Follathf1d617d2022-07-21 09:29:32 +0100289}
290/* END_CASE */
291
292/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100293void mpi_core_io_le( data_t *input, int nb_int, int nx_32_int, int iret,
294 int oret )
Janos Follath6ff35362022-07-21 15:27:21 +0100295{
Janos Follath6ff35362022-07-21 15:27:21 +0100296 if( iret != 0 )
297 TEST_ASSERT( oret == 0 );
298
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100299 TEST_LE_S( 0, nb_int );
Janos Follath81620642022-08-15 11:13:38 +0100300 size_t nb = nb_int;
Janos Follath6ff35362022-07-21 15:27:21 +0100301
Janos Follath81620642022-08-15 11:13:38 +0100302 unsigned char buf[1024];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100303 TEST_LE_U( nb, sizeof( buf ) );
Janos Follath81620642022-08-15 11:13:38 +0100304
Janos Follath9dfb5622022-08-11 12:15:55 +0100305 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
306 * to halve the number of limbs to have the same size. */
Janos Follath6b8e0c22022-08-22 09:54:25 +0100307 size_t nx;
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100308 TEST_LE_S( 0, nx_32_int );
Janos Follath6b8e0c22022-08-22 09:54:25 +0100309 if( sizeof( mbedtls_mpi_uint ) == 8 )
310 nx = nx_32_int / 2 + nx_32_int % 2;
311 else
312 nx = nx_32_int;
Janos Follath6ff35362022-07-21 15:27:21 +0100313
Janos Follath81620642022-08-15 11:13:38 +0100314 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100315 TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
Janos Follath81620642022-08-15 11:13:38 +0100316
317 int ret = mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100318 TEST_EQUAL( ret, iret );
Janos Follath6ff35362022-07-21 15:27:21 +0100319
320 if( iret == 0 )
321 {
322 ret = mbedtls_mpi_core_write_le( X, nx, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100323 TEST_EQUAL( ret, oret );
Janos Follath6ff35362022-07-21 15:27:21 +0100324 }
325
326 if( ( iret == 0 ) && ( oret == 0 ) )
327 {
328 if( nb > input->len )
329 {
330 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
331 for( size_t i = input->len; i < nb; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100332 TEST_EQUAL( buf[i], 0 );
Janos Follath6ff35362022-07-21 15:27:21 +0100333 }
334 else
335 {
336 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
337 for( size_t i = nb; i < input->len; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100338 TEST_EQUAL( input->x[i], 0 );
Janos Follath6ff35362022-07-21 15:27:21 +0100339 }
340 }
341
342exit:
343 ;
Janos Follath6ff35362022-07-21 15:27:21 +0100344}
345/* END_CASE */
346
347/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100348void mpi_mod_setup( int ext_rep, int int_rep, int iret )
Janos Follath16949692022-08-08 13:37:20 +0100349{
350 #define MLIMBS 8
351 mbedtls_mpi_uint mp[MLIMBS];
352 mbedtls_mpi_mod_modulus m;
353 int ret;
354
355 memset( mp, 0xFF, sizeof(mp) );
356
357 mbedtls_mpi_mod_modulus_init( &m );
358 ret = mbedtls_mpi_mod_modulus_setup( &m, mp, MLIMBS, ext_rep, int_rep );
Janos Follath494a6d22022-08-22 09:36:17 +0100359 TEST_EQUAL( ret, iret );
Janos Follath16949692022-08-08 13:37:20 +0100360
361 /* Address sanitiser should catch if we try to free mp */
362 mbedtls_mpi_mod_modulus_free( &m );
363
364 /* Make sure that the modulus doesn't have reference to mp anymore */
365 TEST_ASSERT( m.p != mp );
366
367exit:
368 /* It should be safe to call an mbedtls free several times */
369 mbedtls_mpi_mod_modulus_free( &m );
370
371 #undef MLIMBS
372}
373/* END_CASE */
374
375
376/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100377void mpi_mod_raw_io( data_t *input, int nb_int, int nx_32_int,
378 int iendian, int iret, int oret )
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200379{
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200380 if( iret != 0 )
381 TEST_ASSERT( oret == 0 );
382
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100383 TEST_LE_S( 0, nb_int );
Janos Follath81620642022-08-15 11:13:38 +0100384 size_t nb = nb_int;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200385
Janos Follath81620642022-08-15 11:13:38 +0100386 unsigned char buf[1024];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100387 TEST_LE_U( nb, sizeof( buf ) );
Janos Follath81620642022-08-15 11:13:38 +0100388
Gabor Mezei7f081782022-08-12 18:00:33 +0200389 /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
390 * to halve the number of limbs to have the same size. */
Janos Follath6b8e0c22022-08-22 09:54:25 +0100391 size_t nx;
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100392 TEST_LE_S( 0, nx_32_int );
Janos Follath6b8e0c22022-08-22 09:54:25 +0100393 if( sizeof( mbedtls_mpi_uint ) == 8 )
394 nx = nx_32_int / 2 + nx_32_int % 2;
395 else
396 nx = nx_32_int;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200397
Janos Follath81620642022-08-15 11:13:38 +0100398 mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +0100399 TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
Janos Follath81620642022-08-15 11:13:38 +0100400
401 int endian;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200402 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID )
403 endian = MBEDTLS_MPI_MOD_EXT_REP_LE;
404 else
405 endian = iendian;
406
Janos Follath81620642022-08-15 11:13:38 +0100407 mbedtls_mpi_mod_modulus m;
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200408 mbedtls_mpi_mod_modulus_init( &m );
Janos Follath81620642022-08-15 11:13:38 +0100409 mbedtls_mpi_uint init[sizeof( X ) / sizeof( X[0] )];
410 memset( init, 0xFF, sizeof( init ) );
411 int ret = mbedtls_mpi_mod_modulus_setup( &m, init, nx, endian,
412 MBEDTLS_MPI_MOD_REP_MONTGOMERY );
Janos Follath494a6d22022-08-22 09:36:17 +0100413 TEST_EQUAL( ret, 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200414
415 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && iret != 0 )
416 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
417
418 ret = mbedtls_mpi_mod_raw_read( X, &m, input->x, input->len );
Janos Follath494a6d22022-08-22 09:36:17 +0100419 TEST_EQUAL( ret, iret );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200420
421 if( iret == 0 )
422 {
423 if( iendian == MBEDTLS_MPI_MOD_EXT_REP_INVALID && oret != 0 )
424 m.ext_rep = MBEDTLS_MPI_MOD_EXT_REP_INVALID;
425
426 ret = mbedtls_mpi_mod_raw_write( X, &m, buf, nb );
Janos Follath494a6d22022-08-22 09:36:17 +0100427 TEST_EQUAL( ret, oret );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200428 }
429
430 if( ( iret == 0 ) && ( oret == 0 ) )
431 {
432 if( nb > input->len )
433 {
434 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
435 {
436 size_t leading_zeroes = nb - input->len;
437 TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
438 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100439 TEST_EQUAL( buf[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200440 }
441 else
442 {
443 TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
444 for( size_t i = input->len; i < nb; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100445 TEST_EQUAL( buf[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200446 }
447 }
448 else
449 {
450 if( endian == MBEDTLS_MPI_MOD_EXT_REP_BE )
451 {
452 size_t leading_zeroes = input->len - nb;
453 TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
454 for( size_t i = 0; i < leading_zeroes; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100455 TEST_EQUAL( input->x[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200456 }
457 else
458 {
459 TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
460 for( size_t i = nb; i < input->len; i++ )
Janos Follath494a6d22022-08-22 09:36:17 +0100461 TEST_EQUAL( input->x[i], 0 );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200462 }
463 }
464 }
465
466exit:
467 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezei23a1ce92022-08-02 11:54:44 +0200468}
469/* END_CASE */
470
471/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100472void mpi_read_binary_le( data_t * buf, char * input_A )
Janos Follatha778a942019-02-13 10:28:28 +0000473{
474 mbedtls_mpi X;
Janos Follathe5670f22019-02-25 16:11:58 +0000475 char str[1000];
Janos Follatha778a942019-02-13 10:28:28 +0000476 size_t len;
477
478 mbedtls_mpi_init( &X );
479
480
481 TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200482 TEST_ASSERT( sign_is_valid( &X ) );
Werner Lewisf65a3272022-07-07 11:38:44 +0100483 TEST_ASSERT( mbedtls_mpi_write_string( &X, 16, str, sizeof( str ), &len ) == 0 );
Werner Lewisdc47fe72022-08-01 13:55:41 +0100484 TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
Janos Follatha778a942019-02-13 10:28:28 +0000485
486exit:
487 mbedtls_mpi_free( &X );
488}
489/* END_CASE */
490
491/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100492void mpi_write_binary( char * input_X, data_t * input_A,
493 int output_size, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000494{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000496 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000497 size_t buflen;
Paul Bakkere896fea2009-07-06 06:40:23 +0000498
499 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000500
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200501 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000502
Werner Lewis19b4cd82022-07-07 11:02:27 +0100503 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +0100504
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200505 buflen = mbedtls_mpi_size( &X );
Paul Bakker33b43f12013-08-20 11:48:36 +0200506 if( buflen > (size_t) output_size )
507 buflen = (size_t) output_size;
Paul Bakkere896fea2009-07-06 06:40:23 +0000508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
Paul Bakker33b43f12013-08-20 11:48:36 +0200510 if( result == 0)
Paul Bakkerba48cb22009-07-12 11:01:32 +0000511 {
Paul Bakkere896fea2009-07-06 06:40:23 +0000512
Ronald Cron2dbba992020-06-10 11:42:32 +0200513 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
514 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000515 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000516
Paul Bakkerbd51b262014-07-10 15:26:12 +0200517exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200518 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000519}
Paul Bakker33b43f12013-08-20 11:48:36 +0200520/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000521
Janos Follathe344d0f2019-02-19 16:17:40 +0000522/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100523void mpi_write_binary_le( char * input_X, data_t * input_A,
524 int output_size, int result )
Janos Follathe344d0f2019-02-19 16:17:40 +0000525{
526 mbedtls_mpi X;
527 unsigned char buf[1000];
528 size_t buflen;
529
530 memset( buf, 0x00, 1000 );
531
532 mbedtls_mpi_init( &X );
533
Werner Lewis19b4cd82022-07-07 11:02:27 +0100534 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000535
536 buflen = mbedtls_mpi_size( &X );
537 if( buflen > (size_t) output_size )
538 buflen = (size_t) output_size;
539
540 TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
541 if( result == 0)
542 {
543
Ronald Cron2dbba992020-06-10 11:42:32 +0200544 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
545 buflen, input_A->len ) == 0 );
Janos Follathe344d0f2019-02-19 16:17:40 +0000546 }
547
548exit:
549 mbedtls_mpi_free( &X );
550}
551/* END_CASE */
552
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200553/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100554void mpi_read_file( char * input_file, data_t * input_A, int result )
Paul Bakkere896fea2009-07-06 06:40:23 +0000555{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 mbedtls_mpi X;
Paul Bakkere896fea2009-07-06 06:40:23 +0000557 unsigned char buf[1000];
Paul Bakkerf4a3f302011-04-24 15:53:29 +0000558 size_t buflen;
Paul Bakker69998dd2009-07-11 19:15:20 +0000559 FILE *file;
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000560 int ret;
Paul Bakkere896fea2009-07-06 06:40:23 +0000561
562 memset( buf, 0x00, 1000 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000563
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200564 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000565
Paul Bakker33b43f12013-08-20 11:48:36 +0200566 file = fopen( input_file, "r" );
Paul Bakker8a0c0a92014-04-17 16:08:20 +0200567 TEST_ASSERT( file != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100568 ret = mbedtls_mpi_read_file( &X, 16, file );
Paul Bakkere896fea2009-07-06 06:40:23 +0000569 fclose(file);
Manuel Pégourié-Gonnarde43187d2015-02-14 16:01:34 +0000570 TEST_ASSERT( ret == result );
Paul Bakkere896fea2009-07-06 06:40:23 +0000571
Paul Bakker33b43f12013-08-20 11:48:36 +0200572 if( result == 0 )
Paul Bakkerba48cb22009-07-12 11:01:32 +0000573 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200574 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200575 buflen = mbedtls_mpi_size( &X );
576 TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000577
Paul Bakkere896fea2009-07-06 06:40:23 +0000578
Ronald Cron2dbba992020-06-10 11:42:32 +0200579 TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
580 buflen, input_A->len ) == 0 );
Paul Bakkerba48cb22009-07-12 11:01:32 +0000581 }
Paul Bakker6c591fa2011-05-05 11:49:20 +0000582
Paul Bakkerbd51b262014-07-10 15:26:12 +0200583exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200584 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000585}
Paul Bakker33b43f12013-08-20 11:48:36 +0200586/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000587
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200588/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100589void mpi_write_file( char * input_X, char * output_file )
Paul Bakkere896fea2009-07-06 06:40:23 +0000590{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200591 mbedtls_mpi X, Y;
Paul Bakker69998dd2009-07-11 19:15:20 +0000592 FILE *file_out, *file_in;
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200593 int ret;
Paul Bakker69998dd2009-07-11 19:15:20 +0000594
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200595 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000596
Werner Lewis19b4cd82022-07-07 11:02:27 +0100597 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000598
Paul Bakker33b43f12013-08-20 11:48:36 +0200599 file_out = fopen( output_file, "w" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000600 TEST_ASSERT( file_out != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100601 ret = mbedtls_mpi_write_file( NULL, &X, 16, file_out );
Paul Bakkere896fea2009-07-06 06:40:23 +0000602 fclose(file_out);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200603 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000604
Paul Bakker33b43f12013-08-20 11:48:36 +0200605 file_in = fopen( output_file, "r" );
Paul Bakker5690efc2011-05-26 13:16:06 +0000606 TEST_ASSERT( file_in != NULL );
Werner Lewisf65a3272022-07-07 11:38:44 +0100607 ret = mbedtls_mpi_read_file( &Y, 16, file_in );
Paul Bakkere896fea2009-07-06 06:40:23 +0000608 fclose(file_in);
Manuel Pégourié-Gonnardac5361f2015-06-24 01:08:09 +0200609 TEST_ASSERT( ret == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +0000610
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200611 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000612
Paul Bakkerbd51b262014-07-10 15:26:12 +0200613exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200614 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakkere896fea2009-07-06 06:40:23 +0000615}
Paul Bakker33b43f12013-08-20 11:48:36 +0200616/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000617
Paul Bakker33b43f12013-08-20 11:48:36 +0200618/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100619void mpi_get_bit( char * input_X, int pos, int val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000620{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200621 mbedtls_mpi X;
622 mbedtls_mpi_init( &X );
Werner Lewis19b4cd82022-07-07 11:02:27 +0100623 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200624 TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000625
Paul Bakkerbd51b262014-07-10 15:26:12 +0200626exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200627 mbedtls_mpi_free( &X );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000628}
Paul Bakker33b43f12013-08-20 11:48:36 +0200629/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000630
Paul Bakker33b43f12013-08-20 11:48:36 +0200631/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100632void mpi_set_bit( char * input_X, int pos, int val,
633 char * output_Y, int result )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000634{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200635 mbedtls_mpi X, Y;
636 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000637
Werner Lewis19b4cd82022-07-07 11:02:27 +0100638 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
639 TEST_ASSERT( mbedtls_test_read_mpi( &Y, output_Y ) == 0 );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100640 TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
641
642 if( result == 0 )
643 {
Gilles Peskinedffc7102021-06-10 15:34:15 +0200644 TEST_ASSERT( sign_is_valid( &X ) );
Paul Bakkerec5ceb62016-07-14 12:47:07 +0100645 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
646 }
Paul Bakker2f5947e2011-05-18 15:47:11 +0000647
Paul Bakkerbd51b262014-07-10 15:26:12 +0200648exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200649 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000650}
Paul Bakker33b43f12013-08-20 11:48:36 +0200651/* END_CASE */
Paul Bakker2f5947e2011-05-18 15:47:11 +0000652
Paul Bakker33b43f12013-08-20 11:48:36 +0200653/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100654void mpi_lsb( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000655{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656 mbedtls_mpi X;
657 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000658
Werner Lewis19b4cd82022-07-07 11:02:27 +0100659 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000661
Paul Bakkerbd51b262014-07-10 15:26:12 +0200662exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200663 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000664}
Paul Bakker33b43f12013-08-20 11:48:36 +0200665/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +0000666
Paul Bakker33b43f12013-08-20 11:48:36 +0200667/* BEGIN_CASE */
Gilles Peskineb50e4332022-10-09 21:17:26 +0200668void mpi_core_bitlen( char *input_X, int nr_bits )
669{
670 mbedtls_mpi_uint *X = NULL;
671 size_t limbs;
672
673 TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs, input_X ), 0 );
674 TEST_EQUAL( mbedtls_mpi_core_bitlen( X, limbs ), nr_bits );
675
676exit:
677 mbedtls_free( X );
678}
679/* END_CASE */
680
681/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100682void mpi_bitlen( char * input_X, int nr_bits )
Paul Bakkere896fea2009-07-06 06:40:23 +0000683{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200684 mbedtls_mpi X;
685 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +0000686
Werner Lewis19b4cd82022-07-07 11:02:27 +0100687 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200688 TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000689
Paul Bakkerbd51b262014-07-10 15:26:12 +0200690exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200691 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000692}
Paul Bakker33b43f12013-08-20 11:48:36 +0200693/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000694
Paul Bakker33b43f12013-08-20 11:48:36 +0200695/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100696void mpi_gcd( char * input_X, char * input_Y,
697 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000698{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200699 mbedtls_mpi A, X, Y, Z;
700 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000701
Werner Lewis19b4cd82022-07-07 11:02:27 +0100702 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
703 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
704 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200705 TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +0200706 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200707 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000708
Paul Bakkerbd51b262014-07-10 15:26:12 +0200709exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200710 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Paul Bakker367dae42009-06-28 21:50:27 +0000711}
Paul Bakker33b43f12013-08-20 11:48:36 +0200712/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000713
Paul Bakker33b43f12013-08-20 11:48:36 +0200714/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100715void mpi_cmp_int( int input_X, int input_A, int result_CMP )
Paul Bakker367dae42009-06-28 21:50:27 +0000716{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200717 mbedtls_mpi X;
718 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000719
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200720 TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
721 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
Paul Bakker6c591fa2011-05-05 11:49:20 +0000722
Paul Bakkerbd51b262014-07-10 15:26:12 +0200723exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200724 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +0000725}
Paul Bakker33b43f12013-08-20 11:48:36 +0200726/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000727
Paul Bakker33b43f12013-08-20 11:48:36 +0200728/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +0100729void mpi_cmp_mpi( char * input_X, char * input_Y,
730 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +0000731{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200732 mbedtls_mpi X, Y;
733 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000734
Werner Lewis19b4cd82022-07-07 11:02:27 +0100735 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
736 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200737 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +0000738
Paul Bakkerbd51b262014-07-10 15:26:12 +0200739exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200740 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +0000741}
Paul Bakker33b43f12013-08-20 11:48:36 +0200742/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +0000743
Paul Bakker33b43f12013-08-20 11:48:36 +0200744/* BEGIN_CASE */
Gilles Peskinec5772a12022-10-09 21:14:09 +0200745void mpi_core_lt_ct( char *input_X, char *input_Y, int exp_ret )
Janos Follath23bdeca2022-07-22 18:24:06 +0100746{
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200747 mbedtls_mpi_uint *X = NULL;
748 size_t X_limbs;
749 mbedtls_mpi_uint *Y = NULL;
750 size_t Y_limbs;
751 int ret;
Janos Follath23bdeca2022-07-22 18:24:06 +0100752
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200753 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
754 TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &Y, &Y_limbs, input_Y ) );
Janos Follath23bdeca2022-07-22 18:24:06 +0100755
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200756 /* We need two same-length limb arrays */
757 TEST_EQUAL( X_limbs, Y_limbs );
Janos Follath23bdeca2022-07-22 18:24:06 +0100758
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200759 TEST_CF_SECRET( X, X_limbs * sizeof( mbedtls_mpi_uint ) );
760 TEST_CF_SECRET( Y, X_limbs * sizeof( mbedtls_mpi_uint ) );
Janos Follath23bdeca2022-07-22 18:24:06 +0100761
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200762 ret = mbedtls_mpi_core_lt_ct( X, Y, X_limbs );
Janos Follath494a6d22022-08-22 09:36:17 +0100763 TEST_EQUAL( ret, exp_ret );
Janos Follath23bdeca2022-07-22 18:24:06 +0100764
765exit:
Gilles Peskine5bbdfce2022-09-20 21:39:25 +0200766 mbedtls_free( X );
767 mbedtls_free( Y );
Janos Follath23bdeca2022-07-22 18:24:06 +0100768}
769/* END_CASE */
770
771/* BEGIN_CASE */
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200772void mpi_core_cond_assign( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200773 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200774 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200775{
Gabor Mezeia7584882022-09-27 13:18:02 +0200776 mbedtls_mpi_uint *X = NULL;
777 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200778 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
779 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200780 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200781 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
782 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
783 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200784
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200785 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200786 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200787
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200788 ASSERT_ALLOC( X, limbs );
789 ASSERT_ALLOC( Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200790
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200791 TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs, input_X->x, input_X->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200792 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200793
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200794 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs, input_Y->x, input_Y->len )
Gabor Mezei027d6962022-09-16 17:16:27 +0200795 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200796
Gabor Mezei821d1512022-09-27 12:41:28 +0200797 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200798 TEST_CF_SECRET( X, bytes );
799 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200800
Gabor Mezei02e5d432022-10-03 16:45:11 +0200801 mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200802
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200803 TEST_CF_PUBLIC( X, bytes );
804 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200805
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200806 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200807
Gabor Mezei821d1512022-09-27 12:41:28 +0200808 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200809 TEST_CF_SECRET( X, bytes );
810 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200811
Gabor Mezei02e5d432022-10-03 16:45:11 +0200812 mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 1 );
Gabor Mezei821d1512022-09-27 12:41:28 +0200813
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200814 TEST_CF_PUBLIC( X, bytes );
815 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200816
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200817 /* Check if the given length is copied even it is smaller
Gabor Mezei4dceede2022-10-18 16:44:17 +0200818 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200819 if( copy_limbs < limbs )
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200820 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200821 ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
822 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200823 }
Gabor Mezei02e5d432022-10-03 16:45:11 +0200824 else
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200825 ASSERT_COMPARE( X, bytes, Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200826
827exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200828 mbedtls_free( X );
829 mbedtls_free( Y );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200830}
831/* END_CASE */
832
833/* BEGIN_CASE */
834void mpi_core_cond_swap( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200835 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200836 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200837{
Gabor Mezeia7584882022-09-27 13:18:02 +0200838 mbedtls_mpi_uint *tmp_X = NULL;
839 mbedtls_mpi_uint *tmp_Y = NULL;
840 mbedtls_mpi_uint *X = NULL;
841 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200842 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
843 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200844 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200845 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
846 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
847 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200848
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200849 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200850 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200851
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200852 ASSERT_ALLOC( tmp_X, limbs );
853 ASSERT_ALLOC( tmp_Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200854
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200855 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200856 input_X->x, input_X->len )
857 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200858 ASSERT_ALLOC( X, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200859 memcpy( X, tmp_X, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200860
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200861 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200862 input_Y->x, input_Y->len )
863 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200864 ASSERT_ALLOC( Y, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200865 memcpy( Y, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200866
Gabor Mezei821d1512022-09-27 12:41:28 +0200867 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200868 TEST_CF_SECRET( X, bytes );
869 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200870
Gabor Mezei02e5d432022-10-03 16:45:11 +0200871 mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200872
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200873 TEST_CF_PUBLIC( X, bytes );
874 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200875
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200876 ASSERT_COMPARE( X, bytes, tmp_X, bytes );
877 ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200878
Gabor Mezei821d1512022-09-27 12:41:28 +0200879 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200880 TEST_CF_SECRET( X, bytes );
881 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200882
Gabor Mezei02e5d432022-10-03 16:45:11 +0200883 mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 1 );
Gabor Mezei821d1512022-09-27 12:41:28 +0200884
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200885 TEST_CF_PUBLIC( X, bytes );
886 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200887
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200888 /* Check if the given length is copied even it is smaller
889 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200890 if( copy_limbs < limbs )
Gabor Mezei02e5d432022-10-03 16:45:11 +0200891 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200892 ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
893 ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
894 TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
895 TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
896 TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
897 TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200898 }
899 else
900 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200901 ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
902 ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200903 }
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200904
905exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200906 mbedtls_free( tmp_X );
907 mbedtls_free( tmp_Y );
908 mbedtls_free( X );
909 mbedtls_free( Y );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200910}
911/* END_CASE */
912
913/* BEGIN_CASE */
914void mpi_mod_raw_cond_assign( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200915 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200916 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200917{
Gabor Mezeia7584882022-09-27 13:18:02 +0200918 mbedtls_mpi_uint *X = NULL;
919 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200920 mbedtls_mpi_uint *buff_m = NULL;
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200921 mbedtls_mpi_mod_modulus m;
Gabor Mezeif5ca7262022-09-30 14:28:26 +0200922 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
923 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200924 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200925 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
926 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
927 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200928
Gabor Mezeid71eb0c2022-10-10 13:09:04 +0200929 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +0200930 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200931
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200932 ASSERT_ALLOC( X, limbs );
933 ASSERT_ALLOC( Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +0200934
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +0200935 ASSERT_ALLOC( buff_m, limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200936 mbedtls_mpi_mod_modulus_init( &m );
937 TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
Gabor Mezei02e5d432022-10-03 16:45:11 +0200938 &m, buff_m, copy_limbs,
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200939 MBEDTLS_MPI_MOD_EXT_REP_BE,
940 MBEDTLS_MPI_MOD_REP_MONTGOMERY )
941 == 0 );
942
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200943 TEST_ASSERT( mbedtls_mpi_core_read_be( X, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200944 input_X->x, input_X->len )
945 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200946
Gabor Mezei6546a6c2022-09-30 14:55:16 +0200947 TEST_ASSERT( mbedtls_mpi_core_read_be( Y, limbs,
Gabor Mezei027d6962022-09-16 17:16:27 +0200948 input_Y->x, input_Y->len )
949 == 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200950
Gabor Mezei821d1512022-09-27 12:41:28 +0200951 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200952 TEST_CF_SECRET( X, bytes );
953 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200954
Gabor Mezei821d1512022-09-27 12:41:28 +0200955 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200956
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200957 TEST_CF_PUBLIC( X, bytes );
958 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200959
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200960 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200961
Gabor Mezei821d1512022-09-27 12:41:28 +0200962 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200963 TEST_CF_SECRET( X, bytes );
964 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200965
966 mbedtls_mpi_mod_raw_cond_assign( X, Y, &m, 1 );
967
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200968 TEST_CF_PUBLIC( X, bytes );
969 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +0200970
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200971 /* Check if the given length is copied even it is smaller
972 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +0200973 if( copy_limbs <limbs )
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200974 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200975 ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
976 TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
Gabor Mezeia67a1a32022-10-10 15:25:59 +0200977 }
Gabor Mezei02e5d432022-10-03 16:45:11 +0200978 else
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200979 ASSERT_COMPARE( X, bytes, Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200980
981exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +0200982 mbedtls_free( X );
983 mbedtls_free( Y );
984
985 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200986 mbedtls_free( buff_m );
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200987}
988/* END_CASE */
989
990/* BEGIN_CASE */
991void mpi_mod_raw_cond_swap( data_t * input_X,
Gabor Mezei02e5d432022-10-03 16:45:11 +0200992 data_t * input_Y,
Gabor Mezeiffb4aa02022-10-14 16:39:04 +0200993 int input_bytes )
Gabor Mezeib27b1c52022-09-12 16:36:48 +0200994{
Gabor Mezeia7584882022-09-27 13:18:02 +0200995 mbedtls_mpi_uint *tmp_X = NULL;
996 mbedtls_mpi_uint *tmp_Y = NULL;
997 mbedtls_mpi_uint *X = NULL;
998 mbedtls_mpi_uint *Y = NULL;
Gabor Mezeiec5685f2022-09-30 14:41:13 +0200999 mbedtls_mpi_uint *buff_m = NULL;
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001000 mbedtls_mpi_mod_modulus m;
Gabor Mezeif5ca7262022-09-30 14:28:26 +02001001 size_t limbs_X = CHARS_TO_LIMBS( input_X->len );
1002 size_t limbs_Y = CHARS_TO_LIMBS( input_Y->len );
Gabor Mezei6546a6c2022-09-30 14:55:16 +02001003 size_t limbs = limbs_X;
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001004 size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
1005 size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
1006 size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001007
Gabor Mezeid71eb0c2022-10-10 13:09:04 +02001008 TEST_EQUAL( limbs_X, limbs_Y );
Gabor Mezei02e5d432022-10-03 16:45:11 +02001009 TEST_ASSERT( copy_limbs <= limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001010
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +02001011 ASSERT_ALLOC( tmp_X, limbs );
1012 ASSERT_ALLOC( tmp_Y, limbs );
Gabor Mezeia7584882022-09-27 13:18:02 +02001013
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +02001014 ASSERT_ALLOC( buff_m, copy_limbs );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001015 mbedtls_mpi_mod_modulus_init( &m );
1016 TEST_ASSERT( mbedtls_mpi_mod_modulus_setup(
Gabor Mezei02e5d432022-10-03 16:45:11 +02001017 &m, buff_m, copy_limbs,
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001018 MBEDTLS_MPI_MOD_EXT_REP_BE,
1019 MBEDTLS_MPI_MOD_REP_MONTGOMERY )
1020 == 0 );
1021
Gabor Mezei6546a6c2022-09-30 14:55:16 +02001022 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_X, limbs, input_X->x, input_X->len )
Gabor Mezei027d6962022-09-16 17:16:27 +02001023 == 0 );
Gabor Mezei8bcd7cc2022-10-14 16:18:10 +02001024 ASSERT_ALLOC( X, limbs );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001025 memcpy( X, tmp_X, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001026
Gabor Mezei6546a6c2022-09-30 14:55:16 +02001027 TEST_ASSERT( mbedtls_mpi_core_read_be( tmp_Y, limbs, input_Y->x, input_Y->len )
Gabor Mezei027d6962022-09-16 17:16:27 +02001028 == 0 );
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001029 ASSERT_ALLOC( Y, bytes );
1030 memcpy( Y, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001031
Gabor Mezei821d1512022-09-27 12:41:28 +02001032 /* condition is false */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001033 TEST_CF_SECRET( X, bytes );
1034 TEST_CF_SECRET( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001035
Gabor Mezei821d1512022-09-27 12:41:28 +02001036 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 0 );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001037
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001038 TEST_CF_PUBLIC( X, bytes );
1039 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001040
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001041 ASSERT_COMPARE( X, bytes, tmp_X, bytes );
1042 ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001043
Gabor Mezei821d1512022-09-27 12:41:28 +02001044 /* condition is true */
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001045 TEST_CF_SECRET( X, bytes );
1046 TEST_CF_SECRET( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +02001047
1048 mbedtls_mpi_mod_raw_cond_swap( X, Y, &m, 1 );
1049
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001050 TEST_CF_PUBLIC( X, bytes );
1051 TEST_CF_PUBLIC( Y, bytes );
Gabor Mezei821d1512022-09-27 12:41:28 +02001052
Gabor Mezeia67a1a32022-10-10 15:25:59 +02001053 /* Check if the given length is copied even it is smaller
1054 than the length of the given MPIs. */
Gabor Mezei0c74e082022-10-17 16:09:58 +02001055 if( copy_limbs < limbs )
Gabor Mezei02e5d432022-10-03 16:45:11 +02001056 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001057 ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
1058 ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
1059 TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
1060 TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
1061 TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
1062 TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
Gabor Mezei02e5d432022-10-03 16:45:11 +02001063 }
1064 else
1065 {
Gabor Mezeiffb4aa02022-10-14 16:39:04 +02001066 ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
1067 ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
Gabor Mezei02e5d432022-10-03 16:45:11 +02001068 }
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001069
1070exit:
Gabor Mezei8b05e3b2022-09-28 12:37:02 +02001071 mbedtls_free( tmp_X );
1072 mbedtls_free( tmp_Y );
1073 mbedtls_free( X );
1074 mbedtls_free( Y );
1075
1076 mbedtls_mpi_mod_modulus_free( &m );
Gabor Mezeiec5685f2022-09-30 14:41:13 +02001077 mbedtls_free( buff_m );
Gabor Mezeib27b1c52022-09-12 16:36:48 +02001078}
1079/* END_CASE */
1080
1081/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001082void mpi_lt_mpi_ct( int size_X, char * input_X,
1083 int size_Y, char * input_Y,
1084 int input_ret, int input_err )
Janos Follath385d5b82019-09-11 16:07:14 +01001085{
Gilles Peskine0deccf12020-09-02 15:18:07 +02001086 unsigned ret = -1;
Janos Follath0e5532d2019-10-11 14:21:53 +01001087 unsigned input_uret = input_ret;
Janos Follath385d5b82019-09-11 16:07:14 +01001088 mbedtls_mpi X, Y;
1089 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
1090
Werner Lewis19b4cd82022-07-07 11:02:27 +01001091 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1092 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +01001093
Gilles Peskine9018b112020-01-21 16:30:53 +01001094 TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
1095 TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
Janos Follath385d5b82019-09-11 16:07:14 +01001096
Janos Follath0e5532d2019-10-11 14:21:53 +01001097 TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
Janos Follath385d5b82019-09-11 16:07:14 +01001098 if( input_err == 0 )
Janos Follath0e5532d2019-10-11 14:21:53 +01001099 TEST_ASSERT( ret == input_uret );
Janos Follath385d5b82019-09-11 16:07:14 +01001100
1101exit:
1102 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
1103}
1104/* END_CASE */
1105
1106/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001107void mpi_cmp_abs( char * input_X, char * input_Y,
1108 int input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001109{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001110 mbedtls_mpi X, Y;
1111 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +00001112
Werner Lewis19b4cd82022-07-07 11:02:27 +01001113 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1114 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001115 TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001116
Paul Bakkerbd51b262014-07-10 15:26:12 +02001117exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001118 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
Paul Bakker367dae42009-06-28 21:50:27 +00001119}
Paul Bakker33b43f12013-08-20 11:48:36 +02001120/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001121
Paul Bakker33b43f12013-08-20 11:48:36 +02001122/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001123void mpi_copy( char *src_hex, char *dst_hex )
Paul Bakker367dae42009-06-28 21:50:27 +00001124{
Gilles Peskined0722f82021-06-10 23:00:33 +02001125 mbedtls_mpi src, dst, ref;
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001126 mbedtls_mpi_init( &src );
1127 mbedtls_mpi_init( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +02001128 mbedtls_mpi_init( &ref );
Paul Bakker367dae42009-06-28 21:50:27 +00001129
Werner Lewis19b4cd82022-07-07 11:02:27 +01001130 TEST_ASSERT( mbedtls_test_read_mpi( &src, src_hex ) == 0 );
1131 TEST_ASSERT( mbedtls_test_read_mpi( &ref, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +02001132
1133 /* mbedtls_mpi_copy() */
Werner Lewis19b4cd82022-07-07 11:02:27 +01001134 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001135 TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001136 TEST_ASSERT( sign_is_valid( &dst ) );
1137 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001138
Gilles Peskined0722f82021-06-10 23:00:33 +02001139 /* mbedtls_mpi_safe_cond_assign(), assignment done */
1140 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001141 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +02001142 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
1143 TEST_ASSERT( sign_is_valid( &dst ) );
1144 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
1145
1146 /* mbedtls_mpi_safe_cond_assign(), assignment not done */
1147 mbedtls_mpi_free( &dst );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001148 TEST_ASSERT( mbedtls_test_read_mpi( &dst, dst_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +02001149 TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
1150 TEST_ASSERT( sign_is_valid( &dst ) );
1151 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
1152
Paul Bakkerbd51b262014-07-10 15:26:12 +02001153exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001154 mbedtls_mpi_free( &src );
1155 mbedtls_mpi_free( &dst );
Gilles Peskined0722f82021-06-10 23:00:33 +02001156 mbedtls_mpi_free( &ref );
Gilles Peskine7428b452020-01-20 21:01:51 +01001157}
1158/* END_CASE */
1159
1160/* BEGIN_CASE */
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001161void mpi_copy_self( char *input_X )
Gilles Peskine7428b452020-01-20 21:01:51 +01001162{
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001163 mbedtls_mpi X, A;
1164 mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001165 mbedtls_mpi_init( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +00001166
Werner Lewis19b4cd82022-07-07 11:02:27 +01001167 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001168 TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001169
Werner Lewis19b4cd82022-07-07 11:02:27 +01001170 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_X ) == 0 );
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001171 TEST_ASSERT( sign_is_valid( &X ) );
1172 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001173
Paul Bakkerbd51b262014-07-10 15:26:12 +02001174exit:
Gilles Peskine90ec8e82021-06-10 15:17:30 +02001175 mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001176 mbedtls_mpi_free( &X );
Paul Bakkere896fea2009-07-06 06:40:23 +00001177}
Paul Bakker33b43f12013-08-20 11:48:36 +02001178/* END_CASE */
Paul Bakkere896fea2009-07-06 06:40:23 +00001179
Paul Bakker33b43f12013-08-20 11:48:36 +02001180/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001181void mpi_swap( char *X_hex, char *Y_hex )
Gilles Peskinefc1eeef2021-06-10 22:29:57 +02001182{
1183 mbedtls_mpi X, Y, X0, Y0;
1184 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
1185 mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
1186
Werner Lewis19b4cd82022-07-07 11:02:27 +01001187 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
1188 TEST_ASSERT( mbedtls_test_read_mpi( &Y0, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +02001189
Gilles Peskined0722f82021-06-10 23:00:33 +02001190 /* mbedtls_mpi_swap() */
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +01001191 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
1192 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +02001193 mbedtls_mpi_swap( &X, &Y );
1194 TEST_ASSERT( sign_is_valid( &X ) );
1195 TEST_ASSERT( sign_is_valid( &Y ) );
1196 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
1197 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
1198
Gilles Peskined0722f82021-06-10 23:00:33 +02001199 /* mbedtls_mpi_safe_cond_swap(), swap done */
1200 mbedtls_mpi_free( &X );
1201 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +01001202 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
1203 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +02001204 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
1205 TEST_ASSERT( sign_is_valid( &X ) );
1206 TEST_ASSERT( sign_is_valid( &Y ) );
1207 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
1208 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
1209
1210 /* mbedtls_mpi_safe_cond_swap(), swap not done */
1211 mbedtls_mpi_free( &X );
1212 mbedtls_mpi_free( &Y );
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +01001213 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
1214 TEST_ASSERT( mbedtls_test_read_mpi( &Y, Y_hex ) == 0 );
Gilles Peskined0722f82021-06-10 23:00:33 +02001215 TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
1216 TEST_ASSERT( sign_is_valid( &X ) );
1217 TEST_ASSERT( sign_is_valid( &Y ) );
1218 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
1219 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
1220
Gilles Peskinefc1eeef2021-06-10 22:29:57 +02001221exit:
1222 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
1223 mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
1224}
1225/* END_CASE */
1226
1227/* BEGIN_CASE */
1228void mpi_swap_self( char *X_hex )
1229{
1230 mbedtls_mpi X, X0;
1231 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
1232
Tom Cosgrovec71ca0c2022-09-15 15:38:17 +01001233 TEST_ASSERT( mbedtls_test_read_mpi( &X, X_hex ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001234 TEST_ASSERT( mbedtls_test_read_mpi( &X0, X_hex ) == 0 );
Gilles Peskinefc1eeef2021-06-10 22:29:57 +02001235
1236 mbedtls_mpi_swap( &X, &X );
1237 TEST_ASSERT( sign_is_valid( &X ) );
1238 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
1239
1240exit:
1241 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
1242}
1243/* END_CASE */
1244
1245/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001246void mpi_shrink( int before, int used, int min, int after )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +01001247{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001248 mbedtls_mpi X;
1249 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +01001250
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001251 TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +02001252 if( used > 0 )
1253 {
1254 size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
1255 TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
1256 }
1257 TEST_EQUAL( X.n, (size_t) before );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001258 TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
Gilles Peskinee1091752021-06-15 21:19:18 +02001259 TEST_EQUAL( X.n, (size_t) after );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +01001260
Paul Bakkerbd51b262014-07-10 15:26:12 +02001261exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001262 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +01001263}
1264/* END_CASE */
1265
1266/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001267void mpi_add_mpi( char * input_X, char * input_Y,
1268 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001269{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001270 mbedtls_mpi X, Y, Z, A;
1271 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001272
Werner Lewis19b4cd82022-07-07 11:02:27 +01001273 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1274 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1275 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001276 TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001277 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001278 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001279
Gilles Peskine56f943a2020-07-23 01:18:11 +02001280 /* result == first operand */
1281 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001282 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001283 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001284 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001285
1286 /* result == second operand */
1287 TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001288 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001289 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1290
Paul Bakkerbd51b262014-07-10 15:26:12 +02001291exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001292 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001293}
Paul Bakker33b43f12013-08-20 11:48:36 +02001294/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001295
Paul Bakker33b43f12013-08-20 11:48:36 +02001296/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001297void mpi_add_mpi_inplace( char * input_X, char * input_A )
Janos Follath044a86b2015-10-25 10:58:03 +01001298{
1299 mbedtls_mpi X, A;
1300 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1301
Werner Lewis19b4cd82022-07-07 11:02:27 +01001302 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001303
Werner Lewis19b4cd82022-07-07 11:02:27 +01001304 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001305 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
1306 TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001307 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001308
Werner Lewis19b4cd82022-07-07 11:02:27 +01001309 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath6cbacec2015-10-25 12:29:13 +01001310 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001311 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath6cbacec2015-10-25 12:29:13 +01001312 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1313
Werner Lewis19b4cd82022-07-07 11:02:27 +01001314 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Janos Follath044a86b2015-10-25 10:58:03 +01001315 TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001316 TEST_ASSERT( sign_is_valid( &X ) );
Janos Follath044a86b2015-10-25 10:58:03 +01001317 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1318
1319exit:
1320 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1321}
1322/* END_CASE */
1323
1324
1325/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001326void mpi_add_abs( char * input_X, char * input_Y,
1327 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001328{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001329 mbedtls_mpi X, Y, Z, A;
1330 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001331
Werner Lewis19b4cd82022-07-07 11:02:27 +01001332 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1333 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1334 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001335 TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001336 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001337 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001338
Gilles Peskine56f943a2020-07-23 01:18:11 +02001339 /* result == first operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001340 TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001341 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001342 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001343 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001344
1345 /* result == second operand */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001346 TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001347 TEST_ASSERT( sign_is_valid( &Y ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001348 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001349
Paul Bakkerbd51b262014-07-10 15:26:12 +02001350exit:
Gilles Peskine56f943a2020-07-23 01:18:11 +02001351 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakkerba48cb22009-07-12 11:01:32 +00001352}
Paul Bakker33b43f12013-08-20 11:48:36 +02001353/* END_CASE */
Paul Bakkerba48cb22009-07-12 11:01:32 +00001354
Paul Bakker33b43f12013-08-20 11:48:36 +02001355/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001356void mpi_add_int( char * input_X, int input_Y,
1357 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001358{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001359 mbedtls_mpi X, Z, A;
1360 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001361
Werner Lewis19b4cd82022-07-07 11:02:27 +01001362 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1363 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001364 TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001365 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001366 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001367
Paul Bakkerbd51b262014-07-10 15:26:12 +02001368exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001369 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001370}
Paul Bakker33b43f12013-08-20 11:48:36 +02001371/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001372
Paul Bakker33b43f12013-08-20 11:48:36 +02001373/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001374void mpi_sub_mpi( char * input_X, char * input_Y,
1375 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001376{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001377 mbedtls_mpi X, Y, Z, A;
1378 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001379
Werner Lewis19b4cd82022-07-07 11:02:27 +01001380 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1381 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1382 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001383 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001384 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001385 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001386
Gilles Peskine56f943a2020-07-23 01:18:11 +02001387 /* result == first operand */
1388 TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001389 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001390 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001391 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001392
1393 /* result == second operand */
1394 TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001395 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001396 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1397
Paul Bakkerbd51b262014-07-10 15:26:12 +02001398exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001399 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001400}
Paul Bakker33b43f12013-08-20 11:48:36 +02001401/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001402
Paul Bakker33b43f12013-08-20 11:48:36 +02001403/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001404void mpi_sub_abs( char * input_X, char * input_Y,
1405 char * input_A, int sub_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001406{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001407 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001408 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001409 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001410
Werner Lewis19b4cd82022-07-07 11:02:27 +01001411 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1412 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1413 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnarde670f902015-10-30 09:23:19 +01001414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001415 res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001416 TEST_ASSERT( res == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001417 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakker367dae42009-06-28 21:50:27 +00001418 if( res == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001419 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001420
Gilles Peskine56f943a2020-07-23 01:18:11 +02001421 /* result == first operand */
1422 TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001423 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001424 if( sub_result == 0 )
1425 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Werner Lewis19b4cd82022-07-07 11:02:27 +01001426 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001427
1428 /* result == second operand */
1429 TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001430 TEST_ASSERT( sign_is_valid( &Y ) );
Gilles Peskine56f943a2020-07-23 01:18:11 +02001431 if( sub_result == 0 )
1432 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
1433
Paul Bakkerbd51b262014-07-10 15:26:12 +02001434exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001435 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001436}
Paul Bakker33b43f12013-08-20 11:48:36 +02001437/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001438
Paul Bakker33b43f12013-08-20 11:48:36 +02001439/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001440void mpi_sub_int( char * input_X, int input_Y,
1441 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001442{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001443 mbedtls_mpi X, Z, A;
1444 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001445
Werner Lewis19b4cd82022-07-07 11:02:27 +01001446 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1447 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001448 TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001449 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001450 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001451
Paul Bakkerbd51b262014-07-10 15:26:12 +02001452exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001453 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001454}
Paul Bakker33b43f12013-08-20 11:48:36 +02001455/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001456
Paul Bakker33b43f12013-08-20 11:48:36 +02001457/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001458void mpi_mul_mpi( char * input_X, char * input_Y,
1459 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001460{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001461 mbedtls_mpi X, Y, Z, A;
1462 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001463
Werner Lewis19b4cd82022-07-07 11:02:27 +01001464 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1465 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1466 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001467 TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001468 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001469 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001470
Paul Bakkerbd51b262014-07-10 15:26:12 +02001471exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001473}
Paul Bakker33b43f12013-08-20 11:48:36 +02001474/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001475
Paul Bakker33b43f12013-08-20 11:48:36 +02001476/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001477void mpi_mul_int( char * input_X, int input_Y,
1478 char * input_A, char * result_comparison )
Paul Bakker367dae42009-06-28 21:50:27 +00001479{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001480 mbedtls_mpi X, Z, A;
1481 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001482
Werner Lewis19b4cd82022-07-07 11:02:27 +01001483 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1484 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001485 TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001486 TEST_ASSERT( sign_is_valid( &Z ) );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001487 if( strcmp( result_comparison, "==" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001488 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001489 else if( strcmp( result_comparison, "!=" ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001490 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
Paul Bakkerdbd443d2013-08-16 13:38:47 +02001491 else
1492 TEST_ASSERT( "unknown operator" == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001493
Paul Bakkerbd51b262014-07-10 15:26:12 +02001494exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001496}
Paul Bakker33b43f12013-08-20 11:48:36 +02001497/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001498
Paul Bakker33b43f12013-08-20 11:48:36 +02001499/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001500void mpi_div_mpi( char * input_X, char * input_Y,
1501 char * input_A, char * input_B,
1502 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001503{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001504 mbedtls_mpi X, Y, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001505 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001506 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
1507 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001508
Werner Lewis19b4cd82022-07-07 11:02:27 +01001509 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1510 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1511 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1512 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001513 res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001514 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001515 if( res == 0 )
1516 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001517 TEST_ASSERT( sign_is_valid( &Q ) );
1518 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001519 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1520 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001521 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001522
Paul Bakkerbd51b262014-07-10 15:26:12 +02001523exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001524 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
1525 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001526}
Paul Bakker33b43f12013-08-20 11:48:36 +02001527/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001528
Paul Bakker33b43f12013-08-20 11:48:36 +02001529/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001530void mpi_div_int( char * input_X, int input_Y,
1531 char * input_A, char * input_B,
1532 int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001533{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001534 mbedtls_mpi X, Q, R, A, B;
Paul Bakker367dae42009-06-28 21:50:27 +00001535 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001536 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
1537 mbedtls_mpi_init( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001538
Werner Lewis19b4cd82022-07-07 11:02:27 +01001539 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1540 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1541 TEST_ASSERT( mbedtls_test_read_mpi( &B, input_B ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542 res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001543 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001544 if( res == 0 )
1545 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001546 TEST_ASSERT( sign_is_valid( &Q ) );
1547 TEST_ASSERT( sign_is_valid( &R ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001548 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
1549 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001550 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001551
Paul Bakkerbd51b262014-07-10 15:26:12 +02001552exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001553 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
1554 mbedtls_mpi_free( &B );
Paul Bakker367dae42009-06-28 21:50:27 +00001555}
Paul Bakker33b43f12013-08-20 11:48:36 +02001556/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001557
Paul Bakker33b43f12013-08-20 11:48:36 +02001558/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001559void mpi_mod_mpi( char * input_X, char * input_Y,
1560 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001561{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001562 mbedtls_mpi X, Y, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001563 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001564 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001565
Werner Lewis19b4cd82022-07-07 11:02:27 +01001566 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1567 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1568 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001569 res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001570 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001571 if( res == 0 )
1572 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001573 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001574 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001575 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001576
Paul Bakkerbd51b262014-07-10 15:26:12 +02001577exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001578 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001579}
Paul Bakker33b43f12013-08-20 11:48:36 +02001580/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001581
Paul Bakker33b43f12013-08-20 11:48:36 +02001582/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001583void mpi_mod_int( char * input_X, int input_Y,
1584 int input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001585{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001586 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001587 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001588 mbedtls_mpi_uint r;
1589 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001590
Werner Lewis19b4cd82022-07-07 11:02:27 +01001591 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001592 res = mbedtls_mpi_mod_int( &r, &X, input_Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001593 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001594 if( res == 0 )
1595 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001596 TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
Paul Bakker367dae42009-06-28 21:50:27 +00001597 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001598
Paul Bakkerbd51b262014-07-10 15:26:12 +02001599exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001600 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001601}
Paul Bakker33b43f12013-08-20 11:48:36 +02001602/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001603
Paul Bakker33b43f12013-08-20 11:48:36 +02001604/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001605void mpi_exp_mod( char * input_A, char * input_E,
1606 char * input_N, char * input_X,
1607 int exp_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001608{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001609 mbedtls_mpi A, E, N, RR, Z, X;
Paul Bakker367dae42009-06-28 21:50:27 +00001610 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001611 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1612 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001613
Werner Lewis19b4cd82022-07-07 11:02:27 +01001614 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
1615 TEST_ASSERT( mbedtls_test_read_mpi( &E, input_E ) == 0 );
1616 TEST_ASSERT( mbedtls_test_read_mpi( &N, input_N ) == 0 );
1617 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001618
Gilles Peskine342f71b2021-06-09 18:31:35 +02001619 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001620 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001621 if( res == 0 )
1622 {
1623 TEST_ASSERT( sign_is_valid( &Z ) );
1624 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1625 }
1626
1627 /* Now test again with the speed-up parameter supplied as an output. */
1628 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001629 TEST_ASSERT( res == exp_result );
Gilles Peskine342f71b2021-06-09 18:31:35 +02001630 if( res == 0 )
1631 {
1632 TEST_ASSERT( sign_is_valid( &Z ) );
1633 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1634 }
1635
1636 /* Now test again with the speed-up parameter supplied in calculated form. */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001637 res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
Gilles Peskine722c62c2021-06-15 21:55:05 +02001638 TEST_ASSERT( res == exp_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001639 if( res == 0 )
1640 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001641 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001642 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001643 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001644
Paul Bakkerbd51b262014-07-10 15:26:12 +02001645exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001646 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1647 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001648}
Paul Bakker33b43f12013-08-20 11:48:36 +02001649/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001650
Paul Bakker33b43f12013-08-20 11:48:36 +02001651/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001652void mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1653 char * input_RR, int exp_result )
Chris Jonesd10b3312020-12-02 10:41:50 +00001654{
1655 mbedtls_mpi A, E, N, RR, Z;
1656 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1657 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1658
Chris Jonesaa850cd2020-12-03 11:35:41 +00001659 /* Set A to 2^(A_bytes - 1) + 1 */
Chris Jonesd10b3312020-12-02 10:41:50 +00001660 TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001661 TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001662 TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001663
1664 /* Set E to 2^(E_bytes - 1) + 1 */
1665 TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1666 TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001667 TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
Chris Jonesaa850cd2020-12-03 11:35:41 +00001668
1669 /* Set N to 2^(N_bytes - 1) + 1 */
1670 TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1671 TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001672 TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1673
1674 if( strlen( input_RR ) )
Werner Lewis19b4cd82022-07-07 11:02:27 +01001675 TEST_ASSERT( mbedtls_test_read_mpi( &RR, input_RR ) == 0 );
Chris Jonesd10b3312020-12-02 10:41:50 +00001676
Chris Jonesaa850cd2020-12-03 11:35:41 +00001677 TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
Chris Jonesd10b3312020-12-02 10:41:50 +00001678
1679exit:
1680 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1681 mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1682}
1683/* END_CASE */
1684
1685/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001686void mpi_inv_mod( char * input_X, char * input_Y,
1687 char * input_A, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001688{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001689 mbedtls_mpi X, Y, Z, A;
Paul Bakker367dae42009-06-28 21:50:27 +00001690 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001691 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001692
Werner Lewis19b4cd82022-07-07 11:02:27 +01001693 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1694 TEST_ASSERT( mbedtls_test_read_mpi( &Y, input_Y ) == 0 );
1695 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001696 res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
Paul Bakker33b43f12013-08-20 11:48:36 +02001697 TEST_ASSERT( res == div_result );
Paul Bakker367dae42009-06-28 21:50:27 +00001698 if( res == 0 )
1699 {
Gilles Peskinedffc7102021-06-10 15:34:15 +02001700 TEST_ASSERT( sign_is_valid( &Z ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001701 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
Paul Bakker367dae42009-06-28 21:50:27 +00001702 }
Paul Bakker6c591fa2011-05-05 11:49:20 +00001703
Paul Bakkerbd51b262014-07-10 15:26:12 +02001704exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001705 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001706}
Paul Bakker33b43f12013-08-20 11:48:36 +02001707/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001708
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001709/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001710void mpi_is_prime( char * input_X, int div_result )
Paul Bakker367dae42009-06-28 21:50:27 +00001711{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001712 mbedtls_mpi X;
Paul Bakker367dae42009-06-28 21:50:27 +00001713 int res;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001714 mbedtls_mpi_init( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001715
Werner Lewis19b4cd82022-07-07 11:02:27 +01001716 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
Ronald Cron351f0ee2020-06-10 12:12:18 +02001717 res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
Paul Bakker33b43f12013-08-20 11:48:36 +02001718 TEST_ASSERT( res == div_result );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001719
Paul Bakkerbd51b262014-07-10 15:26:12 +02001720exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001721 mbedtls_mpi_free( &X );
Paul Bakker367dae42009-06-28 21:50:27 +00001722}
Paul Bakker33b43f12013-08-20 11:48:36 +02001723/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001724
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001725/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001726void mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1727 int chunk_len, int rounds )
Janos Follath64eca052018-09-05 17:04:49 +01001728{
1729 mbedtls_mpi X;
1730 int res;
1731 mbedtls_test_mpi_random rand;
1732
1733 mbedtls_mpi_init( &X );
1734 rand.data = witnesses;
1735 rand.pos = 0;
1736 rand.chunk_len = chunk_len;
1737
1738 TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
Darryl Greenac2ead02018-10-02 15:30:39 +01001739 res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1740 mbedtls_test_mpi_miller_rabin_determinizer,
1741 &rand );
1742 TEST_ASSERT( res == 0 );
1743
1744 rand.data = witnesses;
1745 rand.pos = 0;
1746 rand.chunk_len = chunk_len;
1747
Janos Follatha0b67c22018-09-18 14:48:23 +01001748 res = mbedtls_mpi_is_prime_ext( &X, rounds,
1749 mbedtls_test_mpi_miller_rabin_determinizer,
Janos Follath64eca052018-09-05 17:04:49 +01001750 &rand );
Darryl Greenac2ead02018-10-02 15:30:39 +01001751 TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Janos Follath64eca052018-09-05 17:04:49 +01001752
1753exit:
1754 mbedtls_mpi_free( &X );
1755}
1756/* END_CASE */
1757
1758/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001759void mpi_gen_prime( int bits, int flags, int ref_ret )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001760{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001761 mbedtls_mpi X;
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001762 int my_ret;
1763
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001764 mbedtls_mpi_init( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001765
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001766 my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1767 mbedtls_test_rnd_std_rand, NULL );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001768 TEST_ASSERT( my_ret == ref_ret );
1769
1770 if( ref_ret == 0 )
1771 {
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001772 size_t actual_bits = mbedtls_mpi_bitlen( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001773
1774 TEST_ASSERT( actual_bits >= (size_t) bits );
1775 TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001776 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001777
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001778 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1779 mbedtls_test_rnd_std_rand,
1780 NULL ) == 0 );
Janos Follatha3cb7eb2018-08-14 15:31:54 +01001781 if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001782 {
Hanno Beckerd4d60572018-01-10 07:12:01 +00001783 /* X = ( X - 1 ) / 2 */
1784 TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
Ronald Cron6c5bd7f2020-06-10 14:08:26 +02001785 TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1786 mbedtls_test_rnd_std_rand,
1787 NULL ) == 0 );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001788 }
1789 }
1790
Paul Bakkerbd51b262014-07-10 15:26:12 +02001791exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001792 mbedtls_mpi_free( &X );
Manuel Pégourié-Gonnard15f58a82014-06-16 17:12:40 +02001793}
1794/* END_CASE */
1795
Paul Bakker33b43f12013-08-20 11:48:36 +02001796/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001797void mpi_shift_l( char * input_X, int shift_X,
1798 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001799{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001800 mbedtls_mpi X, A;
1801 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001802
Werner Lewis19b4cd82022-07-07 11:02:27 +01001803 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1804 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001805 TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001806 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001807 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001808
Paul Bakkerbd51b262014-07-10 15:26:12 +02001809exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001810 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001811}
Paul Bakker33b43f12013-08-20 11:48:36 +02001812/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001813
Paul Bakker33b43f12013-08-20 11:48:36 +02001814/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01001815void mpi_shift_r( char * input_X, int shift_X,
1816 char * input_A )
Paul Bakker367dae42009-06-28 21:50:27 +00001817{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001818 mbedtls_mpi X, A;
1819 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001820
Werner Lewis19b4cd82022-07-07 11:02:27 +01001821 TEST_ASSERT( mbedtls_test_read_mpi( &X, input_X ) == 0 );
1822 TEST_ASSERT( mbedtls_test_read_mpi( &A, input_A ) == 0 );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001823 TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001824 TEST_ASSERT( sign_is_valid( &X ) );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001825 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001826
Paul Bakkerbd51b262014-07-10 15:26:12 +02001827exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001828 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
Paul Bakker367dae42009-06-28 21:50:27 +00001829}
Paul Bakker33b43f12013-08-20 11:48:36 +02001830/* END_CASE */
Paul Bakker367dae42009-06-28 21:50:27 +00001831
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001832/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001833void mpi_fill_random( int wanted_bytes, int rng_bytes,
1834 int before, int expected_ret )
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001835{
1836 mbedtls_mpi X;
1837 int ret;
1838 size_t bytes_left = rng_bytes;
1839 mbedtls_mpi_init( &X );
1840
Gilles Peskine422e8672021-04-02 00:02:27 +02001841 if( before != 0 )
1842 {
1843 /* Set X to sign(before) * 2^(|before|-1) */
1844 TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1845 if( before < 0 )
1846 before = - before;
1847 TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1848 }
1849
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001850 ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1851 f_rng_bytes_left, &bytes_left );
1852 TEST_ASSERT( ret == expected_ret );
1853
1854 if( expected_ret == 0 )
1855 {
1856 /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1857 * as a big-endian representation of the number. We know when
1858 * our RNG function returns null bytes, so we know how many
1859 * leading zero bytes the number has. */
1860 size_t leading_zeros = 0;
1861 if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1862 leading_zeros = 1;
1863 TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1864 (size_t) wanted_bytes );
1865 TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
Gilles Peskinedffc7102021-06-10 15:34:15 +02001866 TEST_ASSERT( sign_is_valid( &X ) );
Gilles Peskine3cb1e292020-11-25 15:37:20 +01001867 }
1868
1869exit:
1870 mbedtls_mpi_free( &X );
1871}
1872/* END_CASE */
1873
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001874/* BEGIN_CASE */
1875void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1876{
1877 /* Generate numbers in the range 1..bound-1. Do it iterations times.
1878 * This function assumes that the value of bound is at least 2 and
1879 * that iterations is large enough that a one-in-2^iterations chance
1880 * effectively never occurs.
1881 */
1882
1883 mbedtls_mpi upper_bound;
1884 size_t n_bits;
1885 mbedtls_mpi result;
1886 size_t b;
1887 /* If upper_bound is small, stats[b] is the number of times the value b
1888 * has been generated. Otherwise stats[b] is the number of times a
1889 * value with bit b set has been generated. */
1890 size_t *stats = NULL;
1891 size_t stats_len;
1892 int full_stats;
1893 size_t i;
1894
1895 mbedtls_mpi_init( &upper_bound );
1896 mbedtls_mpi_init( &result );
1897
1898 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1899 bound_bytes->x, bound_bytes->len ) );
1900 n_bits = mbedtls_mpi_bitlen( &upper_bound );
1901 /* Consider a bound "small" if it's less than 2^5. This value is chosen
1902 * to be small enough that the probability of missing one value is
1903 * negligible given the number of iterations. It must be less than
1904 * 256 because some of the code below assumes that "small" values
1905 * fit in a byte. */
1906 if( n_bits <= 5 )
1907 {
1908 full_stats = 1;
1909 stats_len = bound_bytes->x[bound_bytes->len - 1];
1910 }
1911 else
1912 {
1913 full_stats = 0;
1914 stats_len = n_bits;
1915 }
1916 ASSERT_ALLOC( stats, stats_len );
1917
1918 for( i = 0; i < (size_t) iterations; i++ )
1919 {
1920 mbedtls_test_set_step( i );
1921 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1922 mbedtls_test_rnd_std_rand, NULL ) );
1923
Gilles Peskinedffc7102021-06-10 15:34:15 +02001924 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001925 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1926 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1927 if( full_stats )
1928 {
1929 uint8_t value;
1930 TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1931 TEST_ASSERT( value < stats_len );
1932 ++stats[value];
1933 }
1934 else
1935 {
1936 for( b = 0; b < n_bits; b++ )
1937 stats[b] += mbedtls_mpi_get_bit( &result, b );
1938 }
1939 }
1940
1941 if( full_stats )
1942 {
Gilles Peskined463edf2021-04-13 20:45:05 +02001943 for( b = min; b < stats_len; b++ )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001944 {
1945 mbedtls_test_set_step( 1000000 + b );
1946 /* Assert that each value has been reached at least once.
1947 * This is almost guaranteed if the iteration count is large
1948 * enough. This is a very crude way of checking the distribution.
1949 */
1950 TEST_ASSERT( stats[b] > 0 );
1951 }
1952 }
1953 else
1954 {
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001955 int statistically_safe_all_the_way =
1956 is_significantly_above_a_power_of_2( bound_bytes );
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001957 for( b = 0; b < n_bits; b++ )
1958 {
1959 mbedtls_test_set_step( 1000000 + b );
1960 /* Assert that each bit has been set in at least one result and
1961 * clear in at least one result. Provided that iterations is not
1962 * too small, it would be extremely unlikely for this not to be
1963 * the case if the results are uniformly distributed.
1964 *
1965 * As an exception, the top bit may legitimately never be set
1966 * if bound is a power of 2 or only slightly above.
1967 */
Gilles Peskineceefe5d2021-06-02 21:24:04 +02001968 if( statistically_safe_all_the_way || b != n_bits - 1 )
Gilles Peskine02ac93a2021-03-29 22:02:55 +02001969 {
1970 TEST_ASSERT( stats[b] > 0 );
1971 }
1972 TEST_ASSERT( stats[b] < (size_t) iterations );
1973 }
1974 }
1975
1976exit:
1977 mbedtls_mpi_free( &upper_bound );
1978 mbedtls_mpi_free( &result );
1979 mbedtls_free( stats );
1980}
1981/* END_CASE */
1982
Gilles Peskine1e918f42021-03-29 22:14:51 +02001983/* BEGIN_CASE */
Gilles Peskine422e8672021-04-02 00:02:27 +02001984void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02001985{
1986 mbedtls_mpi upper_bound;
1987 mbedtls_mpi result;
1988
1989 mbedtls_mpi_init( &upper_bound );
1990 mbedtls_mpi_init( &result );
1991
Gilles Peskine422e8672021-04-02 00:02:27 +02001992 if( before != 0 )
1993 {
1994 /* Set result to sign(before) * 2^(|before|-1) */
1995 TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1996 if( before < 0 )
1997 before = - before;
1998 TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1999 }
2000
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02002001 TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
2002 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
2003 bound_bytes->x, bound_bytes->len ) );
2004 TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
2005 mbedtls_test_rnd_std_rand, NULL ) );
Gilles Peskinedffc7102021-06-10 15:34:15 +02002006 TEST_ASSERT( sign_is_valid( &result ) );
Gilles Peskine1a7df4e2021-04-01 15:57:18 +02002007 TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
2008 TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
2009
2010exit:
2011 mbedtls_mpi_free( &upper_bound );
2012 mbedtls_mpi_free( &result );
2013}
2014/* END_CASE */
2015
2016/* BEGIN_CASE */
Gilles Peskine1e918f42021-03-29 22:14:51 +02002017void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
2018{
2019 mbedtls_mpi upper_bound;
2020 mbedtls_mpi result;
2021 int actual_ret;
2022
2023 mbedtls_mpi_init( &upper_bound );
2024 mbedtls_mpi_init( &result );
2025
2026 TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
2027 bound_bytes->x, bound_bytes->len ) );
2028 actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
2029 mbedtls_test_rnd_std_rand, NULL );
2030 TEST_EQUAL( expected_ret, actual_ret );
2031
2032exit:
2033 mbedtls_mpi_free( &upper_bound );
2034 mbedtls_mpi_free( &result );
2035}
2036/* END_CASE */
2037
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002038/* BEGIN_CASE */
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002039void mpi_core_add_if( char * input_A, char * input_B,
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002040 char * input_S4, int carry4,
2041 char * input_S8, int carry8 )
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002042{
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002043 mbedtls_mpi S4, S8, A, B;
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002044 mbedtls_mpi_uint *a = NULL; /* first value to add */
2045 mbedtls_mpi_uint *b = NULL; /* second value to add */
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002046 mbedtls_mpi_uint *sum = NULL;
2047 mbedtls_mpi_uint *d = NULL; /* destination - the in/out first operand */
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002048
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002049 mbedtls_mpi_init( &A );
2050 mbedtls_mpi_init( &B );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002051 mbedtls_mpi_init( &S4 );
2052 mbedtls_mpi_init( &S8 );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002053
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002054 TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
2055 TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002056 TEST_EQUAL( 0, mbedtls_test_read_mpi( &S4, input_S4 ) );
2057 TEST_EQUAL( 0, mbedtls_test_read_mpi( &S8, input_S8 ) );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002058
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002059 /* We only need to work with one of (S4, carry4) or (S8, carry8) depending
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002060 * on sizeof(mbedtls_mpi_uint)
2061 */
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002062 mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &S4 : &S8;
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002063 mbedtls_mpi_uint carry = ( sizeof(mbedtls_mpi_uint) == 4 ) ? carry4 : carry8;
2064
2065 /* All of the inputs are +ve (or zero) */
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002066 TEST_EQUAL( 1, A.s );
2067 TEST_EQUAL( 1, B.s );
Tom Cosgrove9339f052022-09-01 13:02:53 +01002068 TEST_EQUAL( 1, X->s );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002069
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002070 /* Test cases are such that A <= B, so #limbs should be <= */
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +01002071 TEST_LE_U( A.n, B.n );
2072 TEST_LE_U( X->n, B.n );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002073
2074 /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002075
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002076 /* mbedtls_mpi_core_add_if() uses input arrays of mbedtls_mpi_uints which
2077 * must be the same size. The MPIs we've read in will only have arrays
2078 * large enough for the number they represent. Therefore we create new
2079 * raw arrays of mbedtls_mpi_uints and populate them from the MPIs we've
2080 * just read in.
2081 *
2082 * We generated test data such that B was always >= A, so that's how many
2083 * limbs each of these need.
2084 */
Tom Cosgrove1135b202022-09-02 11:46:18 +01002085 size_t limbs = B.n;
Tom Cosgrove1135b202022-09-02 11:46:18 +01002086 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002087
Tom Cosgrove2b177922022-09-15 14:07:18 +01002088 /* ASSERT_ALLOC() uses calloc() under the hood, so these do get zeroed */
2089 ASSERT_ALLOC( a, bytes );
2090 ASSERT_ALLOC( b, bytes );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002091 ASSERT_ALLOC( sum, bytes );
Tom Cosgrove2b177922022-09-15 14:07:18 +01002092 ASSERT_ALLOC( d, bytes );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002093
2094 /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
2095 * processed by mbedtls_mpi_core_add_if()) are little endian, we can just
Tom Cosgrove2b177922022-09-15 14:07:18 +01002096 * copy what we have as long as MSBs are 0 (which they are from ASSERT_ALLOC())
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002097 */
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002098 memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
2099 memcpy( b, B.p, B.n * sizeof(mbedtls_mpi_uint) );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002100 memcpy( sum, X->p, X->n * sizeof(mbedtls_mpi_uint) );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002101
Tom Cosgrovedbc15612022-09-15 15:36:23 +01002102 /* The test cases have a <= b to avoid repetition, so we test a + b then,
2103 * if a != b, b + a. If a == b, we can test when a and b are aliased */
Tom Cosgrove17f1fdc2022-09-15 15:23:56 +01002104
2105 /* a + b */
2106
2107 /* cond = 0 => d unchanged, no carry */
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002108 memcpy( d, a, bytes );
Tom Cosgrove1135b202022-09-02 11:46:18 +01002109 TEST_EQUAL( 0, mbedtls_mpi_core_add_if( d, b, limbs, 0 ) );
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002110 ASSERT_COMPARE( d, bytes, a, bytes );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002111
Tom Cosgrove17f1fdc2022-09-15 15:23:56 +01002112 /* cond = 1 => correct result and carry */
Tom Cosgrove1135b202022-09-02 11:46:18 +01002113 TEST_EQUAL( carry, mbedtls_mpi_core_add_if( d, b, limbs, 1 ) );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002114 ASSERT_COMPARE( d, bytes, sum, bytes );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002115
Tom Cosgrove1135b202022-09-02 11:46:18 +01002116 if ( A.n == B.n && memcmp( A.p, B.p, bytes ) == 0 )
2117 {
Tom Cosgrovedbc15612022-09-15 15:36:23 +01002118 /* a == b, so test where a and b are aliased */
2119
Tom Cosgrove17f1fdc2022-09-15 15:23:56 +01002120 /* cond = 0 => d unchanged, no carry */
Tom Cosgrove1135b202022-09-02 11:46:18 +01002121 TEST_EQUAL( 0, mbedtls_mpi_core_add_if( b, b, limbs, 0 ) );
2122 ASSERT_COMPARE( b, bytes, B.p, bytes );
2123
Tom Cosgrove17f1fdc2022-09-15 15:23:56 +01002124 /* cond = 1 => correct result and carry */
Tom Cosgrove1135b202022-09-02 11:46:18 +01002125 TEST_EQUAL( carry, mbedtls_mpi_core_add_if( b, b, limbs, 1 ) );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002126 ASSERT_COMPARE( b, bytes, sum, bytes );
Tom Cosgrove1135b202022-09-02 11:46:18 +01002127 }
Tom Cosgrovedbc15612022-09-15 15:36:23 +01002128 else
2129 {
2130 /* a != b, so test b + a */
2131
2132 /* cond = 0 => d unchanged, no carry */
2133 memcpy( d, b, bytes );
2134 TEST_EQUAL( 0, mbedtls_mpi_core_add_if( d, a, limbs, 0 ) );
2135 ASSERT_COMPARE( d, bytes, b, bytes );
2136
2137 /* cond = 1 => correct result and carry */
2138 TEST_EQUAL( carry, mbedtls_mpi_core_add_if( d, a, limbs, 1 ) );
2139 ASSERT_COMPARE( d, bytes, sum, bytes );
2140 }
Tom Cosgrove1135b202022-09-02 11:46:18 +01002141
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002142exit:
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002143 mbedtls_free( a );
2144 mbedtls_free( b );
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002145 mbedtls_free( sum );
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002146 mbedtls_free( d );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002147
Tom Cosgrove50c477b2022-09-15 14:28:30 +01002148 mbedtls_mpi_free( &S4 );
2149 mbedtls_mpi_free( &S8 );
Tom Cosgroveeceb4cc2022-09-02 10:46:09 +01002150 mbedtls_mpi_free( &A );
2151 mbedtls_mpi_free( &B );
Tom Cosgrove0cc78652022-08-23 16:26:52 +01002152}
2153/* END_CASE */
2154
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002155/* BEGIN_CASE */
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002156void mpi_core_sub( char * input_A, char * input_B,
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01002157 char * input_X4, char * input_X8,
2158 int carry )
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002159{
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002160 mbedtls_mpi A, B, X4, X8;
2161 mbedtls_mpi_uint *a = NULL;
2162 mbedtls_mpi_uint *b = NULL;
2163 mbedtls_mpi_uint *x = NULL; /* expected */
2164 mbedtls_mpi_uint *r = NULL; /* result */
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002165
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002166 mbedtls_mpi_init( &A );
2167 mbedtls_mpi_init( &B );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002168 mbedtls_mpi_init( &X4 );
2169 mbedtls_mpi_init( &X8 );
2170
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002171 TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
2172 TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
Tom Cosgrove9339f052022-09-01 13:02:53 +01002173 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
2174 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002175
2176 /* All of the inputs are +ve (or zero) */
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002177 TEST_EQUAL( 1, A.s );
2178 TEST_EQUAL( 1, B.s );
Tom Cosgrove9339f052022-09-01 13:02:53 +01002179 TEST_EQUAL( 1, X4.s );
2180 TEST_EQUAL( 1, X8.s );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002181
2182 /* Get the number of limbs we will need */
Tom Cosgrovee2159f22022-09-15 14:40:10 +01002183 size_t limbs = MAX( A.n, B.n );
Tom Cosgroveb0fb17a2022-09-01 15:04:43 +01002184 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002185
2186 /* We only need to work with X4 or X8, depending on sizeof(mbedtls_mpi_uint) */
2187 mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
2188
2189 /* The result shouldn't have more limbs than the longest input */
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +01002190 TEST_LE_U( X->n, limbs );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002191
2192 /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002193
Tom Cosgrove2b177922022-09-15 14:07:18 +01002194 /* ASSERT_ALLOC() uses calloc() under the hood, so these do get zeroed */
2195 ASSERT_ALLOC( a, bytes );
2196 ASSERT_ALLOC( b, bytes );
2197 ASSERT_ALLOC( x, bytes );
2198 ASSERT_ALLOC( r, bytes );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002199
2200 /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002201 * processed by mbedtls_mpi_core_sub()) are little endian, we can just
Tom Cosgrove2b177922022-09-15 14:07:18 +01002202 * copy what we have as long as MSBs are 0 (which they are from ASSERT_ALLOC())
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002203 */
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002204 memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
2205 memcpy( b, B.p, B.n * sizeof(mbedtls_mpi_uint) );
2206 memcpy( x, X->p, X->n * sizeof(mbedtls_mpi_uint) );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002207
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002208 /* 1a) r = a - b => we should get the correct carry */
Tom Cosgrovebe7209d2022-09-15 14:32:38 +01002209 TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, a, b, limbs ) );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002210
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002211 /* 1b) r = a - b => we should get the correct result */
2212 ASSERT_COMPARE( r, bytes, x, bytes );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002213
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002214 /* 2 and 3 test "r may be aliased to a or b" */
2215 /* 2a) r = a; r -= b => we should get the correct carry (use r to avoid clobbering a) */
2216 memcpy( r, a, bytes );
Tom Cosgrovebe7209d2022-09-15 14:32:38 +01002217 TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, r, b, limbs ) );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002218
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002219 /* 2b) r -= b => we should get the correct result */
2220 ASSERT_COMPARE( r, bytes, x, bytes );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002221
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002222 /* 3a) r = b; r = a - r => we should get the correct carry (use r to avoid clobbering b) */
2223 memcpy( r, b, bytes );
Tom Cosgrovebe7209d2022-09-15 14:32:38 +01002224 TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, a, r, limbs ) );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002225
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002226 /* 3b) r = a - b => we should get the correct result */
2227 ASSERT_COMPARE( r, bytes, x, bytes );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002228
Tom Cosgrovef2b38182022-09-20 09:08:31 +01002229 /* 4 tests "r may be aliased to [...] both" */
2230 if ( A.n == B.n && memcmp( A.p, B.p, bytes ) == 0 )
2231 {
2232 memcpy( r, b, bytes );
2233 TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, r, r, limbs ) );
2234 ASSERT_COMPARE( r, bytes, x, bytes );
2235 }
2236
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002237exit:
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002238 mbedtls_free( a );
2239 mbedtls_free( b );
2240 mbedtls_free( x );
2241 mbedtls_free( r );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002242
Tom Cosgrovea043aeb2022-09-02 10:59:59 +01002243 mbedtls_mpi_free( &A );
2244 mbedtls_mpi_free( &B );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002245 mbedtls_mpi_free( &X4 );
2246 mbedtls_mpi_free( &X8 );
Tom Cosgrove2a65b852022-08-17 05:43:54 +01002247}
2248/* END_CASE */
2249
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002250/* BEGIN_CASE */
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002251void mpi_core_mla( char * input_A, char * input_B, char * input_S,
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01002252 char * input_X4, char * input_cy4,
2253 char * input_X8, char * input_cy8 )
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002254{
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002255 /* We are testing A += B * s; A, B are MPIs, s is a scalar.
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002256 *
Tom Cosgrove359feb02022-09-15 14:52:34 +01002257 * However, we encode s as an MPI in the .data file as the test framework
2258 * currently only supports `int`-typed scalars, and that doesn't cover the
2259 * full range of `mbedtls_mpi_uint`.
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002260 *
2261 * We also have the different results for sizeof(mbedtls_mpi_uint) == 4 or 8.
2262 */
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002263 mbedtls_mpi A, B, S, X4, X8, cy4, cy8;
2264 mbedtls_mpi_uint *a = NULL;
2265 mbedtls_mpi_uint *x = NULL;
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002266
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002267 mbedtls_mpi_init( &A );
2268 mbedtls_mpi_init( &B );
2269 mbedtls_mpi_init( &S );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002270 mbedtls_mpi_init( &X4 );
2271 mbedtls_mpi_init( &X8 );
2272 mbedtls_mpi_init( &cy4 );
2273 mbedtls_mpi_init( &cy8 );
2274
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002275 TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
2276 TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
2277 TEST_EQUAL( 0, mbedtls_test_read_mpi( &S, input_S ) );
Tom Cosgrove9339f052022-09-01 13:02:53 +01002278 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
2279 TEST_EQUAL( 0, mbedtls_test_read_mpi( &cy4, input_cy4 ) );
2280 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
2281 TEST_EQUAL( 0, mbedtls_test_read_mpi( &cy8, input_cy8 ) );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002282
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002283 /* The MPI encoding of scalar s must be only 1 limb */
2284 TEST_EQUAL( 1, S.n );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002285
2286 /* We only need to work with X4 or X8, and cy4 or cy8, depending on sizeof(mbedtls_mpi_uint) */
2287 mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
2288 mbedtls_mpi *cy = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &cy4 : &cy8;
2289
2290 /* The carry should only have one limb */
Tom Cosgrove9339f052022-09-01 13:02:53 +01002291 TEST_EQUAL( 1, cy->n );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002292
2293 /* All of the inputs are +ve (or zero) */
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002294 TEST_EQUAL( 1, A.s );
2295 TEST_EQUAL( 1, B.s );
2296 TEST_EQUAL( 1, S.s );
Tom Cosgrove9339f052022-09-01 13:02:53 +01002297 TEST_EQUAL( 1, X->s );
2298 TEST_EQUAL( 1, cy->s );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002299
2300 /* Get the (max) number of limbs we will need */
Tom Cosgrovee2159f22022-09-15 14:40:10 +01002301 size_t limbs = MAX( A.n, B.n );
Tom Cosgroveb0fb17a2022-09-01 15:04:43 +01002302 size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002303
2304 /* The result shouldn't have more limbs than the longest input */
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +01002305 TEST_LE_U( X->n, limbs );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002306
2307 /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002308
Tom Cosgrove2b177922022-09-15 14:07:18 +01002309 /* ASSERT_ALLOC() uses calloc() under the hood, so these do get zeroed */
2310 ASSERT_ALLOC( a, bytes );
2311 ASSERT_ALLOC( x, bytes );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002312
2313 /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002314 * processed by mbedtls_mpi_core_mla()) are little endian, we can just
Tom Cosgrove2b177922022-09-15 14:07:18 +01002315 * copy what we have as long as MSBs are 0 (which they are from ASSERT_ALLOC()).
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002316 */
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002317 memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
2318 memcpy( x, X->p, X->n * sizeof(mbedtls_mpi_uint) );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002319
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002320 /* 1a) A += B * s => we should get the correct carry */
2321 TEST_EQUAL( mbedtls_mpi_core_mla( a, limbs, B.p, B.n, *S.p ), *cy->p );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002322
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002323 /* 1b) A += B * s => we should get the correct result */
2324 ASSERT_COMPARE( a, bytes, x, bytes );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002325
Tom Cosgroveb0b77e12022-09-20 13:33:40 +01002326 if ( A.n == B.n && memcmp( A.p, B.p, bytes ) == 0 )
2327 {
2328 /* Check when A and B are aliased */
2329 memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
2330 TEST_EQUAL( mbedtls_mpi_core_mla( a, limbs, a, limbs, *S.p ), *cy->p );
2331 ASSERT_COMPARE( a, bytes, x, bytes );
2332 }
2333
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002334exit:
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002335 mbedtls_free( a );
2336 mbedtls_free( x );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002337
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002338 mbedtls_mpi_free( &A );
2339 mbedtls_mpi_free( &B );
2340 mbedtls_mpi_free( &S );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002341 mbedtls_mpi_free( &X4 );
2342 mbedtls_mpi_free( &X8 );
Tom Cosgrove42dfac62022-09-02 11:16:39 +01002343 mbedtls_mpi_free( &cy4 );
2344 mbedtls_mpi_free( &cy8 );
Tom Cosgrove659c84a2022-08-17 05:45:19 +01002345}
2346/* END_CASE */
2347
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002348/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01002349void mpi_montg_init( char * input_N, char * input_mm )
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002350{
2351 mbedtls_mpi N, mm;
2352
2353 mbedtls_mpi_init( &N );
2354 mbedtls_mpi_init( &mm );
2355
Tom Cosgrove9339f052022-09-01 13:02:53 +01002356 TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
2357 TEST_EQUAL( 0, mbedtls_test_read_mpi( &mm, input_mm ) );
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002358
2359 /* The MPI encoding of mm should be 1 limb (sizeof(mbedtls_mpi_uint) == 8) or
2360 * 2 limbs (sizeof(mbedtls_mpi_uint) == 4).
2361 *
2362 * The data file contains the expected result for sizeof(mbedtls_mpi_uint) == 8;
2363 * for sizeof(mbedtls_mpi_uint) == 4 it's just the LSW of this.
2364 */
Tom Cosgroveb2c06f42022-08-24 17:45:58 +01002365 TEST_ASSERT( mm.n == 1 || mm.n == 2 );
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002366
2367 /* All of the inputs are +ve (or zero) */
Tom Cosgrove9339f052022-09-01 13:02:53 +01002368 TEST_EQUAL( 1, N.s );
2369 TEST_EQUAL( 1, mm.s );
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002370
Tom Cosgroveb7438d12022-09-15 15:05:59 +01002371 /* mbedtls_mpi_core_montmul_init() only returns a result, no error possible */
2372 mbedtls_mpi_uint result = mbedtls_mpi_core_montmul_init( N.p );
Tom Cosgrove79b70f62022-08-17 06:17:00 +01002373
2374 /* Check we got the correct result */
2375 TEST_EQUAL( result, mm.p[0] );
2376
2377exit:
2378 mbedtls_mpi_free( &N );
2379 mbedtls_mpi_free( &mm );
2380}
2381/* END_CASE */
2382
Tom Cosgrovef334d962022-08-17 06:29:32 +01002383/* BEGIN_CASE */
Tom Cosgrove1b2947a2022-09-02 10:24:55 +01002384void mpi_core_montmul( int limbs_AN4, int limbs_B4,
2385 int limbs_AN8, int limbs_B8,
2386 char * input_A,
2387 char * input_B,
2388 char * input_N,
2389 char * input_X4,
2390 char * input_X8 )
Tom Cosgrovef334d962022-08-17 06:29:32 +01002391{
Tom Cosgrove93842842022-08-05 16:59:43 +01002392 mbedtls_mpi A, B, N, X4, X8, T, R;
Tom Cosgrovef334d962022-08-17 06:29:32 +01002393
2394 mbedtls_mpi_init( &A );
2395 mbedtls_mpi_init( &B );
2396 mbedtls_mpi_init( &N );
2397 mbedtls_mpi_init( &X4 ); /* expected result, sizeof(mbedtls_mpi_uint) == 4 */
2398 mbedtls_mpi_init( &X8 ); /* expected result, sizeof(mbedtls_mpi_uint) == 8 */
2399 mbedtls_mpi_init( &T );
Tom Cosgrove93842842022-08-05 16:59:43 +01002400 mbedtls_mpi_init( &R ); /* for the result */
Tom Cosgrovef334d962022-08-17 06:29:32 +01002401
Tom Cosgrove9339f052022-09-01 13:02:53 +01002402 TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
2403 TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
2404 TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
2405 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
2406 TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002407
2408 mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
2409
2410 int limbs_AN = ( sizeof(mbedtls_mpi_uint) == 4 ) ? limbs_AN4 : limbs_AN8;
2411 int limbs_B = ( sizeof(mbedtls_mpi_uint) == 4 ) ? limbs_B4 : limbs_B8;
2412
Tom Cosgrove1feb5ac2022-09-15 14:22:35 +01002413 TEST_LE_U( A.n, (size_t)limbs_AN );
2414 TEST_LE_U( X->n, (size_t)limbs_AN );
2415 TEST_LE_U( B.n, (size_t)limbs_B );
2416 TEST_LE_U( limbs_B, limbs_AN );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002417
2418 /* All of the inputs are +ve (or zero) */
Tom Cosgrove9339f052022-09-01 13:02:53 +01002419 TEST_EQUAL( 1, A.s );
2420 TEST_EQUAL( 1, B.s );
2421 TEST_EQUAL( 1, N.s );
2422 TEST_EQUAL( 1, X->s );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002423
Tom Cosgrove9339f052022-09-01 13:02:53 +01002424 TEST_EQUAL( 0, mbedtls_mpi_grow( &A, limbs_AN ) );
2425 TEST_EQUAL( 0, mbedtls_mpi_grow( &N, limbs_AN ) );
2426 TEST_EQUAL( 0, mbedtls_mpi_grow( X, limbs_AN ) );
2427 TEST_EQUAL( 0, mbedtls_mpi_grow( &B, limbs_B ) );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002428
Tom Cosgrove9339f052022-09-01 13:02:53 +01002429 TEST_EQUAL( 0, mbedtls_mpi_grow( &T, limbs_AN * 2 + 1 ) );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002430
2431 /* Calculate the Montgomery constant (this is unit tested separately) */
Tom Cosgroveb7438d12022-09-15 15:05:59 +01002432 mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init( N.p );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002433
Tom Cosgrove9339f052022-09-01 13:02:53 +01002434 TEST_EQUAL( 0, mbedtls_mpi_grow( &R, limbs_AN ) ); /* ensure it's got the right number of limbs */
Tom Cosgrovef334d962022-08-17 06:29:32 +01002435
Tom Cosgrove93842842022-08-05 16:59:43 +01002436 mbedtls_mpi_core_montmul( R.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
Tom Cosgroveb0fb17a2022-09-01 15:04:43 +01002437 size_t bytes = N.n * sizeof(mbedtls_mpi_uint);
2438 ASSERT_COMPARE( R.p, bytes, X->p, bytes );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002439
Tom Cosgroveea45c1d2022-09-20 13:17:51 +01002440 /* The output (R, above) may be aliased to A - use R to save the value of A */
2441
2442 memcpy( R.p, A.p, bytes );
2443
2444 mbedtls_mpi_core_montmul( A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
2445 ASSERT_COMPARE( A.p, bytes, X->p, bytes );
2446
2447 memcpy( A.p, R.p, bytes ); /* restore A */
2448
2449 /* The output may be aliased to N - use R to save the value of N */
2450
2451 memcpy( R.p, N.p, bytes );
2452
2453 mbedtls_mpi_core_montmul( N.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
2454 ASSERT_COMPARE( N.p, bytes, X->p, bytes );
2455
2456 memcpy( N.p, R.p, bytes );
2457
Tom Cosgroveea45c1d2022-09-20 13:17:51 +01002458 if (limbs_AN == limbs_B)
2459 {
Tom Cosgrove4386ead2022-09-29 14:40:21 +01002460 /* Test when A aliased to B (requires A == B on input values) */
2461 if ( memcmp( A.p, B.p, bytes ) == 0 )
2462 {
2463 /* Test with A aliased to B and output, since this is permitted -
2464 * don't bother with yet another test with only A and B aliased */
2465
2466 mbedtls_mpi_core_montmul( B.p, B.p, B.p, B.n, N.p, N.n, mm, T.p );
2467 ASSERT_COMPARE( B.p, bytes, X->p, bytes );
2468
2469 memcpy( B.p, A.p, bytes ); /* restore B from equal value A */
2470 }
2471
2472 /* The output may be aliased to B - last test, so we don't save B */
2473
Tom Cosgroveea45c1d2022-09-20 13:17:51 +01002474 mbedtls_mpi_core_montmul( B.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
2475 ASSERT_COMPARE( B.p, bytes, X->p, bytes );
2476 }
2477
Tom Cosgrovef334d962022-08-17 06:29:32 +01002478exit:
2479 mbedtls_mpi_free( &A );
2480 mbedtls_mpi_free( &B );
2481 mbedtls_mpi_free( &N );
2482 mbedtls_mpi_free( &X4 );
2483 mbedtls_mpi_free( &X8 );
2484 mbedtls_mpi_free( &T );
Tom Cosgrove93842842022-08-05 16:59:43 +01002485 mbedtls_mpi_free( &R );
Tom Cosgrovef334d962022-08-17 06:29:32 +01002486}
2487/* END_CASE */
2488
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002489/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
Azim Khanf1aaec92017-05-30 14:23:15 +01002490void mpi_selftest( )
Paul Bakkere896fea2009-07-06 06:40:23 +00002491{
Andres AG93012e82016-09-09 09:10:28 +01002492 TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
Paul Bakkere896fea2009-07-06 06:40:23 +00002493}
Paul Bakker33b43f12013-08-20 11:48:36 +02002494/* END_CASE */