]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cryptkit/lib/giantIntegers.c
Security-58286.1.32.tar.gz
[apple/security.git] / OSX / libsecurity_cryptkit / lib / giantIntegers.c
1 /* Copyright (c) 1998,2011-2014 Apple Inc. All Rights Reserved.
2 *
3 * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
4 * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
5 * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
10
11 giantIntegers.c - library for large-integer arithmetic.
12
13 Revision History
14 ----------------
15 Fixed a==b bug in addg().
16 10/06/98 ap
17 Changed to compile with C++.
18 13 Apr 98 Fixed shiftright(1) bug in modg_via_recip.
19 09 Apr 98 at Apple
20 Major rewrite of core arithmetic routines to make this module
21 independent of size of giantDigit.
22 Removed idivg() and radixdiv().
23 20 Jan 98 at Apple
24 Deleted FFT arithmetic; simplified mulg().
25 09 Jan 98 at Apple
26 gshiftright() optimization.
27 08 Jan 98 at Apple
28 newGiant() returns NULL on malloc failure
29 24 Dec 97 at Apple
30 New grammarSquare(); optimized modg_via_recip()
31 11 Jun 97 at Apple
32 Added modg_via_recip(), divg_via_recip(), make_recip()
33 Added new multiple giant stack mechanism
34 Fixed potential packing/alignment bug in copyGiant()
35 Added profiling for borrowGiant(), returnGiant()
36 Deleted obsolete ifdef'd code
37 Deleted newgiant()
38 All calls to borrowGiant() now specify required size (no more
39 borrowGiant(0) calls)
40 08 May 97 at Apple
41 Changed size of giantstruct.n to 1 for Mac build
42 05 Feb 97 at Apple
43 newGiant() no longer modifies CurrentMaxShorts or giant stack
44 Added modg profiling
45 01 Feb 97 at NeXT
46 Added iszero() check in gcompg
47 17 Jan 97 at NeXT
48 Fixed negation bug in gmersennemod()
49 Fixed n[words-1] == 0 bug in extractbits()
50 Cleaned up lots of static declarations
51 19 Sep 96 at NeXT
52 Fixed --size underflow bug in normal_subg().
53 4 Sep 96 at NeXT
54 Fixed (b<n), (sign<0) case in gmersennemod() to allow for arbitrary n.
55 9 Aug 96 at NeXT
56 Fixed sign-extend bug in data_to_giant().
57 7 Aug 96 at NeXT
58 Changed precision in newtondivide().
59 Removed #ifdef UNUSED code.
60 24 Jul 96 at NeXT
61 Added scompg().
62 Created.
63
64 */
65
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include "platform.h"
70 #include "giantIntegers.h"
71 #include "feeDebug.h"
72 #include "ckconfig.h"
73 #include "ellipticMeasure.h"
74 #include "falloc.h"
75 #include "giantPortCommon.h"
76
77 #ifdef FEE_DEBUG
78 #if (GIANT_LOG2_BITS_PER_DIGIT == 4)
79 #warning Compiling with two-byte giantDigits
80 #endif
81 #endif
82
83 #if 0
84 #if FEE_DEBUG
85 char printbuf1[200];
86 char printbuf2[200];
87 char printbuf3[200];
88 void printGiantBuf(giant x)
89 {
90 int i;
91
92 sprintf(printbuf2, "sign=%d cap=%d n[]=", x->sign, x->capacity);
93 for(i=0; i<abs(x->sign); i++) {
94 sprintf(printbuf3 + 10*i, "%u:", x->n[i]);
95 }
96 }
97
98 char printbuf4[200];
99 char printbuf5[200];
100 void printGiantBuf2(giant x)
101 {
102 int i;
103
104 sprintf(printbuf4, "sign=%d cap=%d n[]=", x->sign, x->capacity);
105 for(i=0; i<abs(x->sign); i++) {
106 sprintf(printbuf5 + 10*i, "%u:", x->n[i]);
107 }
108 }
109 #endif /* FEE_DEBUG */
110 #endif /* 0 */
111
112 /******** debugging flags *********/
113
114 /*
115 * Flag use of unoptimized divg, modg, binvg
116 */
117 //#define WARN_UNOPTIMIZE FEE_DEBUG
118 #define WARN_UNOPTIMIZE 0
119
120 /*
121 * Log interesting giant stack events
122 */
123 #define LOG_GIANT_STACK 0
124
125 /*
126 * Log allocation of giant larger than stack size
127 */
128 #define LOG_GIANT_STACK_OVERFLOW 1
129
130 /*
131 * Flag newGiant(0) and borrowGiant(0) calls
132 */
133 #define WARN_ZERO_GIANT_SIZE FEE_DEBUG
134
135 /* temp mac-only giant initialization debug */
136 #define GIANT_MAC_DEBUG 0
137 #if GIANT_MAC_DEBUG
138
139 #include <string.h>
140 #include <TextUtils.h>
141
142 /* this one needs a writable string */
143 static void logCom(unsigned char *str) {
144 c2pstr((char *)str);
145 DebugStr(str);
146 }
147
148 /* constant strings */
149 void dblog0(const char *str) {
150 Str255 outStr;
151 strcpy((char *)outStr, str);
152 logCom(outStr);
153 }
154
155 #else
156 #define dblog0(s)
157
158 #endif /* GIANT_MAC_DEBUG */
159
160 #ifndef min
161 #define min(a,b) ((a)<(b)? (a) : (b))
162 #endif // min
163 #ifndef max
164 #define max(a,b) ((a)>(b)? (a) : (b))
165 #endif // max
166
167 #ifndef TRUE
168 #define TRUE 1
169 #endif // TRUE
170 #ifndef FALSE
171 #define FALSE 0
172 #endif // FALSE
173
174 static void absg(giant g); /* g := |g|. */
175
176 /************** globals *******************/
177
178
179 /* ------ giant stack package ------ */
180
181 /*
182 * The giant stack package is a local cache which allows us to avoid calls
183 * to malloc() for borrowGiant(). On a 90 Mhz Pentium, enabling the
184 * giant stack package shows about a 1.35 speedup factor over an identical
185 * CryptKit without the giant stacks enabled.
186 */
187
188 #if GIANTS_VIA_STACK
189
190 #if LOG_GIANT_STACK
191 #define gstackDbg(x) printf x
192 #else // LOG_GIANT_STACK
193 #define gstackDbg(x)
194 #endif // LOG_GIANT_STACK
195
196 typedef struct {
197 unsigned numDigits; // capacity of giants in this stack
198 unsigned numFree; // number of free giants in stack
199 unsigned totalGiants; // total number in *stack
200 giant *stack;
201 } gstack;
202
203 static gstack *gstacks = NULL; // array of stacks
204 static unsigned numGstacks = 0; // # of elements in gstacks
205 static int gstackInitd = 0; // this module has been init'd
206
207 #define INIT_NUM_GIANTS 16 /* initial # of giants / stack */
208 #define MIN_GIANT_SIZE 4 /* numDigits for gstack[0] */
209 #define GIANT_SIZE_INCR 2 /* in << bits */
210
211 /*
212 * Initialize giant stacks, with up to specified max giant size.
213 */
214 void initGiantStacks(unsigned maxDigits)
215 {
216 unsigned curSize = MIN_GIANT_SIZE;
217 unsigned sz;
218 unsigned i;
219
220 dblog0("initGiantStacks\n");
221
222 if(gstackInitd) {
223 /*
224 * Shouldn't be called more than once...
225 */
226 printf("multiple initGiantStacks calls\n");
227 return;
228 }
229 gstackDbg(("initGiantStacks(%d)\n", maxDigits));
230
231 /*
232 * How many stacks?
233 */
234 numGstacks = 1;
235 while(curSize<=maxDigits) {
236 curSize <<= GIANT_SIZE_INCR;
237 numGstacks++;
238 }
239
240 sz = sizeof(gstack) * numGstacks;
241 gstacks = (gstack*) fmalloc(sz);
242 bzero(gstacks, sz);
243
244 curSize = MIN_GIANT_SIZE;
245 for(i=0; i<numGstacks; i++) {
246 gstacks[i].numDigits = curSize;
247 curSize <<= GIANT_SIZE_INCR;
248 }
249
250 gstackInitd = 1;
251 }
252
253 /* called at shut down - free resources */
254 void freeGiantStacks(void)
255 {
256 int i;
257 int j;
258 gstack *gs;
259
260 if(!gstackInitd) {
261 return;
262 }
263 for(i=0; i<numGstacks; i++) {
264 gs = &gstacks[i];
265 for(j=0; j<gs->numFree; j++) {
266 freeGiant(gs->stack[j]);
267 gs->stack[j] = NULL;
268 }
269 /* and the stack itself - may be null if this was never used */
270 if(gs->stack != NULL) {
271 ffree(gs->stack);
272 gs->stack = NULL;
273 }
274 }
275 ffree(gstacks);
276 gstacks = NULL;
277 gstackInitd = 0;
278 }
279
280 #endif // GIANTS_VIA_STACK
281
282 giant borrowGiant(unsigned numDigits)
283 {
284 giant result;
285
286 #if GIANTS_VIA_STACK
287
288 unsigned stackNum;
289 gstack *gs = gstacks;
290
291 #if WARN_ZERO_GIANT_SIZE
292 if(numDigits == 0) {
293 printf("borrowGiant(0)\n");
294 numDigits = gstacks[numGstacks-1].numDigits;
295 }
296 #endif // WARN_ZERO_GIANT_SIZE
297
298 /*
299 * Find appropriate stack
300 */
301 if(numDigits <= MIN_GIANT_SIZE)
302 stackNum = 0;
303 else if (numDigits <= (MIN_GIANT_SIZE << GIANT_SIZE_INCR))
304 stackNum = 1;
305 else if (numDigits <= (MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR)))
306 stackNum = 2;
307 else if (numDigits <= (MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR)))
308 stackNum = 3;
309 else if (numDigits <= (MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR)))
310 stackNum = 4;
311 else
312 stackNum = numGstacks;
313
314 if(stackNum >= numGstacks) {
315 /*
316 * out of bounds; just malloc
317 */
318 #if LOG_GIANT_STACK_OVERFLOW
319 gstackDbg(("giantFromStack overflow; numDigits %d\n",
320 numDigits));
321 #endif // LOG_GIANT_STACK_OVERFLOW
322 return newGiant(numDigits);
323 }
324 gs = &gstacks[stackNum];
325
326 #if GIANT_MAC_DEBUG
327 if((gs->numFree != 0) && (gs->stack == NULL)) {
328 dblog0("borrowGiant: null stack!\n");
329 }
330 #endif
331
332 if(gs->numFree != 0) {
333 result = gs->stack[--gs->numFree];
334 }
335 else {
336 /*
337 * Stack empty; malloc
338 */
339 result = newGiant(gs->numDigits);
340 }
341
342 #else /* GIANTS_VIA_STACK */
343
344 result = newGiant(numDigits);
345
346 #endif /* GIANTS_VIA_STACK */
347
348 PROF_INCR(numBorrows);
349 return result;
350 }
351
352 void returnGiant(giant g)
353 {
354
355 #if GIANTS_VIA_STACK
356
357 unsigned stackNum;
358 gstack *gs;
359 unsigned cap = g->capacity;
360
361
362 #if FEE_DEBUG
363 if(!gstackInitd) {
364 CKRaise("returnGiant before stacks initialized!");
365 }
366 #endif // FEE_DEBUG
367
368 #if GIANT_MAC_DEBUG
369 if(g == NULL) {
370 dblog0("returnGiant: null g!\n");
371 }
372 #endif
373
374 /*
375 * Find appropriate stack. Note we expect exact match of
376 * capacity and stack's giant size.
377 */
378 /*
379 * Optimized unrolled loop. Just make sure there are enough cases
380 * to handle all of the stacks. Errors in this case will be flagged
381 * via LOG_GIANT_STACK_OVERFLOW.
382 */
383 switch(cap) {
384 case MIN_GIANT_SIZE:
385 stackNum = 0;
386 break;
387 case MIN_GIANT_SIZE << GIANT_SIZE_INCR:
388 stackNum = 1;
389 break;
390 case MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR):
391 stackNum = 2;
392 break;
393 case MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR):
394 stackNum = 3;
395 break;
396 case MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR):
397 stackNum = 4;
398 break;
399 default:
400 stackNum = numGstacks;
401 break;
402 }
403
404 if(stackNum >= numGstacks) {
405 /*
406 * out of bounds; just free
407 */
408 #if LOG_GIANT_STACK_OVERFLOW
409 gstackDbg(("giantToStack overflow; numDigits %d\n", cap));
410 #endif // LOG_GIANT_STACK_OVERFLOW
411 freeGiant(g);
412 return;
413 }
414 gs = &gstacks[stackNum];
415 if(gs->numFree == gs->totalGiants) {
416 if(gs->totalGiants == 0) {
417 gstackDbg(("Initial alloc of gstack(%d)\n",
418 gs->numDigits));
419 gs->totalGiants = INIT_NUM_GIANTS;
420 }
421 else {
422 gs->totalGiants *= 2;
423 gstackDbg(("Bumping gstack(%d) to %d\n",
424 gs->numDigits, gs->totalGiants));
425 }
426 gs->stack = (giantstruct**) frealloc(gs->stack, gs->totalGiants*sizeof(giant));
427 }
428 g->sign = 0; // not sure this is important...
429 gs->stack[gs->numFree++] = g;
430
431 #if GIANT_MAC_DEBUG
432 if((gs->numFree != 0) && (gs->stack == NULL)) {
433 dblog0("borrowGiant: null stack!\n");
434 }
435 #endif
436
437 #else /* GIANTS_VIA_STACK */
438
439 freeGiant(g);
440
441 #endif /* GIANTS_VIA_STACK */
442 }
443
444 void freeGiant(giant x) {
445 ffree(x);
446 }
447
448 giant newGiant(unsigned numDigits) {
449 // giant sufficient for 2^numbits+16 sized ops
450 int size;
451 giant result;
452
453 #if WARN_ZERO_GIANT_SIZE
454 if(numDigits == 0) {
455 printf("newGiant(0)\n");
456 #if GIANTS_VIA_STACK
457 numDigits = gstacks[numGstacks-1].totalGiants;
458 #else
459 /* HACK */
460 numDigits = 20;
461 #endif
462 }
463 #endif // WARN_ZERO_GIANT_SIZE
464
465 size = (numDigits-1) * GIANT_BYTES_PER_DIGIT + sizeof(giantstruct);
466 result = (giant)fmalloc(size);
467 if(result == NULL) {
468 return NULL;
469 }
470 result->sign = 0;
471 result->capacity = numDigits;
472 return result;
473 }
474
475 giant copyGiant(giant x)
476 {
477 int bytes;
478
479 giant result = newGiant(x->capacity);
480
481 /*
482 * 13 Jun 1997
483 * NO! this assumes packed alignment
484 */
485 bytes = sizeof(giantstruct) +
486 ((x->capacity - 1) * GIANT_BYTES_PER_DIGIT);
487 bcopy(x, result, bytes);
488 return result;
489 }
490
491 /* ------ initialization and utility routines ------ */
492
493
494 unsigned bitlen(giant n) {
495 unsigned b = GIANT_BITS_PER_DIGIT;
496 giantDigit c = ((giantDigit)1) << (GIANT_BITS_PER_DIGIT - 1);
497 giantDigit w;
498
499 if (isZero(n)) {
500 return(0);
501 }
502 w = n->n[abs(n->sign) - 1];
503 if (!w) {
504 CKRaise("bitlen - no bit set!");
505 }
506 while((w&c) == 0) {
507 b--;
508 c >>= 1;
509 }
510 return(GIANT_BITS_PER_DIGIT * (abs(n->sign)-1) + b);
511 }
512
513 int bitval(giant n, int pos) {
514 int i = abs(pos) >> GIANT_LOG2_BITS_PER_DIGIT;
515 giantDigit c = ((giantDigit)1) << (pos & (GIANT_BITS_PER_DIGIT - 1));
516
517 return ((0!=((n->n[i]) & c))?1:0);
518 }
519
520 int gsign(giant g)
521 /* returns the sign of g */
522 {
523 if (isZero(g)) return(0);
524 if (g->sign > 0) return(1);
525 return(-1);
526 }
527
528 /*
529 * Adjust sign for possible leading (m.s.) zero digits
530 */
531 void gtrimSign(giant g)
532 {
533 int numDigits = abs(g->sign);
534 int i;
535
536 for(i=numDigits-1; i>=0; i--) {
537 if(g->n[i] == 0) {
538 numDigits--;
539 }
540 else {
541 break;
542 }
543 }
544 if(g->sign < 0) {
545 g->sign = -numDigits;
546 }
547 else {
548 g->sign = numDigits;
549 }
550 }
551
552
553 int isone(giant g) {
554 return((g->sign==1)&&(g->n[0]==1));
555 }
556
557 int isZero(giant thegiant) {
558 /* Returns TRUE if thegiant == 0. */
559 int count;
560 int length = abs(thegiant->sign);
561 giantDigit *numpointer;
562
563 if (length) {
564 numpointer = thegiant->n;
565
566 for(count = 0; count<length; ++count,++numpointer)
567 if (*numpointer != 0 ) return(FALSE);
568 }
569 return(TRUE);
570 }
571
572 int gcompg(giant a, giant b)
573 /* returns -1,0,1 if a<b, a=b, a>b, respectively */
574 {
575 int sa = a->sign;
576 int j;
577 int sb = b->sign;
578 giantDigit va;
579 giantDigit vb;
580 int sgn;
581
582 if(isZero(a) && isZero(b)) return 0;
583 if(sa > sb) return(1);
584 if(sa < sb) return(-1);
585 if(sa < 0) {
586 sa = -sa; /* Take absolute value of sa */
587 sgn = -1;
588 } else sgn = 1;
589 for(j = sa-1; j >= 0; j--) {
590 va = a->n[j]; vb = b->n[j];
591 if (va > vb) return(sgn);
592 if (va < vb) return(-sgn);
593 }
594 return(0);
595 }
596
597 /* destgiant becomes equal to srcgiant */
598 void gtog(giant srcgiant, giant destgiant) {
599
600 int numbytes;
601
602 CKASSERT(srcgiant != NULL);
603 numbytes = abs(srcgiant->sign) * GIANT_BYTES_PER_DIGIT;
604 if (destgiant->capacity < abs(srcgiant->sign))
605 CKRaise("gtog overflow!!");
606 memcpy((char *)destgiant->n, (char *)srcgiant->n, numbytes);
607 destgiant->sign = srcgiant->sign;
608 }
609
610 void int_to_giant(int i, giant g) {
611 /* The giant g becomes set to the integer value i. */
612 int isneg = (i<0);
613 unsigned int j = abs(i);
614 unsigned dex;
615
616 g->sign = 0;
617 if (i==0) {
618 g->n[0] = 0;
619 return;
620 }
621
622 if(GIANT_BYTES_PER_DIGIT == sizeof(int)) {
623 g->n[0] = j;
624 g->sign = 1;
625 }
626 else {
627 /* one loop per digit */
628 unsigned scnt = GIANT_BITS_PER_DIGIT; // fool compiler
629
630 for(dex=0; dex<sizeof(int); dex++) {
631 g->n[dex] = j & GIANT_DIGIT_MASK;
632 j >>= scnt;
633 g->sign++;
634 if(j == 0) {
635 break;
636 }
637 }
638 }
639 if (isneg) {
640 g->sign = -(g->sign);
641 }
642 }
643
644 /*------------- Arithmetic --------------*/
645
646 void negg(giant g) {
647 /* g becomes -g */
648 g->sign = -g->sign;
649 }
650
651 void iaddg(int i, giant g) { /* positive g becomes g + (int)i */
652 int j;
653 giantDigit carry;
654 int size = abs(g->sign);
655
656 if (isZero(g)) {
657 int_to_giant(i,g);
658 }
659 else {
660 carry = i;
661 for(j=0; ((j<size) && (carry != 0)); j++) {
662 g->n[j] = giantAddDigits(g->n[j], carry, &carry);
663 }
664 if(carry) {
665 ++g->sign;
666 // realloc
667 if (g->sign > (int)g->capacity) CKRaise("iaddg overflow!");
668 g->n[size] = carry;
669 }
670 }
671 }
672
673 /*
674 * g *= (int n)
675 *
676 * FIXME - we can improve this...
677 */
678 void imulg(unsigned n, giant g)
679 {
680 giant tmp = borrowGiant(abs(g->sign) + sizeof(int));
681
682 int_to_giant(n, tmp);
683 mulg(tmp, g);
684 returnGiant(tmp);
685 }
686
687 static void normal_addg(giant a, giant b)
688 /* b := a + b, both a,b assumed non-negative. */
689 {
690 giantDigit carry1 = 0;
691 giantDigit carry2 = 0;
692 int asize = a->sign, bsize = b->sign;
693 giantDigit *an = a->n;
694 giantDigit *bn = b->n;
695 giantDigit tmp;
696 int j;
697 int comSize;
698 int maxSize;
699
700 if(asize < bsize) {
701 comSize = asize;
702 maxSize = bsize;
703 }
704 else {
705 comSize = bsize;
706 maxSize = asize;
707 }
708
709 /* first handle the common digits */
710 for(j=0; j<comSize; j++) {
711 /*
712 * first add the carry, then an[j] - either add could result
713 * in another carry
714 */
715 if(carry1 || carry2) {
716 tmp = giantAddDigits(bn[j], (giantDigit)1, &carry1);
717 }
718 else {
719 carry1 = 0;
720 tmp = bn[j];
721 }
722 bn[j] = giantAddDigits(tmp, an[j], &carry2);
723 }
724
725 if(asize < bsize) {
726
727 /* now propagate remaining carry beyond asize */
728 if(carry2) {
729 carry1 = 1;
730 }
731 if(carry1) {
732 for(; j<bsize; j++) {
733 bn[j] = giantAddDigits(bn[j], (giantDigit)1, &carry1);
734 if(carry1 == 0) {
735 break;
736 }
737 }
738 }
739 } else {
740 /* now propagate remaining an[] and carry beyond bsize */
741 if(carry2) {
742 carry1 = 1;
743 }
744 for(; j<asize; j++) {
745 if(carry1) {
746 bn[j] = giantAddDigits(an[j], (giantDigit)1, &carry1);
747 }
748 else {
749 bn[j] = an[j];
750 carry1 = 0;
751 }
752 }
753 }
754 b->sign = maxSize;
755 if(carry1) {
756 // realloc?
757 bn[j] = 1;
758 b->sign++;
759 if (b->sign > (int)b->capacity) CKRaise("iaddg overflow!");
760 }
761
762 }
763
764 static void normal_subg(giant a, giant b)
765 /* b := b - a; requires b, a non-negative and b >= a. */
766 {
767 int j;
768 int size = b->sign;
769 giantDigit tmp;
770 giantDigit borrow1 = 0;
771 giantDigit borrow2 = 0;
772 giantDigit *an = a->n;
773 giantDigit *bn = b->n;
774
775 if(a->sign == 0) {
776 return;
777 }
778
779 for (j=0; j<a->sign; ++j) {
780 if(borrow1 || borrow2) {
781 tmp = giantSubDigits(bn[j], (giantDigit)1, &borrow1);
782 }
783 else {
784 tmp = bn[j];
785 borrow1 = 0;
786 }
787 bn[j] = giantSubDigits(tmp, an[j], &borrow2);
788 }
789 if(borrow1 || borrow2) {
790 /* propagate borrow thru remainder of bn[] */
791 borrow1 = 1;
792 for (j=a->sign; j<size; ++j) {
793 if(borrow1) {
794 bn[j] = giantSubDigits(bn[j], (giantDigit)1, &borrow1);
795 }
796 else {
797 break;
798 }
799 }
800 }
801
802 /* adjust sign for leading zero digits */
803 while((size-- > 0) && (b->n[size] == 0))
804 ;
805 b->sign = (b->n[size] == 0)? 0 : size+1;
806 }
807
808 static void reverse_subg(giant a, giant b)
809 /* b := a - b; requires b, a non-negative and a >= b. */
810 {
811 int j;
812 int size = a->sign;
813 giantDigit tmp;
814 giantDigit borrow1 = 0;
815 giantDigit borrow2 = 0;
816 giantDigit *an = a->n;
817 giantDigit *bn = b->n;
818
819 if(b->sign == 0) {
820 gtog(a, b);
821 return;
822 }
823 for (j=0; j<b->sign; ++j) {
824 if(borrow1 || borrow2) {
825 tmp = giantSubDigits(an[j], (giantDigit)1, &borrow1);
826 }
827 else {
828 tmp = an[j];
829 borrow1 = 0;
830 }
831 bn[j] = giantSubDigits(tmp, bn[j], &borrow2);
832 }
833 if(borrow1 || borrow2) {
834 /* propagate borrow thru remainder of bn[] */
835 borrow1 = 1;
836 }
837 for (j=b->sign; j<size; ++j) {
838 if(borrow1) {
839 bn[j] = giantSubDigits(an[j], (giantDigit)1, &borrow1);
840 }
841 else {
842 bn[j] = an[j];
843 borrow1 = 0;
844 }
845 }
846
847 b->sign = size; /* REC, 21 Apr 1996. */
848 while(!b->n[--size]);
849 b->sign = size+1;
850 }
851
852
853 void addg(giant a, giant b)
854 /* b := b + a, any signs any result. */
855 { int asgn = a->sign, bsgn = b->sign;
856 if(asgn == 0) return;
857 if(bsgn == 0) {
858 gtog(a,b);
859 return;
860 }
861 if((asgn < 0) == (bsgn < 0)) {
862 if(bsgn > 0) {
863 normal_addg(a,b);
864 return;
865 }
866 negg(a); if(a != b) negg(b); normal_addg(a,b); /* Fix REC 1 Dec 98. */
867 negg(a); if(a != b) negg(b); return; /* Fix REC 1 Dec 98. */
868 }
869 if(bsgn > 0) {
870 negg(a);
871 if(gcompg(b,a) >= 0) {
872 normal_subg(a,b);
873 negg(a);
874 return;
875 }
876 reverse_subg(a,b);
877 negg(a);
878 negg(b);
879 return;
880 }
881 negg(b);
882 if(gcompg(b,a) < 0) {
883 reverse_subg(a,b);
884 return;
885 }
886 normal_subg(a,b);
887 negg(b);
888 return;
889 }
890
891 void subg(giant a, giant b)
892 /* b := b - a, any signs, any result. */
893 {
894 int asgn = a->sign, bsgn = b->sign;
895 if(asgn == 0) return;
896 if(bsgn == 0) {
897 gtog(a,b);
898 negg(b);
899 return;
900 }
901 if((asgn < 0) != (bsgn < 0)) {
902 if(bsgn > 0) {
903 negg(a);
904 normal_addg(a,b);
905 negg(a);
906 return;
907 }
908 negg(b);
909 normal_addg(a,b);
910 negg(b);
911 return;
912 }
913 if(bsgn > 0) {
914 if(gcompg(b,a) >= 0) {
915 normal_subg(a,b);
916 return;
917 }
918 reverse_subg(a,b);
919 negg(b);
920 return;
921 }
922 negg(a); negg(b);
923 if(gcompg(b,a) >= 0) {
924 normal_subg(a,b);
925 negg(a);
926 negg(b);
927 return;
928 }
929 reverse_subg(a,b);
930 negg(a);
931 return;
932 }
933
934 static void bdivg(giant v, giant u)
935 /* u becomes greatest power of two not exceeding u/v. */
936 {
937 int diff = bitlen(u) - bitlen(v);
938 giant scratch7;
939
940 if (diff<0) {
941 int_to_giant(0,u);
942 return;
943 }
944 scratch7 = borrowGiant(u->capacity);
945 gtog(v, scratch7);
946 gshiftleft(diff,scratch7);
947 if(gcompg(u,scratch7) < 0) diff--;
948 if(diff<0) {
949 int_to_giant(0,u);
950 returnGiant(scratch7);
951 return;
952 }
953 int_to_giant(1,u);
954 gshiftleft(diff,u);
955 returnGiant(scratch7);
956 }
957
958 int binvaux(giant p, giant x)
959 /* Binary inverse method.
960 Returns zero if no inverse exists, in which case x becomes
961 GCD(x,p). */
962 {
963 giant scratch7;
964 giant u0;
965 giant u1;
966 giant v0;
967 giant v1;
968 int result = 1;
969 int giantSize;
970 PROF_START;
971
972 if(isone(x)) return(result);
973 giantSize = 4 * abs(p->sign);
974 scratch7 = borrowGiant(giantSize);
975 u0 = borrowGiant(giantSize);
976 u1 = borrowGiant(giantSize);
977 v0 = borrowGiant(giantSize);
978 v1 = borrowGiant(giantSize);
979 int_to_giant(1, v0); gtog(x, v1);
980 int_to_giant(0,x); gtog(p, u1);
981 while(!isZero(v1)) {
982 gtog(u1, u0); bdivg(v1, u0);
983 gtog(x, scratch7);
984 gtog(v0, x);
985 mulg(u0, v0);
986 subg(v0,scratch7);
987 gtog(scratch7, v0);
988
989 gtog(u1, scratch7);
990 gtog(v1, u1);
991 mulg(u0, v1);
992 subg(v1,scratch7);
993 gtog(scratch7, v1);
994 }
995 if (!isone(u1)) {
996 gtog(u1,x);
997 if(x->sign<0) addg(p, x);
998 result = 0;
999 goto done;
1000 }
1001 if (x->sign<0) addg(p, x);
1002 done:
1003 returnGiant(scratch7);
1004 returnGiant(u0);
1005 returnGiant(u1);
1006 returnGiant(v0);
1007 returnGiant(v1);
1008 PROF_END(binvauxTime);
1009 return(result);
1010 }
1011
1012 /*
1013 * Superceded by binvg_cp()
1014 */
1015 #if 0
1016 int binvg(giant p, giant x)
1017 {
1018 modg(p, x);
1019 return(binvaux(p,x));
1020 }
1021 #endif
1022
1023 static void absg(giant g) {
1024 /* g becomes the absolute value of g */
1025 if (g->sign < 0) g->sign = -g->sign;
1026 }
1027
1028 void gshiftleft(int bits, giant g) {
1029 /* shift g left bits bits. Equivalent to g = g*2^bits */
1030 int rem = bits & (GIANT_BITS_PER_DIGIT - 1);
1031 int crem = GIANT_BITS_PER_DIGIT - rem;
1032 int digits = 1 + (bits >> GIANT_LOG2_BITS_PER_DIGIT);
1033 int size = abs(g->sign);
1034 int j;
1035 int k;
1036 int sign = gsign(g);
1037 giantDigit carry;
1038 giantDigit dat;
1039
1040 #if FEE_DEBUG
1041 if(bits < 0) {
1042 CKRaise("gshiftleft(-bits)\n");
1043 }
1044 #endif /* FEE_DEBUG */
1045
1046 if(!bits) return;
1047 if(!size) return;
1048 if((size+digits) > (int)g->capacity) {
1049 CKRaise("gshiftleft overflow");
1050 }
1051 k = size - 1 + digits; // (MSD of result + 1)
1052 carry = 0;
1053
1054 /* bug fix for 32-bit giantDigits; this is also an optimization for
1055 * other sizes. rem=0 means we're shifting strictly by digits, no
1056 * bit shifts. */
1057 if(rem == 0) {
1058 g->n[k] = 0; // XXX hack - for sign fixup
1059 for(j=size-1; j>=0; j--) {
1060 g->n[--k] = g->n[j];
1061 }
1062 do{
1063 g->n[--k] = 0;
1064 } while(k>0);
1065 }
1066 else {
1067 /*
1068 * normal unaligned case
1069 * FIXME - this writes past g->n[size-1] the first time thru!
1070 */
1071 for(j=size-1; j>=0; j--) {
1072 dat = g->n[j];
1073 g->n[k--] = (dat >> crem) | carry;
1074 carry = (dat << rem);
1075 }
1076 do{
1077 g->n[k--] = carry;
1078 carry = 0;
1079 } while(k>=0);
1080 }
1081 k = size - 1 + digits;
1082 if(g->n[k] == 0) --k;
1083 g->sign = sign * (k+1);
1084 if (abs(g->sign) > g->capacity) {
1085 CKRaise("gshiftleft overflow");
1086 }
1087 }
1088
1089 void gshiftright(int bits, giant g) {
1090 /* shift g right bits bits. Equivalent to g = g/2^bits */
1091 int j;
1092 int size=abs(g->sign);
1093 giantDigit carry;
1094 int digits = bits >> GIANT_LOG2_BITS_PER_DIGIT;
1095 int remain = bits & (GIANT_BITS_PER_DIGIT - 1);
1096 int cremain = GIANT_BITS_PER_DIGIT - remain;
1097
1098 #if FEE_DEBUG
1099 if(bits < 0) {
1100 CKRaise("gshiftright(-bits)\n");
1101 }
1102 #endif /* FEE_DEBUG */
1103 if(bits==0) return;
1104 if(isZero(g)) return;
1105 if (digits >= size) {
1106 g->sign = 0;
1107 return;
1108 }
1109
1110 size -= digits;
1111
1112 /* Begin OPT: 9 Jan 98 REC. */
1113 if(remain == 0) {
1114 if(g->sign > 0) {
1115 g->sign = size;
1116 }
1117 else {
1118 g->sign = -size;
1119 }
1120 for(j=0; j < size; j++) {
1121 g->n[j] = g->n[j+digits];
1122 }
1123 return;
1124 }
1125 /* End OPT: 9 Jan 98 REC. */
1126
1127 for(j=0;j<size;++j) {
1128 if (j==size-1) {
1129 carry = 0;
1130 }
1131 else {
1132 carry = (g->n[j+digits+1]) << cremain;
1133 }
1134 g->n[j] = ((g->n[j+digits]) >> remain ) | carry;
1135 }
1136 if (g->n[size-1] == 0) {
1137 --size;
1138 }
1139 if(g->sign > 0) {
1140 g->sign = size;
1141 }
1142 else {
1143 g->sign = -size;
1144 }
1145 if (abs(g->sign) > g->capacity) {
1146 CKRaise("gshiftright overflow");
1147 }
1148 }
1149
1150
1151 void extractbits(unsigned n, giant src, giant dest) {
1152 /* dest becomes lowermost n bits of src. Equivalent to dest = src % 2^n */
1153 int digits = n >> GIANT_LOG2_BITS_PER_DIGIT;
1154 int numbytes = digits * GIANT_BYTES_PER_DIGIT;
1155 int bits = n & (GIANT_BITS_PER_DIGIT - 1);
1156
1157 if (n <= 0) {
1158 return;
1159 }
1160 if (dest->capacity * 8 * GIANT_BYTES_PER_DIGIT < n) {
1161 CKRaise("extractbits - not enough room");
1162 }
1163 if (digits >= abs(src->sign)) {
1164 gtog(src,dest);
1165 }
1166 else {
1167 memcpy((char *)(dest->n), (char *)(src->n), numbytes);
1168 if (bits) {
1169 dest->n[digits] = src->n[digits] & ((1<<bits)-1);
1170 ++digits;
1171 }
1172 /* Next, fix by REC, 12 Jan 97. */
1173 // while((dest->n[words-1] == 0) && (words > 0)) --words;
1174 while((digits > 0) && (dest->n[digits-1] == 0)) {
1175 --digits;
1176 }
1177 if(src->sign < 0) {
1178 dest->sign = -digits;
1179 }
1180 else {
1181 dest->sign = digits;
1182 }
1183 }
1184 if (abs(dest->sign) > dest->capacity) {
1185 CKRaise("extractbits overflow");
1186 }
1187 }
1188
1189 #define NEW_MERSENNE 0
1190
1191 /*
1192 * New gmersennemod, 24 Dec 1997. This runs significantly slower than the
1193 * original.
1194 */
1195 #if NEW_MERSENNE
1196
1197 void
1198 gmersennemod(
1199 int n,
1200 giant g
1201 )
1202 /* g := g (mod 2^n - 1) */
1203 {
1204 int the_sign;
1205 giant scratch3 = borrowGiant(g->capacity);
1206 giant scratch4 = borrowGiant(1);
1207
1208 if ((the_sign = gsign(g)) < 0) absg(g);
1209 while (bitlen(g) > n) {
1210 gtog(g,scratch3);
1211 gshiftright(n,scratch3);
1212 addg(scratch3,g);
1213 gshiftleft(n,scratch3);
1214 subg(scratch3,g);
1215 }
1216 if(isZero(g)) goto out;
1217 int_to_giant(1,scratch3);
1218 gshiftleft(n,scratch3);
1219 int_to_giant(1,scratch4);
1220 subg(scratch4,scratch3);
1221 if(gcompg(g,scratch3) >= 0) subg(scratch3,g);
1222 if (the_sign < 0) {
1223 g->sign = -g->sign;
1224 addg(scratch3,g);
1225 }
1226 out:
1227 returnGiant(scratch3);
1228 returnGiant(scratch4);
1229 }
1230
1231 #else /* NEW_MERSENNE */
1232
1233 void gmersennemod(int n, giant g) {
1234 /* g becomes g mod ((2^n)-1)
1235 31 Jul 96 modified REC.
1236 17 Jan 97 modified REC.
1237 */
1238 unsigned bits = n & (GIANT_BITS_PER_DIGIT - 1);
1239 unsigned digits = 1 + ((n-1) >> GIANT_LOG2_BITS_PER_DIGIT);
1240 int isPositive = (g->sign > 0);
1241 int j;
1242 int b;
1243 int size;
1244 int foundzero;
1245 giantDigit mask = (bits == 0) ? GIANT_DIGIT_MASK : (giantDigit)((1<<bits)-1);
1246 giant scratch1;
1247
1248 b = bitlen(g);
1249 if(b < n) {
1250 unsigned numDigits = (n + GIANT_BITS_PER_DIGIT - 1) >>
1251 GIANT_LOG2_BITS_PER_DIGIT;
1252 giantDigit lastWord = 0;
1253 giantDigit bits = 1;
1254
1255 if(g->sign >= 0) return;
1256
1257 /*
1258 * Cons up ((2**n)-1), add to g.
1259 */
1260 scratch1 = borrowGiant(numDigits + 1);
1261 scratch1->sign = numDigits;
1262 for(j=0; j<(int)(numDigits-1); j++) {
1263 scratch1->n[j] = GIANT_DIGIT_MASK;
1264 }
1265
1266 /*
1267 * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
1268 */
1269 for(j=0; j < (int)(n & (GIANT_BITS_PER_DIGIT-1)); j++) {
1270 lastWord |= bits;
1271 bits <<= 1;
1272 }
1273 scratch1->n[numDigits-1] = lastWord;
1274 addg(g, scratch1); /* One version. */
1275 gtog(scratch1, g);
1276 returnGiant(scratch1);
1277 return;
1278 }
1279 if(b == n) {
1280 for(foundzero=0, j=0; j<b; j++) {
1281 if(bitval(g, j)==0) {
1282 foundzero = 1;
1283 break;
1284 }
1285 }
1286 if (!foundzero) {
1287 int_to_giant(0, g);
1288 return;
1289 }
1290 }
1291
1292 absg(g);
1293 scratch1 = borrowGiant(g->capacity);
1294 while ( ((unsigned)(g->sign) > digits) ||
1295 ( ((unsigned)(g->sign)==digits) && (g->n[digits-1] > mask))) {
1296 extractbits(n, g, scratch1);
1297 gshiftright(n, g);
1298 addg(scratch1, g);
1299 }
1300 size = g->sign;
1301
1302 /* Commence new negation routine - REC 17 Jan 1997. */
1303 if (!isPositive) { /* Mersenne negation is just bitwise complement. */
1304 for(j = digits-1; j >= size; j--) {
1305 g->n[j] = GIANT_DIGIT_MASK;
1306 }
1307 for(j = size-1; j >= 0; j--) {
1308 g->n[j] = ~g->n[j];
1309 }
1310 g->n[digits-1] &= mask;
1311 j = digits-1;
1312 while((g->n[j] == 0) && (j > 0)) {
1313 --j;
1314 }
1315 size = j+1;
1316 }
1317 /* End new negation routine. */
1318
1319 g->sign = size;
1320 if (abs(g->sign) > g->capacity) {
1321 CKRaise("gmersennemod overflow");
1322 }
1323 if (size < (int)digits) {
1324 goto bye;
1325 }
1326 if (g->n[size-1] != mask) {
1327 goto bye;
1328 }
1329 mask = GIANT_DIGIT_MASK;
1330 for(j=0; j<(size-1); j++) {
1331 if (g->n[j] != mask) {
1332 goto bye;
1333 }
1334 }
1335 g->sign = 0;
1336 bye:
1337 returnGiant(scratch1);
1338 }
1339
1340 #endif /* NEW_MERSENNE */
1341
1342 void mulg(giant a, giant b) { /* b becomes a*b. */
1343
1344 int i;
1345 int asize, bsize;
1346 giantDigit *bptr = b->n;
1347 giantDigit mult;
1348 giant scratch1;
1349 giantDigit carry;
1350 giantDigit *scrPtr;
1351
1352
1353 if (isZero(b)) {
1354 return;
1355 }
1356 if (isZero(a)) {
1357 gtog(a, b);
1358 return;
1359 }
1360 if(a == b) {
1361 grammarSquare(b);
1362 return;
1363 }
1364
1365 bsize = abs(b->sign);
1366 asize = abs(a->sign);
1367 scratch1 = borrowGiant((asize+bsize));
1368 scrPtr = scratch1->n;
1369
1370 for(i=0; i<asize+bsize; ++i) {
1371 scrPtr[i]=0;
1372 }
1373
1374 for(i=0; i<bsize; ++i, scrPtr++) {
1375 mult = bptr[i];
1376 if (mult != 0) {
1377 carry = VectorMultiply(mult,
1378 a->n,
1379 asize,
1380 scrPtr);
1381 /* handle MSD carry */
1382 scrPtr[asize] += carry;
1383 }
1384 }
1385 bsize+=asize;
1386 if(scratch1->n[bsize - 1] == 0) {
1387 --bsize;
1388 }
1389 scratch1->sign = gsign(a) * gsign(b) * bsize;
1390 if (abs(scratch1->sign) > scratch1->capacity) {
1391 CKRaise("GiantGrammarMul overflow");
1392 }
1393 gtog(scratch1,b);
1394 returnGiant(scratch1);
1395
1396 #if FEE_DEBUG
1397 (void)bitlen(b); // Assertion....
1398 #endif /* FEE_DEBUG */
1399 PROF_INCR(numMulg); // for normal profiling
1400 INCR_MULGS; // for ellipticMeasure
1401 }
1402
1403 void grammarSquare(giant a) {
1404 /*
1405 * For now, we're going to match the old implementation line for
1406 * line by maintaining prod, carry, and temp as double precision
1407 * giantDigits. There is probably a much better implementation....
1408 */
1409 giantDigit prodLo;
1410 giantDigit prodHi;
1411 giantDigit carryLo = 0;
1412 giantDigit carryHi = 0;
1413 giantDigit tempLo;
1414 giantDigit tempHi;
1415 unsigned int cur_term;
1416 unsigned asize;
1417 unsigned max;
1418 giantDigit *ptr = a->n;
1419 giantDigit *ptr1;
1420 giantDigit *ptr2;
1421 giant scratch;
1422
1423 /* dmitch 11 Jan 1998 - special case for a == 0 */
1424 if(a->sign == 0) {
1425 goto end;
1426 }
1427 /* end a == 0 case */
1428 asize = abs(a->sign);
1429 max = asize * 2 - 1;
1430 scratch = borrowGiant(2 * asize);
1431 asize--;
1432
1433 /*
1434 * temp = *ptr;
1435 * temp *= temp;
1436 * scratch->n[0] = temp;
1437 * carry = temp >> 16;
1438 */
1439 giantMulDigits(*ptr, *ptr, &tempLo, &tempHi);
1440 scratch->n[0] = tempLo;
1441 carryLo = tempHi;
1442 carryHi = 0;
1443
1444 for (cur_term = 1; cur_term < max; cur_term++) {
1445 ptr1 = ptr2 = ptr;
1446 if (cur_term <= asize) {
1447 ptr2 += cur_term;
1448 } else {
1449 ptr1 += cur_term - asize;
1450 ptr2 += asize;
1451 }
1452
1453 /*
1454 * prod = carry & 0xFFFF;
1455 * carry >>= 16;
1456 */
1457 prodLo = carryLo;
1458 prodHi = 0;
1459 carryLo = carryHi;
1460 carryHi = 0;
1461 while(ptr1 < ptr2) {
1462 /*
1463 * temp = *ptr1++ * *ptr2--;
1464 */
1465 giantMulDigits(*ptr1++, *ptr2--, &tempLo, &tempHi);
1466
1467 /*
1468 * prod += (temp << 1) & 0xFFFF;
1469 */
1470 giantAddDouble(&prodLo, &prodHi, (tempLo << 1));
1471
1472 /*
1473 * carry += (temp >> 15);
1474 * use bits from both product digits..
1475 */
1476 giantAddDouble(&carryLo, &carryHi,
1477 (tempLo >> (GIANT_BITS_PER_DIGIT - 1)));
1478 giantAddDouble(&carryLo, &carryHi, (tempHi << 1));
1479
1480 /* snag the msb from that last shift */
1481 carryHi += (tempHi >> (GIANT_BITS_PER_DIGIT - 1));
1482 }
1483 if (ptr1 == ptr2) {
1484 /*
1485 * temp = *ptr1;
1486 * temp *= temp;
1487 */
1488 giantMulDigits(*ptr1, *ptr1, &tempLo, &tempHi);
1489
1490 /*
1491 * prod += temp & 0xFFFF;
1492 */
1493 giantAddDouble(&prodLo, &prodHi, tempLo);
1494
1495 /*
1496 * carry += (temp >> 16);
1497 */
1498 giantAddDouble(&carryLo, &carryHi, tempHi);
1499 }
1500
1501 /*
1502 * carry += prod >> 16;
1503 */
1504 giantAddDouble(&carryLo, &carryHi, prodHi);
1505
1506 scratch->n[cur_term] = prodLo;
1507 }
1508 if (carryLo) {
1509 scratch->n[cur_term] = carryLo;
1510 scratch->sign = cur_term+1;
1511 } else scratch->sign = cur_term;
1512
1513 gtog(scratch,a);
1514 returnGiant(scratch);
1515 end:
1516 PROF_INCR(numGsquare);
1517 }
1518
1519 /*
1520 * Clear all of a giant's data fields, for secure erasure of sensitive data.,
1521 */
1522 void clearGiant(giant g)
1523 {
1524 unsigned i;
1525
1526 for(i=0; i<g->capacity; i++) {
1527 g->n[i] = 0;
1528 }
1529 g->sign = 0;
1530 }
1531
1532 #if ENGINE_127_BITS
1533 /*
1534 * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997
1535 */
1536 int
1537 scompg(int n, giant g) {
1538 if((g->sign == 1) && (g->n[0] == n)) return(1);
1539 return(0);
1540 }
1541
1542 #endif // ENGINE_127_BITS
1543
1544 /*
1545 */
1546
1547 /*
1548 * Calculate the reciprocal of a demonimator used in divg_via_recip() and
1549 * modg_via_recip().
1550 */
1551 void
1552 make_recip(giant d, giant r)
1553 /* r becomes the steady-state reciprocal
1554 2^(2b)/d, where b = bit-length of d-1. */
1555 {
1556 int b;
1557 int giantSize = 4 * abs(d->sign);
1558 giant tmp = borrowGiant(giantSize);
1559 giant tmp2 = borrowGiant(giantSize);
1560
1561 if (isZero(d) || (d->sign < 0))
1562 {
1563 CKRaise("illegal argument to make_recip");
1564 }
1565 int_to_giant(1, r); subg(r, d); b = bitlen(d); addg(r, d);
1566 gshiftleft(b, r); gtog(r, tmp2);
1567 while(1) {
1568 gtog(r, tmp);
1569 gsquare(tmp);
1570 gshiftright(b, tmp);
1571 mulg(d, tmp);
1572 gshiftright(b, tmp);
1573 addg(r, r); subg(tmp, r);
1574 if(gcompg(r, tmp2) <= 0) break;
1575 gtog(r, tmp2);
1576 }
1577 int_to_giant(1, tmp);
1578 gshiftleft(2*b, tmp);
1579 gtog(r, tmp2); mulg(d, tmp2);
1580 subg(tmp2, tmp);
1581 int_to_giant(1, tmp2);
1582 while(tmp->sign < 0) {
1583 subg(tmp2, r);
1584 addg(d, tmp);
1585 }
1586
1587 returnGiant(tmp);
1588 returnGiant(tmp2);
1589 return;
1590 }
1591
1592 /*
1593 * Optimized divg, when reciprocal of denominator is known.
1594 */
1595 void
1596 divg_via_recip(giant d, giant r, giant n)
1597 /* n := n/d, where r is the precalculated
1598 steady-state reciprocal of d. */
1599 {
1600 int s = 2*(bitlen(r)-1), sign = gsign(n);
1601 int giantSize = (4 * abs(d->sign)) + abs(n->sign);
1602 giant tmp = borrowGiant(giantSize);
1603 giant tmp2 = borrowGiant(giantSize);
1604
1605 if (isZero(d) || (d->sign < 0))
1606 {
1607 CKRaise("illegal argument to divg_via_recip");
1608 }
1609 n->sign = abs(n->sign);
1610 int_to_giant(0, tmp2);
1611 while(1) {
1612 gtog(n, tmp);
1613 mulg(r, tmp);
1614 gshiftright(s, tmp);
1615 addg(tmp, tmp2);
1616 mulg(d, tmp);
1617 subg(tmp, n);
1618 if(gcompg(n,d) >= 0) {
1619 subg(d,n);
1620 iaddg(1, tmp2);
1621 }
1622 if(gcompg(n,d) < 0) break;
1623 }
1624 gtog(tmp2, n);
1625 n->sign *= sign;
1626 returnGiant(tmp);
1627 returnGiant(tmp2);
1628 return;
1629 }
1630
1631 /*
1632 * Optimized modg, when reciprocal of denominator is known.
1633 */
1634
1635 /* New version, 24 Dec 1997. */
1636
1637 void
1638 modg_via_recip(
1639 giant d,
1640 giant r,
1641 giant n
1642 )
1643 /* This is the fastest mod of the present collection.
1644 n := n % d, where r is the precalculated
1645 steady-state reciprocal of d. */
1646
1647 {
1648 int s = (bitlen(r)-1), sign = n->sign;
1649 int giantSize = (4 * abs(d->sign)) + abs(n->sign);
1650 giant tmp, tmp2;
1651
1652 tmp = borrowGiant(giantSize);
1653 tmp2 = borrowGiant(giantSize);
1654 if (isZero(d) || (d->sign < 0))
1655 {
1656 CKRaise("illegal argument to modg_via_recip");
1657 }
1658 n->sign = abs(n->sign);
1659 while (1)
1660 {
1661 gtog(n, tmp);
1662 /* bug fix 13 Apr 1998 */
1663 if(s == 0) {
1664 gshiftleft(1, tmp);
1665 }
1666 else {
1667 gshiftright(s-1, tmp);
1668 }
1669 /* end fix */
1670 mulg(r, tmp);
1671 gshiftright(s+1, tmp);
1672 mulg(d, tmp);
1673 subg(tmp, n);
1674 if (gcompg(n,d) >= 0)
1675 subg(d,n);
1676 if (gcompg(n,d) < 0)
1677 break;
1678 }
1679 if (sign >= 0)
1680 goto done;
1681 if (isZero(n))
1682 goto done;
1683 negg(n);
1684 addg(d,n);
1685 done:
1686 returnGiant(tmp);
1687 returnGiant(tmp2);
1688 return;
1689 }
1690
1691 /*
1692 * Unoptimized, inefficient general modg, when reciprocal of denominator
1693 * is not known.
1694 */
1695 void
1696 modg(
1697 giant d,
1698 giant n
1699 )
1700 {
1701 /* n becomes n%d. n is arbitrary, but the denominator d must be
1702 * positive! */
1703
1704 /*
1705 * 4/9/2001: seeing overflow on this recip. Alloc per
1706 * d->capacity, not d->sign.
1707 */
1708 //giant recip = borrowGiant(2 * abs(d->sign));
1709 giant recip = borrowGiant(2 * d->capacity);
1710
1711 #if WARN_UNOPTIMIZE
1712 dbgLog(("Warning: unoptimized modg!\n"));
1713 #endif // WARN_UNOPTIMIZE
1714
1715 make_recip(d, recip);
1716 modg_via_recip(d, recip, n);
1717 returnGiant(recip);
1718 }
1719
1720 /*
1721 * Unoptimized, inefficient general divg, when reciprocal of denominator
1722 * is not known.
1723 */
1724 void
1725 divg(
1726 giant d,
1727 giant n
1728 )
1729 {
1730 /* n becomes n/d. n is arbitrary, but the denominator d must be
1731 * positive!
1732 */
1733
1734 giant recip = borrowGiant(2 * abs(d->sign));
1735
1736 #if WARN_UNOPTIMIZE
1737 dbgLog(("Warning: unoptimized divg!\n"));
1738 #endif // WARN_UNOPTIMIZE
1739
1740 make_recip(d, recip);
1741 divg_via_recip(d, recip, n);
1742 returnGiant(recip);
1743 }