progs/perftest.c: Use from Glibc syscall numbers.
[catacomb] / symm / sha512.c
index d4df182..5c75eb8 100644 (file)
@@ -36,7 +36,7 @@
 
 /*----- Main code ---------------------------------------------------------*/
 
-/* --- @sha512_compress@, @sha384_compress@ --- *
+/* --- @sha512_compress@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *sbuf@ = pointer to buffer of appropriate size
@@ -49,7 +49,9 @@
 void sha512_compress(sha512_ctx *ctx, const void *sbuf)
 {
   kludge64 a, b, c, d, e, f, g, h;
-  kludge64 buf[80];
+  kludge64 m[16];
+  const kludge64 *k;
+  const octet *p;
   int i;
 
   static const kludge64 K[80] = {
@@ -95,16 +97,9 @@ void sha512_compress(sha512_ctx *ctx, const void *sbuf)
     X64(5fcb6fab, 3ad6faec), X64(6c44198c, 4a475817)
   };
 
-  /* --- Fetch the chaining variables --- */
-
-  a = ctx->a;
-  b = ctx->b;
-  c = ctx->c;
-  d = ctx->d;
-  e = ctx->e;
-  f = ctx->f;
-  g = ctx->g;
-  h = ctx->h;
+  a  = ctx->a; b  = ctx->b; c  = ctx->c; d  = ctx->d;
+  e  = ctx->e; f  = ctx->f; g  = ctx->g; h  = ctx->h;
+  for (p = sbuf, i = 0; i < 16; i++, p += 8) LOAD64_(m[i], p);
 
   /* --- Definitions for round functions --- */
 
@@ -130,53 +125,66 @@ void sha512_compress(sha512_ctx *ctx, const void *sbuf)
 
 #define T(a, b, c, d, e, f, g, h, i) do {                              \
   kludge64 t1, t2, x;                                                  \
-  ADD64(t1, buf[i], K[i]); ADD64(t1, t1, h);                           \
+  ADD64(t1, m[i], k[i]); ADD64(t1, t1, h);                             \
   S1(x, e); ADD64(t1, t1, x); CH(x, e, f, g); ADD64(t1, t1, x);                \
   S0(t2, a); MAJ(x, a, b, c); ADD64(t2, t2, x);                                \
   ADD64(d, d, t1); ADD64(h, t1, t2);                                   \
 } while (0)
 
-  /* --- Fetch and expand the buffer contents --- */
-
-  {
-    const octet *p;
-
-    for (i = 0, p = sbuf; i < 16; i++, p += 8)
-      LOAD64_(buf[i], p);
-    for (i = 16; i < 80; i++) {
-      kludge64 x;
-      buf[i] = buf[i - 7]; s1(x, buf[i - 2]); ADD64(buf[i], buf[i], x);
-      s0(x, buf[i - 15]); ADD64(buf[i], buf[i], x);
-      ADD64(buf[i], buf[i], buf[i - 16]);
-    }
-  }
+#define M(i, i2, i7, i15) do {                                         \
+  kludge64 t;                                                          \
+  ADD64(m[i], m[i], m[i7]);                                            \
+  s1(t, m[i2]); ADD64(m[i], m[i], t);                                  \
+  s0(t, m[i15]); ADD64(m[i], m[i], t);                                 \
+} while (0)
 
   /* --- The main compression function --- */
 
-  for (i = 0; i < 80; i += 8) {
-    T(a, b, c, d, e, f, g, h, i + 0);
-    T(h, a, b, c, d, e, f, g, i + 1);
-    T(g, h, a, b, c, d, e, f, i + 2);
-    T(f, g, h, a, b, c, d, e, i + 3);
-    T(e, f, g, h, a, b, c, d, i + 4);
-    T(d, e, f, g, h, a, b, c, i + 5);
-    T(c, d, e, f, g, h, a, b, i + 6);
-    T(b, c, d, e, f, g, h, a, i + 7);
+  for (i = 0, k = K; i < 64; i += 16, k += 16) {
+    T(a, b, c, d, e, f, g, h,  0);     M( 0, 14,  9,  1);
+    T(h, a, b, c, d, e, f, g,  1);     M( 1, 15, 10,  2);
+    T(g, h, a, b, c, d, e, f,  2);     M( 2,  0, 11,  3);
+    T(f, g, h, a, b, c, d, e,  3);     M( 3,  1, 12,  4);
+    T(e, f, g, h, a, b, c, d,  4);     M( 4,  2, 13,  5);
+    T(d, e, f, g, h, a, b, c,  5);     M( 5,  3, 14,  6);
+    T(c, d, e, f, g, h, a, b,  6);     M( 6,  4, 15,  7);
+    T(b, c, d, e, f, g, h, a,  7);     M( 7,  5,  0,  8);
+    T(a, b, c, d, e, f, g, h,  8);     M( 8,  6,  1,  9);
+    T(h, a, b, c, d, e, f, g,  9);     M( 9,  7,  2, 10);
+    T(g, h, a, b, c, d, e, f, 10);     M(10,  8,  3, 11);
+    T(f, g, h, a, b, c, d, e, 11);     M(11,  9,  4, 12);
+    T(e, f, g, h, a, b, c, d, 12);     M(12, 10,  5, 13);
+    T(d, e, f, g, h, a, b, c, 13);     M(13, 11,  6, 14);
+    T(c, d, e, f, g, h, a, b, 14);     M(14, 12,  7, 15);
+    T(b, c, d, e, f, g, h, a, 15);     M(15, 13,  8,  0);
   }
 
+  T(a, b, c, d, e, f, g, h,  0);
+  T(h, a, b, c, d, e, f, g,  1);
+  T(g, h, a, b, c, d, e, f,  2);
+  T(f, g, h, a, b, c, d, e,  3);
+  T(e, f, g, h, a, b, c, d,  4);
+  T(d, e, f, g, h, a, b, c,  5);
+  T(c, d, e, f, g, h, a, b,  6);
+  T(b, c, d, e, f, g, h, a,  7);
+  T(a, b, c, d, e, f, g, h,  8);
+  T(h, a, b, c, d, e, f, g,  9);
+  T(g, h, a, b, c, d, e, f, 10);
+  T(f, g, h, a, b, c, d, e, 11);
+  T(e, f, g, h, a, b, c, d, 12);
+  T(d, e, f, g, h, a, b, c, 13);
+  T(c, d, e, f, g, h, a, b, 14);
+  T(b, c, d, e, f, g, h, a, 15);
+
   /* --- Update the chaining variables --- */
 
-  ADD64(ctx->a, ctx->a, a);
-  ADD64(ctx->b, ctx->b, b);
-  ADD64(ctx->c, ctx->c, c);
-  ADD64(ctx->d, ctx->d, d);
-  ADD64(ctx->e, ctx->e, e);
-  ADD64(ctx->f, ctx->f, f);
-  ADD64(ctx->g, ctx->g, g);
-  ADD64(ctx->h, ctx->h, h);
+  ADD64(ctx->a, ctx->a, a); ADD64(ctx->b, ctx->b, b);
+  ADD64(ctx->c, ctx->c, c); ADD64(ctx->d, ctx->d, d);
+  ADD64(ctx->e, ctx->e, e); ADD64(ctx->f, ctx->f, f);
+  ADD64(ctx->g, ctx->g, g); ADD64(ctx->h, ctx->h, h);
 }
 
-/* --- @sha512_init@, @sha384_init@ --- *
+/* --- @sha512_init@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block to initialize
  *
@@ -213,7 +221,35 @@ void sha384_init(sha512_ctx *ctx)
   ctx->nh = ctx->nl = 0;
 }
 
-/* --- @sha512_set@, @sha384_set@ --- *
+void sha512_256_init(sha512_ctx *ctx)
+{
+  SET64(ctx->a,        0x22312194, 0xfc2bf72c);
+  SET64(ctx->b,        0x9f555fa3, 0xc84c64c2);
+  SET64(ctx->c,        0x2393b86b, 0x6f53b151);
+  SET64(ctx->d,        0x96387719, 0x5940eabd);
+  SET64(ctx->e,        0x96283ee2, 0xa88effe3);
+  SET64(ctx->f,        0xbe5e1e25, 0x53863992);
+  SET64(ctx->g,        0x2b0199fc, 0x2c85b8aa);
+  SET64(ctx->h,        0x0eb72ddc, 0x81c52ca2);
+  ctx->off = 0;
+  ctx->nh = ctx->nl = 0;
+}
+
+void sha512_224_init(sha512_ctx *ctx)
+{
+  SET64(ctx->a,        0x8c3d37c8, 0x19544da2);
+  SET64(ctx->b,        0x73e19966, 0x89dcd4d6);
+  SET64(ctx->c,        0x1dfab7ae, 0x32ff9c82);
+  SET64(ctx->d,        0x679dd514, 0x582f9fcf);
+  SET64(ctx->e,        0x0f6d2b69, 0x7bd44da8);
+  SET64(ctx->f,        0x77e36f73, 0x04c48942);
+  SET64(ctx->g,        0x3f9d85a8, 0x6a1d36c8);
+  SET64(ctx->h,        0x1112e6ad, 0x91d692a1);
+  ctx->off = 0;
+  ctx->nh = ctx->nl = 0;
+}
+
+/* --- @sha512_set@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *buf@ = pointer to state buffer
@@ -239,7 +275,7 @@ void sha512_set(sha512_ctx *ctx, const void *buf, unsigned long count)
   LOAD64_(ctx->h, p + 56);
   ctx->off = 0;
   ctx->nl = U32(count);
-  ctx->nh = U32(((count & ~MASK32) >> 16) >> 16);
+  ctx->nh = U32(((count & ~(unsigned long)MASK32) >> 16) >> 16);
 }
 
 /* --- @sha512_hash@, @sha384_hash@ --- *
@@ -259,7 +295,7 @@ void sha512_hash(sha512_ctx *ctx, const void *buf, size_t sz)
   HASH_BUFFER(SHA512, sha512, ctx, buf, sz);
 }
 
-/* --- @sha512_done@, @sha384_done@ --- *
+/* --- @sha512_done@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @void *hash@ = pointer to output buffer
@@ -292,7 +328,7 @@ void sha512_done(sha512_ctx *ctx, void *hash)
   STORE64_(p + 56, ctx->h);
 }
 
-void sha384_done(sha384_ctx *ctx, void *hash)
+void sha384_done(sha512_ctx *ctx, void *hash)
 {
   octet *p = hash;
   final(ctx);
@@ -304,7 +340,27 @@ void sha384_done(sha384_ctx *ctx, void *hash)
   STORE64_(p + 40, ctx->f);
 }
 
-/* --- @sha512_state@, @sha384_state@ --- *
+void sha512_256_done(sha384_ctx *ctx, void *hash)
+{
+  octet *p = hash;
+  final(ctx);
+  STORE64_(p + 0, ctx->a);
+  STORE64_(p + 8, ctx->b);
+  STORE64_(p + 16, ctx->c);
+  STORE64_(p + 24, ctx->d);
+}
+
+void sha512_224_done(sha384_ctx *ctx, void *hash)
+{
+  octet *p = hash;
+  final(ctx);
+  STORE64_(p + 0, ctx->a);
+  STORE64_(p + 8, ctx->b);
+  STORE64_(p + 16, ctx->c);
+  STORE32 (p + 24, HI64(ctx->d));
+}
+
+/* --- @sha512_state@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context
  *             @void *state@ = pointer to buffer for current state
@@ -331,10 +387,33 @@ unsigned long sha512_state(sha512_ctx *ctx, void *state)
 
 /* --- Generic interface --- */
 
-GHASH_DEF(SHA512, sha512)
+#define HASHES(_)                                                      \
+  _(SHA512_224, sha512_224, "sha512/224")                              \
+  _(SHA512_256, sha512_256, "sha512/256")                              \
+  _(SHA384, sha384, "sha384")                                          \
+  _(SHA512, sha512, "sha512")
+
+HASHES(GHASH_DEFX)
+
+/*----- Test rig ----------------------------------------------------------*/
+
+#ifdef TEST_RIG
 
-/* --- Test code --- */
+#include <mLib/testrig.h>
+
+HASHES(HASH_VERIFYX)
+
+static const test_chunk defs[] = {
+  HASHES(HASH_TESTDEFSX)
+  { 0, 0, { 0 } }
+};
+
+int main(int argc, char *argv[])
+{
+  test_run(argc, argv, defs, SRCDIR "/t/sha512");
+  return (0);
+}
 
-HASH_TEST(SHA512, sha512)
+#endif
 
 /*----- That's all, folks -------------------------------------------------*/