mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

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