From 12a5df4273e7939847d7919d0c2db8b8f777fc13 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 10 May 2017 20:58:34 +0100 Subject: [PATCH] symm/sha512.[ch], etc.: Support SHA512/224 and SHA512/256. 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 | 4 ++++ symm/Makefile.am | 6 +++++- symm/sha512.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++------ symm/sha512.h | 34 ++++++++++++++++++++++++------ symm/t/sha512 | 24 +++++++++++++++++++++ symm/t/sha512-224 | 13 ++++++++++++ symm/t/sha512-256 | 13 ++++++++++++ 7 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 symm/t/sha512-224 create mode 100644 symm/t/sha512-256 diff --git a/.gitignore b/.gitignore index f90258b2..f6ad394a 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/symm/Makefile.am b/symm/Makefile.am index a15ef2e9..9d4e3f42 100644 --- a/symm/Makefile.am +++ b/symm/Makefile.am @@ -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 diff --git a/symm/sha512.c b/symm/sha512.c index 04b0a9db..ed022cac 100644 --- a/symm/sha512.c +++ b/symm/sha512.c @@ -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") diff --git a/symm/sha512.h b/symm/sha512.h index 2f3edc29..1a0de279 100644 --- a/symm/sha512.h +++ b/symm/sha512.h @@ -61,6 +61,14 @@ #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 -------------------------------------------------*/ diff --git a/symm/t/sha512 b/symm/t/sha512 index 857241f3..a894f146 100644 --- a/symm/t/sha512 +++ b/symm/t/sha512 @@ -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 index 00000000..f7cff7f9 --- /dev/null +++ b/symm/t/sha512-224 @@ -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 index 00000000..d6f63df6 --- /dev/null +++ b/symm/t/sha512-256 @@ -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; +} -- 2.11.0