initial commit; it works
[psslcertgen.git] / src / libpolarssl / bignum.c
bloba0f10a00ffd653886f9d0a63c06d06befab108a5
1 /*
2 * Multi-precision integer library
4 * Copyright (C) 2006-2010, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
9 * All rights reserved.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * This MPI implementation is based on:
28 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
29 * http://www.stillhq.com/extracted/gnupg-api/mpi/
30 * http://math.libtomcrypt.com/files/tommath.pdf
33 #include "config.h"
35 #if defined(POLARSSL_BIGNUM_C)
37 #include "bignum.h"
38 #include "bn_mul.h"
40 #include <stdlib.h>
42 #define ciL (sizeof(t_uint)) /* chars in limb */
43 #define biL (ciL << 3) /* bits in limb */
44 #define biH (ciL << 2) /* half limb size */
47 * Convert between bits/chars and number of limbs
49 #define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
50 #define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
53 * Initialize one MPI
55 void mpi_init( mpi *X )
57 if( X == NULL )
58 return;
60 X->s = 1;
61 X->n = 0;
62 X->p = NULL;
66 * Unallocate one MPI
68 void mpi_free( mpi *X )
70 if( X == NULL )
71 return;
73 if( X->p != NULL )
75 memset( X->p, 0, X->n * ciL );
76 free( X->p );
79 X->s = 1;
80 X->n = 0;
81 X->p = NULL;
85 * Enlarge to the specified number of limbs
87 int mpi_grow( mpi *X, size_t nblimbs )
89 t_uint *p;
91 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
92 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
94 if( X->n < nblimbs )
96 if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
97 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
99 memset( p, 0, nblimbs * ciL );
101 if( X->p != NULL )
103 memcpy( p, X->p, X->n * ciL );
104 memset( X->p, 0, X->n * ciL );
105 free( X->p );
108 X->n = nblimbs;
109 X->p = p;
112 return( 0 );
116 * Copy the contents of Y into X
118 int mpi_copy( mpi *X, const mpi *Y )
120 int ret;
121 size_t i;
123 if( X == Y )
124 return( 0 );
126 for( i = Y->n - 1; i > 0; i-- )
127 if( Y->p[i] != 0 )
128 break;
129 i++;
131 X->s = Y->s;
133 MPI_CHK( mpi_grow( X, i ) );
135 memset( X->p, 0, X->n * ciL );
136 memcpy( X->p, Y->p, i * ciL );
138 cleanup:
140 return( ret );
144 * Swap the contents of X and Y
146 void mpi_swap( mpi *X, mpi *Y )
148 mpi T;
150 memcpy( &T, X, sizeof( mpi ) );
151 memcpy( X, Y, sizeof( mpi ) );
152 memcpy( Y, &T, sizeof( mpi ) );
156 * Set value from integer
158 int mpi_lset( mpi *X, t_sint z )
160 int ret;
162 MPI_CHK( mpi_grow( X, 1 ) );
163 memset( X->p, 0, X->n * ciL );
165 X->p[0] = ( z < 0 ) ? -z : z;
166 X->s = ( z < 0 ) ? -1 : 1;
168 cleanup:
170 return( ret );
174 * Get a specific bit
176 int mpi_get_bit( const mpi *X, size_t pos )
178 if( X->n * biL <= pos )
179 return( 0 );
181 return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
185 * Set a bit to a specific value of 0 or 1
187 int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
189 int ret = 0;
190 size_t off = pos / biL;
191 size_t idx = pos % biL;
193 if( val != 0 && val != 1 )
194 return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
196 if( X->n * biL <= pos )
198 if( val == 0 )
199 return ( 0 );
201 MPI_CHK( mpi_grow( X, off + 1 ) );
204 X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx );
206 cleanup:
208 return( ret );
212 * Return the number of least significant bits
214 size_t mpi_lsb( const mpi *X )
216 size_t i, j, count = 0;
218 for( i = 0; i < X->n; i++ )
219 for( j = 0; j < biL; j++, count++ )
220 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
221 return( count );
223 return( 0 );
227 * Return the number of most significant bits
229 size_t mpi_msb( const mpi *X )
231 size_t i, j;
233 for( i = X->n - 1; i > 0; i-- )
234 if( X->p[i] != 0 )
235 break;
237 for( j = biL; j > 0; j-- )
238 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
239 break;
241 return( ( i * biL ) + j );
245 * Return the total size in bytes
247 size_t mpi_size( const mpi *X )
249 return( ( mpi_msb( X ) + 7 ) >> 3 );
253 * Convert an ASCII character to digit value
255 static int mpi_get_digit( t_uint *d, int radix, char c )
257 *d = 255;
259 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
260 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
261 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
263 if( *d >= (t_uint) radix )
264 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
266 return( 0 );
270 * Import from an ASCII string
272 int mpi_read_string( mpi *X, int radix, const char *s )
274 int ret;
275 size_t i, j, slen, n;
276 t_uint d;
277 mpi T;
279 if( radix < 2 || radix > 16 )
280 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
282 mpi_init( &T );
284 slen = strlen( s );
286 if( radix == 16 )
288 n = BITS_TO_LIMBS( slen << 2 );
290 MPI_CHK( mpi_grow( X, n ) );
291 MPI_CHK( mpi_lset( X, 0 ) );
293 for( i = slen, j = 0; i > 0; i--, j++ )
295 if( i == 1 && s[i - 1] == '-' )
297 X->s = -1;
298 break;
301 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
302 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
305 else
307 MPI_CHK( mpi_lset( X, 0 ) );
309 for( i = 0; i < slen; i++ )
311 if( i == 0 && s[i] == '-' )
313 X->s = -1;
314 continue;
317 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
318 MPI_CHK( mpi_mul_int( &T, X, radix ) );
320 if( X->s == 1 )
322 MPI_CHK( mpi_add_int( X, &T, d ) );
324 else
326 MPI_CHK( mpi_sub_int( X, &T, d ) );
331 cleanup:
333 mpi_free( &T );
335 return( ret );
339 * Helper to write the digits high-order first
341 static int mpi_write_hlp( mpi *X, int radix, char **p )
343 int ret;
344 t_uint r;
346 if( radix < 2 || radix > 16 )
347 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
349 MPI_CHK( mpi_mod_int( &r, X, radix ) );
350 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
352 if( mpi_cmp_int( X, 0 ) != 0 )
353 MPI_CHK( mpi_write_hlp( X, radix, p ) );
355 if( r < 10 )
356 *(*p)++ = (char)( r + 0x30 );
357 else
358 *(*p)++ = (char)( r + 0x37 );
360 cleanup:
362 return( ret );
366 * Export into an ASCII string
368 int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
370 int ret = 0;
371 size_t n;
372 char *p;
373 mpi T;
375 if( radix < 2 || radix > 16 )
376 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
378 n = mpi_msb( X );
379 if( radix >= 4 ) n >>= 1;
380 if( radix >= 16 ) n >>= 1;
381 n += 3;
383 if( *slen < n )
385 *slen = n;
386 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
389 p = s;
390 mpi_init( &T );
392 if( X->s == -1 )
393 *p++ = '-';
395 if( radix == 16 )
397 int c;
398 size_t i, j, k;
400 for( i = X->n, k = 0; i > 0; i-- )
402 for( j = ciL; j > 0; j-- )
404 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
406 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
407 continue;
409 *(p++) = "0123456789ABCDEF" [c / 16];
410 *(p++) = "0123456789ABCDEF" [c % 16];
411 k = 1;
415 else
417 MPI_CHK( mpi_copy( &T, X ) );
419 if( T.s == -1 )
420 T.s = 1;
422 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
425 *p++ = '\0';
426 *slen = p - s;
428 cleanup:
430 mpi_free( &T );
432 return( ret );
435 #if defined(POLARSSL_FS_IO)
437 * Read X from an opened file
439 int mpi_read_file( mpi *X, int radix, FILE *fin )
441 t_uint d;
442 size_t slen;
443 char *p;
445 * Buffer should have space for (short) label and decimal formatted MPI,
446 * newline characters and '\0'
448 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
450 memset( s, 0, sizeof( s ) );
451 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
452 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
454 slen = strlen( s );
455 if( slen == sizeof( s ) - 2 )
456 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
458 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
459 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
461 p = s + slen;
462 while( --p >= s )
463 if( mpi_get_digit( &d, radix, *p ) != 0 )
464 break;
466 return( mpi_read_string( X, radix, p + 1 ) );
470 * Write X into an opened file (or stdout if fout == NULL)
472 int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
474 int ret;
475 size_t n, slen, plen;
477 * Buffer should have space for (short) label and decimal formatted MPI,
478 * newline characters and '\0'
480 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
482 n = sizeof( s );
483 memset( s, 0, n );
484 n -= 2;
486 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
488 if( p == NULL ) p = "";
490 plen = strlen( p );
491 slen = strlen( s );
492 s[slen++] = '\r';
493 s[slen++] = '\n';
495 if( fout != NULL )
497 if( fwrite( p, 1, plen, fout ) != plen ||
498 fwrite( s, 1, slen, fout ) != slen )
499 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
501 else
502 printf( "%s%s", p, s );
504 cleanup:
506 return( ret );
508 #endif /* POLARSSL_FS_IO */
511 * Import X from unsigned binary data, big endian
513 int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
515 int ret;
516 size_t i, j, n;
518 for( n = 0; n < buflen; n++ )
519 if( buf[n] != 0 )
520 break;
522 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
523 MPI_CHK( mpi_lset( X, 0 ) );
525 for( i = buflen, j = 0; i > n; i--, j++ )
526 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
528 cleanup:
530 return( ret );
534 * Export X into unsigned binary data, big endian
536 int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
538 size_t i, j, n;
540 n = mpi_size( X );
542 if( buflen < n )
543 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
545 memset( buf, 0, buflen );
547 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
548 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
550 return( 0 );
554 * Left-shift: X <<= count
556 int mpi_shift_l( mpi *X, size_t count )
558 int ret;
559 size_t i, v0, t1;
560 t_uint r0 = 0, r1;
562 v0 = count / (biL );
563 t1 = count & (biL - 1);
565 i = mpi_msb( X ) + count;
567 if( X->n * biL < i )
568 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
570 ret = 0;
573 * shift by count / limb_size
575 if( v0 > 0 )
577 for( i = X->n; i > v0; i-- )
578 X->p[i - 1] = X->p[i - v0 - 1];
580 for( ; i > 0; i-- )
581 X->p[i - 1] = 0;
585 * shift by count % limb_size
587 if( t1 > 0 )
589 for( i = v0; i < X->n; i++ )
591 r1 = X->p[i] >> (biL - t1);
592 X->p[i] <<= t1;
593 X->p[i] |= r0;
594 r0 = r1;
598 cleanup:
600 return( ret );
604 * Right-shift: X >>= count
606 int mpi_shift_r( mpi *X, size_t count )
608 size_t i, v0, v1;
609 t_uint r0 = 0, r1;
611 v0 = count / biL;
612 v1 = count & (biL - 1);
614 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
615 return mpi_lset( X, 0 );
618 * shift by count / limb_size
620 if( v0 > 0 )
622 for( i = 0; i < X->n - v0; i++ )
623 X->p[i] = X->p[i + v0];
625 for( ; i < X->n; i++ )
626 X->p[i] = 0;
630 * shift by count % limb_size
632 if( v1 > 0 )
634 for( i = X->n; i > 0; i-- )
636 r1 = X->p[i - 1] << (biL - v1);
637 X->p[i - 1] >>= v1;
638 X->p[i - 1] |= r0;
639 r0 = r1;
643 return( 0 );
647 * Compare unsigned values
649 int mpi_cmp_abs( const mpi *X, const mpi *Y )
651 size_t i, j;
653 for( i = X->n; i > 0; i-- )
654 if( X->p[i - 1] != 0 )
655 break;
657 for( j = Y->n; j > 0; j-- )
658 if( Y->p[j - 1] != 0 )
659 break;
661 if( i == 0 && j == 0 )
662 return( 0 );
664 if( i > j ) return( 1 );
665 if( j > i ) return( -1 );
667 for( ; i > 0; i-- )
669 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
670 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
673 return( 0 );
677 * Compare signed values
679 int mpi_cmp_mpi( const mpi *X, const mpi *Y )
681 size_t i, j;
683 for( i = X->n; i > 0; i-- )
684 if( X->p[i - 1] != 0 )
685 break;
687 for( j = Y->n; j > 0; j-- )
688 if( Y->p[j - 1] != 0 )
689 break;
691 if( i == 0 && j == 0 )
692 return( 0 );
694 if( i > j ) return( X->s );
695 if( j > i ) return( -Y->s );
697 if( X->s > 0 && Y->s < 0 ) return( 1 );
698 if( Y->s > 0 && X->s < 0 ) return( -1 );
700 for( ; i > 0; i-- )
702 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
703 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
706 return( 0 );
710 * Compare signed values
712 int mpi_cmp_int( const mpi *X, t_sint z )
714 mpi Y;
715 t_uint p[1];
717 *p = ( z < 0 ) ? -z : z;
718 Y.s = ( z < 0 ) ? -1 : 1;
719 Y.n = 1;
720 Y.p = p;
722 return( mpi_cmp_mpi( X, &Y ) );
726 * Unsigned addition: X = |A| + |B| (HAC 14.7)
728 int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
730 int ret;
731 size_t i, j;
732 t_uint *o, *p, c;
734 if( X == B )
736 const mpi *T = A; A = X; B = T;
739 if( X != A )
740 MPI_CHK( mpi_copy( X, A ) );
743 * X should always be positive as a result of unsigned additions.
745 X->s = 1;
747 for( j = B->n; j > 0; j-- )
748 if( B->p[j - 1] != 0 )
749 break;
751 MPI_CHK( mpi_grow( X, j ) );
753 o = B->p; p = X->p; c = 0;
755 for( i = 0; i < j; i++, o++, p++ )
757 *p += c; c = ( *p < c );
758 *p += *o; c += ( *p < *o );
761 while( c != 0 )
763 if( i >= X->n )
765 MPI_CHK( mpi_grow( X, i + 1 ) );
766 p = X->p + i;
769 *p += c; c = ( *p < c ); i++; p++;
772 cleanup:
774 return( ret );
778 * Helper for mpi substraction
780 static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
782 size_t i;
783 t_uint c, z;
785 for( i = c = 0; i < n; i++, s++, d++ )
787 z = ( *d < c ); *d -= c;
788 c = ( *d < *s ) + z; *d -= *s;
791 while( c != 0 )
793 z = ( *d < c ); *d -= c;
794 c = z; i++; d++;
799 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
801 int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
803 mpi TB;
804 int ret;
805 size_t n;
807 if( mpi_cmp_abs( A, B ) < 0 )
808 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
810 mpi_init( &TB );
812 if( X == B )
814 MPI_CHK( mpi_copy( &TB, B ) );
815 B = &TB;
818 if( X != A )
819 MPI_CHK( mpi_copy( X, A ) );
822 * X should always be positive as a result of unsigned substractions.
824 X->s = 1;
826 ret = 0;
828 for( n = B->n; n > 0; n-- )
829 if( B->p[n - 1] != 0 )
830 break;
832 mpi_sub_hlp( n, B->p, X->p );
834 cleanup:
836 mpi_free( &TB );
838 return( ret );
842 * Signed addition: X = A + B
844 int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
846 int ret, s = A->s;
848 if( A->s * B->s < 0 )
850 if( mpi_cmp_abs( A, B ) >= 0 )
852 MPI_CHK( mpi_sub_abs( X, A, B ) );
853 X->s = s;
855 else
857 MPI_CHK( mpi_sub_abs( X, B, A ) );
858 X->s = -s;
861 else
863 MPI_CHK( mpi_add_abs( X, A, B ) );
864 X->s = s;
867 cleanup:
869 return( ret );
873 * Signed substraction: X = A - B
875 int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
877 int ret, s = A->s;
879 if( A->s * B->s > 0 )
881 if( mpi_cmp_abs( A, B ) >= 0 )
883 MPI_CHK( mpi_sub_abs( X, A, B ) );
884 X->s = s;
886 else
888 MPI_CHK( mpi_sub_abs( X, B, A ) );
889 X->s = -s;
892 else
894 MPI_CHK( mpi_add_abs( X, A, B ) );
895 X->s = s;
898 cleanup:
900 return( ret );
904 * Signed addition: X = A + b
906 int mpi_add_int( mpi *X, const mpi *A, t_sint b )
908 mpi _B;
909 t_uint p[1];
911 p[0] = ( b < 0 ) ? -b : b;
912 _B.s = ( b < 0 ) ? -1 : 1;
913 _B.n = 1;
914 _B.p = p;
916 return( mpi_add_mpi( X, A, &_B ) );
920 * Signed substraction: X = A - b
922 int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
924 mpi _B;
925 t_uint p[1];
927 p[0] = ( b < 0 ) ? -b : b;
928 _B.s = ( b < 0 ) ? -1 : 1;
929 _B.n = 1;
930 _B.p = p;
932 return( mpi_sub_mpi( X, A, &_B ) );
936 * Helper for mpi multiplication
938 static
939 #if defined(__APPLE__) && defined(__arm__)
941 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
942 * appears to need this to prevent bad ARM code generation at -O3.
944 __attribute__ ((noinline))
945 #endif
946 void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
948 t_uint c = 0, t = 0;
950 #if defined(MULADDC_HUIT)
951 for( ; i >= 8; i -= 8 )
953 MULADDC_INIT
954 MULADDC_HUIT
955 MULADDC_STOP
958 for( ; i > 0; i-- )
960 MULADDC_INIT
961 MULADDC_CORE
962 MULADDC_STOP
964 #else
965 for( ; i >= 16; i -= 16 )
967 MULADDC_INIT
968 MULADDC_CORE MULADDC_CORE
969 MULADDC_CORE MULADDC_CORE
970 MULADDC_CORE MULADDC_CORE
971 MULADDC_CORE MULADDC_CORE
973 MULADDC_CORE MULADDC_CORE
974 MULADDC_CORE MULADDC_CORE
975 MULADDC_CORE MULADDC_CORE
976 MULADDC_CORE MULADDC_CORE
977 MULADDC_STOP
980 for( ; i >= 8; i -= 8 )
982 MULADDC_INIT
983 MULADDC_CORE MULADDC_CORE
984 MULADDC_CORE MULADDC_CORE
986 MULADDC_CORE MULADDC_CORE
987 MULADDC_CORE MULADDC_CORE
988 MULADDC_STOP
991 for( ; i > 0; i-- )
993 MULADDC_INIT
994 MULADDC_CORE
995 MULADDC_STOP
997 #endif
999 t++;
1001 do {
1002 *d += c; c = ( *d < c ); d++;
1004 while( c != 0 );
1008 * Baseline multiplication: X = A * B (HAC 14.12)
1010 int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
1012 int ret;
1013 size_t i, j;
1014 mpi TA, TB;
1016 mpi_init( &TA ); mpi_init( &TB );
1018 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1019 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1021 for( i = A->n; i > 0; i-- )
1022 if( A->p[i - 1] != 0 )
1023 break;
1025 for( j = B->n; j > 0; j-- )
1026 if( B->p[j - 1] != 0 )
1027 break;
1029 MPI_CHK( mpi_grow( X, i + j ) );
1030 MPI_CHK( mpi_lset( X, 0 ) );
1032 for( i++; j > 0; j-- )
1033 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
1035 X->s = A->s * B->s;
1037 cleanup:
1039 mpi_free( &TB ); mpi_free( &TA );
1041 return( ret );
1045 * Baseline multiplication: X = A * b
1047 int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
1049 mpi _B;
1050 t_uint p[1];
1052 _B.s = 1;
1053 _B.n = 1;
1054 _B.p = p;
1055 p[0] = b;
1057 return( mpi_mul_mpi( X, A, &_B ) );
1061 * Division by mpi: A = Q * B + R (HAC 14.20)
1063 int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
1065 int ret;
1066 size_t i, n, t, k;
1067 mpi X, Y, Z, T1, T2;
1069 if( mpi_cmp_int( B, 0 ) == 0 )
1070 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
1072 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1073 mpi_init( &T1 ); mpi_init( &T2 );
1075 if( mpi_cmp_abs( A, B ) < 0 )
1077 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1078 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1079 return( 0 );
1082 MPI_CHK( mpi_copy( &X, A ) );
1083 MPI_CHK( mpi_copy( &Y, B ) );
1084 X.s = Y.s = 1;
1086 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1087 MPI_CHK( mpi_lset( &Z, 0 ) );
1088 MPI_CHK( mpi_grow( &T1, 2 ) );
1089 MPI_CHK( mpi_grow( &T2, 3 ) );
1091 k = mpi_msb( &Y ) % biL;
1092 if( k < biL - 1 )
1094 k = biL - 1 - k;
1095 MPI_CHK( mpi_shift_l( &X, k ) );
1096 MPI_CHK( mpi_shift_l( &Y, k ) );
1098 else k = 0;
1100 n = X.n - 1;
1101 t = Y.n - 1;
1102 MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
1104 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1106 Z.p[n - t]++;
1107 mpi_sub_mpi( &X, &X, &Y );
1109 mpi_shift_r( &Y, biL * (n - t) );
1111 for( i = n; i > t ; i-- )
1113 if( X.p[i] >= Y.p[t] )
1114 Z.p[i - t - 1] = ~0;
1115 else
1117 #if defined(POLARSSL_HAVE_UDBL)
1118 t_udbl r;
1120 r = (t_udbl) X.p[i] << biL;
1121 r |= (t_udbl) X.p[i - 1];
1122 r /= Y.p[t];
1123 if( r > ((t_udbl) 1 << biL) - 1)
1124 r = ((t_udbl) 1 << biL) - 1;
1126 Z.p[i - t - 1] = (t_uint) r;
1127 #else
1129 * __udiv_qrnnd_c, from gmp/longlong.h
1131 t_uint q0, q1, r0, r1;
1132 t_uint d0, d1, d, m;
1134 d = Y.p[t];
1135 d0 = ( d << biH ) >> biH;
1136 d1 = ( d >> biH );
1138 q1 = X.p[i] / d1;
1139 r1 = X.p[i] - d1 * q1;
1140 r1 <<= biH;
1141 r1 |= ( X.p[i - 1] >> biH );
1143 m = q1 * d0;
1144 if( r1 < m )
1146 q1--, r1 += d;
1147 while( r1 >= d && r1 < m )
1148 q1--, r1 += d;
1150 r1 -= m;
1152 q0 = r1 / d1;
1153 r0 = r1 - d1 * q0;
1154 r0 <<= biH;
1155 r0 |= ( X.p[i - 1] << biH ) >> biH;
1157 m = q0 * d0;
1158 if( r0 < m )
1160 q0--, r0 += d;
1161 while( r0 >= d && r0 < m )
1162 q0--, r0 += d;
1164 r0 -= m;
1166 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1167 #endif
1170 Z.p[i - t - 1]++;
1173 Z.p[i - t - 1]--;
1175 MPI_CHK( mpi_lset( &T1, 0 ) );
1176 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1177 T1.p[1] = Y.p[t];
1178 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1180 MPI_CHK( mpi_lset( &T2, 0 ) );
1181 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1182 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1183 T2.p[2] = X.p[i];
1185 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1187 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1188 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1189 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1191 if( mpi_cmp_int( &X, 0 ) < 0 )
1193 MPI_CHK( mpi_copy( &T1, &Y ) );
1194 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1195 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1196 Z.p[i - t - 1]--;
1200 if( Q != NULL )
1202 mpi_copy( Q, &Z );
1203 Q->s = A->s * B->s;
1206 if( R != NULL )
1208 mpi_shift_r( &X, k );
1209 X.s = A->s;
1210 mpi_copy( R, &X );
1212 if( mpi_cmp_int( R, 0 ) == 0 )
1213 R->s = 1;
1216 cleanup:
1218 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1219 mpi_free( &T1 ); mpi_free( &T2 );
1221 return( ret );
1225 * Division by int: A = Q * b + R
1227 int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
1229 mpi _B;
1230 t_uint p[1];
1232 p[0] = ( b < 0 ) ? -b : b;
1233 _B.s = ( b < 0 ) ? -1 : 1;
1234 _B.n = 1;
1235 _B.p = p;
1237 return( mpi_div_mpi( Q, R, A, &_B ) );
1241 * Modulo: R = A mod B
1243 int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
1245 int ret;
1247 if( mpi_cmp_int( B, 0 ) < 0 )
1248 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1250 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1252 while( mpi_cmp_int( R, 0 ) < 0 )
1253 MPI_CHK( mpi_add_mpi( R, R, B ) );
1255 while( mpi_cmp_mpi( R, B ) >= 0 )
1256 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1258 cleanup:
1260 return( ret );
1264 * Modulo: r = A mod b
1266 int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
1268 size_t i;
1269 t_uint x, y, z;
1271 if( b == 0 )
1272 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
1274 if( b < 0 )
1275 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1278 * handle trivial cases
1280 if( b == 1 )
1282 *r = 0;
1283 return( 0 );
1286 if( b == 2 )
1288 *r = A->p[0] & 1;
1289 return( 0 );
1293 * general case
1295 for( i = A->n, y = 0; i > 0; i-- )
1297 x = A->p[i - 1];
1298 y = ( y << biH ) | ( x >> biH );
1299 z = y / b;
1300 y -= z * b;
1302 x <<= biH;
1303 y = ( y << biH ) | ( x >> biH );
1304 z = y / b;
1305 y -= z * b;
1309 * If A is negative, then the current y represents a negative value.
1310 * Flipping it to the positive side.
1312 if( A->s < 0 && y != 0 )
1313 y = b - y;
1315 *r = y;
1317 return( 0 );
1321 * Fast Montgomery initialization (thanks to Tom St Denis)
1323 static void mpi_montg_init( t_uint *mm, const mpi *N )
1325 t_uint x, m0 = N->p[0];
1327 x = m0;
1328 x += ( ( m0 + 2 ) & 4 ) << 1;
1329 x *= ( 2 - ( m0 * x ) );
1331 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1332 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1333 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1335 *mm = ~x + 1;
1339 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1341 static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
1343 size_t i, n, m;
1344 t_uint u0, u1, *d;
1346 memset( T->p, 0, T->n * ciL );
1348 d = T->p;
1349 n = N->n;
1350 m = ( B->n < n ) ? B->n : n;
1352 for( i = 0; i < n; i++ )
1355 * T = (T + u0*B + u1*N) / 2^biL
1357 u0 = A->p[i];
1358 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1360 mpi_mul_hlp( m, B->p, d, u0 );
1361 mpi_mul_hlp( n, N->p, d, u1 );
1363 *d++ = u0; d[n + 1] = 0;
1366 memcpy( A->p, d, (n + 1) * ciL );
1368 if( mpi_cmp_abs( A, N ) >= 0 )
1369 mpi_sub_hlp( n, N->p, A->p );
1370 else
1371 /* prevent timing attacks */
1372 mpi_sub_hlp( n, A->p, T->p );
1376 * Montgomery reduction: A = A * R^-1 mod N
1378 static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
1380 t_uint z = 1;
1381 mpi U;
1383 U.n = U.s = (int) z;
1384 U.p = &z;
1386 mpi_montmul( A, &U, N, mm, T );
1390 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1392 int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
1394 int ret;
1395 size_t wbits, wsize, one = 1;
1396 size_t i, j, nblimbs;
1397 size_t bufsize, nbits;
1398 t_uint ei, mm, state;
1399 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1400 int neg;
1402 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
1403 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1405 if( mpi_cmp_int( E, 0 ) < 0 )
1406 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1409 * Init temps and window size
1411 mpi_montg_init( &mm, N );
1412 mpi_init( &RR ); mpi_init( &T );
1413 memset( W, 0, sizeof( W ) );
1415 i = mpi_msb( E );
1417 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1418 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1420 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1421 wsize = POLARSSL_MPI_WINDOW_SIZE;
1423 j = N->n + 1;
1424 MPI_CHK( mpi_grow( X, j ) );
1425 MPI_CHK( mpi_grow( &W[1], j ) );
1426 MPI_CHK( mpi_grow( &T, j * 2 ) );
1429 * Compensate for negative A (and correct at the end)
1431 neg = ( A->s == -1 );
1433 mpi_init( &Apos );
1434 if( neg )
1436 MPI_CHK( mpi_copy( &Apos, A ) );
1437 Apos.s = 1;
1438 A = &Apos;
1442 * If 1st call, pre-compute R^2 mod N
1444 if( _RR == NULL || _RR->p == NULL )
1446 MPI_CHK( mpi_lset( &RR, 1 ) );
1447 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1448 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1450 if( _RR != NULL )
1451 memcpy( _RR, &RR, sizeof( mpi ) );
1453 else
1454 memcpy( &RR, _RR, sizeof( mpi ) );
1457 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1459 if( mpi_cmp_mpi( A, N ) >= 0 )
1460 mpi_mod_mpi( &W[1], A, N );
1461 else mpi_copy( &W[1], A );
1463 mpi_montmul( &W[1], &RR, N, mm, &T );
1466 * X = R^2 * R^-1 mod N = R mod N
1468 MPI_CHK( mpi_copy( X, &RR ) );
1469 mpi_montred( X, N, mm, &T );
1471 if( wsize > 1 )
1474 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1476 j = one << (wsize - 1);
1478 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1479 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1481 for( i = 0; i < wsize - 1; i++ )
1482 mpi_montmul( &W[j], &W[j], N, mm, &T );
1485 * W[i] = W[i - 1] * W[1]
1487 for( i = j + 1; i < (one << wsize); i++ )
1489 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1490 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1492 mpi_montmul( &W[i], &W[1], N, mm, &T );
1496 nblimbs = E->n;
1497 bufsize = 0;
1498 nbits = 0;
1499 wbits = 0;
1500 state = 0;
1502 while( 1 )
1504 if( bufsize == 0 )
1506 if( nblimbs-- == 0 )
1507 break;
1509 bufsize = sizeof( t_uint ) << 3;
1512 bufsize--;
1514 ei = (E->p[nblimbs] >> bufsize) & 1;
1517 * skip leading 0s
1519 if( ei == 0 && state == 0 )
1520 continue;
1522 if( ei == 0 && state == 1 )
1525 * out of window, square X
1527 mpi_montmul( X, X, N, mm, &T );
1528 continue;
1532 * add ei to current window
1534 state = 2;
1536 nbits++;
1537 wbits |= (ei << (wsize - nbits));
1539 if( nbits == wsize )
1542 * X = X^wsize R^-1 mod N
1544 for( i = 0; i < wsize; i++ )
1545 mpi_montmul( X, X, N, mm, &T );
1548 * X = X * W[wbits] R^-1 mod N
1550 mpi_montmul( X, &W[wbits], N, mm, &T );
1552 state--;
1553 nbits = 0;
1554 wbits = 0;
1559 * process the remaining bits
1561 for( i = 0; i < nbits; i++ )
1563 mpi_montmul( X, X, N, mm, &T );
1565 wbits <<= 1;
1567 if( (wbits & (one << wsize)) != 0 )
1568 mpi_montmul( X, &W[1], N, mm, &T );
1572 * X = A^E * R * R^-1 mod N = A^E mod N
1574 mpi_montred( X, N, mm, &T );
1576 if( neg )
1578 X->s = -1;
1579 mpi_add_mpi( X, N, X );
1582 cleanup:
1584 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
1585 mpi_free( &W[i] );
1587 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
1589 if( _RR == NULL )
1590 mpi_free( &RR );
1592 return( ret );
1596 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1598 int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
1600 int ret;
1601 size_t lz, lzt;
1602 mpi TG, TA, TB;
1604 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
1606 MPI_CHK( mpi_copy( &TA, A ) );
1607 MPI_CHK( mpi_copy( &TB, B ) );
1609 lz = mpi_lsb( &TA );
1610 lzt = mpi_lsb( &TB );
1612 if ( lzt < lz )
1613 lz = lzt;
1615 MPI_CHK( mpi_shift_r( &TA, lz ) );
1616 MPI_CHK( mpi_shift_r( &TB, lz ) );
1618 TA.s = TB.s = 1;
1620 while( mpi_cmp_int( &TA, 0 ) != 0 )
1622 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1623 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
1625 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1627 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1628 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1630 else
1632 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1633 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1637 MPI_CHK( mpi_shift_l( &TB, lz ) );
1638 MPI_CHK( mpi_copy( G, &TB ) );
1640 cleanup:
1642 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
1644 return( ret );
1647 int mpi_fill_random( mpi *X, size_t size,
1648 int (*f_rng)(void *, unsigned char *, size_t),
1649 void *p_rng )
1651 int ret;
1653 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
1654 MPI_CHK( mpi_lset( X, 0 ) );
1656 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
1658 cleanup:
1659 return( ret );
1663 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1665 int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
1667 int ret;
1668 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1670 if( mpi_cmp_int( N, 0 ) <= 0 )
1671 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1673 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1674 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1675 mpi_init( &V1 ); mpi_init( &V2 );
1677 MPI_CHK( mpi_gcd( &G, A, N ) );
1679 if( mpi_cmp_int( &G, 1 ) != 0 )
1681 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
1682 goto cleanup;
1685 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1686 MPI_CHK( mpi_copy( &TU, &TA ) );
1687 MPI_CHK( mpi_copy( &TB, N ) );
1688 MPI_CHK( mpi_copy( &TV, N ) );
1690 MPI_CHK( mpi_lset( &U1, 1 ) );
1691 MPI_CHK( mpi_lset( &U2, 0 ) );
1692 MPI_CHK( mpi_lset( &V1, 0 ) );
1693 MPI_CHK( mpi_lset( &V2, 1 ) );
1697 while( ( TU.p[0] & 1 ) == 0 )
1699 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1701 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1703 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1704 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1707 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1708 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1711 while( ( TV.p[0] & 1 ) == 0 )
1713 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1715 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1717 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1718 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1721 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1722 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1725 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1727 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1728 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1729 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1731 else
1733 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1734 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1735 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1738 while( mpi_cmp_int( &TU, 0 ) != 0 );
1740 while( mpi_cmp_int( &V1, 0 ) < 0 )
1741 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1743 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1744 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1746 MPI_CHK( mpi_copy( X, &V1 ) );
1748 cleanup:
1750 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1751 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1752 mpi_free( &V1 ); mpi_free( &V2 );
1754 return( ret );
1757 #if defined(POLARSSL_GENPRIME)
1759 static const int small_prime[] =
1761 3, 5, 7, 11, 13, 17, 19, 23,
1762 29, 31, 37, 41, 43, 47, 53, 59,
1763 61, 67, 71, 73, 79, 83, 89, 97,
1764 101, 103, 107, 109, 113, 127, 131, 137,
1765 139, 149, 151, 157, 163, 167, 173, 179,
1766 181, 191, 193, 197, 199, 211, 223, 227,
1767 229, 233, 239, 241, 251, 257, 263, 269,
1768 271, 277, 281, 283, 293, 307, 311, 313,
1769 317, 331, 337, 347, 349, 353, 359, 367,
1770 373, 379, 383, 389, 397, 401, 409, 419,
1771 421, 431, 433, 439, 443, 449, 457, 461,
1772 463, 467, 479, 487, 491, 499, 503, 509,
1773 521, 523, 541, 547, 557, 563, 569, 571,
1774 577, 587, 593, 599, 601, 607, 613, 617,
1775 619, 631, 641, 643, 647, 653, 659, 661,
1776 673, 677, 683, 691, 701, 709, 719, 727,
1777 733, 739, 743, 751, 757, 761, 769, 773,
1778 787, 797, 809, 811, 821, 823, 827, 829,
1779 839, 853, 857, 859, 863, 877, 881, 883,
1780 887, 907, 911, 919, 929, 937, 941, 947,
1781 953, 967, 971, 977, 983, 991, 997, -103
1785 * Miller-Rabin primality test (HAC 4.24)
1787 int mpi_is_prime( mpi *X,
1788 int (*f_rng)(void *, unsigned char *, size_t),
1789 void *p_rng )
1791 int ret, xs;
1792 size_t i, j, n, s;
1793 mpi W, R, T, A, RR;
1795 if( mpi_cmp_int( X, 0 ) == 0 ||
1796 mpi_cmp_int( X, 1 ) == 0 )
1797 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1799 if( mpi_cmp_int( X, 2 ) == 0 )
1800 return( 0 );
1802 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1803 mpi_init( &RR );
1805 xs = X->s; X->s = 1;
1808 * test trivial factors first
1810 if( ( X->p[0] & 1 ) == 0 )
1811 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1813 for( i = 0; small_prime[i] > 0; i++ )
1815 t_uint r;
1817 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1818 return( 0 );
1820 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1822 if( r == 0 )
1823 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1827 * W = |X| - 1
1828 * R = W >> lsb( W )
1830 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
1831 s = mpi_lsb( &W );
1832 MPI_CHK( mpi_copy( &R, &W ) );
1833 MPI_CHK( mpi_shift_r( &R, s ) );
1835 i = mpi_msb( X );
1837 * HAC, table 4.4
1839 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1840 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1841 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1843 for( i = 0; i < n; i++ )
1846 * pick a random A, 1 < A < |X| - 1
1848 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
1850 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1852 j = mpi_msb( &A ) - mpi_msb( &W );
1853 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1855 A.p[0] |= 3;
1858 * A = A^R mod |X|
1860 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1862 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1863 mpi_cmp_int( &A, 1 ) == 0 )
1864 continue;
1866 j = 1;
1867 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1870 * A = A * A mod |X|
1872 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1873 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1875 if( mpi_cmp_int( &A, 1 ) == 0 )
1876 break;
1878 j++;
1882 * not prime if A != |X| - 1 or A == 1
1884 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1885 mpi_cmp_int( &A, 1 ) == 0 )
1887 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
1888 break;
1892 cleanup:
1894 X->s = xs;
1896 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
1897 mpi_free( &RR );
1899 return( ret );
1903 * Prime number generation
1905 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
1906 int (*f_rng)(void *, unsigned char *, size_t),
1907 void *p_rng )
1909 int ret;
1910 size_t k, n;
1911 mpi Y;
1913 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
1914 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1916 mpi_init( &Y );
1918 n = BITS_TO_LIMBS( nbits );
1920 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
1922 k = mpi_msb( X );
1923 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1924 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1926 X->p[0] |= 3;
1928 if( dh_flag == 0 )
1930 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1932 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
1933 goto cleanup;
1935 MPI_CHK( mpi_add_int( X, X, 2 ) );
1938 else
1940 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1941 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1943 while( 1 )
1945 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1947 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1948 break;
1950 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
1951 goto cleanup;
1954 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
1955 goto cleanup;
1957 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1958 MPI_CHK( mpi_add_int( X, X, 2 ) );
1959 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1963 cleanup:
1965 mpi_free( &Y );
1967 return( ret );
1970 #endif
1972 #if defined(POLARSSL_SELF_TEST)
1974 #define GCD_PAIR_COUNT 3
1976 static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1978 { 693, 609, 21 },
1979 { 1764, 868, 28 },
1980 { 768454923, 542167814, 1 }
1984 * Checkup routine
1986 int mpi_self_test( int verbose )
1988 int ret, i;
1989 mpi A, E, N, X, Y, U, V;
1991 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
1992 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
1994 MPI_CHK( mpi_read_string( &A, 16,
1995 "EFE021C2645FD1DC586E69184AF4A31E" \
1996 "D5F53E93B5F123FA41680867BA110131" \
1997 "944FE7952E2517337780CB0DB80E61AA" \
1998 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2000 MPI_CHK( mpi_read_string( &E, 16,
2001 "B2E7EFD37075B9F03FF989C7C5051C20" \
2002 "34D2A323810251127E7BF8625A4F49A5" \
2003 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2004 "5B5C25763222FEFCCFC38B832366C29E" ) );
2006 MPI_CHK( mpi_read_string( &N, 16,
2007 "0066A198186C18C10B2F5ED9B522752A" \
2008 "9830B69916E535C8F047518A889A43A5" \
2009 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2011 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2013 MPI_CHK( mpi_read_string( &U, 16,
2014 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2015 "9E857EA95A03512E2BAE7391688D264A" \
2016 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2017 "8001B72E848A38CAE1C65F78E56ABDEF" \
2018 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2019 "ECF677152EF804370C1A305CAF3B5BF1" \
2020 "30879B56C61DE584A0F53A2447A51E" ) );
2022 if( verbose != 0 )
2023 printf( " MPI test #1 (mul_mpi): " );
2025 if( mpi_cmp_mpi( &X, &U ) != 0 )
2027 if( verbose != 0 )
2028 printf( "failed\n" );
2030 return( 1 );
2033 if( verbose != 0 )
2034 printf( "passed\n" );
2036 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2038 MPI_CHK( mpi_read_string( &U, 16,
2039 "256567336059E52CAE22925474705F39A94" ) );
2041 MPI_CHK( mpi_read_string( &V, 16,
2042 "6613F26162223DF488E9CD48CC132C7A" \
2043 "0AC93C701B001B092E4E5B9F73BCD27B" \
2044 "9EE50D0657C77F374E903CDFA4C642" ) );
2046 if( verbose != 0 )
2047 printf( " MPI test #2 (div_mpi): " );
2049 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2050 mpi_cmp_mpi( &Y, &V ) != 0 )
2052 if( verbose != 0 )
2053 printf( "failed\n" );
2055 return( 1 );
2058 if( verbose != 0 )
2059 printf( "passed\n" );
2061 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2063 MPI_CHK( mpi_read_string( &U, 16,
2064 "36E139AEA55215609D2816998ED020BB" \
2065 "BD96C37890F65171D948E9BC7CBAA4D9" \
2066 "325D24D6A3C12710F10A09FA08AB87" ) );
2068 if( verbose != 0 )
2069 printf( " MPI test #3 (exp_mod): " );
2071 if( mpi_cmp_mpi( &X, &U ) != 0 )
2073 if( verbose != 0 )
2074 printf( "failed\n" );
2076 return( 1 );
2079 if( verbose != 0 )
2080 printf( "passed\n" );
2082 #if defined(POLARSSL_GENPRIME)
2083 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2085 MPI_CHK( mpi_read_string( &U, 16,
2086 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2087 "C3DBA76456363A10869622EAC2DD84EC" \
2088 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2090 if( verbose != 0 )
2091 printf( " MPI test #4 (inv_mod): " );
2093 if( mpi_cmp_mpi( &X, &U ) != 0 )
2095 if( verbose != 0 )
2096 printf( "failed\n" );
2098 return( 1 );
2101 if( verbose != 0 )
2102 printf( "passed\n" );
2103 #endif
2105 if( verbose != 0 )
2106 printf( " MPI test #5 (simple gcd): " );
2108 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2110 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
2111 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
2113 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
2115 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2117 if( verbose != 0 )
2118 printf( "failed at %d\n", i );
2120 return( 1 );
2124 if( verbose != 0 )
2125 printf( "passed\n" );
2127 cleanup:
2129 if( ret != 0 && verbose != 0 )
2130 printf( "Unexpected error, return code = %08X\n", ret );
2132 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2133 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
2135 if( verbose != 0 )
2136 printf( "\n" );
2138 return( ret );
2141 #endif
2143 #endif