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"); } }
/* 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; }
/* * serialize, deserialize giants's n[] to/from byte stream. * First byte of byte stream is the MS byte of the resulting giant, * regardless of the size of giantDigit. * * No assumption is made about the alignment of cp. * * As of 7 Apr 1998, these routines are in compliance with IEEE P1363, * section 5.5.1, for the representation of a large integer as a byte * stream. */ void serializeGiant(giant g, unsigned char *cp, unsigned numBytes) { unsigned digitDex; unsigned numDigits = BYTES_TO_GIANT_DIGITS(numBytes); giantDigit digit; unsigned char *ptr; unsigned digitByte; int size = abs(g->sign); if(numBytes == 0) { return; } if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) { CKRaise("serializeGiant: CAPACITY EXCEEDED!\n"); } /* * note we might be asked to write more than the valid number * if bytes in the giant in the case if truncated sign due to * zero M.S. digit(s).... */ /* * zero out unused digits so we can infer sign during deserialize */ for(digitDex=size; digitDex<numDigits; digitDex++) { g->n[digitDex] = 0; } /* * Emit bytes starting from l.s. byte. L.s. byte of the outgoing * data stream is *last*. L.s. digit of giant's digits is *first*. */ digitDex = 0; ptr = &cp[numBytes - 1]; do { /* one loop per giant digit */ digit = g->n[digitDex++]; for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) { /* one loop per byte in the digit */ *ptr-- = (unsigned char)digit; if(--numBytes == 0) { break; } digit >>= 8; } } while(numBytes != 0); }
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"); } }
/* * Resulting sign here is always positive; leading zeroes are reflected * in an altered g->sign. */ void deserializeGiant(const unsigned char *cp, giant g, unsigned numBytes) { unsigned numDigits; giantDigit digit; int digitDex; unsigned digitByte; const unsigned char *ptr; if(numBytes == 0) { g->sign = 0; return; } numDigits = (numBytes + GIANT_BYTES_PER_DIGIT - 1) / GIANT_BYTES_PER_DIGIT; if(numBytes > (g->capacity * GIANT_BYTES_PER_DIGIT)) { CKRaise("deserializeGiant: CAPACITY EXCEEDED!\n"); } /* * Start at l.s. byte. That's the end of the cp[] array and * the beginning of the giantDigit array. */ digitDex = 0; ptr = &cp[numBytes - 1]; do { /* one loop per digit */ digit = 0; for(digitByte=0; digitByte<GIANT_BYTES_PER_DIGIT; digitByte++) { /* one loop per byte in the digit */ digit |= (*ptr-- << (8 * digitByte)); /* FIXME - shouldn't we update g->n before this break? */ if(--numBytes == 0) { break; } } g->n[digitDex++] = digit; } while (numBytes != 0); /* * Infer sign from non-zero n[] elements */ g->sign = numDigits; gtrimSign(g); }
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); }
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; } } }
/* new addg, negg, and gcompg from Crandall 6/95 */ 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!"); } }
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 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"); } }