• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* BEGIN_HEADER */
2#include "mbedtls/bignum.h"
3#include "mbedtls/entropy.h"
4#include "bignum_core.h"
5#include "constant_time_internal.h"
6#include "test/constant_flow.h"
7
8/** Verifies mbedtls_mpi_core_add().
9 *
10 * \param[in] A       Little-endian presentation of the left operand.
11 * \param[in] B       Little-endian presentation of the right operand.
12 * \param limbs       Number of limbs in each MPI (\p A, \p B, \p S and \p X).
13 * \param[in] S       Little-endian presentation of the expected sum.
14 * \param carry       Expected carry from the addition.
15 * \param[in,out] X   Temporary storage to be used for results.
16 *
17 * \return  1 if mbedtls_mpi_core_add() passes this test, otherwise 0.
18 */
19static int mpi_core_verify_add( mbedtls_mpi_uint *A,
20                                mbedtls_mpi_uint *B,
21                                size_t limbs,
22                                mbedtls_mpi_uint *S,
23                                int carry,
24                                mbedtls_mpi_uint *X )
25{
26    int ret = 0;
27
28    size_t bytes = limbs * sizeof( *A );
29
30    /* The test cases have A <= B to avoid repetition, so we test A + B then,
31     * if A != B, B + A. If A == B, we can test when A and B are aliased */
32
33    /* A + B */
34
35    /* A + B => correct result and carry */
36    TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, B, limbs ) );
37    ASSERT_COMPARE( X, bytes, S, bytes );
38
39    /* A + B; alias output and first operand => correct result and carry */
40    memcpy( X, A, bytes );
41    TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, B, limbs ) );
42    ASSERT_COMPARE( X, bytes, S, bytes );
43
44    /* A + B; alias output and second operand => correct result and carry */
45    memcpy( X, B, bytes );
46    TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, X, limbs ) );
47    ASSERT_COMPARE( X, bytes, S, bytes );
48
49    if ( memcmp( A, B, bytes ) == 0 )
50    {
51        /* A == B, so test where A and B are aliased */
52
53        /* A + A => correct result and carry */
54        TEST_EQUAL( carry, mbedtls_mpi_core_add( X, A, A, limbs ) );
55        ASSERT_COMPARE( X, bytes, S, bytes );
56
57        /* A + A, output aliased to both operands => correct result and carry */
58        memcpy( X, A, bytes );
59        TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, X, limbs ) );
60        ASSERT_COMPARE( X, bytes, S, bytes );
61    }
62    else
63    {
64        /* A != B, so test B + A */
65
66        /* B + A => correct result and carry */
67        TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, A, limbs ) );
68        ASSERT_COMPARE( X, bytes, S, bytes );
69
70        /* B + A; alias output and first operand => correct result and carry */
71        memcpy( X, B, bytes );
72        TEST_EQUAL( carry, mbedtls_mpi_core_add( X, X, A, limbs ) );
73        ASSERT_COMPARE( X, bytes, S, bytes );
74
75        /* B + A; alias output and second operand => correct result and carry */
76        memcpy( X, A, bytes );
77        TEST_EQUAL( carry, mbedtls_mpi_core_add( X, B, X, limbs ) );
78        ASSERT_COMPARE( X, bytes, S, bytes );
79    }
80
81    ret = 1;
82
83exit:
84    return ret;
85}
86
87/** Verifies mbedtls_mpi_core_add_if().
88 *
89 * \param[in] A       Little-endian presentation of the left operand.
90 * \param[in] B       Little-endian presentation of the right operand.
91 * \param limbs       Number of limbs in each MPI (\p A, \p B, \p S and \p X).
92 * \param[in] S       Little-endian presentation of the expected sum.
93 * \param carry       Expected carry from the addition.
94 * \param[in,out] X   Temporary storage to be used for results.
95 *
96 * \return  1 if mbedtls_mpi_core_add_if() passes this test, otherwise 0.
97 */
98static int mpi_core_verify_add_if( mbedtls_mpi_uint *A,
99                                   mbedtls_mpi_uint *B,
100                                   size_t limbs,
101                                   mbedtls_mpi_uint *S,
102                                   int carry,
103                                   mbedtls_mpi_uint *X )
104{
105    int ret = 0;
106
107    size_t bytes = limbs * sizeof( *A );
108
109    /* The test cases have A <= B to avoid repetition, so we test A + B then,
110     * if A != B, B + A. If A == B, we can test when A and B are aliased */
111
112    /* A + B */
113
114    /* cond = 0 => X unchanged, no carry */
115    memcpy( X, A, bytes );
116    TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, B, limbs, 0 ) );
117    ASSERT_COMPARE( X, bytes, A, bytes );
118
119    /* cond = 1 => correct result and carry */
120    TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, B, limbs, 1 ) );
121    ASSERT_COMPARE( X, bytes, S, bytes );
122
123    if ( memcmp( A, B, bytes ) == 0 )
124    {
125        /* A == B, so test where A and B are aliased */
126
127        /* cond = 0 => X unchanged, no carry */
128        memcpy( X, B, bytes );
129        TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, X, limbs, 0 ) );
130        ASSERT_COMPARE( X, bytes, B, bytes );
131
132        /* cond = 1 => correct result and carry */
133        TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, X, limbs, 1 ) );
134        ASSERT_COMPARE( X, bytes, S, bytes );
135    }
136    else
137    {
138        /* A != B, so test B + A */
139
140        /* cond = 0 => d unchanged, no carry */
141        memcpy( X, B, bytes );
142        TEST_EQUAL( 0, mbedtls_mpi_core_add_if( X, A, limbs, 0 ) );
143        ASSERT_COMPARE( X, bytes, B, bytes );
144
145        /* cond = 1 => correct result and carry */
146        TEST_EQUAL( carry, mbedtls_mpi_core_add_if( X, A, limbs, 1 ) );
147        ASSERT_COMPARE( X, bytes, S, bytes );
148    }
149
150    ret = 1;
151
152exit:
153    return ret;
154}
155
156/* END_HEADER */
157
158/* BEGIN_DEPENDENCIES
159 * depends_on:MBEDTLS_BIGNUM_C
160 * END_DEPENDENCIES
161 */
162
163/* BEGIN_CASE */
164void mpi_core_io_null()
165{
166    mbedtls_mpi_uint X = 0;
167    int ret;
168
169    ret = mbedtls_mpi_core_read_be( &X, 1, NULL, 0 );
170    TEST_EQUAL( ret, 0 );
171    ret = mbedtls_mpi_core_write_be( &X, 1, NULL, 0 );
172    TEST_EQUAL( ret, 0 );
173
174    ret = mbedtls_mpi_core_read_be( NULL, 0, NULL, 0 );
175    TEST_EQUAL( ret, 0 );
176    ret = mbedtls_mpi_core_write_be( NULL, 0, NULL, 0 );
177    TEST_EQUAL( ret, 0 );
178
179    ret = mbedtls_mpi_core_read_le( &X, 1, NULL, 0 );
180    TEST_EQUAL( ret, 0 );
181    ret = mbedtls_mpi_core_write_le( &X, 1, NULL, 0 );
182    TEST_EQUAL( ret, 0 );
183
184    ret = mbedtls_mpi_core_read_le( NULL, 0, NULL, 0 );
185    TEST_EQUAL( ret, 0 );
186    ret = mbedtls_mpi_core_write_le( NULL, 0, NULL, 0 );
187    TEST_EQUAL( ret, 0 );
188
189exit:
190    ;
191}
192/* END_CASE */
193
194/* BEGIN_CASE */
195void mpi_core_io_be( data_t *input, int nb_int, int nx_32_int, int iret,
196                     int oret )
197{
198    if( iret != 0 )
199        TEST_ASSERT( oret == 0 );
200
201    TEST_LE_S( 0, nb_int );
202    size_t nb = nb_int;
203
204    unsigned char buf[1024];
205    TEST_LE_U( nb, sizeof( buf ) );
206
207    /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
208     * to halve the number of limbs to have the same size. */
209    size_t nx;
210    TEST_LE_S( 0, nx_32_int );
211    if( sizeof( mbedtls_mpi_uint ) == 8 )
212        nx = nx_32_int / 2 + nx_32_int % 2;
213    else
214        nx = nx_32_int;
215
216    mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
217    TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
218
219    int ret = mbedtls_mpi_core_read_be( X, nx, input->x, input->len );
220    TEST_EQUAL( ret, iret );
221
222    if( iret == 0 )
223    {
224        ret =  mbedtls_mpi_core_write_be( X, nx, buf, nb );
225        TEST_EQUAL( ret, oret );
226    }
227
228    if( ( iret == 0 ) && ( oret == 0 ) )
229    {
230        if( nb > input->len )
231        {
232            size_t leading_zeroes = nb - input->len;
233            TEST_ASSERT( memcmp( buf + nb - input->len, input->x, input->len ) == 0 );
234            for( size_t i = 0; i < leading_zeroes; i++ )
235                TEST_EQUAL( buf[i], 0 );
236        }
237        else
238        {
239            size_t leading_zeroes = input->len - nb;
240            TEST_ASSERT( memcmp( input->x + input->len - nb, buf, nb ) == 0 );
241            for( size_t i = 0; i < leading_zeroes; i++ )
242                TEST_EQUAL( input->x[i], 0 );
243        }
244    }
245
246exit:
247    ;
248}
249/* END_CASE */
250
251/* BEGIN_CASE */
252void mpi_core_io_le( data_t *input, int nb_int, int nx_32_int, int iret,
253                     int oret )
254{
255    if( iret != 0 )
256        TEST_ASSERT( oret == 0 );
257
258    TEST_LE_S( 0, nb_int );
259    size_t nb = nb_int;
260
261    unsigned char buf[1024];
262    TEST_LE_U( nb, sizeof( buf ) );
263
264    /* nx_32_int is the number of 32 bit limbs, if we have 64 bit limbs we need
265     * to halve the number of limbs to have the same size. */
266    size_t nx;
267    TEST_LE_S( 0, nx_32_int );
268    if( sizeof( mbedtls_mpi_uint ) == 8 )
269        nx = nx_32_int / 2 + nx_32_int % 2;
270    else
271        nx = nx_32_int;
272
273    mbedtls_mpi_uint X[sizeof( buf ) / sizeof( mbedtls_mpi_uint )];
274    TEST_LE_U( nx, sizeof( X ) / sizeof( X[0] ) );
275
276    int ret =  mbedtls_mpi_core_read_le( X, nx, input->x, input->len );
277    TEST_EQUAL( ret, iret );
278
279    if( iret == 0 )
280    {
281        ret =  mbedtls_mpi_core_write_le( X, nx, buf, nb );
282        TEST_EQUAL( ret, oret );
283    }
284
285    if( ( iret == 0 ) && ( oret == 0 ) )
286    {
287        if( nb > input->len )
288        {
289            TEST_ASSERT( memcmp( buf, input->x, input->len ) == 0 );
290            for( size_t i = input->len; i < nb; i++ )
291                TEST_EQUAL( buf[i], 0 );
292        }
293        else
294        {
295            TEST_ASSERT( memcmp( input->x, buf, nb ) == 0 );
296            for( size_t i = nb; i < input->len; i++ )
297                TEST_EQUAL( input->x[i], 0 );
298        }
299    }
300
301exit:
302    ;
303}
304/* END_CASE */
305
306/* BEGIN_CASE */
307void mpi_core_bitlen( char *input_X, int nr_bits )
308{
309    mbedtls_mpi_uint *X = NULL;
310    size_t limbs;
311
312    TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs, input_X ), 0 );
313    TEST_EQUAL( mbedtls_mpi_core_bitlen( X, limbs ), nr_bits );
314
315exit:
316    mbedtls_free( X );
317}
318/* END_CASE */
319
320/* BEGIN_CASE */
321void mpi_core_lt_ct( char *input_X, char *input_Y, int exp_ret )
322{
323    mbedtls_mpi_uint *X = NULL;
324    size_t X_limbs;
325    mbedtls_mpi_uint *Y = NULL;
326    size_t Y_limbs;
327    int ret;
328
329    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
330    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &Y, &Y_limbs, input_Y ) );
331
332    /* We need two same-length limb arrays */
333    TEST_EQUAL( X_limbs, Y_limbs );
334
335    TEST_CF_SECRET( X, X_limbs * sizeof( mbedtls_mpi_uint ) );
336    TEST_CF_SECRET( Y, X_limbs * sizeof( mbedtls_mpi_uint ) );
337
338    ret = mbedtls_mpi_core_lt_ct( X, Y, X_limbs );
339    TEST_EQUAL( ret, exp_ret );
340
341exit:
342    mbedtls_free( X );
343    mbedtls_free( Y );
344}
345/* END_CASE */
346
347/* BEGIN_CASE */
348void mpi_core_cond_assign( char * input_X,
349                           char * input_Y,
350                           int input_bytes )
351{
352    mbedtls_mpi_uint *X = NULL;
353    mbedtls_mpi_uint *Y = NULL;
354    size_t limbs_X;
355    size_t limbs_Y;
356
357    TEST_EQUAL( mbedtls_test_read_mpi_core( &X, &limbs_X, input_X ), 0 );
358    TEST_EQUAL( mbedtls_test_read_mpi_core( &Y, &limbs_Y, input_Y ), 0 );
359
360    size_t limbs = limbs_X;
361    size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
362    size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
363    size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
364
365    TEST_EQUAL( limbs_X, limbs_Y );
366    TEST_ASSERT( copy_limbs <= limbs );
367
368    /* condition is false */
369    TEST_CF_SECRET( X, bytes );
370    TEST_CF_SECRET( Y, bytes );
371
372    mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 0 );
373
374    TEST_CF_PUBLIC( X, bytes );
375    TEST_CF_PUBLIC( Y, bytes );
376
377    TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
378
379    /* condition is true */
380    TEST_CF_SECRET( X, bytes );
381    TEST_CF_SECRET( Y, bytes );
382
383    mbedtls_mpi_core_cond_assign( X, Y, copy_limbs, 1 );
384
385    TEST_CF_PUBLIC( X, bytes );
386    TEST_CF_PUBLIC( Y, bytes );
387
388    /* Check if the given length is copied even it is smaller
389       than the length of the given MPIs. */
390    if( copy_limbs < limbs )
391    {
392        TEST_CF_PUBLIC( X, bytes );
393        TEST_CF_PUBLIC( Y, bytes );
394
395        ASSERT_COMPARE( X, copy_bytes, Y, copy_bytes );
396        TEST_ASSERT( memcmp( X, Y, bytes ) != 0 );
397    }
398    else
399        ASSERT_COMPARE( X, bytes, Y, bytes );
400
401exit:
402    mbedtls_free( X );
403    mbedtls_free( Y );
404}
405/* END_CASE */
406
407/* BEGIN_CASE */
408void mpi_core_cond_swap( char * input_X,
409                         char * input_Y,
410                         int input_bytes )
411{
412    mbedtls_mpi_uint *tmp_X = NULL;
413    mbedtls_mpi_uint *tmp_Y = NULL;
414    mbedtls_mpi_uint *X = NULL;
415    mbedtls_mpi_uint *Y = NULL;
416    size_t limbs_X;
417    size_t limbs_Y;
418
419    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_X, &limbs_X, input_X ), 0 );
420    TEST_EQUAL( mbedtls_test_read_mpi_core( &tmp_Y, &limbs_Y, input_Y ), 0 );
421
422    size_t limbs = limbs_X;
423    size_t copy_limbs = CHARS_TO_LIMBS( input_bytes );
424    size_t bytes = limbs * sizeof( mbedtls_mpi_uint );
425    size_t copy_bytes = copy_limbs * sizeof( mbedtls_mpi_uint );
426
427    TEST_EQUAL( limbs_X, limbs_Y );
428    TEST_ASSERT( copy_limbs <= limbs );
429
430    ASSERT_ALLOC( X, limbs );
431    memcpy( X, tmp_X, bytes );
432
433    ASSERT_ALLOC( Y, limbs );
434    memcpy( Y, tmp_Y, bytes );
435
436    /* condition is false */
437    TEST_CF_SECRET( X, bytes );
438    TEST_CF_SECRET( Y, bytes );
439
440    mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 0 );
441
442    TEST_CF_PUBLIC( X, bytes );
443    TEST_CF_PUBLIC( Y, bytes );
444
445    ASSERT_COMPARE( X, bytes, tmp_X, bytes );
446    ASSERT_COMPARE( Y, bytes, tmp_Y, bytes );
447
448    /* condition is true */
449    TEST_CF_SECRET( X, bytes );
450    TEST_CF_SECRET( Y, bytes );
451
452    mbedtls_mpi_core_cond_swap( X, Y, copy_limbs, 1 );
453
454    TEST_CF_PUBLIC( X, bytes );
455    TEST_CF_PUBLIC( Y, bytes );
456
457    /* Check if the given length is copied even it is smaller
458       than the length of the given MPIs. */
459    if( copy_limbs < limbs )
460    {
461        ASSERT_COMPARE( X, copy_bytes, tmp_Y, copy_bytes );
462        ASSERT_COMPARE( Y, copy_bytes, tmp_X, copy_bytes );
463        TEST_ASSERT( memcmp( X, tmp_X, bytes ) != 0 );
464        TEST_ASSERT( memcmp( X, tmp_Y, bytes ) != 0 );
465        TEST_ASSERT( memcmp( Y, tmp_X, bytes ) != 0 );
466        TEST_ASSERT( memcmp( Y, tmp_Y, bytes ) != 0 );
467    }
468    else
469    {
470        ASSERT_COMPARE( X, bytes, tmp_Y, bytes );
471        ASSERT_COMPARE( Y, bytes, tmp_X, bytes );
472    }
473
474exit:
475    mbedtls_free( tmp_X );
476    mbedtls_free( tmp_Y );
477    mbedtls_free( X );
478    mbedtls_free( Y );
479}
480/* END_CASE */
481
482/* BEGIN_CASE */
483void mpi_core_shift_r( char *input, int count, char *result )
484{
485    mbedtls_mpi_uint *X = NULL;
486    mbedtls_mpi_uint *Y = NULL;
487    size_t limbs, n;
488
489    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &limbs, input ) );
490    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &Y, &n, result ) );
491    TEST_EQUAL( limbs, n );
492
493    mbedtls_mpi_core_shift_r( X, limbs, count );
494    ASSERT_COMPARE( X, limbs * ciL, Y, limbs * ciL );
495
496exit:
497    mbedtls_free( X );
498    mbedtls_free( Y );
499}
500/* END_CASE */
501
502/* BEGIN_CASE */
503void mpi_core_add_and_add_if( char * input_A, char * input_B,
504                              char * input_S, int carry )
505{
506    mbedtls_mpi_uint *A = NULL; /* first value to add */
507    mbedtls_mpi_uint *B = NULL; /* second value to add */
508    mbedtls_mpi_uint *S = NULL; /* expected result */
509    mbedtls_mpi_uint *X = NULL; /* destination - the in/out first operand */
510    size_t A_limbs, B_limbs, S_limbs;
511
512    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
513    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) );
514    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &S, &S_limbs, input_S ) );
515
516    /* add and add_if expect all operands to be the same length */
517    TEST_EQUAL( A_limbs, B_limbs );
518    TEST_EQUAL( A_limbs, S_limbs );
519
520    size_t limbs = A_limbs;
521    ASSERT_ALLOC( X, limbs );
522
523    TEST_ASSERT( mpi_core_verify_add( A, B, limbs, S, carry, X ) );
524    TEST_ASSERT( mpi_core_verify_add_if( A, B, limbs, S, carry, X ) );
525
526exit:
527    mbedtls_free( A );
528    mbedtls_free( B );
529    mbedtls_free( S );
530    mbedtls_free( X );
531}
532/* END_CASE */
533
534/* BEGIN_CASE */
535void mpi_core_sub( char * input_A, char * input_B,
536                   char * input_X4, char * input_X8,
537                   int carry )
538{
539    mbedtls_mpi A, B, X4, X8;
540    mbedtls_mpi_uint *a = NULL;
541    mbedtls_mpi_uint *b = NULL;
542    mbedtls_mpi_uint *x = NULL; /* expected */
543    mbedtls_mpi_uint *r = NULL; /* result */
544
545    mbedtls_mpi_init( &A );
546    mbedtls_mpi_init( &B );
547    mbedtls_mpi_init( &X4 );
548    mbedtls_mpi_init( &X8 );
549
550    TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
551    TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
552    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
553    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
554
555    /* All of the inputs are +ve (or zero) */
556    TEST_EQUAL( 1, A.s );
557    TEST_EQUAL( 1, B.s );
558    TEST_EQUAL( 1, X4.s );
559    TEST_EQUAL( 1, X8.s );
560
561    /* Get the number of limbs we will need */
562    size_t limbs = MAX( A.n, B.n );
563    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
564
565    /* We only need to work with X4 or X8, depending on sizeof(mbedtls_mpi_uint) */
566    mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
567
568    /* The result shouldn't have more limbs than the longest input */
569    TEST_LE_U( X->n, limbs );
570
571    /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
572
573    /* ASSERT_ALLOC() uses calloc() under the hood, so these do get zeroed */
574    ASSERT_ALLOC( a, bytes );
575    ASSERT_ALLOC( b, bytes );
576    ASSERT_ALLOC( x, bytes );
577    ASSERT_ALLOC( r, bytes );
578
579    /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
580     * processed by mbedtls_mpi_core_sub()) are little endian, we can just
581     * copy what we have as long as MSBs are 0 (which they are from ASSERT_ALLOC())
582     */
583    memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
584    memcpy( b, B.p, B.n * sizeof(mbedtls_mpi_uint) );
585    memcpy( x, X->p, X->n * sizeof(mbedtls_mpi_uint) );
586
587    /* 1a) r = a - b => we should get the correct carry */
588    TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, a, b, limbs ) );
589
590    /* 1b) r = a - b => we should get the correct result */
591    ASSERT_COMPARE( r, bytes, x, bytes );
592
593    /* 2 and 3 test "r may be aliased to a or b" */
594    /* 2a) r = a; r -= b => we should get the correct carry (use r to avoid clobbering a) */
595    memcpy( r, a, bytes );
596    TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, r, b, limbs ) );
597
598    /* 2b) r -= b => we should get the correct result */
599    ASSERT_COMPARE( r, bytes, x, bytes );
600
601    /* 3a) r = b; r = a - r => we should get the correct carry (use r to avoid clobbering b) */
602    memcpy( r, b, bytes );
603    TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, a, r, limbs ) );
604
605    /* 3b) r = a - b => we should get the correct result */
606    ASSERT_COMPARE( r, bytes, x, bytes );
607
608    /* 4 tests "r may be aliased to [...] both" */
609    if ( A.n == B.n && memcmp( A.p, B.p, bytes ) == 0 )
610    {
611        memcpy( r, b, bytes );
612        TEST_EQUAL( carry, mbedtls_mpi_core_sub( r, r, r, limbs ) );
613        ASSERT_COMPARE( r, bytes, x, bytes );
614    }
615
616exit:
617    mbedtls_free( a );
618    mbedtls_free( b );
619    mbedtls_free( x );
620    mbedtls_free( r );
621
622    mbedtls_mpi_free( &A );
623    mbedtls_mpi_free( &B );
624    mbedtls_mpi_free( &X4 );
625    mbedtls_mpi_free( &X8 );
626}
627/* END_CASE */
628
629/* BEGIN_CASE */
630void mpi_core_mla( char * input_A, char * input_B, char * input_S,
631                   char * input_X4, char * input_cy4,
632                   char * input_X8, char * input_cy8 )
633{
634    /* We are testing A += B * s; A, B are MPIs, s is a scalar.
635     *
636     * However, we encode s as an MPI in the .data file as the test framework
637     * currently only supports `int`-typed scalars, and that doesn't cover the
638     * full range of `mbedtls_mpi_uint`.
639     *
640     * We also have the different results for sizeof(mbedtls_mpi_uint) == 4 or 8.
641     */
642    mbedtls_mpi A, B, S, X4, X8, cy4, cy8;
643    mbedtls_mpi_uint *a = NULL;
644    mbedtls_mpi_uint *x = NULL;
645
646    mbedtls_mpi_init( &A );
647    mbedtls_mpi_init( &B );
648    mbedtls_mpi_init( &S );
649    mbedtls_mpi_init( &X4 );
650    mbedtls_mpi_init( &X8 );
651    mbedtls_mpi_init( &cy4 );
652    mbedtls_mpi_init( &cy8 );
653
654    TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
655    TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
656    TEST_EQUAL( 0, mbedtls_test_read_mpi( &S, input_S ) );
657    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
658    TEST_EQUAL( 0, mbedtls_test_read_mpi( &cy4, input_cy4 ) );
659    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
660    TEST_EQUAL( 0, mbedtls_test_read_mpi( &cy8, input_cy8 ) );
661
662    /* The MPI encoding of scalar s must be only 1 limb */
663    TEST_EQUAL( 1, S.n );
664
665    /* We only need to work with X4 or X8, and cy4 or cy8, depending on sizeof(mbedtls_mpi_uint) */
666    mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
667    mbedtls_mpi *cy = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &cy4 : &cy8;
668
669    /* The carry should only have one limb */
670    TEST_EQUAL( 1, cy->n );
671
672    /* All of the inputs are +ve (or zero) */
673    TEST_EQUAL( 1, A.s );
674    TEST_EQUAL( 1, B.s );
675    TEST_EQUAL( 1, S.s );
676    TEST_EQUAL( 1, X->s );
677    TEST_EQUAL( 1, cy->s );
678
679    /* Get the (max) number of limbs we will need */
680    size_t limbs = MAX( A.n, B.n );
681    size_t bytes = limbs * sizeof(mbedtls_mpi_uint);
682
683    /* The result shouldn't have more limbs than the longest input */
684    TEST_LE_U( X->n, limbs );
685
686    /* Now let's get arrays of mbedtls_mpi_uints, rather than MPI structures */
687
688    /* ASSERT_ALLOC() uses calloc() under the hood, so these do get zeroed */
689    ASSERT_ALLOC( a, bytes );
690    ASSERT_ALLOC( x, bytes );
691
692    /* Populate the arrays. As the mbedtls_mpi_uint[]s in mbedtls_mpis (and as
693     * processed by mbedtls_mpi_core_mla()) are little endian, we can just
694     * copy what we have as long as MSBs are 0 (which they are from ASSERT_ALLOC()).
695     */
696    memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
697    memcpy( x, X->p, X->n * sizeof(mbedtls_mpi_uint) );
698
699    /* 1a) A += B * s => we should get the correct carry */
700    TEST_EQUAL( mbedtls_mpi_core_mla( a, limbs, B.p, B.n, *S.p ), *cy->p );
701
702    /* 1b) A += B * s => we should get the correct result */
703    ASSERT_COMPARE( a, bytes, x, bytes );
704
705    if ( A.n == B.n && memcmp( A.p, B.p, bytes ) == 0 )
706    {
707        /* Check when A and B are aliased */
708        memcpy( a, A.p, A.n * sizeof(mbedtls_mpi_uint) );
709        TEST_EQUAL( mbedtls_mpi_core_mla( a, limbs, a, limbs, *S.p ), *cy->p );
710        ASSERT_COMPARE( a, bytes, x, bytes );
711    }
712
713exit:
714    mbedtls_free( a );
715    mbedtls_free( x );
716
717    mbedtls_mpi_free( &A );
718    mbedtls_mpi_free( &B );
719    mbedtls_mpi_free( &S );
720    mbedtls_mpi_free( &X4 );
721    mbedtls_mpi_free( &X8 );
722    mbedtls_mpi_free( &cy4 );
723    mbedtls_mpi_free( &cy8 );
724}
725/* END_CASE */
726
727
728/* BEGIN_CASE */
729void mpi_montg_init( char * input_N, char * input_mm )
730{
731    mbedtls_mpi N, mm;
732
733    mbedtls_mpi_init( &N );
734    mbedtls_mpi_init( &mm );
735
736    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
737    TEST_EQUAL( 0, mbedtls_test_read_mpi( &mm, input_mm ) );
738
739    /* The MPI encoding of mm should be 1 limb (sizeof(mbedtls_mpi_uint) == 8) or
740     * 2 limbs (sizeof(mbedtls_mpi_uint) == 4).
741     *
742     * The data file contains the expected result for sizeof(mbedtls_mpi_uint) == 8;
743     * for sizeof(mbedtls_mpi_uint) == 4 it's just the LSW of this.
744     */
745    TEST_ASSERT( mm.n == 1  || mm.n == 2 );
746
747    /* All of the inputs are +ve (or zero) */
748    TEST_EQUAL( 1, N.s );
749    TEST_EQUAL( 1, mm.s );
750
751    /* mbedtls_mpi_core_montmul_init() only returns a result, no error possible */
752    mbedtls_mpi_uint result = mbedtls_mpi_core_montmul_init( N.p );
753
754    /* Check we got the correct result */
755    TEST_EQUAL( result, mm.p[0] );
756
757exit:
758    mbedtls_mpi_free( &N );
759    mbedtls_mpi_free( &mm );
760}
761/* END_CASE */
762
763/* BEGIN_CASE */
764void mpi_core_montmul( int limbs_AN4, int limbs_B4,
765                       int limbs_AN8, int limbs_B8,
766                       char * input_A,
767                       char * input_B,
768                       char * input_N,
769                       char * input_X4,
770                       char * input_X8 )
771{
772    mbedtls_mpi A, B, N, X4, X8, T, R;
773
774    mbedtls_mpi_init( &A );
775    mbedtls_mpi_init( &B );
776    mbedtls_mpi_init( &N );
777    mbedtls_mpi_init( &X4 );    /* expected result, sizeof(mbedtls_mpi_uint) == 4 */
778    mbedtls_mpi_init( &X8 );    /* expected result, sizeof(mbedtls_mpi_uint) == 8 */
779    mbedtls_mpi_init( &T );
780    mbedtls_mpi_init( &R );     /* for the result */
781
782    TEST_EQUAL( 0, mbedtls_test_read_mpi( &A, input_A ) );
783    TEST_EQUAL( 0, mbedtls_test_read_mpi( &B, input_B ) );
784    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
785    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X4, input_X4 ) );
786    TEST_EQUAL( 0, mbedtls_test_read_mpi( &X8, input_X8 ) );
787
788    mbedtls_mpi *X = ( sizeof(mbedtls_mpi_uint) == 4 ) ? &X4 : &X8;
789
790    int limbs_AN = ( sizeof(mbedtls_mpi_uint) == 4 ) ? limbs_AN4 : limbs_AN8;
791    int limbs_B = ( sizeof(mbedtls_mpi_uint) == 4 ) ? limbs_B4 : limbs_B8;
792
793    TEST_LE_U( A.n, (size_t)limbs_AN );
794    TEST_LE_U( X->n, (size_t)limbs_AN );
795    TEST_LE_U( B.n, (size_t)limbs_B );
796    TEST_LE_U( limbs_B, limbs_AN );
797
798    /* All of the inputs are +ve (or zero) */
799    TEST_EQUAL( 1, A.s );
800    TEST_EQUAL( 1, B.s );
801    TEST_EQUAL( 1, N.s );
802    TEST_EQUAL( 1, X->s );
803
804    TEST_EQUAL( 0, mbedtls_mpi_grow( &A, limbs_AN ) );
805    TEST_EQUAL( 0, mbedtls_mpi_grow( &N, limbs_AN ) );
806    TEST_EQUAL( 0, mbedtls_mpi_grow( X, limbs_AN ) );
807    TEST_EQUAL( 0, mbedtls_mpi_grow( &B, limbs_B ) );
808
809    TEST_EQUAL( 0, mbedtls_mpi_grow( &T, limbs_AN * 2 + 1 ) );
810
811    /* Calculate the Montgomery constant (this is unit tested separately) */
812    mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init( N.p );
813
814    TEST_EQUAL( 0, mbedtls_mpi_grow( &R, limbs_AN ) ); /* ensure it's got the right number of limbs */
815
816    mbedtls_mpi_core_montmul( R.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
817    size_t bytes = N.n * sizeof(mbedtls_mpi_uint);
818    ASSERT_COMPARE( R.p, bytes, X->p, bytes );
819
820    /* The output (R, above) may be aliased to A - use R to save the value of A */
821
822    memcpy( R.p, A.p, bytes );
823
824    mbedtls_mpi_core_montmul( A.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
825    ASSERT_COMPARE( A.p, bytes, X->p, bytes );
826
827    memcpy( A.p, R.p, bytes );  /* restore A */
828
829    /* The output may be aliased to N - use R to save the value of N */
830
831    memcpy( R.p, N.p, bytes );
832
833    mbedtls_mpi_core_montmul( N.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
834    ASSERT_COMPARE( N.p, bytes, X->p, bytes );
835
836    memcpy( N.p, R.p, bytes );
837
838    if (limbs_AN == limbs_B)
839    {
840        /* Test when A aliased to B (requires A == B on input values) */
841        if ( memcmp( A.p, B.p, bytes ) == 0 )
842        {
843            /* Test with A aliased to B and output, since this is permitted -
844             * don't bother with yet another test with only A and B aliased */
845
846            mbedtls_mpi_core_montmul( B.p, B.p, B.p, B.n, N.p, N.n, mm, T.p );
847            ASSERT_COMPARE( B.p, bytes, X->p, bytes );
848
849            memcpy( B.p, A.p, bytes );  /* restore B from equal value A */
850        }
851
852        /* The output may be aliased to B - last test, so we don't save B */
853
854        mbedtls_mpi_core_montmul( B.p, A.p, B.p, B.n, N.p, N.n, mm, T.p );
855        ASSERT_COMPARE( B.p, bytes, X->p, bytes );
856    }
857
858exit:
859    mbedtls_mpi_free( &A );
860    mbedtls_mpi_free( &B );
861    mbedtls_mpi_free( &N );
862    mbedtls_mpi_free( &X4 );
863    mbedtls_mpi_free( &X8 );
864    mbedtls_mpi_free( &T );
865    mbedtls_mpi_free( &R );
866}
867/* END_CASE */
868
869/* BEGIN_CASE */
870void mpi_core_get_mont_r2_unsafe_neg(  )
871{
872    mbedtls_mpi N, RR;
873    mbedtls_mpi_init( &N );
874    mbedtls_mpi_init( &RR );
875    const char * n = "7ffffffffffffff1";
876
877    /* Test for zero divisor */
878    TEST_EQUAL( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO,
879               mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
880
881    /* Test for negative input */
882    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, n ) );
883    N.s = -1;
884    TEST_EQUAL( MBEDTLS_ERR_MPI_NEGATIVE_VALUE,
885               mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
886    N.s = 1;
887
888exit:
889    mbedtls_mpi_free( &N );
890    mbedtls_mpi_free( &RR );
891}
892/* END_CASE */
893
894/* BEGIN_CASE */
895void mpi_core_get_mont_r2_unsafe( char * input_N,
896                                  char * input_RR_X4,
897                                  char * input_RR_X8 )
898{
899    mbedtls_mpi N, RR, RR_REF;
900
901    /* Select the appropriate output */
902    char * input_rr = ( sizeof(mbedtls_mpi_uint) == 4 ) ? input_RR_X4: input_RR_X8;
903
904    mbedtls_mpi_init( &N );
905    mbedtls_mpi_init( &RR );
906    mbedtls_mpi_init( &RR_REF );
907
908    /* Read inputs */
909    TEST_EQUAL( 0, mbedtls_test_read_mpi( &N, input_N ) );
910    TEST_EQUAL( 0, mbedtls_test_read_mpi( &RR_REF, input_rr ) );
911
912    /* All of the inputs are +ve (or zero) */
913    TEST_EQUAL( 1, N.s );
914    TEST_EQUAL( 1, RR_REF.s );
915
916    /* Test valid input */
917    TEST_EQUAL( 0, mbedtls_mpi_core_get_mont_r2_unsafe( &RR, &N ) );
918
919    /* Test that the moduli is odd */
920    TEST_EQUAL( N.p[0] ^ 1, N.p[0] - 1 );
921
922   /* Output is +ve (or zero) */
923    TEST_EQUAL( 1, RR_REF.s );
924
925    /* rr is updated to a valid pointer */
926    TEST_ASSERT( RR.p != NULL );
927
928    /* Calculated rr matches expected value */
929    TEST_ASSERT( mbedtls_mpi_cmp_mpi( &RR, &RR_REF ) == 0 );
930
931exit:
932    mbedtls_mpi_free( &N );
933    mbedtls_mpi_free( &RR );
934    mbedtls_mpi_free( &RR_REF );
935}
936/* END_CASE */
937
938/* BEGIN_CASE depends_on:MBEDTLS_TEST_HOOKS */
939void mpi_core_ct_uint_table_lookup( int bitlen, int window_size )
940{
941    size_t limbs = BITS_TO_LIMBS( bitlen );
942    size_t count = ( (size_t) 1 ) << window_size;
943
944    mbedtls_mpi_uint *table = NULL;
945    mbedtls_mpi_uint *dest = NULL;
946
947    ASSERT_ALLOC( table, limbs * count );
948    ASSERT_ALLOC( dest, limbs );
949
950    /*
951     * Fill the table with a unique counter so that differences are easily
952     * detected. (And have their relationship to the index relatively non-trivial just
953     * to be sure.)
954     */
955    for( size_t i = 0; i < count * limbs; i++ )
956    {
957        table[i] = ~i - 1;
958    }
959
960    for( size_t i = 0; i < count; i++ )
961    {
962        mbedtls_mpi_uint *current = table + i * limbs;
963        memset( dest, 0x00, limbs * sizeof( *dest ) );
964
965        /*
966         * We shouldn't leak anything through timing.
967         * We need to set these in every loop as we need to make the loop
968         * variable public for the loop head and the buffers for comparison.
969         */
970        TEST_CF_SECRET( &i, sizeof( i ) );
971        TEST_CF_SECRET( dest, limbs * sizeof( *dest ) );
972        TEST_CF_SECRET( table, count * limbs * sizeof( *table ) );
973
974        mbedtls_mpi_core_ct_uint_table_lookup( dest, table, limbs, count, i );
975
976        TEST_CF_PUBLIC( dest, limbs * sizeof( *dest ) );
977        TEST_CF_PUBLIC( table, count * limbs * sizeof( *table ) );
978        ASSERT_COMPARE( dest, limbs * sizeof( *dest ),
979                        current, limbs * sizeof( *current ) );
980        TEST_CF_PUBLIC( &i, sizeof( i ) );
981    }
982
983exit:
984    mbedtls_free(table);
985    mbedtls_free(dest);
986}
987/* END_CASE */
988
989/* BEGIN_CASE */
990void mpi_core_fill_random( int wanted_bytes_arg, int extra_rng_bytes,
991                           int extra_limbs, int before, int expected_ret )
992{
993    size_t wanted_bytes = wanted_bytes_arg;
994    mbedtls_mpi_uint *X = NULL;
995    size_t X_limbs = CHARS_TO_LIMBS( wanted_bytes ) + extra_limbs;
996    size_t rng_bytes = wanted_bytes + extra_rng_bytes;
997    unsigned char *rnd_data = NULL;
998    mbedtls_test_rnd_buf_info rnd_info = {NULL, rng_bytes, NULL, NULL};
999    int ret;
1000
1001    /* Prepare an RNG with known output, limited to rng_bytes. */
1002    ASSERT_ALLOC( rnd_data, rng_bytes );
1003    TEST_EQUAL( 0, mbedtls_test_rnd_std_rand( NULL, rnd_data, rng_bytes ) );
1004    rnd_info.buf = rnd_data;
1005
1006    /* Allocate an MPI with room for wanted_bytes plus extra_limbs.
1007     * extra_limbs may be negative but the total limb count must be positive.
1008     * Fill the MPI with the byte value in before. */
1009    TEST_LE_U( 1, X_limbs );
1010    ASSERT_ALLOC( X, X_limbs );
1011    memset( X, before, X_limbs * sizeof( *X ) );
1012
1013    ret = mbedtls_mpi_core_fill_random( X, X_limbs, wanted_bytes,
1014                                        mbedtls_test_rnd_buffer_rand,
1015                                        &rnd_info );
1016    TEST_EQUAL( expected_ret, ret );
1017
1018    if( expected_ret == 0 )
1019    {
1020        /* mbedtls_mpi_core_fill_random is documented to use bytes from the
1021         * RNG as a big-endian representation of the number. We used an RNG
1022         * with known output, so check that the output contains the
1023         * expected value. Bytes above wanted_bytes must be zero. */
1024        for( size_t i = 0; i < wanted_bytes; i++ )
1025        {
1026            mbedtls_test_set_step( i );
1027            TEST_EQUAL( GET_BYTE( X, i ), rnd_data[wanted_bytes - 1 - i] );
1028        }
1029        for( size_t i = wanted_bytes; i < X_limbs * ciL; i++ )
1030        {
1031            mbedtls_test_set_step( i );
1032            TEST_EQUAL( GET_BYTE( X, i ), 0 );
1033        }
1034    }
1035
1036exit:
1037    mbedtls_free( rnd_data );
1038    mbedtls_free( X );
1039}
1040/* END_CASE */
1041
1042/* BEGIN MERGE SLOT 1 */
1043
1044/* BEGIN_CASE */
1045void mpi_core_exp_mod( char * input_N, char * input_A,
1046                       char * input_E, char * input_X )
1047{
1048    mbedtls_mpi_uint *A = NULL;
1049    mbedtls_mpi_uint *E = NULL;
1050    mbedtls_mpi_uint *N = NULL;
1051    mbedtls_mpi_uint *X = NULL;
1052    size_t A_limbs, E_limbs, N_limbs, X_limbs;
1053    const mbedtls_mpi_uint *R2 = NULL;
1054    mbedtls_mpi_uint *Y = NULL;
1055    mbedtls_mpi_uint *T = NULL;
1056    /* Legacy MPIs for computing R2 */
1057    mbedtls_mpi N_mpi;
1058    mbedtls_mpi_init( &N_mpi );
1059    mbedtls_mpi R2_mpi;
1060    mbedtls_mpi_init( &R2_mpi );
1061
1062    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
1063    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &E, &E_limbs, input_E ) );
1064    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &N, &N_limbs, input_N ) );
1065    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
1066    ASSERT_ALLOC( Y, N_limbs );
1067
1068    TEST_EQUAL( A_limbs, N_limbs );
1069    TEST_EQUAL( X_limbs, N_limbs );
1070
1071    TEST_EQUAL( 0, mbedtls_mpi_grow( &N_mpi, N_limbs ) );
1072    memcpy( N_mpi.p, N, N_limbs * sizeof( *N ) );
1073    N_mpi.n = N_limbs;
1074    TEST_EQUAL( 0,
1075                mbedtls_mpi_core_get_mont_r2_unsafe( &R2_mpi, &N_mpi ) );
1076    TEST_EQUAL( 0, mbedtls_mpi_grow( &R2_mpi, N_limbs ) );
1077    R2 = R2_mpi.p;
1078
1079    size_t working_limbs = mbedtls_mpi_core_exp_mod_working_limbs( N_limbs,
1080                                                                   E_limbs );
1081
1082    /* No point exactly duplicating the code in mbedtls_mpi_core_exp_mod_working_limbs()
1083     * to see if the output is correct, but we can check that it's in a
1084     * reasonable range.  The current calculation works out as
1085     * `1 + N_limbs * (welem + 3)`, where welem is the number of elements in
1086     * the window (1 << 1 up to 1 << 6).
1087     */
1088    size_t min_expected_working_limbs = 1 + N_limbs * 4;
1089    size_t max_expected_working_limbs = 1 + N_limbs * 67;
1090
1091    TEST_LE_U( min_expected_working_limbs, working_limbs );
1092    TEST_LE_U( working_limbs, max_expected_working_limbs );
1093
1094    ASSERT_ALLOC( T, working_limbs );
1095
1096    mbedtls_mpi_core_exp_mod( Y, A, N, N_limbs, E, E_limbs, R2, T );
1097
1098    TEST_EQUAL( 0, memcmp( X, Y, N_limbs * sizeof( mbedtls_mpi_uint ) ) );
1099
1100exit:
1101    mbedtls_free( T );
1102    mbedtls_free( A );
1103    mbedtls_free( E );
1104    mbedtls_free( N );
1105    mbedtls_free( X );
1106    mbedtls_free( Y );
1107    mbedtls_mpi_free( &N_mpi );
1108    mbedtls_mpi_free( &R2_mpi );
1109    // R2 doesn't need to be freed as it is only aliasing R2_mpi
1110}
1111/* END_CASE */
1112
1113/* END MERGE SLOT 1 */
1114
1115/* BEGIN MERGE SLOT 2 */
1116
1117/* END MERGE SLOT 2 */
1118
1119/* BEGIN MERGE SLOT 3 */
1120
1121/* BEGIN_CASE */
1122void mpi_core_sub_int( char * input_A, char * input_B,
1123                       char * input_X, int borrow )
1124{
1125    /* We are testing A - b, where A is an MPI and b is a scalar, expecting
1126     * result X with borrow borrow.  However, for ease of handling we encode b
1127     * as a 1-limb MPI (B) in the .data file. */
1128
1129    mbedtls_mpi_uint *A = NULL;
1130    mbedtls_mpi_uint *B = NULL;
1131    mbedtls_mpi_uint *X = NULL;
1132    mbedtls_mpi_uint *R = NULL;
1133    size_t A_limbs, B_limbs, X_limbs;
1134
1135    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &A, &A_limbs, input_A ) );
1136    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &B, &B_limbs, input_B ) );
1137    TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &X_limbs, input_X ) );
1138
1139    /* The MPI encoding of scalar b must be only 1 limb */
1140    TEST_EQUAL( B_limbs, 1 );
1141
1142    /* The subtraction is fixed-width, so A and X must have the same number of limbs */
1143    TEST_EQUAL( A_limbs, X_limbs );
1144    size_t limbs = A_limbs;
1145
1146    ASSERT_ALLOC( R, limbs );
1147
1148#define TEST_COMPARE_CORE_MPIS( A, B, limbs ) \
1149                ASSERT_COMPARE( A, (limbs) * sizeof(mbedtls_mpi_uint), B, (limbs) * sizeof(mbedtls_mpi_uint) )
1150
1151    /* 1. R = A - b. Result and borrow should be correct */
1152    TEST_EQUAL( mbedtls_mpi_core_sub_int( R, A, B[0], limbs ), borrow );
1153    TEST_COMPARE_CORE_MPIS( R, X, limbs );
1154
1155    /* 2. A = A - b. Result and borrow should be correct */
1156    TEST_EQUAL( mbedtls_mpi_core_sub_int( A, A, B[0], limbs ), borrow );
1157    TEST_COMPARE_CORE_MPIS( A, X, limbs );
1158
1159exit:
1160    mbedtls_free( A );
1161    mbedtls_free( B );
1162    mbedtls_free( X );
1163    mbedtls_free( R );
1164}
1165/* END_CASE */
1166
1167/* END MERGE SLOT 3 */
1168
1169/* BEGIN MERGE SLOT 4 */
1170
1171/* END MERGE SLOT 4 */
1172
1173/* BEGIN MERGE SLOT 5 */
1174
1175/* END MERGE SLOT 5 */
1176
1177/* BEGIN MERGE SLOT 6 */
1178
1179/* END MERGE SLOT 6 */
1180
1181/* BEGIN MERGE SLOT 7 */
1182
1183/* END MERGE SLOT 7 */
1184
1185/* BEGIN MERGE SLOT 8 */
1186
1187/* END MERGE SLOT 8 */
1188
1189/* BEGIN MERGE SLOT 9 */
1190
1191/* END MERGE SLOT 9 */
1192
1193/* BEGIN MERGE SLOT 10 */
1194
1195/* END MERGE SLOT 10 */
1196