Esempio n. 1
0
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");
    }
}
Esempio n. 2
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;
}
/*
 * 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);

}
Esempio n. 4
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);
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
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;
	}
    }
}
Esempio n. 8
0
/* 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!");
    }

}
Esempio n. 9
0
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 */
}
Esempio n. 10
0
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");
    }
}