1 /* Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
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 COMPUTER, INC. AND THE
6 * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE COMPUTER,
7 * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
8 * EXPOSE YOU TO LIABILITY.
9 ***************************************************************************
11 giantIntegers.c - library for large-integer arithmetic.
15 12/04/98 dmitch/R. Crandall
16 Fixed a==b bug in addg().
18 Changed to compile with C++.
19 13 Apr 98 Fixed shiftright(1) bug in modg_via_recip.
20 09 Apr 98 Doug Mitchell at Apple
21 Major rewrite of core arithmetic routines to make this module
22 independent of size of giantDigit.
23 Removed idivg() and radixdiv().
24 20 Jan 98 Doug Mitchell at Apple
25 Deleted FFT arithmetic; simplified mulg().
26 09 Jan 98 Doug Mitchell and Richard Crandall at Apple
27 gshiftright() optimization.
28 08 Jan 98 Doug Mitchell at Apple
29 newGiant() returns NULL on malloc failure
30 24 Dec 97 Doug Mitchell and Richard Crandall at Apple
31 New grammarSquare(); optimized modg_via_recip()
32 11 Jun 97 Doug Mitchell and Richard Crandall at Apple
33 Added modg_via_recip(), divg_via_recip(), make_recip()
34 Added new multiple giant stack mechanism
35 Fixed potential packing/alignment bug in copyGiant()
36 Added profiling for borrowGiant(), returnGiant()
37 Deleted obsolete ifdef'd code
39 All calls to borrowGiant() now specify required size (no more
41 08 May 97 Doug Mitchell at Apple
42 Changed size of giantstruct.n to 1 for Mac build
43 05 Feb 97 Doug Mitchell at Apple
44 newGiant() no longer modifies CurrentMaxShorts or giant stack
46 01 Feb 97 Doug Mitchell at NeXT
47 Added iszero() check in gcompg
48 17 Jan 97 Richard Crandall, Doug Mitchell at NeXT
49 Fixed negation bug in gmersennemod()
50 Fixed n[words-1] == 0 bug in extractbits()
51 Cleaned up lots of static declarations
52 19 Sep 96 Doug Mitchell at NeXT
53 Fixed --size underflow bug in normal_subg().
54 4 Sep 96 Doug Mitchell at NeXT
55 Fixed (b<n), (sign<0) case in gmersennemod() to allow for arbitrary n.
56 9 Aug 96 Doug Mitchell at NeXT
57 Fixed sign-extend bug in data_to_giant().
58 7 Aug 96 Doug Mitchell at NeXT
59 Changed precision in newtondivide().
60 Removed #ifdef UNUSED code.
61 24 Jul 96 Doug Mitchell at NeXT
63 1991 Richard Crandall at NeXT
72 #include "giantIntegers.h"
75 #include "ellipticMeasure.h"
77 #include "giantPortCommon.h"
80 #if (GIANT_LOG2_BITS_PER_DIGIT == 4)
81 #warning Compiling with two-byte giantDigits
90 void printGiantBuf(giant x
)
94 sprintf(printbuf2
, "sign=%d cap=%d n[]=", x
->sign
, x
->capacity
);
95 for(i
=0; i
<abs(x
->sign
); i
++) {
96 sprintf(printbuf3
+ 10*i
, "%u:", x
->n
[i
]);
102 void printGiantBuf2(giant x
)
106 sprintf(printbuf4
, "sign=%d cap=%d n[]=", x
->sign
, x
->capacity
);
107 for(i
=0; i
<abs(x
->sign
); i
++) {
108 sprintf(printbuf5
+ 10*i
, "%u:", x
->n
[i
]);
111 #endif /* FEE_DEBUG */
113 /******** debugging flags *********/
116 * Flag use of unoptimized divg, modg, binvg
118 //#define WARN_UNOPTIMIZE FEE_DEBUG
119 #define WARN_UNOPTIMIZE 0
122 * Log interesting giant stack events
124 #define LOG_GIANT_STACK 0
127 * Log allocation of giant larger than stack size
129 #define LOG_GIANT_STACK_OVERFLOW 1
132 * Flag newGiant(0) and borrowGiant(0) calls
134 #define WARN_ZERO_GIANT_SIZE FEE_DEBUG
136 /* temp mac-only giant initialization debug */
137 #define GIANT_MAC_DEBUG 0
141 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
142 #include <TextUtils.h>
144 /* this one needs a writable string */
145 static void logCom(unsigned char *str
) {
150 /* constant strings */
151 void dblog0(const char *str
) {
153 strcpy((char *)outStr
, str
);
160 #endif /* GIANT_MAC_DEBUG */
163 #define min(a,b) ((a)<(b)? (a) : (b))
166 #define max(a,b) ((a)>(b)? (a) : (b))
176 static void absg(giant g
); /* g := |g|. */
178 /************** globals *******************/
181 /* ------ giant stack package ------ */
184 * The giant stack package is a local cache which allows us to avoid calls
185 * to malloc() for borrowGiant(). On a 90 Mhz Pentium, enabling the
186 * giant stack package shows about a 1.35 speedup factor over an identical
187 * CryptKit without the giant stacks enabled.
193 #define gstackDbg(x) printf x
194 #else // LOG_GIANT_STACK
196 #endif // LOG_GIANT_STACK
199 unsigned numDigits
; // capacity of giants in this stack
200 unsigned numFree
; // number of free giants in stack
201 unsigned totalGiants
; // total number in *stack
205 static gstack
*gstacks
= NULL
; // array of stacks
206 static unsigned numGstacks
= 0; // # of elements in gstacks
207 static int gstackInitd
= 0; // this module has been init'd
209 #define INIT_NUM_GIANTS 16 /* initial # of giants / stack */
210 #define MIN_GIANT_SIZE 4 /* numDigits for gstack[0] */
211 #define GIANT_SIZE_INCR 2 /* in << bits */
214 * Initialize giant stacks, with up to specified max giant size.
216 void initGiantStacks(unsigned maxDigits
)
218 unsigned curSize
= MIN_GIANT_SIZE
;
222 dblog0("initGiantStacks\n");
226 * Shouldn't be called more than once...
228 printf("multiple initGiantStacks calls\n");
231 gstackDbg(("initGiantStacks(%d)\n", maxDigits
));
237 while(curSize
<=maxDigits
) {
238 curSize
<<= GIANT_SIZE_INCR
;
242 sz
= sizeof(gstack
) * numGstacks
;
243 gstacks
= (gstack
*) fmalloc(sz
);
246 curSize
= MIN_GIANT_SIZE
;
247 for(i
=0; i
<numGstacks
; i
++) {
248 gstacks
[i
].numDigits
= curSize
;
249 curSize
<<= GIANT_SIZE_INCR
;
255 /* called at shut down - free resources */
256 void freeGiantStacks()
265 for(i
=0; i
<numGstacks
; i
++) {
267 for(j
=0; j
<gs
->numFree
; j
++) {
268 freeGiant(gs
->stack
[j
]);
271 /* and the stack itself - may be null if this was never used */
272 if(gs
->stack
!= NULL
) {
282 #endif // GIANTS_VIA_STACK
284 giant
borrowGiant(unsigned numDigits
)
291 gstack
*gs
= gstacks
;
293 #if WARN_ZERO_GIANT_SIZE
295 printf("borrowGiant(0)\n");
296 numDigits
= gstacks
[numGstacks
-1].numDigits
;
298 #endif // WARN_ZERO_GIANT_SIZE
301 * Find appropriate stack
303 if(numDigits
<= MIN_GIANT_SIZE
)
305 else if (numDigits
<= (MIN_GIANT_SIZE
<< GIANT_SIZE_INCR
))
307 else if (numDigits
<= (MIN_GIANT_SIZE
<< (2 * GIANT_SIZE_INCR
)))
309 else if (numDigits
<= (MIN_GIANT_SIZE
<< (3 * GIANT_SIZE_INCR
)))
311 else if (numDigits
<= (MIN_GIANT_SIZE
<< (4 * GIANT_SIZE_INCR
)))
314 stackNum
= numGstacks
;
316 if(stackNum
>= numGstacks
) {
318 * out of bounds; just malloc
320 #if LOG_GIANT_STACK_OVERFLOW
321 gstackDbg(("giantFromStack overflow; numDigits %d\n",
323 #endif // LOG_GIANT_STACK_OVERFLOW
324 return newGiant(numDigits
);
326 gs
= &gstacks
[stackNum
];
329 if((gs
->numFree
!= 0) && (gs
->stack
== NULL
)) {
330 dblog0("borrowGiant: null stack!\n");
334 if(gs
->numFree
!= 0) {
335 result
= gs
->stack
[--gs
->numFree
];
339 * Stack empty; malloc
341 result
= newGiant(gs
->numDigits
);
344 #else /* GIANTS_VIA_STACK */
346 result
= newGiant(numDigits
);
348 #endif /* GIANTS_VIA_STACK */
350 PROF_INCR(numBorrows
);
354 void returnGiant(giant g
)
361 unsigned cap
= g
->capacity
;
366 CKRaise("returnGiant before stacks initialized!");
372 dblog0("returnGiant: null g!\n");
377 * Find appropriate stack. Note we expect exact match of
378 * capacity and stack's giant size.
381 * Optimized unrolled loop. Just make sure there are enough cases
382 * to handle all of the stacks. Errors in this case will be flagged
383 * via LOG_GIANT_STACK_OVERFLOW.
389 case MIN_GIANT_SIZE
<< GIANT_SIZE_INCR
:
392 case MIN_GIANT_SIZE
<< (2 * GIANT_SIZE_INCR
):
395 case MIN_GIANT_SIZE
<< (3 * GIANT_SIZE_INCR
):
398 case MIN_GIANT_SIZE
<< (4 * GIANT_SIZE_INCR
):
402 stackNum
= numGstacks
;
406 if(stackNum
>= numGstacks
) {
408 * out of bounds; just free
410 #if LOG_GIANT_STACK_OVERFLOW
411 gstackDbg(("giantToStack overflow; numDigits %d\n", cap
));
412 #endif // LOG_GIANT_STACK_OVERFLOW
416 gs
= &gstacks
[stackNum
];
417 if(gs
->numFree
== gs
->totalGiants
) {
418 if(gs
->totalGiants
== 0) {
419 gstackDbg(("Initial alloc of gstack(%d)\n",
421 gs
->totalGiants
= INIT_NUM_GIANTS
;
424 gs
->totalGiants
*= 2;
425 gstackDbg(("Bumping gstack(%d) to %d\n",
426 gs
->numDigits
, gs
->totalGiants
));
428 gs
->stack
= (giantstruct
**) frealloc(gs
->stack
, gs
->totalGiants
*sizeof(giant
));
430 g
->sign
= 0; // not sure this is important...
431 gs
->stack
[gs
->numFree
++] = g
;
434 if((gs
->numFree
!= 0) && (gs
->stack
== NULL
)) {
435 dblog0("borrowGiant: null stack!\n");
439 #else /* GIANTS_VIA_STACK */
443 #endif /* GIANTS_VIA_STACK */
446 void freeGiant(giant x
) {
450 giant
newGiant(unsigned numDigits
) {
451 // giant sufficient for 2^numbits+16 sized ops
455 #if WARN_ZERO_GIANT_SIZE
457 printf("newGiant(0)\n");
459 numDigits
= gstacks
[numGstacks
-1].totalGiants
;
465 #endif // WARN_ZERO_GIANT_SIZE
467 size
= (numDigits
-1) * GIANT_BYTES_PER_DIGIT
+ sizeof(giantstruct
);
468 result
= (giant
)fmalloc(size
);
473 result
->capacity
= numDigits
;
477 giant
copyGiant(giant x
)
481 giant result
= newGiant(x
->capacity
);
485 * NO! this assumes packed alignment
487 bytes
= sizeof(giantstruct
) +
488 ((x
->capacity
- 1) * GIANT_BYTES_PER_DIGIT
);
489 bcopy(x
, result
, bytes
);
493 /* ------ initialization and utility routines ------ */
496 unsigned bitlen(giant n
) {
497 unsigned b
= GIANT_BITS_PER_DIGIT
;
498 giantDigit c
= 1 << (GIANT_BITS_PER_DIGIT
- 1);
504 w
= n
->n
[abs(n
->sign
) - 1];
506 CKRaise("bitlen - no bit set!");
512 return(GIANT_BITS_PER_DIGIT
* (abs(n
->sign
)-1) + b
);
515 int bitval(giant n
, int pos
) {
516 int i
= abs(pos
) >> GIANT_LOG2_BITS_PER_DIGIT
;
517 giantDigit c
= 1 << (pos
& (GIANT_BITS_PER_DIGIT
- 1));
519 return((n
->n
[i
]) & c
);
523 /* returns the sign of g */
525 if (isZero(g
)) return(0);
526 if (g
->sign
> 0) return(1);
531 * Adjust sign for possible leading (m.s.) zero digits
533 void gtrimSign(giant g
)
535 int numDigits
= abs(g
->sign
);
538 for(i
=numDigits
-1; i
>=0; i
--) {
547 g
->sign
= -numDigits
;
556 return((g
->sign
==1)&&(g
->n
[0]==1));
559 int isZero(giant thegiant
) {
560 /* Returns TRUE if thegiant == 0. */
562 int length
= abs(thegiant
->sign
);
563 giantDigit
*numpointer
;
566 numpointer
= thegiant
->n
;
568 for(count
= 0; count
<length
; ++count
,++numpointer
)
569 if (*numpointer
!= 0 ) return(FALSE
);
574 int gcompg(giant a
, giant b
)
575 /* returns -1,0,1 if a<b, a=b, a>b, respectively */
584 if(isZero(a
) && isZero(b
)) return 0;
585 if(sa
> sb
) return(1);
586 if(sa
< sb
) return(-1);
588 sa
= -sa
; /* Take absolute value of sa */
591 for(j
= sa
-1; j
>= 0; j
--) {
592 va
= a
->n
[j
]; vb
= b
->n
[j
];
593 if (va
> vb
) return(sgn
);
594 if (va
< vb
) return(-sgn
);
599 /* destgiant becomes equal to srcgiant */
600 void gtog(giant srcgiant
, giant destgiant
) {
604 CKASSERT(srcgiant
!= NULL
);
605 numbytes
= abs(srcgiant
->sign
) * GIANT_BYTES_PER_DIGIT
;
606 if (destgiant
->capacity
< abs(srcgiant
->sign
))
607 CKRaise("gtog overflow!!");
608 memcpy((char *)destgiant
->n
, (char *)srcgiant
->n
, numbytes
);
609 destgiant
->sign
= srcgiant
->sign
;
612 void int_to_giant(int i
, giant g
) {
613 /* The giant g becomes set to the integer value i. */
615 unsigned int j
= abs(i
);
624 if(GIANT_BYTES_PER_DIGIT
== sizeof(int)) {
629 /* one loop per digit */
630 unsigned scnt
= GIANT_BITS_PER_DIGIT
; // fool compiler
632 for(dex
=0; dex
<sizeof(int); dex
++) {
633 g
->n
[dex
] = j
& GIANT_DIGIT_MASK
;
642 g
->sign
= -(g
->sign
);
646 /*------------- Arithmetic --------------*/
653 void iaddg(int i
, giant g
) { /* positive g becomes g + (int)i */
656 int size
= abs(g
->sign
);
663 for(j
=0; ((j
<size
) && (carry
!= 0)); j
++) {
664 g
->n
[j
] = giantAddDigits(g
->n
[j
], carry
, &carry
);
669 if (g
->sign
> (int)g
->capacity
) CKRaise("iaddg overflow!");
678 * FIXME - we can improve this...
680 void imulg(unsigned n
, giant g
)
682 giant tmp
= borrowGiant(abs(g
->sign
) + sizeof(int));
684 int_to_giant(n
, tmp
);
689 /* new addg, negg, and gcompg from Crandall 6/95 */
690 static void normal_addg(giant a
, giant b
)
691 /* b := a + b, both a,b assumed non-negative. */
693 giantDigit carry1
= 0;
694 giantDigit carry2
= 0;
695 int asize
= a
->sign
, bsize
= b
->sign
;
696 giantDigit
*an
= a
->n
;
697 giantDigit
*bn
= b
->n
;
712 /* first handle the common digits */
713 for(j
=0; j
<comSize
; j
++) {
715 * first add the carry, then an[j] - either add could result
718 if(carry1
|| carry2
) {
719 tmp
= giantAddDigits(bn
[j
], (giantDigit
)1, &carry1
);
725 bn
[j
] = giantAddDigits(tmp
, an
[j
], &carry2
);
730 /* now propagate remaining carry beyond asize */
735 for(; j
<bsize
; j
++) {
736 bn
[j
] = giantAddDigits(bn
[j
], (giantDigit
)1, &carry1
);
743 /* now propagate remaining an[] and carry beyond bsize */
747 for(; j
<asize
; j
++) {
749 bn
[j
] = giantAddDigits(an
[j
], (giantDigit
)1, &carry1
);
762 if (b
->sign
> (int)b
->capacity
) CKRaise("iaddg overflow!");
767 static void normal_subg(giant a
, giant b
)
768 /* b := b - a; requires b, a non-negative and b >= a. */
773 giantDigit borrow1
= 0;
774 giantDigit borrow2
= 0;
775 giantDigit
*an
= a
->n
;
776 giantDigit
*bn
= b
->n
;
782 for (j
=0; j
<a
->sign
; ++j
) {
783 if(borrow1
|| borrow2
) {
784 tmp
= giantSubDigits(bn
[j
], (giantDigit
)1, &borrow1
);
790 bn
[j
] = giantSubDigits(tmp
, an
[j
], &borrow2
);
792 if(borrow1
|| borrow2
) {
793 /* propagate borrow thru remainder of bn[] */
795 for (j
=a
->sign
; j
<size
; ++j
) {
797 bn
[j
] = giantSubDigits(bn
[j
], (giantDigit
)1, &borrow1
);
805 /* adjust sign for leading zero digits */
806 while((size
-- > 0) && (b
->n
[size
] == 0))
808 b
->sign
= (b
->n
[size
] == 0)? 0 : size
+1;
811 static void reverse_subg(giant a
, giant b
)
812 /* b := a - b; requires b, a non-negative and a >= b. */
817 giantDigit borrow1
= 0;
818 giantDigit borrow2
= 0;
819 giantDigit
*an
= a
->n
;
820 giantDigit
*bn
= b
->n
;
826 for (j
=0; j
<b
->sign
; ++j
) {
827 if(borrow1
|| borrow2
) {
828 tmp
= giantSubDigits(an
[j
], (giantDigit
)1, &borrow1
);
834 bn
[j
] = giantSubDigits(tmp
, bn
[j
], &borrow2
);
836 if(borrow1
|| borrow2
) {
837 /* propagate borrow thru remainder of bn[] */
840 for (j
=b
->sign
; j
<size
; ++j
) {
842 bn
[j
] = giantSubDigits(an
[j
], (giantDigit
)1, &borrow1
);
850 b
->sign
= size
; /* REC, 21 Apr 1996. */
851 while(!b
->n
[--size
]);
856 void addg(giant a
, giant b
)
857 /* b := b + a, any signs any result. */
858 { int asgn
= a
->sign
, bsgn
= b
->sign
;
859 if(asgn
== 0) return;
864 if((asgn
< 0) == (bsgn
< 0)) {
869 negg(a
); if(a
!= b
) negg(b
); normal_addg(a
,b
); /* Fix REC 1 Dec 98. */
870 negg(a
); if(a
!= b
) negg(b
); return; /* Fix REC 1 Dec 98. */
874 if(gcompg(b
,a
) >= 0) {
885 if(gcompg(b
,a
) < 0) {
894 void subg(giant a
, giant b
)
895 /* b := b - a, any signs, any result. */
897 int asgn
= a
->sign
, bsgn
= b
->sign
;
898 if(asgn
== 0) return;
904 if((asgn
< 0) != (bsgn
< 0)) {
917 if(gcompg(b
,a
) >= 0) {
926 if(gcompg(b
,a
) >= 0) {
937 static void bdivg(giant v
, giant u
)
938 /* u becomes greatest power of two not exceeding u/v. */
940 int diff
= bitlen(u
) - bitlen(v
);
947 scratch7
= borrowGiant(u
->capacity
);
949 gshiftleft(diff
,scratch7
);
950 if(gcompg(u
,scratch7
) < 0) diff
--;
953 returnGiant(scratch7
);
958 returnGiant(scratch7
);
961 int binvaux(giant p
, giant x
)
962 /* Binary inverse method.
963 Returns zero if no inverse exists, in which case x becomes
975 if(isone(x
)) return(result
);
976 giantSize
= 4 * abs(p
->sign
);
977 scratch7
= borrowGiant(giantSize
);
978 u0
= borrowGiant(giantSize
);
979 u1
= borrowGiant(giantSize
);
980 v0
= borrowGiant(giantSize
);
981 v1
= borrowGiant(giantSize
);
982 int_to_giant(1, v0
); gtog(x
, v1
);
983 int_to_giant(0,x
); gtog(p
, u1
);
985 gtog(u1
, u0
); bdivg(v1
, u0
);
1000 if(x
->sign
<0) addg(p
, x
);
1004 if (x
->sign
<0) addg(p
, x
);
1006 returnGiant(scratch7
);
1011 PROF_END(binvauxTime
);
1016 * Superceded by binvg_cp()
1019 int binvg(giant p
, giant x
)
1022 return(binvaux(p
,x
));
1026 static void absg(giant g
) {
1027 /* g becomes the absolute value of g */
1028 if (g
->sign
< 0) g
->sign
= -g
->sign
;
1031 void gshiftleft(int bits
, giant g
) {
1032 /* shift g left bits bits. Equivalent to g = g*2^bits */
1033 int rem
= bits
& (GIANT_BITS_PER_DIGIT
- 1);
1034 int crem
= GIANT_BITS_PER_DIGIT
- rem
;
1035 int digits
= 1 + (bits
>> GIANT_LOG2_BITS_PER_DIGIT
);
1036 int size
= abs(g
->sign
);
1039 int sign
= gsign(g
);
1045 CKRaise("gshiftleft(-bits)\n");
1047 #endif /* FEE_DEBUG */
1051 if((size
+digits
) > (int)g
->capacity
) {
1052 CKRaise("gshiftleft overflow");
1055 k
= size
- 1 + digits
; // (MSD of result + 1)
1058 /* bug fix for 32-bit giantDigits; this is also an optimization for
1059 * other sizes. rem=0 means we're shifting strictly by digits, no
1062 g
->n
[k
] = 0; // XXX hack - for sign fixup
1063 for(j
=size
-1; j
>=0; j
--) {
1064 g
->n
[--k
] = g
->n
[j
];
1072 * normal unaligned case
1073 * FIXME - this writes past g->n[size-1] the first time thru!
1075 for(j
=size
-1; j
>=0; j
--) {
1077 g
->n
[k
--] = (dat
>> crem
) | carry
;
1078 carry
= (dat
<< rem
);
1085 k
= size
- 1 + digits
;
1086 if(g
->n
[k
] == 0) --k
;
1087 g
->sign
= sign
* (k
+1);
1088 if (abs(g
->sign
) > g
->capacity
) {
1089 CKRaise("gshiftleft overflow");
1093 void gshiftright(int bits
, giant g
) {
1094 /* shift g right bits bits. Equivalent to g = g/2^bits */
1096 int size
=abs(g
->sign
);
1098 int digits
= bits
>> GIANT_LOG2_BITS_PER_DIGIT
;
1099 int remain
= bits
& (GIANT_BITS_PER_DIGIT
- 1);
1100 int cremain
= GIANT_BITS_PER_DIGIT
- remain
;
1104 CKRaise("gshiftright(-bits)\n");
1106 #endif /* FEE_DEBUG */
1108 if(isZero(g
)) return;
1109 if (digits
>= size
) {
1116 /* Begin OPT: 9 Jan 98 REC. */
1124 for(j
=0; j
< size
; j
++) {
1125 g
->n
[j
] = g
->n
[j
+digits
];
1129 /* End OPT: 9 Jan 98 REC. */
1131 for(j
=0;j
<size
;++j
) {
1136 carry
= (g
->n
[j
+digits
+1]) << cremain
;
1138 g
->n
[j
] = ((g
->n
[j
+digits
]) >> remain
) | carry
;
1140 if (g
->n
[size
-1] == 0) {
1149 if (abs(g
->sign
) > g
->capacity
) {
1150 CKRaise("gshiftright overflow");
1155 void extractbits(unsigned n
, giant src
, giant dest
) {
1156 /* dest becomes lowermost n bits of src. Equivalent to dest = src % 2^n */
1157 int digits
= n
>> GIANT_LOG2_BITS_PER_DIGIT
;
1158 int numbytes
= digits
* GIANT_BYTES_PER_DIGIT
;
1159 int bits
= n
& (GIANT_BITS_PER_DIGIT
- 1);
1164 if (dest
->capacity
* 8 * GIANT_BYTES_PER_DIGIT
< n
) {
1165 CKRaise("extractbits - not enough room");
1167 if (digits
>= abs(src
->sign
)) {
1171 memcpy((char *)(dest
->n
), (char *)(src
->n
), numbytes
);
1173 dest
->n
[digits
] = src
->n
[digits
] & ((1<<bits
)-1);
1176 /* Next, fix by REC, 12 Jan 97. */
1177 // while((dest->n[words-1] == 0) && (words > 0)) --words;
1178 while((digits
> 0) && (dest
->n
[digits
-1] == 0)) {
1182 dest
->sign
= -digits
;
1185 dest
->sign
= digits
;
1188 if (abs(dest
->sign
) > dest
->capacity
) {
1189 CKRaise("extractbits overflow");
1193 #define NEW_MERSENNE 0
1196 * New gmersennemod, 24 Dec 1997. This runs significantly slower than the
1206 /* g := g (mod 2^n - 1) */
1209 giant scratch3
= borrowGiant(g
->capacity
);
1210 giant scratch4
= borrowGiant(1);
1212 if ((the_sign
= gsign(g
)) < 0) absg(g
);
1213 while (bitlen(g
) > n
) {
1215 gshiftright(n
,scratch3
);
1217 gshiftleft(n
,scratch3
);
1220 if(isZero(g
)) goto out
;
1221 int_to_giant(1,scratch3
);
1222 gshiftleft(n
,scratch3
);
1223 int_to_giant(1,scratch4
);
1224 subg(scratch4
,scratch3
);
1225 if(gcompg(g
,scratch3
) >= 0) subg(scratch3
,g
);
1231 returnGiant(scratch3
);
1232 returnGiant(scratch4
);
1235 #else /* NEW_MERSENNE */
1237 void gmersennemod(int n
, giant g
) {
1238 /* g becomes g mod ((2^n)-1)
1239 31 Jul 96 modified REC.
1240 17 Jan 97 modified REC.
1242 unsigned bits
= n
& (GIANT_BITS_PER_DIGIT
- 1);
1243 unsigned digits
= 1 + ((n
-1) >> GIANT_LOG2_BITS_PER_DIGIT
);
1244 int isPositive
= (g
->sign
> 0);
1249 giantDigit mask
= (bits
== 0) ? GIANT_DIGIT_MASK
: (giantDigit
)((1<<bits
)-1);
1254 unsigned numDigits
= (n
+ GIANT_BITS_PER_DIGIT
- 1) >>
1255 GIANT_LOG2_BITS_PER_DIGIT
;
1256 giantDigit lastWord
= 0;
1257 giantDigit bits
= 1;
1259 if(g
->sign
>= 0) return;
1262 * Cons up ((2**n)-1), add to g.
1264 scratch1
= borrowGiant(numDigits
+ 1);
1265 scratch1
->sign
= numDigits
;
1266 for(j
=0; j
<(int)(numDigits
-1); j
++) {
1267 scratch1
->n
[j
] = GIANT_DIGIT_MASK
;
1271 * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
1273 for(j
=0; j
< (int)(n
& (GIANT_BITS_PER_DIGIT
-1)); j
++) {
1277 scratch1
->n
[numDigits
-1] = lastWord
;
1278 addg(g
, scratch1
); /* One version. */
1280 returnGiant(scratch1
);
1284 for(foundzero
=0, j
=0; j
<b
; j
++) {
1285 if(bitval(g
, j
)==0) {
1297 scratch1
= borrowGiant(g
->capacity
);
1298 while ( ((unsigned)(g
->sign
) > digits
) ||
1299 ( ((unsigned)(g
->sign
)==digits
) && (g
->n
[digits
-1] > mask
))) {
1300 extractbits(n
, g
, scratch1
);
1306 /* Commence new negation routine - REC 17 Jan 1997. */
1307 if (!isPositive
) { /* Mersenne negation is just bitwise complement. */
1308 for(j
= digits
-1; j
>= size
; j
--) {
1309 g
->n
[j
] = GIANT_DIGIT_MASK
;
1311 for(j
= size
-1; j
>= 0; j
--) {
1314 g
->n
[digits
-1] &= mask
;
1316 while((g
->n
[j
] == 0) && (j
> 0)) {
1321 /* End new negation routine. */
1324 if (abs(g
->sign
) > g
->capacity
) {
1325 CKRaise("gmersennemod overflow");
1327 if (size
< (int)digits
) {
1330 if (g
->n
[size
-1] != mask
) {
1333 mask
= GIANT_DIGIT_MASK
;
1334 for(j
=0; j
<(size
-1); j
++) {
1335 if (g
->n
[j
] != mask
) {
1341 returnGiant(scratch1
);
1344 #endif /* NEW_MERSENNE */
1346 void mulg(giant a
, giant b
) { /* b becomes a*b. */
1350 giantDigit
*bptr
= b
->n
;
1369 bsize
= abs(b
->sign
);
1370 asize
= abs(a
->sign
);
1371 scratch1
= borrowGiant((asize
+bsize
));
1372 scrPtr
= scratch1
->n
;
1374 for(i
=0; i
<asize
+bsize
; ++i
) {
1378 for(i
=0; i
<bsize
; ++i
, scrPtr
++) {
1381 carry
= VectorMultiply(mult
,
1385 /* handle MSD carry */
1386 scrPtr
[asize
] += carry
;
1390 if(scratch1
->n
[bsize
- 1] == 0) {
1393 scratch1
->sign
= gsign(a
) * gsign(b
) * bsize
;
1394 if (abs(scratch1
->sign
) > scratch1
->capacity
) {
1395 CKRaise("GiantGrammarMul overflow");
1398 returnGiant(scratch1
);
1401 (void)bitlen(b
); // Assertion....
1402 #endif /* FEE_DEBUG */
1403 PROF_INCR(numMulg
); // for normal profiling
1404 INCR_MULGS
; // for ellipticMeasure
1407 void grammarSquare(giant a
) {
1409 * For now, we're going to match the old implementation line for
1410 * line by maintaining prod, carry, and temp as double precision
1411 * giantDigits. There is probably a much better implementation....
1415 giantDigit carryLo
= 0;
1416 giantDigit carryHi
= 0;
1419 unsigned int cur_term
;
1422 giantDigit
*ptr
= a
->n
;
1427 /* dmitch 11 Jan 1998 - special case for a == 0 */
1431 /* end a == 0 case */
1432 asize
= abs(a
->sign
);
1433 max
= asize
* 2 - 1;
1434 scratch
= borrowGiant(2 * asize
);
1440 * scratch->n[0] = temp;
1441 * carry = temp >> 16;
1443 giantMulDigits(*ptr
, *ptr
, &tempLo
, &tempHi
);
1444 scratch
->n
[0] = tempLo
;
1448 for (cur_term
= 1; cur_term
< max
; cur_term
++) {
1450 if (cur_term
<= asize
) {
1453 ptr1
+= cur_term
- asize
;
1458 * prod = carry & 0xFFFF;
1465 while(ptr1
< ptr2
) {
1467 * temp = *ptr1++ * *ptr2--;
1469 giantMulDigits(*ptr1
++, *ptr2
--, &tempLo
, &tempHi
);
1472 * prod += (temp << 1) & 0xFFFF;
1474 giantAddDouble(&prodLo
, &prodHi
, (tempLo
<< 1));
1477 * carry += (temp >> 15);
1478 * use bits from both product digits..
1480 giantAddDouble(&carryLo
, &carryHi
,
1481 (tempLo
>> (GIANT_BITS_PER_DIGIT
- 1)));
1482 giantAddDouble(&carryLo
, &carryHi
, (tempHi
<< 1));
1484 /* snag the msb from that last shift */
1485 carryHi
+= (tempHi
>> (GIANT_BITS_PER_DIGIT
- 1));
1492 giantMulDigits(*ptr1
, *ptr1
, &tempLo
, &tempHi
);
1495 * prod += temp & 0xFFFF;
1497 giantAddDouble(&prodLo
, &prodHi
, tempLo
);
1500 * carry += (temp >> 16);
1502 giantAddDouble(&carryLo
, &carryHi
, tempHi
);
1506 * carry += prod >> 16;
1508 giantAddDouble(&carryLo
, &carryHi
, prodHi
);
1510 scratch
->n
[cur_term
] = prodLo
;
1513 scratch
->n
[cur_term
] = carryLo
;
1514 scratch
->sign
= cur_term
+1;
1515 } else scratch
->sign
= cur_term
;
1518 returnGiant(scratch
);
1520 PROF_INCR(numGsquare
);
1524 * Clear all of a giant's data fields, for secure erasure of sensitive data.,
1526 void clearGiant(giant g
)
1530 for(i
=0; i
<g
->capacity
; i
++) {
1538 * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997
1541 scompg(int n
, giant g
) {
1542 if((g
->sign
== 1) && (g
->n
[0] == n
)) return(1);
1546 #endif // ENGINE_127_BITS
1549 * New modg() and divg() arithmetic, from R. Crandall, 11 June 1997.
1553 * Calculate the reciprocal of a demonimator used in divg_via_recip() and
1557 make_recip(giant d
, giant r
)
1558 /* r becomes the steady-state reciprocal
1559 2^(2b)/d, where b = bit-length of d-1. */
1562 int giantSize
= 4 * abs(d
->sign
);
1563 giant tmp
= borrowGiant(giantSize
);
1564 giant tmp2
= borrowGiant(giantSize
);
1566 if (isZero(d
) || (d
->sign
< 0))
1568 CKRaise("illegal argument to make_recip");
1570 int_to_giant(1, r
); subg(r
, d
); b
= bitlen(d
); addg(r
, d
);
1571 gshiftleft(b
, r
); gtog(r
, tmp2
);
1575 gshiftright(b
, tmp
);
1577 gshiftright(b
, tmp
);
1578 addg(r
, r
); subg(tmp
, r
);
1579 if(gcompg(r
, tmp2
) <= 0) break;
1582 int_to_giant(1, tmp
);
1583 gshiftleft(2*b
, tmp
);
1584 gtog(r
, tmp2
); mulg(d
, tmp2
);
1586 int_to_giant(1, tmp2
);
1587 while(tmp
->sign
< 0) {
1598 * Optimized divg, when reciprocal of denominator is known.
1601 divg_via_recip(giant d
, giant r
, giant n
)
1602 /* n := n/d, where r is the precalculated
1603 steady-state reciprocal of d. */
1605 int s
= 2*(bitlen(r
)-1), sign
= gsign(n
);
1606 int giantSize
= (4 * abs(d
->sign
)) + abs(n
->sign
);
1607 giant tmp
= borrowGiant(giantSize
);
1608 giant tmp2
= borrowGiant(giantSize
);
1610 if (isZero(d
) || (d
->sign
< 0))
1612 CKRaise("illegal argument to divg_via_recip");
1614 n
->sign
= abs(n
->sign
);
1615 int_to_giant(0, tmp2
);
1619 gshiftright(s
, tmp
);
1623 if(gcompg(n
,d
) >= 0) {
1627 if(gcompg(n
,d
) < 0) break;
1637 * Optimized modg, when reciprocal of denominator is known.
1640 /* New version, 24 Dec 1997. */
1648 /* This is the fastest mod of the present collection.
1649 n := n % d, where r is the precalculated
1650 steady-state reciprocal of d. */
1653 int s
= (bitlen(r
)-1), sign
= n
->sign
;
1654 int giantSize
= (4 * abs(d
->sign
)) + abs(n
->sign
);
1657 tmp
= borrowGiant(giantSize
);
1658 tmp2
= borrowGiant(giantSize
);
1659 if (isZero(d
) || (d
->sign
< 0))
1661 CKRaise("illegal argument to modg_via_recip");
1663 n
->sign
= abs(n
->sign
);
1667 /* bug fix 13 Apr 1998 */
1672 gshiftright(s
-1, tmp
);
1676 gshiftright(s
+1, tmp
);
1679 if (gcompg(n
,d
) >= 0)
1681 if (gcompg(n
,d
) < 0)
1697 * Unoptimized, inefficient general modg, when reciprocal of denominator
1706 /* n becomes n%d. n is arbitrary, but the denominator d must be
1710 * 4/9/2001: seeing overflow on this recip. Alloc per
1711 * d->capacity, not d->sign.
1713 //giant recip = borrowGiant(2 * abs(d->sign));
1714 giant recip
= borrowGiant(2 * d
->capacity
);
1717 dbgLog(("Warning: unoptimized modg!\n"));
1718 #endif // WARN_UNOPTIMIZE
1720 make_recip(d
, recip
);
1721 modg_via_recip(d
, recip
, n
);
1726 * Unoptimized, inefficient general divg, when reciprocal of denominator
1735 /* n becomes n/d. n is arbitrary, but the denominator d must be
1739 giant recip
= borrowGiant(2 * abs(d
->sign
));
1742 dbgLog(("Warning: unoptimized divg!\n"));
1743 #endif // WARN_UNOPTIMIZE
1745 make_recip(d
, recip
);
1746 divg_via_recip(d
, recip
, n
);