1 /* Copyright (c) 1998,2011-2014 Apple 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, 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 ***************************************************************************
11 giantIntegers.c - library for large-integer arithmetic.
15 Fixed a==b bug in addg().
17 Changed to compile with C++.
18 13 Apr 98 Fixed shiftright(1) bug in modg_via_recip.
20 Major rewrite of core arithmetic routines to make this module
21 independent of size of giantDigit.
22 Removed idivg() and radixdiv().
24 Deleted FFT arithmetic; simplified mulg().
26 gshiftright() optimization.
28 newGiant() returns NULL on malloc failure
30 New grammarSquare(); optimized modg_via_recip()
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
38 All calls to borrowGiant() now specify required size (no more
41 Changed size of giantstruct.n to 1 for Mac build
43 newGiant() no longer modifies CurrentMaxShorts or giant stack
46 Added iszero() check in gcompg
48 Fixed negation bug in gmersennemod()
49 Fixed n[words-1] == 0 bug in extractbits()
50 Cleaned up lots of static declarations
52 Fixed --size underflow bug in normal_subg().
54 Fixed (b<n), (sign<0) case in gmersennemod() to allow for arbitrary n.
56 Fixed sign-extend bug in data_to_giant().
58 Changed precision in newtondivide().
59 Removed #ifdef UNUSED code.
70 #include "giantIntegers.h"
73 #include "ellipticMeasure.h"
75 #include "giantPortCommon.h"
78 #if (GIANT_LOG2_BITS_PER_DIGIT == 4)
79 #warning Compiling with two-byte giantDigits
88 void printGiantBuf(giant x
)
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
]);
100 void printGiantBuf2(giant x
)
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
]);
109 #endif /* FEE_DEBUG */
112 /******** debugging flags *********/
115 * Flag use of unoptimized divg, modg, binvg
117 //#define WARN_UNOPTIMIZE FEE_DEBUG
118 #define WARN_UNOPTIMIZE 0
121 * Log interesting giant stack events
123 #define LOG_GIANT_STACK 0
126 * Log allocation of giant larger than stack size
128 #define LOG_GIANT_STACK_OVERFLOW 1
131 * Flag newGiant(0) and borrowGiant(0) calls
133 #define WARN_ZERO_GIANT_SIZE FEE_DEBUG
135 /* temp mac-only giant initialization debug */
136 #define GIANT_MAC_DEBUG 0
140 #include <TextUtils.h>
142 /* this one needs a writable string */
143 static void logCom(unsigned char *str
) {
148 /* constant strings */
149 void dblog0(const char *str
) {
151 strcpy((char *)outStr
, str
);
158 #endif /* GIANT_MAC_DEBUG */
161 #define min(a,b) ((a)<(b)? (a) : (b))
164 #define max(a,b) ((a)>(b)? (a) : (b))
174 static void absg(giant g
); /* g := |g|. */
176 /************** globals *******************/
179 /* ------ giant stack package ------ */
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.
191 #define gstackDbg(x) printf x
192 #else // LOG_GIANT_STACK
194 #endif // LOG_GIANT_STACK
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
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
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 */
212 * Initialize giant stacks, with up to specified max giant size.
214 void initGiantStacks(unsigned maxDigits
)
216 unsigned curSize
= MIN_GIANT_SIZE
;
220 dblog0("initGiantStacks\n");
224 * Shouldn't be called more than once...
226 printf("multiple initGiantStacks calls\n");
229 gstackDbg(("initGiantStacks(%d)\n", maxDigits
));
235 while(curSize
<=maxDigits
) {
236 curSize
<<= GIANT_SIZE_INCR
;
240 sz
= sizeof(gstack
) * numGstacks
;
241 gstacks
= (gstack
*) fmalloc(sz
);
244 curSize
= MIN_GIANT_SIZE
;
245 for(i
=0; i
<numGstacks
; i
++) {
246 gstacks
[i
].numDigits
= curSize
;
247 curSize
<<= GIANT_SIZE_INCR
;
253 /* called at shut down - free resources */
254 void freeGiantStacks(void)
263 for(i
=0; i
<numGstacks
; i
++) {
265 for(j
=0; j
<gs
->numFree
; j
++) {
266 freeGiant(gs
->stack
[j
]);
269 /* and the stack itself - may be null if this was never used */
270 if(gs
->stack
!= NULL
) {
280 #endif // GIANTS_VIA_STACK
282 giant
borrowGiant(unsigned numDigits
)
289 gstack
*gs
= gstacks
;
291 #if WARN_ZERO_GIANT_SIZE
293 printf("borrowGiant(0)\n");
294 numDigits
= gstacks
[numGstacks
-1].numDigits
;
296 #endif // WARN_ZERO_GIANT_SIZE
299 * Find appropriate stack
301 if(numDigits
<= MIN_GIANT_SIZE
)
303 else if (numDigits
<= (MIN_GIANT_SIZE
<< GIANT_SIZE_INCR
))
305 else if (numDigits
<= (MIN_GIANT_SIZE
<< (2 * GIANT_SIZE_INCR
)))
307 else if (numDigits
<= (MIN_GIANT_SIZE
<< (3 * GIANT_SIZE_INCR
)))
309 else if (numDigits
<= (MIN_GIANT_SIZE
<< (4 * GIANT_SIZE_INCR
)))
312 stackNum
= numGstacks
;
314 if(stackNum
>= numGstacks
) {
316 * out of bounds; just malloc
318 #if LOG_GIANT_STACK_OVERFLOW
319 gstackDbg(("giantFromStack overflow; numDigits %d\n",
321 #endif // LOG_GIANT_STACK_OVERFLOW
322 return newGiant(numDigits
);
324 gs
= &gstacks
[stackNum
];
327 if((gs
->numFree
!= 0) && (gs
->stack
== NULL
)) {
328 dblog0("borrowGiant: null stack!\n");
332 if(gs
->numFree
!= 0) {
333 result
= gs
->stack
[--gs
->numFree
];
337 * Stack empty; malloc
339 result
= newGiant(gs
->numDigits
);
342 #else /* GIANTS_VIA_STACK */
344 result
= newGiant(numDigits
);
346 #endif /* GIANTS_VIA_STACK */
348 PROF_INCR(numBorrows
);
352 void returnGiant(giant g
)
359 unsigned cap
= g
->capacity
;
364 CKRaise("returnGiant before stacks initialized!");
370 dblog0("returnGiant: null g!\n");
375 * Find appropriate stack. Note we expect exact match of
376 * capacity and stack's giant size.
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.
387 case MIN_GIANT_SIZE
<< GIANT_SIZE_INCR
:
390 case MIN_GIANT_SIZE
<< (2 * GIANT_SIZE_INCR
):
393 case MIN_GIANT_SIZE
<< (3 * GIANT_SIZE_INCR
):
396 case MIN_GIANT_SIZE
<< (4 * GIANT_SIZE_INCR
):
400 stackNum
= numGstacks
;
404 if(stackNum
>= numGstacks
) {
406 * out of bounds; just free
408 #if LOG_GIANT_STACK_OVERFLOW
409 gstackDbg(("giantToStack overflow; numDigits %d\n", cap
));
410 #endif // LOG_GIANT_STACK_OVERFLOW
414 gs
= &gstacks
[stackNum
];
415 if(gs
->numFree
== gs
->totalGiants
) {
416 if(gs
->totalGiants
== 0) {
417 gstackDbg(("Initial alloc of gstack(%d)\n",
419 gs
->totalGiants
= INIT_NUM_GIANTS
;
422 gs
->totalGiants
*= 2;
423 gstackDbg(("Bumping gstack(%d) to %d\n",
424 gs
->numDigits
, gs
->totalGiants
));
426 gs
->stack
= (giantstruct
**) frealloc(gs
->stack
, gs
->totalGiants
*sizeof(giant
));
428 g
->sign
= 0; // not sure this is important...
429 gs
->stack
[gs
->numFree
++] = g
;
432 if((gs
->numFree
!= 0) && (gs
->stack
== NULL
)) {
433 dblog0("borrowGiant: null stack!\n");
437 #else /* GIANTS_VIA_STACK */
441 #endif /* GIANTS_VIA_STACK */
444 void freeGiant(giant x
) {
448 giant
newGiant(unsigned numDigits
) {
449 // giant sufficient for 2^numbits+16 sized ops
453 #if WARN_ZERO_GIANT_SIZE
455 printf("newGiant(0)\n");
457 numDigits
= gstacks
[numGstacks
-1].totalGiants
;
463 #endif // WARN_ZERO_GIANT_SIZE
465 size
= (numDigits
-1) * GIANT_BYTES_PER_DIGIT
+ sizeof(giantstruct
);
466 result
= (giant
)fmalloc(size
);
471 result
->capacity
= numDigits
;
475 giant
copyGiant(giant x
)
479 giant result
= newGiant(x
->capacity
);
483 * NO! this assumes packed alignment
485 bytes
= sizeof(giantstruct
) +
486 ((x
->capacity
- 1) * GIANT_BYTES_PER_DIGIT
);
487 bcopy(x
, result
, bytes
);
491 /* ------ initialization and utility routines ------ */
494 unsigned bitlen(giant n
) {
495 unsigned b
= GIANT_BITS_PER_DIGIT
;
496 giantDigit c
= ((giantDigit
)1) << (GIANT_BITS_PER_DIGIT
- 1);
502 w
= n
->n
[abs(n
->sign
) - 1];
504 CKRaise("bitlen - no bit set!");
510 return(GIANT_BITS_PER_DIGIT
* (abs(n
->sign
)-1) + b
);
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));
517 return ((0!=((n
->n
[i
]) & c
))?1:0);
521 /* returns the sign of g */
523 if (isZero(g
)) return(0);
524 if (g
->sign
> 0) return(1);
529 * Adjust sign for possible leading (m.s.) zero digits
531 void gtrimSign(giant g
)
533 int numDigits
= abs(g
->sign
);
536 for(i
=numDigits
-1; i
>=0; i
--) {
545 g
->sign
= -numDigits
;
554 return((g
->sign
==1)&&(g
->n
[0]==1));
557 int isZero(giant thegiant
) {
558 /* Returns TRUE if thegiant == 0. */
560 int length
= abs(thegiant
->sign
);
561 giantDigit
*numpointer
;
564 numpointer
= thegiant
->n
;
566 for(count
= 0; count
<length
; ++count
,++numpointer
)
567 if (*numpointer
!= 0 ) return(FALSE
);
572 int gcompg(giant a
, giant b
)
573 /* returns -1,0,1 if a<b, a=b, a>b, respectively */
582 if(isZero(a
) && isZero(b
)) return 0;
583 if(sa
> sb
) return(1);
584 if(sa
< sb
) return(-1);
586 sa
= -sa
; /* Take absolute value of sa */
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
);
597 /* destgiant becomes equal to srcgiant */
598 void gtog(giant srcgiant
, giant destgiant
) {
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
;
610 void int_to_giant(int i
, giant g
) {
611 /* The giant g becomes set to the integer value i. */
613 unsigned int j
= abs(i
);
622 if(GIANT_BYTES_PER_DIGIT
== sizeof(int)) {
627 /* one loop per digit */
628 unsigned scnt
= GIANT_BITS_PER_DIGIT
; // fool compiler
630 for(dex
=0; dex
<sizeof(int); dex
++) {
631 g
->n
[dex
] = j
& GIANT_DIGIT_MASK
;
640 g
->sign
= -(g
->sign
);
644 /*------------- Arithmetic --------------*/
651 void iaddg(int i
, giant g
) { /* positive g becomes g + (int)i */
654 int size
= abs(g
->sign
);
661 for(j
=0; ((j
<size
) && (carry
!= 0)); j
++) {
662 g
->n
[j
] = giantAddDigits(g
->n
[j
], carry
, &carry
);
667 if (g
->sign
> (int)g
->capacity
) CKRaise("iaddg overflow!");
676 * FIXME - we can improve this...
678 void imulg(unsigned n
, giant g
)
680 giant tmp
= borrowGiant(abs(g
->sign
) + sizeof(int));
682 int_to_giant(n
, tmp
);
687 static void normal_addg(giant a
, giant b
)
688 /* b := a + b, both a,b assumed non-negative. */
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
;
709 /* first handle the common digits */
710 for(j
=0; j
<comSize
; j
++) {
712 * first add the carry, then an[j] - either add could result
715 if(carry1
|| carry2
) {
716 tmp
= giantAddDigits(bn
[j
], (giantDigit
)1, &carry1
);
722 bn
[j
] = giantAddDigits(tmp
, an
[j
], &carry2
);
727 /* now propagate remaining carry beyond asize */
732 for(; j
<bsize
; j
++) {
733 bn
[j
] = giantAddDigits(bn
[j
], (giantDigit
)1, &carry1
);
740 /* now propagate remaining an[] and carry beyond bsize */
744 for(; j
<asize
; j
++) {
746 bn
[j
] = giantAddDigits(an
[j
], (giantDigit
)1, &carry1
);
759 if (b
->sign
> (int)b
->capacity
) CKRaise("iaddg overflow!");
764 static void normal_subg(giant a
, giant b
)
765 /* b := b - a; requires b, a non-negative and b >= a. */
770 giantDigit borrow1
= 0;
771 giantDigit borrow2
= 0;
772 giantDigit
*an
= a
->n
;
773 giantDigit
*bn
= b
->n
;
779 for (j
=0; j
<a
->sign
; ++j
) {
780 if(borrow1
|| borrow2
) {
781 tmp
= giantSubDigits(bn
[j
], (giantDigit
)1, &borrow1
);
787 bn
[j
] = giantSubDigits(tmp
, an
[j
], &borrow2
);
789 if(borrow1
|| borrow2
) {
790 /* propagate borrow thru remainder of bn[] */
792 for (j
=a
->sign
; j
<size
; ++j
) {
794 bn
[j
] = giantSubDigits(bn
[j
], (giantDigit
)1, &borrow1
);
802 /* adjust sign for leading zero digits */
803 while((size
-- > 0) && (b
->n
[size
] == 0))
805 b
->sign
= (b
->n
[size
] == 0)? 0 : size
+1;
808 static void reverse_subg(giant a
, giant b
)
809 /* b := a - b; requires b, a non-negative and a >= b. */
814 giantDigit borrow1
= 0;
815 giantDigit borrow2
= 0;
816 giantDigit
*an
= a
->n
;
817 giantDigit
*bn
= b
->n
;
823 for (j
=0; j
<b
->sign
; ++j
) {
824 if(borrow1
|| borrow2
) {
825 tmp
= giantSubDigits(an
[j
], (giantDigit
)1, &borrow1
);
831 bn
[j
] = giantSubDigits(tmp
, bn
[j
], &borrow2
);
833 if(borrow1
|| borrow2
) {
834 /* propagate borrow thru remainder of bn[] */
837 for (j
=b
->sign
; j
<size
; ++j
) {
839 bn
[j
] = giantSubDigits(an
[j
], (giantDigit
)1, &borrow1
);
847 b
->sign
= size
; /* REC, 21 Apr 1996. */
848 while(!b
->n
[--size
]);
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;
861 if((asgn
< 0) == (bsgn
< 0)) {
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. */
871 if(gcompg(b
,a
) >= 0) {
882 if(gcompg(b
,a
) < 0) {
891 void subg(giant a
, giant b
)
892 /* b := b - a, any signs, any result. */
894 int asgn
= a
->sign
, bsgn
= b
->sign
;
895 if(asgn
== 0) return;
901 if((asgn
< 0) != (bsgn
< 0)) {
914 if(gcompg(b
,a
) >= 0) {
923 if(gcompg(b
,a
) >= 0) {
934 static void bdivg(giant v
, giant u
)
935 /* u becomes greatest power of two not exceeding u/v. */
937 int diff
= bitlen(u
) - bitlen(v
);
944 scratch7
= borrowGiant(u
->capacity
);
946 gshiftleft(diff
,scratch7
);
947 if(gcompg(u
,scratch7
) < 0) diff
--;
950 returnGiant(scratch7
);
955 returnGiant(scratch7
);
958 int binvaux(giant p
, giant x
)
959 /* Binary inverse method.
960 Returns zero if no inverse exists, in which case x becomes
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
);
982 gtog(u1
, u0
); bdivg(v1
, u0
);
997 if(x
->sign
<0) addg(p
, x
);
1001 if (x
->sign
<0) addg(p
, x
);
1003 returnGiant(scratch7
);
1008 PROF_END(binvauxTime
);
1013 * Superceded by binvg_cp()
1016 int binvg(giant p
, giant x
)
1019 return(binvaux(p
,x
));
1023 static void absg(giant g
) {
1024 /* g becomes the absolute value of g */
1025 if (g
->sign
< 0) g
->sign
= -g
->sign
;
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
);
1036 int sign
= gsign(g
);
1042 CKRaise("gshiftleft(-bits)\n");
1044 #endif /* FEE_DEBUG */
1048 if((size
+digits
) > (int)g
->capacity
) {
1049 CKRaise("gshiftleft overflow");
1051 k
= size
- 1 + digits
; // (MSD of result + 1)
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
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
];
1068 * normal unaligned case
1069 * FIXME - this writes past g->n[size-1] the first time thru!
1071 for(j
=size
-1; j
>=0; j
--) {
1073 g
->n
[k
--] = (dat
>> crem
) | carry
;
1074 carry
= (dat
<< rem
);
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");
1089 void gshiftright(int bits
, giant g
) {
1090 /* shift g right bits bits. Equivalent to g = g/2^bits */
1092 int size
=abs(g
->sign
);
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
;
1100 CKRaise("gshiftright(-bits)\n");
1102 #endif /* FEE_DEBUG */
1104 if(isZero(g
)) return;
1105 if (digits
>= size
) {
1112 /* Begin OPT: 9 Jan 98 REC. */
1120 for(j
=0; j
< size
; j
++) {
1121 g
->n
[j
] = g
->n
[j
+digits
];
1125 /* End OPT: 9 Jan 98 REC. */
1127 for(j
=0;j
<size
;++j
) {
1132 carry
= (g
->n
[j
+digits
+1]) << cremain
;
1134 g
->n
[j
] = ((g
->n
[j
+digits
]) >> remain
) | carry
;
1136 if (g
->n
[size
-1] == 0) {
1145 if (abs(g
->sign
) > g
->capacity
) {
1146 CKRaise("gshiftright overflow");
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);
1160 if (dest
->capacity
* 8 * GIANT_BYTES_PER_DIGIT
< n
) {
1161 CKRaise("extractbits - not enough room");
1163 if (digits
>= abs(src
->sign
)) {
1167 memcpy((char *)(dest
->n
), (char *)(src
->n
), numbytes
);
1169 dest
->n
[digits
] = src
->n
[digits
] & ((1<<bits
)-1);
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)) {
1178 dest
->sign
= -digits
;
1181 dest
->sign
= digits
;
1184 if (abs(dest
->sign
) > dest
->capacity
) {
1185 CKRaise("extractbits overflow");
1189 #define NEW_MERSENNE 0
1192 * New gmersennemod, 24 Dec 1997. This runs significantly slower than the
1202 /* g := g (mod 2^n - 1) */
1205 giant scratch3
= borrowGiant(g
->capacity
);
1206 giant scratch4
= borrowGiant(1);
1208 if ((the_sign
= gsign(g
)) < 0) absg(g
);
1209 while (bitlen(g
) > n
) {
1211 gshiftright(n
,scratch3
);
1213 gshiftleft(n
,scratch3
);
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
);
1227 returnGiant(scratch3
);
1228 returnGiant(scratch4
);
1231 #else /* NEW_MERSENNE */
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.
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);
1245 giantDigit mask
= (bits
== 0) ? GIANT_DIGIT_MASK
: (giantDigit
)((1<<bits
)-1);
1250 unsigned numDigits
= (n
+ GIANT_BITS_PER_DIGIT
- 1) >>
1251 GIANT_LOG2_BITS_PER_DIGIT
;
1252 giantDigit lastWord
= 0;
1253 giantDigit bits
= 1;
1255 if(g
->sign
>= 0) return;
1258 * Cons up ((2**n)-1), add to g.
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
;
1267 * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
1269 for(j
=0; j
< (int)(n
& (GIANT_BITS_PER_DIGIT
-1)); j
++) {
1273 scratch1
->n
[numDigits
-1] = lastWord
;
1274 addg(g
, scratch1
); /* One version. */
1276 returnGiant(scratch1
);
1280 for(foundzero
=0, j
=0; j
<b
; j
++) {
1281 if(bitval(g
, j
)==0) {
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
);
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
;
1307 for(j
= size
-1; j
>= 0; j
--) {
1310 g
->n
[digits
-1] &= mask
;
1312 while((g
->n
[j
] == 0) && (j
> 0)) {
1317 /* End new negation routine. */
1320 if (abs(g
->sign
) > g
->capacity
) {
1321 CKRaise("gmersennemod overflow");
1323 if (size
< (int)digits
) {
1326 if (g
->n
[size
-1] != mask
) {
1329 mask
= GIANT_DIGIT_MASK
;
1330 for(j
=0; j
<(size
-1); j
++) {
1331 if (g
->n
[j
] != mask
) {
1337 returnGiant(scratch1
);
1340 #endif /* NEW_MERSENNE */
1342 void mulg(giant a
, giant b
) { /* b becomes a*b. */
1346 giantDigit
*bptr
= b
->n
;
1365 bsize
= abs(b
->sign
);
1366 asize
= abs(a
->sign
);
1367 scratch1
= borrowGiant((asize
+bsize
));
1368 scrPtr
= scratch1
->n
;
1370 for(i
=0; i
<asize
+bsize
; ++i
) {
1374 for(i
=0; i
<bsize
; ++i
, scrPtr
++) {
1377 carry
= VectorMultiply(mult
,
1381 /* handle MSD carry */
1382 scrPtr
[asize
] += carry
;
1386 if(scratch1
->n
[bsize
- 1] == 0) {
1389 scratch1
->sign
= gsign(a
) * gsign(b
) * bsize
;
1390 if (abs(scratch1
->sign
) > scratch1
->capacity
) {
1391 CKRaise("GiantGrammarMul overflow");
1394 returnGiant(scratch1
);
1397 (void)bitlen(b
); // Assertion....
1398 #endif /* FEE_DEBUG */
1399 PROF_INCR(numMulg
); // for normal profiling
1400 INCR_MULGS
; // for ellipticMeasure
1403 void grammarSquare(giant a
) {
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....
1411 giantDigit carryLo
= 0;
1412 giantDigit carryHi
= 0;
1415 unsigned int cur_term
;
1418 giantDigit
*ptr
= a
->n
;
1423 /* dmitch 11 Jan 1998 - special case for a == 0 */
1427 /* end a == 0 case */
1428 asize
= abs(a
->sign
);
1429 max
= asize
* 2 - 1;
1430 scratch
= borrowGiant(2 * asize
);
1436 * scratch->n[0] = temp;
1437 * carry = temp >> 16;
1439 giantMulDigits(*ptr
, *ptr
, &tempLo
, &tempHi
);
1440 scratch
->n
[0] = tempLo
;
1444 for (cur_term
= 1; cur_term
< max
; cur_term
++) {
1446 if (cur_term
<= asize
) {
1449 ptr1
+= cur_term
- asize
;
1454 * prod = carry & 0xFFFF;
1461 while(ptr1
< ptr2
) {
1463 * temp = *ptr1++ * *ptr2--;
1465 giantMulDigits(*ptr1
++, *ptr2
--, &tempLo
, &tempHi
);
1468 * prod += (temp << 1) & 0xFFFF;
1470 giantAddDouble(&prodLo
, &prodHi
, (tempLo
<< 1));
1473 * carry += (temp >> 15);
1474 * use bits from both product digits..
1476 giantAddDouble(&carryLo
, &carryHi
,
1477 (tempLo
>> (GIANT_BITS_PER_DIGIT
- 1)));
1478 giantAddDouble(&carryLo
, &carryHi
, (tempHi
<< 1));
1480 /* snag the msb from that last shift */
1481 carryHi
+= (tempHi
>> (GIANT_BITS_PER_DIGIT
- 1));
1488 giantMulDigits(*ptr1
, *ptr1
, &tempLo
, &tempHi
);
1491 * prod += temp & 0xFFFF;
1493 giantAddDouble(&prodLo
, &prodHi
, tempLo
);
1496 * carry += (temp >> 16);
1498 giantAddDouble(&carryLo
, &carryHi
, tempHi
);
1502 * carry += prod >> 16;
1504 giantAddDouble(&carryLo
, &carryHi
, prodHi
);
1506 scratch
->n
[cur_term
] = prodLo
;
1509 scratch
->n
[cur_term
] = carryLo
;
1510 scratch
->sign
= cur_term
+1;
1511 } else scratch
->sign
= cur_term
;
1514 returnGiant(scratch
);
1516 PROF_INCR(numGsquare
);
1520 * Clear all of a giant's data fields, for secure erasure of sensitive data.,
1522 void clearGiant(giant g
)
1526 for(i
=0; i
<g
->capacity
; i
++) {
1534 * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997
1537 scompg(int n
, giant g
) {
1538 if((g
->sign
== 1) && (g
->n
[0] == n
)) return(1);
1542 #endif // ENGINE_127_BITS
1548 * Calculate the reciprocal of a demonimator used in divg_via_recip() and
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. */
1557 int giantSize
= 4 * abs(d
->sign
);
1558 giant tmp
= borrowGiant(giantSize
);
1559 giant tmp2
= borrowGiant(giantSize
);
1561 if (isZero(d
) || (d
->sign
< 0))
1563 CKRaise("illegal argument to make_recip");
1565 int_to_giant(1, r
); subg(r
, d
); b
= bitlen(d
); addg(r
, d
);
1566 gshiftleft(b
, r
); gtog(r
, tmp2
);
1570 gshiftright(b
, tmp
);
1572 gshiftright(b
, tmp
);
1573 addg(r
, r
); subg(tmp
, r
);
1574 if(gcompg(r
, tmp2
) <= 0) break;
1577 int_to_giant(1, tmp
);
1578 gshiftleft(2*b
, tmp
);
1579 gtog(r
, tmp2
); mulg(d
, tmp2
);
1581 int_to_giant(1, tmp2
);
1582 while(tmp
->sign
< 0) {
1593 * Optimized divg, when reciprocal of denominator is known.
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. */
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
);
1605 if (isZero(d
) || (d
->sign
< 0))
1607 CKRaise("illegal argument to divg_via_recip");
1609 n
->sign
= abs(n
->sign
);
1610 int_to_giant(0, tmp2
);
1614 gshiftright(s
, tmp
);
1618 if(gcompg(n
,d
) >= 0) {
1622 if(gcompg(n
,d
) < 0) break;
1632 * Optimized modg, when reciprocal of denominator is known.
1635 /* New version, 24 Dec 1997. */
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. */
1648 int s
= (bitlen(r
)-1), sign
= n
->sign
;
1649 int giantSize
= (4 * abs(d
->sign
)) + abs(n
->sign
);
1652 tmp
= borrowGiant(giantSize
);
1653 tmp2
= borrowGiant(giantSize
);
1654 if (isZero(d
) || (d
->sign
< 0))
1656 CKRaise("illegal argument to modg_via_recip");
1658 n
->sign
= abs(n
->sign
);
1662 /* bug fix 13 Apr 1998 */
1667 gshiftright(s
-1, tmp
);
1671 gshiftright(s
+1, tmp
);
1674 if (gcompg(n
,d
) >= 0)
1676 if (gcompg(n
,d
) < 0)
1692 * Unoptimized, inefficient general modg, when reciprocal of denominator
1701 /* n becomes n%d. n is arbitrary, but the denominator d must be
1705 * 4/9/2001: seeing overflow on this recip. Alloc per
1706 * d->capacity, not d->sign.
1708 //giant recip = borrowGiant(2 * abs(d->sign));
1709 giant recip
= borrowGiant(2 * d
->capacity
);
1712 dbgLog(("Warning: unoptimized modg!\n"));
1713 #endif // WARN_UNOPTIMIZE
1715 make_recip(d
, recip
);
1716 modg_via_recip(d
, recip
, n
);
1721 * Unoptimized, inefficient general divg, when reciprocal of denominator
1730 /* n becomes n/d. n is arbitrary, but the denominator d must be
1734 giant recip
= borrowGiant(2 * abs(d
->sign
));
1737 dbgLog(("Warning: unoptimized divg!\n"));
1738 #endif // WARN_UNOPTIMIZE
1740 make_recip(d
, recip
);
1741 divg_via_recip(d
, recip
, n
);