symm/sha512.[ch], etc.: Support SHA512/224 and SHA512/256.
authorMark Wooding <mdw@distorted.org.uk>
Wed, 10 May 2017 19:58:34 +0000 (20:58 +0100)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 14 May 2017 13:58:41 +0000 (14:58 +0100)
These are more truncated versions of SHA512 with different initial
values.  The point of the exercise is performance: SHA512 runs faster
than SHA256 on 64-bit processors (it munches twice as much data per run
through the compression function, but has only 25% more rounds).  Add
test vectors for the hash function from NIST and Wikipedia, and HMAC
tests I found under a rock.

.gitignore
symm/Makefile.am
symm/sha512.c
symm/sha512.h
symm/t/sha512
symm/t/sha512-224 [new file with mode: 0644]
symm/t/sha512-256 [new file with mode: 0644]

index f90258b..f6ad394 100644 (file)
@@ -39,4 +39,8 @@ symm/stubs.am
 /symm/safersk.c
 /symm/sha224.c
 /symm/sha384.c
+/symm/sha512-224.c
+/symm/sha512-224.h
+/symm/sha512-256.c
+/symm/sha512-256.h
 /symm/whirlpool256.c
index a15ef2e..9d4e3f4 100644 (file)
@@ -328,11 +328,15 @@ HASHES                    += sha
 
 ## The National Security Agency's `SHA-2' suite.
 HASHES                 += sha224 sha256
-HASHES                 += sha384 sha512
+HASHES                 += sha384 sha512 sha512/224 sha512/256
 STUBS_HDR              += SHA-224,sha224,sha256
 STUBS_HDR              += SHA-384,sha384,sha512
+STUBS_HDR              += SHA-512/256,sha512-256,sha512
+STUBS_HDR              += SHA-512/224,sha512-224,sha512
 STUBS_SRC              += sha224,sha256
 STUBS_SRC              += sha384,sha512
+STUBS_SRC              += sha512-256,sha512
+STUBS_SRC              += sha512-224,sha512
 
 ## Anderson and Biham's `Tiger' hash function.
 HASHES                 += tiger
index 04b0a9d..ed022ca 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
@@ -176,7 +176,7 @@ void sha512_compress(sha512_ctx *ctx, const void *sbuf)
   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 +213,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
@@ -259,7 +287,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 +320,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 +332,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
@@ -332,6 +380,8 @@ unsigned long sha512_state(sha512_ctx *ctx, void *state)
 /* --- Generic interface --- */
 
 #define HASHES(_)                                                      \
+  _(SHA512_224, sha512_224, "sha512/224")                              \
+  _(SHA512_256, sha512_256, "sha512/256")                              \
   _(SHA384, sha384, "sha384")                                          \
   _(SHA512, sha512, "sha512")
 
index 2f3edc2..1a0de27 100644 (file)
 #define SHA384_HASHSZ 48
 #define SHA384_STATESZ 64
 
+#define SHA512_256_BUFSZ 128
+#define SHA512_256_HASHSZ 32
+#define SHA512_256_STATESZ 64
+
+#define SHA512_224_BUFSZ 128
+#define SHA512_224_HASHSZ 28
+#define SHA512_224_STATESZ 64
+
 /*----- Data structures ---------------------------------------------------*/
 
 typedef struct sha512_ctx {
@@ -68,11 +76,11 @@ typedef struct sha512_ctx {
   uint32 nh, nl;                       /* Byte count so far */
   unsigned off;                                /* Offset into buffer */
   octet buf[SHA512_BUFSZ];             /* Accumulation buffer */
-} sha512_ctx, sha384_ctx;
+} sha512_ctx, sha384_ctx, sha512_256_ctx, sha512_224_ctx;
 
 /*----- Functions provided ------------------------------------------------*/
 
-/* --- @sha512_compress@, @sha384_compress@ --- *
+/* --- @sha512_compress@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *sbuf@ = pointer to buffer of appropriate size
@@ -84,8 +92,10 @@ typedef struct sha512_ctx {
 
 extern void sha512_compress(sha512_ctx */*ctx*/, const void */*sbuf*/);
 #define sha384_compress sha512_compress
+#define sha512_256_compress sha512_compress
+#define sha512_224_compress sha512_compress
 
-/* --- @sha512_init@, @sha384_init@ --- *
+/* --- @sha512_init@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block to initialize
  *
@@ -96,8 +106,10 @@ extern void sha512_compress(sha512_ctx */*ctx*/, const void */*sbuf*/);
 
 extern void sha512_init(sha512_ctx */*ctx*/);
 extern void sha384_init(sha512_ctx */*ctx*/);
+extern void sha512_256_init(sha512_ctx */*ctx*/);
+extern void sha512_224_init(sha512_ctx */*ctx*/);
 
-/* --- @sha512_set@, @sha384_set@ --- *
+/* --- @sha512_set@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *buf@ = pointer to state buffer
@@ -113,8 +125,10 @@ extern void sha384_init(sha512_ctx */*ctx*/);
 extern void sha512_set(sha512_ctx */*ctx*/, const void */*buf*/,
                       unsigned long /*count*/);
 #define sha384_set sha512_set
+#define sha512_256_set sha512_set
+#define sha512_224_set sha512_set
 
-/* --- @sha512_hash@, @sha384_hash@ --- *
+/* --- @sha512_hash@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @const void *buf@ = buffer of data to hash
@@ -129,8 +143,10 @@ extern void sha512_set(sha512_ctx */*ctx*/, const void */*buf*/,
 extern void sha512_hash(sha512_ctx */*ctx*/,
                        const void */*buf*/, size_t /*sz*/);
 #define sha384_hash sha512_hash
+#define sha512_256_hash sha512_hash
+#define sha512_224_hash sha512_hash
 
-/* --- @sha512_done@, @sha384_done@ --- *
+/* --- @sha512_done@, etc. --- *
  *
  * Arguments:  @sha512_ctx *ctx@ = pointer to context block
  *             @void *hash@ = pointer to output buffer
@@ -142,6 +158,8 @@ extern void sha512_hash(sha512_ctx */*ctx*/,
 
 extern void sha512_done(sha512_ctx */*ctx*/, void */*hash*/);
 extern void sha384_done(sha512_ctx */*ctx*/, void */*hash*/);
+extern void sha512_256_done(sha512_ctx */*ctx*/, void */*hash*/);
+extern void sha512_224_done(sha512_ctx */*ctx*/, void */*hash*/);
 
 /* --- @sha512_state@, @sha384_state@ --- *
  *
@@ -156,11 +174,15 @@ extern void sha384_done(sha512_ctx */*ctx*/, void */*hash*/);
 
 extern unsigned long sha512_state(sha512_ctx */*ctx*/, void */*state*/);
 #define sha384_state sha512_state
+#define sha512_256_state sha512_state
+#define sha512_224_state sha512_state
 
 /*----- Generic hash interface --------------------------------------------*/
 
 extern const gchash sha512;
 extern const gchash sha384;
+extern const gchash sha512_256;
+extern const gchash sha512_224;
 
 /*----- That's all, folks -------------------------------------------------*/
 
index 857241f..a894f14 100644 (file)
@@ -52,6 +52,30 @@ sha384 {
        1761336e3f7cbfe51deb137f026f89e01a448e3b1fafa64039c1464ee8732f11a5341a6f41e0c202294736ed64db1a84;
 }
 
+sha512/256 {
+  ## From Wikipedia, embarrassingly enough.
+  ## https://en.wikipedia.org/w/index.php?title=SHA-2&oldid=776962092
+  "" c672b8d1ef56ed28ab87c3622c5114069bdd3ad7b8f9737498d0c01ecef0967a;
+
+  ## From NIST.
+  abc
+       53048e2681941ef99b2e29b76b4c7dabe4c2d0c634fc6d46e0e2f13107e7af23;
+  abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu
+       3928e184fb8690f840da3988121d31be65cb9d3ef83ee6146feac861e19b563a;
+}
+
+sha512/224 {
+  ## From Wikipedia, embarrassingly enough.
+  ## https://en.wikipedia.org/w/index.php?title=SHA-2&oldid=776962092
+  "" 6ed0dd02806fa89e25de060c19d3ac86cabb87d6a0ddd05c333b84f4;
+
+  ## From NIST.
+  abc
+       4634270f707b6a54daae7530460842e20e37ed265ceee9a43e8924aa;
+  abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu
+       23fec5bb94d60b23308192640b0c453335d664734fe40e7268674af9;
+}
+
 sha512-rep {
   "1234567890" 8
        72ec1ef1124a45b047e8b7c75a932195135bb61de24ec0d1914042246e0aec3a2354e093d76f3048b456764346900cb130d2a4fd5dd16abb5e30bcb850dee843;
diff --git a/symm/t/sha512-224 b/symm/t/sha512-224
new file mode 100644 (file)
index 0000000..f7cff7f
--- /dev/null
@@ -0,0 +1,13 @@
+# HMAC sha512-224 test vectors.
+
+sha512-224-hmac {
+  ## From sci.crypt, `Test vectors HMAC-SHA-512/256 and .../224', message-id
+  ## <4d5d7e4b.10692396@news.individual.net> onwards, Wolfgang Ehrhardt, Paul
+  ## Rubin, micha8s, and Thomas Pornin.
+  "Hi There"
+       0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+       b244ba01307c0e7a8ccaad13b1067a4cf6b961fe0c6a20bda3d92039;
+  "what do ya want for nothing?"
+       4a656665
+       4a530b31a79ebcce36916546317c45f247d83241dfb818fd37254bde;
+}
diff --git a/symm/t/sha512-256 b/symm/t/sha512-256
new file mode 100644 (file)
index 0000000..d6f63df
--- /dev/null
@@ -0,0 +1,13 @@
+# HMAC sha512-256 test vectors.
+
+sha512-256-hmac {
+  ## From sci.crypt, `Test vectors HMAC-SHA-512/256 and .../224', message-id
+  ## <4d5d7e4b.10692396@news.individual.net> onwards, Wolfgang Ehrhardt, Paul
+  ## Rubin, micha8s, and Thomas Pornin.
+  "Hi There"
+       0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
+       9f9126c3d9c3c330d760425ca8a217e31feae31bfe70196ff81642b868402eab;
+  "what do ya want for nothing?"
+       4a656665
+       6df7b24630d5ccb2ee335407081a87188c221489768fa2020513b2d593359456;
+}