Mercurial > hg > ucis.core
diff NaCl/crypto_hash/sha512.cs @ 72:b7d981ccd434
NaCl: improved sha512 implementation
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 02 Nov 2013 15:59:51 +0100 |
parents | 7e9d1cfcc562 |
children |
line wrap: on
line diff
--- a/NaCl/crypto_hash/sha512.cs Fri Nov 01 00:07:36 2013 +0100 +++ b/NaCl/crypto_hash/sha512.cs Sat Nov 02 15:59:51 2013 +0100 @@ -4,75 +4,79 @@ public static class sha512 { public static int BYTES = 64; -/* static Byte[] iv = new Byte[64] { - 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, - 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, - 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, - 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, - 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, - 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, - 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, - 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 -};*/ - public static unsafe void crypto_hash(Byte[] outv, Byte[] inv, int inlen) { if (outv.Length < 64) throw new ArgumentException("outv.Length < 64"); if (inv.Length < inlen) throw new ArgumentException("inv.Length < inlen"); fixed (Byte* outp = outv, inp = inv) crypto_hash(outp, inp, (UInt64)inlen); } public static unsafe void crypto_hash(Byte* outp, Byte* inp, UInt64 inlen) { -// Byte[] h = new Byte[64]; - Byte[] padded = new Byte[256]; - UInt64 i; - UInt64 bytes = inlen; - Byte[] h = new Byte[64] { - 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, - 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, - 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, - 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, - 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, - 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, - 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, - 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 - }; + sha512state state = new sha512state(); + state.init(); + state.process(inp, (int)inlen); + state.finish(outp); + } -// for (i = 0; i < 64; ++i) h[i] = iv[i]; - - fixed (Byte* hp = h) crypto_hashblocks.sha512.crypto_hashblocks(hp, inp, inlen); - inp += inlen; - inlen &= 127; - inp -= inlen; - - for (i = 0; i < inlen; ++i) padded[i] = inp[i]; - padded[inlen] = 0x80; + public unsafe struct sha512state { + fixed UInt64 state[8]; + fixed Byte input[128]; + int offset; + int length; - if (inlen < 112) { - for (i = inlen + 1; i < 119; ++i) padded[i] = 0; - padded[119] = (Byte)(bytes >> 61); - padded[120] = (Byte)(bytes >> 53); - padded[121] = (Byte)(bytes >> 45); - padded[122] = (Byte)(bytes >> 37); - padded[123] = (Byte)(bytes >> 29); - padded[124] = (Byte)(bytes >> 21); - padded[125] = (Byte)(bytes >> 13); - padded[126] = (Byte)(bytes >> 5); - padded[127] = (Byte)(bytes << 3); - fixed (Byte* hp = h, paddedp = padded) crypto_hashblocks.sha512.crypto_hashblocks(hp, paddedp, 128); - } else { - for (i = inlen + 1; i < 247; ++i) padded[i] = 0; - padded[247] = (Byte)(bytes >> 61); - padded[248] = (Byte)(bytes >> 53); - padded[249] = (Byte)(bytes >> 45); - padded[250] = (Byte)(bytes >> 37); - padded[251] = (Byte)(bytes >> 29); - padded[252] = (Byte)(bytes >> 21); - padded[253] = (Byte)(bytes >> 13); - padded[254] = (Byte)(bytes >> 5); - padded[255] = (Byte)(bytes << 3); - fixed (Byte* hp = h, paddedp = padded) crypto_hashblocks.sha512.crypto_hashblocks(hp, paddedp, 256); + public unsafe void init() { + fixed (UInt64* s = state) { + s[0] = 0x6a09e667f3bcc908; s[1] = 0xbb67ae8584caa73b; s[2] = 0x3c6ef372fe94f82b; s[3] = 0xa54ff53a5f1d36f1; + s[4] = 0x510e527fade682d1; s[5] = 0x9b05688c2b3e6c1f; s[6] = 0x1f83d9abfb41bd6b; s[7] = 0x5be0cd19137e2179; + } + offset = 0; + length = 0; } - - for (i = 0; i < 64; ++i) outp[i] = h[i]; + public unsafe void process(Byte* inp, int inlen) { + fixed (sha512state* pthis = &this) { + length += inlen; + if (offset > 0) { + int blen = 128 - offset; + if (blen > inlen) blen = inlen; + for (int i = 0; i < blen; i++) pthis->input[offset++] = *inp++; + inlen -= blen; + } + if (offset == 128) { + crypto_hashblocks.sha512.crypto_hashblocks(pthis->state, pthis->input, (UInt64)offset); + offset = 0; + } + if (inlen >= 128) { + crypto_hashblocks.sha512.crypto_hashblocks(pthis->state, inp, (UInt64)inlen); + inp += inlen; + inlen &= 127; + inp -= inlen; + } + if (inlen > 0) { + for (int i = 0; i < inlen; i++) pthis->input[offset++] = *inp++; + } + } + } + public unsafe void finish(Byte* outp) { + fixed (sha512state* s = &this) { + s->input[offset++] = 0x80; + if (offset > 112) { + for (int i = offset; i < 128; i++) s->input[i] = 0; + crypto_hashblocks.sha512.crypto_hashblocks(s->state, s->input, 128); + offset = 0; + } + for (int i = offset; i < 119; i++) s->input[i] = 0; + UInt64 bytes = (UInt64)length; + s->input[119] = (Byte)(bytes >> 61); + s->input[120] = (Byte)(bytes >> 53); + s->input[121] = (Byte)(bytes >> 45); + s->input[122] = (Byte)(bytes >> 37); + s->input[123] = (Byte)(bytes >> 29); + s->input[124] = (Byte)(bytes >> 21); + s->input[125] = (Byte)(bytes >> 13); + s->input[126] = (Byte)(bytes >> 5); + s->input[127] = (Byte)(bytes << 3); + crypto_hashblocks.sha512.crypto_hashblocks(s->state, s->input, 128); + crypto_hashblocks.sha512.crypto_hashblocks_state_pack(outp, s->state); + } + } } } }