key/key-io.c: Add low-level `key_mergeline' and `key_extractline' functions.
[catacomb] / pub / dsa-misc.c
index 4d8bc2a..3902f68 100644 (file)
@@ -61,4 +61,53 @@ mp *dsa_h2n(mp *d, mp *r, const void *h, size_t hsz)
   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 -------------------------------------------------*/