X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/8b810a45dec25017a6256e4ef134236444a00921..674cd11ec63b56561980249cb19a0db54bacfa86:/dsa-gen.c diff --git a/dsa-gen.c b/dsa-gen.c index ac33088..b719a23 100644 --- a/dsa-gen.c +++ b/dsa-gen.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: dsa-gen.c,v 1.1 1999/11/19 19:28:00 mdw Exp $ + * $Id: dsa-gen.c,v 1.3 1999/12/10 23:18:38 mdw Exp $ * * Generate DSA shared parameters * @@ -30,6 +30,12 @@ /*----- Revision history --------------------------------------------------* * * $Log: dsa-gen.c,v $ + * 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. * @@ -41,10 +47,11 @@ #include #include "dsa.h" +#include "fibrand.h" #include "mp.h" +#include "mprand.h" #include "pgen.h" #include "rabin.h" -#include "rc4.h" #include "sha.h" /*----- Main code ---------------------------------------------------------*/ @@ -54,8 +61,8 @@ * 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 * @size_t sz@ = size of key material + * @int (*proc)(int ev, mp *m, void *p)@ = event procedure * * Returns: Zero if all went well, nonzero if key material was * unsuitable (one of the @DSAEV@ codes). @@ -69,20 +76,22 @@ * 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; + grand *gr; + int fail = 0; l /= 8; - rc4_init(&rc4, k, sz); + gr = fibrand_create(LOAD32(k)); /* --- Generate @q@ --- */ @@ -95,7 +104,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t 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); @@ -110,14 +119,18 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, /* --- Quick primality check --- */ + if (proc && (fail = proc(DSAEV_FINDQ, 0, arg)) != 0) + goto fail_0; + { pgen pg; int rc = pgen_create(&pg, q); 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; } } @@ -132,27 +145,30 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, rabin r; int i; mp *g = MP_NEW; - octet gbuf[SHA_HASHSZ]; rabin_create(&r, q); for (i = 0; i < 18; i++) { - rc4_encrypt(&rc4, 0, gbuf, sizeof(gbuf)); - g = mp_loadb(g, gbuf, sizeof(gbuf)); + g = mprand(g, 8 * SHA_HASHSZ, gr, 1); 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; + if (proc && (fail = proc(DSAEV_FINDP, 0, arg)) != 0) + goto fail_0; } /* --- Now generate @p@ --- * @@ -184,7 +200,7 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, 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); @@ -228,23 +244,23 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t 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); + g = mprand(g, 8 * (psz - b), gr, 1); 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; } } @@ -252,14 +268,16 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, /* --- It worked! --- */ if (proc) - proc(DSAEV_GOODP, p, arg); + fail = proc(DSAEV_GOODP, p, arg); + if (proc && !fail) + fail = proc(DSAEV_FINDG, 0, arg); break; } free(pbuf); mp_drop(q2); mp_drop(ll); - if (j >= 4096) + if (j >= 4096 || fail) goto fail_1; } @@ -274,11 +292,8 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, /* --- Calculate %$p' = (p - 1)/q$% --- */ - { - mp *p1 = mp_sub(MP_NEW, p, MP_ONE); - mp_div(&pp, 0, p1, q); - mp_drop(p1); - } + pp = mp_sub(MP_NEW, p, MP_ONE); + mp_div(&pp, 0, pp, q); /* --- Now find %$h$% where %$g = h^{p'} \bmod p \ne 1$% --- */ @@ -286,40 +301,48 @@ int dsa_seed(dsa_param *dp, unsigned l, const void *k, size_t sz, mpmont_create(&mm, p); for (i = 0; i < NPRIME; i++) { hw = ptab[i]; - if (proc) - proc(DSAEV_TRYH, &h, arg); - g = mpmont_exp(&mm, &h, pp); + if (proc && (fail = proc(DSAEV_TRYH, &h, arg)) != 0) + break; + g = mpmont_exp(&mm, MP_NEW, &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); + mpmont_destroy(&mm); + 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); + gr->ops->destroy(gr); return (0); /* --- Tidy up after failure --- */ +fail_2: + mp_drop(g); fail_1: mp_drop(p); fail_0: mp_drop(q); mp_drop(s); free(sbuf); + gr->ops->destroy(gr); return (-1); } @@ -330,7 +353,7 @@ 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); @@ -339,6 +362,7 @@ static void event(int ev, mp *m, void *p) if (!*b) b = baton; } + return (0); } static int verify(dstr *v) @@ -373,6 +397,7 @@ static int verify(dstr *v) if (!rc) { mp_drop(dp.q); mp_drop(dp.p); mp_drop(dp.g); } + assert(mparena_count(MPARENA_GLOBAL) == 0); return (ok); }