if (k) { MP_COPY(k); goto have_k; }
new_k:
- k = mprand_range(k, g->r, c->r, 0);
+ k = dsa_nonce(k, g->r, c->u, m, c->h, c->r);
have_k:
if (MP_ZEROP(k)) goto new_k;
G_EXP(g, z, g->g, k);
#ifdef TEST_RIG
+#include "rand.h"
+
static group *getgroup(const char *p) {
group *g; qd_parse qd;
qd.p = p; qd.e = 0; g = group_parse(&qd);
if (g && !qd_eofp(&qd)) { G_DESTROYGROUP(g); g = 0; qd.e = "junk at eof"; }
- if (!g) { fprintf(stderr, "bad group string `%.*s|%s': %s\n", qd.p - p,
- p, qd.p, qd.e); exit(1); }
+ if (!g) {
+ fprintf(stderr, "bad group string `%.*s|%s': %s\n",
+ (int)(qd.p - p), p, qd.p, qd.e);
+ exit(1);
+ }
return (g);
}
gdsa c;
gdsa_sig s, ss = GDSA_SIG_INIT;
ghash *h;
+ octet *m;
mp *k;
int ok = 1;
c.g = getgroup(v[0].buf); c.h = ghash_byname(v[1].buf);
c.u = *(mp **)v[2].buf; k = *(mp **)v[4].buf;
s.r = *(mp **)v[5].buf; s.s = *(mp **)v[6].buf;
+ c.p = G_CREATE(c.g); G_EXP(c.g, c.p, c.g->g, c.u);
h = gdsa_beginhash(&c);
GH_HASH(h, v[3].buf, v[3].len);
showmp("computed r", ss.r, 16); showmp("computed s", ss.s, 16);
showmp("expected r", s.r, 16); showmp("expected s", s.s, 16);
}
+
+ c.r = &rand_global;
+ h = gdsa_beginhash(&c);
+ GH_HASH(h, v[3].buf, v[3].len);
+ m = GH_DONE(h, 0);
+ GH_DESTROY(h);
+ gdsa_sign(&c, &ss, m, 0);
+ if (gdsa_verify(&c, &ss, m)) {
+ ok = 0;
+ fprintf(stderr, "*** sign cross-check failed!\n");
+ fprintf(stderr, "*** group: %s\n", v[0].buf);
+ fprintf(stderr, "*** hash: %s\n", c.h->name);
+ showmp("private key", c.u, 16);
+ showge(c.g, "public key", c.p);
+ fprintf(stderr, "*** message: `%s'\n", v[3].buf);
+ showmp("computed r", ss.r, 16); showmp("computed s", ss.s, 16);
+ }
+
mp_drop(s.r); mp_drop(s.s); mp_drop(ss.r); mp_drop(ss.s);
- mp_drop(k); mp_drop(c.u); G_DESTROYGROUP(c.g); GH_DESTROY(h);
+ mp_drop(k); mp_drop(c.u); G_DESTROY(c.g, c.p); G_DESTROYGROUP(c.g);
assert(mparena_count(MPARENA_GLOBAL) == 0);
return (ok);
}