1/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4
5#if MBEDTLS_MPI_MAX_BITS > 792
6#define MPI_MAX_BITS_LARGER_THAN_792
7#endif
8
9/* Check the validity of the sign bit in an MPI object. Reject representations
10 * that are not supported by the rest of the library and indicate a bug when
11 * constructing the value. */
12static int sign_is_valid( const mbedtls_mpi *X )
13{
14    if( X->s != 1 && X->s != -1 )
15        return( 0 ); // invalid sign bit, e.g. 0
16    if( mbedtls_mpi_bitlen( X ) == 0 && X->s != 1 )
17        return( 0 ); // negative zero
18    return( 1 );
19}
20
21typedef struct mbedtls_test_mpi_random
22{
23    data_t *data;
24    size_t  pos;
25    size_t  chunk_len;
26} mbedtls_test_mpi_random;
27
28/*
29 * This function is called by the Miller-Rabin primality test each time it
30 * chooses a random witness. The witnesses (or non-witnesses as provided by the
31 * test) are stored in the data member of the state structure. Each number is in
32 * the format that mbedtls_mpi_read_string understands and is chunk_len long.
33 */
34int mbedtls_test_mpi_miller_rabin_determinizer( void* state,
35                                                unsigned char* buf,
36                                                size_t len )
37{
38    mbedtls_test_mpi_random *random = (mbedtls_test_mpi_random*) state;
39
40    if( random == NULL || random->data->x == NULL || buf == NULL )
41        return( -1 );
42
43    if( random->pos + random->chunk_len > random->data->len
44            || random->chunk_len > len )
45    {
46        return( -1 );
47    }
48
49    memset( buf, 0, len );
50
51    /* The witness is written to the end of the buffer, since the buffer is
52     * used as big endian, unsigned binary data in mbedtls_mpi_read_binary.
53     * Writing the witness to the start of the buffer would result in the
54     * buffer being 'witness 000...000', which would be treated as
55     * witness * 2^n for some n. */
56    memcpy( buf + len - random->chunk_len, &random->data->x[random->pos],
57            random->chunk_len );
58
59    random->pos += random->chunk_len;
60
61    return( 0 );
62}
63
64/* Random generator that is told how many bytes to return. */
65static int f_rng_bytes_left( void *state, unsigned char *buf, size_t len )
66{
67    size_t *bytes_left = state;
68    size_t i;
69    for( i = 0; i < len; i++ )
70    {
71        if( *bytes_left == 0 )
72            return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
73        buf[i] = *bytes_left & 0xff;
74        --( *bytes_left );
75    }
76    return( 0 );
77}
78
79/* Test whether bytes represents (in big-endian base 256) a number b that
80 * is significantly above a power of 2. That is, b must not have a long run
81 * of unset bits after the most significant bit.
82 *
83 * Let n be the bit-size of b, i.e. the integer such that 2^n <= b < 2^{n+1}.
84 * This function returns 1 if, when drawing a number between 0 and b,
85 * the probability that this number is at least 2^n is not negligible.
86 * This probability is (b - 2^n) / b and this function checks that this
87 * number is above some threshold A. The threshold value is heuristic and
88 * based on the needs of mpi_random_many().
89 */
90static int is_significantly_above_a_power_of_2( data_t *bytes )
91{
92    const uint8_t *p = bytes->x;
93    size_t len = bytes->len;
94    unsigned x;
95
96    /* Skip leading null bytes */
97    while( len > 0 && p[0] == 0 )
98    {
99        ++p;
100        --len;
101    }
102    /* 0 is not significantly above a power of 2 */
103    if( len == 0 )
104        return( 0 );
105    /* Extract the (up to) 2 most significant bytes */
106    if( len == 1 )
107        x = p[0];
108    else
109        x = ( p[0] << 8 ) | p[1];
110
111    /* Shift the most significant bit of x to position 8 and mask it out */
112    while( ( x & 0xfe00 ) != 0 )
113        x >>= 1;
114    x &= 0x00ff;
115
116    /* At this point, x = floor((b - 2^n) / 2^(n-8)). b is significantly above
117     * a power of 2 iff x is significantly above 0 compared to 2^8.
118     * Testing x >= 2^4 amounts to picking A = 1/16 in the function
119     * description above. */
120    return( x >= 0x10 );
121}
122
123/* END_HEADER */
124
125/* BEGIN_DEPENDENCIES
126 * depends_on:MBEDTLS_BIGNUM_C
127 * END_DEPENDENCIES
128 */
129
130/* BEGIN_CASE */
131void mpi_null(  )
132{
133    mbedtls_mpi X, Y, Z;
134
135    mbedtls_mpi_init( &X );
136    mbedtls_mpi_init( &Y );
137    mbedtls_mpi_init( &Z );
138
139    TEST_ASSERT( mbedtls_mpi_get_bit( &X, 42 ) == 0 );
140    TEST_ASSERT( mbedtls_mpi_lsb( &X ) == 0 );
141    TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == 0 );
142    TEST_ASSERT( mbedtls_mpi_size( &X ) == 0 );
143
144exit:
145    mbedtls_mpi_free( &X );
146}
147/* END_CASE */
148
149/* BEGIN_CASE */
150void mpi_read_write_string( int radix_X, char * input_X, int radix_A,
151                            char * input_A, int output_size, int result_read,
152                            int result_write )
153{
154    mbedtls_mpi X;
155    char str[1000];
156    size_t len;
157
158    mbedtls_mpi_init( &X );
159
160    memset( str, '!', sizeof( str ) );
161
162    TEST_ASSERT( mbedtls_mpi_read_string( &X, radix_X, input_X ) == result_read );
163    if( result_read == 0 )
164    {
165        TEST_ASSERT( sign_is_valid( &X ) );
166        TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, output_size, &len ) == result_write );
167        if( result_write == 0 )
168        {
169            TEST_ASSERT( strcasecmp( str, input_A ) == 0 );
170            TEST_ASSERT( str[len] == '!' );
171        }
172    }
173
174exit:
175    mbedtls_mpi_free( &X );
176}
177/* END_CASE */
178
179/* BEGIN_CASE */
180void mbedtls_mpi_read_binary( data_t * buf, int radix_A, char * input_A )
181{
182    mbedtls_mpi X;
183    char str[1000];
184    size_t len;
185
186    mbedtls_mpi_init( &X );
187
188
189    TEST_ASSERT( mbedtls_mpi_read_binary( &X, buf->x, buf->len ) == 0 );
190    TEST_ASSERT( sign_is_valid( &X ) );
191    TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
192    TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
193
194exit:
195    mbedtls_mpi_free( &X );
196}
197/* END_CASE */
198
199/* BEGIN_CASE */
200void mbedtls_mpi_read_binary_le( data_t * buf, int radix_A, char * input_A )
201{
202    mbedtls_mpi X;
203    char str[1000];
204    size_t len;
205
206    mbedtls_mpi_init( &X );
207
208
209    TEST_ASSERT( mbedtls_mpi_read_binary_le( &X, buf->x, buf->len ) == 0 );
210    TEST_ASSERT( sign_is_valid( &X ) );
211    TEST_ASSERT( mbedtls_mpi_write_string( &X, radix_A, str, sizeof( str ), &len ) == 0 );
212    TEST_ASSERT( strcmp( (char *) str, input_A ) == 0 );
213
214exit:
215    mbedtls_mpi_free( &X );
216}
217/* END_CASE */
218
219/* BEGIN_CASE */
220void mbedtls_mpi_write_binary( int radix_X, char * input_X,
221                               data_t * input_A, int output_size,
222                               int result )
223{
224    mbedtls_mpi X;
225    unsigned char buf[1000];
226    size_t buflen;
227
228    memset( buf, 0x00, 1000 );
229
230    mbedtls_mpi_init( &X );
231
232    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
233
234    buflen = mbedtls_mpi_size( &X );
235    if( buflen > (size_t) output_size )
236        buflen = (size_t) output_size;
237
238    TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == result );
239    if( result == 0)
240    {
241
242        TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
243                                          buflen, input_A->len ) == 0 );
244    }
245
246exit:
247    mbedtls_mpi_free( &X );
248}
249/* END_CASE */
250
251/* BEGIN_CASE */
252void mbedtls_mpi_write_binary_le( int radix_X, char * input_X,
253                                  data_t * input_A, int output_size,
254                                  int result )
255{
256    mbedtls_mpi X;
257    unsigned char buf[1000];
258    size_t buflen;
259
260    memset( buf, 0x00, 1000 );
261
262    mbedtls_mpi_init( &X );
263
264    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
265
266    buflen = mbedtls_mpi_size( &X );
267    if( buflen > (size_t) output_size )
268        buflen = (size_t) output_size;
269
270    TEST_ASSERT( mbedtls_mpi_write_binary_le( &X, buf, buflen ) == result );
271    if( result == 0)
272    {
273
274        TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
275                                          buflen, input_A->len ) == 0 );
276    }
277
278exit:
279    mbedtls_mpi_free( &X );
280}
281/* END_CASE */
282
283/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
284void mbedtls_mpi_read_file( int radix_X, char * input_file,
285                            data_t * input_A, int result )
286{
287    mbedtls_mpi X;
288    unsigned char buf[1000];
289    size_t buflen;
290    FILE *file;
291    int ret;
292
293    memset( buf, 0x00, 1000 );
294
295    mbedtls_mpi_init( &X );
296
297    file = fopen( input_file, "r" );
298    TEST_ASSERT( file != NULL );
299    ret = mbedtls_mpi_read_file( &X, radix_X, file );
300    fclose(file);
301    TEST_ASSERT( ret == result );
302
303    if( result == 0 )
304    {
305        TEST_ASSERT( sign_is_valid( &X ) );
306        buflen = mbedtls_mpi_size( &X );
307        TEST_ASSERT( mbedtls_mpi_write_binary( &X, buf, buflen ) == 0 );
308
309
310        TEST_ASSERT( mbedtls_test_hexcmp( buf, input_A->x,
311                                          buflen, input_A->len ) == 0 );
312    }
313
314exit:
315    mbedtls_mpi_free( &X );
316}
317/* END_CASE */
318
319/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
320void mbedtls_mpi_write_file( int radix_X, char * input_X, int output_radix,
321                             char * output_file )
322{
323    mbedtls_mpi X, Y;
324    FILE *file_out, *file_in;
325    int ret;
326
327    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
328
329    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
330
331    file_out = fopen( output_file, "w" );
332    TEST_ASSERT( file_out != NULL );
333    ret = mbedtls_mpi_write_file( NULL, &X, output_radix, file_out );
334    fclose(file_out);
335    TEST_ASSERT( ret == 0 );
336
337    file_in = fopen( output_file, "r" );
338    TEST_ASSERT( file_in != NULL );
339    ret = mbedtls_mpi_read_file( &Y, output_radix, file_in );
340    fclose(file_in);
341    TEST_ASSERT( ret == 0 );
342
343    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
344
345exit:
346    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
347}
348/* END_CASE */
349
350/* BEGIN_CASE */
351void mbedtls_mpi_get_bit( int radix_X, char * input_X, int pos, int val )
352{
353    mbedtls_mpi X;
354    mbedtls_mpi_init( &X );
355    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
356    TEST_ASSERT( mbedtls_mpi_get_bit( &X, pos ) == val );
357
358exit:
359    mbedtls_mpi_free( &X );
360}
361/* END_CASE */
362
363/* BEGIN_CASE */
364void mbedtls_mpi_set_bit( int radix_X, char * input_X, int pos, int val,
365                          int radix_Y, char * output_Y, int result )
366{
367    mbedtls_mpi X, Y;
368    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
369
370    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
371    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, output_Y ) == 0 );
372    TEST_ASSERT( mbedtls_mpi_set_bit( &X, pos, val ) == result );
373
374    if( result == 0 )
375    {
376        TEST_ASSERT( sign_is_valid( &X ) );
377        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == 0 );
378    }
379
380exit:
381    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
382}
383/* END_CASE */
384
385/* BEGIN_CASE */
386void mbedtls_mpi_lsb( int radix_X, char * input_X, int nr_bits )
387{
388    mbedtls_mpi X;
389    mbedtls_mpi_init( &X );
390
391    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
392    TEST_ASSERT( mbedtls_mpi_lsb( &X ) == (size_t) nr_bits );
393
394exit:
395    mbedtls_mpi_free( &X );
396}
397/* END_CASE */
398
399/* BEGIN_CASE */
400void mbedtls_mpi_bitlen( int radix_X, char * input_X, int nr_bits )
401{
402    mbedtls_mpi X;
403    mbedtls_mpi_init( &X );
404
405    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
406    TEST_ASSERT( mbedtls_mpi_bitlen( &X ) == (size_t) nr_bits );
407
408exit:
409    mbedtls_mpi_free( &X );
410}
411/* END_CASE */
412
413/* BEGIN_CASE */
414void mbedtls_mpi_gcd( int radix_X, char * input_X, int radix_Y,
415                      char * input_Y, int radix_A, char * input_A )
416{
417    mbedtls_mpi A, X, Y, Z;
418    mbedtls_mpi_init( &A ); mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
419
420    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
421    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
422    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
423    TEST_ASSERT( mbedtls_mpi_gcd( &Z, &X, &Y ) == 0 );
424    TEST_ASSERT( sign_is_valid( &Z ) );
425    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
426
427exit:
428    mbedtls_mpi_free( &A ); mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
429}
430/* END_CASE */
431
432/* BEGIN_CASE */
433void mbedtls_mpi_cmp_int( int input_X, int input_A, int result_CMP )
434{
435    mbedtls_mpi X;
436    mbedtls_mpi_init( &X  );
437
438    TEST_ASSERT( mbedtls_mpi_lset( &X, input_X ) == 0);
439    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, input_A ) == result_CMP);
440
441exit:
442    mbedtls_mpi_free( &X );
443}
444/* END_CASE */
445
446/* BEGIN_CASE */
447void mbedtls_mpi_cmp_mpi( int radix_X, char * input_X, int radix_Y,
448                          char * input_Y, int input_A )
449{
450    mbedtls_mpi X, Y;
451    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
452
453    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
454    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
455    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y ) == input_A );
456
457exit:
458    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
459}
460/* END_CASE */
461
462/* BEGIN_CASE */
463void mbedtls_mpi_lt_mpi_ct( int size_X, char * input_X,
464                            int size_Y, char * input_Y,
465                            int input_ret, int input_err )
466{
467    unsigned ret = -1;
468    unsigned input_uret = input_ret;
469    mbedtls_mpi X, Y;
470    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
471
472    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
473    TEST_ASSERT( mbedtls_test_read_mpi( &Y, 16, input_Y ) == 0 );
474
475    TEST_ASSERT( mbedtls_mpi_grow( &X, size_X ) == 0 );
476    TEST_ASSERT( mbedtls_mpi_grow( &Y, size_Y ) == 0 );
477
478    TEST_ASSERT( mbedtls_mpi_lt_mpi_ct( &X, &Y, &ret ) == input_err );
479    if( input_err == 0 )
480        TEST_ASSERT( ret == input_uret );
481
482exit:
483    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
484}
485/* END_CASE */
486
487/* BEGIN_CASE */
488void mbedtls_mpi_cmp_abs( int radix_X, char * input_X, int radix_Y,
489                          char * input_Y, int input_A )
490{
491    mbedtls_mpi X, Y;
492    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
493
494    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
495    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
496    TEST_ASSERT( mbedtls_mpi_cmp_abs( &X, &Y ) == input_A );
497
498exit:
499    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
500}
501/* END_CASE */
502
503/* BEGIN_CASE */
504void mbedtls_mpi_copy( char *src_hex, char *dst_hex )
505{
506    mbedtls_mpi src, dst, ref;
507    mbedtls_mpi_init( &src );
508    mbedtls_mpi_init( &dst );
509    mbedtls_mpi_init( &ref );
510
511    TEST_ASSERT( mbedtls_test_read_mpi( &src, 16, src_hex ) == 0 );
512    TEST_ASSERT( mbedtls_test_read_mpi( &ref, 16, dst_hex ) == 0 );
513
514    /* mbedtls_mpi_copy() */
515    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
516    TEST_ASSERT( mbedtls_mpi_copy( &dst, &src ) == 0 );
517    TEST_ASSERT( sign_is_valid( &dst ) );
518    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
519
520    /* mbedtls_mpi_safe_cond_assign(), assignment done */
521    mbedtls_mpi_free( &dst );
522    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
523    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 1 ) == 0 );
524    TEST_ASSERT( sign_is_valid( &dst ) );
525    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &src ) == 0 );
526
527    /* mbedtls_mpi_safe_cond_assign(), assignment not done */
528    mbedtls_mpi_free( &dst );
529    TEST_ASSERT( mbedtls_test_read_mpi( &dst, 16, dst_hex ) == 0 );
530    TEST_ASSERT( mbedtls_mpi_safe_cond_assign( &dst, &src, 0 ) == 0 );
531    TEST_ASSERT( sign_is_valid( &dst ) );
532    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &dst, &ref ) == 0 );
533
534exit:
535    mbedtls_mpi_free( &src );
536    mbedtls_mpi_free( &dst );
537    mbedtls_mpi_free( &ref );
538}
539/* END_CASE */
540
541/* BEGIN_CASE */
542void mpi_copy_self( char *input_X )
543{
544    mbedtls_mpi X, A;
545    mbedtls_mpi_init( &A );
546    mbedtls_mpi_init( &X );
547
548    TEST_ASSERT( mbedtls_test_read_mpi( &X, 16, input_X ) == 0 );
549    TEST_ASSERT( mbedtls_mpi_copy( &X, &X ) == 0 );
550
551    TEST_ASSERT( mbedtls_test_read_mpi( &A, 16, input_X ) == 0 );
552    TEST_ASSERT( sign_is_valid( &X ) );
553    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
554
555exit:
556    mbedtls_mpi_free( &A );
557    mbedtls_mpi_free( &X );
558}
559/* END_CASE */
560
561/* BEGIN_CASE */
562void mbedtls_mpi_swap( char *X_hex, char *Y_hex )
563{
564    mbedtls_mpi X, Y, X0, Y0;
565    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y );
566    mbedtls_mpi_init( &X0 ); mbedtls_mpi_init( &Y0 );
567
568    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
569    TEST_ASSERT( mbedtls_test_read_mpi( &Y0, 16, Y_hex ) == 0 );
570
571    /* mbedtls_mpi_swap() */
572    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
573    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
574    mbedtls_mpi_swap( &X, &Y );
575    TEST_ASSERT( sign_is_valid( &X ) );
576    TEST_ASSERT( sign_is_valid( &Y ) );
577    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
578    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
579
580    /* mbedtls_mpi_safe_cond_swap(), swap done */
581    mbedtls_mpi_free( &X );
582    mbedtls_mpi_free( &Y );
583    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
584    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
585    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 1 ) == 0 );
586    TEST_ASSERT( sign_is_valid( &X ) );
587    TEST_ASSERT( sign_is_valid( &Y ) );
588    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &Y0 ) == 0 );
589    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &X0 ) == 0 );
590
591    /* mbedtls_mpi_safe_cond_swap(), swap not done */
592    mbedtls_mpi_free( &X );
593    mbedtls_mpi_free( &Y );
594    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
595    TEST_ASSERT( mbedtls_test_read_mpi( &Y,  16, Y_hex ) == 0 );
596    TEST_ASSERT( mbedtls_mpi_safe_cond_swap( &X, &Y, 0 ) == 0 );
597    TEST_ASSERT( sign_is_valid( &X ) );
598    TEST_ASSERT( sign_is_valid( &Y ) );
599    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
600    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &Y0 ) == 0 );
601
602exit:
603    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y );
604    mbedtls_mpi_free( &X0 ); mbedtls_mpi_free( &Y0 );
605}
606/* END_CASE */
607
608/* BEGIN_CASE */
609void mpi_swap_self( char *X_hex )
610{
611    mbedtls_mpi X, X0;
612    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &X0 );
613
614    TEST_ASSERT( mbedtls_test_read_mpi( &X,  16, X_hex ) == 0 );
615    TEST_ASSERT( mbedtls_test_read_mpi( &X0, 16, X_hex ) == 0 );
616
617    mbedtls_mpi_swap( &X, &X );
618    TEST_ASSERT( sign_is_valid( &X ) );
619    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &X0 ) == 0 );
620
621exit:
622    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &X0 );
623}
624/* END_CASE */
625
626/* BEGIN_CASE */
627void mbedtls_mpi_shrink( int before, int used, int min, int after )
628{
629    mbedtls_mpi X;
630    mbedtls_mpi_init( &X );
631
632    TEST_ASSERT( mbedtls_mpi_grow( &X, before ) == 0 );
633    if( used > 0 )
634    {
635        size_t used_bit_count = used * 8 * sizeof( mbedtls_mpi_uint );
636        TEST_ASSERT( mbedtls_mpi_set_bit( &X, used_bit_count - 1, 1 ) == 0 );
637    }
638    TEST_EQUAL( X.n, (size_t) before );
639    TEST_ASSERT( mbedtls_mpi_shrink( &X, min ) == 0 );
640    TEST_EQUAL( X.n, (size_t) after );
641
642exit:
643    mbedtls_mpi_free( &X );
644}
645/* END_CASE */
646
647/* BEGIN_CASE */
648void mbedtls_mpi_add_mpi( int radix_X, char * input_X, int radix_Y,
649                          char * input_Y, int radix_A, char * input_A )
650{
651    mbedtls_mpi X, Y, Z, A;
652    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
653
654    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
655    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
656    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
657    TEST_ASSERT( mbedtls_mpi_add_mpi( &Z, &X, &Y ) == 0 );
658    TEST_ASSERT( sign_is_valid( &Z ) );
659    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
660
661    /* result == first operand */
662    TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &Y ) == 0 );
663    TEST_ASSERT( sign_is_valid( &X ) );
664    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
665    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
666
667    /* result == second operand */
668    TEST_ASSERT( mbedtls_mpi_add_mpi( &Y, &X, &Y ) == 0 );
669    TEST_ASSERT( sign_is_valid( &Y ) );
670    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
671
672exit:
673    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
674}
675/* END_CASE */
676
677/* BEGIN_CASE */
678void mbedtls_mpi_add_mpi_inplace( int radix_X, char * input_X, int radix_A,
679                                  char * input_A )
680{
681    mbedtls_mpi X, A;
682    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
683
684    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
685
686    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
687    TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &X ) == 0 );
688    TEST_ASSERT( mbedtls_mpi_cmp_int( &X, 0 ) == 0 );
689    TEST_ASSERT( sign_is_valid( &X ) );
690
691    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
692    TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &X ) == 0 );
693    TEST_ASSERT( sign_is_valid( &X ) );
694    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
695
696    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
697    TEST_ASSERT( mbedtls_mpi_add_mpi( &X, &X, &X ) == 0 );
698    TEST_ASSERT( sign_is_valid( &X ) );
699    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
700
701exit:
702    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
703}
704/* END_CASE */
705
706
707/* BEGIN_CASE */
708void mbedtls_mpi_add_abs( int radix_X, char * input_X, int radix_Y,
709                          char * input_Y, int radix_A, char * input_A )
710{
711    mbedtls_mpi X, Y, Z, A;
712    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
713
714    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
715    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
716    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
717    TEST_ASSERT( mbedtls_mpi_add_abs( &Z, &X, &Y ) == 0 );
718    TEST_ASSERT( sign_is_valid( &Z ) );
719    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
720
721    /* result == first operand */
722    TEST_ASSERT( mbedtls_mpi_add_abs( &X, &X, &Y ) == 0 );
723    TEST_ASSERT( sign_is_valid( &X ) );
724    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
725    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
726
727    /* result == second operand */
728    TEST_ASSERT( mbedtls_mpi_add_abs( &Y, &X, &Y ) == 0 );
729    TEST_ASSERT( sign_is_valid( &Y ) );
730    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
731
732exit:
733    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
734}
735/* END_CASE */
736
737/* BEGIN_CASE */
738void mbedtls_mpi_add_int( int radix_X, char * input_X, int input_Y,
739                          int radix_A, char * input_A )
740{
741    mbedtls_mpi X, Z, A;
742    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
743
744    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
745    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
746    TEST_ASSERT( mbedtls_mpi_add_int( &Z, &X, input_Y ) == 0 );
747    TEST_ASSERT( sign_is_valid( &Z ) );
748    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
749
750exit:
751    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
752}
753/* END_CASE */
754
755/* BEGIN_CASE */
756void mbedtls_mpi_sub_mpi( int radix_X, char * input_X, int radix_Y,
757                          char * input_Y, int radix_A, char * input_A )
758{
759    mbedtls_mpi X, Y, Z, A;
760    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
761
762    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
763    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
764    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
765    TEST_ASSERT( mbedtls_mpi_sub_mpi( &Z, &X, &Y ) == 0 );
766    TEST_ASSERT( sign_is_valid( &Z ) );
767    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
768
769    /* result == first operand */
770    TEST_ASSERT( mbedtls_mpi_sub_mpi( &X, &X, &Y ) == 0 );
771    TEST_ASSERT( sign_is_valid( &X ) );
772    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
773    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
774
775    /* result == second operand */
776    TEST_ASSERT( mbedtls_mpi_sub_mpi( &Y, &X, &Y ) == 0 );
777    TEST_ASSERT( sign_is_valid( &Y ) );
778    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
779
780exit:
781    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
782}
783/* END_CASE */
784
785/* BEGIN_CASE */
786void mbedtls_mpi_sub_abs( int radix_X, char * input_X, int radix_Y,
787                          char * input_Y, int radix_A, char * input_A,
788                          int sub_result )
789{
790    mbedtls_mpi X, Y, Z, A;
791    int res;
792    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
793
794    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
795    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
796    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
797
798    res = mbedtls_mpi_sub_abs( &Z, &X, &Y );
799    TEST_ASSERT( res == sub_result );
800    TEST_ASSERT( sign_is_valid( &Z ) );
801    if( res == 0 )
802        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
803
804    /* result == first operand */
805    TEST_ASSERT( mbedtls_mpi_sub_abs( &X, &X, &Y ) == sub_result );
806    TEST_ASSERT( sign_is_valid( &X ) );
807    if( sub_result == 0 )
808        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
809    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
810
811    /* result == second operand */
812    TEST_ASSERT( mbedtls_mpi_sub_abs( &Y, &X, &Y ) == sub_result );
813    TEST_ASSERT( sign_is_valid( &Y ) );
814    if( sub_result == 0 )
815        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Y, &A ) == 0 );
816
817exit:
818    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
819}
820/* END_CASE */
821
822/* BEGIN_CASE */
823void mbedtls_mpi_sub_int( int radix_X, char * input_X, int input_Y,
824                          int radix_A, char * input_A )
825{
826    mbedtls_mpi X, Z, A;
827    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
828
829    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
830    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
831    TEST_ASSERT( mbedtls_mpi_sub_int( &Z, &X, input_Y ) == 0 );
832    TEST_ASSERT( sign_is_valid( &Z ) );
833    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
834
835exit:
836    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
837}
838/* END_CASE */
839
840/* BEGIN_CASE */
841void mbedtls_mpi_mul_mpi( int radix_X, char * input_X, int radix_Y,
842                          char * input_Y, int radix_A, char * input_A )
843{
844    mbedtls_mpi X, Y, Z, A;
845    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
846
847    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
848    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
849    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
850    TEST_ASSERT( mbedtls_mpi_mul_mpi( &Z, &X, &Y ) == 0 );
851    TEST_ASSERT( sign_is_valid( &Z ) );
852    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
853
854exit:
855    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
856}
857/* END_CASE */
858
859/* BEGIN_CASE */
860void mbedtls_mpi_mul_int( int radix_X, char * input_X, int input_Y,
861                          int radix_A, char * input_A,
862                          char * result_comparison )
863{
864    mbedtls_mpi X, Z, A;
865    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
866
867    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
868    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
869    TEST_ASSERT( mbedtls_mpi_mul_int( &Z, &X, input_Y ) == 0 );
870    TEST_ASSERT( sign_is_valid( &Z ) );
871    if( strcmp( result_comparison, "==" ) == 0 )
872        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
873    else if( strcmp( result_comparison, "!=" ) == 0 )
874        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) != 0 );
875    else
876        TEST_ASSERT( "unknown operator" == 0 );
877
878exit:
879    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
880}
881/* END_CASE */
882
883/* BEGIN_CASE */
884void mbedtls_mpi_div_mpi( int radix_X, char * input_X, int radix_Y,
885                          char * input_Y, int radix_A, char * input_A,
886                          int radix_B, char * input_B, int div_result )
887{
888    mbedtls_mpi X, Y, Q, R, A, B;
889    int res;
890    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R );
891    mbedtls_mpi_init( &A ); mbedtls_mpi_init( &B );
892
893    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
894    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
895    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
896    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
897    res = mbedtls_mpi_div_mpi( &Q, &R, &X, &Y );
898    TEST_ASSERT( res == div_result );
899    if( res == 0 )
900    {
901        TEST_ASSERT( sign_is_valid( &Q ) );
902        TEST_ASSERT( sign_is_valid( &R ) );
903        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
904        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
905    }
906
907exit:
908    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R );
909    mbedtls_mpi_free( &A ); mbedtls_mpi_free( &B );
910}
911/* END_CASE */
912
913/* BEGIN_CASE */
914void mbedtls_mpi_div_int( int radix_X, char * input_X, int input_Y,
915                          int radix_A, char * input_A, int radix_B,
916                          char * input_B, int div_result )
917{
918    mbedtls_mpi X, Q, R, A, B;
919    int res;
920    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Q ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &A );
921    mbedtls_mpi_init( &B );
922
923    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
924    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
925    TEST_ASSERT( mbedtls_test_read_mpi( &B, radix_B, input_B ) == 0 );
926    res = mbedtls_mpi_div_int( &Q, &R, &X, input_Y );
927    TEST_ASSERT( res == div_result );
928    if( res == 0 )
929    {
930        TEST_ASSERT( sign_is_valid( &Q ) );
931        TEST_ASSERT( sign_is_valid( &R ) );
932        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Q, &A ) == 0 );
933        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &R, &B ) == 0 );
934    }
935
936exit:
937    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Q ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &A );
938    mbedtls_mpi_free( &B );
939}
940/* END_CASE */
941
942/* BEGIN_CASE */
943void mbedtls_mpi_mod_mpi( int radix_X, char * input_X, int radix_Y,
944                          char * input_Y, int radix_A, char * input_A,
945                          int div_result )
946{
947    mbedtls_mpi X, Y, A;
948    int res;
949    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &A );
950
951    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
952    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
953    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
954    res = mbedtls_mpi_mod_mpi( &X, &X, &Y );
955    TEST_ASSERT( res == div_result );
956    if( res == 0 )
957    {
958        TEST_ASSERT( sign_is_valid( &X ) );
959        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
960    }
961
962exit:
963    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &A );
964}
965/* END_CASE */
966
967/* BEGIN_CASE */
968void mbedtls_mpi_mod_int( int radix_X, char * input_X, int input_Y,
969                          int input_A, int div_result )
970{
971    mbedtls_mpi X;
972    int res;
973    mbedtls_mpi_uint r;
974    mbedtls_mpi_init( &X );
975
976    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
977    res = mbedtls_mpi_mod_int( &r, &X, input_Y );
978    TEST_ASSERT( res == div_result );
979    if( res == 0 )
980    {
981        TEST_ASSERT( r == (mbedtls_mpi_uint) input_A );
982    }
983
984exit:
985    mbedtls_mpi_free( &X );
986}
987/* END_CASE */
988
989/* BEGIN_CASE */
990void mbedtls_mpi_exp_mod( int radix_A, char * input_A, int radix_E,
991                          char * input_E, int radix_N, char * input_N,
992                          int radix_X, char * input_X, int exp_result )
993{
994    mbedtls_mpi A, E, N, RR, Z, X;
995    int res;
996    mbedtls_mpi_init( &A  ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
997    mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &X );
998
999    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
1000    TEST_ASSERT( mbedtls_test_read_mpi( &E, radix_E, input_E ) == 0 );
1001    TEST_ASSERT( mbedtls_test_read_mpi( &N, radix_N, input_N ) == 0 );
1002    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1003
1004    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, NULL );
1005    TEST_ASSERT( res == exp_result );
1006    if( res == 0 )
1007    {
1008        TEST_ASSERT( sign_is_valid( &Z ) );
1009        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1010    }
1011
1012    /* Now test again with the speed-up parameter supplied as an output. */
1013    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
1014    TEST_ASSERT( res == exp_result );
1015    if( res == 0 )
1016    {
1017        TEST_ASSERT( sign_is_valid( &Z ) );
1018        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1019    }
1020
1021    /* Now test again with the speed-up parameter supplied in calculated form. */
1022    res = mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR );
1023    TEST_ASSERT( res == exp_result );
1024    if( res == 0 )
1025    {
1026        TEST_ASSERT( sign_is_valid( &Z ) );
1027        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &X ) == 0 );
1028    }
1029
1030exit:
1031    mbedtls_mpi_free( &A  ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1032    mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &X );
1033}
1034/* END_CASE */
1035
1036/* BEGIN_CASE */
1037void mbedtls_mpi_exp_mod_size( int A_bytes, int E_bytes, int N_bytes,
1038                               int radix_RR, char * input_RR, int exp_result )
1039{
1040    mbedtls_mpi A, E, N, RR, Z;
1041    mbedtls_mpi_init( &A  ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N );
1042    mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &Z );
1043
1044    /* Set A to 2^(A_bytes - 1) + 1 */
1045    TEST_ASSERT( mbedtls_mpi_lset( &A, 1 ) == 0 );
1046    TEST_ASSERT( mbedtls_mpi_shift_l( &A, ( A_bytes * 8 ) - 1 ) == 0 );
1047    TEST_ASSERT( mbedtls_mpi_set_bit( &A, 0, 1 ) == 0 );
1048
1049    /* Set E to 2^(E_bytes - 1) + 1 */
1050    TEST_ASSERT( mbedtls_mpi_lset( &E, 1 ) == 0 );
1051    TEST_ASSERT( mbedtls_mpi_shift_l( &E, ( E_bytes * 8 ) - 1 ) == 0 );
1052    TEST_ASSERT( mbedtls_mpi_set_bit( &E, 0, 1 ) == 0 );
1053
1054    /* Set N to 2^(N_bytes - 1) + 1 */
1055    TEST_ASSERT( mbedtls_mpi_lset( &N, 1 ) == 0 );
1056    TEST_ASSERT( mbedtls_mpi_shift_l( &N, ( N_bytes * 8 ) - 1 ) == 0 );
1057    TEST_ASSERT( mbedtls_mpi_set_bit( &N, 0, 1 ) == 0 );
1058
1059    if( strlen( input_RR ) )
1060        TEST_ASSERT( mbedtls_test_read_mpi( &RR, radix_RR, input_RR ) == 0 );
1061
1062    TEST_ASSERT( mbedtls_mpi_exp_mod( &Z, &A, &E, &N, &RR ) == exp_result );
1063
1064exit:
1065    mbedtls_mpi_free( &A  ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N );
1066    mbedtls_mpi_free( &RR ); mbedtls_mpi_free( &Z );
1067}
1068/* END_CASE */
1069
1070/* BEGIN_CASE */
1071void mbedtls_mpi_inv_mod( int radix_X, char * input_X, int radix_Y,
1072                          char * input_Y, int radix_A, char * input_A,
1073                          int div_result )
1074{
1075    mbedtls_mpi X, Y, Z, A;
1076    int res;
1077    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); mbedtls_mpi_init( &A );
1078
1079    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1080    TEST_ASSERT( mbedtls_test_read_mpi( &Y, radix_Y, input_Y ) == 0 );
1081    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
1082    res = mbedtls_mpi_inv_mod( &Z, &X, &Y );
1083    TEST_ASSERT( res == div_result );
1084    if( res == 0 )
1085    {
1086        TEST_ASSERT( sign_is_valid( &Z ) );
1087        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &Z, &A ) == 0 );
1088    }
1089
1090exit:
1091    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); mbedtls_mpi_free( &A );
1092}
1093/* END_CASE */
1094
1095/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
1096void mbedtls_mpi_is_prime( int radix_X, char * input_X, int div_result )
1097{
1098    mbedtls_mpi X;
1099    int res;
1100    mbedtls_mpi_init( &X );
1101
1102    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1103    res = mbedtls_mpi_is_prime_ext( &X, 40, mbedtls_test_rnd_std_rand, NULL );
1104    TEST_ASSERT( res == div_result );
1105
1106exit:
1107    mbedtls_mpi_free( &X );
1108}
1109/* END_CASE */
1110
1111/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
1112void mbedtls_mpi_is_prime_det( data_t * input_X, data_t * witnesses,
1113                               int chunk_len, int rounds )
1114{
1115    mbedtls_mpi X;
1116    int res;
1117    mbedtls_test_mpi_random rand;
1118
1119    mbedtls_mpi_init( &X );
1120    rand.data = witnesses;
1121    rand.pos = 0;
1122    rand.chunk_len = chunk_len;
1123
1124    TEST_ASSERT( mbedtls_mpi_read_binary( &X, input_X->x, input_X->len ) == 0 );
1125    res = mbedtls_mpi_is_prime_ext( &X, rounds - 1,
1126                                    mbedtls_test_mpi_miller_rabin_determinizer,
1127                                    &rand );
1128    TEST_ASSERT( res == 0 );
1129
1130    rand.data = witnesses;
1131    rand.pos = 0;
1132    rand.chunk_len = chunk_len;
1133
1134    res = mbedtls_mpi_is_prime_ext( &X, rounds,
1135                                    mbedtls_test_mpi_miller_rabin_determinizer,
1136                                    &rand );
1137    TEST_ASSERT( res == MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
1138
1139exit:
1140    mbedtls_mpi_free( &X );
1141}
1142/* END_CASE */
1143
1144/* BEGIN_CASE depends_on:MBEDTLS_GENPRIME */
1145void mbedtls_mpi_gen_prime( int bits, int flags, int ref_ret )
1146{
1147    mbedtls_mpi X;
1148    int my_ret;
1149
1150    mbedtls_mpi_init( &X );
1151
1152    my_ret = mbedtls_mpi_gen_prime( &X, bits, flags,
1153                                    mbedtls_test_rnd_std_rand, NULL );
1154    TEST_ASSERT( my_ret == ref_ret );
1155
1156    if( ref_ret == 0 )
1157    {
1158        size_t actual_bits = mbedtls_mpi_bitlen( &X );
1159
1160        TEST_ASSERT( actual_bits >= (size_t) bits );
1161        TEST_ASSERT( actual_bits <= (size_t) bits + 1 );
1162        TEST_ASSERT( sign_is_valid( &X ) );
1163
1164        TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1165                                               mbedtls_test_rnd_std_rand,
1166                                               NULL ) == 0 );
1167        if( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH )
1168        {
1169            /* X = ( X - 1 ) / 2 */
1170            TEST_ASSERT( mbedtls_mpi_shift_r( &X, 1 ) == 0 );
1171            TEST_ASSERT( mbedtls_mpi_is_prime_ext( &X, 40,
1172                                                   mbedtls_test_rnd_std_rand,
1173                                                   NULL ) == 0 );
1174        }
1175    }
1176
1177exit:
1178    mbedtls_mpi_free( &X );
1179}
1180/* END_CASE */
1181
1182/* BEGIN_CASE */
1183void mbedtls_mpi_shift_l( int radix_X, char * input_X, int shift_X,
1184                          int radix_A, char * input_A )
1185{
1186    mbedtls_mpi X, A;
1187    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1188
1189    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1190    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
1191    TEST_ASSERT( mbedtls_mpi_shift_l( &X, shift_X ) == 0 );
1192    TEST_ASSERT( sign_is_valid( &X ) );
1193    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1194
1195exit:
1196    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1197}
1198/* END_CASE */
1199
1200/* BEGIN_CASE */
1201void mbedtls_mpi_shift_r( int radix_X, char * input_X, int shift_X,
1202                          int radix_A, char * input_A )
1203{
1204    mbedtls_mpi X, A;
1205    mbedtls_mpi_init( &X ); mbedtls_mpi_init( &A );
1206
1207    TEST_ASSERT( mbedtls_test_read_mpi( &X, radix_X, input_X ) == 0 );
1208    TEST_ASSERT( mbedtls_test_read_mpi( &A, radix_A, input_A ) == 0 );
1209    TEST_ASSERT( mbedtls_mpi_shift_r( &X, shift_X ) == 0 );
1210    TEST_ASSERT( sign_is_valid( &X ) );
1211    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &X, &A ) == 0 );
1212
1213exit:
1214    mbedtls_mpi_free( &X ); mbedtls_mpi_free( &A );
1215}
1216/* END_CASE */
1217
1218/* BEGIN_CASE */
1219void mpi_fill_random( int wanted_bytes, int rng_bytes,
1220                      int before, int expected_ret )
1221{
1222    mbedtls_mpi X;
1223    int ret;
1224    size_t bytes_left = rng_bytes;
1225    mbedtls_mpi_init( &X );
1226
1227    if( before != 0 )
1228    {
1229        /* Set X to sign(before) * 2^(|before|-1) */
1230        TEST_ASSERT( mbedtls_mpi_lset( &X, before > 0 ? 1 : -1 ) == 0 );
1231        if( before < 0 )
1232            before = - before;
1233        TEST_ASSERT( mbedtls_mpi_shift_l( &X, before - 1 ) == 0 );
1234    }
1235
1236    ret = mbedtls_mpi_fill_random( &X, wanted_bytes,
1237                                   f_rng_bytes_left, &bytes_left );
1238    TEST_ASSERT( ret == expected_ret );
1239
1240    if( expected_ret == 0 )
1241    {
1242        /* mbedtls_mpi_fill_random is documented to use bytes from the RNG
1243         * as a big-endian representation of the number. We know when
1244         * our RNG function returns null bytes, so we know how many
1245         * leading zero bytes the number has. */
1246        size_t leading_zeros = 0;
1247        if( wanted_bytes > 0 && rng_bytes % 256 == 0 )
1248            leading_zeros = 1;
1249        TEST_ASSERT( mbedtls_mpi_size( &X ) + leading_zeros ==
1250                     (size_t) wanted_bytes );
1251        TEST_ASSERT( (int) bytes_left == rng_bytes - wanted_bytes );
1252        TEST_ASSERT( sign_is_valid( &X ) );
1253    }
1254
1255exit:
1256    mbedtls_mpi_free( &X );
1257}
1258/* END_CASE */
1259
1260/* BEGIN_CASE */
1261void mpi_random_many( int min, data_t *bound_bytes, int iterations )
1262{
1263    /* Generate numbers in the range 1..bound-1. Do it iterations times.
1264     * This function assumes that the value of bound is at least 2 and
1265     * that iterations is large enough that a one-in-2^iterations chance
1266     * effectively never occurs.
1267     */
1268
1269    mbedtls_mpi upper_bound;
1270    size_t n_bits;
1271    mbedtls_mpi result;
1272    size_t b;
1273    /* If upper_bound is small, stats[b] is the number of times the value b
1274     * has been generated. Otherwise stats[b] is the number of times a
1275     * value with bit b set has been generated. */
1276    size_t *stats = NULL;
1277    size_t stats_len;
1278    int full_stats;
1279    size_t i;
1280
1281    mbedtls_mpi_init( &upper_bound );
1282    mbedtls_mpi_init( &result );
1283
1284    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1285                                            bound_bytes->x, bound_bytes->len ) );
1286    n_bits = mbedtls_mpi_bitlen( &upper_bound );
1287    /* Consider a bound "small" if it's less than 2^5. This value is chosen
1288     * to be small enough that the probability of missing one value is
1289     * negligible given the number of iterations. It must be less than
1290     * 256 because some of the code below assumes that "small" values
1291     * fit in a byte. */
1292    if( n_bits <= 5 )
1293    {
1294        full_stats = 1;
1295        stats_len = bound_bytes->x[bound_bytes->len - 1];
1296    }
1297    else
1298    {
1299        full_stats = 0;
1300        stats_len = n_bits;
1301    }
1302    ASSERT_ALLOC( stats, stats_len );
1303
1304    for( i = 0; i < (size_t) iterations; i++ )
1305    {
1306        mbedtls_test_set_step( i );
1307        TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1308                                           mbedtls_test_rnd_std_rand, NULL ) );
1309
1310        TEST_ASSERT( sign_is_valid( &result ) );
1311        TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1312        TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1313        if( full_stats )
1314        {
1315            uint8_t value;
1316            TEST_EQUAL( 0, mbedtls_mpi_write_binary( &result, &value, 1 ) );
1317            TEST_ASSERT( value < stats_len );
1318            ++stats[value];
1319        }
1320        else
1321        {
1322            for( b = 0; b < n_bits; b++ )
1323                stats[b] += mbedtls_mpi_get_bit( &result, b );
1324        }
1325    }
1326
1327    if( full_stats )
1328    {
1329        for( b = min; b < stats_len; b++ )
1330        {
1331            mbedtls_test_set_step( 1000000 + b );
1332            /* Assert that each value has been reached at least once.
1333             * This is almost guaranteed if the iteration count is large
1334             * enough. This is a very crude way of checking the distribution.
1335             */
1336            TEST_ASSERT( stats[b] > 0 );
1337        }
1338    }
1339    else
1340    {
1341        int statistically_safe_all_the_way =
1342            is_significantly_above_a_power_of_2( bound_bytes );
1343        for( b = 0; b < n_bits; b++ )
1344        {
1345            mbedtls_test_set_step( 1000000 + b );
1346            /* Assert that each bit has been set in at least one result and
1347             * clear in at least one result. Provided that iterations is not
1348             * too small, it would be extremely unlikely for this not to be
1349             * the case if the results are uniformly distributed.
1350             *
1351             * As an exception, the top bit may legitimately never be set
1352             * if bound is a power of 2 or only slightly above.
1353             */
1354            if( statistically_safe_all_the_way || b != n_bits - 1 )
1355            {
1356                TEST_ASSERT( stats[b] > 0 );
1357            }
1358            TEST_ASSERT( stats[b] < (size_t) iterations );
1359        }
1360    }
1361
1362exit:
1363    mbedtls_mpi_free( &upper_bound );
1364    mbedtls_mpi_free( &result );
1365    mbedtls_free( stats );
1366}
1367/* END_CASE */
1368
1369/* BEGIN_CASE */
1370void mpi_random_sizes( int min, data_t *bound_bytes, int nlimbs, int before )
1371{
1372    mbedtls_mpi upper_bound;
1373    mbedtls_mpi result;
1374
1375    mbedtls_mpi_init( &upper_bound );
1376    mbedtls_mpi_init( &result );
1377
1378    if( before != 0 )
1379    {
1380        /* Set result to sign(before) * 2^(|before|-1) */
1381        TEST_ASSERT( mbedtls_mpi_lset( &result, before > 0 ? 1 : -1 ) == 0 );
1382        if( before < 0 )
1383            before = - before;
1384        TEST_ASSERT( mbedtls_mpi_shift_l( &result, before - 1 ) == 0 );
1385    }
1386
1387    TEST_EQUAL( 0, mbedtls_mpi_grow( &result, nlimbs ) );
1388    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1389                                            bound_bytes->x, bound_bytes->len ) );
1390    TEST_EQUAL( 0, mbedtls_mpi_random( &result, min, &upper_bound,
1391                                       mbedtls_test_rnd_std_rand, NULL ) );
1392    TEST_ASSERT( sign_is_valid( &result ) );
1393    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &result, &upper_bound ) < 0 );
1394    TEST_ASSERT( mbedtls_mpi_cmp_int( &result, min ) >= 0 );
1395
1396exit:
1397    mbedtls_mpi_free( &upper_bound );
1398    mbedtls_mpi_free( &result );
1399}
1400/* END_CASE */
1401
1402/* BEGIN_CASE */
1403void mpi_random_fail( int min, data_t *bound_bytes, int expected_ret )
1404{
1405    mbedtls_mpi upper_bound;
1406    mbedtls_mpi result;
1407    int actual_ret;
1408
1409    mbedtls_mpi_init( &upper_bound );
1410    mbedtls_mpi_init( &result );
1411
1412    TEST_EQUAL( 0, mbedtls_mpi_read_binary( &upper_bound,
1413                                            bound_bytes->x, bound_bytes->len ) );
1414    actual_ret = mbedtls_mpi_random( &result, min, &upper_bound,
1415                                     mbedtls_test_rnd_std_rand, NULL );
1416    TEST_EQUAL( expected_ret, actual_ret );
1417
1418exit:
1419    mbedtls_mpi_free( &upper_bound );
1420    mbedtls_mpi_free( &result );
1421}
1422/* END_CASE */
1423
1424/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
1425void mpi_selftest(  )
1426{
1427    TEST_ASSERT( mbedtls_mpi_self_test( 1 ) == 0 );
1428}
1429/* END_CASE */
1430