mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
bignum.c
00001 /* 00002 * Multi-precision integer library 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 /* 00023 * This MPI implementation is based on: 00024 * 00025 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf 00026 * http://www.stillhq.com/extracted/gnupg-api/mpi/ 00027 * http://math.libtomcrypt.com/files/tommath.pdf 00028 */ 00029 00030 #if !defined(POLARSSL_CONFIG_FILE) 00031 #include "polarssl/config.h" 00032 #else 00033 #include POLARSSL_CONFIG_FILE 00034 #endif 00035 00036 #if defined(POLARSSL_BIGNUM_C) 00037 00038 #include "polarssl/bignum.h" 00039 #include "polarssl/bn_mul.h" 00040 00041 #include <string.h> 00042 00043 #if defined(POLARSSL_PLATFORM_C) 00044 #include "polarssl/platform.h" 00045 #else 00046 #include <stdio.h> 00047 #include <stdlib.h> 00048 #define polarssl_printf printf 00049 #define polarssl_malloc malloc 00050 #define polarssl_free free 00051 #endif 00052 00053 /* Implementation that should never be optimized out by the compiler */ 00054 static void polarssl_zeroize( void *v, size_t n ) { 00055 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00056 } 00057 00058 #define ciL (sizeof(t_uint)) /* chars in limb */ 00059 #define biL (ciL << 3) /* bits in limb */ 00060 #define biH (ciL << 2) /* half limb size */ 00061 00062 /* 00063 * Convert between bits/chars and number of limbs 00064 */ 00065 #define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL) 00066 #define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL) 00067 00068 /* 00069 * Initialize one MPI 00070 */ 00071 void mpi_init( mpi *X ) 00072 { 00073 if( X == NULL ) 00074 return; 00075 00076 X->s = 1; 00077 X->n = 0; 00078 X->p = NULL; 00079 } 00080 00081 /* 00082 * Unallocate one MPI 00083 */ 00084 void mpi_free( mpi *X ) 00085 { 00086 if( X == NULL ) 00087 return; 00088 00089 if( X->p != NULL ) 00090 { 00091 polarssl_zeroize( X->p , X->n * ciL ); 00092 polarssl_free( X->p ); 00093 } 00094 00095 X->s = 1; 00096 X->n = 0; 00097 X->p = NULL; 00098 } 00099 00100 /* 00101 * Enlarge to the specified number of limbs 00102 */ 00103 int mpi_grow( mpi *X, size_t nblimbs ) 00104 { 00105 t_uint *p; 00106 00107 if( nblimbs > POLARSSL_MPI_MAX_LIMBS ) 00108 return( POLARSSL_ERR_MPI_MALLOC_FAILED ); 00109 00110 if( X->n < nblimbs ) 00111 { 00112 if( ( p = polarssl_malloc( nblimbs * ciL ) ) == NULL ) 00113 return( POLARSSL_ERR_MPI_MALLOC_FAILED ); 00114 00115 memset( p, 0, nblimbs * ciL ); 00116 00117 if( X->p != NULL ) 00118 { 00119 memcpy( p, X->p , X->n * ciL ); 00120 polarssl_zeroize( X->p , X->n * ciL ); 00121 polarssl_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 mpi_shrink( mpi *X, size_t nblimbs ) 00136 { 00137 t_uint *p; 00138 size_t i; 00139 00140 /* Actually resize up in this case */ 00141 if( X->n <= nblimbs ) 00142 return( 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 = polarssl_malloc( i * ciL ) ) == NULL ) 00153 return( POLARSSL_ERR_MPI_MALLOC_FAILED ); 00154 00155 memset( p, 0, i * ciL ); 00156 00157 if( X->p != NULL ) 00158 { 00159 memcpy( p, X->p , i * ciL ); 00160 polarssl_zeroize( X->p , X->n * ciL ); 00161 polarssl_free( X->p ); 00162 } 00163 00164 X->n = i; 00165 X->p = p; 00166 00167 return( 0 ); 00168 } 00169 00170 /* 00171 * Copy the contents of Y into X 00172 */ 00173 int mpi_copy( mpi *X, const mpi *Y ) 00174 { 00175 int ret; 00176 size_t i; 00177 00178 if( X == Y ) 00179 return( 0 ); 00180 00181 if( Y->p == NULL ) 00182 { 00183 mpi_free( X ); 00184 return( 0 ); 00185 } 00186 00187 for( i = Y->n - 1; i > 0; i-- ) 00188 if( Y->p [i] != 0 ) 00189 break; 00190 i++; 00191 00192 X->s = Y->s ; 00193 00194 MPI_CHK( mpi_grow( X, i ) ); 00195 00196 memset( X->p , 0, X->n * ciL ); 00197 memcpy( X->p , Y->p , i * ciL ); 00198 00199 cleanup: 00200 00201 return( ret ); 00202 } 00203 00204 /* 00205 * Swap the contents of X and Y 00206 */ 00207 void mpi_swap( mpi *X, mpi *Y ) 00208 { 00209 mpi T; 00210 00211 memcpy( &T, X, sizeof( mpi ) ); 00212 memcpy( X, Y, sizeof( mpi ) ); 00213 memcpy( Y, &T, sizeof( mpi ) ); 00214 } 00215 00216 /* 00217 * Conditionally assign X = Y, without leaking information 00218 * about whether the assignment was made or not. 00219 * (Leaking information about the respective sizes of X and Y is ok however.) 00220 */ 00221 int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ) 00222 { 00223 int ret = 0; 00224 size_t i; 00225 00226 /* make sure assign is 0 or 1 in a time-constant manner */ 00227 assign = (assign | (unsigned char)-assign) >> 7; 00228 00229 MPI_CHK( mpi_grow( X, Y->n ) ); 00230 00231 X->s = X->s * ( 1 - assign ) + Y->s * assign; 00232 00233 for( i = 0; i < Y->n; i++ ) 00234 X->p [i] = X->p [i] * ( 1 - assign ) + Y->p [i] * assign; 00235 00236 for( ; i < X->n; i++ ) 00237 X->p [i] *= ( 1 - assign ); 00238 00239 cleanup: 00240 return( ret ); 00241 } 00242 00243 /* 00244 * Conditionally swap X and Y, without leaking information 00245 * about whether the swap was made or not. 00246 * Here it is not ok to simply swap the pointers, which whould lead to 00247 * different memory access patterns when X and Y are used afterwards. 00248 */ 00249 int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap ) 00250 { 00251 int ret, s; 00252 size_t i; 00253 t_uint tmp; 00254 00255 if( X == Y ) 00256 return( 0 ); 00257 00258 /* make sure swap is 0 or 1 in a time-constant manner */ 00259 swap = (swap | (unsigned char)-swap) >> 7; 00260 00261 MPI_CHK( mpi_grow( X, Y->n ) ); 00262 MPI_CHK( mpi_grow( Y, X->n ) ); 00263 00264 s = X->s ; 00265 X->s = X->s * ( 1 - swap ) + Y->s * swap; 00266 Y->s = Y->s * ( 1 - swap ) + s * swap; 00267 00268 00269 for( i = 0; i < X->n ; i++ ) 00270 { 00271 tmp = X->p [i]; 00272 X->p [i] = X->p [i] * ( 1 - swap ) + Y->p [i] * swap; 00273 Y->p [i] = Y->p [i] * ( 1 - swap ) + tmp * swap; 00274 } 00275 00276 cleanup: 00277 return( ret ); 00278 } 00279 00280 /* 00281 * Set value from integer 00282 */ 00283 int mpi_lset( mpi *X, t_sint z ) 00284 { 00285 int ret; 00286 00287 MPI_CHK( mpi_grow( X, 1 ) ); 00288 memset( X->p , 0, X->n * ciL ); 00289 00290 X->p [0] = ( z < 0 ) ? -z : z; 00291 X->s = ( z < 0 ) ? -1 : 1; 00292 00293 cleanup: 00294 00295 return( ret ); 00296 } 00297 00298 /* 00299 * Get a specific bit 00300 */ 00301 int mpi_get_bit( const mpi *X, size_t pos ) 00302 { 00303 if( X->n * biL <= pos ) 00304 return( 0 ); 00305 00306 return( ( X->p [pos / biL] >> ( pos % biL ) ) & 0x01 ); 00307 } 00308 00309 /* 00310 * Set a bit to a specific value of 0 or 1 00311 */ 00312 int mpi_set_bit( mpi *X, size_t pos, unsigned char val ) 00313 { 00314 int ret = 0; 00315 size_t off = pos / biL; 00316 size_t idx = pos % biL; 00317 00318 if( val != 0 && val != 1 ) 00319 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 00320 00321 if( X->n * biL <= pos ) 00322 { 00323 if( val == 0 ) 00324 return( 0 ); 00325 00326 MPI_CHK( mpi_grow( X, off + 1 ) ); 00327 } 00328 00329 X->p [off] &= ~( (t_uint) 0x01 << idx ); 00330 X->p [off] |= (t_uint) val << idx; 00331 00332 cleanup: 00333 00334 return( ret ); 00335 } 00336 00337 /* 00338 * Return the number of least significant bits 00339 */ 00340 size_t mpi_lsb( const mpi *X ) 00341 { 00342 size_t i, j, count = 0; 00343 00344 for( i = 0; i < X->n ; i++ ) 00345 for( j = 0; j < biL; j++, count++ ) 00346 if( ( ( X->p [i] >> j ) & 1 ) != 0 ) 00347 return( count ); 00348 00349 return( 0 ); 00350 } 00351 00352 /* 00353 * Return the number of most significant bits 00354 */ 00355 size_t mpi_msb( const mpi *X ) 00356 { 00357 size_t i, j; 00358 00359 if( X->n == 0 ) 00360 return( 0 ); 00361 00362 for( i = X->n - 1; i > 0; i-- ) 00363 if( X->p [i] != 0 ) 00364 break; 00365 00366 for( j = biL; j > 0; j-- ) 00367 if( ( ( X->p [i] >> ( j - 1 ) ) & 1 ) != 0 ) 00368 break; 00369 00370 return( ( i * biL ) + j ); 00371 } 00372 00373 /* 00374 * Return the total size in bytes 00375 */ 00376 size_t mpi_size( const mpi *X ) 00377 { 00378 return( ( mpi_msb( X ) + 7 ) >> 3 ); 00379 } 00380 00381 /* 00382 * Convert an ASCII character to digit value 00383 */ 00384 static int mpi_get_digit( t_uint *d, int radix, char c ) 00385 { 00386 *d = 255; 00387 00388 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; 00389 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; 00390 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; 00391 00392 if( *d >= (t_uint) radix ) 00393 return( POLARSSL_ERR_MPI_INVALID_CHARACTER ); 00394 00395 return( 0 ); 00396 } 00397 00398 /* 00399 * Import from an ASCII string 00400 */ 00401 int mpi_read_string( mpi *X, int radix, const char *s ) 00402 { 00403 int ret; 00404 size_t i, j, slen, n; 00405 t_uint d; 00406 mpi T; 00407 00408 if( radix < 2 || radix > 16 ) 00409 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 00410 00411 mpi_init( &T ); 00412 00413 slen = strlen( s ); 00414 00415 if( radix == 16 ) 00416 { 00417 n = BITS_TO_LIMBS( slen << 2 ); 00418 00419 MPI_CHK( mpi_grow( X, n ) ); 00420 MPI_CHK( mpi_lset( X, 0 ) ); 00421 00422 for( i = slen, j = 0; i > 0; i--, j++ ) 00423 { 00424 if( i == 1 && s[i - 1] == '-' ) 00425 { 00426 X->s = -1; 00427 break; 00428 } 00429 00430 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); 00431 X->p [j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); 00432 } 00433 } 00434 else 00435 { 00436 MPI_CHK( mpi_lset( X, 0 ) ); 00437 00438 for( i = 0; i < slen; i++ ) 00439 { 00440 if( i == 0 && s[i] == '-' ) 00441 { 00442 X->s = -1; 00443 continue; 00444 } 00445 00446 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); 00447 MPI_CHK( mpi_mul_int( &T, X, radix ) ); 00448 00449 if( X->s == 1 ) 00450 { 00451 MPI_CHK( mpi_add_int( X, &T, d ) ); 00452 } 00453 else 00454 { 00455 MPI_CHK( mpi_sub_int( X, &T, d ) ); 00456 } 00457 } 00458 } 00459 00460 cleanup: 00461 00462 mpi_free( &T ); 00463 00464 return( ret ); 00465 } 00466 00467 /* 00468 * Helper to write the digits high-order first 00469 */ 00470 static int mpi_write_hlp( mpi *X, int radix, char **p ) 00471 { 00472 int ret; 00473 t_uint r; 00474 00475 if( radix < 2 || radix > 16 ) 00476 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 00477 00478 MPI_CHK( mpi_mod_int( &r, X, radix ) ); 00479 MPI_CHK( mpi_div_int( X, NULL, X, radix ) ); 00480 00481 if( mpi_cmp_int( X, 0 ) != 0 ) 00482 MPI_CHK( mpi_write_hlp( X, radix, p ) ); 00483 00484 if( r < 10 ) 00485 *(*p)++ = (char)( r + 0x30 ); 00486 else 00487 *(*p)++ = (char)( r + 0x37 ); 00488 00489 cleanup: 00490 00491 return( ret ); 00492 } 00493 00494 /* 00495 * Export into an ASCII string 00496 */ 00497 int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ) 00498 { 00499 int ret = 0; 00500 size_t n; 00501 char *p; 00502 mpi T; 00503 00504 if( radix < 2 || radix > 16 ) 00505 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 00506 00507 n = mpi_msb( X ); 00508 if( radix >= 4 ) n >>= 1; 00509 if( radix >= 16 ) n >>= 1; 00510 n += 3; 00511 00512 if( *slen < n ) 00513 { 00514 *slen = n; 00515 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); 00516 } 00517 00518 p = s; 00519 mpi_init( &T ); 00520 00521 if( X->s == -1 ) 00522 *p++ = '-'; 00523 00524 if( radix == 16 ) 00525 { 00526 int c; 00527 size_t i, j, k; 00528 00529 for( i = X->n , k = 0; i > 0; i-- ) 00530 { 00531 for( j = ciL; j > 0; j-- ) 00532 { 00533 c = ( X->p [i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; 00534 00535 if( c == 0 && k == 0 && ( i + j ) != 2 ) 00536 continue; 00537 00538 *(p++) = "0123456789ABCDEF" [c / 16]; 00539 *(p++) = "0123456789ABCDEF" [c % 16]; 00540 k = 1; 00541 } 00542 } 00543 } 00544 else 00545 { 00546 MPI_CHK( mpi_copy( &T, X ) ); 00547 00548 if( T.s == -1 ) 00549 T.s = 1; 00550 00551 MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); 00552 } 00553 00554 *p++ = '\0'; 00555 *slen = p - s; 00556 00557 cleanup: 00558 00559 mpi_free( &T ); 00560 00561 return( ret ); 00562 } 00563 00564 #if defined(POLARSSL_FS_IO) 00565 /* 00566 * Read X from an opened file 00567 */ 00568 int mpi_read_file( mpi *X, int radix, FILE *fin ) 00569 { 00570 t_uint d; 00571 size_t slen; 00572 char *p; 00573 /* 00574 * Buffer should have space for (short) label and decimal formatted MPI, 00575 * newline characters and '\0' 00576 */ 00577 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; 00578 00579 memset( s, 0, sizeof( s ) ); 00580 if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) 00581 return( POLARSSL_ERR_MPI_FILE_IO_ERROR ); 00582 00583 slen = strlen( s ); 00584 if( slen == sizeof( s ) - 2 ) 00585 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL ); 00586 00587 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } 00588 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } 00589 00590 p = s + slen; 00591 while( --p >= s ) 00592 if( mpi_get_digit( &d, radix, *p ) != 0 ) 00593 break; 00594 00595 return( mpi_read_string( X, radix, p + 1 ) ); 00596 } 00597 00598 /* 00599 * Write X into an opened file (or stdout if fout == NULL) 00600 */ 00601 int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ) 00602 { 00603 int ret; 00604 size_t n, slen, plen; 00605 /* 00606 * Buffer should have space for (short) label and decimal formatted MPI, 00607 * newline characters and '\0' 00608 */ 00609 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ]; 00610 00611 n = sizeof( s ); 00612 memset( s, 0, n ); 00613 n -= 2; 00614 00615 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &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( POLARSSL_ERR_MPI_FILE_IO_ERROR ); 00629 } 00630 else 00631 polarssl_printf( "%s%s", p, s ); 00632 00633 cleanup: 00634 00635 return( ret ); 00636 } 00637 #endif /* POLARSSL_FS_IO */ 00638 00639 /* 00640 * Import X from unsigned binary data, big endian 00641 */ 00642 int mpi_read_binary( 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 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); 00652 MPI_CHK( mpi_lset( X, 0 ) ); 00653 00654 for( i = buflen, j = 0; i > n; i--, j++ ) 00655 X->p [j / ciL] |= ((t_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 mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ) 00666 { 00667 size_t i, j, n; 00668 00669 n = mpi_size( X ); 00670 00671 if( buflen < n ) 00672 return( POLARSSL_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 mpi_shift_l( mpi *X, size_t count ) 00686 { 00687 int ret; 00688 size_t i, v0, t1; 00689 t_uint r0 = 0, r1; 00690 00691 v0 = count / (biL ); 00692 t1 = count & (biL - 1); 00693 00694 i = mpi_msb( X ) + count; 00695 00696 if( X->n * biL < i ) 00697 MPI_CHK( 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 mpi_shift_r( mpi *X, size_t count ) 00736 { 00737 size_t i, v0, v1; 00738 t_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 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 mpi_cmp_abs( const mpi *X, const 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 mpi_cmp_mpi( const mpi *X, const 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 mpi_cmp_int( const mpi *X, t_sint z ) 00842 { 00843 mpi Y; 00844 t_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( mpi_cmp_mpi( X, &Y ) ); 00852 } 00853 00854 /* 00855 * Unsigned addition: X = |A| + |B| (HAC 14.7) 00856 */ 00857 int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ) 00858 { 00859 int ret; 00860 size_t i, j; 00861 t_uint *o, *p, c; 00862 00863 if( X == B ) 00864 { 00865 const mpi *T = A; A = X; B = T; 00866 } 00867 00868 if( X != A ) 00869 MPI_CHK( 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 MPI_CHK( 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 MPI_CHK( 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 mpi subtraction 00908 */ 00909 static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d ) 00910 { 00911 size_t i; 00912 t_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 mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ) 00931 { 00932 mpi TB; 00933 int ret; 00934 size_t n; 00935 00936 if( mpi_cmp_abs( A, B ) < 0 ) 00937 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); 00938 00939 mpi_init( &TB ); 00940 00941 if( X == B ) 00942 { 00943 MPI_CHK( mpi_copy( &TB, B ) ); 00944 B = &TB; 00945 } 00946 00947 if( X != A ) 00948 MPI_CHK( 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 mpi_free( &TB ); 00966 00967 return( ret ); 00968 } 00969 00970 /* 00971 * Signed addition: X = A + B 00972 */ 00973 int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ) 00974 { 00975 int ret, s = A->s ; 00976 00977 if( A->s * B->s < 0 ) 00978 { 00979 if( mpi_cmp_abs( A, B ) >= 0 ) 00980 { 00981 MPI_CHK( mpi_sub_abs( X, A, B ) ); 00982 X->s = s; 00983 } 00984 else 00985 { 00986 MPI_CHK( mpi_sub_abs( X, B, A ) ); 00987 X->s = -s; 00988 } 00989 } 00990 else 00991 { 00992 MPI_CHK( 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 mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ) 01005 { 01006 int ret, s = A->s ; 01007 01008 if( A->s * B->s > 0 ) 01009 { 01010 if( mpi_cmp_abs( A, B ) >= 0 ) 01011 { 01012 MPI_CHK( mpi_sub_abs( X, A, B ) ); 01013 X->s = s; 01014 } 01015 else 01016 { 01017 MPI_CHK( mpi_sub_abs( X, B, A ) ); 01018 X->s = -s; 01019 } 01020 } 01021 else 01022 { 01023 MPI_CHK( 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 mpi_add_int( mpi *X, const mpi *A, t_sint b ) 01036 { 01037 mpi _B; 01038 t_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( mpi_add_mpi( X, A, &_B ) ); 01046 } 01047 01048 /* 01049 * Signed subtraction: X = A - b 01050 */ 01051 int mpi_sub_int( mpi *X, const mpi *A, t_sint b ) 01052 { 01053 mpi _B; 01054 t_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( mpi_sub_mpi( X, A, &_B ) ); 01062 } 01063 01064 /* 01065 * Helper for 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, t_uint *s, t_uint *d, t_uint b ) 01076 { 01077 t_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 mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ) 01140 { 01141 int ret; 01142 size_t i, j; 01143 mpi TA, TB; 01144 01145 mpi_init( &TA ); mpi_init( &TB ); 01146 01147 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; } 01148 if( X == B ) { MPI_CHK( 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 MPI_CHK( mpi_grow( X, i + j ) ); 01159 MPI_CHK( 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 mpi_free( &TB ); mpi_free( &TA ); 01169 01170 return( ret ); 01171 } 01172 01173 /* 01174 * Baseline multiplication: X = A * b 01175 */ 01176 int mpi_mul_int( mpi *X, const mpi *A, t_sint b ) 01177 { 01178 mpi _B; 01179 t_uint p[1]; 01180 01181 _B.s = 1; 01182 _B.n = 1; 01183 _B.p = p; 01184 p[0] = b; 01185 01186 return( mpi_mul_mpi( X, A, &_B ) ); 01187 } 01188 01189 /* 01190 * Division by mpi: A = Q * B + R (HAC 14.20) 01191 */ 01192 int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ) 01193 { 01194 int ret; 01195 size_t i, n, t, k; 01196 mpi X, Y, Z, T1, T2; 01197 01198 if( mpi_cmp_int( B, 0 ) == 0 ) 01199 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); 01200 01201 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); 01202 mpi_init( &T1 ); mpi_init( &T2 ); 01203 01204 if( mpi_cmp_abs( A, B ) < 0 ) 01205 { 01206 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) ); 01207 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) ); 01208 return( 0 ); 01209 } 01210 01211 MPI_CHK( mpi_copy( &X, A ) ); 01212 MPI_CHK( mpi_copy( &Y, B ) ); 01213 X.s = Y.s = 1; 01214 01215 MPI_CHK( mpi_grow( &Z, A->n + 2 ) ); 01216 MPI_CHK( mpi_lset( &Z, 0 ) ); 01217 MPI_CHK( mpi_grow( &T1, 2 ) ); 01218 MPI_CHK( mpi_grow( &T2, 3 ) ); 01219 01220 k = mpi_msb( &Y ) % biL; 01221 if( k < biL - 1 ) 01222 { 01223 k = biL - 1 - k; 01224 MPI_CHK( mpi_shift_l( &X, k ) ); 01225 MPI_CHK( mpi_shift_l( &Y, k ) ); 01226 } 01227 else k = 0; 01228 01229 n = X.n - 1; 01230 t = Y.n - 1; 01231 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) ); 01232 01233 while( mpi_cmp_mpi( &X, &Y ) >= 0 ) 01234 { 01235 Z.p [n - t]++; 01236 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) ); 01237 } 01238 MPI_CHK( 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(POLARSSL_HAVE_UDBL) 01247 t_udbl r; 01248 01249 r = (t_udbl) X.p [i] << biL; 01250 r |= (t_udbl) X.p [i - 1]; 01251 r /= Y.p [t]; 01252 if( r > ( (t_udbl) 1 << biL ) - 1 ) 01253 r = ( (t_udbl) 1 << biL ) - 1; 01254 01255 Z.p [i - t - 1] = (t_uint) r; 01256 #else 01257 /* 01258 * __udiv_qrnnd_c, from gmp/longlong.h 01259 */ 01260 t_uint q0, q1, r0, r1; 01261 t_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 /* POLARSSL_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 MPI_CHK( mpi_lset( &T1, 0 ) ); 01305 T1.p [0] = ( t < 1 ) ? 0 : Y.p [t - 1]; 01306 T1.p [1] = Y.p [t]; 01307 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p [i - t - 1] ) ); 01308 01309 MPI_CHK( 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( mpi_cmp_mpi( &T1, &T2 ) > 0 ); 01315 01316 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p [i - t - 1] ) ); 01317 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); 01318 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) ); 01319 01320 if( mpi_cmp_int( &X, 0 ) < 0 ) 01321 { 01322 MPI_CHK( mpi_copy( &T1, &Y ) ); 01323 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); 01324 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) ); 01325 Z.p [i - t - 1]--; 01326 } 01327 } 01328 01329 if( Q != NULL ) 01330 { 01331 MPI_CHK( mpi_copy( Q, &Z ) ); 01332 Q->s = A->s * B->s ; 01333 } 01334 01335 if( R != NULL ) 01336 { 01337 MPI_CHK( mpi_shift_r( &X, k ) ); 01338 X.s = A->s ; 01339 MPI_CHK( mpi_copy( R, &X ) ); 01340 01341 if( mpi_cmp_int( R, 0 ) == 0 ) 01342 R->s = 1; 01343 } 01344 01345 cleanup: 01346 01347 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); 01348 mpi_free( &T1 ); mpi_free( &T2 ); 01349 01350 return( ret ); 01351 } 01352 01353 /* 01354 * Division by int: A = Q * b + R 01355 */ 01356 int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ) 01357 { 01358 mpi _B; 01359 t_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( mpi_div_mpi( Q, R, A, &_B ) ); 01367 } 01368 01369 /* 01370 * Modulo: R = A mod B 01371 */ 01372 int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ) 01373 { 01374 int ret; 01375 01376 if( mpi_cmp_int( B, 0 ) < 0 ) 01377 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE ); 01378 01379 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) ); 01380 01381 while( mpi_cmp_int( R, 0 ) < 0 ) 01382 MPI_CHK( mpi_add_mpi( R, R, B ) ); 01383 01384 while( mpi_cmp_mpi( R, B ) >= 0 ) 01385 MPI_CHK( 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 mpi_mod_int( t_uint *r, const mpi *A, t_sint b ) 01396 { 01397 size_t i; 01398 t_uint x, y, z; 01399 01400 if( b == 0 ) 01401 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO ); 01402 01403 if( b < 0 ) 01404 return( POLARSSL_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( t_uint *mm, const mpi *N ) 01453 { 01454 t_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( mpi *A, const mpi *B, const mpi *N, t_uint mm, 01470 const mpi *T ) 01471 { 01472 size_t i, n, m; 01473 t_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( 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( mpi *A, const mpi *N, t_uint mm, const mpi *T ) 01508 { 01509 t_uint z = 1; 01510 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 mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, 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 t_uint ei, mm, state; 01528 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos; 01529 int neg; 01530 01531 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p [0] & 1 ) == 0 ) 01532 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 01533 01534 if( mpi_cmp_int( E, 0 ) < 0 ) 01535 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 01536 01537 /* 01538 * Init temps and window size 01539 */ 01540 mpi_montg_init( &mm, N ); 01541 mpi_init( &RR ); mpi_init( &T ); 01542 mpi_init( &Apos ); 01543 memset( W, 0, sizeof( W ) ); 01544 01545 i = mpi_msb( E ); 01546 01547 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : 01548 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; 01549 01550 if( wsize > POLARSSL_MPI_WINDOW_SIZE ) 01551 wsize = POLARSSL_MPI_WINDOW_SIZE; 01552 01553 j = N->n + 1; 01554 MPI_CHK( mpi_grow( X, j ) ); 01555 MPI_CHK( mpi_grow( &W[1], j ) ); 01556 MPI_CHK( 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 MPI_CHK( 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 MPI_CHK( mpi_lset( &RR, 1 ) ); 01575 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) ); 01576 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) ); 01577 01578 if( _RR != NULL ) 01579 memcpy( _RR, &RR, sizeof( mpi ) ); 01580 } 01581 else 01582 memcpy( &RR, _RR, sizeof( mpi ) ); 01583 01584 /* 01585 * W[1] = A * R^2 * R^-1 mod N = A * R mod N 01586 */ 01587 if( mpi_cmp_mpi( A, N ) >= 0 ) 01588 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) ); 01589 else 01590 MPI_CHK( 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 MPI_CHK( 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 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) ); 01608 MPI_CHK( 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 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) ); 01619 MPI_CHK( 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( t_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 MPI_CHK( mpi_add_mpi( X, N, X ) ); 01711 } 01712 01713 cleanup: 01714 01715 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) 01716 mpi_free( &W[i] ); 01717 01718 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos ); 01719 01720 if( _RR == NULL || _RR->p == NULL ) 01721 mpi_free( &RR ); 01722 01723 return( ret ); 01724 } 01725 01726 /* 01727 * Greatest common divisor: G = gcd(A, B) (HAC 14.54) 01728 */ 01729 int mpi_gcd( mpi *G, const mpi *A, const mpi *B ) 01730 { 01731 int ret; 01732 size_t lz, lzt; 01733 mpi TG, TA, TB; 01734 01735 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB ); 01736 01737 MPI_CHK( mpi_copy( &TA, A ) ); 01738 MPI_CHK( mpi_copy( &TB, B ) ); 01739 01740 lz = mpi_lsb( &TA ); 01741 lzt = mpi_lsb( &TB ); 01742 01743 if( lzt < lz ) 01744 lz = lzt; 01745 01746 MPI_CHK( mpi_shift_r( &TA, lz ) ); 01747 MPI_CHK( mpi_shift_r( &TB, lz ) ); 01748 01749 TA.s = TB.s = 1; 01750 01751 while( mpi_cmp_int( &TA, 0 ) != 0 ) 01752 { 01753 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) ); 01754 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) ); 01755 01756 if( mpi_cmp_mpi( &TA, &TB ) >= 0 ) 01757 { 01758 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) ); 01759 MPI_CHK( mpi_shift_r( &TA, 1 ) ); 01760 } 01761 else 01762 { 01763 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) ); 01764 MPI_CHK( mpi_shift_r( &TB, 1 ) ); 01765 } 01766 } 01767 01768 MPI_CHK( mpi_shift_l( &TB, lz ) ); 01769 MPI_CHK( mpi_copy( G, &TB ) ); 01770 01771 cleanup: 01772 01773 mpi_free( &TG ); mpi_free( &TA ); 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 mpi_fill_random( 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[POLARSSL_MPI_MAX_SIZE]; 01791 01792 if( size > POLARSSL_MPI_MAX_SIZE ) 01793 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 01794 01795 MPI_CHK( f_rng( p_rng, buf, size ) ); 01796 MPI_CHK( 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 mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ) 01806 { 01807 int ret; 01808 mpi G, TA, TU, U1, U2, TB, TV, V1, V2; 01809 01810 if( mpi_cmp_int( N, 0 ) <= 0 ) 01811 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 01812 01813 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 ); 01814 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV ); 01815 mpi_init( &V1 ); mpi_init( &V2 ); 01816 01817 MPI_CHK( mpi_gcd( &G, A, N ) ); 01818 01819 if( mpi_cmp_int( &G, 1 ) != 0 ) 01820 { 01821 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; 01822 goto cleanup; 01823 } 01824 01825 MPI_CHK( mpi_mod_mpi( &TA, A, N ) ); 01826 MPI_CHK( mpi_copy( &TU, &TA ) ); 01827 MPI_CHK( mpi_copy( &TB, N ) ); 01828 MPI_CHK( mpi_copy( &TV, N ) ); 01829 01830 MPI_CHK( mpi_lset( &U1, 1 ) ); 01831 MPI_CHK( mpi_lset( &U2, 0 ) ); 01832 MPI_CHK( mpi_lset( &V1, 0 ) ); 01833 MPI_CHK( mpi_lset( &V2, 1 ) ); 01834 01835 do 01836 { 01837 while( ( TU.p [0] & 1 ) == 0 ) 01838 { 01839 MPI_CHK( mpi_shift_r( &TU, 1 ) ); 01840 01841 if( ( U1.p [0] & 1 ) != 0 || ( U2.p [0] & 1 ) != 0 ) 01842 { 01843 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) ); 01844 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) ); 01845 } 01846 01847 MPI_CHK( mpi_shift_r( &U1, 1 ) ); 01848 MPI_CHK( mpi_shift_r( &U2, 1 ) ); 01849 } 01850 01851 while( ( TV.p [0] & 1 ) == 0 ) 01852 { 01853 MPI_CHK( mpi_shift_r( &TV, 1 ) ); 01854 01855 if( ( V1.p [0] & 1 ) != 0 || ( V2.p [0] & 1 ) != 0 ) 01856 { 01857 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) ); 01858 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) ); 01859 } 01860 01861 MPI_CHK( mpi_shift_r( &V1, 1 ) ); 01862 MPI_CHK( mpi_shift_r( &V2, 1 ) ); 01863 } 01864 01865 if( mpi_cmp_mpi( &TU, &TV ) >= 0 ) 01866 { 01867 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) ); 01868 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) ); 01869 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) ); 01870 } 01871 else 01872 { 01873 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) ); 01874 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) ); 01875 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) ); 01876 } 01877 } 01878 while( mpi_cmp_int( &TU, 0 ) != 0 ); 01879 01880 while( mpi_cmp_int( &V1, 0 ) < 0 ) 01881 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) ); 01882 01883 while( mpi_cmp_mpi( &V1, N ) >= 0 ) 01884 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) ); 01885 01886 MPI_CHK( mpi_copy( X, &V1 ) ); 01887 01888 cleanup: 01889 01890 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 ); 01891 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV ); 01892 mpi_free( &V1 ); mpi_free( &V2 ); 01893 01894 return( ret ); 01895 } 01896 01897 #if defined(POLARSSL_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 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime 01931 * other negative: error 01932 */ 01933 static int mpi_check_small_factors( const mpi *X ) 01934 { 01935 int ret = 0; 01936 size_t i; 01937 t_uint r; 01938 01939 if( ( X->p [0] & 1 ) == 0 ) 01940 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); 01941 01942 for( i = 0; small_prime[i] > 0; i++ ) 01943 { 01944 if( mpi_cmp_int( X, small_prime[i] ) <= 0 ) 01945 return( 1 ); 01946 01947 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) ); 01948 01949 if( r == 0 ) 01950 return( POLARSSL_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 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 mpi W, R, T, A, RR; 01967 01968 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A ); 01969 mpi_init( &RR ); 01970 01971 /* 01972 * W = |X| - 1 01973 * R = W >> lsb( W ) 01974 */ 01975 MPI_CHK( mpi_sub_int( &W, X, 1 ) ); 01976 s = mpi_lsb( &W ); 01977 MPI_CHK( mpi_copy( &R, &W ) ); 01978 MPI_CHK( mpi_shift_r( &R, s ) ); 01979 01980 i = mpi_msb( 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 01994 count = 0; 01995 do { 01996 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); 01997 01998 j = mpi_msb( &A ); 01999 k = mpi_msb( &W ); 02000 if (j > k) { 02001 MPI_CHK( mpi_shift_r( &A, j - k ) ); 02002 } 02003 02004 if (count++ > 30) { 02005 return POLARSSL_ERR_MPI_NOT_ACCEPTABLE; 02006 } 02007 02008 } while ( (mpi_cmp_mpi( &A, &W ) >= 0) || 02009 (mpi_cmp_int( &A, 1 ) <= 0) ); 02010 02011 /* 02012 * A = A^R mod |X| 02013 */ 02014 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) ); 02015 02016 if( mpi_cmp_mpi( &A, &W ) == 0 || 02017 mpi_cmp_int( &A, 1 ) == 0 ) 02018 continue; 02019 02020 j = 1; 02021 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 ) 02022 { 02023 /* 02024 * A = A * A mod |X| 02025 */ 02026 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) ); 02027 MPI_CHK( mpi_mod_mpi( &A, &T, X ) ); 02028 02029 if( mpi_cmp_int( &A, 1 ) == 0 ) 02030 break; 02031 02032 j++; 02033 } 02034 02035 /* 02036 * not prime if A != |X| - 1 or A == 1 02037 */ 02038 if( mpi_cmp_mpi( &A, &W ) != 0 || 02039 mpi_cmp_int( &A, 1 ) == 0 ) 02040 { 02041 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE; 02042 break; 02043 } 02044 } 02045 02046 cleanup: 02047 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A ); 02048 mpi_free( &RR ); 02049 02050 return( ret ); 02051 } 02052 02053 /* 02054 * Pseudo-primality test: small factors, then Miller-Rabin 02055 */ 02056 int mpi_is_prime( mpi *X, 02057 int (*f_rng)(void *, unsigned char *, size_t), 02058 void *p_rng ) 02059 { 02060 int ret; 02061 mpi XX; 02062 02063 XX.s = 1; 02064 XX.n = X->n ; 02065 XX.p = X->p ; 02066 02067 if( mpi_cmp_int( &XX, 0 ) == 0 || 02068 mpi_cmp_int( &XX, 1 ) == 0 ) 02069 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE ); 02070 02071 if( mpi_cmp_int( &XX, 2 ) == 0 ) 02072 return( 0 ); 02073 02074 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) 02075 { 02076 if( ret == 1 ) 02077 return( 0 ); 02078 02079 return( ret ); 02080 } 02081 02082 return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); 02083 } 02084 02085 /* 02086 * Prime number generation 02087 */ 02088 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, 02089 int (*f_rng)(void *, unsigned char *, size_t), 02090 void *p_rng ) 02091 { 02092 int ret; 02093 size_t k, n; 02094 t_uint r; 02095 mpi Y; 02096 02097 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS ) 02098 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA ); 02099 02100 mpi_init( &Y ); 02101 02102 n = BITS_TO_LIMBS( nbits ); 02103 02104 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); 02105 02106 k = mpi_msb( X ); 02107 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) ); 02108 02109 mpi_set_bit( X, nbits-1, 1 ); 02110 02111 X->p [0] |= 1; 02112 02113 if( dh_flag == 0 ) 02114 { 02115 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) 02116 { 02117 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) 02118 goto cleanup; 02119 02120 MPI_CHK( mpi_add_int( X, X, 2 ) ); 02121 } 02122 } 02123 else 02124 { 02125 /* 02126 * An necessary condition for Y and X = 2Y + 1 to be prime 02127 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). 02128 * Make sure it is satisfied, while keeping X = 3 mod 4 02129 */ 02130 02131 X->p [0] |= 2; 02132 02133 MPI_CHK( mpi_mod_int( &r, X, 3 ) ); 02134 if( r == 0 ) 02135 MPI_CHK( mpi_add_int( X, X, 8 ) ); 02136 else if( r == 1 ) 02137 MPI_CHK( mpi_add_int( X, X, 4 ) ); 02138 02139 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ 02140 MPI_CHK( mpi_copy( &Y, X ) ); 02141 MPI_CHK( mpi_shift_r( &Y, 1 ) ); 02142 02143 while( 1 ) 02144 { 02145 /* 02146 * First, check small factors for X and Y 02147 * before doing Miller-Rabin on any of them 02148 */ 02149 if( ( ret = mpi_check_small_factors( X ) ) == 0 && 02150 ( ret = mpi_check_small_factors( &Y ) ) == 0 && 02151 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && 02152 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) 02153 { 02154 break; 02155 } 02156 02157 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE ) 02158 goto cleanup; 02159 02160 /* 02161 * Next candidates. We want to preserve Y = (X-1) / 2 and 02162 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) 02163 * so up Y by 6 and X by 12. 02164 */ 02165 MPI_CHK( mpi_add_int( X, X, 12 ) ); 02166 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) ); 02167 } 02168 } 02169 02170 cleanup: 02171 02172 mpi_free( &Y ); 02173 02174 return( ret ); 02175 } 02176 02177 #endif /* POLARSSL_GENPRIME */ 02178 02179 #if defined(POLARSSL_SELF_TEST) 02180 02181 #define GCD_PAIR_COUNT 3 02182 02183 static const int gcd_pairs[GCD_PAIR_COUNT][3] = 02184 { 02185 { 693, 609, 21 }, 02186 { 1764, 868, 28 }, 02187 { 768454923, 542167814, 1 } 02188 }; 02189 02190 /* 02191 * Checkup routine 02192 */ 02193 int mpi_self_test( int verbose ) 02194 { 02195 int ret, i; 02196 mpi A, E, N, X, Y, U, V; 02197 02198 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X ); 02199 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V ); 02200 02201 MPI_CHK( mpi_read_string( &A, 16, 02202 "EFE021C2645FD1DC586E69184AF4A31E" \ 02203 "D5F53E93B5F123FA41680867BA110131" \ 02204 "944FE7952E2517337780CB0DB80E61AA" \ 02205 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); 02206 02207 MPI_CHK( mpi_read_string( &E, 16, 02208 "B2E7EFD37075B9F03FF989C7C5051C20" \ 02209 "34D2A323810251127E7BF8625A4F49A5" \ 02210 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ 02211 "5B5C25763222FEFCCFC38B832366C29E" ) ); 02212 02213 MPI_CHK( mpi_read_string( &N, 16, 02214 "0066A198186C18C10B2F5ED9B522752A" \ 02215 "9830B69916E535C8F047518A889A43A5" \ 02216 "94B6BED27A168D31D4A52F88925AA8F5" ) ); 02217 02218 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) ); 02219 02220 MPI_CHK( mpi_read_string( &U, 16, 02221 "602AB7ECA597A3D6B56FF9829A5E8B85" \ 02222 "9E857EA95A03512E2BAE7391688D264A" \ 02223 "A5663B0341DB9CCFD2C4C5F421FEC814" \ 02224 "8001B72E848A38CAE1C65F78E56ABDEF" \ 02225 "E12D3C039B8A02D6BE593F0BBBDA56F1" \ 02226 "ECF677152EF804370C1A305CAF3B5BF1" \ 02227 "30879B56C61DE584A0F53A2447A51E" ) ); 02228 02229 if( verbose != 0 ) 02230 polarssl_printf( " MPI test #1 (mul_mpi): " ); 02231 02232 if( mpi_cmp_mpi( &X, &U ) != 0 ) 02233 { 02234 if( verbose != 0 ) 02235 polarssl_printf( "failed\n" ); 02236 02237 ret = 1; 02238 goto cleanup; 02239 } 02240 02241 if( verbose != 0 ) 02242 polarssl_printf( "passed\n" ); 02243 02244 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) ); 02245 02246 MPI_CHK( mpi_read_string( &U, 16, 02247 "256567336059E52CAE22925474705F39A94" ) ); 02248 02249 MPI_CHK( mpi_read_string( &V, 16, 02250 "6613F26162223DF488E9CD48CC132C7A" \ 02251 "0AC93C701B001B092E4E5B9F73BCD27B" \ 02252 "9EE50D0657C77F374E903CDFA4C642" ) ); 02253 02254 if( verbose != 0 ) 02255 polarssl_printf( " MPI test #2 (div_mpi): " ); 02256 02257 if( mpi_cmp_mpi( &X, &U ) != 0 || 02258 mpi_cmp_mpi( &Y, &V ) != 0 ) 02259 { 02260 if( verbose != 0 ) 02261 polarssl_printf( "failed\n" ); 02262 02263 ret = 1; 02264 goto cleanup; 02265 } 02266 02267 if( verbose != 0 ) 02268 polarssl_printf( "passed\n" ); 02269 02270 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) ); 02271 02272 MPI_CHK( mpi_read_string( &U, 16, 02273 "36E139AEA55215609D2816998ED020BB" \ 02274 "BD96C37890F65171D948E9BC7CBAA4D9" \ 02275 "325D24D6A3C12710F10A09FA08AB87" ) ); 02276 02277 if( verbose != 0 ) 02278 polarssl_printf( " MPI test #3 (exp_mod): " ); 02279 02280 if( mpi_cmp_mpi( &X, &U ) != 0 ) 02281 { 02282 if( verbose != 0 ) 02283 polarssl_printf( "failed\n" ); 02284 02285 ret = 1; 02286 goto cleanup; 02287 } 02288 02289 if( verbose != 0 ) 02290 polarssl_printf( "passed\n" ); 02291 02292 MPI_CHK( mpi_inv_mod( &X, &A, &N ) ); 02293 02294 MPI_CHK( mpi_read_string( &U, 16, 02295 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ 02296 "C3DBA76456363A10869622EAC2DD84EC" \ 02297 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); 02298 02299 if( verbose != 0 ) 02300 polarssl_printf( " MPI test #4 (inv_mod): " ); 02301 02302 if( mpi_cmp_mpi( &X, &U ) != 0 ) 02303 { 02304 if( verbose != 0 ) 02305 polarssl_printf( "failed\n" ); 02306 02307 ret = 1; 02308 goto cleanup; 02309 } 02310 02311 if( verbose != 0 ) 02312 polarssl_printf( "passed\n" ); 02313 02314 if( verbose != 0 ) 02315 polarssl_printf( " MPI test #5 (simple gcd): " ); 02316 02317 for( i = 0; i < GCD_PAIR_COUNT; i++ ) 02318 { 02319 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) ); 02320 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) ); 02321 02322 MPI_CHK( mpi_gcd( &A, &X, &Y ) ); 02323 02324 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) 02325 { 02326 if( verbose != 0 ) 02327 polarssl_printf( "failed at %d\n", i ); 02328 02329 ret = 1; 02330 goto cleanup; 02331 } 02332 } 02333 02334 if( verbose != 0 ) 02335 polarssl_printf( "passed\n" ); 02336 02337 cleanup: 02338 02339 if( ret != 0 && verbose != 0 ) 02340 polarssl_printf( "Unexpected error, return code = %08X\n", ret ); 02341 02342 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X ); 02343 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V ); 02344 02345 if( verbose != 0 ) 02346 polarssl_printf( "\n" ); 02347 02348 return( ret ); 02349 } 02350 02351 #endif /* POLARSSL_SELF_TEST */ 02352 02353 #endif /* POLARSSL_BIGNUM_C */ 02354
Generated on Tue Jul 12 2022 13:50:36 by
![doxygen](doxygen.png)