1use crate::c;
16use core::{
17 num::Wrapping,
18 ops::{Add, AddAssign, BitAnd, BitOr, BitXor, Not, Shr},
19};
20
21#[cfg(not(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64")))]
22pub(super) extern "C" fn sha256_block_data_order(
23 state: &mut super::State,
24 data: *const u8,
25 num: c::size_t,
26) {
27 let state = unsafe { &mut state.as32 };
28 *state = block_data_order(*state, data, num)
29}
30
31#[cfg(not(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64")))]
32pub(super) extern "C" fn sha512_block_data_order(
33 state: &mut super::State,
34 data: *const u8,
35 num: c::size_t,
36) {
37 let state = unsafe { &mut state.as64 };
38 *state = block_data_order(*state, data, num)
39}
40
41#[cfg_attr(
42 any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"),
43 allow(dead_code)
44)]
45#[inline]
46fn block_data_order<S: Sha2>(
47 mut H: [S; CHAINING_WORDS],
48 M: *const u8,
49 num: c::size_t,
50) -> [S; CHAINING_WORDS] {
51 let M = M.cast::<[S::InputBytes; 16]>();
52 let M: &[[S::InputBytes; 16]] = unsafe { core::slice::from_raw_parts(M, num) };
53
54 for M in M {
55 let mut W = [S::ZERO; MAX_ROUNDS];
61 let W: &[S] = {
62 let W = &mut W[..S::K.len()];
63 for (W, M) in W.iter_mut().zip(M) {
64 *W = S::from_be_bytes(*M);
65 }
66 for t in M.len()..S::K.len() {
67 W[t] = sigma_1(W[t - 2]) + W[t - 7] + sigma_0(W[t - 15]) + W[t - 16]
68 }
69
70 W
71 };
72
73 let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h] = H;
75
76 for (Kt, Wt) in S::K.iter().zip(W.iter()) {
78 let T1 = h + SIGMA_1(e) + ch(e, f, g) + *Kt + *Wt;
79 let T2 = SIGMA_0(a) + maj(a, b, c);
80 h = g;
81 g = f;
82 f = e;
83 e = d + T1;
84 d = c;
85 c = b;
86 b = a;
87 a = T1 + T2;
88 }
89
90 H[0] += a;
92 H[1] += b;
93 H[2] += c;
94 H[3] += d;
95 H[4] += e;
96 H[5] += f;
97 H[6] += g;
98 H[7] += h;
99 }
100
101 H
102}
103
104#[inline(always)]
106pub(super) fn ch<W: Word>(x: W, y: W, z: W) -> W {
107 (x & y) | (!x & z)
108}
109
110#[inline(always)]
112pub(super) fn maj<W: Word>(x: W, y: W, z: W) -> W {
113 (x & y) | (x & z) | (y & z)
114}
115
116#[inline(always)]
118fn SIGMA_0<S: Sha2>(x: S) -> S {
119 x.rotr(S::BIG_SIGMA_0.0) ^ x.rotr(S::BIG_SIGMA_0.1) ^ x.rotr(S::BIG_SIGMA_0.2)
120}
121
122#[inline(always)]
124fn SIGMA_1<S: Sha2>(x: S) -> S {
125 x.rotr(S::BIG_SIGMA_1.0) ^ x.rotr(S::BIG_SIGMA_1.1) ^ x.rotr(S::BIG_SIGMA_1.2)
126}
127
128#[inline(always)]
130fn sigma_0<S: Sha2>(x: S) -> S {
131 x.rotr(S::SMALL_SIGMA_0.0) ^ x.rotr(S::SMALL_SIGMA_0.1) ^ (x >> S::SMALL_SIGMA_0.2)
132}
133
134#[inline(always)]
136fn sigma_1<S: Sha2>(x: S) -> S {
137 x.rotr(S::SMALL_SIGMA_1.0) ^ x.rotr(S::SMALL_SIGMA_1.1) ^ (x >> S::SMALL_SIGMA_1.2)
138}
139
140pub(super) trait Word:
142 'static
143 + Sized
144 + Copy
145 + Add<Output = Self>
146 + AddAssign
147 + BitAnd<Output = Self>
148 + BitOr<Output = Self>
149 + Not<Output = Self>
150{
151 const ZERO: Self;
152
153 type InputBytes: Copy;
154
155 fn from_be_bytes(input: Self::InputBytes) -> Self;
156
157 fn rotr(self, count: u32) -> Self;
158}
159
160trait Sha2: Word + BitXor<Output = Self> + Shr<usize, Output = Self> {
162 const BIG_SIGMA_0: (u32, u32, u32);
163 const BIG_SIGMA_1: (u32, u32, u32);
164 const SMALL_SIGMA_0: (u32, u32, usize);
165 const SMALL_SIGMA_1: (u32, u32, usize);
166
167 const K: &'static [Self];
168}
169
170const MAX_ROUNDS: usize = 80;
171pub(super) const CHAINING_WORDS: usize = 8;
172
173impl Word for Wrapping<u32> {
174 const ZERO: Self = Self(0);
175 type InputBytes = [u8; 4];
176
177 #[inline(always)]
178 fn from_be_bytes(input: Self::InputBytes) -> Self {
179 Self(u32::from_be_bytes(input))
180 }
181
182 #[inline(always)]
183 fn rotr(self, count: u32) -> Self {
184 Self(self.0.rotate_right(count))
185 }
186}
187
188impl Sha2 for Wrapping<u32> {
190 const BIG_SIGMA_0: (u32, u32, u32) = (2, 13, 22);
192 const BIG_SIGMA_1: (u32, u32, u32) = (6, 11, 25);
193 const SMALL_SIGMA_0: (u32, u32, usize) = (7, 18, 3);
194 const SMALL_SIGMA_1: (u32, u32, usize) = (17, 19, 10);
195
196 const K: &'static [Self] = &[
198 Self(0x428a2f98),
199 Self(0x71374491),
200 Self(0xb5c0fbcf),
201 Self(0xe9b5dba5),
202 Self(0x3956c25b),
203 Self(0x59f111f1),
204 Self(0x923f82a4),
205 Self(0xab1c5ed5),
206 Self(0xd807aa98),
207 Self(0x12835b01),
208 Self(0x243185be),
209 Self(0x550c7dc3),
210 Self(0x72be5d74),
211 Self(0x80deb1fe),
212 Self(0x9bdc06a7),
213 Self(0xc19bf174),
214 Self(0xe49b69c1),
215 Self(0xefbe4786),
216 Self(0x0fc19dc6),
217 Self(0x240ca1cc),
218 Self(0x2de92c6f),
219 Self(0x4a7484aa),
220 Self(0x5cb0a9dc),
221 Self(0x76f988da),
222 Self(0x983e5152),
223 Self(0xa831c66d),
224 Self(0xb00327c8),
225 Self(0xbf597fc7),
226 Self(0xc6e00bf3),
227 Self(0xd5a79147),
228 Self(0x06ca6351),
229 Self(0x14292967),
230 Self(0x27b70a85),
231 Self(0x2e1b2138),
232 Self(0x4d2c6dfc),
233 Self(0x53380d13),
234 Self(0x650a7354),
235 Self(0x766a0abb),
236 Self(0x81c2c92e),
237 Self(0x92722c85),
238 Self(0xa2bfe8a1),
239 Self(0xa81a664b),
240 Self(0xc24b8b70),
241 Self(0xc76c51a3),
242 Self(0xd192e819),
243 Self(0xd6990624),
244 Self(0xf40e3585),
245 Self(0x106aa070),
246 Self(0x19a4c116),
247 Self(0x1e376c08),
248 Self(0x2748774c),
249 Self(0x34b0bcb5),
250 Self(0x391c0cb3),
251 Self(0x4ed8aa4a),
252 Self(0x5b9cca4f),
253 Self(0x682e6ff3),
254 Self(0x748f82ee),
255 Self(0x78a5636f),
256 Self(0x84c87814),
257 Self(0x8cc70208),
258 Self(0x90befffa),
259 Self(0xa4506ceb),
260 Self(0xbef9a3f7),
261 Self(0xc67178f2),
262 ];
263}
264
265impl Word for Wrapping<u64> {
266 const ZERO: Self = Self(0);
267 type InputBytes = [u8; 8];
268
269 #[inline(always)]
270 fn from_be_bytes(input: Self::InputBytes) -> Self {
271 Self(u64::from_be_bytes(input))
272 }
273
274 #[inline(always)]
275 fn rotr(self, count: u32) -> Self {
276 Self(self.0.rotate_right(count))
277 }
278}
279
280impl Sha2 for Wrapping<u64> {
282 const BIG_SIGMA_0: (u32, u32, u32) = (28, 34, 39);
284 const BIG_SIGMA_1: (u32, u32, u32) = (14, 18, 41);
285 const SMALL_SIGMA_0: (u32, u32, usize) = (1, 8, 7);
286 const SMALL_SIGMA_1: (u32, u32, usize) = (19, 61, 6);
287
288 const K: &'static [Self] = &[
290 Self(0x428a2f98d728ae22),
291 Self(0x7137449123ef65cd),
292 Self(0xb5c0fbcfec4d3b2f),
293 Self(0xe9b5dba58189dbbc),
294 Self(0x3956c25bf348b538),
295 Self(0x59f111f1b605d019),
296 Self(0x923f82a4af194f9b),
297 Self(0xab1c5ed5da6d8118),
298 Self(0xd807aa98a3030242),
299 Self(0x12835b0145706fbe),
300 Self(0x243185be4ee4b28c),
301 Self(0x550c7dc3d5ffb4e2),
302 Self(0x72be5d74f27b896f),
303 Self(0x80deb1fe3b1696b1),
304 Self(0x9bdc06a725c71235),
305 Self(0xc19bf174cf692694),
306 Self(0xe49b69c19ef14ad2),
307 Self(0xefbe4786384f25e3),
308 Self(0x0fc19dc68b8cd5b5),
309 Self(0x240ca1cc77ac9c65),
310 Self(0x2de92c6f592b0275),
311 Self(0x4a7484aa6ea6e483),
312 Self(0x5cb0a9dcbd41fbd4),
313 Self(0x76f988da831153b5),
314 Self(0x983e5152ee66dfab),
315 Self(0xa831c66d2db43210),
316 Self(0xb00327c898fb213f),
317 Self(0xbf597fc7beef0ee4),
318 Self(0xc6e00bf33da88fc2),
319 Self(0xd5a79147930aa725),
320 Self(0x06ca6351e003826f),
321 Self(0x142929670a0e6e70),
322 Self(0x27b70a8546d22ffc),
323 Self(0x2e1b21385c26c926),
324 Self(0x4d2c6dfc5ac42aed),
325 Self(0x53380d139d95b3df),
326 Self(0x650a73548baf63de),
327 Self(0x766a0abb3c77b2a8),
328 Self(0x81c2c92e47edaee6),
329 Self(0x92722c851482353b),
330 Self(0xa2bfe8a14cf10364),
331 Self(0xa81a664bbc423001),
332 Self(0xc24b8b70d0f89791),
333 Self(0xc76c51a30654be30),
334 Self(0xd192e819d6ef5218),
335 Self(0xd69906245565a910),
336 Self(0xf40e35855771202a),
337 Self(0x106aa07032bbd1b8),
338 Self(0x19a4c116b8d2d0c8),
339 Self(0x1e376c085141ab53),
340 Self(0x2748774cdf8eeb99),
341 Self(0x34b0bcb5e19b48a8),
342 Self(0x391c0cb3c5c95a63),
343 Self(0x4ed8aa4ae3418acb),
344 Self(0x5b9cca4f7763e373),
345 Self(0x682e6ff3d6b2b8a3),
346 Self(0x748f82ee5defb2fc),
347 Self(0x78a5636f43172f60),
348 Self(0x84c87814a1f0ab72),
349 Self(0x8cc702081a6439ec),
350 Self(0x90befffa23631e28),
351 Self(0xa4506cebde82bde9),
352 Self(0xbef9a3f7b2c67915),
353 Self(0xc67178f2e372532b),
354 Self(0xca273eceea26619c),
355 Self(0xd186b8c721c0c207),
356 Self(0xeada7dd6cde0eb1e),
357 Self(0xf57d4f7fee6ed178),
358 Self(0x06f067aa72176fba),
359 Self(0x0a637dc5a2c898a6),
360 Self(0x113f9804bef90dae),
361 Self(0x1b710b35131c471b),
362 Self(0x28db77f523047d84),
363 Self(0x32caab7b40c72493),
364 Self(0x3c9ebe0a15c9bebc),
365 Self(0x431d67c49c100d4c),
366 Self(0x4cc5d4becb3e42b6),
367 Self(0x597f299cfc657e2a),
368 Self(0x5fcb6fab3ad6faec),
369 Self(0x6c44198c4a475817),
370 ];
371}
372
373#[cfg(any(target_arch = "aarch64", target_arch = "arm", target_arch = "x86_64"))]
374prefixed_extern! {
375 pub(super) fn sha256_block_data_order(
376 state: &mut super::State,
377 data: *const u8,
378 num: c::size_t,
379 );
380 pub(super) fn sha512_block_data_order(
381 state: &mut super::State,
382 data: *const u8,
383 num: c::size_t,
384 );
385}