Exemplo n.º 1
0
/*
 * mpbsubone
 *  copies (b-1) into result
 */
void mpbsubone(const mpbarrett* b, mpw* result)
{
	register size_t size = b->size;

	mpcopy(size, result, b->modl);
	mpsubw(size, result, 1);
}
Exemplo n.º 2
0
/*
 * needs workspace of (8*size+2) words
 */
int mppmilrab_w(const mpbarrett* p, randomGeneratorContext* rc, int t, mpw* wksp)
{
	/*
	 * Miller-Rabin probabilistic primality test, with modification
	 *
	 * For more information, see:
	 * "Handbook of Applied Cryptography"
	 *  Chapter 4.24
	 *
	 * Modification to the standard algorithm:
	 *  The first value of a is not obtained randomly, but set to two
	 */

	/* this routine uses (size*3) storage, and calls mpbpowmod, which needs (size*4+2) */
	/* (size) for a, (size) for r, (size) for n-1 */

	register size_t  size  = p->size;
	register mpw* ndata = wksp;
	register mpw* rdata = ndata+size;
	register mpw* adata = rdata+size;

	int s;

	mpcopy(size, ndata, p->modl);
	mpsubw(size, ndata, 1);
	mpcopy(size, rdata, ndata);

	s = mprshiftlsz(size, rdata); /* we've split p-1 into (2^s)*r */

	/* should do an assert that s != 0 */

	/* do at least one test, with a = 2 */
	if (t == 0)
		t++;

	if (!mppmilrabtwo_w(p, s, rdata, ndata, wksp+3*size))
		return 0;

	while (t-- > 0)
	{
		/* generate a random 'a' into b->data */
		mpbrnd_w(p, rc, adata, wksp);

		if (!mppmilraba_w(p, adata, s, rdata, ndata, wksp+3*size))
			return 0;
	}

    return 1;
}
Exemplo n.º 3
0
/*
 * mpbrnd_w
 *  generates a random number in the range 1 < r < b-1
 *  need workspace of (size) words
 */
void mpbrnd_w(const mpbarrett* b, randomGeneratorContext* rc, mpw* result, mpw* wksp)
{
	size_t msz = mpmszcnt(b->size, b->modl);

	mpcopy(b->size, wksp, b->modl);
	mpsubw(b->size, wksp, 1);

	do
	{
		rc->rng->next(rc->param, (byte*) result, MP_WORDS_TO_BYTES(b->size));

		result[0] &= (MP_ALLMASK >> msz);

		while (mpge(b->size, result, wksp))
			mpsub(b->size, result, wksp);
	} while (mpleone(b->size, result));
}
Exemplo n.º 4
0
/*
 * needs workspace of (8*size+2) words
 */
void mpprndconone_w(mpbarrett* p, randomGeneratorContext* rc, size_t bits, int t, const mpbarrett* q, const mpnumber* f, mpnumber* r, int cofactor, mpw* wksp)
{
	/*
	 * Generate a prime p with n bits such that p mod q = 1, and p = qr+1 where r = 2s
	 *
	 * Conditions: q > 2 and size(q) < size(p) and size(f) <= size(p)
	 *
	 * Conditions: r must be chosen so that r is even, otherwise p will be even!
	 *
	 * if cofactor == 0, then s will be chosen randomly
	 * if cofactor == 1, then make sure that q does not divide r, i.e.:
	 *    q cannot be equal to r, since r is even, and q > 2; hence if q <= r make sure that GCD(q,r) == 1
	 * if cofactor == 2, then make sure that s is prime
	 * 
	 * Optional input f: if f is not null, then search p so that GCD(p-1,f) = 1
	 */

	mpbinit(p, MP_BITS_TO_WORDS(bits + MP_WBITS - 1));

	if (p->modl != (mpw*) 0)
	{
		size_t sbits = bits - mpbits(q->size, q->modl) - 1;
		mpbarrett s;

		mpbzero(&s);
		mpbinit(&s, MP_BITS_TO_WORDS(sbits + MP_WBITS - 1));

		while (1)
		{
			mpprndbits(&s, sbits, 0, (mpnumber*) 0, (mpnumber*) 0, rc, wksp);

			if (cofactor == 1)
			{
				mpsetlsb(s.size, s.modl);

				/* if (q <= s) check if GCD(q,s) != 1 */
				if (mplex(q->size, q->modl, s.size, s.modl))
				{
					/* we can find adequate storage for computing the gcd in s->wksp */
					mpsetx(s.size, wksp, q->size, q->modl);
					mpgcd_w(s.size, s.modl, wksp, wksp+s.size, wksp+2*s.size);

					if (!mpisone(s.size, wksp+s.size))
						continue;
				}
			}
			else if (cofactor == 2)
			{
				mpsetlsb(s.size, s.modl);
			}

			if (cofactor == 2)
			{
				/* do a small prime product trial division test on r */
				if (!mppsppdiv_w(&s, wksp))
					continue;
			}

			/* multiply q*s */
			mpmul(wksp, s.size, s.modl, q->size, q->modl);
			/* s.size + q.size may be greater than p.size by 1, but the product will fit exactly into p */
			mpsetx(p->size, p->modl, s.size+q->size, wksp);
			/* multiply by two and add 1 */
			mpmultwo(p->size, p->modl);
			mpaddw(p->size, p->modl, 1);
			/* test if the product actually contains enough bits */
			if (mpbits(p->size, p->modl) < bits)
				continue;

			/* do a small prime product trial division test on p */
			if (!mppsppdiv_w(p, wksp))
				continue;

			/* if we have an f, do the congruence test */
			if (f != (mpnumber*) 0)
			{
				mpcopy(p->size, wksp, p->modl);
				mpsubw(p->size, wksp, 1);
				mpsetx(p->size, wksp, f->size, f->data);
				mpgcd_w(p->size, wksp, wksp+p->size, wksp+2*p->size, wksp+3*p->size);
				if (!mpisone(p->size, wksp+2*p->size))
					continue;
			}

			/* if cofactor is two, test if s is prime */
			if (cofactor == 2)
			{
				mpbmu_w(&s, wksp);

				if (!mppmilrab_w(&s, rc, mpptrials(sbits), wksp))
					continue;
			}

			/* candidate has passed so far, now we do the probabilistic test on p */
			mpbmu_w(p, wksp);

			if (!mppmilrab_w(p, rc, t, wksp))
				continue;

			mpnset(r, s.size, s.modl);
			mpmultwo(r->size, r->data);
			mpbfree(&s);

			return;
		}
	}
}
Exemplo n.º 5
0
/*
 * implements IEEE P1363 A.15.6
 *
 * f, min, max are optional
 */
int mpprndr_w(mpbarrett* p, randomGeneratorContext* rc, size_t bits, int t, const mpnumber* min, const mpnumber* max, const mpnumber* f, mpw* wksp)
{
	/*
	 * Generate a prime into p with the requested number of bits
	 *
	 * Conditions: size(f) <= size(p)
	 *
	 * Optional input min: if min is not null, then search p so that min <= p
	 * Optional input max: if max is not null, then search p so that p <= max
	 * Optional input f: if f is not null, then search p so that GCD(p-1,f) = 1
	 */

	size_t size = MP_BITS_TO_WORDS(bits + MP_WBITS - 1);

	/* if min has more bits than what was requested for p, bail out */
	if (min && (mpbits(min->size, min->data) > bits))
		return -1;

	/* if max has a different number of bits than what was requested for p, bail out */
	if (max && (mpbits(max->size, max->data) != bits))
		return -1;

	/* if min is not less than max, bail out */
	if (min && max && mpgex(min->size, min->data, max->size, max->data))
		return -1;

	mpbinit(p, size);

	if (p->modl)
	{
		while (1)
		{
			/*
			 * Generate a random appropriate candidate prime, and test
			 * it with small prime divisor test BEFORE computing mu
			 */
			mpprndbits(p, bits, 1, min, max, rc, wksp);

			/* do a small prime product trial division test on p */
			if (!mppsppdiv_w(p, wksp))
				continue;

			/* if we have an f, do the congruence test */
			if (f != (mpnumber*) 0)
			{
				mpcopy(size, wksp, p->modl);
				mpsubw(size, wksp, 1);
				mpsetx(size, wksp+size, f->size, f->data);
				mpgcd_w(size, wksp, wksp+size, wksp+2*size, wksp+3*size);

				if (!mpisone(size, wksp+2*size))
					continue;
			}

			/* candidate has passed so far, now we do the probabilistic test */
			mpbmu_w(p, wksp);

			if (mppmilrab_w(p, rc, t, wksp))
				return 0;
		}
	}
	return -1;
}
Exemplo n.º 6
0
Arquivo: tinv.c Projeto: avokhmin/RPM5
static int Ympbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp)
{
	size_t  ysize = b->size+1;
 	int k;
	mpw* u1 = wksp;
	mpw* u2 = u1+ysize;
	mpw* u3 = u2+ysize;
	mpw* v1 = u3+ysize;
	mpw* v2 = v1+ysize;
	mpw* v3 = v2+ysize;
	mpw* t1 = v3+ysize;
	mpw* t2 = t1+ysize;
	mpw* t3 = t2+ysize;
	mpw* u  = t3+ysize;
	mpw* v  =  u+ysize;

	mpsetx(ysize, u, xsize, xdata);
	mpsetx(ysize, v, b->size, b->modl);

	/* Y1. Find power of 2. */
	for (k = 0; mpeven(ysize, u) && mpeven(ysize, v); k++) {
		mpdivtwo(ysize, u);
		mpdivtwo(ysize, v);
	}

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

	/* Y2. Initialize. */
	mpsetw(ysize, u1, 1);
if (_debug < 0)
fprintf(stderr, "      u1: "), mpfprintln(stderr, ysize, u1);
	mpzero(ysize, u2);
if (_debug < 0)
fprintf(stderr, "      u2: "), mpfprintln(stderr, ysize, u2);
	mpsetx(ysize, u3, ysize, u);
if (_debug < 0)
fprintf(stderr, "      u3: "), mpfprintln(stderr, ysize, u3);

	mpsetx(ysize, v1, ysize, v);
if (_debug < 0)
fprintf(stderr, "      v1: "), mpfprintln(stderr, ysize, v1);
	mpsetw(ysize, v2, 1);
	(void) mpsub(ysize, v2, u);
if (_debug < 0)
fprintf(stderr, "      v2: "), mpfprintln(stderr, ysize, v2);
	mpsetx(ysize, v3, ysize, v);
if (_debug < 0)
fprintf(stderr, "      v3: "), mpfprintln(stderr, ysize, v3);

	if (mpodd(ysize, u)) {
		mpzero(ysize, t1);
if (_debug < 0)
fprintf(stderr, "      t1: "), mpfprintln(stderr, ysize, t1);
		mpzero(ysize, t2);
		mpsubw(ysize, t2, 1);
if (_debug < 0)
fprintf(stderr, "      t2: "), mpfprintln(stderr, ysize, t2);
		mpzero(ysize, t3);
		mpsub(ysize, t3, v);
if (_debug < 0)
fprintf(stderr, "      t3: "), mpfprintln(stderr, ysize, t3);
		goto Y4;
	} else {
		mpsetw(ysize, t1, 1);
if (_debug < 0)
fprintf(stderr, "      t1: "), mpfprintln(stderr, ysize, t1);
		mpzero(ysize, t2);
if (_debug < 0)
fprintf(stderr, "      t2: "), mpfprintln(stderr, ysize, t2);
		mpsetx(ysize, t3, ysize, u);
if (_debug < 0)
fprintf(stderr, "      t3: "), mpfprintln(stderr, ysize, t3);
	}

	do {
	    do {
		if (mpodd(ysize, t1) || mpodd(ysize, t2)) {
			mpadd(ysize, t1, v);
			mpsub(ysize, t2, u);
		}
		mpsdivtwo(ysize, t1);
		mpsdivtwo(ysize, t2);
		mpsdivtwo(ysize, t3);
Y4:
if (_debug < 0)
fprintf(stderr, "   Y4 t3: "), mpfprintln(stderr, ysize, t3);
	    } while (mpeven(ysize, t3));

	    /* Y5. Reset max(u3,v3). */
	    if (!(*t3 & 0x80000000)) {
if (_debug < 0)
fprintf(stderr, "--> Y5 (t3 > 0)\n");
		mpsetx(ysize, u1, ysize, t1);
if (_debug < 0)
fprintf(stderr, "      u1: "), mpfprintln(stderr, ysize, u1);
		mpsetx(ysize, u2, ysize, t2);
if (_debug < 0)
fprintf(stderr, "      u2: "), mpfprintln(stderr, ysize, u2);
		mpsetx(ysize, u3, ysize, t3);
if (_debug < 0)
fprintf(stderr, "      u3: "), mpfprintln(stderr, ysize, u3);
	    } else {
if (_debug < 0)
fprintf(stderr, "--> Y5 (t3 <= 0)\n");
		mpsetx(ysize, v1, ysize, v);
		mpsub(ysize, v1, t1);
if (_debug < 0)
fprintf(stderr, "      v1: "), mpfprintln(stderr, ysize, v1);
		mpsetx(ysize, v2, ysize, u);
		mpneg(ysize, v2);
		mpsub(ysize, v2, t2);
if (_debug < 0)
fprintf(stderr, "      v2: "), mpfprintln(stderr, ysize, v2);
		mpzero(ysize, v3);
		mpsub(ysize, v3, t3);
if (_debug < 0)
fprintf(stderr, "      v3: "), mpfprintln(stderr, ysize, v3);
	    }

	    /* Y6. Subtract. */
	    mpsetx(ysize, t1, ysize, u1);
	    mpsub(ysize, t1, v1);
	    mpsetx(ysize, t2, ysize, u2);
	    mpsub(ysize, t2, v2);
	    mpsetx(ysize, t3, ysize, u3);
	    mpsub(ysize, t3, v3);

	    if (*t1 & 0x80000000) {
		mpadd(ysize, t1, v);
		mpsub(ysize, t2, u);
	    }

if (_debug < 0)
fprintf(stderr, "-->Y6 t1: "), mpfprintln(stderr, ysize, t1);
if (_debug < 0)
fprintf(stderr, "      t2: "), mpfprintln(stderr, ysize, t2);
if (_debug < 0)
fprintf(stderr, "      t3: "), mpfprintln(stderr, ysize, t3);

	} while (mpnz(ysize, t3));

	if (!(mpisone(ysize, u3) && mpisone(ysize, v3)))
		return 0;

	if (result) {
		while (--k > 0)
			mpadd(ysize, u1, u1);
		mpsetx(b->size, result, ysize, u1);
	}

fprintf(stderr, "=== EXIT: "), mpfprintln(stderr, b->size, result);
fprintf(stderr, "      u1: "), mpfprintln(stderr, ysize, u1);
fprintf(stderr, "      u2: "), mpfprintln(stderr, ysize, u2);
fprintf(stderr, "      u3: "), mpfprintln(stderr, ysize, u3);
fprintf(stderr, "      v1: "), mpfprintln(stderr, ysize, v1);
fprintf(stderr, "      v2: "), mpfprintln(stderr, ysize, v2);
fprintf(stderr, "      v3: "), mpfprintln(stderr, ysize, v3);
fprintf(stderr, "      t1: "), mpfprintln(stderr, ysize, t1);
fprintf(stderr, "      t2: "), mpfprintln(stderr, ysize, t2);
fprintf(stderr, "      t3: "), mpfprintln(stderr, ysize, t3);

	return 1;
}