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
= 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
= 1 << (pos
& (GIANT_BITS_PER_DIGIT
- 1));
517 return((n
->n
[i
]) & c
);
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");
1052 k
= size
- 1 + digits
; // (MSD of result + 1)
1055 /* bug fix for 32-bit giantDigits; this is also an optimization for
1056 * other sizes. rem=0 means we're shifting strictly by digits, no
1059 g
->n
[k
] = 0; // XXX hack - for sign fixup
1060 for(j
=size
-1; j
>=0; j
--) {
1061 g
->n
[--k
] = g
->n
[j
];
1069 * normal unaligned case
1070 * FIXME - this writes past g->n[size-1] the first time thru!
1072 for(j
=size
-1; j
>=0; j
--) {
1074 g
->n
[k
--] = (dat
>> crem
) | carry
;
1075 carry
= (dat
<< rem
);
1082 k
= size
- 1 + digits
;
1083 if(g
->n
[k
] == 0) --k
;
1084 g
->sign
= sign
* (k
+1);
1085 if (abs(g
->sign
) > g
->capacity
) {
1086 CKRaise("gshiftleft overflow");
1090 void gshiftright(int bits
, giant g
) {
1091 /* shift g right bits bits. Equivalent to g = g/2^bits */
1093 int size
=abs(g
->sign
);
1095 int digits
= bits
>> GIANT_LOG2_BITS_PER_DIGIT
;
1096 int remain
= bits
& (GIANT_BITS_PER_DIGIT
- 1);
1097 int cremain
= GIANT_BITS_PER_DIGIT
- remain
;
1101 CKRaise("gshiftright(-bits)\n");
1103 #endif /* FEE_DEBUG */
1105 if(isZero(g
)) return;
1106 if (digits
>= size
) {
1113 /* Begin OPT: 9 Jan 98 REC. */
1121 for(j
=0; j
< size
; j
++) {
1122 g
->n
[j
] = g
->n
[j
+digits
];
1126 /* End OPT: 9 Jan 98 REC. */
1128 for(j
=0;j
<size
;++j
) {
1133 carry
= (g
->n
[j
+digits
+1]) << cremain
;
1135 g
->n
[j
] = ((g
->n
[j
+digits
]) >> remain
) | carry
;
1137 if (g
->n
[size
-1] == 0) {
1146 if (abs(g
->sign
) > g
->capacity
) {
1147 CKRaise("gshiftright overflow");
1152 void extractbits(unsigned n
, giant src
, giant dest
) {
1153 /* dest becomes lowermost n bits of src. Equivalent to dest = src % 2^n */
1154 int digits
= n
>> GIANT_LOG2_BITS_PER_DIGIT
;
1155 int numbytes
= digits
* GIANT_BYTES_PER_DIGIT
;
1156 int bits
= n
& (GIANT_BITS_PER_DIGIT
- 1);
1161 if (dest
->capacity
* 8 * GIANT_BYTES_PER_DIGIT
< n
) {
1162 CKRaise("extractbits - not enough room");
1164 if (digits
>= abs(src
->sign
)) {
1168 memcpy((char *)(dest
->n
), (char *)(src
->n
), numbytes
);
1170 dest
->n
[digits
] = src
->n
[digits
] & ((1<<bits
)-1);
1173 /* Next, fix by REC, 12 Jan 97. */
1174 // while((dest->n[words-1] == 0) && (words > 0)) --words;
1175 while((digits
> 0) && (dest
->n
[digits
-1] == 0)) {
1179 dest
->sign
= -digits
;
1182 dest
->sign
= digits
;
1185 if (abs(dest
->sign
) > dest
->capacity
) {
1186 CKRaise("extractbits overflow");
1190 #define NEW_MERSENNE 0
1193 * New gmersennemod, 24 Dec 1997. This runs significantly slower than the
1203 /* g := g (mod 2^n - 1) */
1206 giant scratch3
= borrowGiant(g
->capacity
);
1207 giant scratch4
= borrowGiant(1);
1209 if ((the_sign
= gsign(g
)) < 0) absg(g
);
1210 while (bitlen(g
) > n
) {
1212 gshiftright(n
,scratch3
);
1214 gshiftleft(n
,scratch3
);
1217 if(isZero(g
)) goto out
;
1218 int_to_giant(1,scratch3
);
1219 gshiftleft(n
,scratch3
);
1220 int_to_giant(1,scratch4
);
1221 subg(scratch4
,scratch3
);
1222 if(gcompg(g
,scratch3
) >= 0) subg(scratch3
,g
);
1228 returnGiant(scratch3
);
1229 returnGiant(scratch4
);
1232 #else /* NEW_MERSENNE */
1234 void gmersennemod(int n
, giant g
) {
1235 /* g becomes g mod ((2^n)-1)
1236 31 Jul 96 modified REC.
1237 17 Jan 97 modified REC.
1239 unsigned bits
= n
& (GIANT_BITS_PER_DIGIT
- 1);
1240 unsigned digits
= 1 + ((n
-1) >> GIANT_LOG2_BITS_PER_DIGIT
);
1241 int isPositive
= (g
->sign
> 0);
1246 giantDigit mask
= (bits
== 0) ? GIANT_DIGIT_MASK
: (giantDigit
)((1<<bits
)-1);
1251 unsigned numDigits
= (n
+ GIANT_BITS_PER_DIGIT
- 1) >>
1252 GIANT_LOG2_BITS_PER_DIGIT
;
1253 giantDigit lastWord
= 0;
1254 giantDigit bits
= 1;
1256 if(g
->sign
>= 0) return;
1259 * Cons up ((2**n)-1), add to g.
1261 scratch1
= borrowGiant(numDigits
+ 1);
1262 scratch1
->sign
= numDigits
;
1263 for(j
=0; j
<(int)(numDigits
-1); j
++) {
1264 scratch1
->n
[j
] = GIANT_DIGIT_MASK
;
1268 * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
1270 for(j
=0; j
< (int)(n
& (GIANT_BITS_PER_DIGIT
-1)); j
++) {
1274 scratch1
->n
[numDigits
-1] = lastWord
;
1275 addg(g
, scratch1
); /* One version. */
1277 returnGiant(scratch1
);
1281 for(foundzero
=0, j
=0; j
<b
; j
++) {
1282 if(bitval(g
, j
)==0) {
1294 scratch1
= borrowGiant(g
->capacity
);
1295 while ( ((unsigned)(g
->sign
) > digits
) ||
1296 ( ((unsigned)(g
->sign
)==digits
) && (g
->n
[digits
-1] > mask
))) {
1297 extractbits(n
, g
, scratch1
);
1303 /* Commence new negation routine - REC 17 Jan 1997. */
1304 if (!isPositive
) { /* Mersenne negation is just bitwise complement. */
1305 for(j
= digits
-1; j
>= size
; j
--) {
1306 g
->n
[j
] = GIANT_DIGIT_MASK
;
1308 for(j
= size
-1; j
>= 0; j
--) {
1311 g
->n
[digits
-1] &= mask
;
1313 while((g
->n
[j
] == 0) && (j
> 0)) {
1318 /* End new negation routine. */
1321 if (abs(g
->sign
) > g
->capacity
) {
1322 CKRaise("gmersennemod overflow");
1324 if (size
< (int)digits
) {
1327 if (g
->n
[size
-1] != mask
) {
1330 mask
= GIANT_DIGIT_MASK
;
1331 for(j
=0; j
<(size
-1); j
++) {
1332 if (g
->n
[j
] != mask
) {
1338 returnGiant(scratch1
);
1341 #endif /* NEW_MERSENNE */
1343 void mulg(giant a
, giant b
) { /* b becomes a*b. */
1347 giantDigit
*bptr
= b
->n
;
1366 bsize
= abs(b
->sign
);
1367 asize
= abs(a
->sign
);
1368 scratch1
= borrowGiant((asize
+bsize
));
1369 scrPtr
= scratch1
->n
;
1371 for(i
=0; i
<asize
+bsize
; ++i
) {
1375 for(i
=0; i
<bsize
; ++i
, scrPtr
++) {
1378 carry
= VectorMultiply(mult
,
1382 /* handle MSD carry */
1383 scrPtr
[asize
] += carry
;
1387 if(scratch1
->n
[bsize
- 1] == 0) {
1390 scratch1
->sign
= gsign(a
) * gsign(b
) * bsize
;
1391 if (abs(scratch1
->sign
) > scratch1
->capacity
) {
1392 CKRaise("GiantGrammarMul overflow");
1395 returnGiant(scratch1
);
1398 (void)bitlen(b
); // Assertion....
1399 #endif /* FEE_DEBUG */
1400 PROF_INCR(numMulg
); // for normal profiling
1401 INCR_MULGS
; // for ellipticMeasure
1404 void grammarSquare(giant a
) {
1406 * For now, we're going to match the old implementation line for
1407 * line by maintaining prod, carry, and temp as double precision
1408 * giantDigits. There is probably a much better implementation....
1412 giantDigit carryLo
= 0;
1413 giantDigit carryHi
= 0;
1416 unsigned int cur_term
;
1419 giantDigit
*ptr
= a
->n
;
1424 /* dmitch 11 Jan 1998 - special case for a == 0 */
1428 /* end a == 0 case */
1429 asize
= abs(a
->sign
);
1430 max
= asize
* 2 - 1;
1431 scratch
= borrowGiant(2 * asize
);
1437 * scratch->n[0] = temp;
1438 * carry = temp >> 16;
1440 giantMulDigits(*ptr
, *ptr
, &tempLo
, &tempHi
);
1441 scratch
->n
[0] = tempLo
;
1445 for (cur_term
= 1; cur_term
< max
; cur_term
++) {
1447 if (cur_term
<= asize
) {
1450 ptr1
+= cur_term
- asize
;
1455 * prod = carry & 0xFFFF;
1462 while(ptr1
< ptr2
) {
1464 * temp = *ptr1++ * *ptr2--;
1466 giantMulDigits(*ptr1
++, *ptr2
--, &tempLo
, &tempHi
);
1469 * prod += (temp << 1) & 0xFFFF;
1471 giantAddDouble(&prodLo
, &prodHi
, (tempLo
<< 1));
1474 * carry += (temp >> 15);
1475 * use bits from both product digits..
1477 giantAddDouble(&carryLo
, &carryHi
,
1478 (tempLo
>> (GIANT_BITS_PER_DIGIT
- 1)));
1479 giantAddDouble(&carryLo
, &carryHi
, (tempHi
<< 1));
1481 /* snag the msb from that last shift */
1482 carryHi
+= (tempHi
>> (GIANT_BITS_PER_DIGIT
- 1));
1489 giantMulDigits(*ptr1
, *ptr1
, &tempLo
, &tempHi
);
1492 * prod += temp & 0xFFFF;
1494 giantAddDouble(&prodLo
, &prodHi
, tempLo
);
1497 * carry += (temp >> 16);
1499 giantAddDouble(&carryLo
, &carryHi
, tempHi
);
1503 * carry += prod >> 16;
1505 giantAddDouble(&carryLo
, &carryHi
, prodHi
);
1507 scratch
->n
[cur_term
] = prodLo
;
1510 scratch
->n
[cur_term
] = carryLo
;
1511 scratch
->sign
= cur_term
+1;
1512 } else scratch
->sign
= cur_term
;
1515 returnGiant(scratch
);
1517 PROF_INCR(numGsquare
);
1521 * Clear all of a giant's data fields, for secure erasure of sensitive data.,
1523 void clearGiant(giant g
)
1527 for(i
=0; i
<g
->capacity
; i
++) {
1535 * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997
1538 scompg(int n
, giant g
) {
1539 if((g
->sign
== 1) && (g
->n
[0] == n
)) return(1);
1543 #endif // ENGINE_127_BITS
1549 * Calculate the reciprocal of a demonimator used in divg_via_recip() and
1553 make_recip(giant d
, giant r
)
1554 /* r becomes the steady-state reciprocal
1555 2^(2b)/d, where b = bit-length of d-1. */
1558 int giantSize
= 4 * abs(d
->sign
);
1559 giant tmp
= borrowGiant(giantSize
);
1560 giant tmp2
= borrowGiant(giantSize
);
1562 if (isZero(d
) || (d
->sign
< 0))
1564 CKRaise("illegal argument to make_recip");
1566 int_to_giant(1, r
); subg(r
, d
); b
= bitlen(d
); addg(r
, d
);
1567 gshiftleft(b
, r
); gtog(r
, tmp2
);
1571 gshiftright(b
, tmp
);
1573 gshiftright(b
, tmp
);
1574 addg(r
, r
); subg(tmp
, r
);
1575 if(gcompg(r
, tmp2
) <= 0) break;
1578 int_to_giant(1, tmp
);
1579 gshiftleft(2*b
, tmp
);
1580 gtog(r
, tmp2
); mulg(d
, tmp2
);
1582 int_to_giant(1, tmp2
);
1583 while(tmp
->sign
< 0) {
1594 * Optimized divg, when reciprocal of denominator is known.
1597 divg_via_recip(giant d
, giant r
, giant n
)
1598 /* n := n/d, where r is the precalculated
1599 steady-state reciprocal of d. */
1601 int s
= 2*(bitlen(r
)-1), sign
= gsign(n
);
1602 int giantSize
= (4 * abs(d
->sign
)) + abs(n
->sign
);
1603 giant tmp
= borrowGiant(giantSize
);
1604 giant tmp2
= borrowGiant(giantSize
);
1606 if (isZero(d
) || (d
->sign
< 0))
1608 CKRaise("illegal argument to divg_via_recip");
1610 n
->sign
= abs(n
->sign
);
1611 int_to_giant(0, tmp2
);
1615 gshiftright(s
, tmp
);
1619 if(gcompg(n
,d
) >= 0) {
1623 if(gcompg(n
,d
) < 0) break;
1633 * Optimized modg, when reciprocal of denominator is known.
1636 /* New version, 24 Dec 1997. */
1644 /* This is the fastest mod of the present collection.
1645 n := n % d, where r is the precalculated
1646 steady-state reciprocal of d. */
1649 int s
= (bitlen(r
)-1), sign
= n
->sign
;
1650 int giantSize
= (4 * abs(d
->sign
)) + abs(n
->sign
);
1653 tmp
= borrowGiant(giantSize
);
1654 tmp2
= borrowGiant(giantSize
);
1655 if (isZero(d
) || (d
->sign
< 0))
1657 CKRaise("illegal argument to modg_via_recip");
1659 n
->sign
= abs(n
->sign
);
1663 /* bug fix 13 Apr 1998 */
1668 gshiftright(s
-1, tmp
);
1672 gshiftright(s
+1, tmp
);
1675 if (gcompg(n
,d
) >= 0)
1677 if (gcompg(n
,d
) < 0)
1693 * Unoptimized, inefficient general modg, when reciprocal of denominator
1702 /* n becomes n%d. n is arbitrary, but the denominator d must be
1706 * 4/9/2001: seeing overflow on this recip. Alloc per
1707 * d->capacity, not d->sign.
1709 //giant recip = borrowGiant(2 * abs(d->sign));
1710 giant recip
= borrowGiant(2 * d
->capacity
);
1713 dbgLog(("Warning: unoptimized modg!\n"));
1714 #endif // WARN_UNOPTIMIZE
1716 make_recip(d
, recip
);
1717 modg_via_recip(d
, recip
, n
);
1722 * Unoptimized, inefficient general divg, when reciprocal of denominator
1731 /* n becomes n/d. n is arbitrary, but the denominator d must be
1735 giant recip
= borrowGiant(2 * abs(d
->sign
));
1738 dbgLog(("Warning: unoptimized divg!\n"));
1739 #endif // WARN_UNOPTIMIZE
1741 make_recip(d
, recip
);
1742 divg_via_recip(d
, recip
, n
);