Rtos API example

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