/* -*-c-*-
*
- * $Id: dsa-gen.c,v 1.2 1999/11/20 22:23:48 mdw Exp $
+ * $Id: dsa-gen.c,v 1.3 1999/12/10 23:18:38 mdw Exp $
*
* Generate DSA shared parameters
*
/*----- 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.
*
#include <stdlib.h>
#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 ---------------------------------------------------------*/
* Arguments: @dsa_param *dp@ = where to store parameters
* @unsigned l@ = bitlength of @p@ in bits
* @const void *k@ = pointer to key material
- * @int (*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).
mp *q, *p, *g;
mp *s = mp_loadb(MP_NEW, k, sz);
octet *sbuf = xmalloc(sz);
- rc4_ctx rc4;
+ grand *gr;
int fail = 0;
l /= 8;
- rc4_init(&rc4, k, sz);
+ gr = fibrand_create(LOAD32(k));
/* --- Generate @q@ --- */
/* --- Quick primality check --- */
+ if (proc && (fail = proc(DSAEV_FINDQ, 0, arg)) != 0)
+ goto fail_0;
+
{
pgen pg;
int rc = pgen_create(&pg, q);
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 && (fail = proc(DSAEV_PASSQ, q, arg)) != 0)
if (i < 18) {
if (proc)
fail = proc(DSAEV_FAILQ, q, arg);
- if (fail)
+ if (!fail)
fail = DSAEV_FAILQ;
goto fail_0;
}
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@ --- *
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 && (fail = proc(DSAEV_PASSP, p, arg)) != 0)
if (proc)
fail = proc(DSAEV_GOODP, p, arg);
+ if (proc && !fail)
+ fail = proc(DSAEV_FINDG, 0, arg);
break;
}
/* --- 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$% --- */
hw = ptab[i];
if (proc && (fail = proc(DSAEV_TRYH, &h, arg)) != 0)
break;
- g = mpmont_exp(&mm, &h, pp);
+ g = mpmont_exp(&mm, MP_NEW, &h, pp);
if (MP_CMP(g, !=, MP_ONE))
break;
mp_drop(g);
break;
}
mp_drop(pp);
+ mpmont_destroy(&mm);
if (fail)
goto fail_1;
if (i >= NPRIME) {
dp->q = q;
mp_drop(s);
free(sbuf);
+ gr->ops->destroy(gr);
return (0);
/* --- Tidy up after failure --- */
mp_drop(q);
mp_drop(s);
free(sbuf);
+ gr->ops->destroy(gr);
return (-1);
}
if (!rc) {
mp_drop(dp.q); mp_drop(dp.p); mp_drop(dp.g);
}
+ assert(mparena_count(MPARENA_GLOBAL) == 0);
return (ok);
}