Exemplo n.º 1
0
RSApriv*
rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q)
{
	mpint *c2, *kq, *kp, *x;
	RSApriv *rsa;

	// make sure we're not being hoodwinked
	if(!probably_prime(p, 10) || !probably_prime(q, 10)){
		werrstr("rsafill: p or q not prime");
		return nil;
	}
	x = mpnew(0);
	mpmul(p, q, x);
	if(mpcmp(n, x) != 0){
		werrstr("rsafill: n != p*q");
		mpfree(x);
		return nil;
	}
	c2 = mpnew(0);
	mpsub(p, mpone, c2);
	mpsub(q, mpone, x);
	mpmul(c2, x, x);
	mpmul(e, d, c2);
	mpmod(c2, x, x);
	if(mpcmp(x, mpone) != 0){
		werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)");
		mpfree(x);
		mpfree(c2);
		return nil;
	}

	// compute chinese remainder coefficient
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, x);
	mpmod(d, x, kp);
	mpsub(q, mpone, x);
	mpmod(d, x, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = mpcopy(e);
	rsa->pub.n = mpcopy(n);
	rsa->dk = mpcopy(d);
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = mpcopy(p);
	rsa->q = mpcopy(q);
	rsa->c2 = c2;

	mpfree(x);

	return rsa;
}
Exemplo n.º 2
0
ECpoint*
strtoec(ECdomain *dom, char *s, char **rptr, ECpoint *ret)
{
	int allocd, o;
	mpint *r;

	allocd = 0;
	if(ret == nil){
		allocd = 1;
		ret = mallocz(sizeof(*ret), 1);
		if(ret == nil)
			return nil;
		ret->x = mpnew(0);
		ret->y = mpnew(0);
	}
	o = 0;
	switch(octet(&s)){
	case 0:
		ret->inf = 1;
		return ret;
	case 3:
		o = 1;
	case 2:
		if(halfpt(dom, s, &s, ret->x) == nil)
			goto err;
		r = mpnew(0);
		mpmul(ret->x, ret->x, r);
		mpadd(r, dom->a, r);
		mpmul(r, ret->x, r);
		mpadd(r, dom->b, r);
		if(!mpsqrt(r, dom->p, r)){
			mpfree(r);
			goto err;
		}
		if((r->p[0] & 1) != o)
			mpsub(dom->p, r, r);
		mpassign(r, ret->y);
		mpfree(r);
		if(!ecverify(dom, ret))
			goto err;
		return ret;
	case 4:
		if(halfpt(dom, s, &s, ret->x) == nil)
			goto err;
		if(halfpt(dom, s, &s, ret->y) == nil)
			goto err;
		if(!ecverify(dom, ret))
			goto err;
		return ret;
	}
err:
	if(rptr)
		*rptr = s;
	if(allocd){
		mpfree(ret->x);
		mpfree(ret->y);
		free(ret);
	}
	return nil;
}
Exemplo n.º 3
0
void NR::mpdiv(Vec_O_UCHR &q, Vec_O_UCHR &r, Vec_I_UCHR &u, Vec_I_UCHR &v)
{
	const int MACC=1;
	int i,is,mm;

	int n=u.size();
	int m=v.size();
	int p=r.size();
	int n_min=MIN(m,p);
	if (m > n) nrerror("Divisor longer than dividend in mpdiv");
	mm=m+MACC;
	Vec_UCHR s(mm),rr(mm),ss(mm+1),qq(n-m+1),t(n);
	mpinv(s,v);
	mpmul(rr,s,u);
	mpsad(ss,rr,1);
	mplsh(ss);
	mplsh(ss);
	mpmov(qq,ss);
	mpmov(q,qq);
	mpmul(t,qq,v);
	mplsh(t);
	mpsub(is,t,u,t);
	if (is != 0) nrerror("MACC too small in mpdiv");
	for (i=0;i<n_min;i++) r[i]=t[i+n-m];
	if (p>m)
		for (i=m;i<p;i++) r[i]=0;
}
Exemplo n.º 4
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));
}
Exemplo n.º 5
0
DSApriv*
dsagen(DSApub *opub)
{
	DSApub *pub;
	DSApriv *priv;
	mpint *exp;
	mpint *g;
	mpint *r;
	int bits;

	priv = dsaprivalloc();
	pub = &priv->pub;

	if(opub != nil){
		pub->p = mpcopy(opub->p);
		pub->q = mpcopy(opub->q);
	} else {
		pub->p = mpnew(0);
		pub->q = mpnew(0);
		DSAprimes(pub->q, pub->p, nil);
	}
	bits = Dbits*pub->p->top;

	pub->alpha = mpnew(0);
	pub->key = mpnew(0);
	priv->secret = mpnew(0);

	// find a generator alpha of the multiplicative
	// group Z*p, i.e., of order n = p-1.  We use the
	// fact that q divides p-1 to reduce the exponent.
	exp = mpnew(0);
	g = mpnew(0);
	r = mpnew(0);
	mpsub(pub->p, mpone, exp);
	mpdiv(exp, pub->q, exp, r);
	if(mpcmp(r, mpzero) != 0)
		sysfatal("dsagen foul up");
	while(1){
		mprand(bits, genrandom, g);
		mpmod(g, pub->p, g);
		mpexp(g, exp, pub->p, pub->alpha);
		if(mpcmp(pub->alpha, mpone) != 0)
			break;
	}
	mpfree(g);
	mpfree(exp);

	// create the secret key
	mprand(bits, genrandom, priv->secret);
	mpmod(priv->secret, pub->p, priv->secret);
	mpexp(pub->alpha, priv->secret, pub->p, pub->key);

	return priv;
}
Exemplo n.º 6
0
DSAsig*
dsasign(DSApriv *priv, mpint *m)
{
	DSApub *pub = &priv->pub;
	DSAsig *sig;
	mpint *qm1, *k, *kinv, *r, *s;
	mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
	int qlen = mpsignif(q);

	qm1 = mpnew(0);
	kinv = mpnew(0);
	r = mpnew(0);
	s = mpnew(0);
	k = mpnew(0);
	mpsub(pub->q, mpone, qm1);

	// find a k that has an inverse mod q
	while(1){
		mprand(qlen, genrandom, k);
		if((mpcmp(mpone, k) > 0) || (mpcmp(k, qm1) >= 0))
			continue;
		mpextendedgcd(k, q, r, kinv, s);
		if(mpcmp(r, mpone) != 0)
			continue;
		break;
	}

  	// make kinv positive
	mpmod(kinv, qm1, kinv);

	// r = ((alpha**k) mod p) mod q
	mpexp(alpha, k, p, r);
	mpmod(r, q, r);

	// s = (kinv*(m + ar)) mod q
	mpmul(r, priv->secret, s);
	mpadd(s, m, s);
	mpmul(s, kinv, s);
	mpmod(s, q, s);

	sig = dsasigalloc();
	sig->r = r;
	sig->s = s;
	mpfree(qm1);
	mpfree(k);
	mpfree(kinv);
	return sig;
}
Exemplo n.º 7
0
/*
 * mpbmod_w
 *  computes the barrett modular reduction of a number x, which has twice the size of b
 *  needs workspace of (2*size+2) words
 */
void mpbmod_w(const mpbarrett* b, const mpw* data, mpw* result, mpw* wksp)
{
	register mpw rc;
	register size_t sp = 2;
	register const mpw* src = data+b->size+1;
	register       mpw* dst = wksp+b->size+1;

	rc = mpsetmul(sp, dst, b->mu, *(--src));
	*(--dst) = rc;

	while (sp <= b->size)
	{
		sp++;
		if ((rc = *(--src)))
		{
			rc = mpaddmul(sp, dst, b->mu, rc);
			*(--dst) = rc;
		}
		else
			*(--dst) = 0;
	}
	if ((rc = *(--src)))
	{
		rc = mpaddmul(sp, dst, b->mu, rc);
		*(--dst) = rc;
	}
	else
		*(--dst) = 0;

	sp = b->size;
	rc = 0;

	dst = wksp+b->size+1;
	src = dst;

	*dst = mpsetmul(sp, dst+1, b->modl, *(--src));

	while (sp > 0)
		mpaddmul(sp--, dst, b->modl+(rc++), *(--src));

	mpsetx(b->size+1, wksp, b->size*2, data);
	mpsub(b->size+1, wksp, wksp+b->size+1);

	while (mpgex(b->size+1, wksp, b->size, b->modl))
		mpsubx(b->size+1, wksp, b->size, b->modl);

	mpcopy(b->size, result, wksp+1);
}
Exemplo n.º 8
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.º 9
0
/* garners algorithm for converting residue form to linear */
void
crtout(CRTpre *crt, CRTres *res, mpint *x)
{
	mpint *u;
	int i;

	u = mpnew(0);
	mpassign(res->r[0], x);

	for(i = 1; i < crt->n; i++){
		mpsub(res->r[i], x, u);
		mpmul(u, crt->c[i], u);
		mpmod(u, crt->m[i], u);
		mpmul(u, crt->p[i-1], u);
		mpadd(x, u, x);
	}

	mpfree(u);
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
0
/*
 * mpbtwopowmod_w
 *  needs workspace of (4*size+2) words
 */
void mpbtwopowmod_w(const mpbarrett* b, size_t psize, const mpw* pdata, mpw* result, mpw* wksp)
{
	/*
	 * Modular exponention, 2^p mod modulus, special optimization
	 *
	 * Uses left-to-right exponentiation; needs no extra storage
	 *
	 */

	/* this routine calls mpbmod, which needs (size*2+2), this routine needs (size*2) for sdata */

	register size_t size = b->size;
	register mpw temp = 0;

	mpsetw(size, result, 1);

	while (psize)
	{
		if ((temp = *(pdata++))) /* break when first non-zero word found */
			break;
		psize--;
	}

	/* if temp is still zero, then we're trying to raise x to power zero, and result stays one */
	if (temp)
	{
		register int count = MP_WBITS;

		/* first skip bits until we reach a one */
		while (count)
		{
			if (temp & MP_MSBMASK)
				break;
			temp <<= 1;
			count--;
		}

		while (psize--)
		{
			while (count)
			{
				/* always square */
				mpbsqrmod_w(b, size, result, result, wksp);
				
				/* multiply by two if bit is 1 */
				if (temp & MP_MSBMASK)
				{
					if (mpadd(size, result, result) || mpge(size, result, b->modl))
					{
						/* there was carry, or the result is greater than the modulus, so we need to adjust */
						mpsub(size, result, b->modl);
					}
				}

				temp <<= 1;
				count--;
			}
			count = MP_WBITS;
			temp = *(pdata++);
		}
	}
}
Exemplo n.º 12
0
void
mpeuclid(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y)
{
	mpint *tmp, *x0, *x1, *x2, *y0, *y1, *y2, *q, *r;

	if(a->sign<0 || b->sign<0)
		sysfatal("mpeuclid: negative arg");

	if(mpcmp(a, b) < 0){
		tmp = a;
		a = b;
		b = tmp;
		tmp = x;
		x = y;
		y = tmp;
	}

	if(b->top == 0){
		mpassign(a, d);
		mpassign(mpone, x);
		mpassign(mpzero, y);
		return;
	}

	a = mpcopy(a);
	b = mpcopy(b);
	x0 = mpnew(0);
	x1 = mpcopy(mpzero);
	x2 = mpcopy(mpone);
	y0 = mpnew(0);
	y1 = mpcopy(mpone);
	y2 = mpcopy(mpzero);
	q = mpnew(0);
	r = mpnew(0);

	while(b->top != 0 && b->sign > 0){
		// q = a/b
		// r = a mod b
		mpdiv(a, b, q, r);
		// x0 = x2 - qx1
		mpmul(q, x1, x0);
		mpsub(x2, x0, x0);
		// y0 = y2 - qy1
		mpmul(q, y1, y0);
		mpsub(y2, y0, y0);
		// rotate values
		tmp = a;
		a = b;
		b = r;
		r = tmp;
		tmp = x2;
		x2 = x1;
		x1 = x0;
		x0 = tmp;
		tmp = y2;
		y2 = y1;
		y1 = y0;
		y0 = tmp;
	}

	mpassign(a, d);
	mpassign(x2, x);
	mpassign(y2, y);

	mpfree(x0);
	mpfree(x1);
	mpfree(x2);
	mpfree(y0);
	mpfree(y1);
	mpfree(y2);
	mpfree(q);
	mpfree(r);
	mpfree(a);
	mpfree(b);
}
Exemplo n.º 13
0
static int
mpsqrt(mpint *n, mpint *p, mpint *r)
{
	mpint *a, *t, *s, *xp, *xq, *yp, *yq, *zp, *zq, *N;

	if(mpleg(n, p) == -1)
		return 0;
	a = mpnew(0);
	t = mpnew(0);
	s = mpnew(0);
	N = mpnew(0);
	xp = mpnew(0);
	xq = mpnew(0);
	yp = mpnew(0);
	yq = mpnew(0);
	zp = mpnew(0);
	zq = mpnew(0);
	for(;;){
		for(;;){
			mprand(mpsignif(p), genrandom, a);
			if(mpcmp(a, mpzero) > 0 && mpcmp(a, p) < 0)
				break;
		}
		mpmul(a, a, t);
		mpsub(t, n, t);
		mpmod(t, p, t);
		if(mpleg(t, p) == -1)
			break;
	}
	mpadd(p, mpone, N);
	mpright(N, 1, N);
	mpmul(a, a, t);
	mpsub(t, n, t);
	mpassign(a, xp);
	uitomp(1, xq);
	uitomp(1, yp);
	uitomp(0, yq);
	while(mpcmp(N, mpzero) != 0){
		if(N->p[0] & 1){
			mpmul(xp, yp, zp);
			mpmul(xq, yq, zq);
			mpmul(zq, t, zq);
			mpadd(zp, zq, zp);
			mpmod(zp, p, zp);
			mpmul(xp, yq, zq);
			mpmul(xq, yp, s);
			mpadd(zq, s, zq);
			mpmod(zq, p, yq);
			mpassign(zp, yp);
		}
		mpmul(xp, xp, zp);
		mpmul(xq, xq, zq);
		mpmul(zq, t, zq);
		mpadd(zp, zq, zp);
		mpmod(zp, p, zp);
		mpmul(xp, xq, zq);
		mpadd(zq, zq, zq);
		mpmod(zq, p, xq);
		mpassign(zp, xp);
		mpright(N, 1, N);
	}
	if(mpcmp(yq, mpzero) != 0)
		abort();
	mpassign(yp, r);
	mpfree(a);
	mpfree(t);
	mpfree(s);
	mpfree(N);
	mpfree(xp);
	mpfree(xq);
	mpfree(yp);
	mpfree(yq);
	mpfree(zp);
	mpfree(zq);
	return 1;
}
Exemplo n.º 14
0
void
ecadd(ECdomain *dom, ECpoint *a, ECpoint *b, ECpoint *s)
{
	mpint *l, *k, *sx, *sy;

	if(a->inf && b->inf){
		s->inf = 1;
		return;
	}
	if(a->inf){
		ecassign(dom, b, s);
		return;
	}
	if(b->inf){
		ecassign(dom, a, s);
		return;
	}
	if(mpcmp(a->x, b->x) == 0 && (mpcmp(a->y, mpzero) == 0 || mpcmp(a->y, b->y) != 0)){
		s->inf = 1;
		return;
	}
	l = mpnew(0);
	k = mpnew(0);
	sx = mpnew(0);
	sy = mpnew(0);
	if(mpcmp(a->x, b->x) == 0 && mpcmp(a->y, b->y) == 0){
		mpadd(mpone, mptwo, k);
		mpmul(a->x, a->x, l);
		mpmul(l, k, l);
		mpadd(l, dom->a, l);
		mpleft(a->y, 1, k);
		mpmod(k, dom->p, k);
		mpinvert(k, dom->p, k);
		mpmul(k, l, l);
		mpmod(l, dom->p, l);

		mpleft(a->x, 1, k);
		mpmul(l, l, sx);
		mpsub(sx, k, sx);
		mpmod(sx, dom->p, sx);

		mpsub(a->x, sx, sy);
		mpmul(l, sy, sy);
		mpsub(sy, a->y, sy);
		mpmod(sy, dom->p, sy);
		mpassign(sx, s->x);
		mpassign(sy, s->y);
		mpfree(sx);
		mpfree(sy);
		mpfree(l);
		mpfree(k);
		return;
	}
	mpsub(b->y, a->y, l);
	mpmod(l, dom->p, l);
	mpsub(b->x, a->x, k);
	mpmod(k, dom->p, k);
	mpinvert(k, dom->p, k);
	mpmul(k, l, l);
	mpmod(l, dom->p, l);
	
	mpmul(l, l, sx);
	mpsub(sx, a->x, sx);
	mpsub(sx, b->x, sx);
	mpmod(sx, dom->p, sx);
	
	mpsub(a->x, sx, sy);
	mpmul(sy, l, sy);
	mpsub(sy, a->y, sy);
	mpmod(sy, dom->p, sy);
	
	mpassign(sx, s->x);
	mpassign(sy, s->y);
	mpfree(sx);
	mpfree(sy);
	mpfree(l);
	mpfree(k);
}
Exemplo n.º 15
0
// extended binary gcd
//
// For a anv b it solves, v = gcd(a,b) and finds x and y s.t.
// ax + by = v
//
// Handbook of Applied Cryptography, Menezes et al, 1997, pg 608.  
void
mpextendedgcd(mpint *a, mpint *b, mpint *v, mpint *x, mpint *y)
{
	mpint *u, *A, *B, *C, *D;
	int g;

	if(a->top == 0){
		mpassign(b, v);
		mpassign(mpone, y);
		mpassign(mpzero, x);
		return;
	}
	if(b->top == 0){
		mpassign(a, v);
		mpassign(mpone, x);
		mpassign(mpzero, y);
		return;
	}

	g = 0;
	a = mpcopy(a);
	b = mpcopy(b);

	while(iseven(a) && iseven(b)){
		mpright(a, 1, a);
		mpright(b, 1, b);
		g++;
	}

	u = mpcopy(a);
	mpassign(b, v);
	A = mpcopy(mpone);
	B = mpcopy(mpzero);
	C = mpcopy(mpzero);
	D = mpcopy(mpone);

	for(;;) {
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		while(iseven(u)){
			mpright(u, 1, u);
			if(!iseven(A) || !iseven(B)) {
				mpadd(A, b, A);
				mpsub(B, a, B);
			}
			mpright(A, 1, A);
			mpright(B, 1, B);
		}
	
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		while(iseven(v)){
			mpright(v, 1, v);
			if(!iseven(C) || !iseven(D)) {
				mpadd(C, b, C);
				mpsub(D, a, D);
			}
			mpright(C, 1, C);
			mpright(D, 1, D);
		}
	
//		print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
		if(mpcmp(u, v) >= 0){
			mpsub(u, v, u);
			mpsub(A, C, A);
			mpsub(B, D, B);
		} else {
			mpsub(v, u, v);
			mpsub(C, A, C);
			mpsub(D, B, D);
		}

		if(u->top == 0)
			break;

	}
	mpassign(C, x);
	mpassign(D, y);
	mpleft(v, g, v);

	mpfree(A);
	mpfree(B);
	mpfree(C);
	mpfree(D);
	mpfree(u);
	mpfree(a);
	mpfree(b);
}
Exemplo n.º 16
0
RSApriv*
rsagen(int nlen, int elen, int rounds)
{
	mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
	RSApriv *rsa;

	p = mpnew(nlen/2);
	q = mpnew(nlen/2);
	n = mpnew(nlen);
	e = mpnew(elen);
	d = mpnew(0);
	phi = mpnew(nlen);

	// create the prime factors and euclid's function
	genprime(p, nlen/2, rounds);
	genprime(q, nlen - mpsignif(p) + 1, rounds);
	mpmul(p, q, n);
	mpsub(p, mpone, e);
	mpsub(q, mpone, d);
	mpmul(e, d, phi);

	// find an e relatively prime to phi
	t1 = mpnew(0);
	t2 = mpnew(0);
	mprand(elen, genrandom, e);
	if(mpcmp(e,mptwo) <= 0)
		itomp(3, e);
	// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
	// of the merits of various choices of primes and exponents.  e=3 is a
	// common and recommended exponent, but doesn't necessarily work here
	// because we chose strong rather than safe primes.
	for(;;){
		mpextendedgcd(e, phi, t1, d, t2);
		if(mpcmp(t1, mpone) == 0)
			break;
		mpadd(mpone, e, e);
	}
	mpfree(t1);
	mpfree(t2);

	// compute chinese remainder coefficient
	c2 = mpnew(0);
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, phi);
	mpmod(d, phi, kp);
	mpsub(q, mpone, phi);
	mpmod(d, phi, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = e;
	rsa->pub.n = n;
	rsa->dk = d;
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = p;
	rsa->q = q;
	rsa->c2 = c2;

	mpfree(phi);

	return rsa;
}
Exemplo n.º 17
0
Arquivo: tinv.c Projeto: avokhmin/RPM5
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;
}
Exemplo n.º 18
0
Arquivo: tinv.c Projeto: avokhmin/RPM5
/**
 *  Computes the inverse (modulo b) of x, and returns 1 if x was invertible.
 *  needs workspace of (6*size+6) words
 *  @note xdata and result cannot point to the same area
 */
static int Xmpbinv_w(const mpbarrett* b, size_t xsize, const mpw* xdata, mpw* result, mpw* wksp)
{
	/*
	 * Fact: if a element of Zn, then a is invertible if and only if gcd(a,n) = 1
	 * Hence: if b->modl is even, then x must be odd, otherwise the gcd(x,n) >= 2
	 *
	 * The calling routine must guarantee this condition.
	 */

	size_t ysize = b->size+1;

	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, b->size, b->modl);
	mpsetx(ysize, v, xsize, xdata);
	mpsetw(ysize, A, 1);
	mpzero(ysize, B);
	mpzero(ysize, C);
	mpsetw(ysize, D, 1);

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);

	do {
		while (mpeven(ysize, u))
		{
			mpdivtwo(ysize, u);

			if (mpodd(ysize, A) || mpodd(ysize, B))
			{
				(void) mpaddx(ysize, A, xsize, xdata);
				(void) mpsubx(ysize, B, b->size, b->modl);
			}

			mpsdivtwo(ysize, A);
			mpsdivtwo(ysize, B);
		}
		while (mpeven(ysize, v))
		{
			mpdivtwo(ysize, v);

			if (mpodd(ysize, C) || mpodd(ysize, D))
			{
				(void) mpaddx(ysize, C, xsize, xdata);
				(void) mpsubx(ysize, D, b->size, b->modl);
			}

			mpsdivtwo(ysize, C);
			mpsdivtwo(ysize, D);
		}
		if (mpge(ysize, u, v))
		{
if (_debug < 0)
fprintf(stderr, "--> 5 (u >= v)\n");
			(void) mpsub(ysize, u, v);
			(void) mpsub(ysize, A, C);
			(void) mpsub(ysize, B, D);
if (_debug < 0)
fprintf(stderr, "       u: "), mpfprintln(stderr, ysize, u);
if (_debug < 0)
fprintf(stderr, "       A: "), mpfprintln(stderr, ysize, A);
if (_debug < 0)
fprintf(stderr, "       B: "), mpfprintln(stderr, ysize, B);
		}
		else
		{
if (_debug < 0)
fprintf(stderr, "--> 5 (u < v)\n");
			(void) mpsub(ysize, v, u);
			(void) mpsub(ysize, C, A);
			(void) 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);
		}

	} while (mpnz(ysize, u));

	if (!mpisone(ysize, v))
		return 0;

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

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;
}
Exemplo n.º 19
0
// Miller-Rabin probabilistic primality testing
//	Knuth (1981) Seminumerical Algorithms, p.379
//	Menezes et al () Handbook, p.39
// 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
int
probably_prime(mpint *n, int nrep)
{
	int j, k, rep, nbits, isprime = 1;
	mpint *nm1, *q, *x, *y, *r;

	if(n->sign < 0)
		sysfatal("negative prime candidate");

	if(nrep <= 0)
		nrep = 18;

	k = mptoi(n);
	if(k == 2)		// 2 is prime
		return 1;
	if(k < 2)		// 1 is not prime
		return 0;
	if((n->p[0] & 1) == 0)	// even is not prime
		return 0;

	// test against small prime numbers
	if(smallprimetest(n) < 0)
		return 0;

	// fermat test, 2^n mod n == 2 if p is prime
	x = uitomp(2, nil);
	y = mpnew(0);
	mpexp(x, n, n, y);
	k = mptoi(y);
	if(k != 2){
		mpfree(x);
		mpfree(y);
		return 0;
	}

	nbits = mpsignif(n);
	nm1 = mpnew(nbits);
	mpsub(n, mpone, nm1);	// nm1 = n - 1 */
	k = mplowbits0(nm1);
	q = mpnew(0);
	mpright(nm1, k, q);	// q = (n-1)/2**k

	for(rep = 0; rep < nrep; rep++){
		
		// x = random in [2, n-2]
		r = mprand(nbits, prng, nil);
		mpmod(r, nm1, x);
		mpfree(r);
		if(mpcmp(x, mpone) <= 0)
			continue;

		// y = x**q mod n
		mpexp(x, q, n, y);

		if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
			goto done;

		for(j = 1; j < k; j++){
			mpmul(y, y, x);
			mpmod(x, n, y);	// y = y*y mod n
			if(mpcmp(y, nm1) == 0)
				goto done;
			if(mpcmp(y, mpone) == 0){
				isprime = 0;
				goto done;
			}
		}
		isprime = 0;
	}
done:
	mpfree(y);
	mpfree(x);
	mpfree(q);
	mpfree(nm1);
	return isprime;
}
Exemplo n.º 20
0
/*
 * Miller-Rabin probabilistic primality testing
 *	Knuth (1981) Seminumerical Algorithms, p.379
 *	Menezes et al () Handbook, p.39
 * 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
 */
int
probably_prime(mpint *n, int nrep)
{
	int j, k, rep, nbits, isprime;
	mpint *nm1, *q, *x, *y, *r;

	if(n->sign < 0)
		sysfatal("negative prime candidate");

	if(nrep <= 0)
		nrep = 18;

	k = mptoi(n);
	if(k == 2)		/* 2 is prime */
		return 1;
	if(k < 2)		/* 1 is not prime */
		return 0;
	if((n->p[0] & 1) == 0)	/* even is not prime */
		return 0;

	/* test against small prime numbers */
	if(smallprimetest(n) < 0)
		return 0;

	/* fermat test, 2^n mod n == 2 if p is prime */
	x = uitomp(2, nil);
	y = mpnew(0);
	mpexp(x, n, n, y);
	k = mptoi(y);
	if(k != 2){
		mpfree(x);
		mpfree(y);
		return 0;
	}

	nbits = mpsignif(n);
	nm1 = mpnew(nbits);
	mpsub(n, mpone, nm1);	/* nm1 = n - 1 */
	k = mplowbits0(nm1);
	q = mpnew(0);
	mpright(nm1, k, q);	/* q = (n-1)/2**k */

	for(rep = 0; rep < nrep; rep++){
		for(;;){
			/* find x = random in [2, n-2] */
		 	r = mprand(nbits, prng, nil);
		 	mpmod(r, nm1, x);
		 	mpfree(r);
		 	if(mpcmp(x, mpone) > 0)
		 		break;
		}

		/* y = x**q mod n */
		mpexp(x, q, n, y);

		if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
		 	continue;

		for(j = 1;; j++){
		 	if(j >= k) {
		 		isprime = 0;
		 		goto done;
		 	}
		 	mpmul(y, y, x);
		 	mpmod(x, n, y);	/* y = y*y mod n */
		 	if(mpcmp(y, nm1) == 0)
		 		break;
		 	if(mpcmp(y, mpone) == 0){
		 		isprime = 0;
		 		goto done;
		 	}
		}
	}
	isprime = 1;
done:
	mpfree(y);
	mpfree(x);
	mpfree(q);
	mpfree(nm1);
	return isprime;
}