Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bignum.c Source File

bignum.c

00001 /*
00002  *  Multi-precision integer library
00003  *
00004  *  Copyright (C) 2006-2014, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License along
00022  *  with this program; if not, write to the Free Software Foundation, Inc.,
00023  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00024  */
00025 /*
00026  *  This MPI implementation is based on:
00027  *
00028  *  http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
00029  *  http://www.stillhq.com/extracted/gnupg-api/mpi/
00030  *  http://math.libtomcrypt.com/files/tommath.pdf
00031  */
00032 
00033 #if !defined(POLARSSL_CONFIG_FILE)
00034 #include "polarssl/config.h"
00035 #else
00036 #include POLARSSL_CONFIG_FILE
00037 #endif
00038 
00039 #if defined(POLARSSL_BIGNUM_C)
00040 
00041 #include "polarssl/bignum.h"
00042 #include "polarssl/bn_mul.h"
00043 
00044 #if defined(POLARSSL_PLATFORM_C)
00045 #include "polarssl/platform.h"
00046 #else
00047 #define polarssl_printf     printf
00048 #define polarssl_malloc     malloc
00049 #define polarssl_free       free
00050 #endif
00051 
00052 #include <stdlib.h>
00053 
00054 #define ciL    (sizeof(t_uint))         /* chars in limb  */
00055 #define biL    (ciL << 3)               /* bits  in limb  */
00056 #define biH    (ciL << 2)               /* half limb size */
00057 
00058 /*
00059  * Convert between bits/chars and number of limbs
00060  */
00061 #define BITS_TO_LIMBS(i)  (((i) + biL - 1) / biL)
00062 #define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
00063 
00064 /*
00065  * Initialize one MPI
00066  */
00067 void mpi_init( mpi *X )
00068 {
00069     if( X == NULL )
00070         return;
00071 
00072     X->s  = 1;
00073     X->n  = 0;
00074     X->p  = NULL;
00075 }
00076 
00077 /*
00078  * Unallocate one MPI
00079  */
00080 void mpi_free( mpi *X )
00081 {
00082     if( X == NULL )
00083         return;
00084 
00085     if( X->p  != NULL )
00086     {
00087         memset( X->p , 0, X->n  * ciL );
00088         polarssl_free( X->p  );
00089     }
00090 
00091     X->s  = 1;
00092     X->n  = 0;
00093     X->p  = NULL;
00094 }
00095 
00096 /*
00097  * Enlarge to the specified number of limbs
00098  */
00099 int mpi_grow( mpi *X, size_t nblimbs )
00100 {
00101     t_uint *p;
00102 
00103     if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
00104         return( POLARSSL_ERR_MPI_MALLOC_FAILED );
00105 
00106     if( X->n  < nblimbs )
00107     {
00108         if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
00109             return( POLARSSL_ERR_MPI_MALLOC_FAILED );
00110 
00111         memset( p, 0, nblimbs * ciL );
00112 
00113         if( X->p  != NULL )
00114         {
00115             memcpy( p, X->p , X->n  * ciL );
00116             memset( X->p , 0, X->n  * ciL );
00117             polarssl_free( X->p  );
00118         }
00119 
00120         X->n  = nblimbs;
00121         X->p  = p;
00122     }
00123 
00124     return( 0 );
00125 }
00126 
00127 /*
00128  * Resize down as much as possible,
00129  * while keeping at least the specified number of limbs
00130  */
00131 int mpi_shrink( mpi *X, size_t nblimbs )
00132 {
00133     t_uint *p;
00134     size_t i;
00135 
00136     /* Actually resize up in this case */
00137     if( X->n  <= nblimbs )
00138         return( mpi_grow( X, nblimbs ) );
00139 
00140     for( i = X->n  - 1; i > 0; i-- )
00141         if( X->p [i] != 0 )
00142             break;
00143     i++;
00144 
00145     if( i < nblimbs )
00146         i = nblimbs;
00147 
00148     if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
00149         return( POLARSSL_ERR_MPI_MALLOC_FAILED );
00150 
00151     memset( p, 0, i * ciL );
00152 
00153     if( X->p  != NULL )
00154     {
00155         memcpy( p, X->p , i * ciL );
00156         memset( X->p , 0, X->n  * ciL );
00157         polarssl_free( X->p  );
00158     }
00159 
00160     X->n  = i;
00161     X->p  = p;
00162 
00163     return( 0 );
00164 }
00165 
00166 /*
00167  * Copy the contents of Y into X
00168  */
00169 int mpi_copy( mpi *X, const mpi *Y )
00170 {
00171     int ret;
00172     size_t i;
00173 
00174     if( X == Y )
00175         return( 0 );
00176 
00177     if( Y->p  == NULL )
00178     {
00179         mpi_free( X );
00180         return( 0 );
00181     }
00182 
00183     for( i = Y->n  - 1; i > 0; i-- )
00184         if( Y->p [i] != 0 )
00185             break;
00186     i++;
00187 
00188     X->s  = Y->s ;
00189 
00190     MPI_CHK( mpi_grow( X, i ) );
00191 
00192     memset( X->p , 0, X->n  * ciL );
00193     memcpy( X->p , Y->p , i * ciL );
00194 
00195 cleanup:
00196 
00197     return( ret );
00198 }
00199 
00200 /*
00201  * Swap the contents of X and Y
00202  */
00203 void mpi_swap( mpi *X, mpi *Y )
00204 {
00205     mpi T;
00206 
00207     memcpy( &T,  X, sizeof( mpi ) );
00208     memcpy(  X,  Y, sizeof( mpi ) );
00209     memcpy(  Y, &T, sizeof( mpi ) );
00210 }
00211 
00212 /*
00213  * Conditionally assign X = Y, without leaking information
00214  * about whether the assignment was made or not.
00215  * (Leaking information about the respective sizes of X and Y is ok however.)
00216  */
00217 int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
00218 {
00219     int ret = 0;
00220     size_t i;
00221 
00222     /* make sure assign is 0 or 1 */
00223     assign = ( assign != 0 );
00224 
00225     MPI_CHK( mpi_grow( X, Y->n  ) );
00226 
00227     X->s  = X->s  * (1 - assign) + Y->s  * assign;
00228 
00229     for( i = 0; i < Y->n; i++ )
00230         X->p [i] = X->p [i] * (1 - assign) + Y->p [i] * assign;
00231 
00232     for( ; i < X->n; i++ )
00233         X->p [i] *= (1 - assign);
00234 
00235 cleanup:
00236     return( ret );
00237 }
00238 
00239 /*
00240  * Conditionally swap X and Y, without leaking information
00241  * about whether the swap was made or not.
00242  * Here it is not ok to simply swap the pointers, which whould lead to
00243  * different memory access patterns when X and Y are used afterwards.
00244  */
00245 int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
00246 {
00247     int ret, s;
00248     size_t i;
00249     t_uint tmp;
00250 
00251     if( X == Y )
00252         return( 0 );
00253 
00254     /* make sure swap is 0 or 1 */
00255     swap = ( swap != 0 );
00256 
00257     MPI_CHK( mpi_grow( X, Y->n  ) );
00258     MPI_CHK( mpi_grow( Y, X->n  ) );
00259 
00260     s = X->s ;
00261     X->s  = X->s  * (1 - swap) + Y->s  * swap;
00262     Y->s  = Y->s  * (1 - swap) +    s * swap;
00263 
00264 
00265     for( i = 0; i < X->n ; i++ )
00266     {
00267         tmp = X->p [i];
00268         X->p [i] = X->p [i] * (1 - swap) + Y->p [i] * swap;
00269         Y->p [i] = Y->p [i] * (1 - swap) +     tmp * swap;
00270     }
00271 
00272 cleanup:
00273     return( ret );
00274 }
00275 
00276 /*
00277  * Set value from integer
00278  */
00279 int mpi_lset( mpi *X, t_sint z )
00280 {
00281     int ret;
00282 
00283     MPI_CHK( mpi_grow( X, 1 ) );
00284     memset( X->p , 0, X->n  * ciL );
00285 
00286     X->p [0] = ( z < 0 ) ? -z : z;
00287     X->s     = ( z < 0 ) ? -1 : 1;
00288 
00289 cleanup:
00290 
00291     return( ret );
00292 }
00293 
00294 /*
00295  * Get a specific bit
00296  */
00297 int mpi_get_bit( const mpi *X, size_t pos )
00298 {
00299     if( X->n  * biL <= pos )
00300         return( 0 );
00301 
00302     return ( X->p [pos / biL] >> ( pos % biL ) ) & 0x01;
00303 }
00304 
00305 /*
00306  * Set a bit to a specific value of 0 or 1
00307  */
00308 int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
00309 {
00310     int ret = 0;
00311     size_t off = pos / biL;
00312     size_t idx = pos % biL;
00313 
00314     if( val != 0 && val != 1 )
00315         return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
00316 
00317     if( X->n  * biL <= pos )
00318     {
00319         if( val == 0 )
00320             return ( 0 );
00321 
00322         MPI_CHK( mpi_grow( X, off + 1 ) );
00323     }
00324 
00325     X->p [off] &= ~( (t_uint) 0x01 << idx );
00326     X->p [off] |= (t_uint) val << idx;
00327 
00328 cleanup:
00329 
00330     return( ret );
00331 }
00332 
00333 /*
00334  * Return the number of least significant bits
00335  */
00336 size_t mpi_lsb( const mpi *X )
00337 {
00338     size_t i, j, count = 0;
00339 
00340     for( i = 0; i < X->n ; i++ )
00341         for( j = 0; j < biL; j++, count++ )
00342             if( ( ( X->p [i] >> j ) & 1 ) != 0 )
00343                 return( count );
00344 
00345     return( 0 );
00346 }
00347 
00348 /*
00349  * Return the number of most significant bits
00350  */
00351 size_t mpi_msb( const mpi *X )
00352 {
00353     size_t i, j;
00354 
00355     for( i = X->n  - 1; i > 0; i-- )
00356         if( X->p [i] != 0 )
00357             break;
00358 
00359     for( j = biL; j > 0; j-- )
00360         if( ( ( X->p [i] >> ( j - 1 ) ) & 1 ) != 0 )
00361             break;
00362 
00363     return( ( i * biL ) + j );
00364 }
00365 
00366 /*
00367  * Return the total size in bytes
00368  */
00369 size_t mpi_size( const mpi *X )
00370 {
00371     return( ( mpi_msb( X ) + 7 ) >> 3 );
00372 }
00373 
00374 /*
00375  * Convert an ASCII character to digit value
00376  */
00377 static int mpi_get_digit( t_uint *d, int radix, char c )
00378 {
00379     *d = 255;
00380 
00381     if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
00382     if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
00383     if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
00384 
00385     if( *d >= (t_uint) radix )
00386         return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
00387 
00388     return( 0 );
00389 }
00390 
00391 /*
00392  * Import from an ASCII string
00393  */
00394 int mpi_read_string( mpi *X, int radix, const char *s )
00395 {
00396     int ret;
00397     size_t i, j, slen, n;
00398     t_uint d;
00399     mpi T;
00400 
00401     if( radix < 2 || radix > 16 )
00402         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
00403 
00404     mpi_init( &T );
00405 
00406     slen = strlen( s );
00407 
00408     if( radix == 16 )
00409     {
00410         n = BITS_TO_LIMBS( slen << 2 );
00411 
00412         MPI_CHK( mpi_grow( X, n ) );
00413         MPI_CHK( mpi_lset( X, 0 ) );
00414 
00415         for( i = slen, j = 0; i > 0; i--, j++ )
00416         {
00417             if( i == 1 && s[i - 1] == '-' )
00418             {
00419                 X->s  = -1;
00420                 break;
00421             }
00422 
00423             MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
00424             X->p [j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
00425         }
00426     }
00427     else
00428     {
00429         MPI_CHK( mpi_lset( X, 0 ) );
00430 
00431         for( i = 0; i < slen; i++ )
00432         {
00433             if( i == 0 && s[i] == '-' )
00434             {
00435                 X->s  = -1;
00436                 continue;
00437             }
00438 
00439             MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
00440             MPI_CHK( mpi_mul_int( &T, X, radix ) );
00441 
00442             if( X->s  == 1 )
00443             {
00444                 MPI_CHK( mpi_add_int( X, &T, d ) );
00445             }
00446             else
00447             {
00448                 MPI_CHK( mpi_sub_int( X, &T, d ) );
00449             }
00450         }
00451     }
00452 
00453 cleanup:
00454 
00455     mpi_free( &T );
00456 
00457     return( ret );
00458 }
00459 
00460 /*
00461  * Helper to write the digits high-order first
00462  */
00463 static int mpi_write_hlp( mpi *X, int radix, char **p )
00464 {
00465     int ret;
00466     t_uint r;
00467 
00468     if( radix < 2 || radix > 16 )
00469         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
00470 
00471     MPI_CHK( mpi_mod_int( &r, X, radix ) );
00472     MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
00473 
00474     if( mpi_cmp_int( X, 0 ) != 0 )
00475         MPI_CHK( mpi_write_hlp( X, radix, p ) );
00476 
00477     if( r < 10 )
00478         *(*p)++ = (char)( r + 0x30 );
00479     else
00480         *(*p)++ = (char)( r + 0x37 );
00481 
00482 cleanup:
00483 
00484     return( ret );
00485 }
00486 
00487 /*
00488  * Export into an ASCII string
00489  */
00490 int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
00491 {
00492     int ret = 0;
00493     size_t n;
00494     char *p;
00495     mpi T;
00496 
00497     if( radix < 2 || radix > 16 )
00498         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
00499 
00500     n = mpi_msb( X );
00501     if( radix >=  4 ) n >>= 1;
00502     if( radix >= 16 ) n >>= 1;
00503     n += 3;
00504 
00505     if( *slen < n )
00506     {
00507         *slen = n;
00508         return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
00509     }
00510 
00511     p = s;
00512     mpi_init( &T );
00513 
00514     if( X->s  == -1 )
00515         *p++ = '-';
00516 
00517     if( radix == 16 )
00518     {
00519         int c;
00520         size_t i, j, k;
00521 
00522         for( i = X->n , k = 0; i > 0; i-- )
00523         {
00524             for( j = ciL; j > 0; j-- )
00525             {
00526                 c = ( X->p [i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
00527 
00528                 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
00529                     continue;
00530 
00531                 *(p++) = "0123456789ABCDEF" [c / 16];
00532                 *(p++) = "0123456789ABCDEF" [c % 16];
00533                 k = 1;
00534             }
00535         }
00536     }
00537     else
00538     {
00539         MPI_CHK( mpi_copy( &T, X ) );
00540 
00541         if( T.s  == -1 )
00542             T.s  = 1;
00543 
00544         MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
00545     }
00546 
00547     *p++ = '\0';
00548     *slen = p - s;
00549 
00550 cleanup:
00551 
00552     mpi_free( &T );
00553 
00554     return( ret );
00555 }
00556 
00557 #if defined(POLARSSL_FS_IO)
00558 /*
00559  * Read X from an opened file
00560  */
00561 int mpi_read_file( mpi *X, int radix, FILE *fin )
00562 {
00563     t_uint d;
00564     size_t slen;
00565     char *p;
00566     /*
00567      * Buffer should have space for (short) label and decimal formatted MPI,
00568      * newline characters and '\0'
00569      */
00570     char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
00571 
00572     memset( s, 0, sizeof( s ) );
00573     if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
00574         return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
00575 
00576     slen = strlen( s );
00577     if( slen == sizeof( s ) - 2 )
00578         return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
00579 
00580     if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
00581     if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
00582 
00583     p = s + slen;
00584     while( --p >= s )
00585         if( mpi_get_digit( &d, radix, *p ) != 0 )
00586             break;
00587 
00588     return( mpi_read_string( X, radix, p + 1 ) );
00589 }
00590 
00591 /*
00592  * Write X into an opened file (or stdout if fout == NULL)
00593  */
00594 int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
00595 {
00596     int ret;
00597     size_t n, slen, plen;
00598     /*
00599      * Buffer should have space for (short) label and decimal formatted MPI,
00600      * newline characters and '\0'
00601      */
00602     char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
00603 
00604     n = sizeof( s );
00605     memset( s, 0, n );
00606     n -= 2;
00607 
00608     MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
00609 
00610     if( p == NULL ) p = "";
00611 
00612     plen = strlen( p );
00613     slen = strlen( s );
00614     s[slen++] = '\r';
00615     s[slen++] = '\n';
00616 
00617     if( fout != NULL )
00618     {
00619         if( fwrite( p, 1, plen, fout ) != plen ||
00620             fwrite( s, 1, slen, fout ) != slen )
00621             return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
00622     }
00623     else
00624         polarssl_printf( "%s%s", p, s );
00625 
00626 cleanup:
00627 
00628     return( ret );
00629 }
00630 #endif /* POLARSSL_FS_IO */
00631 
00632 /*
00633  * Import X from unsigned binary data, big endian
00634  */
00635 int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
00636 {
00637     int ret;
00638     size_t i, j, n;
00639 
00640     for( n = 0; n < buflen; n++ )
00641         if( buf[n] != 0 )
00642             break;
00643 
00644     MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
00645     MPI_CHK( mpi_lset( X, 0 ) );
00646 
00647     for( i = buflen, j = 0; i > n; i--, j++ )
00648         X->p [j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
00649 
00650 cleanup:
00651 
00652     return( ret );
00653 }
00654 
00655 /*
00656  * Export X into unsigned binary data, big endian
00657  */
00658 int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
00659 {
00660     size_t i, j, n;
00661 
00662     n = mpi_size( X );
00663 
00664     if( buflen < n )
00665         return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
00666 
00667     memset( buf, 0, buflen );
00668 
00669     for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
00670         buf[i] = (unsigned char)( X->p [j / ciL] >> ((j % ciL) << 3) );
00671 
00672     return( 0 );
00673 }
00674 
00675 /*
00676  * Left-shift: X <<= count
00677  */
00678 int mpi_shift_l( mpi *X, size_t count )
00679 {
00680     int ret;
00681     size_t i, v0, t1;
00682     t_uint r0 = 0, r1;
00683 
00684     v0 = count / (biL    );
00685     t1 = count & (biL - 1);
00686 
00687     i = mpi_msb( X ) + count;
00688 
00689     if( X->n  * biL < i )
00690         MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
00691 
00692     ret = 0;
00693 
00694     /*
00695      * shift by count / limb_size
00696      */
00697     if( v0 > 0 )
00698     {
00699         for( i = X->n ; i > v0; i-- )
00700             X->p [i - 1] = X->p [i - v0 - 1];
00701 
00702         for( ; i > 0; i-- )
00703             X->p [i - 1] = 0;
00704     }
00705 
00706     /*
00707      * shift by count % limb_size
00708      */
00709     if( t1 > 0 )
00710     {
00711         for( i = v0; i < X->n ; i++ )
00712         {
00713             r1 = X->p [i] >> (biL - t1);
00714             X->p [i] <<= t1;
00715             X->p [i] |= r0;
00716             r0 = r1;
00717         }
00718     }
00719 
00720 cleanup:
00721 
00722     return( ret );
00723 }
00724 
00725 /*
00726  * Right-shift: X >>= count
00727  */
00728 int mpi_shift_r( mpi *X, size_t count )
00729 {
00730     size_t i, v0, v1;
00731     t_uint r0 = 0, r1;
00732 
00733     v0 = count /  biL;
00734     v1 = count & (biL - 1);
00735 
00736     if( v0 > X->n  || ( v0 == X->n  && v1 > 0 ) )
00737         return mpi_lset( X, 0 );
00738 
00739     /*
00740      * shift by count / limb_size
00741      */
00742     if( v0 > 0 )
00743     {
00744         for( i = 0; i < X->n  - v0; i++ )
00745             X->p [i] = X->p [i + v0];
00746 
00747         for( ; i < X->n; i++ )
00748             X->p [i] = 0;
00749     }
00750 
00751     /*
00752      * shift by count % limb_size
00753      */
00754     if( v1 > 0 )
00755     {
00756         for( i = X->n ; i > 0; i-- )
00757         {
00758             r1 = X->p [i - 1] << (biL - v1);
00759             X->p [i - 1] >>= v1;
00760             X->p [i - 1] |= r0;
00761             r0 = r1;
00762         }
00763     }
00764 
00765     return( 0 );
00766 }
00767 
00768 /*
00769  * Compare unsigned values
00770  */
00771 int mpi_cmp_abs( const mpi *X, const mpi *Y )
00772 {
00773     size_t i, j;
00774 
00775     for( i = X->n ; i > 0; i-- )
00776         if( X->p [i - 1] != 0 )
00777             break;
00778 
00779     for( j = Y->n ; j > 0; j-- )
00780         if( Y->p [j - 1] != 0 )
00781             break;
00782 
00783     if( i == 0 && j == 0 )
00784         return( 0 );
00785 
00786     if( i > j ) return(  1 );
00787     if( j > i ) return( -1 );
00788 
00789     for( ; i > 0; i-- )
00790     {
00791         if( X->p [i - 1] > Y->p [i - 1] ) return(  1 );
00792         if( X->p [i - 1] < Y->p [i - 1] ) return( -1 );
00793     }
00794 
00795     return( 0 );
00796 }
00797 
00798 /*
00799  * Compare signed values
00800  */
00801 int mpi_cmp_mpi( const mpi *X, const mpi *Y )
00802 {
00803     size_t i, j;
00804 
00805     for( i = X->n ; i > 0; i-- )
00806         if( X->p [i - 1] != 0 )
00807             break;
00808 
00809     for( j = Y->n ; j > 0; j-- )
00810         if( Y->p [j - 1] != 0 )
00811             break;
00812 
00813     if( i == 0 && j == 0 )
00814         return( 0 );
00815 
00816     if( i > j ) return(  X->s  );
00817     if( j > i ) return( -Y->s  );
00818 
00819     if( X->s  > 0 && Y->s  < 0 ) return(  1 );
00820     if( Y->s  > 0 && X->s  < 0 ) return( -1 );
00821 
00822     for( ; i > 0; i-- )
00823     {
00824         if( X->p [i - 1] > Y->p [i - 1] ) return(  X->s  );
00825         if( X->p [i - 1] < Y->p [i - 1] ) return( -X->s  );
00826     }
00827 
00828     return( 0 );
00829 }
00830 
00831 /*
00832  * Compare signed values
00833  */
00834 int mpi_cmp_int( const mpi *X, t_sint z )
00835 {
00836     mpi Y;
00837     t_uint p[1];
00838 
00839     *p  = ( z < 0 ) ? -z : z;
00840     Y.s  = ( z < 0 ) ? -1 : 1;
00841     Y.n  = 1;
00842     Y.p  = p;
00843 
00844     return( mpi_cmp_mpi( X, &Y ) );
00845 }
00846 
00847 /*
00848  * Unsigned addition: X = |A| + |B|  (HAC 14.7)
00849  */
00850 int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
00851 {
00852     int ret;
00853     size_t i, j;
00854     t_uint *o, *p, c;
00855 
00856     if( X == B )
00857     {
00858         const mpi *T = A; A = X; B = T;
00859     }
00860 
00861     if( X != A )
00862         MPI_CHK( mpi_copy( X, A ) );
00863 
00864     /*
00865      * X should always be positive as a result of unsigned additions.
00866      */
00867     X->s  = 1;
00868 
00869     for( j = B->n ; j > 0; j-- )
00870         if( B->p [j - 1] != 0 )
00871             break;
00872 
00873     MPI_CHK( mpi_grow( X, j ) );
00874 
00875     o = B->p ; p = X->p ; c = 0;
00876 
00877     for( i = 0; i < j; i++, o++, p++ )
00878     {
00879         *p +=  c; c  = ( *p <  c );
00880         *p += *o; c += ( *p < *o );
00881     }
00882 
00883     while( c != 0 )
00884     {
00885         if( i >= X->n  )
00886         {
00887             MPI_CHK( mpi_grow( X, i + 1 ) );
00888             p = X->p  + i;
00889         }
00890 
00891         *p += c; c = ( *p < c ); i++; p++;
00892     }
00893 
00894 cleanup:
00895 
00896     return( ret );
00897 }
00898 
00899 /*
00900  * Helper for mpi subtraction
00901  */
00902 static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
00903 {
00904     size_t i;
00905     t_uint c, z;
00906 
00907     for( i = c = 0; i < n; i++, s++, d++ )
00908     {
00909         z = ( *d <  c );     *d -=  c;
00910         c = ( *d < *s ) + z; *d -= *s;
00911     }
00912 
00913     while( c != 0 )
00914     {
00915         z = ( *d < c ); *d -= c;
00916         c = z; i++; d++;
00917     }
00918 }
00919 
00920 /*
00921  * Unsigned subtraction: X = |A| - |B|  (HAC 14.9)
00922  */
00923 int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
00924 {
00925     mpi TB;
00926     int ret;
00927     size_t n;
00928 
00929     if( mpi_cmp_abs( A, B ) < 0 )
00930         return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
00931 
00932     mpi_init( &TB );
00933 
00934     if( X == B )
00935     {
00936         MPI_CHK( mpi_copy( &TB, B ) );
00937         B = &TB;
00938     }
00939 
00940     if( X != A )
00941         MPI_CHK( mpi_copy( X, A ) );
00942 
00943     /*
00944      * X should always be positive as a result of unsigned subtractions.
00945      */
00946     X->s  = 1;
00947 
00948     ret = 0;
00949 
00950     for( n = B->n ; n > 0; n-- )
00951         if( B->p [n - 1] != 0 )
00952             break;
00953 
00954     mpi_sub_hlp( n, B->p , X->p  );
00955 
00956 cleanup:
00957 
00958     mpi_free( &TB );
00959 
00960     return( ret );
00961 }
00962 
00963 /*
00964  * Signed addition: X = A + B
00965  */
00966 int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
00967 {
00968     int ret, s = A->s ;
00969 
00970     if( A->s  * B->s  < 0 )
00971     {
00972         if( mpi_cmp_abs( A, B ) >= 0 )
00973         {
00974             MPI_CHK( mpi_sub_abs( X, A, B ) );
00975             X->s  =  s;
00976         }
00977         else
00978         {
00979             MPI_CHK( mpi_sub_abs( X, B, A ) );
00980             X->s  = -s;
00981         }
00982     }
00983     else
00984     {
00985         MPI_CHK( mpi_add_abs( X, A, B ) );
00986         X->s  = s;
00987     }
00988 
00989 cleanup:
00990 
00991     return( ret );
00992 }
00993 
00994 /*
00995  * Signed subtraction: X = A - B
00996  */
00997 int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
00998 {
00999     int ret, s = A->s ;
01000 
01001     if( A->s  * B->s  > 0 )
01002     {
01003         if( mpi_cmp_abs( A, B ) >= 0 )
01004         {
01005             MPI_CHK( mpi_sub_abs( X, A, B ) );
01006             X->s  =  s;
01007         }
01008         else
01009         {
01010             MPI_CHK( mpi_sub_abs( X, B, A ) );
01011             X->s  = -s;
01012         }
01013     }
01014     else
01015     {
01016         MPI_CHK( mpi_add_abs( X, A, B ) );
01017         X->s  = s;
01018     }
01019 
01020 cleanup:
01021 
01022     return( ret );
01023 }
01024 
01025 /*
01026  * Signed addition: X = A + b
01027  */
01028 int mpi_add_int( mpi *X, const mpi *A, t_sint b )
01029 {
01030     mpi _B;
01031     t_uint p[1];
01032 
01033     p[0] = ( b < 0 ) ? -b : b;
01034     _B.s  = ( b < 0 ) ? -1 : 1;
01035     _B.n  = 1;
01036     _B.p  = p;
01037 
01038     return( mpi_add_mpi( X, A, &_B ) );
01039 }
01040 
01041 /*
01042  * Signed subtraction: X = A - b
01043  */
01044 int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
01045 {
01046     mpi _B;
01047     t_uint p[1];
01048 
01049     p[0] = ( b < 0 ) ? -b : b;
01050     _B.s  = ( b < 0 ) ? -1 : 1;
01051     _B.n  = 1;
01052     _B.p  = p;
01053 
01054     return( mpi_sub_mpi( X, A, &_B ) );
01055 }
01056 
01057 /*
01058  * Helper for mpi multiplication
01059  */
01060 static
01061 #if defined(__APPLE__) && defined(__arm__)
01062 /*
01063  * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
01064  * appears to need this to prevent bad ARM code generation at -O3.
01065  */
01066 __attribute__ ((noinline))
01067 #endif
01068 void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
01069 {
01070     t_uint c = 0, t = 0;
01071 
01072 #if defined(MULADDC_HUIT)
01073     for( ; i >= 8; i -= 8 )
01074     {
01075         MULADDC_INIT
01076         MULADDC_HUIT
01077         MULADDC_STOP
01078     }
01079 
01080     for( ; i > 0; i-- )
01081     {
01082         MULADDC_INIT
01083         MULADDC_CORE
01084         MULADDC_STOP
01085     }
01086 #else /* MULADDC_HUIT */
01087     for( ; i >= 16; i -= 16 )
01088     {
01089         MULADDC_INIT
01090         MULADDC_CORE   MULADDC_CORE
01091         MULADDC_CORE   MULADDC_CORE
01092         MULADDC_CORE   MULADDC_CORE
01093         MULADDC_CORE   MULADDC_CORE
01094 
01095         MULADDC_CORE   MULADDC_CORE
01096         MULADDC_CORE   MULADDC_CORE
01097         MULADDC_CORE   MULADDC_CORE
01098         MULADDC_CORE   MULADDC_CORE
01099         MULADDC_STOP
01100     }
01101 
01102     for( ; i >= 8; i -= 8 )
01103     {
01104         MULADDC_INIT
01105         MULADDC_CORE   MULADDC_CORE
01106         MULADDC_CORE   MULADDC_CORE
01107 
01108         MULADDC_CORE   MULADDC_CORE
01109         MULADDC_CORE   MULADDC_CORE
01110         MULADDC_STOP
01111     }
01112 
01113     for( ; i > 0; i-- )
01114     {
01115         MULADDC_INIT
01116         MULADDC_CORE
01117         MULADDC_STOP
01118     }
01119 #endif /* MULADDC_HUIT */
01120 
01121     t++;
01122 
01123     do {
01124         *d += c; c = ( *d < c ); d++;
01125     }
01126     while( c != 0 );
01127 }
01128 
01129 /*
01130  * Baseline multiplication: X = A * B  (HAC 14.12)
01131  */
01132 int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
01133 {
01134     int ret;
01135     size_t i, j;
01136     mpi TA, TB;
01137 
01138     mpi_init( &TA ); mpi_init( &TB );
01139 
01140     if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
01141     if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
01142 
01143     for( i = A->n ; i > 0; i-- )
01144         if( A->p [i - 1] != 0 )
01145             break;
01146 
01147     for( j = B->n ; j > 0; j-- )
01148         if( B->p [j - 1] != 0 )
01149             break;
01150 
01151     MPI_CHK( mpi_grow( X, i + j ) );
01152     MPI_CHK( mpi_lset( X, 0 ) );
01153 
01154     for( i++; j > 0; j-- )
01155         mpi_mul_hlp( i - 1, A->p , X->p  + j - 1, B->p [j - 1] );
01156 
01157     X->s  = A->s  * B->s ;
01158 
01159 cleanup:
01160 
01161     mpi_free( &TB ); mpi_free( &TA );
01162 
01163     return( ret );
01164 }
01165 
01166 /*
01167  * Baseline multiplication: X = A * b
01168  */
01169 int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
01170 {
01171     mpi _B;
01172     t_uint p[1];
01173 
01174     _B.s  = 1;
01175     _B.n  = 1;
01176     _B.p  = p;
01177     p[0] = b;
01178 
01179     return( mpi_mul_mpi( X, A, &_B ) );
01180 }
01181 
01182 /*
01183  * Division by mpi: A = Q * B + R  (HAC 14.20)
01184  */
01185 int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
01186 {
01187     int ret;
01188     size_t i, n, t, k;
01189     mpi X, Y, Z, T1, T2;
01190 
01191     if( mpi_cmp_int( B, 0 ) == 0 )
01192         return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
01193 
01194     mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
01195     mpi_init( &T1 ); mpi_init( &T2 );
01196 
01197     if( mpi_cmp_abs( A, B ) < 0 )
01198     {
01199         if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
01200         if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
01201         return( 0 );
01202     }
01203 
01204     MPI_CHK( mpi_copy( &X, A ) );
01205     MPI_CHK( mpi_copy( &Y, B ) );
01206     X.s  = Y.s  = 1;
01207 
01208     MPI_CHK( mpi_grow( &Z, A->n  + 2 ) );
01209     MPI_CHK( mpi_lset( &Z,  0 ) );
01210     MPI_CHK( mpi_grow( &T1, 2 ) );
01211     MPI_CHK( mpi_grow( &T2, 3 ) );
01212 
01213     k = mpi_msb( &Y ) % biL;
01214     if( k < biL - 1 )
01215     {
01216         k = biL - 1 - k;
01217         MPI_CHK( mpi_shift_l( &X, k ) );
01218         MPI_CHK( mpi_shift_l( &Y, k ) );
01219     }
01220     else k = 0;
01221 
01222     n = X.n  - 1;
01223     t = Y.n  - 1;
01224     MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
01225 
01226     while( mpi_cmp_mpi( &X, &Y ) >= 0 )
01227     {
01228         Z.p [n - t]++;
01229         MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
01230     }
01231     MPI_CHK( mpi_shift_r( &Y, biL * (n - t) ) );
01232 
01233     for( i = n; i > t ; i-- )
01234     {
01235         if( X.p [i] >= Y.p [t] )
01236             Z.p [i - t - 1] = ~0;
01237         else
01238         {
01239             /*
01240              * The version of Clang shipped by Apple with Mavericks around
01241              * 2014-03 can't handle 128-bit division properly. Disable
01242              * 128-bits division for this version. Let's be optimistic and
01243              * assume it'll be fixed in the next minor version (next
01244              * patchlevel is probably a bit too optimistic).
01245              */
01246 #if defined(POLARSSL_HAVE_UDBL) &&                          \
01247     ! ( defined(__x86_64__) && defined(__APPLE__) &&        \
01248         defined(__clang_major__) && __clang_major__ == 5 && \
01249         defined(__clang_minor__) && __clang_minor__ == 0 )
01250             t_udbl r;
01251 
01252             r  = (t_udbl) X.p [i] << biL;
01253             r |= (t_udbl) X.p [i - 1];
01254             r /= Y.p [t];
01255             if( r > ((t_udbl) 1 << biL) - 1)
01256                 r = ((t_udbl) 1 << biL) - 1;
01257 
01258             Z.p [i - t - 1] = (t_uint) r;
01259 #else
01260             /*
01261              * __udiv_qrnnd_c, from gmp/longlong.h
01262              */
01263             t_uint q0, q1, r0, r1;
01264             t_uint d0, d1, d, m;
01265 
01266             d  = Y.p [t];
01267             d0 = ( d << biH ) >> biH;
01268             d1 = ( d >> biH );
01269 
01270             q1 = X.p [i] / d1;
01271             r1 = X.p [i] - d1 * q1;
01272             r1 <<= biH;
01273             r1 |= ( X.p [i - 1] >> biH );
01274 
01275             m = q1 * d0;
01276             if( r1 < m )
01277             {
01278                 q1--, r1 += d;
01279                 while( r1 >= d && r1 < m )
01280                     q1--, r1 += d;
01281             }
01282             r1 -= m;
01283 
01284             q0 = r1 / d1;
01285             r0 = r1 - d1 * q0;
01286             r0 <<= biH;
01287             r0 |= ( X.p [i - 1] << biH ) >> biH;
01288 
01289             m = q0 * d0;
01290             if( r0 < m )
01291             {
01292                 q0--, r0 += d;
01293                 while( r0 >= d && r0 < m )
01294                     q0--, r0 += d;
01295             }
01296             r0 -= m;
01297 
01298             Z.p [i - t - 1] = ( q1 << biH ) | q0;
01299 #endif
01300         }
01301 
01302         Z.p [i - t - 1]++;
01303         do
01304         {
01305             Z.p [i - t - 1]--;
01306 
01307             MPI_CHK( mpi_lset( &T1, 0 ) );
01308             T1.p [0] = (t < 1) ? 0 : Y.p [t - 1];
01309             T1.p [1] = Y.p [t];
01310             MPI_CHK( mpi_mul_int( &T1, &T1, Z.p [i - t - 1] ) );
01311 
01312             MPI_CHK( mpi_lset( &T2, 0 ) );
01313             T2.p [0] = (i < 2) ? 0 : X.p [i - 2];
01314             T2.p [1] = (i < 1) ? 0 : X.p [i - 1];
01315             T2.p [2] = X.p [i];
01316         }
01317         while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
01318 
01319         MPI_CHK( mpi_mul_int( &T1, &Y, Z.p [i - t - 1] ) );
01320         MPI_CHK( mpi_shift_l( &T1,  biL * (i - t - 1) ) );
01321         MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
01322 
01323         if( mpi_cmp_int( &X, 0 ) < 0 )
01324         {
01325             MPI_CHK( mpi_copy( &T1, &Y ) );
01326             MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
01327             MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
01328             Z.p [i - t - 1]--;
01329         }
01330     }
01331 
01332     if( Q != NULL )
01333     {
01334         MPI_CHK( mpi_copy( Q, &Z ) );
01335         Q->s  = A->s  * B->s ;
01336     }
01337 
01338     if( R != NULL )
01339     {
01340         MPI_CHK( mpi_shift_r( &X, k ) );
01341         X.s  = A->s ;
01342         MPI_CHK( mpi_copy( R, &X ) );
01343 
01344         if( mpi_cmp_int( R, 0 ) == 0 )
01345             R->s  = 1;
01346     }
01347 
01348 cleanup:
01349 
01350     mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
01351     mpi_free( &T1 ); mpi_free( &T2 );
01352 
01353     return( ret );
01354 }
01355 
01356 /*
01357  * Division by int: A = Q * b + R
01358  */
01359 int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
01360 {
01361     mpi _B;
01362     t_uint p[1];
01363 
01364     p[0] = ( b < 0 ) ? -b : b;
01365     _B.s  = ( b < 0 ) ? -1 : 1;
01366     _B.n  = 1;
01367     _B.p  = p;
01368 
01369     return( mpi_div_mpi( Q, R, A, &_B ) );
01370 }
01371 
01372 /*
01373  * Modulo: R = A mod B
01374  */
01375 int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
01376 {
01377     int ret;
01378 
01379     if( mpi_cmp_int( B, 0 ) < 0 )
01380         return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
01381 
01382     MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
01383 
01384     while( mpi_cmp_int( R, 0 ) < 0 )
01385       MPI_CHK( mpi_add_mpi( R, R, B ) );
01386 
01387     while( mpi_cmp_mpi( R, B ) >= 0 )
01388       MPI_CHK( mpi_sub_mpi( R, R, B ) );
01389 
01390 cleanup:
01391 
01392     return( ret );
01393 }
01394 
01395 /*
01396  * Modulo: r = A mod b
01397  */
01398 int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
01399 {
01400     size_t i;
01401     t_uint x, y, z;
01402 
01403     if( b == 0 )
01404         return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
01405 
01406     if( b < 0 )
01407         return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
01408 
01409     /*
01410      * handle trivial cases
01411      */
01412     if( b == 1 )
01413     {
01414         *r = 0;
01415         return( 0 );
01416     }
01417 
01418     if( b == 2 )
01419     {
01420         *r = A->p [0] & 1;
01421         return( 0 );
01422     }
01423 
01424     /*
01425      * general case
01426      */
01427     for( i = A->n , y = 0; i > 0; i-- )
01428     {
01429         x  = A->p [i - 1];
01430         y  = ( y << biH ) | ( x >> biH );
01431         z  = y / b;
01432         y -= z * b;
01433 
01434         x <<= biH;
01435         y  = ( y << biH ) | ( x >> biH );
01436         z  = y / b;
01437         y -= z * b;
01438     }
01439 
01440     /*
01441      * If A is negative, then the current y represents a negative value.
01442      * Flipping it to the positive side.
01443      */
01444     if( A->s  < 0 && y != 0 )
01445         y = b - y;
01446 
01447     *r = y;
01448 
01449     return( 0 );
01450 }
01451 
01452 /*
01453  * Fast Montgomery initialization (thanks to Tom St Denis)
01454  */
01455 static void mpi_montg_init( t_uint *mm, const mpi *N )
01456 {
01457     t_uint x, m0 = N->p [0];
01458     unsigned int i;
01459 
01460     x  = m0;
01461     x += ( ( m0 + 2 ) & 4 ) << 1;
01462 
01463     for( i = biL; i >= 8; i /= 2 )
01464         x *= ( 2 - ( m0 * x ) );
01465 
01466     *mm = ~x + 1;
01467 }
01468 
01469 /*
01470  * Montgomery multiplication: A = A * B * R^-1 mod N  (HAC 14.36)
01471  */
01472 static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
01473                          const mpi *T )
01474 {
01475     size_t i, n, m;
01476     t_uint u0, u1, *d;
01477 
01478     memset( T->p , 0, T->n  * ciL );
01479 
01480     d = T->p ;
01481     n = N->n ;
01482     m = ( B->n  < n ) ? B->n  : n;
01483 
01484     for( i = 0; i < n; i++ )
01485     {
01486         /*
01487          * T = (T + u0*B + u1*N) / 2^biL
01488          */
01489         u0 = A->p [i];
01490         u1 = ( d[0] + u0 * B->p [0] ) * mm;
01491 
01492         mpi_mul_hlp( m, B->p , d, u0 );
01493         mpi_mul_hlp( n, N->p , d, u1 );
01494 
01495         *d++ = u0; d[n + 1] = 0;
01496     }
01497 
01498     memcpy( A->p , d, (n + 1) * ciL );
01499 
01500     if( mpi_cmp_abs( A, N ) >= 0 )
01501         mpi_sub_hlp( n, N->p , A->p  );
01502     else
01503         /* prevent timing attacks */
01504         mpi_sub_hlp( n, A->p , T->p  );
01505 }
01506 
01507 /*
01508  * Montgomery reduction: A = A * R^-1 mod N
01509  */
01510 static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
01511 {
01512     t_uint z = 1;
01513     mpi U;
01514 
01515     U.n  = U.s  = (int) z;
01516     U.p  = &z;
01517 
01518     mpi_montmul( A, &U, N, mm, T );
01519 }
01520 
01521 /*
01522  * Sliding-window exponentiation: X = A^E mod N  (HAC 14.85)
01523  */
01524 int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
01525 {
01526     int ret;
01527     size_t wbits, wsize, one = 1;
01528     size_t i, j, nblimbs;
01529     size_t bufsize, nbits;
01530     t_uint ei, mm, state;
01531     mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
01532     int neg;
01533 
01534     if( mpi_cmp_int( N, 0 ) < 0 || ( N->p [0] & 1 ) == 0 )
01535         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
01536 
01537     if( mpi_cmp_int( E, 0 ) < 0 )
01538         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
01539 
01540     /*
01541      * Init temps and window size
01542      */
01543     mpi_montg_init( &mm, N );
01544     mpi_init( &RR ); mpi_init( &T );
01545     mpi_init( &Apos );
01546     memset( W, 0, sizeof( W ) );
01547 
01548     i = mpi_msb( E );
01549 
01550     wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
01551             ( i >  79 ) ? 4 : ( i >  23 ) ? 3 : 1;
01552 
01553     if( wsize > POLARSSL_MPI_WINDOW_SIZE )
01554         wsize = POLARSSL_MPI_WINDOW_SIZE;
01555 
01556     j = N->n  + 1;
01557     MPI_CHK( mpi_grow( X, j ) );
01558     MPI_CHK( mpi_grow( &W[1],  j ) );
01559     MPI_CHK( mpi_grow( &T, j * 2 ) );
01560 
01561     /*
01562      * Compensate for negative A (and correct at the end)
01563      */
01564     neg = ( A->s  == -1 );
01565     if( neg )
01566     {
01567         MPI_CHK( mpi_copy( &Apos, A ) );
01568         Apos.s  = 1;
01569         A = &Apos;
01570     }
01571 
01572     /*
01573      * If 1st call, pre-compute R^2 mod N
01574      */
01575     if( _RR == NULL || _RR->p  == NULL )
01576     {
01577         MPI_CHK( mpi_lset( &RR, 1 ) );
01578         MPI_CHK( mpi_shift_l( &RR, N->n  * 2 * biL ) );
01579         MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
01580 
01581         if( _RR != NULL )
01582             memcpy( _RR, &RR, sizeof( mpi ) );
01583     }
01584     else
01585         memcpy( &RR, _RR, sizeof( mpi ) );
01586 
01587     /*
01588      * W[1] = A * R^2 * R^-1 mod N = A * R mod N
01589      */
01590     if( mpi_cmp_mpi( A, N ) >= 0 )
01591         MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
01592     else
01593         MPI_CHK( mpi_copy( &W[1], A ) );
01594 
01595     mpi_montmul( &W[1], &RR, N, mm, &T );
01596 
01597     /*
01598      * X = R^2 * R^-1 mod N = R mod N
01599      */
01600     MPI_CHK( mpi_copy( X, &RR ) );
01601     mpi_montred( X, N, mm, &T );
01602 
01603     if( wsize > 1 )
01604     {
01605         /*
01606          * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
01607          */
01608         j =  one << (wsize - 1);
01609 
01610         MPI_CHK( mpi_grow( &W[j], N->n  + 1 ) );
01611         MPI_CHK( mpi_copy( &W[j], &W[1]    ) );
01612 
01613         for( i = 0; i < wsize - 1; i++ )
01614             mpi_montmul( &W[j], &W[j], N, mm, &T );
01615 
01616         /*
01617          * W[i] = W[i - 1] * W[1]
01618          */
01619         for( i = j + 1; i < (one << wsize); i++ )
01620         {
01621             MPI_CHK( mpi_grow( &W[i], N->n  + 1 ) );
01622             MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
01623 
01624             mpi_montmul( &W[i], &W[1], N, mm, &T );
01625         }
01626     }
01627 
01628     nblimbs = E->n ;
01629     bufsize = 0;
01630     nbits   = 0;
01631     wbits   = 0;
01632     state   = 0;
01633 
01634     while( 1 )
01635     {
01636         if( bufsize == 0 )
01637         {
01638             if( nblimbs == 0 )
01639                 break;
01640 
01641             nblimbs--;
01642 
01643             bufsize = sizeof( t_uint ) << 3;
01644         }
01645 
01646         bufsize--;
01647 
01648         ei = (E->p [nblimbs] >> bufsize) & 1;
01649 
01650         /*
01651          * skip leading 0s
01652          */
01653         if( ei == 0 && state == 0 )
01654             continue;
01655 
01656         if( ei == 0 && state == 1 )
01657         {
01658             /*
01659              * out of window, square X
01660              */
01661             mpi_montmul( X, X, N, mm, &T );
01662             continue;
01663         }
01664 
01665         /*
01666          * add ei to current window
01667          */
01668         state = 2;
01669 
01670         nbits++;
01671         wbits |= (ei << (wsize - nbits));
01672 
01673         if( nbits == wsize )
01674         {
01675             /*
01676              * X = X^wsize R^-1 mod N
01677              */
01678             for( i = 0; i < wsize; i++ )
01679                 mpi_montmul( X, X, N, mm, &T );
01680 
01681             /*
01682              * X = X * W[wbits] R^-1 mod N
01683              */
01684             mpi_montmul( X, &W[wbits], N, mm, &T );
01685 
01686             state--;
01687             nbits = 0;
01688             wbits = 0;
01689         }
01690     }
01691 
01692     /*
01693      * process the remaining bits
01694      */
01695     for( i = 0; i < nbits; i++ )
01696     {
01697         mpi_montmul( X, X, N, mm, &T );
01698 
01699         wbits <<= 1;
01700 
01701         if( (wbits & (one << wsize)) != 0 )
01702             mpi_montmul( X, &W[1], N, mm, &T );
01703     }
01704 
01705     /*
01706      * X = A^E * R * R^-1 mod N = A^E mod N
01707      */
01708     mpi_montred( X, N, mm, &T );
01709 
01710     if( neg )
01711     {
01712         X->s  = -1;
01713         MPI_CHK( mpi_add_mpi( X, N, X ) );
01714     }
01715 
01716 cleanup:
01717 
01718     for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
01719         mpi_free( &W[i] );
01720 
01721     mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
01722 
01723     if( _RR == NULL || _RR->p  == NULL )
01724         mpi_free( &RR );
01725 
01726     return( ret );
01727 }
01728 
01729 /*
01730  * Greatest common divisor: G = gcd(A, B)  (HAC 14.54)
01731  */
01732 int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
01733 {
01734     int ret;
01735     size_t lz, lzt;
01736     mpi TG, TA, TB;
01737 
01738     mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
01739 
01740     MPI_CHK( mpi_copy( &TA, A ) );
01741     MPI_CHK( mpi_copy( &TB, B ) );
01742 
01743     lz = mpi_lsb( &TA );
01744     lzt = mpi_lsb( &TB );
01745 
01746     if ( lzt < lz )
01747         lz = lzt;
01748 
01749     MPI_CHK( mpi_shift_r( &TA, lz ) );
01750     MPI_CHK( mpi_shift_r( &TB, lz ) );
01751 
01752     TA.s  = TB.s  = 1;
01753 
01754     while( mpi_cmp_int( &TA, 0 ) != 0 )
01755     {
01756         MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
01757         MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
01758 
01759         if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
01760         {
01761             MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
01762             MPI_CHK( mpi_shift_r( &TA, 1 ) );
01763         }
01764         else
01765         {
01766             MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
01767             MPI_CHK( mpi_shift_r( &TB, 1 ) );
01768         }
01769     }
01770 
01771     MPI_CHK( mpi_shift_l( &TB, lz ) );
01772     MPI_CHK( mpi_copy( G, &TB ) );
01773 
01774 cleanup:
01775 
01776     mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
01777 
01778     return( ret );
01779 }
01780 
01781 /*
01782  * Fill X with size bytes of random.
01783  *
01784  * Use a temporary bytes representation to make sure the result is the same
01785  * regardless of the platform endianness (useful when f_rng is actually
01786  * deterministic, eg for tests).
01787  */
01788 int mpi_fill_random( mpi *X, size_t size,
01789                      int (*f_rng)(void *, unsigned char *, size_t),
01790                      void *p_rng )
01791 {
01792     int ret;
01793     unsigned char buf[POLARSSL_MPI_MAX_SIZE];
01794 
01795     if( size > POLARSSL_MPI_MAX_SIZE )
01796         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
01797 
01798     MPI_CHK( f_rng( p_rng, buf, size ) );
01799     MPI_CHK( mpi_read_binary( X, buf, size ) );
01800 
01801 cleanup:
01802     return( ret );
01803 }
01804 
01805 /*
01806  * Modular inverse: X = A^-1 mod N  (HAC 14.61 / 14.64)
01807  */
01808 int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
01809 {
01810     int ret;
01811     mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
01812 
01813     if( mpi_cmp_int( N, 0 ) <= 0 )
01814         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
01815 
01816     mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
01817     mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
01818     mpi_init( &V1 ); mpi_init( &V2 );
01819 
01820     MPI_CHK( mpi_gcd( &G, A, N ) );
01821 
01822     if( mpi_cmp_int( &G, 1 ) != 0 )
01823     {
01824         ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
01825         goto cleanup;
01826     }
01827 
01828     MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
01829     MPI_CHK( mpi_copy( &TU, &TA ) );
01830     MPI_CHK( mpi_copy( &TB, N ) );
01831     MPI_CHK( mpi_copy( &TV, N ) );
01832 
01833     MPI_CHK( mpi_lset( &U1, 1 ) );
01834     MPI_CHK( mpi_lset( &U2, 0 ) );
01835     MPI_CHK( mpi_lset( &V1, 0 ) );
01836     MPI_CHK( mpi_lset( &V2, 1 ) );
01837 
01838     do
01839     {
01840         while( ( TU.p [0] & 1 ) == 0 )
01841         {
01842             MPI_CHK( mpi_shift_r( &TU, 1 ) );
01843 
01844             if( ( U1.p [0] & 1 ) != 0 || ( U2.p [0] & 1 ) != 0 )
01845             {
01846                 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
01847                 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
01848             }
01849 
01850             MPI_CHK( mpi_shift_r( &U1, 1 ) );
01851             MPI_CHK( mpi_shift_r( &U2, 1 ) );
01852         }
01853 
01854         while( ( TV.p [0] & 1 ) == 0 )
01855         {
01856             MPI_CHK( mpi_shift_r( &TV, 1 ) );
01857 
01858             if( ( V1.p [0] & 1 ) != 0 || ( V2.p [0] & 1 ) != 0 )
01859             {
01860                 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
01861                 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
01862             }
01863 
01864             MPI_CHK( mpi_shift_r( &V1, 1 ) );
01865             MPI_CHK( mpi_shift_r( &V2, 1 ) );
01866         }
01867 
01868         if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
01869         {
01870             MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
01871             MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
01872             MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
01873         }
01874         else
01875         {
01876             MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
01877             MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
01878             MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
01879         }
01880     }
01881     while( mpi_cmp_int( &TU, 0 ) != 0 );
01882 
01883     while( mpi_cmp_int( &V1, 0 ) < 0 )
01884         MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
01885 
01886     while( mpi_cmp_mpi( &V1, N ) >= 0 )
01887         MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
01888 
01889     MPI_CHK( mpi_copy( X, &V1 ) );
01890 
01891 cleanup:
01892 
01893     mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
01894     mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
01895     mpi_free( &V1 ); mpi_free( &V2 );
01896 
01897     return( ret );
01898 }
01899 
01900 #if defined(POLARSSL_GENPRIME)
01901 
01902 static const int small_prime[] =
01903 {
01904         3,    5,    7,   11,   13,   17,   19,   23,
01905        29,   31,   37,   41,   43,   47,   53,   59,
01906        61,   67,   71,   73,   79,   83,   89,   97,
01907       101,  103,  107,  109,  113,  127,  131,  137,
01908       139,  149,  151,  157,  163,  167,  173,  179,
01909       181,  191,  193,  197,  199,  211,  223,  227,
01910       229,  233,  239,  241,  251,  257,  263,  269,
01911       271,  277,  281,  283,  293,  307,  311,  313,
01912       317,  331,  337,  347,  349,  353,  359,  367,
01913       373,  379,  383,  389,  397,  401,  409,  419,
01914       421,  431,  433,  439,  443,  449,  457,  461,
01915       463,  467,  479,  487,  491,  499,  503,  509,
01916       521,  523,  541,  547,  557,  563,  569,  571,
01917       577,  587,  593,  599,  601,  607,  613,  617,
01918       619,  631,  641,  643,  647,  653,  659,  661,
01919       673,  677,  683,  691,  701,  709,  719,  727,
01920       733,  739,  743,  751,  757,  761,  769,  773,
01921       787,  797,  809,  811,  821,  823,  827,  829,
01922       839,  853,  857,  859,  863,  877,  881,  883,
01923       887,  907,  911,  919,  929,  937,  941,  947,
01924       953,  967,  971,  977,  983,  991,  997, -103
01925 };
01926 
01927 /*
01928  * Small divisors test (X must be positive)
01929  *
01930  * Return values:
01931  * 0: no small factor (possible prime, more tests needed)
01932  * 1: certain prime
01933  * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
01934  * other negative: error
01935  */
01936 static int mpi_check_small_factors( const mpi *X )
01937 {
01938     int ret = 0;
01939     size_t i;
01940     t_uint r;
01941 
01942     if( ( X->p [0] & 1 ) == 0 )
01943         return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
01944 
01945     for( i = 0; small_prime[i] > 0; i++ )
01946     {
01947         if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
01948             return( 1 );
01949 
01950         MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
01951 
01952         if( r == 0 )
01953             return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
01954     }
01955 
01956 cleanup:
01957     return( ret );
01958 }
01959 
01960 /*
01961  * Miller-Rabin pseudo-primality test  (HAC 4.24)
01962  */
01963 static int mpi_miller_rabin( const mpi *X,
01964                              int (*f_rng)(void *, unsigned char *, size_t),
01965                              void *p_rng )
01966 {
01967     int ret;
01968     size_t i, j, n, s;
01969     mpi W, R, T, A, RR;
01970 
01971     mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
01972     mpi_init( &RR );
01973 
01974     /*
01975      * W = |X| - 1
01976      * R = W >> lsb( W )
01977      */
01978     MPI_CHK( mpi_sub_int( &W, X, 1 ) );
01979     s = mpi_lsb( &W );
01980     MPI_CHK( mpi_copy( &R, &W ) );
01981     MPI_CHK( mpi_shift_r( &R, s ) );
01982 
01983     i = mpi_msb( X );
01984     /*
01985      * HAC, table 4.4
01986      */
01987     n = ( ( i >= 1300 ) ?  2 : ( i >=  850 ) ?  3 :
01988           ( i >=  650 ) ?  4 : ( i >=  350 ) ?  8 :
01989           ( i >=  250 ) ? 12 : ( i >=  150 ) ? 18 : 27 );
01990 
01991     for( i = 0; i < n; i++ )
01992     {
01993         /*
01994          * pick a random A, 1 < A < |X| - 1
01995          */
01996         MPI_CHK( mpi_fill_random( &A, X->n  * ciL, f_rng, p_rng ) );
01997 
01998         if( mpi_cmp_mpi( &A, &W ) >= 0 )
01999         {
02000             j = mpi_msb( &A ) - mpi_msb( &W );
02001             MPI_CHK( mpi_shift_r( &A, j + 1 ) );
02002         }
02003         A.p [0] |= 3;
02004 
02005         /*
02006          * A = A^R mod |X|
02007          */
02008         MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
02009 
02010         if( mpi_cmp_mpi( &A, &W ) == 0 ||
02011             mpi_cmp_int( &A,  1 ) == 0 )
02012             continue;
02013 
02014         j = 1;
02015         while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
02016         {
02017             /*
02018              * A = A * A mod |X|
02019              */
02020             MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
02021             MPI_CHK( mpi_mod_mpi( &A, &T, X  ) );
02022 
02023             if( mpi_cmp_int( &A, 1 ) == 0 )
02024                 break;
02025 
02026             j++;
02027         }
02028 
02029         /*
02030          * not prime if A != |X| - 1 or A == 1
02031          */
02032         if( mpi_cmp_mpi( &A, &W ) != 0 ||
02033             mpi_cmp_int( &A,  1 ) == 0 )
02034         {
02035             ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
02036             break;
02037         }
02038     }
02039 
02040 cleanup:
02041     mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
02042     mpi_free( &RR );
02043 
02044     return( ret );
02045 }
02046 
02047 /*
02048  * Pseudo-primality test: small factors, then Miller-Rabin
02049  */
02050 int mpi_is_prime( mpi *X,
02051                   int (*f_rng)(void *, unsigned char *, size_t),
02052                   void *p_rng )
02053 {
02054     int ret;
02055     const mpi XX = { 1, X->n , X->p  }; /* Abs(X) */
02056 
02057     if( mpi_cmp_int( &XX, 0 ) == 0 ||
02058         mpi_cmp_int( &XX, 1 ) == 0 )
02059         return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
02060 
02061     if( mpi_cmp_int( &XX, 2 ) == 0 )
02062         return( 0 );
02063 
02064     if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
02065     {
02066         if( ret == 1 )
02067             return( 0 );
02068 
02069         return( ret );
02070     }
02071 
02072     return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
02073 }
02074 
02075 /*
02076  * Prime number generation
02077  */
02078 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
02079                    int (*f_rng)(void *, unsigned char *, size_t),
02080                    void *p_rng )
02081 {
02082     int ret;
02083     size_t k, n;
02084     t_uint r;
02085     mpi Y;
02086 
02087     if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
02088         return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
02089 
02090     mpi_init( &Y );
02091 
02092     n = BITS_TO_LIMBS( nbits );
02093 
02094     MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
02095 
02096     k = mpi_msb( X );
02097     if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
02098     if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
02099 
02100     X->p [0] |= 3;
02101 
02102     if( dh_flag == 0 )
02103     {
02104         while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
02105         {
02106             if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
02107                 goto cleanup;
02108 
02109             MPI_CHK( mpi_add_int( X, X, 2 ) );
02110         }
02111     }
02112     else
02113     {
02114         /*
02115          * An necessary condition for Y and X = 2Y + 1 to be prime
02116          * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
02117          * Make sure it is satisfied, while keeping X = 3 mod 4
02118          */
02119         MPI_CHK( mpi_mod_int( &r, X, 3 ) );
02120         if( r == 0 )
02121             MPI_CHK( mpi_add_int( X, X, 8 ) );
02122         else if( r == 1 )
02123             MPI_CHK( mpi_add_int( X, X, 4 ) );
02124 
02125         /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
02126         MPI_CHK( mpi_copy( &Y, X ) );
02127         MPI_CHK( mpi_shift_r( &Y, 1 ) );
02128 
02129         while( 1 )
02130         {
02131             /*
02132              * First, check small factors for X and Y
02133              * before doing Miller-Rabin on any of them
02134              */
02135             if( ( ret = mpi_check_small_factors(  X         ) ) == 0 &&
02136                 ( ret = mpi_check_small_factors( &Y         ) ) == 0 &&
02137                 ( ret = mpi_miller_rabin(  X, f_rng, p_rng  ) ) == 0 &&
02138                 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng  ) ) == 0 )
02139             {
02140                 break;
02141             }
02142 
02143             if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
02144                 goto cleanup;
02145 
02146             /*
02147              * Next candidates. We want to preserve Y = (X-1) / 2 and
02148              * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
02149              * so up Y by 6 and X by 12.
02150              */
02151             MPI_CHK( mpi_add_int(  X,  X, 12 ) );
02152             MPI_CHK( mpi_add_int( &Y, &Y, 6  ) );
02153         }
02154     }
02155 
02156 cleanup:
02157 
02158     mpi_free( &Y );
02159 
02160     return( ret );
02161 }
02162 
02163 #endif /* POLARSSL_GENPRIME */
02164 
02165 #if defined(POLARSSL_SELF_TEST)
02166 
02167 #define GCD_PAIR_COUNT  3
02168 
02169 static const int gcd_pairs[GCD_PAIR_COUNT][3] =
02170 {
02171     { 693, 609, 21 },
02172     { 1764, 868, 28 },
02173     { 768454923, 542167814, 1 }
02174 };
02175 
02176 /*
02177  * Checkup routine
02178  */
02179 int mpi_self_test( int verbose )
02180 {
02181     int ret, i;
02182     mpi A, E, N, X, Y, U, V;
02183 
02184     mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
02185     mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
02186 
02187     MPI_CHK( mpi_read_string( &A, 16,
02188         "EFE021C2645FD1DC586E69184AF4A31E" \
02189         "D5F53E93B5F123FA41680867BA110131" \
02190         "944FE7952E2517337780CB0DB80E61AA" \
02191         "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
02192 
02193     MPI_CHK( mpi_read_string( &E, 16,
02194         "B2E7EFD37075B9F03FF989C7C5051C20" \
02195         "34D2A323810251127E7BF8625A4F49A5" \
02196         "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
02197         "5B5C25763222FEFCCFC38B832366C29E" ) );
02198 
02199     MPI_CHK( mpi_read_string( &N, 16,
02200         "0066A198186C18C10B2F5ED9B522752A" \
02201         "9830B69916E535C8F047518A889A43A5" \
02202         "94B6BED27A168D31D4A52F88925AA8F5" ) );
02203 
02204     MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
02205 
02206     MPI_CHK( mpi_read_string( &U, 16,
02207         "602AB7ECA597A3D6B56FF9829A5E8B85" \
02208         "9E857EA95A03512E2BAE7391688D264A" \
02209         "A5663B0341DB9CCFD2C4C5F421FEC814" \
02210         "8001B72E848A38CAE1C65F78E56ABDEF" \
02211         "E12D3C039B8A02D6BE593F0BBBDA56F1" \
02212         "ECF677152EF804370C1A305CAF3B5BF1" \
02213         "30879B56C61DE584A0F53A2447A51E" ) );
02214 
02215     if( verbose != 0 )
02216         polarssl_printf( "  MPI test #1 (mul_mpi): " );
02217 
02218     if( mpi_cmp_mpi( &X, &U ) != 0 )
02219     {
02220         if( verbose != 0 )
02221             polarssl_printf( "failed\n" );
02222 
02223         ret = 1;
02224         goto cleanup;
02225     }
02226 
02227     if( verbose != 0 )
02228         polarssl_printf( "passed\n" );
02229 
02230     MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
02231 
02232     MPI_CHK( mpi_read_string( &U, 16,
02233         "256567336059E52CAE22925474705F39A94" ) );
02234 
02235     MPI_CHK( mpi_read_string( &V, 16,
02236         "6613F26162223DF488E9CD48CC132C7A" \
02237         "0AC93C701B001B092E4E5B9F73BCD27B" \
02238         "9EE50D0657C77F374E903CDFA4C642" ) );
02239 
02240     if( verbose != 0 )
02241         polarssl_printf( "  MPI test #2 (div_mpi): " );
02242 
02243     if( mpi_cmp_mpi( &X, &U ) != 0 ||
02244         mpi_cmp_mpi( &Y, &V ) != 0 )
02245     {
02246         if( verbose != 0 )
02247             polarssl_printf( "failed\n" );
02248 
02249         ret = 1;
02250         goto cleanup;
02251     }
02252 
02253     if( verbose != 0 )
02254         polarssl_printf( "passed\n" );
02255 
02256     MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
02257 
02258     MPI_CHK( mpi_read_string( &U, 16,
02259         "36E139AEA55215609D2816998ED020BB" \
02260         "BD96C37890F65171D948E9BC7CBAA4D9" \
02261         "325D24D6A3C12710F10A09FA08AB87" ) );
02262 
02263     if( verbose != 0 )
02264         polarssl_printf( "  MPI test #3 (exp_mod): " );
02265 
02266     if( mpi_cmp_mpi( &X, &U ) != 0 )
02267     {
02268         if( verbose != 0 )
02269             polarssl_printf( "failed\n" );
02270 
02271         ret = 1;
02272         goto cleanup;
02273     }
02274 
02275     if( verbose != 0 )
02276         polarssl_printf( "passed\n" );
02277 
02278     MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
02279 
02280     MPI_CHK( mpi_read_string( &U, 16,
02281         "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
02282         "C3DBA76456363A10869622EAC2DD84EC" \
02283         "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
02284 
02285     if( verbose != 0 )
02286         polarssl_printf( "  MPI test #4 (inv_mod): " );
02287 
02288     if( mpi_cmp_mpi( &X, &U ) != 0 )
02289     {
02290         if( verbose != 0 )
02291             polarssl_printf( "failed\n" );
02292 
02293         ret = 1;
02294         goto cleanup;
02295     }
02296 
02297     if( verbose != 0 )
02298         polarssl_printf( "passed\n" );
02299 
02300     if( verbose != 0 )
02301         polarssl_printf( "  MPI test #5 (simple gcd): " );
02302 
02303     for ( i = 0; i < GCD_PAIR_COUNT; i++)
02304     {
02305         MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
02306         MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
02307 
02308         MPI_CHK( mpi_gcd( &A, &X, &Y ) );
02309 
02310         if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
02311         {
02312             if( verbose != 0 )
02313                 polarssl_printf( "failed at %d\n", i );
02314 
02315             ret = 1;
02316             goto cleanup;
02317         }
02318     }
02319 
02320     if( verbose != 0 )
02321         polarssl_printf( "passed\n" );
02322 
02323 cleanup:
02324 
02325     if( ret != 0 && verbose != 0 )
02326         polarssl_printf( "Unexpected error, return code = %08X\n", ret );
02327 
02328     mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
02329     mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
02330 
02331     if( verbose != 0 )
02332         polarssl_printf( "\n" );
02333 
02334     return( ret );
02335 }
02336 
02337 #endif /* POLARSSL_SELF_TEST */
02338 
02339 #endif /* POLARSSL_BIGNUM_C */
02340 
02341