X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a..HEAD:/symm/sha512.c diff --git a/symm/sha512.c b/symm/sha512.c index d4df182c..5c75eb8e 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 @@ -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 + +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 -------------------------------------------------*/