/* -*-c-*-
*
- * $Id: dsa-gen.c,v 1.1 1999/11/19 19:28:00 mdw Exp $
+ * $Id: dsa-gen.c,v 1.2 1999/11/20 22:23:48 mdw Exp $
*
* Generate DSA shared parameters
*
/*----- Revision history --------------------------------------------------*
*
* $Log: dsa-gen.c,v $
+ * 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.
*
* Arguments: @dsa_param *dp@ = where to store parameters
* @unsigned l@ = bitlength of @p@ in bits
* @const void *k@ = pointer to key material
- * @void (*proc)(int ev, mp *m, void *p)@ = event procedure
+ * @int (*proc)(int ev, mp *m, void *p)@ = event procedure
* @size_t sz@ = size of key material
*
* Returns: Zero if all went well, nonzero if key material was
* The event procedure is informed of various happenings during
* generation. It is passed an event code describing what
* happened, and a multiprecision number which pertains to the
- * event code.
+ * event code. It may abort the search at any time by returning
+ * a nonzero value, which is returned as the result of the
+ * function.
*/
int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz,
- void (*proc)(int /*ev*/, mp */*m*/, void */*p*/), void *arg)
+ int (*proc)(int /*ev*/, mp */*m*/, void */*p*/), void *arg)
{
mp *q, *p, *g;
mp *s = mp_loadb(MP_NEW, k, sz);
octet *sbuf = xmalloc(sz);
rc4_ctx rc4;
- int fail;
+ int fail = 0;
l /= 8;
rc4_init(&rc4, k, sz);
sha_hash(&c, k, sz);
sha_done(&c, xbuf);
- MPX_UADDN(s->v, s->vl, 1);
+ mpx_uaddn(s->v, s->vl, 1);
mp_storeb(s, sbuf, sz);
sha_init(&c);
sha_hash(&c, sbuf, sz);
pgen_destroy(&pg);
if (rc == PGEN_COMPOSITE) {
if (proc)
- proc(DSAEV_FAILQ, q, arg);
- fail = DSAEV_FAILQ;
+ fail = proc(DSAEV_FAILQ, q, arg);
+ if (!fail)
+ fail = DSAEV_FAILQ;
goto fail_0;
}
}
g = mp_loadb(g, gbuf, sizeof(gbuf));
if (rabin_test(&r, g) == PGEN_COMPOSITE)
break;
- if (proc)
- proc(DSAEV_PASSQ, q, arg);
+ if (proc && (fail = proc(DSAEV_PASSQ, q, arg)) != 0)
+ break;
}
mp_drop(g);
rabin_destroy(&r);
+ if (fail)
+ goto fail_0;
if (i < 18) {
if (proc)
- proc(DSAEV_FAILQ, q, arg);
- fail = DSAEV_FAILQ;
+ fail = proc(DSAEV_FAILQ, q, arg);
+ if (fail)
+ fail = DSAEV_FAILQ;
goto fail_0;
}
- if (proc)
- proc(DSAEV_GOODQ, q, arg);
+ if (proc && (fail = proc(DSAEV_GOODQ, q, arg)) != 0)
+ goto fail_0;
}
/* --- Now generate @p@ --- *
octet *pp = pbuf + SHA_HASHSZ * n;
for (i = 0; i <= n; i++) {
- MPX_UADDN(s->v, s->vl, 1);
+ mpx_uaddn(s->v, s->vl, 1);
mp_storeb(s, sbuf, sz);
sha_init(&c);
sha_hash(&c, sbuf, sz);
rabin r;
mp *g = MP_NEW;
- if (proc)
- proc(DSAEV_TRYP, p, arg);
rabin_create(&r, p);
+ if (proc && (fail = proc(DSAEV_TRYP, p, arg)) != 0)
+ break;
for (i = 0; i < 5; i++) {
rc4_encrypt(&rc4, 0, pbuf, psz - b);
g = mp_loadb(g, pbuf, psz - b);
if (rabin_test(&r, g) == PGEN_COMPOSITE)
break;
- if (proc)
- proc(DSAEV_PASSP, p, arg);
+ if (proc && (fail = proc(DSAEV_PASSP, p, arg)) != 0)
+ break;
}
mp_drop(g);
rabin_destroy(&r);
+ if (fail)
+ break;
if (i < 5) {
- if (proc)
- proc(DSAEV_FAILP, p, arg);
- fail = DSAEV_FAILP;
+ if (proc && (fail = proc(DSAEV_FAILP, p, arg)) != 0)
+ break;
continue;
}
}
/* --- It worked! --- */
if (proc)
- proc(DSAEV_GOODP, p, arg);
+ fail = proc(DSAEV_GOODP, p, arg);
break;
}
free(pbuf);
mp_drop(q2);
mp_drop(ll);
- if (j >= 4096)
+ if (j >= 4096 || fail)
goto fail_1;
}
mpmont_create(&mm, p);
for (i = 0; i < NPRIME; i++) {
hw = ptab[i];
- if (proc)
- proc(DSAEV_TRYH, &h, arg);
+ if (proc && (fail = proc(DSAEV_TRYH, &h, arg)) != 0)
+ break;
g = mpmont_exp(&mm, &h, pp);
if (MP_CMP(g, !=, MP_ONE))
break;
- if (proc)
- proc(DSAEV_FAILH, &h, arg);
mp_drop(g);
+ if (proc && (fail = proc(DSAEV_FAILH, &h, arg)) != 0)
+ break;
}
mp_drop(pp);
+ if (fail)
+ goto fail_1;
if (i >= NPRIME) {
fail = DSAEV_FAILH;
goto fail_1;
}
}
- if (proc)
- proc(DSAEV_GOODG, g, arg);
+ if (proc && (fail = proc(DSAEV_GOODG, g, arg) != 0))
+ goto fail_2;
/* --- Return the important information that I succeeded --- */
+ dp->g = g;
dp->p = p;
dp->q = q;
- dp->g = g;
+ mp_drop(s);
free(sbuf);
return (0);
/* --- Tidy up after failure --- */
+fail_2:
+ mp_drop(g);
fail_1:
mp_drop(p);
fail_0:
static char baton[] = "/-\\|";
static char *b = baton;
-static void event(int ev, mp *m, void *p)
+static int event(int ev, mp *m, void *p)
{
if (ev == DSAEV_TRYP || ev == DSAEV_PASSP) {
fputc(*b++, stdout);
if (!*b)
b = baton;
}
+ return (0);
}
static int verify(dstr *v)