Example #1
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;
}
Example #2
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;
}
Example #3
0
void
ecdsasign(ECdomain *dom, ECpriv *priv, uchar *dig, int len, mpint *r, mpint *s)
{
	ECpriv tmp;
	mpint *E, *t;

	tmp.x = mpnew(0);
	tmp.y = mpnew(0);
	tmp.d = mpnew(0);
	E = betomp(dig, len, nil);
	t = mpnew(0);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	for(;;){
		ecgen(dom, &tmp);
		mpmod(tmp.x, dom->n, r);
		if(mpcmp(r, mpzero) == 0)
			continue;
		mpmul(r, priv->d, s);
		mpadd(E, s, s);
		mpinvert(tmp.d, dom->n, t);
		mpmul(s, t, s);
		mpmod(s, dom->n, s);
		if(mpcmp(s, mpzero) != 0)
			break;
	}
	mpfree(t);
	mpfree(E);
	mpfree(tmp.x);
	mpfree(tmp.y);
	mpfree(tmp.d);
}
Example #4
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;
}
Example #5
0
void mpsqrt(unsigned char w[], unsigned char u[], unsigned char v[], int n,
	int m)
{
	void mplsh(unsigned char u[], int n);
	void mpmov(unsigned char u[], unsigned char v[], int n);
	void mpmul(unsigned char w[], unsigned char u[], unsigned char v[], int n,
		int m);
	void mpneg(unsigned char u[], int n);
	void mpsdv(unsigned char w[], unsigned char u[], int n, int iv, int *ir);
	int i,ir,j,mm;
	float fu,fv;
	unsigned char *r,*s;

	r=cvector(1,n<<1);
	s=cvector(1,n<<1);
	mm=IMIN(m,MF);
	fv=(float) v[mm];
	for (j=mm-1;j>=1;j--) {
		fv *= BI;
		fv += v[j];
	}
	fu=1.0/sqrt(fv);
	for (j=1;j<=n;j++) {
		i=(int) fu;
		u[j]=(unsigned char) i;
		fu=256.0*(fu-i);
	}
	for (;;) {
		mpmul(r,u,u,n,n);
		mplsh(r,n);
		mpmul(s,r,v,n,IMIN(m,n));
		mplsh(s,n);
		mpneg(s,n);
		s[1] -= 253;
		mpsdv(s,s,n,2,&ir);
		for (j=2;j<n;j++) {
			if (s[j]) {
				mpmul(r,s,u,n,n);
				mpmov(u,&r[1],n);
				break;
			}
		}
		if (j<n) continue;
		mpmul(r,u,v,n,IMIN(m,n));
		mpmov(w,&r[1],n);
		free_cvector(s,1,n<<1);
		free_cvector(r,1,n<<1);
		return;
	}
}
Example #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;
}
Example #7
0
int
egverify(EGpub *pub, EGsig *sig, mpint *m)
{
	mpint *p = pub->p, *alpha = pub->alpha;
	mpint *r = sig->r, *s = sig->s;
	mpint *v1, *v2, *rs;
	int rv = -1;

	if(mpcmp(r, mpone) < 0 || mpcmp(r, p) >= 0)
		return rv;
	v1 = mpnew(0);
	rs = mpnew(0);
	v2 = mpnew(0);
	mpexp(pub->key, r, p, v1);
	mpexp(r, s, p, rs);
	mpmul(v1, rs, v1);
	mpmod(v1, p, v1);
	mpexp(alpha, m, p, v2);
	if(mpcmp(v1, v2) == 0)
		rv = 0;
	mpfree(v1);
	mpfree(rs);
	mpfree(v2);
	return rv;
}
Example #8
0
void
testcrt(mpint **p)
{
	CRTpre *crt;
	CRTres *res;
	mpint *m, *x, *y;

	fmtinstall('B', mpfmt);

	// get a modulus and a test number
	m = mpnew(1024+160);
	mpmul(p[0], p[1], m);
	x = mpnew(1024+160);
	mpadd(m, mpone, x);

	// do the precomputation for crt conversion
	crt = crtpre(2, p);

	// convert x to residues
	res = crtin(crt, x);

	// convert back
	y = mpnew(1024+160);
	crtout(crt, res, y);
	print("x %B\ny %B\n", x, y);
	mpfree(m);
	mpfree(x);
	mpfree(y);
}
Example #9
0
// find a prime p of length n and a generator alpha of Z^*_p
// Alg 4.86 Menezes et al () Handbook, p.164
void
gensafeprime(mpint *p, mpint *alpha, int n, int accuracy)
{
	mpint *q, *b;

	q = mpnew(n-1);
	while(1){
		genprime(q, n-1, accuracy);
		mpleft(q, 1, p);
		mpadd(p, mpone, p); // p = 2*q+1
		if(probably_prime(p, accuracy))
			break;
	}
	// now find a generator alpha of the multiplicative
	// group Z*_p of order p-1=2q
	b = mpnew(0);
	while(1){
		mprand(n, genrandom, alpha);
		mpmod(alpha, p, alpha);
		mpmul(alpha, alpha, b);
		mpmod(b, p, b);
		if(mpcmp(b, mpone) == 0)
			continue;
		mpexp(alpha, q, p, b);
		if(mpcmp(b, mpone) != 0)
			break;
	}
	mpfree(b);
	mpfree(q);
}
Example #10
0
int
base58dec(char *src, uchar *dst, int len)
{
	mpint *n, *b, *r;
	char *t;
	int l;
	
	n = mpnew(0);
	r = mpnew(0);
	b = uitomp(58, nil);
	for(; *src; src++){
		t = strchr(code, *src);
		if(t == nil){
			mpfree(n);
			mpfree(r);
			mpfree(b);
			werrstr("invalid base58 char");
			return -1;
		}
		uitomp(t - code, r);
		mpmul(n, b, n);
		mpadd(n, r, n);
	}
	memset(dst, 0, len);
	l = (mpsignif(n) + 7) / 8;
	mptobe(n, dst + (len - l), l, nil);
	mpfree(n);
	mpfree(r);
	mpfree(b);
	return 0;
}
Example #11
0
static trace_data *
init_trace(trace_data *T, GEN S, nflift_t *L, GEN q)
{
  long e = gexpo(S), i,j, l,h;
  GEN qgood, S1, invd;

  if (e < 0) return NULL; /* S = 0 */

  qgood = int2n(e - 32); /* single precision check */
  if (cmpii(qgood, q) > 0) q = qgood;

  S1 = gdivround(S, q);
  if (gcmp0(S1)) return NULL;

  invd = ginv(itor(L->den, DEFAULTPREC));

  T->dPinvS = gmul(L->iprk, S);
  l = lg(S);
  h = lg(T->dPinvS[1]);
  T->PinvSdbl = (double**)cgetg(l, t_MAT);
  init_dalloc();
  for (j = 1; j < l; j++)
  {
    double *t = dalloc(h * sizeof(double));
    GEN c = gel(T->dPinvS,j);
    pari_sp av = avma;
    T->PinvSdbl[j] = t;
    for (i=1; i < h; i++) t[i] = rtodbl(mpmul(invd, gel(c,i)));
    avma = av;
  }

  T->d  = L->den;
  T->P1 = gdivround(L->prk, q);
  T->S1 = S1; return T;
}
Example #12
0
/* return a bound for T_2(P), P | polbase in C[X]
 * NB: Mignotte bound: A | S ==>
 *  |a_i| <= binom(d-1, i-1) || S ||_2 + binom(d-1, i) lc(S)
 *
 * Apply to sigma(S) for all embeddings sigma, then take the L_2 norm over
 * sigma, then take the sup over i.
 **/
static GEN
nf_Mignotte_bound(GEN nf, GEN polbase)
{
  GEN G = gmael(nf,5,2), lS = leading_term(polbase); /* t_INT */
  GEN p1, C, N2, matGS, binlS, bin;
  long prec, i, j, d = degpol(polbase), n = degpol(nf[1]), r1 = nf_get_r1(nf);

  binlS = bin = vecbinome(d-1);
  if (!gcmp1(lS)) binlS = gmul(lS, bin);

  N2 = cgetg(n+1, t_VEC);
  prec = gprecision(G);
  for (;;)
  {
    nffp_t F;

    matGS = cgetg(d+2, t_MAT);
    for (j=0; j<=d; j++) gel(matGS,j+1) = arch_for_T2(G, gel(polbase,j+2));
    matGS = shallowtrans(matGS);
    for (j=1; j <= r1; j++) /* N2[j] = || sigma_j(S) ||_2 */
    {
      gel(N2,j) = gsqrt( QuickNormL2(gel(matGS,j), DEFAULTPREC), DEFAULTPREC );
      if (lg(N2[j]) < DEFAULTPREC) goto PRECPB;
    }
    for (   ; j <= n; j+=2)
    {
      GEN q1 = QuickNormL2(gel(matGS,j  ), DEFAULTPREC);
      GEN q2 = QuickNormL2(gel(matGS,j+1), DEFAULTPREC);
      p1 = gmul2n(mpadd(q1, q2), -1);
      gel(N2,j) = gel(N2,j+1) = gsqrt( p1, DEFAULTPREC );
      if (lg(N2[j]) < DEFAULTPREC) goto PRECPB;
    }
    if (j > n) break; /* done */
PRECPB:
    prec = (prec<<1)-2;
    remake_GM(nf, &F, prec); G = F.G;
    if (DEBUGLEVEL>1) pari_warn(warnprec, "nf_factor_bound", prec);
  }

  /* Take sup over 0 <= i <= d of
   * sum_sigma | binom(d-1, i-1) ||sigma(S)||_2 + binom(d-1,i) lc(S) |^2 */

  /* i = 0: n lc(S)^2 */
  C = mulsi(n, sqri(lS));
  /* i = d: sum_sigma ||sigma(S)||_2^2 */
  p1 = gnorml2(N2); if (gcmp(C, p1) < 0) C = p1;
  for (i = 1; i < d; i++)
  {
    GEN s = gen_0;
    for (j = 1; j <= n; j++)
    {
      p1 = mpadd( mpmul(gel(bin,i), gel(N2,j)), gel(binlS,i+1) );
      s = mpadd(s, gsqr(p1));
    }
    if (gcmp(C, s) < 0) C = s;
  }
  return C;
}
Example #13
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);
}
Example #14
0
int
dsaverify(DSApub *pub, DSAsig *sig, mpint *m)
{
	int rv = -1;
	mpint *u1, *u2, *v, *sinv;

	if(sig->r->sign < 0 || mpcmp(sig->r, pub->q) >= 0)
		return rv;
	if(sig->s->sign < 0 || mpcmp(sig->s, pub->q) >= 0)
		return rv;
	u1 = mpnew(0);
	u2 = mpnew(0);
	v = mpnew(0);
	sinv = mpnew(0);

	// find (s**-1) mod q, make sure it exists
	mpextendedgcd(sig->s, pub->q, u1, sinv, v);
	if(mpcmp(u1, mpone) != 0)
		goto out;

	// u1 = (sinv * m) mod q, u2 = (r * sinv) mod q
	mpmul(sinv, m, u1);
	mpmod(u1, pub->q, u1);
	mpmul(sig->r, sinv, u2);
	mpmod(u2, pub->q, u2);

	// v = (((alpha**u1)*(key**u2)) mod p) mod q
	mpexp(pub->alpha, u1, pub->p, sinv);
	mpexp(pub->key, u2, pub->p, v);
	mpmul(sinv, v, v);
	mpmod(v, pub->p, v);
	mpmod(v, pub->q, v);

	if(mpcmp(v, sig->r) == 0)
		rv = 0;
out:
	mpfree(v);
	mpfree(u1);
	mpfree(u2);
	mpfree(sinv);
	return rv;
}
Example #15
0
void mpinv(unsigned char u[], unsigned char v[], int n, int m)
{
	void mpmov(unsigned char u[], unsigned char v[], int n);
	void mpmul(unsigned char w[], unsigned char u[], unsigned char v[], int n,
		int m);
	void mpneg(unsigned char u[], int n);
	unsigned char *rr,*s;
	int i,j,maxmn,mm;
	float fu,fv;

	maxmn=IMAX(n,m);
	rr=cvector(1,1+(maxmn<<1));
	s=cvector(1,maxmn);
	mm=IMIN(MF,m);
	fv=(float) v[mm];
	for (j=mm-1;j>=1;j--) {
		fv *= BI;
		fv += v[j];
	}
	fu=1.0/fv;
	for (j=1;j<=n;j++) {
		i=(int) fu;
		u[j]=(unsigned char) i;
		fu=256.0*(fu-i);
	}
	for (;;) {
		mpmul(rr,u,v,n,m);
		mpmov(s,&rr[1],n);
		mpneg(s,n);
		s[1] -= 254;
		mpmul(rr,s,u,n,n);
		mpmov(u,&rr[1],n);
		for (j=2;j<n;j++)
			if (s[j]) break;
		if (j==n) {
			free_cvector(s,1,maxmn);
			free_cvector(rr,1,1+(maxmn<<1));
			return;
		}
	}
}
Example #16
0
int
ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s)
{
	mpint *E, *t, *u1, *u2;
	ECpoint R, S;
	int ret;

	if(mpcmp(r, mpone) < 0 || mpcmp(s, mpone) < 0 || mpcmp(r, dom->n) >= 0 || mpcmp(r, dom->n) >= 0)
		return 0;
	E = betomp(dig, len, nil);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	t = mpnew(0);
	u1 = mpnew(0);
	u2 = mpnew(0);
	R.x = mpnew(0);
	R.y = mpnew(0);
	S.x = mpnew(0);
	S.y = mpnew(0);
	mpinvert(s, dom->n, t);
	mpmul(E, t, u1);
	mpmod(u1, dom->n, u1);
	mpmul(r, t, u2);
	mpmod(u2, dom->n, u2);
	ecmul(dom, dom->G, u1, &R);
	ecmul(dom, pub, u2, &S);
	ecadd(dom, &R, &S, &R);
	ret = 0;
	if(!R.inf){
		mpmod(R.x, dom->n, t);
		ret = mpcmp(r, t) == 0;
	}
	mpfree(t);
	mpfree(u1);
	mpfree(u2);
	mpfree(R.x);
	mpfree(R.y);
	mpfree(S.x);
	mpfree(S.y);
	return ret;
}
Example #17
0
/* setup crt info, returns a newly created structure */
CRTpre*
crtpre(int n, mpint **m)
{
	CRTpre *crt;
	int i, j;
	mpint *u;

	crt = malloc(sizeof(CRTpre)+sizeof(mpint)*3*n);
	if(crt == nil)
		sysfatal("crtpre: %r");
	crt->m = crt->a;
	crt->c = crt->a+n;
	crt->p = crt->c+n;
	crt->n = n;

	/* make a copy of the moduli */
	for(i = 0; i < n; i++)
		crt->m[i] = mpcopy(m[i]);

	/* precompute the products */
	u = mpcopy(mpone);
	for(i = 0; i < n; i++){
		mpmul(u, m[i], u);
		crt->p[i] = mpcopy(u);
	}

	/* precompute the coefficients */
	for(i = 1; i < n; i++){
		crt->c[i] = mpcopy(mpone);
		for(j = 0; j < i; j++){
			mpinvert(m[j], m[i], u);
			mpmul(u, crt->c[i], u);
			mpmod(u, m[i], crt->c[i]);
		}
	}

	mpfree(u);

	return crt;		
}
Example #18
0
/*
 * mpmulmod_w
 *  computes the product (modulo b) of x and y
 *  needs a workspace of (4*size+2) words
 */
void mpbmulmod_w(const mpbarrett* b, size_t xsize, const mpw* xdata, size_t ysize, const mpw* ydata, mpw* result, mpw* wksp)
{
	/* xsize and ysize must be <= b->size */
	register size_t  size = b->size;
	register mpw* temp = wksp + size*2+2;
	register mpw  fill = size*2-xsize-ysize;

	if (fill)
		mpzero(fill, temp);

	mpmul(temp+fill, xsize, xdata, ysize, ydata);
	mpbmod_w(b, temp, result, wksp);
}
Example #19
0
int
ecverify(ECdomain *dom, ECpoint *a)
{
	mpint *p, *q;
	int r;

	if(a->inf)
		return 1;
	
	p = mpnew(0);
	q = mpnew(0);
	mpmul(a->y, a->y, p);
	mpmod(p, dom->p, p);
	mpmul(a->x, a->x, q);
	mpadd(q, dom->a, q);
	mpmul(a->x, q, q);
	mpadd(q, dom->b, q);
	mpmod(q, dom->p, q);
	r = mpcmp(p, q);
	mpfree(p);
	mpfree(q);
	return r == 0;
}
Example #20
0
void mpbnmulmod(const mpbarrett* b, const mpnumber* x, const mpnumber* y, mpnumber* result)
{
	register size_t  size = b->size;
	register mpw* temp = (mpw*) malloc((4*size+2) * sizeof(mpw));

	/* xsize and ysize must be <= b->size */
	register size_t  fill = 2*size-x->size-y->size;
	register mpw* opnd = temp+size*2+2;

	mpnfree(result);
	mpnsize(result, size);

	if (fill)
		mpzero(fill, opnd);

	mpmul(opnd+fill, x->size, x->data, y->size, y->data);
	mpbmod_w(b, opnd, result->data, temp);

	free(temp);
}
Example #21
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;
}
Example #22
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);
}
Example #23
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;
}
Example #24
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;
}
Example #25
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);
}
Example #26
0
mpint*
mpfactorial(ulong n)
{
    int i;
    ulong k;
    unsigned cnt;
    int max, mmax;
    mpdigit p, pp[2];
    mpint *r, *s, *stk[31];

    cnt = 0;
    max = mmax = -1;
    p = 1;
    r = mpnew(0);
    for(k=2; k<=n; k++) {
        pp[0] = 0;
        pp[1] = 0;
        mpvecdigmuladd(&p, 1, (mpdigit)k, pp);
        if(pp[1] == 0)	/* !overflow */
            p = pp[0];
        else {
            cnt++;
            if((cnt & 1) == 0) {
                s = stk[max];
                mpbits(r, Dbits*(s->top+1+1));
                memset(r->p, 0, Dbytes*(s->top+1+1));
                mpvecmul(s->p, s->top, &p, 1, r->p);
                r->sign = 1;
                r->top = s->top+1+1;		/* XXX: norm */
                mpassign(r, s);
                for(i=4; (cnt & (i-1)) == 0; i=i<<1) {
                    mpmul(stk[max], stk[max-1], r);
                    mpassign(r, stk[max-1]);
                    max--;
                }
            } else {
                max++;
                if(max > mmax) {
                    mmax++;
                    if(max > nelem(stk))
                        abort();
                    stk[max] = mpnew(Dbits);
                }
                stk[max]->top = 1;
                stk[max]->p[0] = p;
            }
            p = (mpdigit)k;
        }
    }
    if(max < 0) {
        mpbits(r, Dbits);
        r->top = 1;
        r->sign = 1;
        r->p[0] = p;
    } else {
        s = stk[max--];
        mpbits(r, Dbits*(s->top+1+1));
        memset(r->p, 0, Dbytes*(s->top+1+1));
        mpvecmul(s->p, s->top, &p, 1, r->p);
        r->sign = 1;
        r->top = s->top+1+1;		/* XXX: norm */
    }

    while(max >= 0)
        mpmul(r, stk[max--], r);
    for(max=mmax; max>=0; max--)
        mpfree(stk[max]);
    mpnorm(r);
    return r;
}
Example #27
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;
}
Example #28
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;
		}
	}
}
Example #29
0
void
mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
{
	mpint *t[2];
	int tofree;
	mpdigit d, bit;
	int i, j;

	t[0] = mpcopy(b);
	t[1] = res;

	tofree = 0;
	if(res == b){
		b = mpcopy(b);
		tofree |= Freeb;
	}
	if(res == e){
		e = mpcopy(e);
		tofree |= Freee;
	}
	if(res == m){
		m = mpcopy(m);
		tofree |= Freem;
	}

	// skip first bit
	i = e->top-1;
	d = e->p[i];
	for(bit = mpdighi; (bit & d) == 0; bit >>= 1)
		;
	bit >>= 1;

	j = 0;
	for(;;){
		for(; bit != 0; bit >>= 1){
			mpmul(t[j], t[j], t[j^1]);
			if(bit & d)
				mpmul(t[j^1], b, t[j]);
			else
				j ^= 1;
			if(m != nil && t[j]->top > m->top){
				mpmod(t[j], m, t[j^1]);
				j ^= 1;
			}
		}
		if(--i < 0)
			break;
		bit = mpdighi;
		d = e->p[i];
	}
	if(m != nil){
		mpmod(t[j], m, t[j^1]);
		j ^= 1;
	}
	if(t[j] == res){
		mpfree(t[j^1]);
	} else {
		mpassign(t[j], res);
		mpfree(t[j]);
	}

	if(tofree){
		if(tofree & Freeb)
			mpfree(b);
		if(tofree & Freee)
			mpfree(e);
		if(tofree & Freem)
			mpfree(m);
	}
}