1
2
3
4
5 package entropy
6
7 import "math/bits"
8
9
10
11
12
13 func SHA384(p *[1024]byte) [48]byte {
14 h := [8]uint64{
15 0xcbbb9d5dc1059ed8,
16 0x629a292a367cd507,
17 0x9159015a3070dd17,
18 0x152fecd8f70e5939,
19 0x67332667ffc00b31,
20 0x8eb44a8768581511,
21 0xdb0c2e0d64f98fa7,
22 0x47b5481dbefa4fa4,
23 }
24
25 sha384Block(&h, (*[128]byte)(p[0:128]))
26 sha384Block(&h, (*[128]byte)(p[128:256]))
27 sha384Block(&h, (*[128]byte)(p[256:384]))
28 sha384Block(&h, (*[128]byte)(p[384:512]))
29 sha384Block(&h, (*[128]byte)(p[512:640]))
30 sha384Block(&h, (*[128]byte)(p[640:768]))
31 sha384Block(&h, (*[128]byte)(p[768:896]))
32 sha384Block(&h, (*[128]byte)(p[896:1024]))
33
34 var padlen [128]byte
35 padlen[0] = 0x80
36 bePutUint64(padlen[112+8:], 1024*8)
37 sha384Block(&h, &padlen)
38
39 var digest [48]byte
40 bePutUint64(digest[0:], h[0])
41 bePutUint64(digest[8:], h[1])
42 bePutUint64(digest[16:], h[2])
43 bePutUint64(digest[24:], h[3])
44 bePutUint64(digest[32:], h[4])
45 bePutUint64(digest[40:], h[5])
46 return digest
47 }
48
49 var _K = [...]uint64{
50 0x428a2f98d728ae22,
51 0x7137449123ef65cd,
52 0xb5c0fbcfec4d3b2f,
53 0xe9b5dba58189dbbc,
54 0x3956c25bf348b538,
55 0x59f111f1b605d019,
56 0x923f82a4af194f9b,
57 0xab1c5ed5da6d8118,
58 0xd807aa98a3030242,
59 0x12835b0145706fbe,
60 0x243185be4ee4b28c,
61 0x550c7dc3d5ffb4e2,
62 0x72be5d74f27b896f,
63 0x80deb1fe3b1696b1,
64 0x9bdc06a725c71235,
65 0xc19bf174cf692694,
66 0xe49b69c19ef14ad2,
67 0xefbe4786384f25e3,
68 0x0fc19dc68b8cd5b5,
69 0x240ca1cc77ac9c65,
70 0x2de92c6f592b0275,
71 0x4a7484aa6ea6e483,
72 0x5cb0a9dcbd41fbd4,
73 0x76f988da831153b5,
74 0x983e5152ee66dfab,
75 0xa831c66d2db43210,
76 0xb00327c898fb213f,
77 0xbf597fc7beef0ee4,
78 0xc6e00bf33da88fc2,
79 0xd5a79147930aa725,
80 0x06ca6351e003826f,
81 0x142929670a0e6e70,
82 0x27b70a8546d22ffc,
83 0x2e1b21385c26c926,
84 0x4d2c6dfc5ac42aed,
85 0x53380d139d95b3df,
86 0x650a73548baf63de,
87 0x766a0abb3c77b2a8,
88 0x81c2c92e47edaee6,
89 0x92722c851482353b,
90 0xa2bfe8a14cf10364,
91 0xa81a664bbc423001,
92 0xc24b8b70d0f89791,
93 0xc76c51a30654be30,
94 0xd192e819d6ef5218,
95 0xd69906245565a910,
96 0xf40e35855771202a,
97 0x106aa07032bbd1b8,
98 0x19a4c116b8d2d0c8,
99 0x1e376c085141ab53,
100 0x2748774cdf8eeb99,
101 0x34b0bcb5e19b48a8,
102 0x391c0cb3c5c95a63,
103 0x4ed8aa4ae3418acb,
104 0x5b9cca4f7763e373,
105 0x682e6ff3d6b2b8a3,
106 0x748f82ee5defb2fc,
107 0x78a5636f43172f60,
108 0x84c87814a1f0ab72,
109 0x8cc702081a6439ec,
110 0x90befffa23631e28,
111 0xa4506cebde82bde9,
112 0xbef9a3f7b2c67915,
113 0xc67178f2e372532b,
114 0xca273eceea26619c,
115 0xd186b8c721c0c207,
116 0xeada7dd6cde0eb1e,
117 0xf57d4f7fee6ed178,
118 0x06f067aa72176fba,
119 0x0a637dc5a2c898a6,
120 0x113f9804bef90dae,
121 0x1b710b35131c471b,
122 0x28db77f523047d84,
123 0x32caab7b40c72493,
124 0x3c9ebe0a15c9bebc,
125 0x431d67c49c100d4c,
126 0x4cc5d4becb3e42b6,
127 0x597f299cfc657e2a,
128 0x5fcb6fab3ad6faec,
129 0x6c44198c4a475817,
130 }
131
132 func sha384Block(dh *[8]uint64, p *[128]byte) {
133 var w [80]uint64
134 for i := range 80 {
135 if i < 16 {
136 w[i] = beUint64(p[i*8:])
137 } else {
138 v1 := w[i-2]
139 t1 := bits.RotateLeft64(v1, -19) ^ bits.RotateLeft64(v1, -61) ^ (v1 >> 6)
140 v2 := w[i-15]
141 t2 := bits.RotateLeft64(v2, -1) ^ bits.RotateLeft64(v2, -8) ^ (v2 >> 7)
142
143 w[i] = t1 + w[i-7] + t2 + w[i-16]
144 }
145 }
146
147 a, b, c, d, e, f, g, h := dh[0], dh[1], dh[2], dh[3], dh[4], dh[5], dh[6], dh[7]
148
149 for i := range 80 {
150 t1 := h + (bits.RotateLeft64(e, -14) ^ bits.RotateLeft64(e, -18) ^
151 bits.RotateLeft64(e, -41)) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
152 t2 := (bits.RotateLeft64(a, -28) ^ bits.RotateLeft64(a, -34) ^
153 bits.RotateLeft64(a, -39)) + ((a & b) ^ (a & c) ^ (b & c))
154
155 h = g
156 g = f
157 f = e
158 e = d + t1
159 d = c
160 c = b
161 b = a
162 a = t1 + t2
163 }
164
165 dh[0] += a
166 dh[1] += b
167 dh[2] += c
168 dh[3] += d
169 dh[4] += e
170 dh[5] += f
171 dh[6] += g
172 dh[7] += h
173 }
174
175 func beUint64(b []byte) uint64 {
176 _ = b[7]
177 return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
178 uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
179 }
180
181 func bePutUint64(b []byte, v uint64) {
182 _ = b[7]
183 b[0] = byte(v >> 56)
184 b[1] = byte(v >> 48)
185 b[2] = byte(v >> 40)
186 b[3] = byte(v >> 32)
187 b[4] = byte(v >> 24)
188 b[5] = byte(v >> 16)
189 b[6] = byte(v >> 8)
190 b[7] = byte(v)
191 }
192
View as plain text