symm/latinpoly.c, etc.: AEADs based on Salsa20 and ChaCha with Poly1305.
[catacomb] / symm / latinpoly.c
diff --git a/symm/latinpoly.c b/symm/latinpoly.c
new file mode 100644 (file)
index 0000000..de73025
--- /dev/null
@@ -0,0 +1,94 @@
+/* -*-c-*-
+ *
+ * AEAD schemes based on Salsa20/ChaCha and Poly1305
+ *
+ * (c) 2018 Straylight/Edgeware
+ */
+
+/*----- Licensing notice --------------------------------------------------*
+ *
+ * This file is part of Catacomb.
+ *
+ * Catacomb is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Library General Public License as published
+ * by the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Catacomb is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with Catacomb.  If not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ */
+
+/*----- Header files ------------------------------------------------------*/
+
+#include "config.h"
+
+#include <mLib/bits.h>
+#include <mLib/buf.h>
+
+#include "gaead.h"
+#include "keysz.h"
+#include "latinpoly-def.h"
+
+#include "poly1305.h"
+#include "salsa20.h"
+
+/*----- Common definitions ------------------------------------------------*/
+
+const octet
+  latinpoly_noncesz[] = { KSZ_SET, SALSA20_NONCESZ, SALSA20_IETF_NONCESZ,
+                         XSALSA20_NONCESZ, 0 },
+  latinpoly_tagsz[] = { KSZ_SET, POLY1305_TAGSZ, 0 };
+
+/* AAD handling. */
+
+void latinpoly_aadhash(gaead_aad *a, const void *h, size_t hsz)
+{
+  latinpoly_aad *aad = (latinpoly_aad *)a;
+  poly1305_hash(&aad->poly, h, hsz);
+}
+
+void latinpoly_aaddestroy(gaead_aad *a) { ; }
+
+/* --- @latinpoly_tag@ --- *
+ *
+ * Arguments:  @const poly1305_ctx *aad@ = Poly1305 context hashing AAD
+ *             @poly1305_ctx *ct@ = Poly1305 context hashing ciphertext
+ *             @void *tag@ = where to write the tag
+ *
+ * Returns:    ---
+ *
+ * Use:                Completes a Latin-dance-Poly1305 tag, combining the AAD and
+ *             ciphertext hashes, appending their lengths, and writing the
+ *             final masked hash to @tag@.  The @ct@ context is clobbered.
+ */
+
+/* Write the length of data pushed through Poly1305 as a 64-bit integer. */
+static void putlen(octet *p, const poly1305_ctx *poly)
+{
+  uint32 lo = U32((poly->count << 4) | poly->nbuf),
+    hi = U32(poly->count >> 28);
+  STORE32_L(p + 0, lo); STORE32_L(p + 4, hi);
+}
+
+void latinpoly_tag(const poly1305_ctx *aad, poly1305_ctx *ct, void *tag)
+{
+  octet b[16];
+  poly1305_ctx t;
+
+  putlen(b + 8, ct); poly1305_flushzero(ct);
+  if (!aad) memset(b, 0, 8);
+  else {
+    putlen(b + 0, aad);
+    t = *aad; poly1305_flushzero(&t); poly1305_concat(ct, &t, ct);
+  }
+  poly1305_hash(ct, b, 16); poly1305_done(ct, tag);
+}
+
+/*----- That's all, folks -------------------------------------------------*/