]> git.saurik.com Git - apple/security.git/blobdiff - Security/libsecurity_cryptkit/lib/giantIntegers.c
Security-57336.1.9.tar.gz
[apple/security.git] / Security / libsecurity_cryptkit / lib / giantIntegers.c
diff --git a/Security/libsecurity_cryptkit/lib/giantIntegers.c b/Security/libsecurity_cryptkit/lib/giantIntegers.c
deleted file mode 100644 (file)
index e7872b5..0000000
+++ /dev/null
@@ -1,1744 +0,0 @@
-/* Copyright (c) 1998,2011-2014 Apple Inc.  All Rights Reserved.
- *
- * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT
- * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE
- * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE
- * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE,
- * INC.  ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL
- * EXPOSE YOU TO LIABILITY.
- ***************************************************************************
-
-   giantIntegers.c - library for large-integer arithmetic.
-
- Revision History
- ----------------
-       Fixed a==b bug in addg(). 
- 10/06/98              ap
-       Changed to compile with C++.
- 13 Apr 98     Fixed shiftright(1) bug in modg_via_recip.
- 09 Apr 98 at Apple
-       Major rewrite of core arithmetic routines to make this module
-               independent of size of giantDigit.
-       Removed idivg() and radixdiv().
- 20 Jan 98 at Apple
-       Deleted FFT arithmetic; simplified mulg().
- 09 Jan 98 at Apple
-       gshiftright() optimization.
- 08 Jan 98 at Apple
-       newGiant() returns NULL on malloc failure
- 24 Dec 97 at Apple
-       New grammarSquare(); optimized modg_via_recip()
- 11 Jun 97 at Apple
-       Added modg_via_recip(), divg_via_recip(), make_recip()
-       Added new multiple giant stack mechanism
-       Fixed potential packing/alignment bug in copyGiant()
-       Added profiling for borrowGiant(), returnGiant()
-       Deleted obsolete ifdef'd code
-       Deleted newgiant()
-       All calls to borrowGiant() now specify required size (no more
-               borrowGiant(0) calls)
- 08 May 97 at Apple
-       Changed size of giantstruct.n to 1 for Mac build
- 05 Feb 97 at Apple
-       newGiant() no longer modifies CurrentMaxShorts or giant stack
-       Added modg profiling
- 01 Feb 97 at NeXT
-       Added iszero() check in gcompg
- 17 Jan 97 at NeXT
-       Fixed negation bug in gmersennemod()
-       Fixed n[words-1] == 0 bug in extractbits()
-       Cleaned up lots of static declarations
- 19 Sep 96 at NeXT
-       Fixed --size underflow bug in normal_subg().
-  4 Sep 96 at NeXT
-       Fixed (b<n), (sign<0) case in gmersennemod() to allow for arbitrary n.
-  9 Aug 96 at NeXT
-       Fixed sign-extend bug in data_to_giant().
-  7 Aug 96 at NeXT
-       Changed precision in newtondivide().
-       Removed #ifdef UNUSED code.
- 24 Jul 96 at NeXT
-       Added scompg().
-       Created.
-
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "platform.h"
-#include "giantIntegers.h"
-#include "feeDebug.h"
-#include "ckconfig.h"
-#include "ellipticMeasure.h"
-#include "falloc.h"
-#include "giantPortCommon.h"
-
-#ifdef FEE_DEBUG
-#if (GIANT_LOG2_BITS_PER_DIGIT == 4)
-#warning Compiling with two-byte giantDigits
-#endif
-#endif
-
-#if 0
-#if    FEE_DEBUG
-char printbuf1[200];
-char printbuf2[200];
-char printbuf3[200];
-void printGiantBuf(giant x)
-{
-       int i;
-
-       sprintf(printbuf2, "sign=%d cap=%d n[]=", x->sign, x->capacity);
-       for(i=0; i<abs(x->sign); i++) {
-               sprintf(printbuf3 + 10*i, "%u:", x->n[i]);
-       }
-}
-
-char printbuf4[200];
-char printbuf5[200];
-void printGiantBuf2(giant x)
-{
-       int i;
-
-       sprintf(printbuf4, "sign=%d cap=%d n[]=", x->sign, x->capacity);
-       for(i=0; i<abs(x->sign); i++) {
-               sprintf(printbuf5 + 10*i, "%u:", x->n[i]);
-       }
-}
-#endif /* FEE_DEBUG */
-#endif /* 0 */
-
-/******** debugging flags *********/
-
-/*
- * Flag use of unoptimized divg, modg, binvg
- */
-//#define WARN_UNOPTIMIZE                      FEE_DEBUG
-#define WARN_UNOPTIMIZE                        0
-
-/*
- * Log interesting giant stack events
- */
-#define LOG_GIANT_STACK                        0
-
-/*
- * Log allocation of giant larger than stack size
- */
-#define LOG_GIANT_STACK_OVERFLOW       1
-
-/*
- * Flag newGiant(0) and borrowGiant(0) calls
- */
-#define WARN_ZERO_GIANT_SIZE           FEE_DEBUG
-
-/* temp mac-only giant initialization debug */
-#define GIANT_MAC_DEBUG                0
-#if    GIANT_MAC_DEBUG
-
-#include <string.h>
-#include <TextUtils.h>
-
-/* this one needs a writable string */
-static void logCom(unsigned char *str) {
-       c2pstr((char *)str);
-       DebugStr(str);
-}
-
-/* constant strings */
-void dblog0(const char *str)   {               
-       Str255  outStr;                         
-       strcpy((char *)outStr, str);    
-       logCom(outStr);                                 
-}
-
-#else  
-#define dblog0(s)
-
-#endif /* GIANT_MAC_DEBUG */
-
-#ifndef        min
-#define min(a,b) ((a)<(b)? (a) : (b))
-#endif // min
-#ifndef        max
-#define max(a,b) ((a)>(b)? (a) : (b))
-#endif // max
-
-#ifndef        TRUE
-#define TRUE           1
-#endif // TRUE
-#ifndef        FALSE
-#define FALSE          0
-#endif // FALSE
-
-static void absg(giant g);  /* g := |g|. */
-
-/************** globals *******************/
-
-
-/* ------ giant stack package ------ */
-
-/*
- * The giant stack package is a local cache which allows us to avoid calls
- * to malloc() for borrowGiant(). On a 90 Mhz Pentium, enabling the
- * giant stack package shows about a 1.35 speedup factor over an identical
- * CryptKit without the giant stacks enabled.
- */
-
-#if    GIANTS_VIA_STACK
-
-#if    LOG_GIANT_STACK
-#define gstackDbg(x)           printf x
-#else  // LOG_GIANT_STACK
-#define gstackDbg(x)
-#endif // LOG_GIANT_STACK
-
-typedef struct {
-       unsigned        numDigits;      // capacity of giants in this stack
-       unsigned        numFree;        // number of free giants in stack
-       unsigned        totalGiants;    // total number in *stack
-       giant           *stack;
-} gstack;
-
-static gstack *gstacks = NULL;         // array of stacks
-static unsigned numGstacks = 0;                // # of elements in gstacks
-static int gstackInitd = 0;            // this module has been init'd
-
-#define INIT_NUM_GIANTS                16      /* initial # of giants / stack */
-#define MIN_GIANT_SIZE         4       /* numDigits for gstack[0]  */
-#define GIANT_SIZE_INCR                2       /* in << bits */
-
-/*
- * Initialize giant stacks, with up to specified max giant size.
- */
-void initGiantStacks(unsigned maxDigits)
-{
-       unsigned curSize = MIN_GIANT_SIZE;
-       unsigned sz;
-       unsigned i;
-
-       dblog0("initGiantStacks\n");
-       
-       if(gstackInitd) {
-               /*
-                * Shouldn't be called more than once...
-                */
-               printf("multiple initGiantStacks calls\n");
-               return;
-       }
-       gstackDbg(("initGiantStacks(%d)\n", maxDigits));
-
-       /*
-        * How many stacks?
-        */
-       numGstacks = 1;
-       while(curSize<=maxDigits) {
-               curSize <<= GIANT_SIZE_INCR;
-               numGstacks++;
-       }
-
-       sz = sizeof(gstack) * numGstacks;
-       gstacks = (gstack*) fmalloc(sz);
-       bzero(gstacks, sz);
-
-       curSize = MIN_GIANT_SIZE;
-       for(i=0; i<numGstacks; i++) {
-               gstacks[i].numDigits = curSize;
-               curSize <<= GIANT_SIZE_INCR;
-       }
-
-       gstackInitd = 1;
-}
-
-/* called at shut down - free resources */ 
-void freeGiantStacks(void)
-{
-       int i;
-       int j;
-       gstack *gs;
-       
-       if(!gstackInitd) {
-               return;
-       }
-       for(i=0; i<numGstacks; i++) {
-               gs = &gstacks[i];
-               for(j=0; j<gs->numFree; j++) {
-                       freeGiant(gs->stack[j]);
-                       gs->stack[j] = NULL;
-               }
-               /* and the stack itself - may be null if this was never used */
-               if(gs->stack != NULL) {
-                       ffree(gs->stack);
-                       gs->stack = NULL;
-               }
-       }
-       ffree(gstacks);
-       gstacks = NULL;
-       gstackInitd = 0;
-}
-
-#endif // GIANTS_VIA_STACK
-
-giant borrowGiant(unsigned numDigits)
-{
-       giant           result;
-
-       #if     GIANTS_VIA_STACK
-
-       unsigned        stackNum;
-       gstack          *gs = gstacks;
-
-       #if     WARN_ZERO_GIANT_SIZE
-       if(numDigits == 0) {
-               printf("borrowGiant(0)\n");
-               numDigits = gstacks[numGstacks-1].numDigits;
-       }
-       #endif  // WARN_ZERO_GIANT_SIZE
-
-       /*
-        * Find appropriate stack
-        */
-       if(numDigits <= MIN_GIANT_SIZE)
-               stackNum = 0;
-       else if (numDigits <= (MIN_GIANT_SIZE << GIANT_SIZE_INCR))
-               stackNum = 1;
-       else if (numDigits <= (MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR)))
-               stackNum = 2;
-       else if (numDigits <= (MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR)))
-               stackNum = 3;
-       else if (numDigits <= (MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR)))
-               stackNum = 4;
-       else
-               stackNum = numGstacks;
-
-       if(stackNum >= numGstacks) {
-               /*
-                * out of bounds; just malloc
-                */
-               #if     LOG_GIANT_STACK_OVERFLOW
-               gstackDbg(("giantFromStack overflow; numDigits %d\n",
-                       numDigits));
-               #endif  // LOG_GIANT_STACK_OVERFLOW
-               return newGiant(numDigits);
-       }
-       gs = &gstacks[stackNum];
-
-       #if     GIANT_MAC_DEBUG
-       if((gs->numFree != 0) && (gs->stack == NULL)) {
-               dblog0("borrowGiant: null stack!\n");
-       }
-       #endif
-       if(gs->numFree != 0) {
-               result = gs->stack[--gs->numFree];
-       }
-       else {
-               /*
-                * Stack empty; malloc
-                */
-               result = newGiant(gs->numDigits);
-       }
-
-       #else   /* GIANTS_VIA_STACK */
-
-       result = newGiant(numDigits);
-
-       #endif  /* GIANTS_VIA_STACK */
-
-       PROF_INCR(numBorrows);
-       return result;
-}
-
-void returnGiant(giant g)
-{
-
-       #if     GIANTS_VIA_STACK
-
-       unsigned        stackNum;
-       gstack          *gs;
-       unsigned        cap = g->capacity;
-
-
-       #if     FEE_DEBUG
-       if(!gstackInitd) {
-               CKRaise("returnGiant before stacks initialized!");
-       }
-       #endif  // FEE_DEBUG
-
-       #if     GIANT_MAC_DEBUG
-       if(g == NULL) {
-               dblog0("returnGiant: null g!\n");
-       }
-       #endif
-
-       /*
-        * Find appropriate stack. Note we expect exact match of
-        * capacity and stack's giant size.
-        */
-       /*
-        * Optimized unrolled loop. Just make sure there are enough cases
-        * to handle all of the stacks. Errors in this case will be flagged
-        * via LOG_GIANT_STACK_OVERFLOW.
-        */
-       switch(cap) {
-           case MIN_GIANT_SIZE:
-               stackNum = 0;
-               break;
-           case MIN_GIANT_SIZE << GIANT_SIZE_INCR:
-               stackNum = 1;
-               break;
-           case MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR):
-               stackNum = 2;
-               break;
-           case MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR):
-               stackNum = 3;
-               break;
-           case MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR):
-               stackNum = 4;
-               break;
-           default:
-               stackNum = numGstacks;
-               break;
-       }
-
-       if(stackNum >= numGstacks) {
-               /*
-                * out of bounds; just free
-                */
-               #if     LOG_GIANT_STACK_OVERFLOW
-               gstackDbg(("giantToStack overflow; numDigits %d\n", cap));
-               #endif  // LOG_GIANT_STACK_OVERFLOW
-               freeGiant(g);
-               return;
-       }
-       gs = &gstacks[stackNum];
-       if(gs->numFree == gs->totalGiants) {
-               if(gs->totalGiants == 0) {
-                       gstackDbg(("Initial alloc of gstack(%d)\n",
-                               gs->numDigits));
-                       gs->totalGiants = INIT_NUM_GIANTS;
-               }
-               else {
-                       gs->totalGiants *= 2;
-                       gstackDbg(("Bumping gstack(%d) to %d\n",
-                               gs->numDigits, gs->totalGiants));
-               }
-               gs->stack = (giantstruct**) frealloc(gs->stack, gs->totalGiants*sizeof(giant));
-       }
-       g->sign = 0;            // not sure this is important...
-       gs->stack[gs->numFree++] = g;
-
-       #if     GIANT_MAC_DEBUG
-       if((gs->numFree != 0) && (gs->stack == NULL)) {
-               dblog0("borrowGiant: null stack!\n");
-       }
-       #endif
-       
-       #else   /* GIANTS_VIA_STACK */
-
-       freeGiant(g);
-
-       #endif  /* GIANTS_VIA_STACK */
-}
-
-void freeGiant(giant x) {
-    ffree(x);
-}
-
-giant newGiant(unsigned numDigits) {
-    // giant sufficient for 2^numbits+16 sized ops
-    int size;
-    giant result;
-
-    #if        WARN_ZERO_GIANT_SIZE
-    if(numDigits == 0) {
-        printf("newGiant(0)\n");
-               #if     GIANTS_VIA_STACK
-        numDigits = gstacks[numGstacks-1].totalGiants;
-               #else
-               /* HACK */
-               numDigits = 20;
-               #endif
-    }
-    #endif     // WARN_ZERO_GIANT_SIZE
-
-    size = (numDigits-1) * GIANT_BYTES_PER_DIGIT + sizeof(giantstruct);
-    result = (giant)fmalloc(size);
-    if(result == NULL) {
-       return NULL;
-    }
-    result->sign = 0;
-    result->capacity = numDigits;
-    return result;
-}
-
-giant copyGiant(giant x)
-{
-       int bytes;
-
-       giant result = newGiant(x->capacity);
-
-       /*
-        * 13 Jun 1997
-        * NO! this assumes packed alignment
-        */
-       bytes = sizeof(giantstruct) +
-               ((x->capacity - 1) * GIANT_BYTES_PER_DIGIT);
-       bcopy(x, result, bytes);
-       return result;
-}
-
-/* ------ initialization and utility routines ------ */
-
-
-unsigned bitlen(giant n) {
-    unsigned   b = GIANT_BITS_PER_DIGIT;
-    giantDigit         c = 1 << (GIANT_BITS_PER_DIGIT - 1);
-    giantDigit         w;
-
-    if (isZero(n)) {
-       return(0);
-    }
-    w = n->n[abs(n->sign) - 1];
-    if (!w) {
-       CKRaise("bitlen - no bit set!");
-    }
-    while((w&c) == 0) {
-        b--;
-        c >>= 1;
-    }
-    return(GIANT_BITS_PER_DIGIT * (abs(n->sign)-1) + b);
-}
-
-int bitval(giant n, int pos) {
-    int i = abs(pos) >> GIANT_LOG2_BITS_PER_DIGIT;
-    giantDigit c = 1 << (pos & (GIANT_BITS_PER_DIGIT - 1));
-
-    return((n->n[i]) & c);
-}
-
-int gsign(giant g)
-/* returns the sign of g */
-{
-       if (isZero(g)) return(0);
-       if (g->sign > 0) return(1);
-       return(-1);
-}
-
-/*
- * Adjust sign for possible leading (m.s.) zero digits
- */
-void gtrimSign(giant g)
-{
-       int numDigits = abs(g->sign);
-       int i;
-
-       for(i=numDigits-1; i>=0; i--) {
-               if(g->n[i] == 0) {
-                       numDigits--;
-               }
-               else {
-                       break;
-               }
-       }
-       if(g->sign < 0) {
-               g->sign = -numDigits;
-       }
-       else {
-               g->sign = numDigits;
-       }
-}
-
-
-int isone(giant g) {
-    return((g->sign==1)&&(g->n[0]==1));
-}
-
-int isZero(giant thegiant) {
-/* Returns TRUE if thegiant == 0.  */
-    int count;
-    int length = abs(thegiant->sign);
-    giantDigit *numpointer;
-
-    if (length) {
-        numpointer = thegiant->n;
-
-        for(count = 0; count<length; ++count,++numpointer)
-            if (*numpointer != 0 ) return(FALSE);
-    }
-    return(TRUE);
-}
-
-int gcompg(giant a, giant b)
-/* returns -1,0,1 if a<b, a=b, a>b, respectively */
-{
-    int sa = a->sign;
-    int j;
-    int sb = b->sign;
-    giantDigit va;
-    giantDigit vb;
-    int sgn;
-
-    if(isZero(a) && isZero(b)) return 0;
-    if(sa > sb) return(1);
-    if(sa < sb) return(-1);
-    if(sa < 0) {
-       sa = -sa; /* Take absolute value of sa */
-       sgn = -1;
-    } else sgn = 1;
-    for(j = sa-1; j >= 0; j--) {
-        va = a->n[j]; vb = b->n[j];
-       if (va > vb) return(sgn);
-       if (va < vb) return(-sgn);
-    }
-    return(0);
-}
-
-/* destgiant becomes equal to srcgiant */
-void gtog(giant srcgiant, giant destgiant) {
-
-    int numbytes;
-
-    CKASSERT(srcgiant != NULL);
-    numbytes =  abs(srcgiant->sign) * GIANT_BYTES_PER_DIGIT;
-    if (destgiant->capacity < abs(srcgiant->sign))
-       CKRaise("gtog overflow!!");
-    memcpy((char *)destgiant->n, (char *)srcgiant->n, numbytes);
-    destgiant->sign = srcgiant->sign;
-}
-
-void int_to_giant(int i, giant g) {
-/* The giant g becomes set to the integer value i. */
-    int isneg = (i<0);
-    unsigned int j = abs(i);
-    unsigned dex;
-
-    g->sign = 0;
-    if (i==0) {
-       g->n[0] = 0;
-       return;
-    }
-
-    if(GIANT_BYTES_PER_DIGIT == sizeof(int)) {
-       g->n[0] = j;
-       g->sign = 1;
-    }
-    else {
-       /* one loop per digit */
-       unsigned scnt = GIANT_BITS_PER_DIGIT;   // fool compiler
-
-       for(dex=0; dex<sizeof(int); dex++) {
-           g->n[dex] = j & GIANT_DIGIT_MASK;
-           j >>= scnt;
-           g->sign++;
-           if(j == 0) {
-               break;
-           }
-       }
-    }
-    if (isneg) {
-       g->sign = -(g->sign);
-    }
-}
-
-/*------------- Arithmetic --------------*/
-
-void negg(giant g) {
-/* g becomes -g */
-    g->sign = -g->sign;
-}
-
-void iaddg(int i, giant g) {  /* positive g becomes g + (int)i */
-    int j;
-    giantDigit carry;
-    int size = abs(g->sign);
-
-    if (isZero(g)) {
-       int_to_giant(i,g);
-    }
-    else {
-       carry = i;
-       for(j=0; ((j<size) && (carry != 0)); j++) {
-            g->n[j] = giantAddDigits(g->n[j], carry, &carry);
-        }
-       if(carry) {
-           ++g->sign;
-           // realloc
-           if (g->sign > (int)g->capacity) CKRaise("iaddg overflow!");
-           g->n[size] = carry;
-       }
-    }
-}
-
-/*
- * g *= (int n)
- *
- * FIXME - we can improve this...
- */
-void imulg(unsigned n, giant g)
-{
-       giant tmp = borrowGiant(abs(g->sign) + sizeof(int));
-
-       int_to_giant(n, tmp);
-       mulg(tmp, g);
-       returnGiant(tmp);
-}
-
-static void normal_addg(giant a, giant b)
-/*  b := a + b, both a,b assumed non-negative.    */
-{
-    giantDigit carry1 = 0;
-    giantDigit carry2 = 0;
-    int asize = a->sign, bsize = b->sign;
-    giantDigit *an = a->n;
-    giantDigit *bn = b->n;
-    giantDigit tmp;
-    int j;
-    int comSize;
-    int maxSize;
-
-    if(asize < bsize) {
-        comSize = asize;
-       maxSize = bsize;
-    }
-    else {
-        comSize = bsize;
-       maxSize = asize;
-    }
-
-    /* first handle the common digits */
-    for(j=0; j<comSize; j++) {
-       /*
-        * first add the carry, then an[j] - either add could result
-        * in another carry
-        */
-       if(carry1 || carry2) {
-           tmp = giantAddDigits(bn[j], (giantDigit)1, &carry1);
-       }
-       else {
-           carry1 = 0;
-           tmp = bn[j];
-       }
-       bn[j] = giantAddDigits(tmp, an[j], &carry2);
-    }
-
-    if(asize < bsize) {
-
-       /* now propagate remaining carry beyond asize */
-       if(carry2) {
-           carry1 = 1;
-       }
-       if(carry1) {
-           for(; j<bsize; j++) {
-               bn[j] = giantAddDigits(bn[j], (giantDigit)1, &carry1);
-               if(carry1 == 0) {
-                   break;
-               }
-           }
-       }
-    } else {
-       /* now propagate remaining an[] and carry beyond bsize */
-       if(carry2) {
-           carry1 = 1;
-       }
-       for(; j<asize; j++) {
-           if(carry1) {
-               bn[j] = giantAddDigits(an[j], (giantDigit)1, &carry1);
-           }
-           else {
-               bn[j] = an[j];
-               carry1 = 0;
-           }
-       }
-    }
-    b->sign = maxSize;
-    if(carry1) {
-       // realloc?
-       bn[j] = 1;
-       b->sign++;
-       if (b->sign > (int)b->capacity) CKRaise("iaddg overflow!");
-    }
-
-}
-
-static void normal_subg(giant a, giant b)
-/* b := b - a; requires b, a non-negative and b >= a. */
-{
-    int j;
-    int size = b->sign;
-    giantDigit tmp;
-    giantDigit borrow1 = 0;
-    giantDigit borrow2 = 0;
-    giantDigit *an = a->n;
-    giantDigit *bn = b->n;
-
-    if(a->sign == 0) {
-       return;
-    }
-
-    for (j=0; j<a->sign; ++j) {
-       if(borrow1 || borrow2) {
-           tmp = giantSubDigits(bn[j], (giantDigit)1, &borrow1);
-       }
-       else {
-           tmp = bn[j];
-           borrow1 = 0;
-       }
-       bn[j] = giantSubDigits(tmp, an[j], &borrow2);
-    }
-    if(borrow1 || borrow2) {
-       /* propagate borrow thru remainder of bn[] */
-       borrow1 = 1;
-       for (j=a->sign; j<size; ++j) {
-           if(borrow1) {
-               bn[j] = giantSubDigits(bn[j], (giantDigit)1, &borrow1);
-           }
-           else {
-               break;
-           }
-       }
-    }
-
-    /* adjust sign for leading zero digits */
-    while((size-- > 0) && (b->n[size] == 0))
-       ;
-    b->sign = (b->n[size] == 0)? 0 : size+1;
-}
-
-static void reverse_subg(giant a, giant b)
-/* b := a - b; requires b, a non-negative and a >= b. */
-{
-    int j;
-    int size = a->sign;
-    giantDigit tmp;
-    giantDigit borrow1 = 0;
-    giantDigit borrow2 = 0;
-    giantDigit *an = a->n;
-    giantDigit *bn = b->n;
-
-    if(b->sign == 0) {
-       gtog(a, b);
-       return;
-    }
-    for (j=0; j<b->sign; ++j) {
-       if(borrow1 || borrow2) {
-           tmp = giantSubDigits(an[j], (giantDigit)1, &borrow1);
-       }
-       else {
-           tmp = an[j];
-           borrow1 = 0;
-       }
-       bn[j] = giantSubDigits(tmp, bn[j], &borrow2);
-    }
-    if(borrow1 || borrow2) {
-       /* propagate borrow thru remainder of bn[] */
-       borrow1 = 1;
-    }
-    for (j=b->sign; j<size; ++j) {
-       if(borrow1) {
-           bn[j] = giantSubDigits(an[j], (giantDigit)1, &borrow1);
-       }
-       else {
-           bn[j] = an[j];
-           borrow1 = 0;
-       }
-    }
-
-    b->sign = size; /* REC, 21 Apr 1996. */
-    while(!b->n[--size]);
-    b->sign = size+1;
-}
-
-
-void addg(giant a, giant b)
-/* b := b + a, any signs any result. */
-{   int asgn = a->sign, bsgn = b->sign;
-    if(asgn == 0) return;
-    if(bsgn == 0) {
-       gtog(a,b);
-       return;
-    }
-    if((asgn < 0) == (bsgn < 0)) {
-       if(bsgn > 0) {
-               normal_addg(a,b);
-               return;
-       }
-       negg(a); if(a != b) negg(b); normal_addg(a,b);  /* Fix REC 1 Dec 98. */
-       negg(a); if(a != b) negg(b); return;  /* Fix REC 1 Dec 98. */
-    }
-    if(bsgn > 0) {
-        negg(a);
-       if(gcompg(b,a) >= 0) {
-               normal_subg(a,b);
-               negg(a);
-               return;
-       }
-       reverse_subg(a,b);
-       negg(a);
-       negg(b);
-       return;
-    }
-    negg(b);
-    if(gcompg(b,a) < 0) {
-       reverse_subg(a,b);
-       return;
-    }
-    normal_subg(a,b);
-    negg(b);
-    return;
-}
-
-void subg(giant a, giant b)
-/* b := b - a, any signs, any result. */
-{
-  int asgn = a->sign, bsgn = b->sign;
-  if(asgn == 0) return;
-  if(bsgn == 0) {
-       gtog(a,b);
-       negg(b);
-       return;
-  }
-  if((asgn < 0) != (bsgn < 0)) {
-       if(bsgn > 0) {
-               negg(a);
-               normal_addg(a,b);
-               negg(a);
-               return;
-       }
-       negg(b);
-       normal_addg(a,b);
-       negg(b);
-       return;
-  }
-  if(bsgn > 0) {
-       if(gcompg(b,a) >= 0) {
-               normal_subg(a,b);
-               return;
-       }
-       reverse_subg(a,b);
-       negg(b);
-       return;
-  }
-  negg(a); negg(b);
-  if(gcompg(b,a) >= 0) {
-               normal_subg(a,b);
-               negg(a);
-               negg(b);
-               return;
-  }
-  reverse_subg(a,b);
-  negg(a);
-  return;
-}
-
-static void bdivg(giant v, giant u)
-/* u becomes greatest power of two not exceeding u/v. */
-{
-    int diff = bitlen(u) - bitlen(v);
-    giant scratch7;
-
-    if (diff<0) {
-        int_to_giant(0,u);
-        return;
-    }
-    scratch7 = borrowGiant(u->capacity);
-    gtog(v, scratch7);
-    gshiftleft(diff,scratch7);
-    if(gcompg(u,scratch7) < 0) diff--;
-    if(diff<0) {
-        int_to_giant(0,u);
-       returnGiant(scratch7);
-        return;
-    }
-    int_to_giant(1,u);
-    gshiftleft(diff,u);
-    returnGiant(scratch7);
-}
-
-int binvaux(giant p, giant x)
-/* Binary inverse method.
-   Returns zero if no inverse exists, in which case x becomes
-   GCD(x,p). */
-{
-    giant scratch7;
-    giant u0;
-    giant u1;
-    giant v0;
-    giant v1;
-    int result = 1;
-    int giantSize;
-    PROF_START;
-
-    if(isone(x)) return(result);
-    giantSize = 4 * abs(p->sign);
-    scratch7 = borrowGiant(giantSize);
-    u0 = borrowGiant(giantSize);
-    u1 = borrowGiant(giantSize);
-    v0 = borrowGiant(giantSize);
-    v1 = borrowGiant(giantSize);
-    int_to_giant(1, v0); gtog(x, v1);
-    int_to_giant(0,x); gtog(p, u1);
-    while(!isZero(v1)) {
-        gtog(u1, u0); bdivg(v1, u0);
-        gtog(x, scratch7);
-        gtog(v0, x);
-        mulg(u0, v0);
-        subg(v0,scratch7);
-        gtog(scratch7, v0);
-
-        gtog(u1, scratch7);
-        gtog(v1, u1);
-        mulg(u0, v1);
-        subg(v1,scratch7);
-        gtog(scratch7, v1);
-    }
-    if (!isone(u1)) {
-        gtog(u1,x);
-        if(x->sign<0) addg(p, x);
-        result = 0;
-        goto done;
-    }
-    if (x->sign<0) addg(p, x);
-  done:
-    returnGiant(scratch7);
-    returnGiant(u0);
-    returnGiant(u1);
-    returnGiant(v0);
-    returnGiant(v1);
-    PROF_END(binvauxTime);
-    return(result);
-}
-
-/*
- * Superceded by binvg_cp()
- */
-#if    0
-int binvg(giant p, giant x)
-{
-       modg(p, x);
-       return(binvaux(p,x));
-}
-#endif
-
-static void absg(giant g) {
-/* g becomes the absolute value of g */
-    if (g->sign < 0) g->sign = -g->sign;
-}
-
-void gshiftleft(int bits, giant g) {
-/* shift g left bits bits.  Equivalent to g = g*2^bits */
-    int        rem = bits & (GIANT_BITS_PER_DIGIT - 1);
-    int        crem = GIANT_BITS_PER_DIGIT - rem;
-    int        digits = 1 + (bits >> GIANT_LOG2_BITS_PER_DIGIT);
-    int        size = abs(g->sign);
-    int        j;
-    int        k;
-    int        sign = gsign(g);
-    giantDigit         carry;
-    giantDigit         dat;
-
-    #if                FEE_DEBUG
-    if(bits < 0) {
-        CKRaise("gshiftleft(-bits)\n");
-    }
-    #endif     /* FEE_DEBUG */
-
-    if(!bits) return;
-    if(!size) return;
-    if((size+digits) > (int)g->capacity) {
-        CKRaise("gshiftleft overflow");
-        return;
-    }
-    k = size - 1 + digits;     // (MSD of result + 1)
-    carry = 0;
-
-    /* bug fix for 32-bit giantDigits; this is also an optimization for
-     * other sizes. rem=0 means we're shifting strictly by digits, no
-     * bit shifts. */
-    if(rem == 0) {
-        g->n[k] = 0;           // XXX hack - for sign fixup
-       for(j=size-1; j>=0; j--) {
-           g->n[--k] = g->n[j];
-       }
-       do{
-           g->n[--k] = 0;
-       } while(k>0);
-    }
-    else {
-       /*
-        * normal unaligned case
-        * FIXME - this writes past g->n[size-1] the first time thru!
-        */
-       for(j=size-1; j>=0; j--) {
-           dat = g->n[j];
-           g->n[k--] = (dat >> crem) | carry;
-           carry = (dat << rem);
-       }
-       do{
-           g->n[k--] = carry;
-           carry = 0;
-       } while(k>=0);
-    }
-    k = size - 1 + digits;
-    if(g->n[k] == 0) --k;
-    g->sign = sign * (k+1);
-    if (abs(g->sign) > g->capacity) {
-       CKRaise("gshiftleft overflow");
-    }
-}
-
-void gshiftright(int bits, giant g) {
-/* shift g right bits bits.  Equivalent to g = g/2^bits */
-    int j;
-    int size=abs(g->sign);
-    giantDigit carry;
-    int digits = bits >> GIANT_LOG2_BITS_PER_DIGIT;
-    int remain = bits & (GIANT_BITS_PER_DIGIT - 1);
-    int cremain = GIANT_BITS_PER_DIGIT - remain;
-
-    #if                FEE_DEBUG
-    if(bits < 0) {
-        CKRaise("gshiftright(-bits)\n");
-    }
-    #endif     /* FEE_DEBUG */
-    if(bits==0) return;
-    if(isZero(g)) return;
-    if (digits >= size) {
-        g->sign = 0;
-        return;
-    }
-
-    size -= digits;
-
-/* Begin OPT: 9 Jan 98 REC. */
-    if(remain == 0) {
-        if(g->sign > 0) {
-           g->sign = size;
-       }
-       else {
-           g->sign = -size;
-       }
-        for(j=0; j < size; j++) {
-           g->n[j] = g->n[j+digits];
-       }
-        return;
-    }
-/* End OPT: 9 Jan 98 REC. */
-
-    for(j=0;j<size;++j) {
-        if (j==size-1) {
-           carry = 0;
-       }
-        else {
-           carry = (g->n[j+digits+1]) << cremain;
-       }
-        g->n[j] = ((g->n[j+digits]) >> remain ) | carry;
-    }
-    if (g->n[size-1] == 0) {
-       --size;
-    }
-    if(g->sign > 0) {
-       g->sign = size;
-    }
-    else {
-        g->sign = -size;
-    }
-    if (abs(g->sign) > g->capacity) {
-       CKRaise("gshiftright overflow");
-    }
-}
-
-
-void extractbits(unsigned n, giant src, giant dest) {
-/* dest becomes lowermost n bits of src.  Equivalent to dest = src % 2^n */
-    int digits = n >> GIANT_LOG2_BITS_PER_DIGIT;
-    int numbytes = digits * GIANT_BYTES_PER_DIGIT;
-    int bits = n & (GIANT_BITS_PER_DIGIT - 1);
-
-    if (n <= 0) {
-       return;
-    }
-    if (dest->capacity * 8 * GIANT_BYTES_PER_DIGIT < n) {
-       CKRaise("extractbits - not enough room");
-    }
-    if (digits >= abs(src->sign)) {
-       gtog(src,dest);
-    }
-    else {
-          memcpy((char *)(dest->n), (char *)(src->n), numbytes);
-          if (bits) {
-              dest->n[digits] = src->n[digits] & ((1<<bits)-1);
-              ++digits;
-          }
-         /* Next, fix by REC, 12 Jan 97. */
-          // while((dest->n[words-1] == 0) && (words > 0)) --words;
-          while((digits > 0) && (dest->n[digits-1] == 0)) {
-             --digits;
-         }
-          if(src->sign < 0) {
-             dest->sign = -digits;
-         }
-          else {
-             dest->sign = digits;
-         }
-    }
-    if (abs(dest->sign) > dest->capacity) {
-       CKRaise("extractbits overflow");
-    }
-}
-
-#define NEW_MERSENNE   0
-
-/*
- * New gmersennemod, 24 Dec 1997. This runs significantly slower than the
- * original.
- */
-#if    NEW_MERSENNE
-
-void
-gmersennemod(
-       int     n,
-       giant   g
-)
-/* g := g (mod 2^n - 1) */
-{
-    int the_sign;
-    giant scratch3 = borrowGiant(g->capacity);
-    giant scratch4 = borrowGiant(1);
-
-    if ((the_sign = gsign(g)) < 0) absg(g);
-    while (bitlen(g) > n) {
-       gtog(g,scratch3);
-       gshiftright(n,scratch3);
-       addg(scratch3,g);
-       gshiftleft(n,scratch3);
-       subg(scratch3,g);
-    }
-    if(isZero(g)) goto out;
-    int_to_giant(1,scratch3);
-    gshiftleft(n,scratch3);
-    int_to_giant(1,scratch4);
-    subg(scratch4,scratch3);
-    if(gcompg(g,scratch3) >= 0) subg(scratch3,g);
-    if (the_sign < 0) {
-       g->sign = -g->sign;
-       addg(scratch3,g);
-    }
-out:
-    returnGiant(scratch3);
-    returnGiant(scratch4);
-}
-
-#else  /* NEW_MERSENNE */
-
-void gmersennemod(int n, giant g) {
-/*   g becomes g mod ((2^n)-1)
-     31 Jul 96 modified REC.
-     17 Jan 97 modified REC.
-*/
-    unsigned bits = n & (GIANT_BITS_PER_DIGIT - 1);
-    unsigned digits =  1 + ((n-1) >> GIANT_LOG2_BITS_PER_DIGIT);
-    int isPositive = (g->sign > 0);
-    int j;
-    int b;
-    int size;
-    int foundzero;
-    giantDigit mask = (bits == 0) ? GIANT_DIGIT_MASK : (giantDigit)((1<<bits)-1);
-    giant scratch1;
-
-    b = bitlen(g);
-    if(b < n) {
-        unsigned numDigits = (n + GIANT_BITS_PER_DIGIT - 1) >>
-               GIANT_LOG2_BITS_PER_DIGIT;
-       giantDigit lastWord = 0;
-       giantDigit bits = 1;
-
-        if(g->sign >= 0) return;
-
-       /*
-        * Cons up ((2**n)-1), add to g.
-        */
-       scratch1 = borrowGiant(numDigits + 1);
-       scratch1->sign = numDigits;
-       for(j=0; j<(int)(numDigits-1); j++) {
-               scratch1->n[j] = GIANT_DIGIT_MASK;
-       }
-
-       /*
-        * Last word has lower (n & (GIANT_BITS_PER_DIGIT-1)) bits set.
-        */
-       for(j=0; j < (int)(n & (GIANT_BITS_PER_DIGIT-1)); j++) {
-               lastWord |= bits;
-               bits <<= 1;
-       }
-       scratch1->n[numDigits-1] = lastWord;
-       addg(g, scratch1);   /* One version. */
-       gtog(scratch1, g);
-       returnGiant(scratch1);
-       return;
-    }
-    if(b == n) {
-        for(foundzero=0, j=0; j<b; j++) {
-            if(bitval(g, j)==0) {
-                foundzero = 1;
-                break;
-            }
-        }
-        if (!foundzero) {
-            int_to_giant(0, g);
-            return;
-        }
-    }
-
-    absg(g);
-    scratch1 = borrowGiant(g->capacity);
-    while ( ((unsigned)(g->sign) > digits) ||
-            ( ((unsigned)(g->sign)==digits) && (g->n[digits-1] > mask))) {
-        extractbits(n, g, scratch1);
-        gshiftright(n, g);
-        addg(scratch1, g);
-    }
-    size = g->sign;
-
-/* Commence new negation routine - REC 17 Jan 1997. */
-    if (!isPositive) { /* Mersenne negation is just bitwise complement. */
-        for(j = digits-1; j >= size; j--) {
-           g->n[j] = GIANT_DIGIT_MASK;
-       }
-        for(j = size-1; j >= 0; j--) {
-           g->n[j] = ~g->n[j];
-       }
-       g->n[digits-1] &= mask;
-       j = digits-1;
-        while((g->n[j] == 0) && (j > 0)) {
-           --j;
-       }
-        size = j+1;
-    }
-/* End new negation routine. */
-
-    g->sign = size;
-    if (abs(g->sign) > g->capacity) {
-       CKRaise("gmersennemod overflow");
-    }
-    if (size < (int)digits) {
-       goto bye;
-    }
-    if (g->n[size-1] != mask) {
-       goto bye;
-    }
-    mask = GIANT_DIGIT_MASK;
-    for(j=0; j<(size-1); j++) {
-       if (g->n[j] != mask) {
-           goto bye;
-       }
-    }
-    g->sign = 0;
-  bye:
-    returnGiant(scratch1);
-}
-
-#endif /* NEW_MERSENNE */
-
-void mulg(giant a, giant b) { /* b becomes a*b. */
-
-    int i;
-    int asize, bsize;
-    giantDigit *bptr = b->n;
-    giantDigit mult;
-    giant scratch1;
-    giantDigit carry;
-    giantDigit *scrPtr;
-
-
-    if (isZero(b)) {
-       return;
-    }
-    if (isZero(a)) {
-       gtog(a, b);
-       return;
-    }
-    if(a == b) {
-       grammarSquare(b);
-       return;
-    }
-
-    bsize = abs(b->sign);
-    asize = abs(a->sign);
-    scratch1 = borrowGiant((asize+bsize));
-    scrPtr = scratch1->n;
-
-    for(i=0; i<asize+bsize; ++i) {
-       scrPtr[i]=0;
-    }
-
-    for(i=0; i<bsize; ++i, scrPtr++) {
-       mult = bptr[i];
-       if (mult != 0) {
-           carry = VectorMultiply(mult,
-               a->n,
-               asize,
-               scrPtr);
-           /* handle MSD carry */
-           scrPtr[asize] += carry;
-       }
-    }
-    bsize+=asize;
-     if(scratch1->n[bsize - 1] == 0) {
-        --bsize;
-    }
-    scratch1->sign = gsign(a) * gsign(b) * bsize;
-    if (abs(scratch1->sign) > scratch1->capacity) {
-       CKRaise("GiantGrammarMul overflow");
-    }
-    gtog(scratch1,b);
-    returnGiant(scratch1);
-
-    #if                FEE_DEBUG
-    (void)bitlen(b); // Assertion....
-    #endif     /* FEE_DEBUG */
-    PROF_INCR(numMulg);                        // for normal profiling
-    INCR_MULGS;                                // for ellipticMeasure
-}
-
-void grammarSquare(giant a) {
-    /*
-     * For now, we're going to match the old implementation line for
-     * line by maintaining prod, carry, and temp as double precision
-     * giantDigits. There is probably a much better implementation....
-     */
-    giantDigit         prodLo;
-    giantDigit         prodHi;
-    giantDigit         carryLo = 0;
-    giantDigit         carryHi = 0;
-    giantDigit         tempLo;
-    giantDigit         tempHi;
-    unsigned int       cur_term;
-    unsigned           asize;
-    unsigned           max;
-    giantDigit         *ptr = a->n;
-    giantDigit         *ptr1;
-    giantDigit         *ptr2;
-    giant              scratch;
-
-    /* dmitch 11 Jan 1998 - special case for a == 0 */
-    if(a->sign == 0) {
-       goto end;
-    }
-    /* end a == 0 case */
-    asize = abs(a->sign);
-    max = asize * 2 - 1;
-    scratch = borrowGiant(2 * asize);
-    asize--;
-
-    /*
-     * temp = *ptr;
-     * temp *= temp;
-     * scratch->n[0] = temp;
-     * carry = temp >> 16;
-     */
-    giantMulDigits(*ptr, *ptr, &tempLo, &tempHi);
-    scratch->n[0] = tempLo;
-    carryLo = tempHi;
-    carryHi = 0;
-
-    for (cur_term = 1; cur_term < max; cur_term++) {
-       ptr1 = ptr2 = ptr;
-       if (cur_term <= asize) {
-           ptr2 += cur_term;
-       } else {
-           ptr1 += cur_term - asize;
-           ptr2 += asize;
-       }
-
-       /*
-        * prod = carry & 0xFFFF;
-        * carry >>= 16;
-        */
-       prodLo = carryLo;
-       prodHi = 0;
-       carryLo = carryHi;
-       carryHi = 0;
-       while(ptr1 < ptr2) {
-           /*
-            * temp = *ptr1++ * *ptr2--;
-            */
-           giantMulDigits(*ptr1++, *ptr2--, &tempLo, &tempHi);
-
-           /*
-            * prod += (temp << 1) & 0xFFFF;
-            */
-           giantAddDouble(&prodLo, &prodHi, (tempLo << 1));
-
-           /*
-            * carry += (temp >> 15);
-            * use bits from both product digits..
-            */
-           giantAddDouble(&carryLo, &carryHi,
-               (tempLo >> (GIANT_BITS_PER_DIGIT - 1)));
-           giantAddDouble(&carryLo, &carryHi, (tempHi << 1));
-
-           /* snag the msb from that last shift */
-           carryHi += (tempHi >> (GIANT_BITS_PER_DIGIT - 1));
-       }
-       if (ptr1 == ptr2) {
-           /*
-            * temp = *ptr1;
-            * temp *= temp;
-            */
-           giantMulDigits(*ptr1, *ptr1, &tempLo, &tempHi);
-
-           /*
-            * prod += temp & 0xFFFF;
-            */
-           giantAddDouble(&prodLo, &prodHi, tempLo);
-
-           /*
-            * carry += (temp >> 16);
-            */
-           giantAddDouble(&carryLo, &carryHi, tempHi);
-       }
-
-       /*
-        * carry += prod >> 16;
-        */
-       giantAddDouble(&carryLo, &carryHi, prodHi);
-
-       scratch->n[cur_term] = prodLo;
-    }
-    if (carryLo) {
-       scratch->n[cur_term] = carryLo;
-       scratch->sign = cur_term+1;
-    } else scratch->sign = cur_term;
-
-    gtog(scratch,a);
-    returnGiant(scratch);
-end:
-    PROF_INCR(numGsquare);
-}
-
-/*
- * Clear all of a giant's data fields, for secure erasure of sensitive data.,
- */
-void clearGiant(giant g)
-{
-    unsigned i;
-
-    for(i=0; i<g->capacity; i++) {
-       g->n[i] = 0;
-    }
-    g->sign = 0;
-}
-
-#if    ENGINE_127_BITS
-/*
- * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997
- */
-int
-scompg(int n, giant g) {
-    if((g->sign == 1) && (g->n[0] == n)) return(1);
-    return(0);
-}
-
-#endif // ENGINE_127_BITS
-
-/*
- */
-
-/*
- * Calculate the reciprocal of a demonimator used in divg_via_recip() and
- * modg_via_recip().
- */
-void
-make_recip(giant d, giant r)
-/* r becomes the steady-state reciprocal
-   2^(2b)/d, where b = bit-length of d-1. */
-{
-       int b;
-       int giantSize = 4 * abs(d->sign);
-       giant tmp = borrowGiant(giantSize);
-       giant tmp2 = borrowGiant(giantSize);
-
-       if (isZero(d) || (d->sign < 0))
-       {
-               CKRaise("illegal argument to make_recip");
-       }
-       int_to_giant(1, r); subg(r, d); b = bitlen(d); addg(r, d);
-       gshiftleft(b, r); gtog(r, tmp2);
-       while(1) {
-               gtog(r, tmp);
-               gsquare(tmp);
-               gshiftright(b, tmp);
-               mulg(d, tmp);
-               gshiftright(b, tmp);
-               addg(r, r); subg(tmp, r);
-               if(gcompg(r, tmp2) <= 0) break;
-               gtog(r, tmp2);
-       }
-       int_to_giant(1, tmp);
-       gshiftleft(2*b, tmp);
-       gtog(r, tmp2); mulg(d, tmp2);
-       subg(tmp2, tmp);
-       int_to_giant(1, tmp2);
-       while(tmp->sign < 0) {
-               subg(tmp2, r);
-               addg(d, tmp);
-       }
-
-       returnGiant(tmp);
-       returnGiant(tmp2);
-       return;
-}
-
-/*
- * Optimized divg, when reciprocal of denominator is known.
- */
-void
-divg_via_recip(giant d, giant r, giant n)
-/* n := n/d, where r is the precalculated
-   steady-state reciprocal of d. */
-{
-       int s = 2*(bitlen(r)-1), sign = gsign(n);
-       int giantSize = (4 * abs(d->sign)) + abs(n->sign);
-       giant tmp = borrowGiant(giantSize);
-       giant tmp2 = borrowGiant(giantSize);
-
-       if (isZero(d) || (d->sign < 0))
-       {
-               CKRaise("illegal argument to divg_via_recip");
-       }
-       n->sign = abs(n->sign);
-       int_to_giant(0, tmp2);
-       while(1) {
-               gtog(n, tmp);
-               mulg(r, tmp);
-               gshiftright(s, tmp);
-               addg(tmp, tmp2);
-               mulg(d, tmp);
-               subg(tmp, n);
-               if(gcompg(n,d) >= 0) {
-                       subg(d,n);
-                       iaddg(1, tmp2);
-               }
-               if(gcompg(n,d) < 0) break;
-       }
-       gtog(tmp2, n);
-       n->sign *= sign;
-       returnGiant(tmp);
-       returnGiant(tmp2);
-       return;
-}
-
-/*
- * Optimized modg, when reciprocal of denominator is known.
- */
-
-/* New version, 24 Dec 1997. */
-
-void
-modg_via_recip(
-       giant   d,
-       giant   r,
-       giant   n
-)
-/* This is the fastest mod of the present collection.
-   n := n % d, where r is the precalculated
-   steady-state reciprocal of d. */
-
-{
-    int                s = (bitlen(r)-1), sign = n->sign;
-    int        giantSize = (4 * abs(d->sign)) + abs(n->sign);
-    giant      tmp, tmp2;
-
-    tmp = borrowGiant(giantSize);
-    tmp2 = borrowGiant(giantSize);
-    if (isZero(d) || (d->sign < 0))
-    {
-       CKRaise("illegal argument to modg_via_recip");
-    }
-    n->sign = abs(n->sign);
-    while (1)
-    {
-       gtog(n, tmp);
-       /* bug fix 13 Apr 1998 */
-       if(s == 0) {
-           gshiftleft(1, tmp);
-       }
-       else {
-           gshiftright(s-1, tmp);
-       }
-       /* end fix */
-       mulg(r, tmp);
-       gshiftright(s+1, tmp);
-       mulg(d, tmp);
-       subg(tmp, n);
-       if (gcompg(n,d) >= 0)
-               subg(d,n);
-       if (gcompg(n,d) < 0)
-               break;
-    }
-    if (sign >= 0)
-       goto done;
-    if (isZero(n))
-       goto done;
-    negg(n);
-    addg(d,n);
-done:
-    returnGiant(tmp);
-    returnGiant(tmp2);
-    return;
-}
-
-/*
- * Unoptimized, inefficient general modg, when reciprocal of denominator
- * is not known.
- */
-void
-modg(
-       giant   d,
-       giant   n
-)
-{
-       /* n becomes n%d. n is arbitrary, but the denominator d must be
-        * positive! */
-
-       /*
-        * 4/9/2001: seeing overflow on this recip. Alloc per 
-        * d->capacity, not d->sign.
-        */
-       //giant recip = borrowGiant(2 * abs(d->sign));
-       giant recip = borrowGiant(2 * d->capacity);
-
-       #if     WARN_UNOPTIMIZE
-       dbgLog(("Warning: unoptimized modg!\n"));
-       #endif  // WARN_UNOPTIMIZE
-
-       make_recip(d, recip);
-       modg_via_recip(d, recip, n);
-       returnGiant(recip);
-}
-
-/*
- * Unoptimized, inefficient general divg, when reciprocal of denominator
- * is not known.
- */
-void
-divg(
-       giant   d,
-       giant   n
-)
-{
-       /* n becomes n/d. n is arbitrary, but the denominator d must be
-        * positive!
-        */
-
-       giant recip = borrowGiant(2 * abs(d->sign));
-
-       #if     WARN_UNOPTIMIZE
-       dbgLog(("Warning: unoptimized divg!\n"));
-       #endif  // WARN_UNOPTIMIZE
-
-       make_recip(d, recip);
-       divg_via_recip(d, recip, n);
-       returnGiant(recip);
-}