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