v2 / vlib / crypto / sha256 / sha256block_generic.v
154 lines · 151 sloc · 2.85 KB · e5d88def78067733949f3427ec5038907bc13da7
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4// SHA256 block step.
5// This is the generic version with no architecture optimizations.
6// In its own file so that an architecture
7// optimized version can be substituted
8module sha256
9
10import math.bits
11
12const _k = [
13 0x428a2f98,
14 0x71374491,
15 0xb5c0fbcf,
16 0xe9b5dba5,
17 0x3956c25b,
18 0x59f111f1,
19 0x923f82a4,
20 0xab1c5ed5,
21 0xd807aa98,
22 0x12835b01,
23 0x243185be,
24 0x550c7dc3,
25 0x72be5d74,
26 0x80deb1fe,
27 0x9bdc06a7,
28 0xc19bf174,
29 0xe49b69c1,
30 0xefbe4786,
31 0x0fc19dc6,
32 0x240ca1cc,
33 0x2de92c6f,
34 0x4a7484aa,
35 0x5cb0a9dc,
36 0x76f988da,
37 0x983e5152,
38 0xa831c66d,
39 0xb00327c8,
40 0xbf597fc7,
41 0xc6e00bf3,
42 0xd5a79147,
43 0x06ca6351,
44 0x14292967,
45 0x27b70a85,
46 0x2e1b2138,
47 0x4d2c6dfc,
48 0x53380d13,
49 0x650a7354,
50 0x766a0abb,
51 0x81c2c92e,
52 0x92722c85,
53 0xa2bfe8a1,
54 0xa81a664b,
55 0xc24b8b70,
56 0xc76c51a3,
57 0xd192e819,
58 0xd6990624,
59 0xf40e3585,
60 0x106aa070,
61 0x19a4c116,
62 0x1e376c08,
63 0x2748774c,
64 0x34b0bcb5,
65 0x391c0cb3,
66 0x4ed8aa4a,
67 0x5b9cca4f,
68 0x682e6ff3,
69 0x748f82ee,
70 0x78a5636f,
71 0x84c87814,
72 0x8cc70208,
73 0x90befffa,
74 0xa4506ceb,
75 0xbef9a3f7,
76 0xc67178f2,
77]
78
79@[direct_array_access]
80fn block_generic(mut dig Digest, p_ []u8) {
81 unsafe {
82 mut p := p_
83 // Keep the message schedule on the stack.
84 mut w := [64]u32{}
85 mut h0 := dig.h[0]
86 mut h1 := dig.h[1]
87 mut h2 := dig.h[2]
88 mut h3 := dig.h[3]
89 mut h4 := dig.h[4]
90 mut h5 := dig.h[5]
91 mut h6 := dig.h[6]
92 mut h7 := dig.h[7]
93 for p.len >= chunk {
94 // Can interlace the computation of w with the
95 // rounds below if needed for speed.
96 for i in 0 .. 16 {
97 j := i * 4
98 w[i] = u32(p[j]) << 24 | u32(p[j + 1]) << 16 | u32(p[j + 2]) << 8 | u32(p[j + 3])
99 }
100 for i := 16; i < 64; i++ {
101 v1 := w[i - 2]
102 t1 := (bits.rotate_left_32(v1, -17)) ^ (bits.rotate_left_32(v1, -19)) ^ (v1 >> 10)
103 v2 := w[i - 15]
104 t2 := (bits.rotate_left_32(v2, -7)) ^ (bits.rotate_left_32(v2, -18)) ^ (v2 >> 3)
105 w[i] = t1 + w[i - 7] + t2 + w[i - 16]
106 }
107 mut a := h0
108 mut b := h1
109 mut c := h2
110 mut d := h3
111 mut e := h4
112 mut f := h5
113 mut g := h6
114 mut h := h7
115 for i in 0 .. 64 {
116 t1 := h +
117 ((bits.rotate_left_32(e, -6)) ^ (bits.rotate_left_32(e, -11)) ^ (bits.rotate_left_32(e, -25))) +
118 ((e & f) ^ (~e & g)) + u32(_k[i]) + w[i]
119 t2 :=
120 ((bits.rotate_left_32(a, -2)) ^ (bits.rotate_left_32(a, -13)) ^ (bits.rotate_left_32(a, -22))) +
121 ((a & b) ^ (a & c) ^ (b & c))
122 h = g
123 g = f
124 f = e
125 e = d + t1
126 d = c
127 c = b
128 b = a
129 a = t1 + t2
130 }
131 h0 += a
132 h1 += b
133 h2 += c
134 h3 += d
135 h4 += e
136 h5 += f
137 h6 += g
138 h7 += h
139 if chunk >= p.len {
140 p = []
141 } else {
142 p = p[chunk..]
143 }
144 }
145 dig.h[0] = h0
146 dig.h[1] = h1
147 dig.h[2] = h2
148 dig.h[3] = h3
149 dig.h[4] = h4
150 dig.h[5] = h5
151 dig.h[6] = h6
152 dig.h[7] = h7
153 }
154}
155