/*----- 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
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] = {
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 --- */
#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
*
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
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@ --- *
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
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);
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
/* --- Generic interface --- */
#define HASHES(_) \
+ _(SHA512_224, sha512_224, "sha512/224") \
+ _(SHA512_256, sha512_256, "sha512/256") \
_(SHA384, sha384, "sha384") \
_(SHA512, sha512, "sha512")