root/trunk/pdns/pdns/ext/polarssl-1.1.2/library/bignum.c @ 2593

Revision 2593, 43.1 KB (checked in by ahu, 14 months ago)

include fix from polarssl to speedup rsa key generation again

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