1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// SHA256 block step.
6// In its own file so that a faster assembly or C version
7// can be substituted easily.
8
9package sha256
10
11import "math/bits"
12
13var _K = []uint32{
14	0x428a2f98,
15	0x71374491,
16	0xb5c0fbcf,
17	0xe9b5dba5,
18	0x3956c25b,
19	0x59f111f1,
20	0x923f82a4,
21	0xab1c5ed5,
22	0xd807aa98,
23	0x12835b01,
24	0x243185be,
25	0x550c7dc3,
26	0x72be5d74,
27	0x80deb1fe,
28	0x9bdc06a7,
29	0xc19bf174,
30	0xe49b69c1,
31	0xefbe4786,
32	0x0fc19dc6,
33	0x240ca1cc,
34	0x2de92c6f,
35	0x4a7484aa,
36	0x5cb0a9dc,
37	0x76f988da,
38	0x983e5152,
39	0xa831c66d,
40	0xb00327c8,
41	0xbf597fc7,
42	0xc6e00bf3,
43	0xd5a79147,
44	0x06ca6351,
45	0x14292967,
46	0x27b70a85,
47	0x2e1b2138,
48	0x4d2c6dfc,
49	0x53380d13,
50	0x650a7354,
51	0x766a0abb,
52	0x81c2c92e,
53	0x92722c85,
54	0xa2bfe8a1,
55	0xa81a664b,
56	0xc24b8b70,
57	0xc76c51a3,
58	0xd192e819,
59	0xd6990624,
60	0xf40e3585,
61	0x106aa070,
62	0x19a4c116,
63	0x1e376c08,
64	0x2748774c,
65	0x34b0bcb5,
66	0x391c0cb3,
67	0x4ed8aa4a,
68	0x5b9cca4f,
69	0x682e6ff3,
70	0x748f82ee,
71	0x78a5636f,
72	0x84c87814,
73	0x8cc70208,
74	0x90befffa,
75	0xa4506ceb,
76	0xbef9a3f7,
77	0xc67178f2,
78}
79
80func blockGeneric(dig *digest, p []byte) {
81	var w [64]uint32
82	h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
83	for len(p) >= chunk {
84		// Can interlace the computation of w with the
85		// rounds below if needed for speed.
86		for i := 0; i < 16; i++ {
87			j := i * 4
88			w[i] = uint32(p[j])<<24 | uint32(p[j+1])<<16 | uint32(p[j+2])<<8 | uint32(p[j+3])
89		}
90		for i := 16; i < 64; i++ {
91			v1 := w[i-2]
92			t1 := (bits.RotateLeft32(v1, -17)) ^ (bits.RotateLeft32(v1, -19)) ^ (v1 >> 10)
93			v2 := w[i-15]
94			t2 := (bits.RotateLeft32(v2, -7)) ^ (bits.RotateLeft32(v2, -18)) ^ (v2 >> 3)
95			w[i] = t1 + w[i-7] + t2 + w[i-16]
96		}
97
98		a, b, c, d, e, f, g, h := h0, h1, h2, h3, h4, h5, h6, h7
99
100		for i := 0; i < 64; i++ {
101			t1 := h + ((bits.RotateLeft32(e, -6)) ^ (bits.RotateLeft32(e, -11)) ^ (bits.RotateLeft32(e, -25))) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
102
103			t2 := ((bits.RotateLeft32(a, -2)) ^ (bits.RotateLeft32(a, -13)) ^ (bits.RotateLeft32(a, -22))) + ((a & b) ^ (a & c) ^ (b & c))
104
105			h = g
106			g = f
107			f = e
108			e = d + t1
109			d = c
110			c = b
111			b = a
112			a = t1 + t2
113		}
114
115		h0 += a
116		h1 += b
117		h2 += c
118		h3 += d
119		h4 += e
120		h5 += f
121		h6 += g
122		h7 += h
123
124		p = p[chunk:]
125	}
126
127	dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7] = h0, h1, h2, h3, h4, h5, h6, h7
128}
129