/* -*-c-*-
*
- * $Id: dsa-gen.c,v 1.8 2000/10/08 12:12:47 mdw Exp $
+ * $Id: dsa-gen.c,v 1.10 2004/04/08 01:36:15 mdw Exp $
*
* Generate DSA shared parameters
*
* (c) 1999 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of Catacomb.
*
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
- *
+ *
* Catacomb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Library General Public
* License along with Catacomb; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: dsa-gen.c,v $
- * Revision 1.8 2000/10/08 12:12:47 mdw
- * Use @MP_EQ@ instead of @MP_CMP@. Remove vestages of @primorial@.
- *
- * Revision 1.7 2000/08/15 21:45:05 mdw
- * Use the new trial division equipment in pfilt. This gives a 10%
- * performance improvement in dsa-gen.t.
- *
- * Revision 1.6 2000/07/29 10:00:14 mdw
- * Rename `dsa_seed' to `dsa_gen' for consistency with other parameter-
- * generation interfaces.
- *
- * Revision 1.5 2000/02/12 18:21:02 mdw
- * Overhaul of key management (again).
- *
- * Revision 1.4 1999/12/22 15:52:44 mdw
- * Reworking for new prime-search system.
- *
- * Revision 1.3 1999/12/10 23:18:38 mdw
- * Change interface for suggested destinations.
- *
- * Revision 1.2 1999/11/20 22:23:48 mdw
- * Allow event handler to abort the search process.
- *
- * Revision 1.1 1999/11/19 19:28:00 mdw
- * Implementation of the Digital Signature Algorithm.
- *
- */
-
/*----- Header files ------------------------------------------------------*/
#include <stdio.h>
/* --- 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("\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);
+ 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 } }
};