Beispiel #1
0
/*
 * needs workspace of (size*2) words
 */
static void mpprndbits(mpbarrett* p, size_t bits, size_t lsbset, const mpnumber* min, const mpnumber* max, randomGeneratorContext* rc, mpw* wksp)
{
	register size_t size = p->size;
	register size_t msbclr = MP_WORDS_TO_BITS(size) - bits;

	/* assume that mpbits(max) == bits */
	/* calculate k=max-min; generate q such that 0 <= q <= k; then set p = q + min */
	/* for the second step, set the appropriate number of bits */

	if (max)
	{
		mpsetx(size, wksp, max->size, max->data);
	} 
	else
	{
		mpfill(size, wksp, MP_ALLMASK);
		wksp[0] &= (MP_ALLMASK >> msbclr);
	}
	if (min)
	{
		mpsetx(size, wksp+size, min->size, min->data);
	}
	else
	{
		mpzero(size, wksp+size);
		wksp[size] |= (MP_MSBMASK >> msbclr);
	}

	mpsub(size, wksp, wksp+size);

	rc->rng->next(rc->param, (byte*) p->modl, MP_WORDS_TO_BYTES(size));

	p->modl[0] &= (MP_ALLMASK >> msbclr);

	while (mpgt(size, p->modl, wksp))
		mpsub(size, p->modl, wksp);

	mpadd(size, p->modl, wksp+size);

	if (lsbset)
		p->modl[size-1] |= (MP_ALLMASK >> (MP_WBITS - lsbset));
}
Beispiel #2
0
static int Zmpbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp)
{
	size_t ysize = b->size+1;
	size_t ubits, vbits;
	int k = 0;

	mpw* u = wksp;
	mpw* v = u+ysize;
	mpw* A = v+ysize;
	mpw* B = A+ysize;
	mpw* C = B+ysize;
	mpw* D = C+ysize;

	mpsetx(ysize, u, xsize, xdata);
	mpsetx(ysize, v, b->size, b->modl);
	mpsetw(ysize, A, 1);
	mpzero(ysize, B);
	mpzero(ysize, C);
	mpsetw(ysize, D, 1);

	for (k = 0; mpeven(ysize, u) && mpeven(ysize, v); k++) {
		mpdivtwo(ysize, u);
		mpdivtwo(ysize, v);
	}

	if (mpeven(ysize, u))
		(void) mpadd(ysize, u, v);

if (_debug < 0)
fprintf(stderr, "       u: "), mpfprintln(stderr, ysize, u);
if (_debug < 0)
fprintf(stderr, "       v: "), mpfprintln(stderr, ysize, v);
if (_debug < 0)
fprintf(stderr, "       A: "), mpfprintln(stderr, ysize, A);
if (_debug < 0)
fprintf(stderr, "       B: "), mpfprintln(stderr, ysize, B);
if (_debug < 0)
fprintf(stderr, "       C: "), mpfprintln(stderr, ysize, C);
if (_debug < 0)
fprintf(stderr, "       D: "), mpfprintln(stderr, ysize, D);

	ubits = vbits = MP_WORDS_TO_BITS(ysize);

	do {
		while (mpeven(ysize, v)) {
			mpsdivtwo(ysize, v);
			vbits -= 1;
			if (mpodd(ysize, C)) {
				(void) mpaddx(ysize, C, b->size, b->modl);
				(void) mpsubx(ysize, D, xsize, xdata);
			}
			mpsdivtwo(ysize, C);
			mpsdivtwo(ysize, D);
if (_debug < 0)
fprintf(stderr, "-->>   v: "), mpfprintln(stderr, ysize, v);
		}

		if (ubits >= vbits) {
			mpw* swapu;
			size_t  swapi;

if (_debug < 0)
fprintf(stderr, "--> (swap u <-> v)\n");
			swapu = u;	u = v;		v = swapu;
			swapi = ubits;	ubits = vbits;	vbits = swapi;
			swapu = A;	A = C;		C = swapu;
			swapu = B;	B = D;		D = swapu;
		}

		if (!((u[ysize-1] + v[ysize-1]) & 0x3)) {
if (_debug < 0)
fprintf(stderr, "--> (even parity)\n");
			mpadd(ysize, v, u);
			mpadd(ysize, C, A);
			mpadd(ysize, D, B);
		} else {
if (_debug < 0)
fprintf(stderr, "--> (odd parity)\n");
			mpsub(ysize, v, u);
			mpsub(ysize, C, A);
			mpsub(ysize, D, B);
		}
if (_debug < 0)
fprintf(stderr, "       v: "), mpfprintln(stderr, ysize, v);
if (_debug < 0)
fprintf(stderr, "       C: "), mpfprintln(stderr, ysize, C);
if (_debug < 0)
fprintf(stderr, "       D: "), mpfprintln(stderr, ysize, D);
		vbits++;
	} while (mpnz(ysize, v));

#ifdef	NOTYET
	if (!mpisone(ysize, u))
		return 0;
#endif

	if (result) {
		mpsetx(b->size, result, ysize, A);
		/*@-usedef@*/
		if (*A & 0x80000000)
			(void) mpneg(b->size, result);
		/*@=usedef@*/
		while (--k > 0)
			mpadd(b->size, result, result);
	}

fprintf(stderr, "=== EXIT: "), mpfprintln(stderr, b->size, result);
fprintf(stderr, "       u: "), mpfprintln(stderr, ysize, u);
fprintf(stderr, "       v: "), mpfprintln(stderr, ysize, v);
fprintf(stderr, "       A: "), mpfprintln(stderr, ysize, A);
fprintf(stderr, "       B: "), mpfprintln(stderr, ysize, B);
fprintf(stderr, "       C: "), mpfprintln(stderr, ysize, C);
fprintf(stderr, "       D: "), mpfprintln(stderr, ysize, D);

	return 1;
}