blob: 9f11a70b9ad9674f0ab1ab9b306575fc8cfaa97b [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00004 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
Paul Bakker785a9ee2009-01-25 14:15:10 +00006 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
Paul Bakker5121ce52009-01-03 21:22:43 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * This MPI implementation is based on:
24 *
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
26 * http://www.stillhq.com/extracted/gnupg-api/mpi/
27 * http://math.libtomcrypt.com/files/tommath.pdf
28 */
29
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakker40e46942009-01-03 21:51:57 +000032#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/bignum.h"
35#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
37#include <string.h>
38#include <stdlib.h>
39#include <stdarg.h>
40
41#define ciL ((int) sizeof(t_int)) /* chars in limb */
42#define biL (ciL << 3) /* bits in limb */
43#define biH (ciL << 2) /* half limb size */
44
45/*
46 * Convert between bits/chars and number of limbs
47 */
48#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
49#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
50
51/*
52 * Initialize one or more mpi
53 */
54void mpi_init( mpi *X, ... )
55{
56 va_list args;
57
58 va_start( args, X );
59
60 while( X != NULL )
61 {
62 X->s = 1;
63 X->n = 0;
64 X->p = NULL;
65
66 X = va_arg( args, mpi* );
67 }
68
69 va_end( args );
70}
71
72/*
73 * Unallocate one or more mpi
74 */
75void mpi_free( mpi *X, ... )
76{
77 va_list args;
78
79 va_start( args, X );
80
81 while( X != NULL )
82 {
83 if( X->p != NULL )
84 {
85 memset( X->p, 0, X->n * ciL );
86 free( X->p );
87 }
88
89 X->s = 1;
90 X->n = 0;
91 X->p = NULL;
92
93 X = va_arg( args, mpi* );
94 }
95
96 va_end( args );
97}
98
99/*
100 * Enlarge to the specified number of limbs
101 */
102int mpi_grow( mpi *X, int nblimbs )
103{
104 t_int *p;
105
106 if( X->n < nblimbs )
107 {
108 if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL )
109 return( 1 );
110
111 memset( p, 0, nblimbs * ciL );
112
113 if( X->p != NULL )
114 {
115 memcpy( p, X->p, X->n * ciL );
116 memset( X->p, 0, X->n * ciL );
117 free( X->p );
118 }
119
120 X->n = nblimbs;
121 X->p = p;
122 }
123
124 return( 0 );
125}
126
127/*
128 * Copy the contents of Y into X
129 */
130int mpi_copy( mpi *X, mpi *Y )
131{
132 int ret, i;
133
134 if( X == Y )
135 return( 0 );
136
137 for( i = Y->n - 1; i > 0; i-- )
138 if( Y->p[i] != 0 )
139 break;
140 i++;
141
142 X->s = Y->s;
143
144 MPI_CHK( mpi_grow( X, i ) );
145
146 memset( X->p, 0, X->n * ciL );
147 memcpy( X->p, Y->p, i * ciL );
148
149cleanup:
150
151 return( ret );
152}
153
154/*
155 * Swap the contents of X and Y
156 */
157void mpi_swap( mpi *X, mpi *Y )
158{
159 mpi T;
160
161 memcpy( &T, X, sizeof( mpi ) );
162 memcpy( X, Y, sizeof( mpi ) );
163 memcpy( Y, &T, sizeof( mpi ) );
164}
165
166/*
167 * Set value from integer
168 */
169int mpi_lset( mpi *X, int z )
170{
171 int ret;
172
173 MPI_CHK( mpi_grow( X, 1 ) );
174 memset( X->p, 0, X->n * ciL );
175
176 X->p[0] = ( z < 0 ) ? -z : z;
177 X->s = ( z < 0 ) ? -1 : 1;
178
179cleanup:
180
181 return( ret );
182}
183
184/*
185 * Return the number of least significant bits
186 */
187int mpi_lsb( mpi *X )
188{
189 int i, j, count = 0;
190
191 for( i = 0; i < X->n; i++ )
192 for( j = 0; j < (int) biL; j++, count++ )
193 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
194 return( count );
195
196 return( 0 );
197}
198
199/*
200 * Return the number of most significant bits
201 */
202int mpi_msb( mpi *X )
203{
204 int i, j;
205
206 for( i = X->n - 1; i > 0; i-- )
207 if( X->p[i] != 0 )
208 break;
209
210 for( j = biL - 1; j >= 0; j-- )
211 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
212 break;
213
214 return( ( i * biL ) + j + 1 );
215}
216
217/*
218 * Return the total size in bytes
219 */
220int mpi_size( mpi *X )
221{
222 return( ( mpi_msb( X ) + 7 ) >> 3 );
223}
224
225/*
226 * Convert an ASCII character to digit value
227 */
228static int mpi_get_digit( t_int *d, int radix, char c )
229{
230 *d = 255;
231
232 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
233 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
234 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
235
236 if( *d >= (t_int) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000237 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 return( 0 );
240}
241
242/*
243 * Import from an ASCII string
244 */
245int mpi_read_string( mpi *X, int radix, char *s )
246{
247 int ret, i, j, n;
248 t_int d;
249 mpi T;
250
251 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000252 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254 mpi_init( &T, NULL );
255
256 if( radix == 16 )
257 {
258 n = BITS_TO_LIMBS( strlen( s ) << 2 );
259
260 MPI_CHK( mpi_grow( X, n ) );
261 MPI_CHK( mpi_lset( X, 0 ) );
262
263 for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ )
264 {
265 if( i == 0 && s[i] == '-' )
266 {
267 X->s = -1;
268 break;
269 }
270
271 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
272 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
273 }
274 }
275 else
276 {
277 MPI_CHK( mpi_lset( X, 0 ) );
278
279 for( i = 0; i < (int) strlen( s ); i++ )
280 {
281 if( i == 0 && s[i] == '-' )
282 {
283 X->s = -1;
284 continue;
285 }
286
287 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
288 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000289
290 if( X->s == 1 )
291 {
292 MPI_CHK( mpi_add_int( X, &T, d ) );
293 }
294 else
295 {
296 MPI_CHK( mpi_sub_int( X, &T, d ) );
297 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 }
299 }
300
301cleanup:
302
303 mpi_free( &T, NULL );
304
305 return( ret );
306}
307
308/*
309 * Helper to write the digits high-order first
310 */
311static int mpi_write_hlp( mpi *X, int radix, char **p )
312{
313 int ret;
314 t_int r;
315
316 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000317 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319 MPI_CHK( mpi_mod_int( &r, X, radix ) );
320 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
321
322 if( mpi_cmp_int( X, 0 ) != 0 )
323 MPI_CHK( mpi_write_hlp( X, radix, p ) );
324
325 if( r < 10 )
326 *(*p)++ = (char)( r + 0x30 );
327 else
328 *(*p)++ = (char)( r + 0x37 );
329
330cleanup:
331
332 return( ret );
333}
334
335/*
336 * Export into an ASCII string
337 */
338int mpi_write_string( mpi *X, int radix, char *s, int *slen )
339{
340 int ret = 0, n;
341 char *p;
342 mpi T;
343
344 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000345 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 n = mpi_msb( X );
348 if( radix >= 4 ) n >>= 1;
349 if( radix >= 16 ) n >>= 1;
350 n += 3;
351
352 if( *slen < n )
353 {
354 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000355 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 }
357
358 p = s;
359 mpi_init( &T, NULL );
360
361 if( X->s == -1 )
362 *p++ = '-';
363
364 if( radix == 16 )
365 {
366 int c, i, j, k;
367
368 for( i = X->n - 1, k = 0; i >= 0; i-- )
369 {
370 for( j = ciL - 1; j >= 0; j-- )
371 {
372 c = ( X->p[i] >> (j << 3) ) & 0xFF;
373
374 if( c == 0 && k == 0 && (i + j) != 0 )
375 continue;
376
377 p += sprintf( p, "%02X", c );
378 k = 1;
379 }
380 }
381 }
382 else
383 {
384 MPI_CHK( mpi_copy( &T, X ) );
385 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
386 }
387
388 *p++ = '\0';
389 *slen = p - s;
390
391cleanup:
392
393 mpi_free( &T, NULL );
394
395 return( ret );
396}
397
398/*
399 * Read X from an opened file
400 */
401int mpi_read_file( mpi *X, int radix, FILE *fin )
402{
403 t_int d;
404 int slen;
405 char *p;
406 char s[1024];
407
408 memset( s, 0, sizeof( s ) );
409 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000410 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 slen = strlen( s );
413 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
414 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
415
416 p = s + slen;
417 while( --p >= s )
418 if( mpi_get_digit( &d, radix, *p ) != 0 )
419 break;
420
421 return( mpi_read_string( X, radix, p + 1 ) );
422}
423
424/*
425 * Write X into an opened file (or stdout if fout == NULL)
426 */
427int mpi_write_file( char *p, mpi *X, int radix, FILE *fout )
428{
429 int n, ret;
430 size_t slen;
431 size_t plen;
432 char s[1024];
433
434 n = sizeof( s );
435 memset( s, 0, n );
436 n -= 2;
437
438 MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) );
439
440 if( p == NULL ) p = "";
441
442 plen = strlen( p );
443 slen = strlen( s );
444 s[slen++] = '\r';
445 s[slen++] = '\n';
446
447 if( fout != NULL )
448 {
449 if( fwrite( p, 1, plen, fout ) != plen ||
450 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000451 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 }
453 else
454 printf( "%s%s", p, s );
455
456cleanup:
457
458 return( ret );
459}
460
461/*
462 * Import X from unsigned binary data, big endian
463 */
464int mpi_read_binary( mpi *X, unsigned char *buf, int buflen )
465{
466 int ret, i, j, n;
467
468 for( n = 0; n < buflen; n++ )
469 if( buf[n] != 0 )
470 break;
471
472 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
473 MPI_CHK( mpi_lset( X, 0 ) );
474
475 for( i = buflen - 1, j = 0; i >= n; i--, j++ )
476 X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3);
477
478cleanup:
479
480 return( ret );
481}
482
483/*
484 * Export X into unsigned binary data, big endian
485 */
486int mpi_write_binary( mpi *X, unsigned char *buf, int buflen )
487{
488 int i, j, n;
489
490 n = mpi_size( X );
491
492 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 memset( buf, 0, buflen );
496
497 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
498 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
499
500 return( 0 );
501}
502
503/*
504 * Left-shift: X <<= count
505 */
506int mpi_shift_l( mpi *X, int count )
507{
508 int ret, i, v0, t1;
509 t_int r0 = 0, r1;
510
511 v0 = count / (biL );
512 t1 = count & (biL - 1);
513
514 i = mpi_msb( X ) + count;
515
516 if( X->n * (int) biL < i )
517 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
518
519 ret = 0;
520
521 /*
522 * shift by count / limb_size
523 */
524 if( v0 > 0 )
525 {
526 for( i = X->n - 1; i >= v0; i-- )
527 X->p[i] = X->p[i - v0];
528
529 for( ; i >= 0; i-- )
530 X->p[i] = 0;
531 }
532
533 /*
534 * shift by count % limb_size
535 */
536 if( t1 > 0 )
537 {
538 for( i = v0; i < X->n; i++ )
539 {
540 r1 = X->p[i] >> (biL - t1);
541 X->p[i] <<= t1;
542 X->p[i] |= r0;
543 r0 = r1;
544 }
545 }
546
547cleanup:
548
549 return( ret );
550}
551
552/*
553 * Right-shift: X >>= count
554 */
555int mpi_shift_r( mpi *X, int count )
556{
557 int i, v0, v1;
558 t_int r0 = 0, r1;
559
560 v0 = count / biL;
561 v1 = count & (biL - 1);
562
563 /*
564 * shift by count / limb_size
565 */
566 if( v0 > 0 )
567 {
568 for( i = 0; i < X->n - v0; i++ )
569 X->p[i] = X->p[i + v0];
570
571 for( ; i < X->n; i++ )
572 X->p[i] = 0;
573 }
574
575 /*
576 * shift by count % limb_size
577 */
578 if( v1 > 0 )
579 {
580 for( i = X->n - 1; i >= 0; i-- )
581 {
582 r1 = X->p[i] << (biL - v1);
583 X->p[i] >>= v1;
584 X->p[i] |= r0;
585 r0 = r1;
586 }
587 }
588
589 return( 0 );
590}
591
592/*
593 * Compare unsigned values
594 */
595int mpi_cmp_abs( mpi *X, mpi *Y )
596{
597 int i, j;
598
599 for( i = X->n - 1; i >= 0; i-- )
600 if( X->p[i] != 0 )
601 break;
602
603 for( j = Y->n - 1; j >= 0; j-- )
604 if( Y->p[j] != 0 )
605 break;
606
607 if( i < 0 && j < 0 )
608 return( 0 );
609
610 if( i > j ) return( 1 );
611 if( j > i ) return( -1 );
612
613 for( ; i >= 0; i-- )
614 {
615 if( X->p[i] > Y->p[i] ) return( 1 );
616 if( X->p[i] < Y->p[i] ) return( -1 );
617 }
618
619 return( 0 );
620}
621
622/*
623 * Compare signed values
624 */
625int mpi_cmp_mpi( mpi *X, mpi *Y )
626{
627 int i, j;
628
629 for( i = X->n - 1; i >= 0; i-- )
630 if( X->p[i] != 0 )
631 break;
632
633 for( j = Y->n - 1; j >= 0; j-- )
634 if( Y->p[j] != 0 )
635 break;
636
637 if( i < 0 && j < 0 )
638 return( 0 );
639
640 if( i > j ) return( X->s );
641 if( j > i ) return( -X->s );
642
643 if( X->s > 0 && Y->s < 0 ) return( 1 );
644 if( Y->s > 0 && X->s < 0 ) return( -1 );
645
646 for( ; i >= 0; i-- )
647 {
648 if( X->p[i] > Y->p[i] ) return( X->s );
649 if( X->p[i] < Y->p[i] ) return( -X->s );
650 }
651
652 return( 0 );
653}
654
655/*
656 * Compare signed values
657 */
658int mpi_cmp_int( mpi *X, int z )
659{
660 mpi Y;
661 t_int p[1];
662
663 *p = ( z < 0 ) ? -z : z;
664 Y.s = ( z < 0 ) ? -1 : 1;
665 Y.n = 1;
666 Y.p = p;
667
668 return( mpi_cmp_mpi( X, &Y ) );
669}
670
671/*
672 * Unsigned addition: X = |A| + |B| (HAC 14.7)
673 */
674int mpi_add_abs( mpi *X, mpi *A, mpi *B )
675{
676 int ret, i, j;
677 t_int *o, *p, c;
678
679 if( X == B )
680 {
681 mpi *T = A; A = X; B = T;
682 }
683
684 if( X != A )
685 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000686
687 /*
688 * X should always be positive as a result of unsigned additions.
689 */
690 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
692 for( j = B->n - 1; j >= 0; j-- )
693 if( B->p[j] != 0 )
694 break;
695
696 MPI_CHK( mpi_grow( X, j + 1 ) );
697
698 o = B->p; p = X->p; c = 0;
699
700 for( i = 0; i <= j; i++, o++, p++ )
701 {
702 *p += c; c = ( *p < c );
703 *p += *o; c += ( *p < *o );
704 }
705
706 while( c != 0 )
707 {
708 if( i >= X->n )
709 {
710 MPI_CHK( mpi_grow( X, i + 1 ) );
711 p = X->p + i;
712 }
713
714 *p += c; c = ( *p < c ); i++;
715 }
716
717cleanup:
718
719 return( ret );
720}
721
722/*
723 * Helper for mpi substraction
724 */
725static void mpi_sub_hlp( int n, t_int *s, t_int *d )
726{
727 int i;
728 t_int c, z;
729
730 for( i = c = 0; i < n; i++, s++, d++ )
731 {
732 z = ( *d < c ); *d -= c;
733 c = ( *d < *s ) + z; *d -= *s;
734 }
735
736 while( c != 0 )
737 {
738 z = ( *d < c ); *d -= c;
739 c = z; i++; d++;
740 }
741}
742
743/*
744 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
745 */
746int mpi_sub_abs( mpi *X, mpi *A, mpi *B )
747{
748 mpi TB;
749 int ret, n;
750
751 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000752 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754 mpi_init( &TB, NULL );
755
756 if( X == B )
757 {
758 MPI_CHK( mpi_copy( &TB, B ) );
759 B = &TB;
760 }
761
762 if( X != A )
763 MPI_CHK( mpi_copy( X, A ) );
764
Paul Bakker1ef7a532009-06-20 10:50:55 +0000765 /*
766 * X should always be positive as a result of unsigned substractions.
767 */
768 X->s = 1;
769
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 ret = 0;
771
772 for( n = B->n - 1; n >= 0; n-- )
773 if( B->p[n] != 0 )
774 break;
775
776 mpi_sub_hlp( n + 1, B->p, X->p );
777
778cleanup:
779
780 mpi_free( &TB, NULL );
781
782 return( ret );
783}
784
785/*
786 * Signed addition: X = A + B
787 */
788int mpi_add_mpi( mpi *X, mpi *A, mpi *B )
789{
790 int ret, s = A->s;
791
792 if( A->s * B->s < 0 )
793 {
794 if( mpi_cmp_abs( A, B ) >= 0 )
795 {
796 MPI_CHK( mpi_sub_abs( X, A, B ) );
797 X->s = s;
798 }
799 else
800 {
801 MPI_CHK( mpi_sub_abs( X, B, A ) );
802 X->s = -s;
803 }
804 }
805 else
806 {
807 MPI_CHK( mpi_add_abs( X, A, B ) );
808 X->s = s;
809 }
810
811cleanup:
812
813 return( ret );
814}
815
816/*
817 * Signed substraction: X = A - B
818 */
819int mpi_sub_mpi( mpi *X, mpi *A, mpi *B )
820{
821 int ret, s = A->s;
822
823 if( A->s * B->s > 0 )
824 {
825 if( mpi_cmp_abs( A, B ) >= 0 )
826 {
827 MPI_CHK( mpi_sub_abs( X, A, B ) );
828 X->s = s;
829 }
830 else
831 {
832 MPI_CHK( mpi_sub_abs( X, B, A ) );
833 X->s = -s;
834 }
835 }
836 else
837 {
838 MPI_CHK( mpi_add_abs( X, A, B ) );
839 X->s = s;
840 }
841
842cleanup:
843
844 return( ret );
845}
846
847/*
848 * Signed addition: X = A + b
849 */
850int mpi_add_int( mpi *X, mpi *A, int b )
851{
852 mpi _B;
853 t_int p[1];
854
855 p[0] = ( b < 0 ) ? -b : b;
856 _B.s = ( b < 0 ) ? -1 : 1;
857 _B.n = 1;
858 _B.p = p;
859
860 return( mpi_add_mpi( X, A, &_B ) );
861}
862
863/*
864 * Signed substraction: X = A - b
865 */
866int mpi_sub_int( mpi *X, mpi *A, int b )
867{
868 mpi _B;
869 t_int p[1];
870
871 p[0] = ( b < 0 ) ? -b : b;
872 _B.s = ( b < 0 ) ? -1 : 1;
873 _B.n = 1;
874 _B.p = p;
875
876 return( mpi_sub_mpi( X, A, &_B ) );
877}
878
879/*
880 * Helper for mpi multiplication
881 */
882static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b )
883{
884 t_int c = 0, t = 0;
885
886#if defined(MULADDC_HUIT)
887 for( ; i >= 8; i -= 8 )
888 {
889 MULADDC_INIT
890 MULADDC_HUIT
891 MULADDC_STOP
892 }
893
894 for( ; i > 0; i-- )
895 {
896 MULADDC_INIT
897 MULADDC_CORE
898 MULADDC_STOP
899 }
900#else
901 for( ; i >= 16; i -= 16 )
902 {
903 MULADDC_INIT
904 MULADDC_CORE MULADDC_CORE
905 MULADDC_CORE MULADDC_CORE
906 MULADDC_CORE MULADDC_CORE
907 MULADDC_CORE MULADDC_CORE
908
909 MULADDC_CORE MULADDC_CORE
910 MULADDC_CORE MULADDC_CORE
911 MULADDC_CORE MULADDC_CORE
912 MULADDC_CORE MULADDC_CORE
913 MULADDC_STOP
914 }
915
916 for( ; i >= 8; i -= 8 )
917 {
918 MULADDC_INIT
919 MULADDC_CORE MULADDC_CORE
920 MULADDC_CORE MULADDC_CORE
921
922 MULADDC_CORE MULADDC_CORE
923 MULADDC_CORE MULADDC_CORE
924 MULADDC_STOP
925 }
926
927 for( ; i > 0; i-- )
928 {
929 MULADDC_INIT
930 MULADDC_CORE
931 MULADDC_STOP
932 }
933#endif
934
935 t++;
936
937 do {
938 *d += c; c = ( *d < c ); d++;
939 }
940 while( c != 0 );
941}
942
943/*
944 * Baseline multiplication: X = A * B (HAC 14.12)
945 */
946int mpi_mul_mpi( mpi *X, mpi *A, mpi *B )
947{
948 int ret, i, j;
949 mpi TA, TB;
950
951 mpi_init( &TA, &TB, NULL );
952
953 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
954 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
955
956 for( i = A->n - 1; i >= 0; i-- )
957 if( A->p[i] != 0 )
958 break;
959
960 for( j = B->n - 1; j >= 0; j-- )
961 if( B->p[j] != 0 )
962 break;
963
964 MPI_CHK( mpi_grow( X, i + j + 2 ) );
965 MPI_CHK( mpi_lset( X, 0 ) );
966
967 for( i++; j >= 0; j-- )
968 mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );
969
970 X->s = A->s * B->s;
971
972cleanup:
973
974 mpi_free( &TB, &TA, NULL );
975
976 return( ret );
977}
978
979/*
980 * Baseline multiplication: X = A * b
981 */
982int mpi_mul_int( mpi *X, mpi *A, t_int b )
983{
984 mpi _B;
985 t_int p[1];
986
987 _B.s = 1;
988 _B.n = 1;
989 _B.p = p;
990 p[0] = b;
991
992 return( mpi_mul_mpi( X, A, &_B ) );
993}
994
995/*
996 * Division by mpi: A = Q * B + R (HAC 14.20)
997 */
998int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B )
999{
1000 int ret, i, n, t, k;
1001 mpi X, Y, Z, T1, T2;
1002
1003 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001004 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
1006 mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
1007
1008 if( mpi_cmp_abs( A, B ) < 0 )
1009 {
1010 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1011 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1012 return( 0 );
1013 }
1014
1015 MPI_CHK( mpi_copy( &X, A ) );
1016 MPI_CHK( mpi_copy( &Y, B ) );
1017 X.s = Y.s = 1;
1018
1019 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1020 MPI_CHK( mpi_lset( &Z, 0 ) );
1021 MPI_CHK( mpi_grow( &T1, 2 ) );
1022 MPI_CHK( mpi_grow( &T2, 3 ) );
1023
1024 k = mpi_msb( &Y ) % biL;
1025 if( k < (int) biL - 1 )
1026 {
1027 k = biL - 1 - k;
1028 MPI_CHK( mpi_shift_l( &X, k ) );
1029 MPI_CHK( mpi_shift_l( &Y, k ) );
1030 }
1031 else k = 0;
1032
1033 n = X.n - 1;
1034 t = Y.n - 1;
1035 mpi_shift_l( &Y, biL * (n - t) );
1036
1037 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1038 {
1039 Z.p[n - t]++;
1040 mpi_sub_mpi( &X, &X, &Y );
1041 }
1042 mpi_shift_r( &Y, biL * (n - t) );
1043
1044 for( i = n; i > t ; i-- )
1045 {
1046 if( X.p[i] >= Y.p[t] )
1047 Z.p[i - t - 1] = ~0;
1048 else
1049 {
Paul Bakker40e46942009-01-03 21:51:57 +00001050#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001051 t_dbl r;
1052
1053 r = (t_dbl) X.p[i] << biL;
1054 r |= (t_dbl) X.p[i - 1];
1055 r /= Y.p[t];
1056 if( r > ((t_dbl) 1 << biL) - 1)
1057 r = ((t_dbl) 1 << biL) - 1;
1058
1059 Z.p[i - t - 1] = (t_int) r;
1060#else
1061 /*
1062 * __udiv_qrnnd_c, from gmp/longlong.h
1063 */
1064 t_int q0, q1, r0, r1;
1065 t_int d0, d1, d, m;
1066
1067 d = Y.p[t];
1068 d0 = ( d << biH ) >> biH;
1069 d1 = ( d >> biH );
1070
1071 q1 = X.p[i] / d1;
1072 r1 = X.p[i] - d1 * q1;
1073 r1 <<= biH;
1074 r1 |= ( X.p[i - 1] >> biH );
1075
1076 m = q1 * d0;
1077 if( r1 < m )
1078 {
1079 q1--, r1 += d;
1080 while( r1 >= d && r1 < m )
1081 q1--, r1 += d;
1082 }
1083 r1 -= m;
1084
1085 q0 = r1 / d1;
1086 r0 = r1 - d1 * q0;
1087 r0 <<= biH;
1088 r0 |= ( X.p[i - 1] << biH ) >> biH;
1089
1090 m = q0 * d0;
1091 if( r0 < m )
1092 {
1093 q0--, r0 += d;
1094 while( r0 >= d && r0 < m )
1095 q0--, r0 += d;
1096 }
1097 r0 -= m;
1098
1099 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1100#endif
1101 }
1102
1103 Z.p[i - t - 1]++;
1104 do
1105 {
1106 Z.p[i - t - 1]--;
1107
1108 MPI_CHK( mpi_lset( &T1, 0 ) );
1109 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1110 T1.p[1] = Y.p[t];
1111 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1112
1113 MPI_CHK( mpi_lset( &T2, 0 ) );
1114 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1115 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1116 T2.p[2] = X.p[i];
1117 }
1118 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1119
1120 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1121 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1122 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1123
1124 if( mpi_cmp_int( &X, 0 ) < 0 )
1125 {
1126 MPI_CHK( mpi_copy( &T1, &Y ) );
1127 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1128 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1129 Z.p[i - t - 1]--;
1130 }
1131 }
1132
1133 if( Q != NULL )
1134 {
1135 mpi_copy( Q, &Z );
1136 Q->s = A->s * B->s;
1137 }
1138
1139 if( R != NULL )
1140 {
1141 mpi_shift_r( &X, k );
1142 mpi_copy( R, &X );
1143
1144 R->s = A->s;
1145 if( mpi_cmp_int( R, 0 ) == 0 )
1146 R->s = 1;
1147 }
1148
1149cleanup:
1150
1151 mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
1152
1153 return( ret );
1154}
1155
1156/*
1157 * Division by int: A = Q * b + R
1158 *
1159 * Returns 0 if successful
1160 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001161 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 */
1163int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b )
1164{
1165 mpi _B;
1166 t_int p[1];
1167
1168 p[0] = ( b < 0 ) ? -b : b;
1169 _B.s = ( b < 0 ) ? -1 : 1;
1170 _B.n = 1;
1171 _B.p = p;
1172
1173 return( mpi_div_mpi( Q, R, A, &_B ) );
1174}
1175
1176/*
1177 * Modulo: R = A mod B
1178 */
1179int mpi_mod_mpi( mpi *R, mpi *A, mpi *B )
1180{
1181 int ret;
1182
1183 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1184
1185 while( mpi_cmp_int( R, 0 ) < 0 )
1186 MPI_CHK( mpi_add_mpi( R, R, B ) );
1187
1188 while( mpi_cmp_mpi( R, B ) >= 0 )
1189 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1190
1191cleanup:
1192
1193 return( ret );
1194}
1195
1196/*
1197 * Modulo: r = A mod b
1198 */
1199int mpi_mod_int( t_int *r, mpi *A, int b )
1200{
1201 int i;
1202 t_int x, y, z;
1203
1204 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001205 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206
1207 if( b < 0 )
1208 b = -b;
1209
1210 /*
1211 * handle trivial cases
1212 */
1213 if( b == 1 )
1214 {
1215 *r = 0;
1216 return( 0 );
1217 }
1218
1219 if( b == 2 )
1220 {
1221 *r = A->p[0] & 1;
1222 return( 0 );
1223 }
1224
1225 /*
1226 * general case
1227 */
1228 for( i = A->n - 1, y = 0; i >= 0; i-- )
1229 {
1230 x = A->p[i];
1231 y = ( y << biH ) | ( x >> biH );
1232 z = y / b;
1233 y -= z * b;
1234
1235 x <<= biH;
1236 y = ( y << biH ) | ( x >> biH );
1237 z = y / b;
1238 y -= z * b;
1239 }
1240
1241 *r = y;
1242
1243 return( 0 );
1244}
1245
1246/*
1247 * Fast Montgomery initialization (thanks to Tom St Denis)
1248 */
1249static void mpi_montg_init( t_int *mm, mpi *N )
1250{
1251 t_int x, m0 = N->p[0];
1252
1253 x = m0;
1254 x += ( ( m0 + 2 ) & 4 ) << 1;
1255 x *= ( 2 - ( m0 * x ) );
1256
1257 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1258 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1259 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1260
1261 *mm = ~x + 1;
1262}
1263
1264/*
1265 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1266 */
1267static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T )
1268{
1269 int i, n, m;
1270 t_int u0, u1, *d;
1271
1272 memset( T->p, 0, T->n * ciL );
1273
1274 d = T->p;
1275 n = N->n;
1276 m = ( B->n < n ) ? B->n : n;
1277
1278 for( i = 0; i < n; i++ )
1279 {
1280 /*
1281 * T = (T + u0*B + u1*N) / 2^biL
1282 */
1283 u0 = A->p[i];
1284 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1285
1286 mpi_mul_hlp( m, B->p, d, u0 );
1287 mpi_mul_hlp( n, N->p, d, u1 );
1288
1289 *d++ = u0; d[n + 1] = 0;
1290 }
1291
1292 memcpy( A->p, d, (n + 1) * ciL );
1293
1294 if( mpi_cmp_abs( A, N ) >= 0 )
1295 mpi_sub_hlp( n, N->p, A->p );
1296 else
1297 /* prevent timing attacks */
1298 mpi_sub_hlp( n, A->p, T->p );
1299}
1300
1301/*
1302 * Montgomery reduction: A = A * R^-1 mod N
1303 */
1304static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T )
1305{
1306 t_int z = 1;
1307 mpi U;
1308
1309 U.n = U.s = z;
1310 U.p = &z;
1311
1312 mpi_montmul( A, &U, N, mm, T );
1313}
1314
1315/*
1316 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1317 */
1318int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR )
1319{
1320 int ret, i, j, wsize, wbits;
1321 int bufsize, nblimbs, nbits;
1322 t_int ei, mm, state;
1323 mpi RR, T, W[64];
1324
1325 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001326 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001327
1328 /*
1329 * Init temps and window size
1330 */
1331 mpi_montg_init( &mm, N );
1332 mpi_init( &RR, &T, NULL );
1333 memset( W, 0, sizeof( W ) );
1334
1335 i = mpi_msb( E );
1336
1337 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1338 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1339
1340 j = N->n + 1;
1341 MPI_CHK( mpi_grow( X, j ) );
1342 MPI_CHK( mpi_grow( &W[1], j ) );
1343 MPI_CHK( mpi_grow( &T, j * 2 ) );
1344
1345 /*
1346 * If 1st call, pre-compute R^2 mod N
1347 */
1348 if( _RR == NULL || _RR->p == NULL )
1349 {
1350 MPI_CHK( mpi_lset( &RR, 1 ) );
1351 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1352 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1353
1354 if( _RR != NULL )
1355 memcpy( _RR, &RR, sizeof( mpi ) );
1356 }
1357 else
1358 memcpy( &RR, _RR, sizeof( mpi ) );
1359
1360 /*
1361 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1362 */
1363 if( mpi_cmp_mpi( A, N ) >= 0 )
1364 mpi_mod_mpi( &W[1], A, N );
1365 else mpi_copy( &W[1], A );
1366
1367 mpi_montmul( &W[1], &RR, N, mm, &T );
1368
1369 /*
1370 * X = R^2 * R^-1 mod N = R mod N
1371 */
1372 MPI_CHK( mpi_copy( X, &RR ) );
1373 mpi_montred( X, N, mm, &T );
1374
1375 if( wsize > 1 )
1376 {
1377 /*
1378 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1379 */
1380 j = 1 << (wsize - 1);
1381
1382 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1383 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1384
1385 for( i = 0; i < wsize - 1; i++ )
1386 mpi_montmul( &W[j], &W[j], N, mm, &T );
1387
1388 /*
1389 * W[i] = W[i - 1] * W[1]
1390 */
1391 for( i = j + 1; i < (1 << wsize); i++ )
1392 {
1393 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1394 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1395
1396 mpi_montmul( &W[i], &W[1], N, mm, &T );
1397 }
1398 }
1399
1400 nblimbs = E->n;
1401 bufsize = 0;
1402 nbits = 0;
1403 wbits = 0;
1404 state = 0;
1405
1406 while( 1 )
1407 {
1408 if( bufsize == 0 )
1409 {
1410 if( nblimbs-- == 0 )
1411 break;
1412
1413 bufsize = sizeof( t_int ) << 3;
1414 }
1415
1416 bufsize--;
1417
1418 ei = (E->p[nblimbs] >> bufsize) & 1;
1419
1420 /*
1421 * skip leading 0s
1422 */
1423 if( ei == 0 && state == 0 )
1424 continue;
1425
1426 if( ei == 0 && state == 1 )
1427 {
1428 /*
1429 * out of window, square X
1430 */
1431 mpi_montmul( X, X, N, mm, &T );
1432 continue;
1433 }
1434
1435 /*
1436 * add ei to current window
1437 */
1438 state = 2;
1439
1440 nbits++;
1441 wbits |= (ei << (wsize - nbits));
1442
1443 if( nbits == wsize )
1444 {
1445 /*
1446 * X = X^wsize R^-1 mod N
1447 */
1448 for( i = 0; i < wsize; i++ )
1449 mpi_montmul( X, X, N, mm, &T );
1450
1451 /*
1452 * X = X * W[wbits] R^-1 mod N
1453 */
1454 mpi_montmul( X, &W[wbits], N, mm, &T );
1455
1456 state--;
1457 nbits = 0;
1458 wbits = 0;
1459 }
1460 }
1461
1462 /*
1463 * process the remaining bits
1464 */
1465 for( i = 0; i < nbits; i++ )
1466 {
1467 mpi_montmul( X, X, N, mm, &T );
1468
1469 wbits <<= 1;
1470
1471 if( (wbits & (1 << wsize)) != 0 )
1472 mpi_montmul( X, &W[1], N, mm, &T );
1473 }
1474
1475 /*
1476 * X = A^E * R * R^-1 mod N = A^E mod N
1477 */
1478 mpi_montred( X, N, mm, &T );
1479
1480cleanup:
1481
1482 for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )
1483 mpi_free( &W[i], NULL );
1484
1485 if( _RR != NULL )
1486 mpi_free( &W[1], &T, NULL );
1487 else mpi_free( &W[1], &T, &RR, NULL );
1488
1489 return( ret );
1490}
1491
Paul Bakker5121ce52009-01-03 21:22:43 +00001492/*
1493 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1494 */
1495int mpi_gcd( mpi *G, mpi *A, mpi *B )
1496{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001497 int ret, lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 mpi TG, TA, TB;
1499
1500 mpi_init( &TG, &TA, &TB, NULL );
1501
Paul Bakker5121ce52009-01-03 21:22:43 +00001502 MPI_CHK( mpi_copy( &TA, A ) );
1503 MPI_CHK( mpi_copy( &TB, B ) );
1504
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001505 lz = mpi_lsb( &TA );
1506 lzt = mpi_lsb( &TB );
1507
1508 if ( lzt < lz )
1509 lz = lzt;
1510
1511 MPI_CHK( mpi_shift_r( &TA, lz ) );
1512 MPI_CHK( mpi_shift_r( &TB, lz ) );
1513
Paul Bakker5121ce52009-01-03 21:22:43 +00001514 TA.s = TB.s = 1;
1515
1516 while( mpi_cmp_int( &TA, 0 ) != 0 )
1517 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001518 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1519 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001520
1521 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1522 {
1523 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1524 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1525 }
1526 else
1527 {
1528 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1529 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1530 }
1531 }
1532
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001533 MPI_CHK( mpi_shift_l( &TB, lz ) );
1534 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001535
1536cleanup:
1537
1538 mpi_free( &TB, &TA, &TG, NULL );
1539
1540 return( ret );
1541}
1542
Paul Bakker70b3eed2009-03-14 18:01:25 +00001543#if defined(POLARSSL_GENPRIME)
1544
Paul Bakker5121ce52009-01-03 21:22:43 +00001545/*
1546 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1547 */
1548int mpi_inv_mod( mpi *X, mpi *A, mpi *N )
1549{
1550 int ret;
1551 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1552
1553 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001554 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001555
1556 mpi_init( &TA, &TU, &U1, &U2, &G,
1557 &TB, &TV, &V1, &V2, NULL );
1558
1559 MPI_CHK( mpi_gcd( &G, A, N ) );
1560
1561 if( mpi_cmp_int( &G, 1 ) != 0 )
1562 {
Paul Bakker40e46942009-01-03 21:51:57 +00001563 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 goto cleanup;
1565 }
1566
1567 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1568 MPI_CHK( mpi_copy( &TU, &TA ) );
1569 MPI_CHK( mpi_copy( &TB, N ) );
1570 MPI_CHK( mpi_copy( &TV, N ) );
1571
1572 MPI_CHK( mpi_lset( &U1, 1 ) );
1573 MPI_CHK( mpi_lset( &U2, 0 ) );
1574 MPI_CHK( mpi_lset( &V1, 0 ) );
1575 MPI_CHK( mpi_lset( &V2, 1 ) );
1576
1577 do
1578 {
1579 while( ( TU.p[0] & 1 ) == 0 )
1580 {
1581 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1582
1583 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1584 {
1585 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1586 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1587 }
1588
1589 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1590 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1591 }
1592
1593 while( ( TV.p[0] & 1 ) == 0 )
1594 {
1595 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1596
1597 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1598 {
1599 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1600 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1601 }
1602
1603 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1604 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1605 }
1606
1607 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1608 {
1609 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1610 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1611 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1612 }
1613 else
1614 {
1615 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1616 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1617 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1618 }
1619 }
1620 while( mpi_cmp_int( &TU, 0 ) != 0 );
1621
1622 while( mpi_cmp_int( &V1, 0 ) < 0 )
1623 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1624
1625 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1626 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1627
1628 MPI_CHK( mpi_copy( X, &V1 ) );
1629
1630cleanup:
1631
1632 mpi_free( &V2, &V1, &TV, &TB, &G,
1633 &U2, &U1, &TU, &TA, NULL );
1634
1635 return( ret );
1636}
1637
1638static const int small_prime[] =
1639{
1640 3, 5, 7, 11, 13, 17, 19, 23,
1641 29, 31, 37, 41, 43, 47, 53, 59,
1642 61, 67, 71, 73, 79, 83, 89, 97,
1643 101, 103, 107, 109, 113, 127, 131, 137,
1644 139, 149, 151, 157, 163, 167, 173, 179,
1645 181, 191, 193, 197, 199, 211, 223, 227,
1646 229, 233, 239, 241, 251, 257, 263, 269,
1647 271, 277, 281, 283, 293, 307, 311, 313,
1648 317, 331, 337, 347, 349, 353, 359, 367,
1649 373, 379, 383, 389, 397, 401, 409, 419,
1650 421, 431, 433, 439, 443, 449, 457, 461,
1651 463, 467, 479, 487, 491, 499, 503, 509,
1652 521, 523, 541, 547, 557, 563, 569, 571,
1653 577, 587, 593, 599, 601, 607, 613, 617,
1654 619, 631, 641, 643, 647, 653, 659, 661,
1655 673, 677, 683, 691, 701, 709, 719, 727,
1656 733, 739, 743, 751, 757, 761, 769, 773,
1657 787, 797, 809, 811, 821, 823, 827, 829,
1658 839, 853, 857, 859, 863, 877, 881, 883,
1659 887, 907, 911, 919, 929, 937, 941, 947,
1660 953, 967, 971, 977, 983, 991, 997, -103
1661};
1662
1663/*
1664 * Miller-Rabin primality test (HAC 4.24)
1665 */
1666int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1667{
1668 int ret, i, j, n, s, xs;
1669 mpi W, R, T, A, RR;
1670 unsigned char *p;
1671
1672 if( mpi_cmp_int( X, 0 ) == 0 )
1673 return( 0 );
1674
1675 mpi_init( &W, &R, &T, &A, &RR, NULL );
1676
1677 xs = X->s; X->s = 1;
1678
1679 /*
1680 * test trivial factors first
1681 */
1682 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001683 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001684
1685 for( i = 0; small_prime[i] > 0; i++ )
1686 {
1687 t_int r;
1688
1689 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1690 return( 0 );
1691
1692 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1693
1694 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001695 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001696 }
1697
1698 /*
1699 * W = |X| - 1
1700 * R = W >> lsb( W )
1701 */
1702 s = mpi_lsb( &W );
1703 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
1704 MPI_CHK( mpi_copy( &R, &W ) );
1705 MPI_CHK( mpi_shift_r( &R, s ) );
1706
1707 i = mpi_msb( X );
1708 /*
1709 * HAC, table 4.4
1710 */
1711 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1712 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1713 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1714
1715 for( i = 0; i < n; i++ )
1716 {
1717 /*
1718 * pick a random A, 1 < A < |X| - 1
1719 */
1720 MPI_CHK( mpi_grow( &A, X->n ) );
1721
1722 p = (unsigned char *) A.p;
1723 for( j = 0; j < A.n * ciL; j++ )
1724 *p++ = (unsigned char) f_rng( p_rng );
1725
1726 j = mpi_msb( &A ) - mpi_msb( &W );
1727 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1728 A.p[0] |= 3;
1729
1730 /*
1731 * A = A^R mod |X|
1732 */
1733 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1734
1735 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1736 mpi_cmp_int( &A, 1 ) == 0 )
1737 continue;
1738
1739 j = 1;
1740 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1741 {
1742 /*
1743 * A = A * A mod |X|
1744 */
1745 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1746 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1747
1748 if( mpi_cmp_int( &A, 1 ) == 0 )
1749 break;
1750
1751 j++;
1752 }
1753
1754 /*
1755 * not prime if A != |X| - 1 or A == 1
1756 */
1757 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1758 mpi_cmp_int( &A, 1 ) == 0 )
1759 {
Paul Bakker40e46942009-01-03 21:51:57 +00001760 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001761 break;
1762 }
1763 }
1764
1765cleanup:
1766
1767 X->s = xs;
1768
1769 mpi_free( &RR, &A, &T, &R, &W, NULL );
1770
1771 return( ret );
1772}
1773
1774/*
1775 * Prime number generation
1776 */
1777int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
1778 int (*f_rng)(void *), void *p_rng )
1779{
1780 int ret, k, n;
1781 unsigned char *p;
1782 mpi Y;
1783
1784 if( nbits < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +00001785 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001786
1787 mpi_init( &Y, NULL );
1788
1789 n = BITS_TO_LIMBS( nbits );
1790
1791 MPI_CHK( mpi_grow( X, n ) );
1792 MPI_CHK( mpi_lset( X, 0 ) );
1793
1794 p = (unsigned char *) X->p;
1795 for( k = 0; k < X->n * ciL; k++ )
1796 *p++ = (unsigned char) f_rng( p_rng );
1797
1798 k = mpi_msb( X );
1799 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1800 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1801
1802 X->p[0] |= 3;
1803
1804 if( dh_flag == 0 )
1805 {
1806 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1807 {
Paul Bakker40e46942009-01-03 21:51:57 +00001808 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001809 goto cleanup;
1810
1811 MPI_CHK( mpi_add_int( X, X, 2 ) );
1812 }
1813 }
1814 else
1815 {
1816 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1817 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1818
1819 while( 1 )
1820 {
1821 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1822 {
1823 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1824 break;
1825
Paul Bakker40e46942009-01-03 21:51:57 +00001826 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 goto cleanup;
1828 }
1829
Paul Bakker40e46942009-01-03 21:51:57 +00001830 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001831 goto cleanup;
1832
1833 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1834 MPI_CHK( mpi_add_int( X, X, 2 ) );
1835 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1836 }
1837 }
1838
1839cleanup:
1840
1841 mpi_free( &Y, NULL );
1842
1843 return( ret );
1844}
1845
1846#endif
1847
Paul Bakker40e46942009-01-03 21:51:57 +00001848#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001849
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001850#define GCD_PAIR_COUNT 3
1851
1852static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1853{
1854 { 693, 609, 21 },
1855 { 1764, 868, 28 },
1856 { 768454923, 542167814, 1 }
1857};
1858
Paul Bakker5121ce52009-01-03 21:22:43 +00001859/*
1860 * Checkup routine
1861 */
1862int mpi_self_test( int verbose )
1863{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001864 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 mpi A, E, N, X, Y, U, V;
1866
1867 mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
1868
1869 MPI_CHK( mpi_read_string( &A, 16,
1870 "EFE021C2645FD1DC586E69184AF4A31E" \
1871 "D5F53E93B5F123FA41680867BA110131" \
1872 "944FE7952E2517337780CB0DB80E61AA" \
1873 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1874
1875 MPI_CHK( mpi_read_string( &E, 16,
1876 "B2E7EFD37075B9F03FF989C7C5051C20" \
1877 "34D2A323810251127E7BF8625A4F49A5" \
1878 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1879 "5B5C25763222FEFCCFC38B832366C29E" ) );
1880
1881 MPI_CHK( mpi_read_string( &N, 16,
1882 "0066A198186C18C10B2F5ED9B522752A" \
1883 "9830B69916E535C8F047518A889A43A5" \
1884 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1885
1886 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1887
1888 MPI_CHK( mpi_read_string( &U, 16,
1889 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1890 "9E857EA95A03512E2BAE7391688D264A" \
1891 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1892 "8001B72E848A38CAE1C65F78E56ABDEF" \
1893 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1894 "ECF677152EF804370C1A305CAF3B5BF1" \
1895 "30879B56C61DE584A0F53A2447A51E" ) );
1896
1897 if( verbose != 0 )
1898 printf( " MPI test #1 (mul_mpi): " );
1899
1900 if( mpi_cmp_mpi( &X, &U ) != 0 )
1901 {
1902 if( verbose != 0 )
1903 printf( "failed\n" );
1904
1905 return( 1 );
1906 }
1907
1908 if( verbose != 0 )
1909 printf( "passed\n" );
1910
1911 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1912
1913 MPI_CHK( mpi_read_string( &U, 16,
1914 "256567336059E52CAE22925474705F39A94" ) );
1915
1916 MPI_CHK( mpi_read_string( &V, 16,
1917 "6613F26162223DF488E9CD48CC132C7A" \
1918 "0AC93C701B001B092E4E5B9F73BCD27B" \
1919 "9EE50D0657C77F374E903CDFA4C642" ) );
1920
1921 if( verbose != 0 )
1922 printf( " MPI test #2 (div_mpi): " );
1923
1924 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1925 mpi_cmp_mpi( &Y, &V ) != 0 )
1926 {
1927 if( verbose != 0 )
1928 printf( "failed\n" );
1929
1930 return( 1 );
1931 }
1932
1933 if( verbose != 0 )
1934 printf( "passed\n" );
1935
1936 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1937
1938 MPI_CHK( mpi_read_string( &U, 16,
1939 "36E139AEA55215609D2816998ED020BB" \
1940 "BD96C37890F65171D948E9BC7CBAA4D9" \
1941 "325D24D6A3C12710F10A09FA08AB87" ) );
1942
1943 if( verbose != 0 )
1944 printf( " MPI test #3 (exp_mod): " );
1945
1946 if( mpi_cmp_mpi( &X, &U ) != 0 )
1947 {
1948 if( verbose != 0 )
1949 printf( "failed\n" );
1950
1951 return( 1 );
1952 }
1953
1954 if( verbose != 0 )
1955 printf( "passed\n" );
1956
1957 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
1958
1959 MPI_CHK( mpi_read_string( &U, 16,
1960 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
1961 "C3DBA76456363A10869622EAC2DD84EC" \
1962 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
1963
1964 if( verbose != 0 )
1965 printf( " MPI test #4 (inv_mod): " );
1966
1967 if( mpi_cmp_mpi( &X, &U ) != 0 )
1968 {
1969 if( verbose != 0 )
1970 printf( "failed\n" );
1971
1972 return( 1 );
1973 }
1974
1975 if( verbose != 0 )
1976 printf( "passed\n" );
1977
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001978 if( verbose != 0 )
1979 printf( " MPI test #5 (simple gcd): " );
1980
1981 for ( i = 0; i < GCD_PAIR_COUNT; i++)
1982 {
1983 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
1984 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
1985
1986 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
1987
1988 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
1989 {
1990 if( verbose != 0 )
1991 printf( "failed at %d\n", i );
1992
1993 return( 1 );
1994 }
1995 }
1996
1997 if( verbose != 0 )
1998 printf( "passed\n" );
1999
Paul Bakker5121ce52009-01-03 21:22:43 +00002000cleanup:
2001
2002 if( ret != 0 && verbose != 0 )
2003 printf( "Unexpected error, return code = %08X\n", ret );
2004
2005 mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
2006
2007 if( verbose != 0 )
2008 printf( "\n" );
2009
2010 return( ret );
2011}
2012
2013#endif
2014
2015#endif