Beispiel #1
0
static void popg(mpz_t val, unsigned char *face, int s)
{
  if(s>=4) {
    s>>=1;
    popg(val, face, s);
    popg(val, face+s, s);
    popg(val, face+s*48, s);
    popg(val, face+s*49, s);
  } else {
Beispiel #2
0
void iaddg(int	i, giant g)
/* Giant g becomes g + (int)i. */
{
	int 	w, j = 0, carry = 0, size = abs(g->sign);
	giant	tmp;

	if (isZero(g))
	{
		itog(i, g);
	}
	else if (g->sign < 0) {
		tmp = popg();
		itog(i, tmp);
		addg(tmp, g);
		pushg(1);
		return;
	}
	else
	{
		w = g->n[0] + i;
		do
		{
			g->n[j] = (unsigned short)(w & 65535L);
			carry = w >> 16;
			w = g->n[++j] + carry;
		} while ((carry != 0) && (j < size));
	}
	if (carry)
	{
		++g->sign;
		g->n[size] = (unsigned short)carry;
	}
}
Beispiel #3
0
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;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}
	tmp = popg();
	tmp2 = popg();
	itog(1, r);
	subg(r, d);
	b = bitlen(d);
	addg(r, d);
	gshiftleft(b, r);
	gtog(r, tmp2);
	while (1)
	{
		gtog(r, tmp);
		squareg(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);
	}
	itog(1, tmp);
	gshiftleft(2 * b, tmp);
	gtog(r, tmp2);
	mulg(d, tmp2);
	subg(tmp2, tmp);
	itog(1, tmp2);
	while (tmp->sign < 0)
	{
		subg(tmp2, r);
		addg(d, tmp);
	}
	pushg(2);
}
Beispiel #4
0
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;
	giant 	tmp, tmp2;

	if (isZero(d) || (d->sign < 0))
	{
		exit(SIGN);
	}

	tmp = popg();
	tmp2 = popg();

	n->sign = abs(n->sign);
	while (1)
	{
		gtog(n, tmp); gshiftright(s - 1, tmp);
		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:
	pushg(2);
	return;
}
Beispiel #5
0
void grammarsquareg(giant a)
/* a := a^2. */
{
	unsigned int	cur_term;
	unsigned int	prod, carry = 0, temp;
	unsigned int	asize = abs(a->sign), max = asize * 2 - 1;
	unsigned short	*ptr = a->n, *ptr1, *ptr2;
	giant scratch;

	if (asize == 0) {
		itog(0, a);
		return;
	}

	scratch = popg();

	asize--;

	temp = *ptr;
	temp *= temp;
	scratch->n[0] = temp;
	carry = temp >> 16;

	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;
		while (ptr1 < ptr2) {
			temp = *ptr1++ * *ptr2--;
			prod += (temp << 1) & 0xFFFF;
			carry += (temp >> 15);
		}
		if (ptr1 == ptr2) {
			temp = *ptr1;
			temp *= temp;
			prod += temp & 0xFFFF;
			carry += (temp >> 16);
		}
		carry += prod >> 16;
		scratch->n[cur_term] = (unsigned short)(prod);
	}
Beispiel #6
0
void grammarmulg(giant a, giant b)
/* b becomes a*b. */
{
	int 			i, j;
	unsigned int 	prod, carry = 0;
	int 			asize = abs(a->sign), bsize = abs(b->sign);
	unsigned short 	*aptr, *bptr, *destptr;
	unsigned short	mult;
	giant scratch = popg();

	for (i = 0; i < asize + bsize; ++i)
	{
		scratch->n[i] = 0;
	}

	bptr = &(b->n[0]);
	for (i = 0; i < bsize; ++i)
	{
		mult = *(bptr++);
		if (mult)
		{
			carry = 0;
			aptr = &(a->n[0]);
			destptr = &(scratch->n[i]);
			for (j = 0; j < asize; ++j)
			{
				prod = *(aptr++) * mult + *destptr + carry;
				*(destptr++) = (unsigned short)(prod & 0xffff);
				carry = prod >> 16;
			}
			*destptr = (unsigned short)carry;
		}
	}
	bsize += asize;
	if (!carry)
		--bsize;
	scratch->sign = gsign(a)*gsign(b)*bsize;
	gtog(scratch, b);
	pushg(1);
}
Beispiel #7
0
void powermodg(giant x, giant n, giant g)
/* x becomes x^n (mod g). */
{
	int 		len, pos;
	giant		scratch2 = popg();

	gtog(x, scratch2);
	itog(1, x);
	len = bitlen(n);
	pos = 0;
	while (1)
	{
		if (bitval(n, pos++))
		{
			mulg(scratch2, x);
			modg(g, x);
		}
		if (pos >= len)
			break;
		squareg(scratch2);
		modg(g, scratch2);
	}
	pushg(1);
}