base/keysz.c: New function to find smallest `key' size larger.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 9 Nov 2018 18:21:34 +0000 (18:21 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Thu, 5 Sep 2019 00:33:36 +0000 (01:33 +0100)
Now that AEAD schemes are (ab)using key-size lists for permitted nonce
lengths, it's useful to ask: what's the smallest acceptable size bigger
than the amount of stuff I want to pack into this nonce?  The new
`keysz_pad' function answers this question.

base/keysz.c
base/keysz.h

index 8e5e2ca..13d850a 100644 (file)
@@ -81,4 +81,43 @@ size_t keysz(size_t sz, const octet *ksz)
   return (0);
 }
 
+/* --- @keysz_pad@ --- *
+ *
+ * Arguments:  @size_t sz@ = a proposed key size
+ *             @const octet *ksz@ = pointer to key size table
+ *
+ * Returns:    A key size, at least as large as @sz@, or zero if no such
+ *             size is available.
+ */
+
+size_t keysz_pad(size_t sz, const octet *ksz)
+{
+  unsigned op = ksz[0]&KSZ_OPMASK;
+  unsigned wd = (ksz[0]&KSZ_16BIT) ? 2 : 1;
+  unsigned t, u, v;
+
+  ksz++;
+#define ARG(i) (wd == 1 ? ksz[i] : LOAD16(ksz + 2*i))
+  switch (op) {
+    case KSZ_ANY: return (sz);
+    case KSZ_RANGE:
+      t = ARG(1); u = ARG(2); v = ARG(3);
+      if (v) { sz += v - 1; sz -= sz%v; }
+      if (u && sz > u) return (0);
+      if (sz < t) return (t);
+      return (sz);
+    case KSZ_SET:
+      u = 0;
+      for (;;) {
+       t = ARG(0); ksz += wd; if (!t) break;
+       if (sz <= t && (!u || u > t)) u = t;
+      }
+      return (u);
+  }
+#undef ARG
+
+  assert(((void)"bad key size table", 0));
+  return (0);
+}
+
 /*----- That's all, folks -------------------------------------------------*/
index b83203b..4ad772a 100644 (file)
@@ -88,6 +88,17 @@ extern size_t keysz(size_t /*sz*/, const octet */*ksz*/);
 #define KSZ_ASSERT(pre, sz)                                            \
   assert(((void)"Bad key size for " #pre, KSZ_CHECK(pre, sz)))
 
+/* --- @keysz_pad@ --- *
+ *
+ * Arguments:  @size_t sz@ = a proposed key size
+ *             @const octet *ksz@ = pointer to key size table
+ *
+ * Returns:    A key size, at least as large as @sz@, or zero if no such
+ *             size is available.
+ */
+
+extern size_t keysz_pad(size_t /*sz*/, const octet */*ksz*/);
+
 /*----- Key size conversions ----------------------------------------------*/
 
 /* --- @keysz_fromdl@, @_fromschnorr@, @_fromif@, @_fromec@ --- *