From fb19e5ef680248830b201468161cca1facf1d175 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Thu, 21 Nov 2013 23:00:15 +0100
Subject: [PATCH] Preparations for 64-bit poly1305.

---
 ChangeLog           | 11 +++++++++++
 poly1305-internal.c | 27 ++++++++++++++++++++++-----
 poly1305.c          |  6 ------
 poly1305.h          | 31 +++++++++++++++++++++----------
 4 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 49a29bd6..19f015a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2013-11-21  Niels Möller  <nisse@lysator.liu.se>
+
+	* poly1305.h (POLY1305_DIGEST): Pass the encrypted nonce as an
+	additional argument to poly1305_digest.
+	(struct poly1305_ctx): Introduce unions, to support either 26-bit
+	or 64-bit implementation.
+
+	* poly1305-internal.c (poly1305_digest): Added s argument.
+
+	* poly1305.c (poly1305_set_s): Deleted function.
+
 2013-11-12  Niels Möller  <nisse@lysator.liu.se>
 
 	* poly1305-internal.c: New file, for poly1305 functions depending
diff --git a/poly1305-internal.c b/poly1305-internal.c
index fd179027..7b1b541f 100644
--- a/poly1305-internal.c
+++ b/poly1305-internal.c
@@ -38,6 +38,22 @@
 
 #define mul32x32_64(a,b) ((uint64_t)(a) * (b))
 
+#define r0 r.r32[0]
+#define r1 r.r32[1]
+#define r2 r.r32[2]
+#define r3 r.r32[3]
+#define r4 r.r32[4]
+#define s1 r.r32[5]
+#define s2 r.s32[0]
+#define s3 r.s32[1]
+#define s4 r.s32[2]
+
+#define h0 h.h32[0]
+#define h1 h.h32[1]
+#define h2 h.h32[2]
+#define h3 h.h32[3]
+#define h4 hh
+
 void
 poly1305_set_key(struct poly1305_ctx *ctx, const uint8_t key[16])
 {
@@ -112,7 +128,8 @@ poly1305_block (struct poly1305_ctx *ctx, const uint8_t m[16])
 
 void
 poly1305_digest (struct poly1305_ctx *ctx,
- 		 size_t length, uint8_t *digest)
+ 		 size_t length, uint8_t *digest,
+		 const uint8_t *s)
 {
   uint32_t b, nb;
   uint64_t f0,f1,f2,f3;
@@ -161,10 +178,10 @@ poly1305_digest (struct poly1305_ctx *ctx,
   ctx->h3 = (ctx->h3 & nb) | (g3 & b);
   ctx->h4 = (ctx->h4 & nb) | (g4 & b);
 
-  f0 = ((ctx->h0      ) | (ctx->h1 << 26)) + (uint64_t)LE_READ_UINT32(ctx->s);
-  f1 = ((ctx->h1 >>  6) | (ctx->h2 << 20)) + (uint64_t)LE_READ_UINT32(ctx->s+4);
-  f2 = ((ctx->h2 >> 12) | (ctx->h3 << 14)) + (uint64_t)LE_READ_UINT32(ctx->s+8);
-  f3 = ((ctx->h3 >> 18) | (ctx->h4 <<  8)) + (uint64_t)LE_READ_UINT32(ctx->s+12);
+  f0 = ((ctx->h0      ) | (ctx->h1 << 26)) + (uint64_t)LE_READ_UINT32(s);
+  f1 = ((ctx->h1 >>  6) | (ctx->h2 << 20)) + (uint64_t)LE_READ_UINT32(s+4);
+  f2 = ((ctx->h2 >> 12) | (ctx->h3 << 14)) + (uint64_t)LE_READ_UINT32(s+8);
+  f3 = ((ctx->h3 >> 18) | (ctx->h4 <<  8)) + (uint64_t)LE_READ_UINT32(s+12);
 
   LE_WRITE_UINT32(td, f0);
   f1 += (f0 >> 32);
diff --git a/poly1305.c b/poly1305.c
index 7ee7db3e..37445316 100644
--- a/poly1305.c
+++ b/poly1305.c
@@ -31,9 +31,3 @@ poly1305_set_nonce (struct poly1305_ctx *ctx, const uint8_t * nonce)
 {
   memcpy (ctx->nonce, nonce, 16);
 }
-
-void
-poly1305_set_s (struct poly1305_ctx *ctx, const uint8_t * s)
-{
-  memcpy (ctx->s, s, 16);
-}
diff --git a/poly1305.h b/poly1305.h
index db4c77f4..3f71d8b1 100644
--- a/poly1305.h
+++ b/poly1305.h
@@ -37,11 +37,23 @@ extern "C" {
 #include "nettle-types.h"
 
 struct poly1305_ctx {
-  uint32_t h0; uint32_t h1; uint32_t h2; uint32_t h3; uint32_t h4;
-  uint32_t r0; uint32_t r1; uint32_t r2; uint32_t r3; uint32_t r4;
-  uint32_t s1; uint32_t s2; uint32_t s3; uint32_t s4;
+  /* Key, 128-bit value and some cached multiples. */
+  union
+  {
+    uint32_t r32[6];
+    uint64_t r64[3];
+  } r;
+  uint32_t s32[3];
+  /* State, represented as words of 26, 32 or 64 bits, depending on
+     implementation. */
+  /* High bits, first to maintain alignment. */
+  uint32_t hh;
+  union
+  {
+    uint32_t h32[4];
+    uint64_t h64[2];
+  } h;
 
-  uint8_t s[16]; /* typically AES_k(nonce) */
   uint8_t nonce[16];
   uint8_t block[16];
   unsigned index;
@@ -53,15 +65,15 @@ struct poly1305_ctx {
 
 #define poly1305_set_key nettle_poly1305_set_key
 #define poly1305_set_nonce nettle_poly1305_set_nonce
-#define poly1305_set_s nettle_poly1305_set_s
-#define poly1305_block nettle_poly1305_round
+#define poly1305_block nettle_poly1305_block
 #define poly1305_digest nettle_poly1305_digest
 
 void poly1305_set_key(struct poly1305_ctx *ctx, const uint8_t key[16]);
 void poly1305_set_nonce (struct poly1305_ctx *ctx, const uint8_t * nonce);
-void poly1305_set_s (struct poly1305_ctx *ctx, const uint8_t *s);
 void poly1305_block (struct poly1305_ctx *ctx, const uint8_t m[16]);
-void poly1305_digest (struct poly1305_ctx *ctx, size_t length, uint8_t *digest);
+
+void poly1305_digest (struct poly1305_ctx *ctx,
+		      size_t length, uint8_t *digest, const uint8_t *s);
 
 #define POLY1305_SET_KEY(ctx, set_key, key)	\
   do {						\
@@ -85,8 +97,7 @@ void poly1305_digest (struct poly1305_ctx *ctx, size_t length, uint8_t *digest);
   do { 								\
     uint8_t _ts[16]; 						\
     (encrypt)(&(ctx)->cipher, 16, _ts, (ctx)->pctx.nonce);	\
-    poly1305_set_s(&(ctx)->pctx, _ts);				\
-    poly1305_digest (&(ctx)->pctx, (length), (digest)); 	\
+    poly1305_digest (&(ctx)->pctx, (length), (digest), _ts); 	\
     INCREMENT (16, (ctx)->pctx.nonce); 				\
     (ctx)->pctx.index = 0; 					\
   } while(0);
-- 
GitLab