return (d);
}
+/* --- @dsa_nonce@ --- *
+ *
+ * Arguments: @mp *d@ = destination integer
+ * @mp *q@ = order of the DSA group
+ * @mp *x@ = secret key
+ * @const octet *m@ = message hash
+ * @const gchash *ch@ = hash class
+ * @grand *r@ = random bit source, or null
+ *
+ * Returns: A nonce.
+ *
+ * Use: Generates a nonce for use in DSA (or another Fiat--Shamir
+ * signature scheme).
+ */
+
+mp *dsa_nonce(mp *d, mp *q, mp *x, const octet *m,
+ const gchash *ch, grand *r)
+{
+ uint32 i = 0;
+ size_t nb = mp_bits(q), n = (nb + 7)/8, j;
+ size_t bsz = 2*n + 2*ch->hashsz;
+ octet *b = XS_ALLOC(bsz);
+ octet *kb = b, *rb = kb + n, *hb = rb + ch->hashsz;
+ static const char prefix[] = "catacomb-dsa-nonce";
+ ghash *h;
+
+ mp_storeb(x, kb, n);
+ if (r) grand_fill(r, rb, ch->hashsz);
+
+ do {
+ for (j = 0; j < n; j += ch->hashsz) {
+ h = GH_INIT(ch);
+ GH_HASH(h, prefix, sizeof(prefix));
+ GH_HASHBUF32(h, kb, n);
+ GH_HASHBUF32(h, m, ch->hashsz);
+ if (r) GH_HASHBUF32(h, rb, ch->hashsz);
+ GH_HASHU32(h, i);
+ GH_DONE(h, hb + j);
+ GH_DESTROY(h);
+ i++;
+ }
+ d = mp_loadb(d, hb, n);
+ d = mp_lsr(d, d, 8*n - nb);
+ } while (MP_CMP(d, >=, q));
+
+ memset(b, 0, bsz); XS_FREE(b);
+ return (d);
+}
+
/*----- That's all, folks -------------------------------------------------*/