ref: 515b8e89c1a6c0859eaefbf7835a4e6497a57e0b
parent: f16bf0e4f8dd5f23b41cfbfa6c24fd0ab79e6dad
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jun 3 18:27:25 EDT 2014
Add support for sha512.
--- a/libcryptohash/Makefile
+++ b/libcryptohash/Makefile
@@ -3,8 +3,7 @@
md5.myr \
sha1.myr \
sha256.myr \
- # sha256.myr \
- # sha512.myr \
+ sha512.myr \
# sha3.myr \
include config.mk
--- /dev/null
+++ b/libcryptohash/sha512.myr
@@ -1,0 +1,400 @@
+use std
+
+pkg cryptohash =
+ type sha512
+
+ const sha512 : (data : byte[:] -> byte[64])
+ const sha512init : (st : sha512# -> void)
+ const sha512add : (st : sha512#, data : byte[:] -> void)
+ const sha512fin : (st : sha512# -> byte[64])
+;;
+
+
+type sha512 = struct
+ x : uint64[8]
+ tail : byte[128]
+ msglen : uint64
+;;
+
+const sha512 = {data
+ var st
+
+ sha512init(&st)
+ sha512add(&st, data)
+ -> sha512fin(&st)
+}
+
+const sha512init = {st
+ st.x[0] = 0x6a09e667f3bcc908ul
+ st.x[1] = 0xbb67ae8584caa73bul
+ st.x[2] = 0x3c6ef372fe94f82bul
+ st.x[3] = 0xa54ff53a5f1d36f1ul
+ st.x[4] = 0x510e527fade682d1ul
+ st.x[5] = 0x9b05688c2b3e6c1ful
+ st.x[6] = 0x1f83d9abfb41bd6bul
+ st.x[7] = 0x5be0cd19137e2179ul
+ st.msglen = 0
+}
+
+const sha512add = {st, data
+ var n, ntail
+
+ ntail = st.msglen % 128
+ st.msglen += data.len
+ if ntail > 0
+ n = 128 - ntail
+ std.slcp(st.tail[n:], data[:n])
+ data = data[n:]
+ step(st.x[:], st.tail[:])
+ ;;
+
+ while data.len >= 128
+ step(st.x[:], data[:128])
+ data = data[128:]
+ ;;
+
+ ntail = st.msglen % 128
+ std.slcp(st.tail[:ntail], data)
+}
+
+const sha512fin = {st
+ var r : byte[64]
+
+ tail(st.x[:], st.msglen, st.tail[:])
+
+ pack(r[ 0: 8], st.x[0])
+ pack(r[ 8:16], st.x[1])
+ pack(r[16:24], st.x[2])
+ pack(r[24:32], st.x[3])
+ pack(r[32:40], st.x[4])
+ pack(r[40:48], st.x[5])
+ pack(r[48:56], st.x[6])
+ pack(r[56:64], st.x[7])
+ -> r
+}
+
+const tail = {x, msglen, tail
+ var ntail
+
+ /* append first padding block */
+ ntail = msglen % 128
+ tail[ntail++] = 0x80
+ std.slfill(tail[ntail:], 0)
+ if 128 - ntail < 16
+ step(x, tail)
+ std.slfill(tail, 0)
+ ;;
+
+ /* append size block */
+ tail[120] = ((msglen * 8) >> 56) castto(byte)
+ tail[121] = ((msglen * 8) >> 48) castto(byte)
+ tail[122] = ((msglen * 8) >> 40) castto(byte)
+ tail[123] = ((msglen * 8) >> 32) castto(byte)
+ tail[124] = ((msglen * 8) >> 24) castto(byte)
+ tail[125] = ((msglen * 8) >> 16) castto(byte)
+ tail[126] = ((msglen * 8) >> 8) castto(byte)
+ tail[127] = ((msglen * 8) >> 0) castto(byte)
+ step(x, tail)
+}
+
+const step = {x : uint64[:], msg
+ var a, b, c, d, e, f, g, h
+ var s00, s01, s02, s03, s04, s05, s06, s07
+ var s08, s09, s10, s11, s12, s13, s14, s15
+ var s16, s17, s18, s19, s20, s21, s22, s23
+ var s24, s25, s26, s27, s28, s29, s30, s31
+ var s32, s33, s34, s35, s36, s37, s38, s39
+ var s40, s41, s42, s43, s44, s45, s46, s47
+ var s48, s49, s50, s51, s52, s53, s54, s55
+ var s56, s57, s58, s59, s60, s61, s62, s63
+ var s64, s65, s66, s67, s68, s69, s70, s71
+ var s72, s73, s74, s75, s76, s77, s78, s79
+
+ a = x[0]
+ b = x[1]
+ c = x[2]
+ d = x[3]
+ e = x[4]
+ f = x[5]
+ g = x[6]
+ h = x[7]
+
+ s00 = unpack(msg[ 0: 8])
+ s01 = unpack(msg[ 8: 16])
+ s02 = unpack(msg[ 16: 24])
+ s03 = unpack(msg[ 24: 32])
+ s04 = unpack(msg[ 32: 40])
+ s05 = unpack(msg[ 40: 48])
+ s06 = unpack(msg[ 48: 56])
+ s07 = unpack(msg[ 56: 64])
+ s08 = unpack(msg[ 64: 72])
+ s09 = unpack(msg[ 72: 80])
+ s10 = unpack(msg[ 80: 88])
+ s11 = unpack(msg[ 88: 96])
+ s12 = unpack(msg[ 96:104])
+ s13 = unpack(msg[104:112])
+ s14 = unpack(msg[112:120])
+ s15 = unpack(msg[120:128])
+
+ s16 = s00 + s09 + (((s01 << 63) | (s01 >> 1))^((s01 << 56) | (s01 >> 8))^(s01 >> 7)) + (((s14 << 45) | (s14 >> 19))^((s14 << 3) | (s14 >> 61))^(s14 >> 6))
+ s17 = s01 + s10 + (((s02 << 63) | (s02 >> 1))^((s02 << 56) | (s02 >> 8))^(s02 >> 7)) + (((s15 << 45) | (s15 >> 19))^((s15 << 3) | (s15 >> 61))^(s15 >> 6))
+ s18 = s02 + s11 + (((s03 << 63) | (s03 >> 1))^((s03 << 56) | (s03 >> 8))^(s03 >> 7)) + (((s16 << 45) | (s16 >> 19))^((s16 << 3) | (s16 >> 61))^(s16 >> 6))
+ s19 = s03 + s12 + (((s04 << 63) | (s04 >> 1))^((s04 << 56) | (s04 >> 8))^(s04 >> 7)) + (((s17 << 45) | (s17 >> 19))^((s17 << 3) | (s17 >> 61))^(s17 >> 6))
+ s20 = s04 + s13 + (((s05 << 63) | (s05 >> 1))^((s05 << 56) | (s05 >> 8))^(s05 >> 7)) + (((s18 << 45) | (s18 >> 19))^((s18 << 3) | (s18 >> 61))^(s18 >> 6))
+ s21 = s05 + s14 + (((s06 << 63) | (s06 >> 1))^((s06 << 56) | (s06 >> 8))^(s06 >> 7)) + (((s19 << 45) | (s19 >> 19))^((s19 << 3) | (s19 >> 61))^(s19 >> 6))
+ s22 = s06 + s15 + (((s07 << 63) | (s07 >> 1))^((s07 << 56) | (s07 >> 8))^(s07 >> 7)) + (((s20 << 45) | (s20 >> 19))^((s20 << 3) | (s20 >> 61))^(s20 >> 6))
+ s23 = s07 + s16 + (((s08 << 63) | (s08 >> 1))^((s08 << 56) | (s08 >> 8))^(s08 >> 7)) + (((s21 << 45) | (s21 >> 19))^((s21 << 3) | (s21 >> 61))^(s21 >> 6))
+ s24 = s08 + s17 + (((s09 << 63) | (s09 >> 1))^((s09 << 56) | (s09 >> 8))^(s09 >> 7)) + (((s22 << 45) | (s22 >> 19))^((s22 << 3) | (s22 >> 61))^(s22 >> 6))
+ s25 = s09 + s18 + (((s10 << 63) | (s10 >> 1))^((s10 << 56) | (s10 >> 8))^(s10 >> 7)) + (((s23 << 45) | (s23 >> 19))^((s23 << 3) | (s23 >> 61))^(s23 >> 6))
+ s26 = s10 + s19 + (((s11 << 63) | (s11 >> 1))^((s11 << 56) | (s11 >> 8))^(s11 >> 7)) + (((s24 << 45) | (s24 >> 19))^((s24 << 3) | (s24 >> 61))^(s24 >> 6))
+ s27 = s11 + s20 + (((s12 << 63) | (s12 >> 1))^((s12 << 56) | (s12 >> 8))^(s12 >> 7)) + (((s25 << 45) | (s25 >> 19))^((s25 << 3) | (s25 >> 61))^(s25 >> 6))
+ s28 = s12 + s21 + (((s13 << 63) | (s13 >> 1))^((s13 << 56) | (s13 >> 8))^(s13 >> 7)) + (((s26 << 45) | (s26 >> 19))^((s26 << 3) | (s26 >> 61))^(s26 >> 6))
+ s29 = s13 + s22 + (((s14 << 63) | (s14 >> 1))^((s14 << 56) | (s14 >> 8))^(s14 >> 7)) + (((s27 << 45) | (s27 >> 19))^((s27 << 3) | (s27 >> 61))^(s27 >> 6))
+ s30 = s14 + s23 + (((s15 << 63) | (s15 >> 1))^((s15 << 56) | (s15 >> 8))^(s15 >> 7)) + (((s28 << 45) | (s28 >> 19))^((s28 << 3) | (s28 >> 61))^(s28 >> 6))
+ s31 = s15 + s24 + (((s16 << 63) | (s16 >> 1))^((s16 << 56) | (s16 >> 8))^(s16 >> 7)) + (((s29 << 45) | (s29 >> 19))^((s29 << 3) | (s29 >> 61))^(s29 >> 6))
+ s32 = s16 + s25 + (((s17 << 63) | (s17 >> 1))^((s17 << 56) | (s17 >> 8))^(s17 >> 7)) + (((s30 << 45) | (s30 >> 19))^((s30 << 3) | (s30 >> 61))^(s30 >> 6))
+ s33 = s17 + s26 + (((s18 << 63) | (s18 >> 1))^((s18 << 56) | (s18 >> 8))^(s18 >> 7)) + (((s31 << 45) | (s31 >> 19))^((s31 << 3) | (s31 >> 61))^(s31 >> 6))
+ s34 = s18 + s27 + (((s19 << 63) | (s19 >> 1))^((s19 << 56) | (s19 >> 8))^(s19 >> 7)) + (((s32 << 45) | (s32 >> 19))^((s32 << 3) | (s32 >> 61))^(s32 >> 6))
+ s35 = s19 + s28 + (((s20 << 63) | (s20 >> 1))^((s20 << 56) | (s20 >> 8))^(s20 >> 7)) + (((s33 << 45) | (s33 >> 19))^((s33 << 3) | (s33 >> 61))^(s33 >> 6))
+ s36 = s20 + s29 + (((s21 << 63) | (s21 >> 1))^((s21 << 56) | (s21 >> 8))^(s21 >> 7)) + (((s34 << 45) | (s34 >> 19))^((s34 << 3) | (s34 >> 61))^(s34 >> 6))
+ s37 = s21 + s30 + (((s22 << 63) | (s22 >> 1))^((s22 << 56) | (s22 >> 8))^(s22 >> 7)) + (((s35 << 45) | (s35 >> 19))^((s35 << 3) | (s35 >> 61))^(s35 >> 6))
+ s38 = s22 + s31 + (((s23 << 63) | (s23 >> 1))^((s23 << 56) | (s23 >> 8))^(s23 >> 7)) + (((s36 << 45) | (s36 >> 19))^((s36 << 3) | (s36 >> 61))^(s36 >> 6))
+ s39 = s23 + s32 + (((s24 << 63) | (s24 >> 1))^((s24 << 56) | (s24 >> 8))^(s24 >> 7)) + (((s37 << 45) | (s37 >> 19))^((s37 << 3) | (s37 >> 61))^(s37 >> 6))
+ s40 = s24 + s33 + (((s25 << 63) | (s25 >> 1))^((s25 << 56) | (s25 >> 8))^(s25 >> 7)) + (((s38 << 45) | (s38 >> 19))^((s38 << 3) | (s38 >> 61))^(s38 >> 6))
+ s41 = s25 + s34 + (((s26 << 63) | (s26 >> 1))^((s26 << 56) | (s26 >> 8))^(s26 >> 7)) + (((s39 << 45) | (s39 >> 19))^((s39 << 3) | (s39 >> 61))^(s39 >> 6))
+ s42 = s26 + s35 + (((s27 << 63) | (s27 >> 1))^((s27 << 56) | (s27 >> 8))^(s27 >> 7)) + (((s40 << 45) | (s40 >> 19))^((s40 << 3) | (s40 >> 61))^(s40 >> 6))
+ s43 = s27 + s36 + (((s28 << 63) | (s28 >> 1))^((s28 << 56) | (s28 >> 8))^(s28 >> 7)) + (((s41 << 45) | (s41 >> 19))^((s41 << 3) | (s41 >> 61))^(s41 >> 6))
+ s44 = s28 + s37 + (((s29 << 63) | (s29 >> 1))^((s29 << 56) | (s29 >> 8))^(s29 >> 7)) + (((s42 << 45) | (s42 >> 19))^((s42 << 3) | (s42 >> 61))^(s42 >> 6))
+ s45 = s29 + s38 + (((s30 << 63) | (s30 >> 1))^((s30 << 56) | (s30 >> 8))^(s30 >> 7)) + (((s43 << 45) | (s43 >> 19))^((s43 << 3) | (s43 >> 61))^(s43 >> 6))
+ s46 = s30 + s39 + (((s31 << 63) | (s31 >> 1))^((s31 << 56) | (s31 >> 8))^(s31 >> 7)) + (((s44 << 45) | (s44 >> 19))^((s44 << 3) | (s44 >> 61))^(s44 >> 6))
+ s47 = s31 + s40 + (((s32 << 63) | (s32 >> 1))^((s32 << 56) | (s32 >> 8))^(s32 >> 7)) + (((s45 << 45) | (s45 >> 19))^((s45 << 3) | (s45 >> 61))^(s45 >> 6))
+ s48 = s32 + s41 + (((s33 << 63) | (s33 >> 1))^((s33 << 56) | (s33 >> 8))^(s33 >> 7)) + (((s46 << 45) | (s46 >> 19))^((s46 << 3) | (s46 >> 61))^(s46 >> 6))
+ s49 = s33 + s42 + (((s34 << 63) | (s34 >> 1))^((s34 << 56) | (s34 >> 8))^(s34 >> 7)) + (((s47 << 45) | (s47 >> 19))^((s47 << 3) | (s47 >> 61))^(s47 >> 6))
+ s50 = s34 + s43 + (((s35 << 63) | (s35 >> 1))^((s35 << 56) | (s35 >> 8))^(s35 >> 7)) + (((s48 << 45) | (s48 >> 19))^((s48 << 3) | (s48 >> 61))^(s48 >> 6))
+ s51 = s35 + s44 + (((s36 << 63) | (s36 >> 1))^((s36 << 56) | (s36 >> 8))^(s36 >> 7)) + (((s49 << 45) | (s49 >> 19))^((s49 << 3) | (s49 >> 61))^(s49 >> 6))
+ s52 = s36 + s45 + (((s37 << 63) | (s37 >> 1))^((s37 << 56) | (s37 >> 8))^(s37 >> 7)) + (((s50 << 45) | (s50 >> 19))^((s50 << 3) | (s50 >> 61))^(s50 >> 6))
+ s53 = s37 + s46 + (((s38 << 63) | (s38 >> 1))^((s38 << 56) | (s38 >> 8))^(s38 >> 7)) + (((s51 << 45) | (s51 >> 19))^((s51 << 3) | (s51 >> 61))^(s51 >> 6))
+ s54 = s38 + s47 + (((s39 << 63) | (s39 >> 1))^((s39 << 56) | (s39 >> 8))^(s39 >> 7)) + (((s52 << 45) | (s52 >> 19))^((s52 << 3) | (s52 >> 61))^(s52 >> 6))
+ s55 = s39 + s48 + (((s40 << 63) | (s40 >> 1))^((s40 << 56) | (s40 >> 8))^(s40 >> 7)) + (((s53 << 45) | (s53 >> 19))^((s53 << 3) | (s53 >> 61))^(s53 >> 6))
+ s56 = s40 + s49 + (((s41 << 63) | (s41 >> 1))^((s41 << 56) | (s41 >> 8))^(s41 >> 7)) + (((s54 << 45) | (s54 >> 19))^((s54 << 3) | (s54 >> 61))^(s54 >> 6))
+ s57 = s41 + s50 + (((s42 << 63) | (s42 >> 1))^((s42 << 56) | (s42 >> 8))^(s42 >> 7)) + (((s55 << 45) | (s55 >> 19))^((s55 << 3) | (s55 >> 61))^(s55 >> 6))
+ s58 = s42 + s51 + (((s43 << 63) | (s43 >> 1))^((s43 << 56) | (s43 >> 8))^(s43 >> 7)) + (((s56 << 45) | (s56 >> 19))^((s56 << 3) | (s56 >> 61))^(s56 >> 6))
+ s59 = s43 + s52 + (((s44 << 63) | (s44 >> 1))^((s44 << 56) | (s44 >> 8))^(s44 >> 7)) + (((s57 << 45) | (s57 >> 19))^((s57 << 3) | (s57 >> 61))^(s57 >> 6))
+ s60 = s44 + s53 + (((s45 << 63) | (s45 >> 1))^((s45 << 56) | (s45 >> 8))^(s45 >> 7)) + (((s58 << 45) | (s58 >> 19))^((s58 << 3) | (s58 >> 61))^(s58 >> 6))
+ s61 = s45 + s54 + (((s46 << 63) | (s46 >> 1))^((s46 << 56) | (s46 >> 8))^(s46 >> 7)) + (((s59 << 45) | (s59 >> 19))^((s59 << 3) | (s59 >> 61))^(s59 >> 6))
+ s62 = s46 + s55 + (((s47 << 63) | (s47 >> 1))^((s47 << 56) | (s47 >> 8))^(s47 >> 7)) + (((s60 << 45) | (s60 >> 19))^((s60 << 3) | (s60 >> 61))^(s60 >> 6))
+ s63 = s47 + s56 + (((s48 << 63) | (s48 >> 1))^((s48 << 56) | (s48 >> 8))^(s48 >> 7)) + (((s61 << 45) | (s61 >> 19))^((s61 << 3) | (s61 >> 61))^(s61 >> 6))
+ s64 = s48 + s57 + (((s49 << 63) | (s49 >> 1))^((s49 << 56) | (s49 >> 8))^(s49 >> 7)) + (((s62 << 45) | (s62 >> 19))^((s62 << 3) | (s62 >> 61))^(s62 >> 6))
+ s65 = s49 + s58 + (((s50 << 63) | (s50 >> 1))^((s50 << 56) | (s50 >> 8))^(s50 >> 7)) + (((s63 << 45) | (s63 >> 19))^((s63 << 3) | (s63 >> 61))^(s63 >> 6))
+ s66 = s50 + s59 + (((s51 << 63) | (s51 >> 1))^((s51 << 56) | (s51 >> 8))^(s51 >> 7)) + (((s64 << 45) | (s64 >> 19))^((s64 << 3) | (s64 >> 61))^(s64 >> 6))
+ s67 = s51 + s60 + (((s52 << 63) | (s52 >> 1))^((s52 << 56) | (s52 >> 8))^(s52 >> 7)) + (((s65 << 45) | (s65 >> 19))^((s65 << 3) | (s65 >> 61))^(s65 >> 6))
+ s68 = s52 + s61 + (((s53 << 63) | (s53 >> 1))^((s53 << 56) | (s53 >> 8))^(s53 >> 7)) + (((s66 << 45) | (s66 >> 19))^((s66 << 3) | (s66 >> 61))^(s66 >> 6))
+ s69 = s53 + s62 + (((s54 << 63) | (s54 >> 1))^((s54 << 56) | (s54 >> 8))^(s54 >> 7)) + (((s67 << 45) | (s67 >> 19))^((s67 << 3) | (s67 >> 61))^(s67 >> 6))
+ s70 = s54 + s63 + (((s55 << 63) | (s55 >> 1))^((s55 << 56) | (s55 >> 8))^(s55 >> 7)) + (((s68 << 45) | (s68 >> 19))^((s68 << 3) | (s68 >> 61))^(s68 >> 6))
+ s71 = s55 + s64 + (((s56 << 63) | (s56 >> 1))^((s56 << 56) | (s56 >> 8))^(s56 >> 7)) + (((s69 << 45) | (s69 >> 19))^((s69 << 3) | (s69 >> 61))^(s69 >> 6))
+ s72 = s56 + s65 + (((s57 << 63) | (s57 >> 1))^((s57 << 56) | (s57 >> 8))^(s57 >> 7)) + (((s70 << 45) | (s70 >> 19))^((s70 << 3) | (s70 >> 61))^(s70 >> 6))
+ s73 = s57 + s66 + (((s58 << 63) | (s58 >> 1))^((s58 << 56) | (s58 >> 8))^(s58 >> 7)) + (((s71 << 45) | (s71 >> 19))^((s71 << 3) | (s71 >> 61))^(s71 >> 6))
+ s74 = s58 + s67 + (((s59 << 63) | (s59 >> 1))^((s59 << 56) | (s59 >> 8))^(s59 >> 7)) + (((s72 << 45) | (s72 >> 19))^((s72 << 3) | (s72 >> 61))^(s72 >> 6))
+ s75 = s59 + s68 + (((s60 << 63) | (s60 >> 1))^((s60 << 56) | (s60 >> 8))^(s60 >> 7)) + (((s73 << 45) | (s73 >> 19))^((s73 << 3) | (s73 >> 61))^(s73 >> 6))
+ s76 = s60 + s69 + (((s61 << 63) | (s61 >> 1))^((s61 << 56) | (s61 >> 8))^(s61 >> 7)) + (((s74 << 45) | (s74 >> 19))^((s74 << 3) | (s74 >> 61))^(s74 >> 6))
+ s77 = s61 + s70 + (((s62 << 63) | (s62 >> 1))^((s62 << 56) | (s62 >> 8))^(s62 >> 7)) + (((s75 << 45) | (s75 >> 19))^((s75 << 3) | (s75 >> 61))^(s75 >> 6))
+ s78 = s62 + s71 + (((s63 << 63) | (s63 >> 1))^((s63 << 56) | (s63 >> 8))^(s63 >> 7)) + (((s76 << 45) | (s76 >> 19))^((s76 << 3) | (s76 >> 61))^(s76 >> 6))
+ s79 = s63 + s72 + (((s64 << 63) | (s64 >> 1))^((s64 << 56) | (s64 >> 8))^(s64 >> 7)) + (((s77 << 45) | (s77 >> 19))^((s77 << 3) | (s77 >> 61))^(s77 >> 6))
+
+
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x428a2f98d728ae22ul + s00
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x7137449123ef65cdul + s01
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb5c0fbcfec4d3b2ful + s02
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xe9b5dba58189dbbcul + s03
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x3956c25bf348b538ul + s04
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x59f111f1b605d019ul + s05
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x923f82a4af194f9bul + s06
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xab1c5ed5da6d8118ul + s07
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xd807aa98a3030242ul + s08
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x12835b0145706fbeul + s09
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x243185be4ee4b28cul + s10
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x550c7dc3d5ffb4e2ul + s11
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x72be5d74f27b896ful + s12
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x80deb1fe3b1696b1ul + s13
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x9bdc06a725c71235ul + s14
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc19bf174cf692694ul + s15
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xe49b69c19ef14ad2ul + s16
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xefbe4786384f25e3ul + s17
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x0fc19dc68b8cd5b5ul + s18
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x240ca1cc77ac9c65ul + s19
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x2de92c6f592b0275ul + s20
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4a7484aa6ea6e483ul + s21
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5cb0a9dcbd41fbd4ul + s22
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x76f988da831153b5ul + s23
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x983e5152ee66dfabul + s24
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa831c66d2db43210ul + s25
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xb00327c898fb213ful + s26
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xbf597fc7beef0ee4ul + s27
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xc6e00bf33da88fc2ul + s28
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd5a79147930aa725ul + s29
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x06ca6351e003826ful + s30
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x142929670a0e6e70ul + s31
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x27b70a8546d22ffcul + s32
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x2e1b21385c26c926ul + s33
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x4d2c6dfc5ac42aedul + s34
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x53380d139d95b3dful + s35
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x650a73548baf63deul + s36
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x766a0abb3c77b2a8ul + s37
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x81c2c92e47edaee6ul + s38
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x92722c851482353bul + s39
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xa2bfe8a14cf10364ul + s40
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xa81a664bbc423001ul + s41
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xc24b8b70d0f89791ul + s42
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xc76c51a30654be30ul + s43
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0xd192e819d6ef5218ul + s44
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xd69906245565a910ul + s45
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xf40e35855771202aul + s46
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x106aa07032bbd1b8ul + s47
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x19a4c116b8d2d0c8ul + s48
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x1e376c085141ab53ul + s49
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x2748774cdf8eeb99ul + s50
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x34b0bcb5e19b48a8ul + s51
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x391c0cb3c5c95a63ul + s52
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x4ed8aa4ae3418acbul + s53
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5b9cca4f7763e373ul + s54
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x682e6ff3d6b2b8a3ul + s55
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x748f82ee5defb2fcul + s56
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x78a5636f43172f60ul + s57
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x84c87814a1f0ab72ul + s58
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x8cc702081a6439ecul + s59
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x90befffa23631e28ul + s60
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0xa4506cebde82bde9ul + s61
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0xbef9a3f7b2c67915ul + s62
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0xc67178f2e372532bul + s63
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0xca273eceea26619cul + s64
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0xd186b8c721c0c207ul + s65
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0xeada7dd6cde0eb1eul + s66
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0xf57d4f7fee6ed178ul + s67
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x06f067aa72176fbaul + s68
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x0a637dc5a2c898a6ul + s69
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x113f9804bef90daeul + s70
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x1b710b35131c471bul + s71
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+ h += (((e << 50) | (e >> 14)) ^ ((e << (64 - 18)) | (e >> 18)) ^ ((e << 23) | (e >> 41))) + (g ^ (e & (f ^ g))) + 0x28db77f523047d84ul + s72
+ d += h; h += (((a << 36) | (a >> 28)) ^ ((a << (64 - 34)) | (a >> 34)) ^ ((a << 25) | (a >> 39))) + ((a & (b | c)) | (b & c));
+ g += (((d << 50) | (d >> 14)) ^ ((d << (64 - 18)) | (d >> 18)) ^ ((d << 23) | (d >> 41))) + (f ^ (d & (e ^ f))) + 0x32caab7b40c72493ul + s73
+ c += g; g += (((h << 36) | (h >> 28)) ^ ((h << (64 - 34)) | (h >> 34)) ^ ((h << 25) | (h >> 39))) + ((h & (a | b)) | (a & b));
+ f += (((c << 50) | (c >> 14)) ^ ((c << (64 - 18)) | (c >> 18)) ^ ((c << 23) | (c >> 41))) + (e ^ (c & (d ^ e))) + 0x3c9ebe0a15c9bebcul + s74
+ b += f; f += (((g << 36) | (g >> 28)) ^ ((g << (64 - 34)) | (g >> 34)) ^ ((g << 25) | (g >> 39))) + ((g & (h | a)) | (h & a));
+ e += (((b << 50) | (b >> 14)) ^ ((b << (64 - 18)) | (b >> 18)) ^ ((b << 23) | (b >> 41))) + (d ^ (b & (c ^ d))) + 0x431d67c49c100d4cul + s75
+ a += e; e += (((f << 36) | (f >> 28)) ^ ((f << (64 - 34)) | (f >> 34)) ^ ((f << 25) | (f >> 39))) + ((f & (g | h)) | (g & h));
+ d += (((a << 50) | (a >> 14)) ^ ((a << (64 - 18)) | (a >> 18)) ^ ((a << 23) | (a >> 41))) + (c ^ (a & (b ^ c))) + 0x4cc5d4becb3e42b6ul + s76
+ h += d; d += (((e << 36) | (e >> 28)) ^ ((e << (64 - 34)) | (e >> 34)) ^ ((e << 25) | (e >> 39))) + ((e & (f | g)) | (f & g));
+ c += (((h << 50) | (h >> 14)) ^ ((h << (64 - 18)) | (h >> 18)) ^ ((h << 23) | (h >> 41))) + (b ^ (h & (a ^ b))) + 0x597f299cfc657e2aul + s77
+ g += c; c += (((d << 36) | (d >> 28)) ^ ((d << (64 - 34)) | (d >> 34)) ^ ((d << 25) | (d >> 39))) + ((d & (e | f)) | (e & f));
+ b += (((g << 50) | (g >> 14)) ^ ((g << (64 - 18)) | (g >> 18)) ^ ((g << 23) | (g >> 41))) + (a ^ (g & (h ^ a))) + 0x5fcb6fab3ad6faecul + s78
+ f += b; b += (((c << 36) | (c >> 28)) ^ ((c << (64 - 34)) | (c >> 34)) ^ ((c << 25) | (c >> 39))) + ((c & (d | e)) | (d & e));
+ a += (((f << 50) | (f >> 14)) ^ ((f << (64 - 18)) | (f >> 18)) ^ ((f << 23) | (f >> 41))) + (h ^ (f & (g ^ h))) + 0x6c44198c4a475817ul + s79
+ e += a; a += (((b << 36) | (b >> 28)) ^ ((b << (64 - 34)) | (b >> 34)) ^ ((b << 25) | (b >> 39))) + ((b & (c | d)) | (c & d));
+
+ x[0] += a
+ x[1] += b
+ x[2] += c
+ x[3] += d
+ x[4] += e
+ x[5] += f
+ x[6] += g
+ x[7] += h
+}
+
+const unpack = {b
+ var v : uint64
+
+ v = ((b[0] castto(uint64)) << 56)
+ v |= ((b[1] castto(uint64)) << 48)
+ v |= ((b[2] castto(uint64)) << 40)
+ v |= ((b[3] castto(uint64)) << 32)
+ v |= ((b[4] castto(uint64)) << 24)
+ v |= ((b[5] castto(uint64)) << 16)
+ v |= ((b[6] castto(uint64)) << 8)
+ v |= ((b[7] castto(uint64)) << 0)
+ -> v
+}
+
+const pack = {out, v
+ out[0] = (v >> 56) castto(byte)
+ out[1] = (v >> 48) castto(byte)
+ out[2] = (v >> 40) castto(byte)
+ out[3] = (v >> 32) castto(byte)
+ out[4] = (v >> 24) castto(byte)
+ out[5] = (v >> 16) castto(byte)
+ out[6] = (v >> 8) castto(byte)
+ out[7] = (v >> 0) castto(byte)
+}
+
--- /dev/null
+++ b/libcryptohash/test/data/sha512-test-expected
@@ -1,0 +1,4 @@
+cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
+2241bc8fc70705b42efead371fd4982c5ba69917e5b4b895810002644f0386da9c3131793458c2bf47608480d64a07278133c99912e0ba2daf23098f3520eb97
+01d35c10c6c38c2dcf48f7eebb3235fb5ad74a65ec4cd016e2354c637a8fb49b695ef3c1d6f7ae4cd74d78cc9c9bcac9d4f23a73019998a7f73038a5c9b2dbde
+d5c989d2e41299b6bfd57562b4b09cd2efa56f13c8fa109e0ce5ddbd6bfb5b34f8563608d6162104bef750023732581f22704d5df43feecbb05742be1d7c34fa
--- /dev/null
+++ b/libcryptohash/test/sha512-test.myr
@@ -1,0 +1,22 @@
+use std
+use cryptohash
+
+const main = {
+ print(cryptohash.sha512(""))
+ print(cryptohash.sha512("h"))
+ /* 64 byte block */
+ print(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
+ /* tail spanning */
+ print(cryptohash.sha512("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb"))
+}
+
+const print = {b
+ for x in b
+ if (x <= 0xf)
+ std.put("0%xb", x)
+ else
+ std.put("%xb", x)
+ ;;
+ ;;
+ std.put("\n")
+}
--- a/libcryptohash/test/tests
+++ b/libcryptohash/test/tests
@@ -24,3 +24,4 @@
B sha1-test C
B sha256-test C
B sha224-test C
+B sha512-test C