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; }
int dlpk_pgonValidate(const dlpk_p* pk, randomGeneratorContext* rgc) { register int rc = dldp_pgonValidate(&pk->param, rgc); if (rc <= 0) return rc; if (mpleone(pk->y.size, pk->y.data)) return 0; if (mpgex(pk->y.size, pk->y.data, pk->param.p.size, pk->param.p.modl)) return 0; return 1; }
/* * 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); }
/* * needs to make workspace of 8*size+2 */ int dldp_pValidate(const dldp_p* dp, randomGeneratorContext* rgc) { register size_t size = dp->p.size; register mpw* temp = (mpw*) malloc((8*size+2) * sizeof(mpw)); if (temp) { /* check that p > 2 and p odd, then run miller-rabin test with t 50 */ if (mpeven(dp->p.size, dp->p.modl)) { free(temp); return 0; } if (mppmilrab_w(&dp->p, rgc, 50, temp) == 0) { free(temp); return 0; } /* check that q > 2 and q odd, then run miller-rabin test with t 50 */ if (mpeven(dp->q.size, dp->q.modl)) { free(temp); return 0; } if (mppmilrab_w(&dp->q, rgc, 50, temp) == 0) { free(temp); return 0; } free(temp); /* check that 1 < g < p */ if (mpleone(dp->g.size, dp->g.data)) return 0; if (mpgex(dp->g.size, dp->g.data, dp->p.size, dp->p.modl)) return 0; return 1; } return -1; }
/* * 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; }
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; }