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>
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 "polarssl_config.h"
35 #if defined(POLARSSL_BIGNUM_C)
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)
55 void mpi_init( mpi
*X
)
68 void mpi_free( mpi
*X
)
75 memset( X
->p
, 0, X
->n
* ciL
);
85 * Enlarge to the specified number of limbs
87 int mpi_grow( mpi
*X
, size_t nblimbs
)
91 if( nblimbs
> POLARSSL_MPI_MAX_LIMBS
)
92 return( POLARSSL_ERR_MPI_MALLOC_FAILED
);
96 if( ( p
= (t_uint
*) malloc( nblimbs
* ciL
) ) == NULL
)
97 return( POLARSSL_ERR_MPI_MALLOC_FAILED
);
99 memset( p
, 0, nblimbs
* ciL
);
103 memcpy( p
, X
->p
, X
->n
* ciL
);
104 memset( X
->p
, 0, X
->n
* ciL
);
116 * Copy the contents of Y into X
118 int mpi_copy( mpi
*X
, const mpi
*Y
)
126 for( i
= Y
->n
- 1; i
> 0; i
-- )
133 MPI_CHK( mpi_grow( X
, i
) );
135 memset( X
->p
, 0, X
->n
* ciL
);
136 memcpy( X
->p
, Y
->p
, i
* ciL
);
144 * Swap the contents of X and Y
146 void mpi_swap( mpi
*X
, mpi
*Y
)
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
)
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;
176 int mpi_get_bit( const mpi
*X
, size_t pos
)
178 if( X
->n
* biL
<= pos
)
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
)
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
)
201 MPI_CHK( mpi_grow( X
, off
+ 1 ) );
204 X
->p
[off
] = ( X
->p
[off
] & ~( 0x01 << idx
) ) | ( val
<< idx
);
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 )
227 * Return the number of most significant bits
229 size_t mpi_msb( const mpi
*X
)
233 for( i
= X
->n
- 1; i
> 0; i
-- )
237 for( j
= biL
; j
> 0; j
-- )
238 if( ( ( X
->p
[i
] >> ( j
- 1 ) ) & 1 ) != 0 )
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
)
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
);
270 * Import from an ASCII string
272 int mpi_read_string( mpi
*X
, int radix
, const char *s
)
275 size_t i
, j
, slen
, n
;
279 if( radix
< 2 || radix
> 16 )
280 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA
);
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] == '-' )
301 MPI_CHK( mpi_get_digit( &d
, radix
, s
[i
- 1] ) );
302 X
->p
[j
/ (2 * ciL
)] |= d
<< ( (j
% (2 * ciL
)) << 2 );
307 MPI_CHK( mpi_lset( X
, 0 ) );
309 for( i
= 0; i
< slen
; i
++ )
311 if( i
== 0 && s
[i
] == '-' )
317 MPI_CHK( mpi_get_digit( &d
, radix
, s
[i
] ) );
318 MPI_CHK( mpi_mul_int( &T
, X
, radix
) );
322 MPI_CHK( mpi_add_int( X
, &T
, d
) );
326 MPI_CHK( mpi_sub_int( X
, &T
, d
) );
339 * Helper to write the digits high-order first
341 static int mpi_write_hlp( mpi
*X
, int radix
, char **p
)
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
) );
356 *(*p
)++ = (char)( r
+ 0x30 );
358 *(*p
)++ = (char)( r
+ 0x37 );
366 * Export into an ASCII string
368 int mpi_write_string( const mpi
*X
, int radix
, char *s
, size_t *slen
)
375 if( radix
< 2 || radix
> 16 )
376 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA
);
379 if( radix
>= 4 ) n
>>= 1;
380 if( radix
>= 16 ) n
>>= 1;
386 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL
);
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 )
409 *(p
++) = "0123456789ABCDEF" [c
/ 16];
410 *(p
++) = "0123456789ABCDEF" [c
% 16];
417 MPI_CHK( mpi_copy( &T
, X
) );
422 MPI_CHK( mpi_write_hlp( &T
, radix
, &p
) );
435 #if defined(POLARSSL_FS_IO)
437 * Read X from an opened file
439 int mpi_read_file( mpi
*X
, int radix
, FILE *fin
)
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
);
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'; }
463 if( mpi_get_digit( &d
, radix
, *p
) != 0 )
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
)
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
];
486 MPI_CHK( mpi_write_string( X
, radix
, s
, (size_t *) &n
) );
488 if( p
== NULL
) p
= "";
497 if( fwrite( p
, 1, plen
, fout
) != plen
||
498 fwrite( s
, 1, slen
, fout
) != slen
)
499 return( POLARSSL_ERR_MPI_FILE_IO_ERROR
);
502 printf( "%s%s", p
, s
);
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
)
518 for( n
= 0; n
< buflen
; n
++ )
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);
534 * Export X into unsigned binary data, big endian
536 int mpi_write_binary( const mpi
*X
, unsigned char *buf
, size_t buflen
)
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) );
554 * Left-shift: X <<= count
556 int mpi_shift_l( mpi
*X
, size_t count
)
563 t1
= count
& (biL
- 1);
565 i
= mpi_msb( X
) + count
;
568 MPI_CHK( mpi_grow( X
, BITS_TO_LIMBS( i
) ) );
573 * shift by count / limb_size
577 for( i
= X
->n
; i
> v0
; i
-- )
578 X
->p
[i
- 1] = X
->p
[i
- v0
- 1];
585 * shift by count % limb_size
589 for( i
= v0
; i
< X
->n
; i
++ )
591 r1
= X
->p
[i
] >> (biL
- t1
);
604 * Right-shift: X >>= count
606 int mpi_shift_r( mpi
*X
, size_t count
)
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
622 for( i
= 0; i
< X
->n
- v0
; i
++ )
623 X
->p
[i
] = X
->p
[i
+ v0
];
625 for( ; i
< X
->n
; i
++ )
630 * shift by count % limb_size
634 for( i
= X
->n
; i
> 0; i
-- )
636 r1
= X
->p
[i
- 1] << (biL
- v1
);
647 * Compare unsigned values
649 int mpi_cmp_abs( const mpi
*X
, const mpi
*Y
)
653 for( i
= X
->n
; i
> 0; i
-- )
654 if( X
->p
[i
- 1] != 0 )
657 for( j
= Y
->n
; j
> 0; j
-- )
658 if( Y
->p
[j
- 1] != 0 )
661 if( i
== 0 && j
== 0 )
664 if( i
> j
) return( 1 );
665 if( j
> i
) return( -1 );
669 if( X
->p
[i
- 1] > Y
->p
[i
- 1] ) return( 1 );
670 if( X
->p
[i
- 1] < Y
->p
[i
- 1] ) return( -1 );
677 * Compare signed values
679 int mpi_cmp_mpi( const mpi
*X
, const mpi
*Y
)
683 for( i
= X
->n
; i
> 0; i
-- )
684 if( X
->p
[i
- 1] != 0 )
687 for( j
= Y
->n
; j
> 0; j
-- )
688 if( Y
->p
[j
- 1] != 0 )
691 if( i
== 0 && j
== 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 );
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
);
710 * Compare signed values
712 int mpi_cmp_int( const mpi
*X
, t_sint z
)
717 *p
= ( z
< 0 ) ? -z
: z
;
718 Y
.s
= ( z
< 0 ) ? -1 : 1;
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
)
736 const mpi
*T
= A
; A
= X
; B
= T
;
740 MPI_CHK( mpi_copy( X
, A
) );
743 * X should always be positive as a result of unsigned additions.
747 for( j
= B
->n
; j
> 0; j
-- )
748 if( B
->p
[j
- 1] != 0 )
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
);
765 MPI_CHK( mpi_grow( X
, i
+ 1 ) );
769 *p
+= c
; c
= ( *p
< c
); i
++; p
++;
778 * Helper for mpi substraction
780 static void mpi_sub_hlp( size_t n
, t_uint
*s
, t_uint
*d
)
785 for( i
= c
= 0; i
< n
; i
++, s
++, d
++ )
787 z
= ( *d
< c
); *d
-= c
;
788 c
= ( *d
< *s
) + z
; *d
-= *s
;
793 z
= ( *d
< c
); *d
-= c
;
799 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
801 int mpi_sub_abs( mpi
*X
, const mpi
*A
, const mpi
*B
)
807 if( mpi_cmp_abs( A
, B
) < 0 )
808 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE
);
814 MPI_CHK( mpi_copy( &TB
, B
) );
819 MPI_CHK( mpi_copy( X
, A
) );
822 * X should always be positive as a result of unsigned substractions.
828 for( n
= B
->n
; n
> 0; n
-- )
829 if( B
->p
[n
- 1] != 0 )
832 mpi_sub_hlp( n
, B
->p
, X
->p
);
842 * Signed addition: X = A + B
844 int mpi_add_mpi( mpi
*X
, const mpi
*A
, const mpi
*B
)
848 if( A
->s
* B
->s
< 0 )
850 if( mpi_cmp_abs( A
, B
) >= 0 )
852 MPI_CHK( mpi_sub_abs( X
, A
, B
) );
857 MPI_CHK( mpi_sub_abs( X
, B
, A
) );
863 MPI_CHK( mpi_add_abs( X
, A
, B
) );
873 * Signed substraction: X = A - B
875 int mpi_sub_mpi( mpi
*X
, const mpi
*A
, const mpi
*B
)
879 if( A
->s
* B
->s
> 0 )
881 if( mpi_cmp_abs( A
, B
) >= 0 )
883 MPI_CHK( mpi_sub_abs( X
, A
, B
) );
888 MPI_CHK( mpi_sub_abs( X
, B
, A
) );
894 MPI_CHK( mpi_add_abs( X
, A
, B
) );
904 * Signed addition: X = A + b
906 int mpi_add_int( mpi
*X
, const mpi
*A
, t_sint b
)
911 p
[0] = ( b
< 0 ) ? -b
: b
;
912 _B
.s
= ( b
< 0 ) ? -1 : 1;
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
)
927 p
[0] = ( b
< 0 ) ? -b
: b
;
928 _B
.s
= ( b
< 0 ) ? -1 : 1;
932 return( mpi_sub_mpi( X
, A
, &_B
) );
936 * Helper for mpi multiplication
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
))
946 void mpi_mul_hlp( size_t i
, t_uint
*s
, t_uint
*d
, t_uint b
)
950 #if defined(MULADDC_HUIT)
951 for( ; i
>= 8; i
-= 8 )
965 for( ; i
>= 16; i
-= 16 )
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
980 for( ; i
>= 8; i
-= 8 )
983 MULADDC_CORE MULADDC_CORE
984 MULADDC_CORE MULADDC_CORE
986 MULADDC_CORE MULADDC_CORE
987 MULADDC_CORE MULADDC_CORE
1002 *d
+= c
; c
= ( *d
< c
); d
++;
1008 * Baseline multiplication: X = A * B (HAC 14.12)
1010 int mpi_mul_mpi( mpi
*X
, const mpi
*A
, const mpi
*B
)
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 )
1025 for( j
= B
->n
; j
> 0; j
-- )
1026 if( B
->p
[j
- 1] != 0 )
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] );
1039 mpi_free( &TB
); mpi_free( &TA
);
1045 * Baseline multiplication: X = A * b
1047 int mpi_mul_int( mpi
*X
, const mpi
*A
, t_sint 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
)
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
) );
1082 MPI_CHK( mpi_copy( &X
, A
) );
1083 MPI_CHK( mpi_copy( &Y
, B
) );
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
;
1095 MPI_CHK( mpi_shift_l( &X
, k
) );
1096 MPI_CHK( mpi_shift_l( &Y
, k
) );
1102 MPI_CHK( mpi_shift_l( &Y
, biL
* (n
- t
) ) );
1104 while( mpi_cmp_mpi( &X
, &Y
) >= 0 )
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;
1117 #if defined(POLARSSL_HAVE_UDBL)
1120 r
= (t_udbl
) X
.p
[i
] << biL
;
1121 r
|= (t_udbl
) X
.p
[i
- 1];
1123 if( r
> ((t_udbl
) 1 << biL
) - 1)
1124 r
= ((t_udbl
) 1 << biL
) - 1;
1126 Z
.p
[i
- t
- 1] = (t_uint
) r
;
1129 * __udiv_qrnnd_c, from gmp/longlong.h
1131 t_uint q0
, q1
, r0
, r1
;
1132 t_uint d0
, d1
, d
, m
;
1135 d0
= ( d
<< biH
) >> biH
;
1139 r1
= X
.p
[i
] - d1
* q1
;
1141 r1
|= ( X
.p
[i
- 1] >> biH
);
1147 while( r1
>= d
&& r1
< m
)
1155 r0
|= ( X
.p
[i
- 1] << biH
) >> biH
;
1161 while( r0
>= d
&& r0
< m
)
1166 Z
.p
[i
- t
- 1] = ( q1
<< biH
) | q0
;
1175 MPI_CHK( mpi_lset( &T1
, 0 ) );
1176 T1
.p
[0] = (t
< 1) ? 0 : Y
.p
[t
- 1];
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];
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
) );
1208 mpi_shift_r( &X
, k
);
1212 if( mpi_cmp_int( R
, 0 ) == 0 )
1218 mpi_free( &X
); mpi_free( &Y
); mpi_free( &Z
);
1219 mpi_free( &T1
); mpi_free( &T2
);
1225 * Division by int: A = Q * b + R
1227 int mpi_div_int( mpi
*Q
, mpi
*R
, const mpi
*A
, t_sint b
)
1232 p
[0] = ( b
< 0 ) ? -b
: b
;
1233 _B
.s
= ( b
< 0 ) ? -1 : 1;
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
)
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
) );
1264 * Modulo: r = A mod b
1266 int mpi_mod_int( t_uint
*r
, const mpi
*A
, t_sint b
)
1272 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO
);
1275 return POLARSSL_ERR_MPI_NEGATIVE_VALUE
;
1278 * handle trivial cases
1295 for( i
= A
->n
, y
= 0; i
> 0; i
-- )
1298 y
= ( y
<< biH
) | ( x
>> biH
);
1303 y
= ( y
<< biH
) | ( x
>> biH
);
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 )
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];
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
) );
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
)
1346 memset( T
->p
, 0, T
->n
* ciL
);
1350 m
= ( B
->n
< n
) ? B
->n
: n
;
1352 for( i
= 0; i
< n
; i
++ )
1355 * T = (T + u0*B + u1*N) / 2^biL
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
);
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
)
1383 U
.n
= U
.s
= (int) 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
)
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
;
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
) );
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
;
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 );
1436 MPI_CHK( mpi_copy( &Apos
, A
) );
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
) );
1451 memcpy( _RR
, &RR
, sizeof( mpi
) );
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
);
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
);
1506 if( nblimbs
-- == 0 )
1509 bufsize
= sizeof( t_uint
) << 3;
1514 ei
= (E
->p
[nblimbs
] >> bufsize
) & 1;
1519 if( ei
== 0 && state
== 0 )
1522 if( ei
== 0 && state
== 1 )
1525 * out of window, square X
1527 mpi_montmul( X
, X
, N
, mm
, &T
);
1532 * add ei to current window
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
);
1559 * process the remaining bits
1561 for( i
= 0; i
< nbits
; i
++ )
1563 mpi_montmul( X
, X
, N
, mm
, &T
);
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
);
1579 mpi_add_mpi( X
, N
, X
);
1584 for( i
= (one
<< (wsize
- 1)); i
< (one
<< wsize
); i
++ )
1587 mpi_free( &W
[1] ); mpi_free( &T
); mpi_free( &Apos
);
1596 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1598 int mpi_gcd( mpi
*G
, const mpi
*A
, const mpi
*B
)
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
);
1615 MPI_CHK( mpi_shift_r( &TA
, lz
) );
1616 MPI_CHK( mpi_shift_r( &TB
, lz
) );
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 ) );
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
) );
1642 mpi_free( &TG
); mpi_free( &TA
); mpi_free( &TB
);
1647 int mpi_fill_random( mpi
*X
, size_t size
,
1648 int (*f_rng
)(void *, unsigned char *, size_t),
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
) );
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
)
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
;
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
) );
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
) );
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
);
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),
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 )
1802 mpi_init( &W
); mpi_init( &R
); mpi_init( &T
); mpi_init( &A
);
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
++ )
1817 if( mpi_cmp_int( X
, small_prime
[i
] ) <= 0 )
1820 MPI_CHK( mpi_mod_int( &r
, X
, small_prime
[i
] ) );
1823 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE
);
1830 MPI_CHK( mpi_sub_int( &W
, X
, 1 ) );
1832 MPI_CHK( mpi_copy( &R
, &W
) );
1833 MPI_CHK( mpi_shift_r( &R
, s
) );
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 ) );
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 )
1867 while( j
< s
&& mpi_cmp_mpi( &A
, &W
) != 0 )
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 )
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
;
1896 mpi_free( &W
); mpi_free( &R
); mpi_free( &T
); mpi_free( &A
);
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),
1913 if( nbits
< 3 || nbits
> POLARSSL_MPI_MAX_BITS
)
1914 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA
);
1918 n
= BITS_TO_LIMBS( nbits
);
1920 MPI_CHK( mpi_fill_random( X
, n
* ciL
, f_rng
, p_rng
) );
1923 if( k
< nbits
) MPI_CHK( mpi_shift_l( X
, nbits
- k
) );
1924 if( k
> nbits
) MPI_CHK( mpi_shift_r( X
, k
- nbits
) );
1930 while( ( ret
= mpi_is_prime( X
, f_rng
, p_rng
) ) != 0 )
1932 if( ret
!= POLARSSL_ERR_MPI_NOT_ACCEPTABLE
)
1935 MPI_CHK( mpi_add_int( X
, X
, 2 ) );
1940 MPI_CHK( mpi_sub_int( &Y
, X
, 1 ) );
1941 MPI_CHK( mpi_shift_r( &Y
, 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 )
1950 if( ret
!= POLARSSL_ERR_MPI_NOT_ACCEPTABLE
)
1954 if( ret
!= POLARSSL_ERR_MPI_NOT_ACCEPTABLE
)
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 ) );
1972 #if defined(POLARSSL_SELF_TEST)
1974 #define GCD_PAIR_COUNT 3
1976 static const int gcd_pairs
[GCD_PAIR_COUNT
][3] =
1980 { 768454923, 542167814, 1 }
1986 int mpi_self_test( int verbose
)
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" ) );
2023 printf( " MPI test #1 (mul_mpi): " );
2025 if( mpi_cmp_mpi( &X
, &U
) != 0 )
2028 printf( "failed\n" );
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" ) );
2047 printf( " MPI test #2 (div_mpi): " );
2049 if( mpi_cmp_mpi( &X
, &U
) != 0 ||
2050 mpi_cmp_mpi( &Y
, &V
) != 0 )
2053 printf( "failed\n" );
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" ) );
2069 printf( " MPI test #3 (exp_mod): " );
2071 if( mpi_cmp_mpi( &X
, &U
) != 0 )
2074 printf( "failed\n" );
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" ) );
2091 printf( " MPI test #4 (inv_mod): " );
2093 if( mpi_cmp_mpi( &X
, &U
) != 0 )
2096 printf( "failed\n" );
2102 printf( "passed\n" );
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 )
2118 printf( "failed at %d\n", i
);
2125 printf( "passed\n" );
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
);