int elgv3sign(const mpbarrett* p, const mpbarrett* n, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t size = p->size; register mpw* temp = (mpw*) malloc((6*size+2)*sizeof(mpw)); if (temp) { /* get a random k */ mpbrnd_w(p, rgc, temp, temp+2*size); /* compute r = g^k mod p */ mpnfree(r); mpnsize(r, size); mpbpowmod_w(p, g->size, g->data, size, temp, r->data, temp+2*size); /* compute u1 = x*r mod n */ mpbmulmod_w(n, x->size, x->data, size, r->data, temp+size, temp+2*size); /* compute u2 = k*h(m) mod n */ mpbmulmod_w(n, size, temp, hm->size, hm->data, temp, temp+2*size); /* compute s = u1+u2 mod n */ mpnfree(s); mpnsize(s, n->size); mpbaddmod_w(n, size, temp, size, temp+size, s->data, temp+2*size); free(temp); return 0; } return -1; }
int dldp_pgoqGenerator_w(dldp_p* dp, randomGeneratorContext* rgc, mpw* wksp) { /* * Randomly determine a generator over the subgroup with order q */ register size_t size = dp->p.size; mpnfree(&dp->g); mpnsize(&dp->g, size); while (1) { /* get a random value h (stored into g) */ mpbrnd_w(&dp->p, rgc, dp->g.data, wksp); /* first compute h^r mod p (stored in g) */ mpbpowmod_w(&dp->p, size, dp->g.data, dp->r.size, dp->r.data, dp->g.data, wksp); if (mpisone(size, dp->g.data)) continue; return 0; } return -1; }
int elgv1vrfy(const mpbarrett* p, const mpbarrett* n, const mpnumber* g, const mpnumber* hm, const mpnumber* y, const mpnumber* r, const mpnumber* s) { register size_t size = p->size; register mpw* temp; if (mpz(r->size, r->data)) return 0; if (mpgex(r->size, r->data, size, p->modl)) return 0; if (mpz(s->size, s->data)) return 0; if (mpgex(s->size, s->data, n->size, n->modl)) return 0; temp = (mpw*) malloc((6*size+2)*sizeof(mpw)); if (temp) { register int rc; /* compute u1 = y^r mod p */ mpbpowmod_w(p, y->size, y->data, r->size, r->data, temp, temp+2*size); /* compute u2 = r^s mod p */ mpbpowmod_w(p, r->size, r->data, s->size, s->data, temp+size, temp+2*size); /* compute v1 = u1*u2 mod p */ mpbmulmod_w(p, size, temp, size, temp+size, temp+size, temp+2*size); /* compute v2 = g^h(m) mod p */ mpbpowmod_w(p, g->size, g->data, hm->size, hm->data, temp, temp+2*size); rc = mpeq(size, temp, temp+size); free(temp); return rc; } return 0; }
void mpbnpowmod(const mpbarrett* b, const mpnumber* x, const mpnumber* pow, mpnumber* y) { register size_t size = b->size; register mpw* temp = (mpw*) malloc((4*size+2) * sizeof(mpw)); mpnfree(y); mpnsize(y, size); mpbpowmod_w(b, x->size, x->data, pow->size, pow->data, y->data, temp); free(temp); }
/* * needs workspace of (5*size+2) words */ int mppmilraba_w(const mpbarrett* p, const mpw* adata, int s, const mpw* rdata, const mpw* ndata, mpw* wksp) { register size_t size = p->size; register int j = 0; mpbpowmod_w(p, size, adata, size, rdata, wksp, wksp+size); while (1) { if (mpisone(size, wksp)) return (j == 0); if (mpeq(size, wksp, ndata)) return 1; if (++j < s) mpbsqrmod_w(p, size, wksp, wksp, wksp+size); else return 0; } }
int elgv1sign(const mpbarrett* p, const mpbarrett* n, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t size = p->size; register mpw* temp = (mpw*) malloc((8*size+6)*sizeof(mpw)); if (temp) { /* get a random k, invertible modulo (p-1) */ mpbrndinv_w(n, rgc, temp, temp+size, temp+2*size); /* compute r = g^k mod p */ mpnfree(r); mpnsize(r, size); mpbpowmod_w(p, g->size, g->data, size, temp, r->data, temp+2*size); /* compute x*r mod n */ mpbmulmod_w(n, x->size, x->data, r->size, r->data, temp, temp+2*size); /* compute -(x*r) mod n */ mpneg(size, temp); mpadd(size, temp, n->modl); /* compute h(m) - x*r mod n */ mpbaddmod_w(n, hm->size, hm->data, size, temp, temp, temp+2*size); /* compute s = inv(k)*(h(m) - x*r) mod n */ mpnfree(s); mpnsize(s, size); mpbmulmod_w(n, size, temp, size, temp+size, s->data, temp+2*size); free(temp); return 0; } return -1; }
int dsavrfy(const mpbarrett* p, const mpbarrett* q, const mpnumber* g, const mpnumber* hm, const mpnumber* y, const mpnumber* r, const mpnumber* s) { register size_t psize = p->size; register size_t qsize = q->size; register mpw* ptemp; register mpw* qtemp; register mpw* pwksp; register mpw* qwksp; register int rc = 0; /* h(m) shouldn't contain more bits than q */ if (mpbits(hm->size, hm->data) > mpbits(q->size, q->modl)) return rc; /* check 0 < r < q */ if (mpz(r->size, r->data)) return rc; if (mpgex(r->size, r->data, qsize, q->modl)) return rc; /* check 0 < s < q */ if (mpz(s->size, s->data)) return rc; if (mpgex(s->size, s->data, qsize, q->modl)) return rc; ptemp = (mpw*) malloc((6*psize+2)*sizeof(mpw)); if (ptemp == (mpw*) 0) return rc; qtemp = (mpw*) malloc((8*qsize+6)*sizeof(mpw)); if (qtemp == (mpw*) 0) { free(ptemp); return rc; } pwksp = ptemp+2*psize; qwksp = qtemp+2*qsize; mpsetx(qsize, qtemp+qsize, s->size, s->data); /* compute w = inv(s) mod q */ if (mpextgcd_w(qsize, q->modl, qtemp+qsize, qtemp, qwksp)) { /* compute u1 = h(m)*w mod q */ mpbmulmod_w(q, hm->size, hm->data, qsize, qtemp, qtemp+qsize, qwksp); /* compute u2 = r*w mod q */ mpbmulmod_w(q, r->size, r->data, qsize, qtemp, qtemp, qwksp); /* compute g^u1 mod p */ mpbpowmod_w(p, g->size, g->data, qsize, qtemp+qsize, ptemp, pwksp); /* compute y^u2 mod p */ mpbpowmod_w(p, y->size, y->data, qsize, qtemp, ptemp+psize, pwksp); /* multiply mod p */ mpbmulmod_w(p, psize, ptemp, psize, ptemp+psize, ptemp, pwksp); /* modulo q */ mpmod(ptemp+psize, psize, ptemp, qsize, q->modl, pwksp); rc = mpeqx(r->size, r->data, psize, ptemp+psize); } free(qtemp); free(ptemp); return rc; }
int dsasign(const mpbarrett* p, const mpbarrett* q, const mpnumber* g, randomGeneratorContext* rgc, const mpnumber* hm, const mpnumber* x, mpnumber* r, mpnumber* s) { register size_t psize = p->size; register size_t qsize = q->size; register mpw* ptemp; register mpw* qtemp; register mpw* pwksp; register mpw* qwksp; register int rc = -1; ptemp = (mpw*) malloc((5*psize+2)*sizeof(mpw)); if (ptemp == (mpw*) 0) return rc; qtemp = (mpw*) malloc((9*qsize+6)*sizeof(mpw)); if (qtemp == (mpw*) 0) { free(ptemp); return rc; } pwksp = ptemp+psize; qwksp = qtemp+3*qsize; /* allocate r */ mpnfree(r); mpnsize(r, qsize); /* get a random k, invertible modulo q; store k @ qtemp, inv(k) @ qtemp+qsize */ mpbrndinv_w(q, rgc, qtemp, qtemp+qsize, qwksp); /* g^k mod p */ mpbpowmod_w(p, g->size, g->data, qsize, qtemp, ptemp, pwksp); /* (g^k mod p) mod q - simple modulo */ mpmod(qtemp+2*qsize, psize, ptemp, qsize, q->modl, pwksp); mpcopy(qsize, r->data, qtemp+psize+qsize); /* allocate s */ mpnfree(s); mpnsize(s, qsize); /* x*r mod q */ mpbmulmod_w(q, x->size, x->data, r->size, r->data, qtemp, qwksp); /* add h(m) mod q */ mpbaddmod_w(q, qsize, qtemp, hm->size, hm->data, qtemp+2*qsize, qwksp); /* multiply inv(k) mod q */ mpbmulmod_w(q, qsize, qtemp+qsize, qsize, qtemp+2*qsize, s->data, qwksp); rc = 0; free(qtemp); free(ptemp); return rc; }
int dldp_pgonGenerator_w(dldp_p* dp, randomGeneratorContext* rgc, mpw* wksp) { register size_t size = dp->p.size; mpnfree(&dp->g); mpnsize(&dp->g, size); while (1) { mpbrnd_w(&dp->p, rgc, dp->g.data, wksp); if (mpistwo(dp->r.size, dp->r.data)) { /* * A little math here: the only element in the group which has order 2 is (p-1); * the two group elements raised to power two which result in 1 (mod p) are thus (p-1) and 1 * * mpbrnd_w doesn't return 1 or (p-1), so the test where g^2 mod p = 1 can be safely skipped */ /* check g^q mod p*/ mpbpowmod_w(&dp->p, size, dp->g.data, dp->q.size, dp->q.modl, wksp, wksp+size); if (mpisone(size, wksp)) continue; } else { /* we can either compute g^r, g^2q and g^(qr/2) or * we first compute s = r/2, and then compute g^2s, g^2q and g^qs * * hence we first compute t = g^s * then compute t^2 mod p, and test if one * then compute t^q mod p, and test if one * then compute (g^q mod p)^2 mod p, and test if one */ /* compute s = r/2 */ mpsetx(size, wksp, dp->r.size, dp->r.data); mpdivtwo(size, wksp); /* compute t = g^s mod p */ mpbpowmod_w(&dp->p, size, dp->g.data, size, wksp, wksp+size, wksp+2*size); /* compute t^2 mod p = g^2s mod p = g^r mod p*/ mpbsqrmod_w(&dp->p, size, wksp+size, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; /* compute t^q mod p = g^qs mod p */ mpbpowmod_w(&dp->p, size, wksp, dp->q.size, dp->q.modl, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; /* compute g^2q mod p */ mpbpowmod_w(&dp->p, size, dp->g.data, dp->q.size, dp->q.modl, wksp, wksp+size); mpbsqrmod_w(&dp->p, size, wksp, wksp+size, wksp+2*size); if (mpisone(size, wksp+size)) continue; } return 0; } return -1; }