]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/CyaSSL/ctaocrypt/src/tfm.c
Update CyaSSL to latest version.
[freertos] / FreeRTOS-Plus / Source / CyaSSL / ctaocrypt / src / tfm.c
1 /* tfm.c
2  *
3  * Copyright (C) 2006-2014 wolfSSL Inc.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22
23 /*
24  * Based on public domain TomsFastMath 0.10 by Tom St Denis, tomstdenis@iahu.ca,
25  * http://math.libtomcrypt.com
26  */
27
28 /**
29  *  Edited by Moisés Guimarães (moisesguimaraesm@gmail.com)
30  *  to fit CyaSSL's needs.
31  */
32
33 #ifdef HAVE_CONFIG_H
34     #include <config.h>
35 #endif
36
37 /* in case user set USE_FAST_MATH there */
38 #include <cyassl/ctaocrypt/settings.h>
39
40 #ifdef USE_FAST_MATH
41
42 #include <cyassl/ctaocrypt/tfm.h>
43 #include <ctaocrypt/src/asm.c>  /* will define asm MACROS or C ones */
44
45
46 /* math settings check */
47 word32 CheckRunTimeSettings(void)
48 {
49     return CTC_SETTINGS;
50 }
51
52
53 /* math settings size check */
54 word32 CheckRunTimeFastMath(void)
55 {
56     return FP_SIZE;
57 }
58
59
60 /* Functions */
61
62 void fp_add(fp_int *a, fp_int *b, fp_int *c)
63 {
64   int     sa, sb;
65
66   /* get sign of both inputs */
67   sa = a->sign;
68   sb = b->sign;
69
70   /* handle two cases, not four */
71   if (sa == sb) {
72     /* both positive or both negative */
73     /* add their magnitudes, copy the sign */
74     c->sign = sa;
75     s_fp_add (a, b, c);
76   } else {
77     /* one positive, the other negative */
78     /* subtract the one with the greater magnitude from */
79     /* the one of the lesser magnitude.  The result gets */
80     /* the sign of the one with the greater magnitude. */
81     if (fp_cmp_mag (a, b) == FP_LT) {
82       c->sign = sb;
83       s_fp_sub (b, a, c);
84     } else {
85       c->sign = sa;
86       s_fp_sub (a, b, c);
87     }
88   }
89 }
90
91 /* unsigned addition */
92 void s_fp_add(fp_int *a, fp_int *b, fp_int *c)
93 {
94   int      x, y, oldused;
95   register fp_word  t;
96
97   y       = MAX(a->used, b->used);
98   oldused = MAX(c->used, FP_SIZE);   /* help static analysis w/ max size */
99   c->used = y;
100  
101   t = 0;
102   for (x = 0; x < y; x++) {
103       t         += ((fp_word)a->dp[x]) + ((fp_word)b->dp[x]);
104       c->dp[x]   = (fp_digit)t;
105       t        >>= DIGIT_BIT;
106   }
107   if (t != 0 && x < FP_SIZE) {
108      c->dp[c->used++] = (fp_digit)t;
109      ++x;
110   }
111
112   c->used = x;
113   for (; x < oldused; x++) {
114      c->dp[x] = 0;
115   }
116   fp_clamp(c);
117 }
118
119 /* c = a - b */
120 void fp_sub(fp_int *a, fp_int *b, fp_int *c)
121 {
122   int     sa, sb;
123
124   sa = a->sign;
125   sb = b->sign;
126
127   if (sa != sb) {
128     /* subtract a negative from a positive, OR */
129     /* subtract a positive from a negative. */
130     /* In either case, ADD their magnitudes, */
131     /* and use the sign of the first number. */
132     c->sign = sa;
133     s_fp_add (a, b, c);
134   } else {
135     /* subtract a positive from a positive, OR */
136     /* subtract a negative from a negative. */
137     /* First, take the difference between their */
138     /* magnitudes, then... */
139     if (fp_cmp_mag (a, b) != FP_LT) {
140       /* Copy the sign from the first */
141       c->sign = sa;
142       /* The first has a larger or equal magnitude */
143       s_fp_sub (a, b, c);
144     } else {
145       /* The result has the *opposite* sign from */
146       /* the first number. */
147       c->sign = (sa == FP_ZPOS) ? FP_NEG : FP_ZPOS;
148       /* The second has a larger magnitude */
149       s_fp_sub (b, a, c);
150     }
151   }
152 }
153
154 /* unsigned subtraction ||a|| >= ||b|| ALWAYS! */
155 void s_fp_sub(fp_int *a, fp_int *b, fp_int *c)
156 {
157   int      x, oldbused, oldused;
158   fp_word  t;
159
160   oldused  = c->used;
161   oldbused = b->used;
162   c->used  = a->used;
163   t       = 0;
164   for (x = 0; x < oldbused; x++) {
165      t         = ((fp_word)a->dp[x]) - (((fp_word)b->dp[x]) + t);
166      c->dp[x]  = (fp_digit)t;
167      t         = (t >> DIGIT_BIT)&1;
168   }
169   for (; x < a->used; x++) {
170      t         = ((fp_word)a->dp[x]) - t;
171      c->dp[x]  = (fp_digit)t;
172      t         = (t >> DIGIT_BIT)&1;
173    }
174   for (; x < oldused; x++) {
175      c->dp[x] = 0;
176   }
177   fp_clamp(c);
178 }
179
180 /* c = a * b */
181 void fp_mul(fp_int *A, fp_int *B, fp_int *C)
182 {
183     int   y, yy;
184
185     y  = MAX(A->used, B->used);
186     yy = MIN(A->used, B->used);
187
188     /* call generic if we're out of range */
189     if (y + yy > FP_SIZE) {
190        fp_mul_comba(A, B, C);
191        return ;
192     }
193
194     /* pick a comba (unrolled 4/8/16/32 x or rolled) based on the size
195        of the largest input.  We also want to avoid doing excess mults if the 
196        inputs are not close to the next power of two.  That is, for example,
197        if say y=17 then we would do (32-17)^2 = 225 unneeded multiplications 
198     */
199
200 #ifdef TFM_MUL3
201         if (y <= 3) {
202            fp_mul_comba3(A,B,C);
203            return;
204         }
205 #endif
206 #ifdef TFM_MUL4
207         if (y == 4) {
208            fp_mul_comba4(A,B,C);
209            return;
210         }
211 #endif
212 #ifdef TFM_MUL6
213         if (y <= 6) {
214            fp_mul_comba6(A,B,C);
215            return;
216         }
217 #endif
218 #ifdef TFM_MUL7
219         if (y == 7) {
220            fp_mul_comba7(A,B,C);
221            return;
222         }
223 #endif
224 #ifdef TFM_MUL8
225         if (y == 8) {
226            fp_mul_comba8(A,B,C);
227            return;
228         }
229 #endif
230 #ifdef TFM_MUL9
231         if (y == 9) {
232            fp_mul_comba9(A,B,C);
233            return;
234         }
235 #endif
236 #ifdef TFM_MUL12
237         if (y <= 12) {
238            fp_mul_comba12(A,B,C);
239            return;
240         }
241 #endif
242 #ifdef TFM_MUL17
243         if (y <= 17) {
244            fp_mul_comba17(A,B,C);
245            return;
246         }
247 #endif
248
249 #ifdef TFM_SMALL_SET
250         if (y <= 16) {
251            fp_mul_comba_small(A,B,C);
252            return;
253         }
254 #endif        
255 #if defined(TFM_MUL20)
256         if (y <= 20) {
257            fp_mul_comba20(A,B,C);
258            return;
259         }
260 #endif
261 #if defined(TFM_MUL24)
262         if (yy >= 16 && y <= 24) {
263            fp_mul_comba24(A,B,C);
264            return;
265         }
266 #endif
267 #if defined(TFM_MUL28)
268         if (yy >= 20 && y <= 28) {
269            fp_mul_comba28(A,B,C);
270            return;
271         }
272 #endif
273 #if defined(TFM_MUL32)
274         if (yy >= 24 && y <= 32) {
275            fp_mul_comba32(A,B,C);
276            return;
277         }
278 #endif
279 #if defined(TFM_MUL48)
280         if (yy >= 40 && y <= 48) {
281            fp_mul_comba48(A,B,C);
282            return;
283         }
284 #endif        
285 #if defined(TFM_MUL64)
286         if (yy >= 56 && y <= 64) {
287            fp_mul_comba64(A,B,C);
288            return;
289         }
290 #endif
291         fp_mul_comba(A,B,C);
292 }
293
294 void fp_mul_2(fp_int * a, fp_int * b)
295 {
296   int     x, oldused;
297    
298   oldused = b->used;
299   b->used = a->used;
300
301   {
302     register fp_digit r, rr, *tmpa, *tmpb;
303
304     /* alias for source */
305     tmpa = a->dp;
306     
307     /* alias for dest */
308     tmpb = b->dp;
309
310     /* carry */
311     r = 0;
312     for (x = 0; x < a->used; x++) {
313     
314       /* get what will be the *next* carry bit from the 
315        * MSB of the current digit 
316        */
317       rr = *tmpa >> ((fp_digit)(DIGIT_BIT - 1));
318       
319       /* now shift up this digit, add in the carry [from the previous] */
320       *tmpb++ = ((*tmpa++ << ((fp_digit)1)) | r);
321       
322       /* copy the carry that would be from the source 
323        * digit into the next iteration 
324        */
325       r = rr;
326     }
327
328     /* new leading digit? */
329     if (r != 0 && b->used != (FP_SIZE-1)) {
330       /* add a MSB which is always 1 at this point */
331       *tmpb = 1;
332       ++(b->used);
333     }
334
335     /* now zero any excess digits on the destination 
336      * that we didn't write to 
337      */
338     tmpb = b->dp + b->used;
339     for (x = b->used; x < oldused; x++) {
340       *tmpb++ = 0;
341     }
342   }
343   b->sign = a->sign;
344 }
345
346 /* c = a * b */
347 void fp_mul_d(fp_int *a, fp_digit b, fp_int *c)
348 {
349    fp_word  w;
350    int      x, oldused;
351
352    oldused = c->used;
353    c->used = a->used;
354    c->sign = a->sign;
355    w       = 0;
356    for (x = 0; x < a->used; x++) {
357        w         = ((fp_word)a->dp[x]) * ((fp_word)b) + w;
358        c->dp[x]  = (fp_digit)w;
359        w         = w >> DIGIT_BIT;
360    }
361    if (w != 0 && (a->used != FP_SIZE)) {
362       c->dp[c->used++] = (fp_digit) w;
363       ++x;
364    }
365    for (; x < oldused; x++) {
366       c->dp[x] = 0;
367    }
368    fp_clamp(c);
369 }
370
371 /* c = a * 2**d */
372 void fp_mul_2d(fp_int *a, int b, fp_int *c)
373 {
374    fp_digit carry, carrytmp, shift;
375    int x;
376
377    /* copy it */
378    fp_copy(a, c);
379
380    /* handle whole digits */
381    if (b >= DIGIT_BIT) {
382       fp_lshd(c, b/DIGIT_BIT);
383    }
384    b %= DIGIT_BIT;
385
386    /* shift the digits */
387    if (b != 0) {
388       carry = 0;   
389       shift = DIGIT_BIT - b;
390       for (x = 0; x < c->used; x++) {
391           carrytmp = c->dp[x] >> shift;
392           c->dp[x] = (c->dp[x] << b) + carry;
393           carry = carrytmp;
394       }
395       /* store last carry if room */
396       if (carry && x < FP_SIZE) {
397          c->dp[c->used++] = carry;
398       }
399    }
400    fp_clamp(c);
401 }
402
403 /* generic PxQ multiplier */
404 void fp_mul_comba(fp_int *A, fp_int *B, fp_int *C)
405 {
406    int       ix, iy, iz, tx, ty, pa;
407    fp_digit  c0, c1, c2, *tmpx, *tmpy;
408    fp_int    tmp, *dst;
409
410    COMBA_START;
411    COMBA_CLEAR;
412    
413    /* get size of output and trim */
414    pa = A->used + B->used;
415    if (pa >= FP_SIZE) {
416       pa = FP_SIZE-1;
417    }
418
419    if (A == C || B == C) {
420       fp_zero(&tmp);
421       dst = &tmp;
422    } else {
423       fp_zero(C);
424       dst = C;
425    }
426
427    for (ix = 0; ix < pa; ix++) {
428       /* get offsets into the two bignums */
429       ty = MIN(ix, B->used-1);
430       tx = ix - ty;
431
432       /* setup temp aliases */
433       tmpx = A->dp + tx;
434       tmpy = B->dp + ty;
435
436       /* this is the number of times the loop will iterrate, essentially its 
437          while (tx++ < a->used && ty-- >= 0) { ... }
438        */
439       iy = MIN(A->used-tx, ty+1);
440
441       /* execute loop */
442       COMBA_FORWARD;
443       for (iz = 0; iz < iy; ++iz) {
444           /* TAO change COMBA_ADD back to MULADD */
445           MULADD(*tmpx++, *tmpy--);
446       }
447
448       /* store term */
449       COMBA_STORE(dst->dp[ix]);
450   }
451   COMBA_FINI;
452
453   dst->used = pa;
454   dst->sign = A->sign ^ B->sign;
455   fp_clamp(dst);
456   fp_copy(dst, C);
457 }
458
459 /* a/b => cb + d == a */
460 int fp_div(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
461 {
462   fp_int  q, x, y, t1, t2;
463   int     n, t, i, norm, neg;
464
465   /* is divisor zero ? */
466   if (fp_iszero (b) == 1) {
467     return FP_VAL;
468   }
469
470   /* if a < b then q=0, r = a */
471   if (fp_cmp_mag (a, b) == FP_LT) {
472     if (d != NULL) {
473       fp_copy (a, d);
474     } 
475     if (c != NULL) {
476       fp_zero (c);
477     }
478     return FP_OKAY;
479   }
480
481   fp_init(&q);
482   q.used = a->used + 2;
483
484   fp_init(&t1);
485   fp_init(&t2);
486   fp_init_copy(&x, a);
487   fp_init_copy(&y, b);
488
489   /* fix the sign */
490   neg = (a->sign == b->sign) ? FP_ZPOS : FP_NEG;
491   x.sign = y.sign = FP_ZPOS;
492
493   /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
494   norm = fp_count_bits(&y) % DIGIT_BIT;
495   if (norm < (int)(DIGIT_BIT-1)) {
496      norm = (DIGIT_BIT-1) - norm;
497      fp_mul_2d (&x, norm, &x);
498      fp_mul_2d (&y, norm, &y);
499   } else {
500      norm = 0;
501   }
502
503   /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
504   n = x.used - 1;
505   t = y.used - 1;
506
507   /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
508   fp_lshd (&y, n - t);                                             /* y = y*b**{n-t} */
509
510   while (fp_cmp (&x, &y) != FP_LT) {
511     ++(q.dp[n - t]);
512     fp_sub (&x, &y, &x);
513   }
514
515   /* reset y by shifting it back down */
516   fp_rshd (&y, n - t);
517
518   /* step 3. for i from n down to (t + 1) */
519   for (i = n; i >= (t + 1); i--) {
520     if (i > x.used) {
521       continue;
522     }
523
524     /* step 3.1 if xi == yt then set q{i-t-1} to b-1, 
525      * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
526     if (x.dp[i] == y.dp[t]) {
527       q.dp[i - t - 1] = (fp_digit) ((((fp_word)1) << DIGIT_BIT) - 1);
528     } else {
529       fp_word tmp;
530       tmp = ((fp_word) x.dp[i]) << ((fp_word) DIGIT_BIT);
531       tmp |= ((fp_word) x.dp[i - 1]);
532       tmp /= ((fp_word)y.dp[t]);
533       q.dp[i - t - 1] = (fp_digit) (tmp);
534     }
535
536     /* while (q{i-t-1} * (yt * b + y{t-1})) > 
537              xi * b**2 + xi-1 * b + xi-2 
538      
539        do q{i-t-1} -= 1; 
540     */
541     q.dp[i - t - 1] = (q.dp[i - t - 1] + 1);
542     do {
543       q.dp[i - t - 1] = (q.dp[i - t - 1] - 1);
544
545       /* find left hand */
546       fp_zero (&t1);
547       t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
548       t1.dp[1] = y.dp[t];
549       t1.used = 2;
550       fp_mul_d (&t1, q.dp[i - t - 1], &t1);
551
552       /* find right hand */
553       t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
554       t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
555       t2.dp[2] = x.dp[i];
556       t2.used = 3;
557     } while (fp_cmp_mag(&t1, &t2) == FP_GT);
558
559     /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
560     fp_mul_d (&y, q.dp[i - t - 1], &t1);
561     fp_lshd  (&t1, i - t - 1);
562     fp_sub   (&x, &t1, &x);
563
564     /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
565     if (x.sign == FP_NEG) {
566       fp_copy (&y, &t1);
567       fp_lshd (&t1, i - t - 1);
568       fp_add (&x, &t1, &x);
569       q.dp[i - t - 1] = q.dp[i - t - 1] - 1;
570     }
571   }
572
573   /* now q is the quotient and x is the remainder 
574    * [which we have to normalize] 
575    */
576   
577   /* get sign before writing to c */
578   x.sign = x.used == 0 ? FP_ZPOS : a->sign;
579
580   if (c != NULL) {
581     fp_clamp (&q);
582     fp_copy (&q, c);
583     c->sign = neg;
584   }
585
586   if (d != NULL) {
587     fp_div_2d (&x, norm, &x, NULL);
588
589 /* the following is a kludge, essentially we were seeing the right remainder but 
590    with excess digits that should have been zero
591  */
592     for (i = b->used; i < x.used; i++) {
593         x.dp[i] = 0;
594     }
595     fp_clamp(&x);
596     fp_copy (&x, d);
597   }
598
599   return FP_OKAY;
600 }
601
602 /* b = a/2 */
603 void fp_div_2(fp_int * a, fp_int * b)
604 {
605   int     x, oldused;
606
607   oldused = b->used;
608   b->used = a->used;
609   {
610     register fp_digit r, rr, *tmpa, *tmpb;
611
612     /* source alias */
613     tmpa = a->dp + b->used - 1;
614
615     /* dest alias */
616     tmpb = b->dp + b->used - 1;
617
618     /* carry */
619     r = 0;
620     for (x = b->used - 1; x >= 0; x--) {
621       /* get the carry for the next iteration */
622       rr = *tmpa & 1;
623
624       /* shift the current digit, add in carry and store */
625       *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
626
627       /* forward carry to next iteration */
628       r = rr;
629     }
630
631     /* zero excess digits */
632     tmpb = b->dp + b->used;
633     for (x = b->used; x < oldused; x++) {
634       *tmpb++ = 0;
635     }
636   }
637   b->sign = a->sign;
638   fp_clamp (b);
639 }
640
641 /* c = a / 2**b */
642 void fp_div_2d(fp_int *a, int b, fp_int *c, fp_int *d)
643 {
644   int      D;
645   fp_int   t;
646
647   /* if the shift count is <= 0 then we do no work */
648   if (b <= 0) {
649     fp_copy (a, c);
650     if (d != NULL) {
651       fp_zero (d);
652     }
653     return;
654   }
655
656   fp_init(&t);
657
658   /* get the remainder */
659   if (d != NULL) {
660     fp_mod_2d (a, b, &t);
661   }
662
663   /* copy */
664   fp_copy(a, c);
665
666   /* shift by as many digits in the bit count */
667   if (b >= (int)DIGIT_BIT) {
668     fp_rshd (c, b / DIGIT_BIT);
669   }
670
671   /* shift any bit count < DIGIT_BIT */
672   D = (b % DIGIT_BIT);
673   if (D != 0) {
674     fp_rshb(c, D);
675   }
676   fp_clamp (c);
677   if (d != NULL) {
678     fp_copy (&t, d);
679   }
680 }
681
682 /* c = a mod b, 0 <= c < b  */
683 int fp_mod(fp_int *a, fp_int *b, fp_int *c)
684 {
685    fp_int t;
686    int    err;
687
688    fp_zero(&t);
689    if ((err = fp_div(a, b, NULL, &t)) != FP_OKAY) {
690       return err;
691    }
692    if (t.sign != b->sign) {
693       fp_add(&t, b, c);
694    } else {
695       fp_copy(&t, c);
696   }
697   return FP_OKAY;
698 }
699
700 /* c = a mod 2**d */
701 void fp_mod_2d(fp_int *a, int b, fp_int *c)
702 {
703    int x;
704
705    /* zero if count less than or equal to zero */
706    if (b <= 0) {
707       fp_zero(c);
708       return;
709    }
710
711    /* get copy of input */
712    fp_copy(a, c);
713  
714    /* if 2**d is larger than we just return */
715    if (b >= (DIGIT_BIT * a->used)) {
716       return;
717    }
718
719   /* zero digits above the last digit of the modulus */
720   for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
721     c->dp[x] = 0;
722   }
723   /* clear the digit that is not completely outside/inside the modulus */
724   c->dp[b / DIGIT_BIT] &= ~((fp_digit)0) >> (DIGIT_BIT - b);
725   fp_clamp (c);
726 }
727
728 static int fp_invmod_slow (fp_int * a, fp_int * b, fp_int * c)
729 {
730   fp_int  x, y, u, v, A, B, C, D;
731   int     res;
732
733   /* b cannot be negative */
734   if (b->sign == FP_NEG || fp_iszero(b) == 1) {
735     return FP_VAL;
736   }
737
738   /* init temps */
739   fp_init(&x);    fp_init(&y);
740   fp_init(&u);    fp_init(&v);
741   fp_init(&A);    fp_init(&B);
742   fp_init(&C);    fp_init(&D);
743
744   /* x = a, y = b */
745   if ((res = fp_mod(a, b, &x)) != FP_OKAY) {
746       return res;
747   }
748   fp_copy(b, &y);
749
750   /* 2. [modified] if x,y are both even then return an error! */
751   if (fp_iseven (&x) == 1 && fp_iseven (&y) == 1) {
752     return FP_VAL;
753   }
754
755   /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
756   fp_copy (&x, &u);
757   fp_copy (&y, &v);
758   fp_set (&A, 1);
759   fp_set (&D, 1);
760
761 top:
762   /* 4.  while u is even do */
763   while (fp_iseven (&u) == 1) {
764     /* 4.1 u = u/2 */
765     fp_div_2 (&u, &u);
766
767     /* 4.2 if A or B is odd then */
768     if (fp_isodd (&A) == 1 || fp_isodd (&B) == 1) {
769       /* A = (A+y)/2, B = (B-x)/2 */
770       fp_add (&A, &y, &A);
771       fp_sub (&B, &x, &B);
772     }
773     /* A = A/2, B = B/2 */
774     fp_div_2 (&A, &A);
775     fp_div_2 (&B, &B);
776   }
777
778   /* 5.  while v is even do */
779   while (fp_iseven (&v) == 1) {
780     /* 5.1 v = v/2 */
781     fp_div_2 (&v, &v);
782
783     /* 5.2 if C or D is odd then */
784     if (fp_isodd (&C) == 1 || fp_isodd (&D) == 1) {
785       /* C = (C+y)/2, D = (D-x)/2 */
786       fp_add (&C, &y, &C);
787       fp_sub (&D, &x, &D);
788     }
789     /* C = C/2, D = D/2 */
790     fp_div_2 (&C, &C);
791     fp_div_2 (&D, &D);
792   }
793
794   /* 6.  if u >= v then */
795   if (fp_cmp (&u, &v) != FP_LT) {
796     /* u = u - v, A = A - C, B = B - D */
797     fp_sub (&u, &v, &u);
798     fp_sub (&A, &C, &A);
799     fp_sub (&B, &D, &B);
800   } else {
801     /* v - v - u, C = C - A, D = D - B */
802     fp_sub (&v, &u, &v);
803     fp_sub (&C, &A, &C);
804     fp_sub (&D, &B, &D);
805   }
806
807   /* if not zero goto step 4 */
808   if (fp_iszero (&u) == 0)
809     goto top;
810
811   /* now a = C, b = D, gcd == g*v */
812
813   /* if v != 1 then there is no inverse */
814   if (fp_cmp_d (&v, 1) != FP_EQ) {
815     return FP_VAL;
816   }
817
818   /* if its too low */
819   while (fp_cmp_d(&C, 0) == FP_LT) {
820       fp_add(&C, b, &C);
821   }
822   
823   /* too big */
824   while (fp_cmp_mag(&C, b) != FP_LT) {
825       fp_sub(&C, b, &C);
826   }
827   
828   /* C is now the inverse */
829   fp_copy(&C, c);
830   return FP_OKAY;
831 }
832
833 /* c = 1/a (mod b) for odd b only */
834 int fp_invmod(fp_int *a, fp_int *b, fp_int *c)
835 {
836   fp_int  x, y, u, v, B, D;
837   int     neg;
838
839   /* 2. [modified] b must be odd   */
840   if (fp_iseven (b) == FP_YES) {
841     return fp_invmod_slow(a,b,c);
842   }
843
844   /* init all our temps */
845   fp_init(&x);  fp_init(&y);
846   fp_init(&u);  fp_init(&v);
847   fp_init(&B);  fp_init(&D);
848
849   /* x == modulus, y == value to invert */
850   fp_copy(b, &x);
851
852   /* we need y = |a| */
853   fp_abs(a, &y);
854
855   /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
856   fp_copy(&x, &u);
857   fp_copy(&y, &v);
858   fp_set (&D, 1);
859
860 top:
861   /* 4.  while u is even do */
862   while (fp_iseven (&u) == FP_YES) {
863     /* 4.1 u = u/2 */
864     fp_div_2 (&u, &u);
865
866     /* 4.2 if B is odd then */
867     if (fp_isodd (&B) == FP_YES) {
868       fp_sub (&B, &x, &B);
869     }
870     /* B = B/2 */
871     fp_div_2 (&B, &B);
872   }
873
874   /* 5.  while v is even do */
875   while (fp_iseven (&v) == FP_YES) {
876     /* 5.1 v = v/2 */
877     fp_div_2 (&v, &v);
878
879     /* 5.2 if D is odd then */
880     if (fp_isodd (&D) == FP_YES) {
881       /* D = (D-x)/2 */
882       fp_sub (&D, &x, &D);
883     }
884     /* D = D/2 */
885     fp_div_2 (&D, &D);
886   }
887
888   /* 6.  if u >= v then */
889   if (fp_cmp (&u, &v) != FP_LT) {
890     /* u = u - v, B = B - D */
891     fp_sub (&u, &v, &u);
892     fp_sub (&B, &D, &B);
893   } else {
894     /* v - v - u, D = D - B */
895     fp_sub (&v, &u, &v);
896     fp_sub (&D, &B, &D);
897   }
898
899   /* if not zero goto step 4 */
900   if (fp_iszero (&u) == FP_NO) {
901     goto top;
902   }
903
904   /* now a = C, b = D, gcd == g*v */
905
906   /* if v != 1 then there is no inverse */
907   if (fp_cmp_d (&v, 1) != FP_EQ) {
908     return FP_VAL;
909   }
910
911   /* b is now the inverse */
912   neg = a->sign;
913   while (D.sign == FP_NEG) {
914     fp_add (&D, b, &D);
915   }
916   fp_copy (&D, c);
917   c->sign = neg;
918   return FP_OKAY;
919 }
920
921 /* d = a * b (mod c) */
922 int fp_mulmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d)
923 {
924   fp_int tmp;
925   fp_zero(&tmp);
926   fp_mul(a, b, &tmp);
927   return fp_mod(&tmp, c, d);
928 }
929
930 #ifdef TFM_TIMING_RESISTANT
931
932 /* timing resistant montgomery ladder based exptmod 
933
934    Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002
935 */
936 static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
937 {
938   fp_int   R[2];
939   fp_digit buf, mp;
940   int      err, bitcnt, digidx, y;
941
942   /* now setup montgomery  */
943   if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
944      return err;
945   }
946
947   fp_init(&R[0]);   
948   fp_init(&R[1]);   
949    
950   /* now we need R mod m */
951   fp_montgomery_calc_normalization (&R[0], P);
952
953   /* now set R[0][1] to G * R mod m */
954   if (fp_cmp_mag(P, G) != FP_GT) {
955      /* G > P so we reduce it first */
956      fp_mod(G, P, &R[1]);
957   } else {
958      fp_copy(G, &R[1]);
959   }
960   fp_mulmod (&R[1], &R[0], P, &R[1]);
961
962   /* for j = t-1 downto 0 do
963         r_!k = R0*R1; r_k = r_k^2
964   */
965   
966   /* set initial mode and bit cnt */
967   bitcnt = 1;
968   buf    = 0;
969   digidx = X->used - 1;
970
971   for (;;) {
972     /* grab next digit as required */
973     if (--bitcnt == 0) {
974       /* if digidx == -1 we are out of digits so break */
975       if (digidx == -1) {
976         break;
977       }
978       /* read next digit and reset bitcnt */
979       buf    = X->dp[digidx--];
980       bitcnt = (int)DIGIT_BIT;
981     }
982
983     /* grab the next msb from the exponent */
984     y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
985     buf <<= (fp_digit)1;
986
987     /* do ops */
988     fp_mul(&R[0], &R[1], &R[y^1]); fp_montgomery_reduce(&R[y^1], P, mp);
989     fp_sqr(&R[y], &R[y]);          fp_montgomery_reduce(&R[y], P, mp);
990   }
991
992    fp_montgomery_reduce(&R[0], P, mp);
993    fp_copy(&R[0], Y);
994    return FP_OKAY;
995 }   
996
997 #else
998
999 /* y = g**x (mod b) 
1000  * Some restrictions... x must be positive and < b
1001  */
1002 static int _fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
1003 {
1004   fp_int   M[64], res;
1005   fp_digit buf, mp;
1006   int      err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
1007
1008   /* find window size */
1009   x = fp_count_bits (X);
1010   if (x <= 21) {
1011     winsize = 1;
1012   } else if (x <= 36) {
1013     winsize = 3;
1014   } else if (x <= 140) {
1015     winsize = 4;
1016   } else if (x <= 450) {
1017     winsize = 5;
1018   } else {
1019     winsize = 6;
1020   } 
1021
1022   /* init M array */
1023   XMEMSET(M, 0, sizeof(M)); 
1024
1025   /* now setup montgomery  */
1026   if ((err = fp_montgomery_setup (P, &mp)) != FP_OKAY) {
1027      return err;
1028   }
1029
1030   /* setup result */
1031   fp_init(&res);
1032
1033   /* create M table
1034    *
1035    * The M table contains powers of the input base, e.g. M[x] = G^x mod P
1036    *
1037    * The first half of the table is not computed though accept for M[0] and M[1]
1038    */
1039
1040    /* now we need R mod m */
1041    fp_montgomery_calc_normalization (&res, P);
1042
1043    /* now set M[1] to G * R mod m */
1044    if (fp_cmp_mag(P, G) != FP_GT) {
1045       /* G > P so we reduce it first */
1046       fp_mod(G, P, &M[1]);
1047    } else {
1048       fp_copy(G, &M[1]);
1049    }
1050    fp_mulmod (&M[1], &res, P, &M[1]);
1051
1052   /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
1053   fp_copy (&M[1], &M[1 << (winsize - 1)]);
1054   for (x = 0; x < (winsize - 1); x++) {
1055     fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]);
1056     fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp);
1057   }
1058
1059   /* create upper table */
1060   for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
1061     fp_mul(&M[x - 1], &M[1], &M[x]);
1062     fp_montgomery_reduce(&M[x], P, mp);
1063   }
1064
1065   /* set initial mode and bit cnt */
1066   mode   = 0;
1067   bitcnt = 1;
1068   buf    = 0;
1069   digidx = X->used - 1;
1070   bitcpy = 0;
1071   bitbuf = 0;
1072
1073   for (;;) {
1074     /* grab next digit as required */
1075     if (--bitcnt == 0) {
1076       /* if digidx == -1 we are out of digits so break */
1077       if (digidx == -1) {
1078         break;
1079       }
1080       /* read next digit and reset bitcnt */
1081       buf    = X->dp[digidx--];
1082       bitcnt = (int)DIGIT_BIT;
1083     }
1084
1085     /* grab the next msb from the exponent */
1086     y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
1087     buf <<= (fp_digit)1;
1088
1089     /* if the bit is zero and mode == 0 then we ignore it
1090      * These represent the leading zero bits before the first 1 bit
1091      * in the exponent.  Technically this opt is not required but it
1092      * does lower the # of trivial squaring/reductions used
1093      */
1094     if (mode == 0 && y == 0) {
1095       continue;
1096     }
1097
1098     /* if the bit is zero and mode == 1 then we square */
1099     if (mode == 1 && y == 0) {
1100       fp_sqr(&res, &res);
1101       fp_montgomery_reduce(&res, P, mp);
1102       continue;
1103     }
1104
1105     /* else we add it to the window */
1106     bitbuf |= (y << (winsize - ++bitcpy));
1107     mode    = 2;
1108
1109     if (bitcpy == winsize) {
1110       /* ok window is filled so square as required and multiply  */
1111       /* square first */
1112       for (x = 0; x < winsize; x++) {
1113         fp_sqr(&res, &res);
1114         fp_montgomery_reduce(&res, P, mp);
1115       }
1116
1117       /* then multiply */
1118       fp_mul(&res, &M[bitbuf], &res);
1119       fp_montgomery_reduce(&res, P, mp);
1120
1121       /* empty window and reset */
1122       bitcpy = 0;
1123       bitbuf = 0;
1124       mode   = 1;
1125     }
1126   }
1127
1128   /* if bits remain then square/multiply */
1129   if (mode == 2 && bitcpy > 0) {
1130     /* square then multiply if the bit is set */
1131     for (x = 0; x < bitcpy; x++) {
1132       fp_sqr(&res, &res);
1133       fp_montgomery_reduce(&res, P, mp);
1134
1135       /* get next bit of the window */
1136       bitbuf <<= 1;
1137       if ((bitbuf & (1 << winsize)) != 0) {
1138         /* then multiply */
1139         fp_mul(&res, &M[1], &res);
1140         fp_montgomery_reduce(&res, P, mp);
1141       }
1142     }
1143   }
1144
1145   /* fixup result if Montgomery reduction is used
1146    * recall that any value in a Montgomery system is
1147    * actually multiplied by R mod n.  So we have
1148    * to reduce one more time to cancel out the factor
1149    * of R.
1150    */
1151   fp_montgomery_reduce(&res, P, mp);
1152
1153   /* swap res with Y */
1154   fp_copy (&res, Y);
1155   return FP_OKAY;
1156 }
1157
1158 #endif
1159
1160 int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y)
1161 {
1162    /* prevent overflows */
1163    if (P->used > (FP_SIZE/2)) {
1164       return FP_VAL;
1165    }
1166
1167    if (X->sign == FP_NEG) {
1168 #ifndef POSITIVE_EXP_ONLY  /* reduce stack if assume no negatives */
1169       int    err;
1170       fp_int tmp;
1171
1172       /* yes, copy G and invmod it */
1173       fp_copy(G, &tmp);
1174       if ((err = fp_invmod(&tmp, P, &tmp)) != FP_OKAY) {
1175          return err;
1176       }
1177       X->sign = FP_ZPOS;
1178       err =  _fp_exptmod(&tmp, X, P, Y);
1179       if (X != Y) {
1180          X->sign = FP_NEG;
1181       }
1182       return err;
1183 #else
1184       return FP_VAL;
1185 #endif 
1186    }
1187    else {
1188       /* Positive exponent so just exptmod */
1189       return _fp_exptmod(G, X, P, Y);
1190    }
1191 }
1192
1193 /* computes a = 2**b */
1194 void fp_2expt(fp_int *a, int b)
1195 {
1196    int     z;
1197
1198    /* zero a as per default */
1199    fp_zero (a);
1200
1201    if (b < 0) { 
1202       return;
1203    }
1204
1205    z = b / DIGIT_BIT;
1206    if (z >= FP_SIZE) {
1207       return; 
1208    }
1209
1210   /* set the used count of where the bit will go */
1211   a->used = z + 1;
1212
1213   /* put the single bit in its place */
1214   a->dp[z] = ((fp_digit)1) << (b % DIGIT_BIT);
1215 }
1216
1217 /* b = a*a  */
1218 void fp_sqr(fp_int *A, fp_int *B)
1219 {
1220     int y = A->used;
1221
1222     /* call generic if we're out of range */
1223     if (y + y > FP_SIZE) {
1224        fp_sqr_comba(A, B);
1225        return ;
1226     }
1227
1228 #if defined(TFM_SQR3)
1229         if (y <= 3) {
1230            fp_sqr_comba3(A,B);
1231            return;
1232         }
1233 #endif
1234 #if defined(TFM_SQR4)
1235         if (y == 4) {
1236            fp_sqr_comba4(A,B);
1237            return;
1238         }
1239 #endif
1240 #if defined(TFM_SQR6)
1241         if (y <= 6) {
1242            fp_sqr_comba6(A,B);
1243            return;
1244         }
1245 #endif
1246 #if defined(TFM_SQR7)
1247         if (y == 7) {
1248            fp_sqr_comba7(A,B);
1249            return;
1250         }
1251 #endif
1252 #if defined(TFM_SQR8)
1253         if (y == 8) {
1254            fp_sqr_comba8(A,B);
1255            return;
1256         }
1257 #endif
1258 #if defined(TFM_SQR9)
1259         if (y == 9) {
1260            fp_sqr_comba9(A,B);
1261            return;
1262         }
1263 #endif
1264 #if defined(TFM_SQR12)
1265         if (y <= 12) {
1266            fp_sqr_comba12(A,B);
1267            return;
1268         }
1269 #endif
1270 #if defined(TFM_SQR17)
1271         if (y <= 17) {
1272            fp_sqr_comba17(A,B);
1273            return;
1274         }
1275 #endif
1276 #if defined(TFM_SMALL_SET)
1277         if (y <= 16) {
1278            fp_sqr_comba_small(A,B);
1279            return;
1280         }
1281 #endif
1282 #if defined(TFM_SQR20)
1283         if (y <= 20) {
1284            fp_sqr_comba20(A,B);
1285            return;
1286         }
1287 #endif
1288 #if defined(TFM_SQR24)
1289         if (y <= 24) {
1290            fp_sqr_comba24(A,B);
1291            return;
1292         }
1293 #endif
1294 #if defined(TFM_SQR28)
1295         if (y <= 28) {
1296            fp_sqr_comba28(A,B);
1297            return;
1298         }
1299 #endif
1300 #if defined(TFM_SQR32)
1301         if (y <= 32) {
1302            fp_sqr_comba32(A,B);
1303            return;
1304         }
1305 #endif
1306 #if defined(TFM_SQR48)
1307         if (y <= 48) {
1308            fp_sqr_comba48(A,B);
1309            return;
1310         }
1311 #endif
1312 #if defined(TFM_SQR64)
1313         if (y <= 64) {
1314            fp_sqr_comba64(A,B);
1315            return;
1316         }
1317 #endif
1318        fp_sqr_comba(A, B);
1319 }
1320
1321 /* generic comba squarer */
1322 void fp_sqr_comba(fp_int *A, fp_int *B)
1323 {
1324   int       pa, ix, iz;
1325   fp_digit  c0, c1, c2;
1326   fp_int    tmp, *dst;
1327 #ifdef TFM_ISO
1328   fp_word   tt;
1329 #endif    
1330
1331   /* get size of output and trim */
1332   pa = A->used + A->used;
1333   if (pa >= FP_SIZE) {
1334      pa = FP_SIZE-1;
1335   }
1336
1337   /* number of output digits to produce */
1338   COMBA_START;
1339   COMBA_CLEAR;
1340
1341   if (A == B) {
1342      fp_zero(&tmp);
1343      dst = &tmp;
1344   } else {
1345      fp_zero(B);
1346      dst = B;
1347   }
1348
1349   for (ix = 0; ix < pa; ix++) { 
1350       int      tx, ty, iy;
1351       fp_digit *tmpy, *tmpx;
1352
1353       /* get offsets into the two bignums */
1354       ty = MIN(A->used-1, ix);
1355       tx = ix - ty;
1356
1357       /* setup temp aliases */
1358       tmpx = A->dp + tx;
1359       tmpy = A->dp + ty;
1360
1361       /* this is the number of times the loop will iterrate,
1362          while (tx++ < a->used && ty-- >= 0) { ... }
1363        */
1364       iy = MIN(A->used-tx, ty+1);
1365
1366       /* now for squaring tx can never equal ty 
1367        * we halve the distance since they approach 
1368        * at a rate of 2x and we have to round because 
1369        * odd cases need to be executed
1370        */
1371       iy = MIN(iy, (ty-tx+1)>>1);
1372
1373       /* forward carries */
1374       COMBA_FORWARD;
1375
1376       /* execute loop */
1377       for (iz = 0; iz < iy; iz++) {
1378           SQRADD2(*tmpx++, *tmpy--);
1379       }
1380
1381       /* even columns have the square term in them */
1382       if ((ix&1) == 0) {
1383           /* TAO change COMBA_ADD back to SQRADD */
1384           SQRADD(A->dp[ix>>1], A->dp[ix>>1]);
1385       }
1386
1387       /* store it */
1388       COMBA_STORE(dst->dp[ix]);
1389   }
1390
1391   COMBA_FINI;
1392
1393   /* setup dest */
1394   dst->used = pa;
1395   fp_clamp (dst);
1396   if (dst != B) {
1397      fp_copy(dst, B);
1398   }
1399 }
1400
1401 int fp_cmp(fp_int *a, fp_int *b)
1402 {
1403    if (a->sign == FP_NEG && b->sign == FP_ZPOS) {
1404       return FP_LT;
1405    } else if (a->sign == FP_ZPOS && b->sign == FP_NEG) {
1406       return FP_GT;
1407    } else {
1408       /* compare digits */
1409       if (a->sign == FP_NEG) {
1410          /* if negative compare opposite direction */
1411          return fp_cmp_mag(b, a);
1412       } else {
1413          return fp_cmp_mag(a, b);
1414       }
1415    }
1416 }
1417
1418 /* compare against a single digit */
1419 int fp_cmp_d(fp_int *a, fp_digit b)
1420 {
1421   /* compare based on sign */
1422   if ((b && a->used == 0) || a->sign == FP_NEG) {
1423     return FP_LT;
1424   }
1425
1426   /* compare based on magnitude */
1427   if (a->used > 1) {
1428     return FP_GT;
1429   }
1430
1431   /* compare the only digit of a to b */
1432   if (a->dp[0] > b) {
1433     return FP_GT;
1434   } else if (a->dp[0] < b) {
1435     return FP_LT;
1436   } else {
1437     return FP_EQ;
1438   }
1439
1440 }
1441
1442 int fp_cmp_mag(fp_int *a, fp_int *b)
1443 {
1444    int x;
1445
1446    if (a->used > b->used) {
1447       return FP_GT;
1448    } else if (a->used < b->used) {
1449       return FP_LT;
1450    } else {
1451       for (x = a->used - 1; x >= 0; x--) {
1452           if (a->dp[x] > b->dp[x]) {
1453              return FP_GT;
1454           } else if (a->dp[x] < b->dp[x]) {
1455              return FP_LT;
1456           }
1457       }
1458    }
1459    return FP_EQ;
1460 }
1461
1462 /* setups the montgomery reduction */
1463 int fp_montgomery_setup(fp_int *a, fp_digit *rho)
1464 {
1465   fp_digit x, b;
1466
1467 /* fast inversion mod 2**k
1468  *
1469  * Based on the fact that
1470  *
1471  * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
1472  *                    =>  2*X*A - X*X*A*A = 1
1473  *                    =>  2*(1) - (1)     = 1
1474  */
1475   b = a->dp[0];
1476
1477   if ((b & 1) == 0) {
1478     return FP_VAL;
1479   }
1480
1481   x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
1482   x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
1483   x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
1484   x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
1485 #ifdef FP_64BIT
1486   x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
1487 #endif
1488
1489   /* rho = -1/m mod b */
1490   *rho = (fp_digit) (((fp_word) 1 << ((fp_word) DIGIT_BIT)) - ((fp_word)x));
1491
1492   return FP_OKAY;
1493 }
1494
1495 /* computes a = B**n mod b without division or multiplication useful for
1496  * normalizing numbers in a Montgomery system.
1497  */
1498 void fp_montgomery_calc_normalization(fp_int *a, fp_int *b)
1499 {
1500   int     x, bits;
1501
1502   /* how many bits of last digit does b use */
1503   bits = fp_count_bits (b) % DIGIT_BIT;
1504   if (!bits) bits = DIGIT_BIT;
1505
1506   /* compute A = B^(n-1) * 2^(bits-1) */
1507   if (b->used > 1) {
1508      fp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1);
1509   } else {
1510      fp_set(a, 1);
1511      bits = 1;
1512   }
1513
1514   /* now compute C = A * B mod b */
1515   for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
1516     fp_mul_2 (a, a);
1517     if (fp_cmp_mag (a, b) != FP_LT) {
1518       s_fp_sub (a, b, a);
1519     }
1520   }
1521 }
1522
1523
1524 #ifdef TFM_SMALL_MONT_SET
1525     #include "fp_mont_small.i"
1526 #endif
1527
1528 /* computes x/R == x (mod N) via Montgomery Reduction */
1529 void fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)
1530 {
1531    fp_digit c[FP_SIZE], *_c, *tmpm, mu = 0;
1532    int      oldused, x, y, pa;
1533
1534    /* bail if too large */
1535    if (m->used > (FP_SIZE/2)) {
1536       (void)mu;                     /* shut up compiler */
1537       return;
1538    }
1539
1540 #ifdef TFM_SMALL_MONT_SET
1541    if (m->used <= 16) {
1542       fp_montgomery_reduce_small(a, m, mp);
1543       return;
1544    }
1545 #endif
1546
1547
1548    /* now zero the buff */
1549    XMEMSET(c, 0, sizeof c);
1550    pa = m->used;
1551
1552    /* copy the input */
1553    oldused = a->used;
1554    for (x = 0; x < oldused; x++) {
1555        c[x] = a->dp[x];
1556    }
1557    MONT_START;
1558
1559    for (x = 0; x < pa; x++) {
1560        fp_digit cy = 0;
1561        /* get Mu for this round */
1562        LOOP_START;
1563        _c   = c + x;
1564        tmpm = m->dp;
1565        y = 0;
1566        #if (defined(TFM_SSE2) || defined(TFM_X86_64))
1567         for (; y < (pa & ~7); y += 8) {
1568               INNERMUL8;
1569               _c   += 8;
1570               tmpm += 8;
1571            }
1572        #endif
1573
1574        for (; y < pa; y++) {
1575           INNERMUL;
1576           ++_c;
1577        }
1578        LOOP_END;
1579        while (cy) {
1580            PROPCARRY;
1581            ++_c;
1582        }
1583   }         
1584
1585   /* now copy out */
1586   _c   = c + pa;
1587   tmpm = a->dp;
1588   for (x = 0; x < pa+1; x++) {
1589      *tmpm++ = *_c++;
1590   }
1591
1592   for (; x < oldused; x++)   {
1593      *tmpm++ = 0;
1594   }
1595
1596   MONT_FINI;
1597
1598   a->used = pa+1;
1599   fp_clamp(a);
1600   
1601   /* if A >= m then A = A - m */
1602   if (fp_cmp_mag (a, m) != FP_LT) {
1603     s_fp_sub (a, m, a);
1604   }
1605 }
1606
1607 void fp_read_unsigned_bin(fp_int *a, unsigned char *b, int c)
1608 {
1609   /* zero the int */
1610   fp_zero (a);
1611
1612   /* If we know the endianness of this architecture, and we're using
1613      32-bit fp_digits, we can optimize this */
1614 #if (defined(LITTLE_ENDIAN_ORDER) || defined(BIG_ENDIAN_ORDER)) && !defined(FP_64BIT)
1615   /* But not for both simultaneously */
1616 #if defined(LITTLE_ENDIAN_ORDER) && defined(BIG_ENDIAN_ORDER)
1617 #error Both LITTLE_ENDIAN_ORDER and BIG_ENDIAN_ORDER defined.
1618 #endif
1619   {
1620      unsigned char *pd = (unsigned char *)a->dp;
1621
1622      if ((unsigned)c > (FP_SIZE * sizeof(fp_digit))) {
1623         int excess = c - (FP_SIZE * sizeof(fp_digit));
1624         c -= excess;
1625         b += excess;
1626      }
1627      a->used = (c + sizeof(fp_digit) - 1)/sizeof(fp_digit);
1628      /* read the bytes in */
1629 #ifdef BIG_ENDIAN_ORDER
1630      {
1631        /* Use Duff's device to unroll the loop. */
1632        int idx = (c - 1) & ~3;
1633        switch (c % 4) {
1634        case 0:  do { pd[idx+0] = *b++;
1635        case 3:       pd[idx+1] = *b++;
1636        case 2:       pd[idx+2] = *b++;
1637        case 1:       pd[idx+3] = *b++;
1638                      idx -= 4;
1639                         } while ((c -= 4) > 0);
1640        }
1641      }
1642 #else
1643      for (c -= 1; c >= 0; c -= 1) {
1644        pd[c] = *b++;
1645      }
1646 #endif
1647   }
1648 #else
1649   /* read the bytes in */
1650   for (; c > 0; c--) {
1651      fp_mul_2d (a, 8, a);
1652      a->dp[0] |= *b++;
1653      a->used += 1;
1654   }
1655 #endif
1656   fp_clamp (a);
1657 }
1658
1659 void fp_to_unsigned_bin(fp_int *a, unsigned char *b)
1660 {
1661   int     x;
1662   fp_int  t;
1663
1664   fp_init_copy(&t, a);
1665
1666   x = 0;
1667   while (fp_iszero (&t) == FP_NO) {
1668       b[x++] = (unsigned char) (t.dp[0] & 255);
1669       fp_div_2d (&t, 8, &t, NULL);
1670   }
1671   fp_reverse (b, x);
1672 }
1673
1674 int fp_unsigned_bin_size(fp_int *a)
1675 {
1676   int     size = fp_count_bits (a);
1677   return (size / 8 + ((size & 7) != 0 ? 1 : 0));
1678 }
1679
1680 void fp_set(fp_int *a, fp_digit b)
1681 {
1682    fp_zero(a);
1683    a->dp[0] = b;
1684    a->used  = a->dp[0] ? 1 : 0;
1685 }
1686
1687 int fp_count_bits (fp_int * a)
1688 {
1689   int     r;
1690   fp_digit q;
1691
1692   /* shortcut */
1693   if (a->used == 0) {
1694     return 0;
1695   }
1696
1697   /* get number of digits and add that */
1698   r = (a->used - 1) * DIGIT_BIT;
1699
1700   /* take the last digit and count the bits in it */
1701   q = a->dp[a->used - 1];
1702   while (q > ((fp_digit) 0)) {
1703     ++r;
1704     q >>= ((fp_digit) 1);
1705   }
1706   return r;
1707 }
1708
1709 int fp_leading_bit(fp_int *a)
1710 {
1711     int bit = 0;
1712
1713     if (a->used != 0) {
1714         fp_digit q = a->dp[a->used - 1];
1715         int qSz = sizeof(fp_digit);
1716
1717         while (qSz > 0) {
1718             if ((unsigned char)q != 0)
1719                 bit = (q & 0x80) != 0;
1720             q >>= 8;
1721             qSz--;
1722         }
1723     }
1724
1725     return bit;
1726 }
1727
1728 void fp_lshd(fp_int *a, int x)
1729 {
1730    int y;
1731
1732    /* move up and truncate as required */
1733    y = MIN(a->used + x - 1, (int)(FP_SIZE-1));
1734
1735    /* store new size */
1736    a->used = y + 1;
1737
1738    /* move digits */
1739    for (; y >= x; y--) {
1740        a->dp[y] = a->dp[y-x];
1741    }
1742  
1743    /* zero lower digits */
1744    for (; y >= 0; y--) {
1745        a->dp[y] = 0;
1746    }
1747
1748    /* clamp digits */
1749    fp_clamp(a);
1750 }
1751
1752
1753 /* right shift by bit count */
1754 void fp_rshb(fp_int *c, int x)
1755 {
1756     register fp_digit *tmpc, mask, shift;
1757     fp_digit r, rr;
1758     fp_digit D = x;
1759
1760     /* mask */
1761     mask = (((fp_digit)1) << D) - 1;
1762
1763     /* shift for lsb */
1764     shift = DIGIT_BIT - D;
1765
1766     /* alias */
1767     tmpc = c->dp + (c->used - 1);
1768
1769     /* carry */
1770     r = 0;
1771     for (x = c->used - 1; x >= 0; x--) {
1772       /* get the lower  bits of this word in a temp */
1773       rr = *tmpc & mask;
1774
1775       /* shift the current word and mix in the carry bits from previous word */
1776       *tmpc = (*tmpc >> D) | (r << shift);
1777       --tmpc;
1778
1779       /* set the carry to the carry bits of the current word found above */
1780       r = rr;
1781     }
1782 }
1783
1784
1785 void fp_rshd(fp_int *a, int x)
1786 {
1787   int y;
1788
1789   /* too many digits just zero and return */
1790   if (x >= a->used) {
1791      fp_zero(a);
1792      return;
1793   }
1794
1795    /* shift */
1796    for (y = 0; y < a->used - x; y++) {
1797       a->dp[y] = a->dp[y+x];
1798    }
1799
1800    /* zero rest */
1801    for (; y < a->used; y++) {
1802       a->dp[y] = 0;
1803    }
1804    
1805    /* decrement count */
1806    a->used -= x;
1807    fp_clamp(a);
1808 }
1809
1810 /* reverse an array, used for radix code */
1811 void fp_reverse (unsigned char *s, int len)
1812 {
1813   int     ix, iy;
1814   unsigned char t;
1815
1816   ix = 0;
1817   iy = len - 1;
1818   while (ix < iy) {
1819     t     = s[ix];
1820     s[ix] = s[iy];
1821     s[iy] = t;
1822     ++ix;
1823     --iy;
1824   }
1825 }
1826
1827
1828 /* c = a - b */
1829 void fp_sub_d(fp_int *a, fp_digit b, fp_int *c)
1830 {
1831    fp_int tmp;
1832    fp_set(&tmp, b);
1833    fp_sub(a, &tmp, c);
1834 }
1835
1836
1837 /* CyaSSL callers from normal lib */
1838
1839 /* init a new mp_int */
1840 int mp_init (mp_int * a)
1841 {
1842   if (a)
1843     fp_init(a);
1844   return MP_OKAY;
1845 }
1846
1847 /* clear one (frees)  */
1848 void mp_clear (mp_int * a)
1849 {
1850   fp_zero(a);
1851 }
1852
1853 /* handle up to 6 inits */
1854 int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, mp_int* f)
1855 {
1856     if (a)
1857         fp_init(a);
1858     if (b)
1859         fp_init(b);
1860     if (c)
1861         fp_init(c);
1862     if (d)
1863         fp_init(d);
1864     if (e)
1865         fp_init(e);
1866     if (f)
1867         fp_init(f);
1868
1869     return MP_OKAY;
1870 }
1871
1872 /* high level addition (handles signs) */
1873 int mp_add (mp_int * a, mp_int * b, mp_int * c)
1874 {
1875   fp_add(a, b, c);
1876   return MP_OKAY;
1877 }
1878
1879 /* high level subtraction (handles signs) */
1880 int mp_sub (mp_int * a, mp_int * b, mp_int * c)
1881 {
1882   fp_sub(a, b, c);
1883   return MP_OKAY;
1884 }
1885
1886 /* high level multiplication (handles sign) */
1887 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
1888 {
1889   fp_mul(a, b, c);
1890   return MP_OKAY;
1891 }
1892
1893 /* d = a * b (mod c) */
1894 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
1895 {
1896   return fp_mulmod(a, b, c, d);
1897 }
1898
1899 /* c = a mod b, 0 <= c < b */
1900 int mp_mod (mp_int * a, mp_int * b, mp_int * c)
1901 {
1902   return fp_mod (a, b, c);
1903 }
1904
1905 /* hac 14.61, pp608 */
1906 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
1907 {
1908   return fp_invmod(a, b, c);
1909 }
1910
1911 /* this is a shell function that calls either the normal or Montgomery
1912  * exptmod functions.  Originally the call to the montgomery code was
1913  * embedded in the normal function but that wasted alot of stack space
1914  * for nothing (since 99% of the time the Montgomery code would be called)
1915  */
1916 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
1917 {
1918   return fp_exptmod(G, X, P, Y);
1919 }
1920
1921 /* compare two ints (signed)*/
1922 int mp_cmp (mp_int * a, mp_int * b)
1923 {
1924   return fp_cmp(a, b);
1925 }
1926
1927 /* compare a digit */
1928 int mp_cmp_d(mp_int * a, mp_digit b)
1929 {
1930   return fp_cmp_d(a, b);
1931 }
1932
1933 /* get the size for an unsigned equivalent */
1934 int mp_unsigned_bin_size (mp_int * a)
1935 {
1936   return fp_unsigned_bin_size(a);
1937 }
1938
1939 /* store in unsigned [big endian] format */
1940 int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
1941 {
1942   fp_to_unsigned_bin(a,b);
1943   return MP_OKAY;
1944 }
1945
1946 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
1947 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
1948 {
1949   fp_read_unsigned_bin(a, (unsigned char *)b, c);
1950   return MP_OKAY;
1951 }
1952
1953
1954 int mp_sub_d(fp_int *a, fp_digit b, fp_int *c)
1955 {
1956     fp_sub_d(a, b, c);
1957     return MP_OKAY;
1958 }
1959
1960
1961 /* fast math conversion */
1962 int mp_copy(fp_int* a, fp_int* b)
1963 {
1964     fp_copy(a, b);
1965     return MP_OKAY;
1966 }
1967
1968
1969 /* fast math conversion */
1970 int mp_isodd(mp_int* a)
1971 {
1972     return fp_isodd(a);
1973 }
1974
1975
1976 /* fast math conversion */
1977 int mp_iszero(mp_int* a)
1978 {
1979     return fp_iszero(a);
1980 }
1981
1982
1983 /* fast math conversion */
1984 int mp_count_bits (mp_int* a)
1985 {
1986     return fp_count_bits(a);
1987 }
1988
1989
1990 int mp_leading_bit (mp_int* a)
1991 {
1992     return fp_leading_bit(a);
1993 }
1994
1995
1996 /* fast math conversion */
1997 void mp_rshb (mp_int* a, int x)
1998 {
1999     fp_rshb(a, x);
2000 }
2001
2002
2003 /* fast math wrappers */
2004 int mp_set_int(fp_int *a, fp_digit b)
2005 {
2006     fp_set(a, b);
2007     return MP_OKAY;
2008 }
2009
2010
2011 #if defined(CYASSL_KEY_GEN) || defined (HAVE_ECC)
2012
2013 /* c = a * a (mod b) */
2014 int fp_sqrmod(fp_int *a, fp_int *b, fp_int *c)
2015 {
2016   fp_int tmp;
2017   fp_zero(&tmp);
2018   fp_sqr(a, &tmp);
2019   return fp_mod(&tmp, b, c);
2020 }
2021
2022 /* fast math conversion */
2023 int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c)
2024 {
2025     return fp_sqrmod(a, b, c);
2026 }
2027
2028 /* fast math conversion */
2029 int mp_montgomery_calc_normalization(mp_int *a, mp_int *b)
2030 {
2031     fp_montgomery_calc_normalization(a, b);
2032     return MP_OKAY;
2033 }
2034
2035 #endif /* CYASSL_KEYGEN || HAVE_ECC */
2036
2037
2038 #ifdef CYASSL_KEY_GEN
2039
2040 void fp_gcd(fp_int *a, fp_int *b, fp_int *c);
2041 void fp_lcm(fp_int *a, fp_int *b, fp_int *c);
2042 int  fp_isprime(fp_int *a);
2043 int  fp_cnt_lsb(fp_int *a);
2044
2045 int mp_gcd(fp_int *a, fp_int *b, fp_int *c)
2046 {
2047     fp_gcd(a, b, c);
2048     return MP_OKAY;
2049 }
2050
2051
2052 int mp_lcm(fp_int *a, fp_int *b, fp_int *c)
2053 {
2054     fp_lcm(a, b, c);
2055     return MP_OKAY;
2056 }
2057
2058
2059 int mp_prime_is_prime(mp_int* a, int t, int* result)
2060 {
2061     (void)t;
2062     *result = fp_isprime(a);
2063     return MP_OKAY;
2064 }
2065
2066
2067
2068 static int s_is_power_of_two(fp_digit b, int *p)
2069 {
2070    int x;
2071
2072    /* fast return if no power of two */
2073    if ((b==0) || (b & (b-1))) {
2074       return 0;
2075    }
2076
2077    for (x = 0; x < DIGIT_BIT; x++) {
2078       if (b == (((fp_digit)1)<<x)) {
2079          *p = x;
2080          return 1;
2081       }
2082    }
2083    return 0;
2084 }
2085
2086 /* a/b => cb + d == a */
2087 static int fp_div_d(fp_int *a, fp_digit b, fp_int *c, fp_digit *d)
2088 {
2089   fp_int   q;
2090   fp_word  w;
2091   fp_digit t;
2092   int      ix;
2093
2094   /* cannot divide by zero */
2095   if (b == 0) {
2096      return FP_VAL;
2097   }
2098
2099   /* quick outs */
2100   if (b == 1 || fp_iszero(a) == 1) {
2101      if (d != NULL) {
2102         *d = 0;
2103      }
2104      if (c != NULL) {
2105         fp_copy(a, c);
2106      }
2107      return FP_OKAY;
2108   }
2109
2110   /* power of two ? */
2111   if (s_is_power_of_two(b, &ix) == 1) {
2112      if (d != NULL) {
2113         *d = a->dp[0] & ((((fp_digit)1)<<ix) - 1);
2114      }
2115      if (c != NULL) {
2116         fp_div_2d(a, ix, c, NULL);
2117      }
2118      return FP_OKAY;
2119   }
2120
2121   /* no easy answer [c'est la vie].  Just division */
2122   fp_init(&q);
2123   
2124   q.used = a->used;
2125   q.sign = a->sign;
2126   w = 0;
2127   for (ix = a->used - 1; ix >= 0; ix--) {
2128      w = (w << ((fp_word)DIGIT_BIT)) | ((fp_word)a->dp[ix]);
2129      
2130      if (w >= b) {
2131         t = (fp_digit)(w / b);
2132         w -= ((fp_word)t) * ((fp_word)b);
2133       } else {
2134         t = 0;
2135       }
2136       q.dp[ix] = (fp_digit)t;
2137   }
2138   
2139   if (d != NULL) {
2140      *d = (fp_digit)w;
2141   }
2142   
2143   if (c != NULL) {
2144      fp_clamp(&q);
2145      fp_copy(&q, c);
2146   }
2147  
2148   return FP_OKAY;
2149 }
2150
2151
2152 /* c = a mod b, 0 <= c < b  */
2153 static int fp_mod_d(fp_int *a, fp_digit b, fp_digit *c)
2154 {
2155    return fp_div_d(a, b, NULL, c);
2156 }
2157
2158
2159 /* Miller-Rabin test of "a" to the base of "b" as described in 
2160  * HAC pp. 139 Algorithm 4.24
2161  *
2162  * Sets result to 0 if definitely composite or 1 if probably prime.
2163  * Randomly the chance of error is no more than 1/4 and often 
2164  * very much lower.
2165  */
2166 static void fp_prime_miller_rabin (fp_int * a, fp_int * b, int *result)
2167 {
2168   fp_int  n1, y, r;
2169   int     s, j;
2170
2171   /* default */
2172   *result = FP_NO;
2173
2174   /* ensure b > 1 */
2175   if (fp_cmp_d(b, 1) != FP_GT) {
2176      return;
2177   }     
2178
2179   /* get n1 = a - 1 */
2180   fp_init_copy(&n1, a);
2181   fp_sub_d(&n1, 1, &n1);
2182
2183   /* set 2**s * r = n1 */
2184   fp_init_copy(&r, &n1);
2185
2186   /* count the number of least significant bits
2187    * which are zero
2188    */
2189   s = fp_cnt_lsb(&r);
2190
2191   /* now divide n - 1 by 2**s */
2192   fp_div_2d (&r, s, &r, NULL);
2193
2194   /* compute y = b**r mod a */
2195   fp_init(&y);
2196   fp_exptmod(b, &r, a, &y);
2197
2198   /* if y != 1 and y != n1 do */
2199   if (fp_cmp_d (&y, 1) != FP_EQ && fp_cmp (&y, &n1) != FP_EQ) {
2200     j = 1;
2201     /* while j <= s-1 and y != n1 */
2202     while ((j <= (s - 1)) && fp_cmp (&y, &n1) != FP_EQ) {
2203       fp_sqrmod (&y, a, &y);
2204
2205       /* if y == 1 then composite */
2206       if (fp_cmp_d (&y, 1) == FP_EQ) {
2207          return;
2208       }
2209       ++j;
2210     }
2211
2212     /* if y != n1 then composite */
2213     if (fp_cmp (&y, &n1) != FP_EQ) {
2214        return;
2215     }
2216   }
2217
2218   /* probably prime now */
2219   *result = FP_YES;
2220 }
2221
2222
2223 /* a few primes */
2224 static const fp_digit primes[256] = {
2225   0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
2226   0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
2227   0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
2228   0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F, 0x0083,
2229   0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
2230   0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
2231   0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
2232   0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
2233
2234   0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
2235   0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
2236   0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
2237   0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
2238   0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
2239   0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
2240   0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
2241   0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
2242
2243   0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
2244   0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
2245   0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
2246   0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
2247   0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
2248   0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
2249   0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
2250   0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
2251
2252   0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
2253   0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
2254   0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
2255   0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
2256   0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
2257   0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
2258   0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
2259   0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
2260 };
2261
2262 int fp_isprime(fp_int *a)
2263 {
2264    fp_int   b;
2265    fp_digit d = 0;
2266    int      r, res;
2267
2268    /* do trial division */
2269    for (r = 0; r < 256; r++) {
2270        fp_mod_d(a, primes[r], &d);
2271        if (d == 0) {
2272           return FP_NO;
2273        }
2274    }
2275
2276    /* now do 8 miller rabins */
2277    fp_init(&b);
2278    for (r = 0; r < 8; r++) {
2279        fp_set(&b, primes[r]);
2280        fp_prime_miller_rabin(a, &b, &res);
2281        if (res == FP_NO) {
2282           return FP_NO;
2283        }
2284    }
2285    return FP_YES;
2286 }
2287
2288
2289 /* c = [a, b] */
2290 void fp_lcm(fp_int *a, fp_int *b, fp_int *c)
2291 {
2292    fp_int  t1, t2;
2293
2294    fp_init(&t1);
2295    fp_init(&t2);
2296    fp_gcd(a, b, &t1);
2297    if (fp_cmp_mag(a, b) == FP_GT) {
2298       fp_div(a, &t1, &t2, NULL);
2299       fp_mul(b, &t2, c);
2300    } else {
2301       fp_div(b, &t1, &t2, NULL);
2302       fp_mul(a, &t2, c);
2303    }   
2304 }
2305
2306
2307 static const int lnz[16] = {
2308    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
2309 };
2310
2311 /* Counts the number of lsbs which are zero before the first zero bit */
2312 int fp_cnt_lsb(fp_int *a)
2313 {
2314    int x;
2315    fp_digit q, qq;
2316
2317    /* easy out */
2318    if (fp_iszero(a) == 1) {
2319       return 0;
2320    }
2321
2322    /* scan lower digits until non-zero */
2323    for (x = 0; x < a->used && a->dp[x] == 0; x++);
2324    q = a->dp[x];
2325    x *= DIGIT_BIT;
2326
2327    /* now scan this digit until a 1 is found */
2328    if ((q & 1) == 0) {
2329       do {
2330          qq  = q & 15;
2331          x  += lnz[qq];
2332          q >>= 4;
2333       } while (qq == 0);
2334    }
2335    return x;
2336 }
2337
2338
2339 /* c = (a, b) */
2340 void fp_gcd(fp_int *a, fp_int *b, fp_int *c)
2341 {
2342    fp_int u, v, r;
2343
2344    /* either zero than gcd is the largest */
2345    if (fp_iszero (a) == 1 && fp_iszero (b) == 0) {
2346      fp_abs (b, c);
2347      return;
2348    }
2349    if (fp_iszero (a) == 0 && fp_iszero (b) == 1) {
2350      fp_abs (a, c);
2351      return;
2352    }
2353
2354    /* optimized.  At this point if a == 0 then
2355     * b must equal zero too
2356     */
2357    if (fp_iszero (a) == 1) {
2358      fp_zero(c);
2359      return;
2360    }
2361
2362    /* sort inputs */
2363    if (fp_cmp_mag(a, b) != FP_LT) {
2364       fp_init_copy(&u, a);
2365       fp_init_copy(&v, b);
2366    } else {
2367       fp_init_copy(&u, b);
2368       fp_init_copy(&v, a);
2369    }
2370  
2371    fp_zero(&r);
2372    while (fp_iszero(&v) == FP_NO) {
2373       fp_mod(&u, &v, &r);
2374       fp_copy(&v, &u);
2375       fp_copy(&r, &v);
2376    }
2377    fp_copy(&u, c);
2378 }
2379
2380 #endif /* CYASSL_KEY_GEN */
2381
2382
2383 #if defined(HAVE_ECC) || !defined(NO_PWDBASED)
2384 /* c = a + b */
2385 void fp_add_d(fp_int *a, fp_digit b, fp_int *c)
2386 {
2387    fp_int tmp;
2388    fp_set(&tmp, b);
2389    fp_add(a,&tmp,c);
2390 }
2391
2392 /* external compatibility */
2393 int mp_add_d(fp_int *a, fp_digit b, fp_int *c)
2394 {
2395     fp_add_d(a, b, c);
2396     return MP_OKAY;
2397 }
2398
2399 #endif  /* HAVE_ECC || !NO_PWDBASED */
2400
2401
2402 #ifdef HAVE_ECC
2403
2404 /* chars used in radix conversions */
2405 static const char *fp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
2406
2407 static int fp_read_radix(fp_int *a, const char *str, int radix)
2408 {
2409   int     y, neg;
2410   char    ch;
2411
2412   /* make sure the radix is ok */
2413   if (radix < 2 || radix > 64) {
2414     return FP_VAL;
2415   }
2416
2417   /* if the leading digit is a
2418    * minus set the sign to negative.
2419    */
2420   if (*str == '-') {
2421     ++str;
2422     neg = FP_NEG;
2423   } else {
2424     neg = FP_ZPOS;
2425   }
2426
2427   /* set the integer to the default of zero */
2428   fp_zero (a);
2429
2430   /* process each digit of the string */
2431   while (*str) {
2432     /* if the radix < 36 the conversion is case insensitive
2433      * this allows numbers like 1AB and 1ab to represent the same  value
2434      * [e.g. in hex]
2435      */
2436     ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str);
2437     for (y = 0; y < 64; y++) {
2438       if (ch == fp_s_rmap[y]) {
2439          break;
2440       }
2441     }
2442
2443     /* if the char was found in the map
2444      * and is less than the given radix add it
2445      * to the number, otherwise exit the loop.
2446      */
2447     if (y < radix) {
2448       fp_mul_d (a, (fp_digit) radix, a);
2449       fp_add_d (a, (fp_digit) y, a);
2450     } else {
2451       break;
2452     }
2453     ++str;
2454   }
2455
2456   /* set the sign only if a != 0 */
2457   if (fp_iszero(a) != FP_YES) {
2458      a->sign = neg;
2459   }
2460   return FP_OKAY;
2461 }
2462
2463 /* fast math conversion */
2464 int mp_read_radix(mp_int *a, const char *str, int radix)
2465 {
2466     return fp_read_radix(a, str, radix);
2467 }
2468
2469 /* fast math conversion */
2470 int mp_set(fp_int *a, fp_digit b)
2471 {
2472     fp_set(a,b);
2473     return MP_OKAY;
2474 }
2475
2476 /* fast math conversion */
2477 int mp_sqr(fp_int *A, fp_int *B)
2478 {
2479     fp_sqr(A, B);
2480     return MP_OKAY;
2481 }
2482   
2483 /* fast math conversion */
2484 int mp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp)
2485 {
2486     fp_montgomery_reduce(a, m, mp);
2487     return MP_OKAY;
2488 }
2489
2490
2491 /* fast math conversion */
2492 int mp_montgomery_setup(fp_int *a, fp_digit *rho)
2493 {
2494     return fp_montgomery_setup(a, rho);
2495 }
2496
2497 int mp_div_2(fp_int * a, fp_int * b)
2498 {
2499     fp_div_2(a, b);
2500     return MP_OKAY;
2501 }
2502
2503
2504 int mp_init_copy(fp_int * a, fp_int * b)
2505 {
2506     fp_init_copy(a, b);
2507     return MP_OKAY;
2508 }
2509
2510
2511
2512 #endif /* HAVE_ECC */
2513
2514 #endif /* USE_FAST_MATH */