/* -*-c-*-
*
- * $Id: dsa-gen.c,v 1.8 2000/10/08 12:12:47 mdw Exp $
+ * $Id: dsa-gen.c,v 1.9 2001/02/03 16:09:29 mdw Exp $
*
* Generate DSA shared parameters
*
/*----- Revision history --------------------------------------------------*
*
* $Log: dsa-gen.c,v $
+ * Revision 1.9 2001/02/03 16:09:29 mdw
+ * Allow the caller to fetch the parameter generation seed and counter.
+ *
* Revision 1.8 2000/10/08 12:12:47 mdw
* Use @MP_EQ@ instead of @MP_CMP@. Remove vestages of @primorial@.
*
/* --- Load the new candidate --- */
- m = mprand(ev->m, d->bits, d->r, d->or);
+ if (d->seedbuf)
+ d->r->ops->misc(d->r, DSARAND_GETSEED, d->seedbuf);
+ m = mprand(ev->m, d->bits, d->r, 0);
/* --- Force to be a multiple of @q@ --- */
/* --- Do the trial division --- */
rc = pfilt_smallfactor(m);
+ d->count++;
/* --- Return the result --- */
* @unsigned steps@ = number of steps to find @q@
* @const void *k@ = pointer to key material
* @size_t sz@ = size of key material
+ * @dsa_seed *ds@ = optional pointer for output seed information
* @pgen_proc *event@ = event handler function
* @void *ectx@ = argument for event handler
*
*/
int dsa_gen(dsa_param *dp, unsigned ql, unsigned pl, unsigned steps,
- const void *k, size_t sz, pgen_proc *event, void *ectx)
+ const void *k, size_t sz, dsa_seed *ds,
+ pgen_proc *event, void *ectx)
{
dsa_stepctx s;
prim_ctx p;
/* --- Initialize the stepping context --- */
s.r = dsarand_create(k, sz);
- s.or = 1;
/* --- Find @q@ --- */
s.q = 0;
s.r->ops->misc(s.r, DSARAND_PASSES, 2);
s.bits = ql;
+ s.count = 0;
+ s.or = 1;
+ if (!ds)
+ s.seedbuf = 0;
+ else {
+ ds->sz = sz;
+ ds->p = s.seedbuf = xmalloc(sz);
+ }
if ((dp->q = pgen("q", MP_NEW, MP_NEW, event, ectx, steps, dsa_step, &s,
rabin_iters(ql), pgen_test, &r)) == 0)
goto fail_q;
/* --- Find @p@ --- */
+ s.count = ~0;
s.q = mp_lsl(MP_NEW, dp->q, 1);
s.r->ops->misc(s.r, DSARAND_PASSES, 1);
s.bits = pl;
+ s.seedbuf = 0;
if ((dp->p = pgen("p", MP_NEW, MP_NEW, event, ectx, 4096, dsa_step, &s,
rabin_iters(pl), pgen_test, &r)) == 0)
goto fail_p;
mp_drop(s.q);
+ if (ds)
+ ds->count = s.count;
/* --- Find @g@ --- *
*
mp_drop(s.q);
fail_q:
s.r->ops->destroy(s.r);
+ if (ds)
+ xfree(ds->p);
return (PGEN_ABORT);
}
static int verify(dstr *v)
{
- mp *q = *(mp **)v[2].buf;
- mp *p = *(mp **)v[3].buf;
- mp *g = *(mp **)v[4].buf;
+ mp *q = *(mp **)v[4].buf;
+ mp *p = *(mp **)v[5].buf;
+ mp *g = *(mp **)v[6].buf;
dsa_param dp;
- unsigned l = *(unsigned *)v[1].buf;
+ dsa_seed ds;
+ unsigned long l = *(unsigned long *)v[1].buf;
+ unsigned long n = *(unsigned long *)v[3].buf;
int ok = 1;
int rc;
+ keycheck kc;
+ keycheck_reportctx kcr;
- rc = dsa_gen(&dp, 160, l, 1, v[0].buf, v[0].len, pgen_evspin, 0);
- if (rc || !MP_EQ(q, dp.q) ||
- !MP_EQ(p, dp.p) || !MP_EQ(g, dp.g)) {
+ rc = dsa_gen(&dp, 160, l, 16, v[0].buf, v[0].len, &ds, pgen_evspin, 0);
+ if (rc || ds.count != n || ds.sz != v[2].len ||
+ memcmp(ds.p, v[2].buf, v[2].len) != 0 ||
+ !MP_EQ(q, dp.q) || !MP_EQ(p, dp.p) || !MP_EQ(g, dp.g)) {
fputs("\n*** gen failed", stderr);
- fputs("\nseed = ", stderr); type_hex.dump(&v[0], stderr);
- fprintf(stderr, "\nl = %u", l);
+ fputs("\nseed_in = ", stderr); type_hex.dump(&v[0], stderr);
+ fprintf(stderr, "\nl = %lu", l);
+ fputs("\nseed_out = ", stderr); type_hex.dump(&v[2], stderr);
+ fprintf(stderr, "\ncount = %lu", n);
fputs("\n q = ", stderr); mp_writefile(q, stderr, 16);
fputs("\n p = ", stderr); mp_writefile(p, stderr, 16);
fputs("\n g = ", stderr); mp_writefile(g, stderr, 16);
if (!rc) {
+ dstr d;
+ d.buf = ds.p; d.len = ds.sz;
+ fputs("\nds.seed = ", stderr); type_hex.dump(&d, stderr);
+ fprintf(stderr, "\nds.count = %u", ds.count);
fputs("\ndp.q = ", stderr); mp_writefile(dp.q, stderr, 16);
fputs("\ndp.p = ", stderr); mp_writefile(dp.p, stderr, 16);
fputs("\ndp.g = ", stderr); mp_writefile(dp.g, stderr, 16);
ok = 0;
}
+ kcr.fp = stderr;
+ kcr.sev = KCSEV_ERR;
+ keycheck_init(&kc, keycheck_stdreport, &kcr);
+ if (!rc)
+ dsa_checkparam(&kc, &dp, &ds);
+ if (!keycheck_allclear(&kc, KCSEV_ERR)) {
+ fputs("\n*** gen failed check", stderr);
+ fputs("\nseed_in = ", stderr); type_hex.dump(&v[0], stderr);
+ fprintf(stderr, "\nl = %lu", l);
+ fputs("\nseed_out = ", stderr); type_hex.dump(&v[2], stderr);
+ fprintf(stderr, "\ncount = %lu", n);
+ fputs("\n q = ", stderr); mp_writefile(q, stderr, 16);
+ fputs("\n p = ", stderr); mp_writefile(p, stderr, 16);
+ fputs("\n g = ", stderr); mp_writefile(g, stderr, 16);
+ fputc('\n', stderr);
+ ok = 0;
+ }
+
mp_drop(q); mp_drop(p); mp_drop(g);
if (!rc) {
- mp_drop(dp.q); mp_drop(dp.p); mp_drop(dp.g);
+ mp_drop(dp.q); mp_drop(dp.p); mp_drop(dp.g); xfree(ds.p);
}
assert(mparena_count(MPARENA_GLOBAL) == 0);
return (ok);
static test_chunk tests[] = {
{ "gen", verify,
- { &type_hex, &type_int, &type_mp, &type_mp, &type_mp, 0 } },
+ { &type_hex, &type_ulong, &type_hex, &type_ulong,
+ &type_mp, &type_mp, &type_mp, 0 } },
{ 0, 0, { 0 } }
};