Line data Source code
1 : // Copyright (c) 2017-present The Bitcoin Core developers
2 : // Distributed under the MIT software license, see the accompanying
3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 : //
5 : // This is a translation to GCC extended asm syntax from YASM code by Intel
6 : // (available at the bottom of this file).
7 :
8 : #if defined(__x86_64__) || defined(__amd64__)
9 :
10 : #include <cstdint>
11 : #include <cstdlib>
12 :
13 : namespace sha256_sse4
14 : {
15 : /*
16 : Both Clang and GCC fail with ASan on this inline assembly:
17 : - Clang: compile failure with -O0 or -O2 + -fcf-protection under ASan.
18 : See https://github.com/llvm/llvm-project/issues/92182
19 : and https://github.com/bitcoin/bitcoin/issues/31913.
20 : - GCC: runtime SEGV during SHA256AutoDetect()'s self-test under ASan,
21 : regardless of optimization level.
22 : See https://github.com/bitcoin/bitcoin/issues/34881.
23 : */
24 : #if defined(__SANITIZE_ADDRESS__)
25 : __attribute__((no_sanitize("address")))
26 : #elif defined(__clang__)
27 : #if __has_feature(address_sanitizer) // fallback can be removed once support for Clang 21 is dropped
28 : __attribute__((no_sanitize("address")))
29 : #endif
30 : #endif
31 0 : void Transform(uint32_t* s, const unsigned char* chunk, size_t blocks)
32 : {
33 0 : static const uint32_t K256 alignas(16) [] = {
34 : 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
35 : 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
36 : 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
37 : 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
38 : 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
39 : 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
40 : 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
41 : 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
42 : 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
43 : 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
44 : 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
45 : 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
46 : 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
47 : 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
48 : 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
49 : 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
50 : };
51 0 : static const uint32_t FLIP_MASK alignas(16) [] = {0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f};
52 0 : static const uint32_t SHUF_00BA alignas(16) [] = {0x03020100, 0x0b0a0908, 0xffffffff, 0xffffffff};
53 0 : static const uint32_t SHUF_DC00 alignas(16) [] = {0xffffffff, 0xffffffff, 0x03020100, 0x0b0a0908};
54 0 : uint32_t a, b, c, d, f, g, h, y0, y1, y2;
55 0 : uint64_t tbl;
56 0 : uint64_t inp_end, inp;
57 0 : uint32_t xfer alignas(16) [4];
58 :
59 0 : __asm__ __volatile__(
60 : "shl $0x6,%2;"
61 : "je Ldone_hash_%=;"
62 : "add %1,%2;"
63 : "mov %2,%14;"
64 : "mov (%0),%3;"
65 : "mov 0x4(%0),%4;"
66 : "mov 0x8(%0),%5;"
67 : "mov 0xc(%0),%6;"
68 : "mov 0x10(%0),%k2;"
69 : "mov 0x14(%0),%7;"
70 : "mov 0x18(%0),%8;"
71 : "mov 0x1c(%0),%9;"
72 : "movdqa %18,%%xmm12;"
73 : "movdqa %19,%%xmm10;"
74 : "movdqa %20,%%xmm11;"
75 :
76 : "Lloop0_%=:"
77 : "lea %17,%13;"
78 : "movdqu (%1),%%xmm4;"
79 : "pshufb %%xmm12,%%xmm4;"
80 : "movdqu 0x10(%1),%%xmm5;"
81 : "pshufb %%xmm12,%%xmm5;"
82 : "movdqu 0x20(%1),%%xmm6;"
83 : "pshufb %%xmm12,%%xmm6;"
84 : "movdqu 0x30(%1),%%xmm7;"
85 : "pshufb %%xmm12,%%xmm7;"
86 : "mov %1,%15;"
87 : "mov $3,%1;"
88 :
89 : "Lloop1_%=:"
90 : "movdqa 0x0(%13),%%xmm9;"
91 : "paddd %%xmm4,%%xmm9;"
92 : "movdqa %%xmm9,%16;"
93 : "movdqa %%xmm7,%%xmm0;"
94 : "mov %k2,%10;"
95 : "ror $0xe,%10;"
96 : "mov %3,%11;"
97 : "palignr $0x4,%%xmm6,%%xmm0;"
98 : "ror $0x9,%11;"
99 : "xor %k2,%10;"
100 : "mov %7,%12;"
101 : "ror $0x5,%10;"
102 : "movdqa %%xmm5,%%xmm1;"
103 : "xor %3,%11;"
104 : "xor %8,%12;"
105 : "paddd %%xmm4,%%xmm0;"
106 : "xor %k2,%10;"
107 : "and %k2,%12;"
108 : "ror $0xb,%11;"
109 : "palignr $0x4,%%xmm4,%%xmm1;"
110 : "xor %3,%11;"
111 : "ror $0x6,%10;"
112 : "xor %8,%12;"
113 : "movdqa %%xmm1,%%xmm2;"
114 : "ror $0x2,%11;"
115 : "add %10,%12;"
116 : "add %16,%12;"
117 : "movdqa %%xmm1,%%xmm3;"
118 : "mov %3,%10;"
119 : "add %12,%9;"
120 : "mov %3,%12;"
121 : "pslld $0x19,%%xmm1;"
122 : "or %5,%10;"
123 : "add %9,%6;"
124 : "and %5,%12;"
125 : "psrld $0x7,%%xmm2;"
126 : "and %4,%10;"
127 : "add %11,%9;"
128 : "por %%xmm2,%%xmm1;"
129 : "or %12,%10;"
130 : "add %10,%9;"
131 : "movdqa %%xmm3,%%xmm2;"
132 : "mov %6,%10;"
133 : "mov %9,%11;"
134 : "movdqa %%xmm3,%%xmm8;"
135 : "ror $0xe,%10;"
136 : "xor %6,%10;"
137 : "mov %k2,%12;"
138 : "ror $0x9,%11;"
139 : "pslld $0xe,%%xmm3;"
140 : "xor %9,%11;"
141 : "ror $0x5,%10;"
142 : "xor %7,%12;"
143 : "psrld $0x12,%%xmm2;"
144 : "ror $0xb,%11;"
145 : "xor %6,%10;"
146 : "and %6,%12;"
147 : "ror $0x6,%10;"
148 : "pxor %%xmm3,%%xmm1;"
149 : "xor %9,%11;"
150 : "xor %7,%12;"
151 : "psrld $0x3,%%xmm8;"
152 : "add %10,%12;"
153 : "add 4+%16,%12;"
154 : "ror $0x2,%11;"
155 : "pxor %%xmm2,%%xmm1;"
156 : "mov %9,%10;"
157 : "add %12,%8;"
158 : "mov %9,%12;"
159 : "pxor %%xmm8,%%xmm1;"
160 : "or %4,%10;"
161 : "add %8,%5;"
162 : "and %4,%12;"
163 : "pshufd $0xfa,%%xmm7,%%xmm2;"
164 : "and %3,%10;"
165 : "add %11,%8;"
166 : "paddd %%xmm1,%%xmm0;"
167 : "or %12,%10;"
168 : "add %10,%8;"
169 : "movdqa %%xmm2,%%xmm3;"
170 : "mov %5,%10;"
171 : "mov %8,%11;"
172 : "ror $0xe,%10;"
173 : "movdqa %%xmm2,%%xmm8;"
174 : "xor %5,%10;"
175 : "ror $0x9,%11;"
176 : "mov %6,%12;"
177 : "xor %8,%11;"
178 : "ror $0x5,%10;"
179 : "psrlq $0x11,%%xmm2;"
180 : "xor %k2,%12;"
181 : "psrlq $0x13,%%xmm3;"
182 : "xor %5,%10;"
183 : "and %5,%12;"
184 : "psrld $0xa,%%xmm8;"
185 : "ror $0xb,%11;"
186 : "xor %8,%11;"
187 : "xor %k2,%12;"
188 : "ror $0x6,%10;"
189 : "pxor %%xmm3,%%xmm2;"
190 : "add %10,%12;"
191 : "ror $0x2,%11;"
192 : "add 8+%16,%12;"
193 : "pxor %%xmm2,%%xmm8;"
194 : "mov %8,%10;"
195 : "add %12,%7;"
196 : "mov %8,%12;"
197 : "pshufb %%xmm10,%%xmm8;"
198 : "or %3,%10;"
199 : "add %7,%4;"
200 : "and %3,%12;"
201 : "paddd %%xmm8,%%xmm0;"
202 : "and %9,%10;"
203 : "add %11,%7;"
204 : "pshufd $0x50,%%xmm0,%%xmm2;"
205 : "or %12,%10;"
206 : "add %10,%7;"
207 : "movdqa %%xmm2,%%xmm3;"
208 : "mov %4,%10;"
209 : "ror $0xe,%10;"
210 : "mov %7,%11;"
211 : "movdqa %%xmm2,%%xmm4;"
212 : "ror $0x9,%11;"
213 : "xor %4,%10;"
214 : "mov %5,%12;"
215 : "ror $0x5,%10;"
216 : "psrlq $0x11,%%xmm2;"
217 : "xor %7,%11;"
218 : "xor %6,%12;"
219 : "psrlq $0x13,%%xmm3;"
220 : "xor %4,%10;"
221 : "and %4,%12;"
222 : "ror $0xb,%11;"
223 : "psrld $0xa,%%xmm4;"
224 : "xor %7,%11;"
225 : "ror $0x6,%10;"
226 : "xor %6,%12;"
227 : "pxor %%xmm3,%%xmm2;"
228 : "ror $0x2,%11;"
229 : "add %10,%12;"
230 : "add 12+%16,%12;"
231 : "pxor %%xmm2,%%xmm4;"
232 : "mov %7,%10;"
233 : "add %12,%k2;"
234 : "mov %7,%12;"
235 : "pshufb %%xmm11,%%xmm4;"
236 : "or %9,%10;"
237 : "add %k2,%3;"
238 : "and %9,%12;"
239 : "paddd %%xmm0,%%xmm4;"
240 : "and %8,%10;"
241 : "add %11,%k2;"
242 : "or %12,%10;"
243 : "add %10,%k2;"
244 : "movdqa 0x10(%13),%%xmm9;"
245 : "paddd %%xmm5,%%xmm9;"
246 : "movdqa %%xmm9,%16;"
247 : "movdqa %%xmm4,%%xmm0;"
248 : "mov %3,%10;"
249 : "ror $0xe,%10;"
250 : "mov %k2,%11;"
251 : "palignr $0x4,%%xmm7,%%xmm0;"
252 : "ror $0x9,%11;"
253 : "xor %3,%10;"
254 : "mov %4,%12;"
255 : "ror $0x5,%10;"
256 : "movdqa %%xmm6,%%xmm1;"
257 : "xor %k2,%11;"
258 : "xor %5,%12;"
259 : "paddd %%xmm5,%%xmm0;"
260 : "xor %3,%10;"
261 : "and %3,%12;"
262 : "ror $0xb,%11;"
263 : "palignr $0x4,%%xmm5,%%xmm1;"
264 : "xor %k2,%11;"
265 : "ror $0x6,%10;"
266 : "xor %5,%12;"
267 : "movdqa %%xmm1,%%xmm2;"
268 : "ror $0x2,%11;"
269 : "add %10,%12;"
270 : "add %16,%12;"
271 : "movdqa %%xmm1,%%xmm3;"
272 : "mov %k2,%10;"
273 : "add %12,%6;"
274 : "mov %k2,%12;"
275 : "pslld $0x19,%%xmm1;"
276 : "or %8,%10;"
277 : "add %6,%9;"
278 : "and %8,%12;"
279 : "psrld $0x7,%%xmm2;"
280 : "and %7,%10;"
281 : "add %11,%6;"
282 : "por %%xmm2,%%xmm1;"
283 : "or %12,%10;"
284 : "add %10,%6;"
285 : "movdqa %%xmm3,%%xmm2;"
286 : "mov %9,%10;"
287 : "mov %6,%11;"
288 : "movdqa %%xmm3,%%xmm8;"
289 : "ror $0xe,%10;"
290 : "xor %9,%10;"
291 : "mov %3,%12;"
292 : "ror $0x9,%11;"
293 : "pslld $0xe,%%xmm3;"
294 : "xor %6,%11;"
295 : "ror $0x5,%10;"
296 : "xor %4,%12;"
297 : "psrld $0x12,%%xmm2;"
298 : "ror $0xb,%11;"
299 : "xor %9,%10;"
300 : "and %9,%12;"
301 : "ror $0x6,%10;"
302 : "pxor %%xmm3,%%xmm1;"
303 : "xor %6,%11;"
304 : "xor %4,%12;"
305 : "psrld $0x3,%%xmm8;"
306 : "add %10,%12;"
307 : "add 4+%16,%12;"
308 : "ror $0x2,%11;"
309 : "pxor %%xmm2,%%xmm1;"
310 : "mov %6,%10;"
311 : "add %12,%5;"
312 : "mov %6,%12;"
313 : "pxor %%xmm8,%%xmm1;"
314 : "or %7,%10;"
315 : "add %5,%8;"
316 : "and %7,%12;"
317 : "pshufd $0xfa,%%xmm4,%%xmm2;"
318 : "and %k2,%10;"
319 : "add %11,%5;"
320 : "paddd %%xmm1,%%xmm0;"
321 : "or %12,%10;"
322 : "add %10,%5;"
323 : "movdqa %%xmm2,%%xmm3;"
324 : "mov %8,%10;"
325 : "mov %5,%11;"
326 : "ror $0xe,%10;"
327 : "movdqa %%xmm2,%%xmm8;"
328 : "xor %8,%10;"
329 : "ror $0x9,%11;"
330 : "mov %9,%12;"
331 : "xor %5,%11;"
332 : "ror $0x5,%10;"
333 : "psrlq $0x11,%%xmm2;"
334 : "xor %3,%12;"
335 : "psrlq $0x13,%%xmm3;"
336 : "xor %8,%10;"
337 : "and %8,%12;"
338 : "psrld $0xa,%%xmm8;"
339 : "ror $0xb,%11;"
340 : "xor %5,%11;"
341 : "xor %3,%12;"
342 : "ror $0x6,%10;"
343 : "pxor %%xmm3,%%xmm2;"
344 : "add %10,%12;"
345 : "ror $0x2,%11;"
346 : "add 8+%16,%12;"
347 : "pxor %%xmm2,%%xmm8;"
348 : "mov %5,%10;"
349 : "add %12,%4;"
350 : "mov %5,%12;"
351 : "pshufb %%xmm10,%%xmm8;"
352 : "or %k2,%10;"
353 : "add %4,%7;"
354 : "and %k2,%12;"
355 : "paddd %%xmm8,%%xmm0;"
356 : "and %6,%10;"
357 : "add %11,%4;"
358 : "pshufd $0x50,%%xmm0,%%xmm2;"
359 : "or %12,%10;"
360 : "add %10,%4;"
361 : "movdqa %%xmm2,%%xmm3;"
362 : "mov %7,%10;"
363 : "ror $0xe,%10;"
364 : "mov %4,%11;"
365 : "movdqa %%xmm2,%%xmm5;"
366 : "ror $0x9,%11;"
367 : "xor %7,%10;"
368 : "mov %8,%12;"
369 : "ror $0x5,%10;"
370 : "psrlq $0x11,%%xmm2;"
371 : "xor %4,%11;"
372 : "xor %9,%12;"
373 : "psrlq $0x13,%%xmm3;"
374 : "xor %7,%10;"
375 : "and %7,%12;"
376 : "ror $0xb,%11;"
377 : "psrld $0xa,%%xmm5;"
378 : "xor %4,%11;"
379 : "ror $0x6,%10;"
380 : "xor %9,%12;"
381 : "pxor %%xmm3,%%xmm2;"
382 : "ror $0x2,%11;"
383 : "add %10,%12;"
384 : "add 12+%16,%12;"
385 : "pxor %%xmm2,%%xmm5;"
386 : "mov %4,%10;"
387 : "add %12,%3;"
388 : "mov %4,%12;"
389 : "pshufb %%xmm11,%%xmm5;"
390 : "or %6,%10;"
391 : "add %3,%k2;"
392 : "and %6,%12;"
393 : "paddd %%xmm0,%%xmm5;"
394 : "and %5,%10;"
395 : "add %11,%3;"
396 : "or %12,%10;"
397 : "add %10,%3;"
398 : "movdqa 0x20(%13),%%xmm9;"
399 : "paddd %%xmm6,%%xmm9;"
400 : "movdqa %%xmm9,%16;"
401 : "movdqa %%xmm5,%%xmm0;"
402 : "mov %k2,%10;"
403 : "ror $0xe,%10;"
404 : "mov %3,%11;"
405 : "palignr $0x4,%%xmm4,%%xmm0;"
406 : "ror $0x9,%11;"
407 : "xor %k2,%10;"
408 : "mov %7,%12;"
409 : "ror $0x5,%10;"
410 : "movdqa %%xmm7,%%xmm1;"
411 : "xor %3,%11;"
412 : "xor %8,%12;"
413 : "paddd %%xmm6,%%xmm0;"
414 : "xor %k2,%10;"
415 : "and %k2,%12;"
416 : "ror $0xb,%11;"
417 : "palignr $0x4,%%xmm6,%%xmm1;"
418 : "xor %3,%11;"
419 : "ror $0x6,%10;"
420 : "xor %8,%12;"
421 : "movdqa %%xmm1,%%xmm2;"
422 : "ror $0x2,%11;"
423 : "add %10,%12;"
424 : "add %16,%12;"
425 : "movdqa %%xmm1,%%xmm3;"
426 : "mov %3,%10;"
427 : "add %12,%9;"
428 : "mov %3,%12;"
429 : "pslld $0x19,%%xmm1;"
430 : "or %5,%10;"
431 : "add %9,%6;"
432 : "and %5,%12;"
433 : "psrld $0x7,%%xmm2;"
434 : "and %4,%10;"
435 : "add %11,%9;"
436 : "por %%xmm2,%%xmm1;"
437 : "or %12,%10;"
438 : "add %10,%9;"
439 : "movdqa %%xmm3,%%xmm2;"
440 : "mov %6,%10;"
441 : "mov %9,%11;"
442 : "movdqa %%xmm3,%%xmm8;"
443 : "ror $0xe,%10;"
444 : "xor %6,%10;"
445 : "mov %k2,%12;"
446 : "ror $0x9,%11;"
447 : "pslld $0xe,%%xmm3;"
448 : "xor %9,%11;"
449 : "ror $0x5,%10;"
450 : "xor %7,%12;"
451 : "psrld $0x12,%%xmm2;"
452 : "ror $0xb,%11;"
453 : "xor %6,%10;"
454 : "and %6,%12;"
455 : "ror $0x6,%10;"
456 : "pxor %%xmm3,%%xmm1;"
457 : "xor %9,%11;"
458 : "xor %7,%12;"
459 : "psrld $0x3,%%xmm8;"
460 : "add %10,%12;"
461 : "add 4+%16,%12;"
462 : "ror $0x2,%11;"
463 : "pxor %%xmm2,%%xmm1;"
464 : "mov %9,%10;"
465 : "add %12,%8;"
466 : "mov %9,%12;"
467 : "pxor %%xmm8,%%xmm1;"
468 : "or %4,%10;"
469 : "add %8,%5;"
470 : "and %4,%12;"
471 : "pshufd $0xfa,%%xmm5,%%xmm2;"
472 : "and %3,%10;"
473 : "add %11,%8;"
474 : "paddd %%xmm1,%%xmm0;"
475 : "or %12,%10;"
476 : "add %10,%8;"
477 : "movdqa %%xmm2,%%xmm3;"
478 : "mov %5,%10;"
479 : "mov %8,%11;"
480 : "ror $0xe,%10;"
481 : "movdqa %%xmm2,%%xmm8;"
482 : "xor %5,%10;"
483 : "ror $0x9,%11;"
484 : "mov %6,%12;"
485 : "xor %8,%11;"
486 : "ror $0x5,%10;"
487 : "psrlq $0x11,%%xmm2;"
488 : "xor %k2,%12;"
489 : "psrlq $0x13,%%xmm3;"
490 : "xor %5,%10;"
491 : "and %5,%12;"
492 : "psrld $0xa,%%xmm8;"
493 : "ror $0xb,%11;"
494 : "xor %8,%11;"
495 : "xor %k2,%12;"
496 : "ror $0x6,%10;"
497 : "pxor %%xmm3,%%xmm2;"
498 : "add %10,%12;"
499 : "ror $0x2,%11;"
500 : "add 8+%16,%12;"
501 : "pxor %%xmm2,%%xmm8;"
502 : "mov %8,%10;"
503 : "add %12,%7;"
504 : "mov %8,%12;"
505 : "pshufb %%xmm10,%%xmm8;"
506 : "or %3,%10;"
507 : "add %7,%4;"
508 : "and %3,%12;"
509 : "paddd %%xmm8,%%xmm0;"
510 : "and %9,%10;"
511 : "add %11,%7;"
512 : "pshufd $0x50,%%xmm0,%%xmm2;"
513 : "or %12,%10;"
514 : "add %10,%7;"
515 : "movdqa %%xmm2,%%xmm3;"
516 : "mov %4,%10;"
517 : "ror $0xe,%10;"
518 : "mov %7,%11;"
519 : "movdqa %%xmm2,%%xmm6;"
520 : "ror $0x9,%11;"
521 : "xor %4,%10;"
522 : "mov %5,%12;"
523 : "ror $0x5,%10;"
524 : "psrlq $0x11,%%xmm2;"
525 : "xor %7,%11;"
526 : "xor %6,%12;"
527 : "psrlq $0x13,%%xmm3;"
528 : "xor %4,%10;"
529 : "and %4,%12;"
530 : "ror $0xb,%11;"
531 : "psrld $0xa,%%xmm6;"
532 : "xor %7,%11;"
533 : "ror $0x6,%10;"
534 : "xor %6,%12;"
535 : "pxor %%xmm3,%%xmm2;"
536 : "ror $0x2,%11;"
537 : "add %10,%12;"
538 : "add 12+%16,%12;"
539 : "pxor %%xmm2,%%xmm6;"
540 : "mov %7,%10;"
541 : "add %12,%k2;"
542 : "mov %7,%12;"
543 : "pshufb %%xmm11,%%xmm6;"
544 : "or %9,%10;"
545 : "add %k2,%3;"
546 : "and %9,%12;"
547 : "paddd %%xmm0,%%xmm6;"
548 : "and %8,%10;"
549 : "add %11,%k2;"
550 : "or %12,%10;"
551 : "add %10,%k2;"
552 : "movdqa 0x30(%13),%%xmm9;"
553 : "paddd %%xmm7,%%xmm9;"
554 : "movdqa %%xmm9,%16;"
555 : "add $0x40,%13;"
556 : "movdqa %%xmm6,%%xmm0;"
557 : "mov %3,%10;"
558 : "ror $0xe,%10;"
559 : "mov %k2,%11;"
560 : "palignr $0x4,%%xmm5,%%xmm0;"
561 : "ror $0x9,%11;"
562 : "xor %3,%10;"
563 : "mov %4,%12;"
564 : "ror $0x5,%10;"
565 : "movdqa %%xmm4,%%xmm1;"
566 : "xor %k2,%11;"
567 : "xor %5,%12;"
568 : "paddd %%xmm7,%%xmm0;"
569 : "xor %3,%10;"
570 : "and %3,%12;"
571 : "ror $0xb,%11;"
572 : "palignr $0x4,%%xmm7,%%xmm1;"
573 : "xor %k2,%11;"
574 : "ror $0x6,%10;"
575 : "xor %5,%12;"
576 : "movdqa %%xmm1,%%xmm2;"
577 : "ror $0x2,%11;"
578 : "add %10,%12;"
579 : "add %16,%12;"
580 : "movdqa %%xmm1,%%xmm3;"
581 : "mov %k2,%10;"
582 : "add %12,%6;"
583 : "mov %k2,%12;"
584 : "pslld $0x19,%%xmm1;"
585 : "or %8,%10;"
586 : "add %6,%9;"
587 : "and %8,%12;"
588 : "psrld $0x7,%%xmm2;"
589 : "and %7,%10;"
590 : "add %11,%6;"
591 : "por %%xmm2,%%xmm1;"
592 : "or %12,%10;"
593 : "add %10,%6;"
594 : "movdqa %%xmm3,%%xmm2;"
595 : "mov %9,%10;"
596 : "mov %6,%11;"
597 : "movdqa %%xmm3,%%xmm8;"
598 : "ror $0xe,%10;"
599 : "xor %9,%10;"
600 : "mov %3,%12;"
601 : "ror $0x9,%11;"
602 : "pslld $0xe,%%xmm3;"
603 : "xor %6,%11;"
604 : "ror $0x5,%10;"
605 : "xor %4,%12;"
606 : "psrld $0x12,%%xmm2;"
607 : "ror $0xb,%11;"
608 : "xor %9,%10;"
609 : "and %9,%12;"
610 : "ror $0x6,%10;"
611 : "pxor %%xmm3,%%xmm1;"
612 : "xor %6,%11;"
613 : "xor %4,%12;"
614 : "psrld $0x3,%%xmm8;"
615 : "add %10,%12;"
616 : "add 4+%16,%12;"
617 : "ror $0x2,%11;"
618 : "pxor %%xmm2,%%xmm1;"
619 : "mov %6,%10;"
620 : "add %12,%5;"
621 : "mov %6,%12;"
622 : "pxor %%xmm8,%%xmm1;"
623 : "or %7,%10;"
624 : "add %5,%8;"
625 : "and %7,%12;"
626 : "pshufd $0xfa,%%xmm6,%%xmm2;"
627 : "and %k2,%10;"
628 : "add %11,%5;"
629 : "paddd %%xmm1,%%xmm0;"
630 : "or %12,%10;"
631 : "add %10,%5;"
632 : "movdqa %%xmm2,%%xmm3;"
633 : "mov %8,%10;"
634 : "mov %5,%11;"
635 : "ror $0xe,%10;"
636 : "movdqa %%xmm2,%%xmm8;"
637 : "xor %8,%10;"
638 : "ror $0x9,%11;"
639 : "mov %9,%12;"
640 : "xor %5,%11;"
641 : "ror $0x5,%10;"
642 : "psrlq $0x11,%%xmm2;"
643 : "xor %3,%12;"
644 : "psrlq $0x13,%%xmm3;"
645 : "xor %8,%10;"
646 : "and %8,%12;"
647 : "psrld $0xa,%%xmm8;"
648 : "ror $0xb,%11;"
649 : "xor %5,%11;"
650 : "xor %3,%12;"
651 : "ror $0x6,%10;"
652 : "pxor %%xmm3,%%xmm2;"
653 : "add %10,%12;"
654 : "ror $0x2,%11;"
655 : "add 8+%16,%12;"
656 : "pxor %%xmm2,%%xmm8;"
657 : "mov %5,%10;"
658 : "add %12,%4;"
659 : "mov %5,%12;"
660 : "pshufb %%xmm10,%%xmm8;"
661 : "or %k2,%10;"
662 : "add %4,%7;"
663 : "and %k2,%12;"
664 : "paddd %%xmm8,%%xmm0;"
665 : "and %6,%10;"
666 : "add %11,%4;"
667 : "pshufd $0x50,%%xmm0,%%xmm2;"
668 : "or %12,%10;"
669 : "add %10,%4;"
670 : "movdqa %%xmm2,%%xmm3;"
671 : "mov %7,%10;"
672 : "ror $0xe,%10;"
673 : "mov %4,%11;"
674 : "movdqa %%xmm2,%%xmm7;"
675 : "ror $0x9,%11;"
676 : "xor %7,%10;"
677 : "mov %8,%12;"
678 : "ror $0x5,%10;"
679 : "psrlq $0x11,%%xmm2;"
680 : "xor %4,%11;"
681 : "xor %9,%12;"
682 : "psrlq $0x13,%%xmm3;"
683 : "xor %7,%10;"
684 : "and %7,%12;"
685 : "ror $0xb,%11;"
686 : "psrld $0xa,%%xmm7;"
687 : "xor %4,%11;"
688 : "ror $0x6,%10;"
689 : "xor %9,%12;"
690 : "pxor %%xmm3,%%xmm2;"
691 : "ror $0x2,%11;"
692 : "add %10,%12;"
693 : "add 12+%16,%12;"
694 : "pxor %%xmm2,%%xmm7;"
695 : "mov %4,%10;"
696 : "add %12,%3;"
697 : "mov %4,%12;"
698 : "pshufb %%xmm11,%%xmm7;"
699 : "or %6,%10;"
700 : "add %3,%k2;"
701 : "and %6,%12;"
702 : "paddd %%xmm0,%%xmm7;"
703 : "and %5,%10;"
704 : "add %11,%3;"
705 : "or %12,%10;"
706 : "add %10,%3;"
707 : "sub $0x1,%1;"
708 : "jne Lloop1_%=;"
709 : "mov $0x2,%1;"
710 :
711 : "Lloop2_%=:"
712 : "paddd 0x0(%13),%%xmm4;"
713 : "movdqa %%xmm4,%16;"
714 : "mov %k2,%10;"
715 : "ror $0xe,%10;"
716 : "mov %3,%11;"
717 : "xor %k2,%10;"
718 : "ror $0x9,%11;"
719 : "mov %7,%12;"
720 : "xor %3,%11;"
721 : "ror $0x5,%10;"
722 : "xor %8,%12;"
723 : "xor %k2,%10;"
724 : "ror $0xb,%11;"
725 : "and %k2,%12;"
726 : "xor %3,%11;"
727 : "ror $0x6,%10;"
728 : "xor %8,%12;"
729 : "add %10,%12;"
730 : "ror $0x2,%11;"
731 : "add %16,%12;"
732 : "mov %3,%10;"
733 : "add %12,%9;"
734 : "mov %3,%12;"
735 : "or %5,%10;"
736 : "add %9,%6;"
737 : "and %5,%12;"
738 : "and %4,%10;"
739 : "add %11,%9;"
740 : "or %12,%10;"
741 : "add %10,%9;"
742 : "mov %6,%10;"
743 : "ror $0xe,%10;"
744 : "mov %9,%11;"
745 : "xor %6,%10;"
746 : "ror $0x9,%11;"
747 : "mov %k2,%12;"
748 : "xor %9,%11;"
749 : "ror $0x5,%10;"
750 : "xor %7,%12;"
751 : "xor %6,%10;"
752 : "ror $0xb,%11;"
753 : "and %6,%12;"
754 : "xor %9,%11;"
755 : "ror $0x6,%10;"
756 : "xor %7,%12;"
757 : "add %10,%12;"
758 : "ror $0x2,%11;"
759 : "add 4+%16,%12;"
760 : "mov %9,%10;"
761 : "add %12,%8;"
762 : "mov %9,%12;"
763 : "or %4,%10;"
764 : "add %8,%5;"
765 : "and %4,%12;"
766 : "and %3,%10;"
767 : "add %11,%8;"
768 : "or %12,%10;"
769 : "add %10,%8;"
770 : "mov %5,%10;"
771 : "ror $0xe,%10;"
772 : "mov %8,%11;"
773 : "xor %5,%10;"
774 : "ror $0x9,%11;"
775 : "mov %6,%12;"
776 : "xor %8,%11;"
777 : "ror $0x5,%10;"
778 : "xor %k2,%12;"
779 : "xor %5,%10;"
780 : "ror $0xb,%11;"
781 : "and %5,%12;"
782 : "xor %8,%11;"
783 : "ror $0x6,%10;"
784 : "xor %k2,%12;"
785 : "add %10,%12;"
786 : "ror $0x2,%11;"
787 : "add 8+%16,%12;"
788 : "mov %8,%10;"
789 : "add %12,%7;"
790 : "mov %8,%12;"
791 : "or %3,%10;"
792 : "add %7,%4;"
793 : "and %3,%12;"
794 : "and %9,%10;"
795 : "add %11,%7;"
796 : "or %12,%10;"
797 : "add %10,%7;"
798 : "mov %4,%10;"
799 : "ror $0xe,%10;"
800 : "mov %7,%11;"
801 : "xor %4,%10;"
802 : "ror $0x9,%11;"
803 : "mov %5,%12;"
804 : "xor %7,%11;"
805 : "ror $0x5,%10;"
806 : "xor %6,%12;"
807 : "xor %4,%10;"
808 : "ror $0xb,%11;"
809 : "and %4,%12;"
810 : "xor %7,%11;"
811 : "ror $0x6,%10;"
812 : "xor %6,%12;"
813 : "add %10,%12;"
814 : "ror $0x2,%11;"
815 : "add 12+%16,%12;"
816 : "mov %7,%10;"
817 : "add %12,%k2;"
818 : "mov %7,%12;"
819 : "or %9,%10;"
820 : "add %k2,%3;"
821 : "and %9,%12;"
822 : "and %8,%10;"
823 : "add %11,%k2;"
824 : "or %12,%10;"
825 : "add %10,%k2;"
826 : "paddd 0x10(%13),%%xmm5;"
827 : "movdqa %%xmm5,%16;"
828 : "add $0x20,%13;"
829 : "mov %3,%10;"
830 : "ror $0xe,%10;"
831 : "mov %k2,%11;"
832 : "xor %3,%10;"
833 : "ror $0x9,%11;"
834 : "mov %4,%12;"
835 : "xor %k2,%11;"
836 : "ror $0x5,%10;"
837 : "xor %5,%12;"
838 : "xor %3,%10;"
839 : "ror $0xb,%11;"
840 : "and %3,%12;"
841 : "xor %k2,%11;"
842 : "ror $0x6,%10;"
843 : "xor %5,%12;"
844 : "add %10,%12;"
845 : "ror $0x2,%11;"
846 : "add %16,%12;"
847 : "mov %k2,%10;"
848 : "add %12,%6;"
849 : "mov %k2,%12;"
850 : "or %8,%10;"
851 : "add %6,%9;"
852 : "and %8,%12;"
853 : "and %7,%10;"
854 : "add %11,%6;"
855 : "or %12,%10;"
856 : "add %10,%6;"
857 : "mov %9,%10;"
858 : "ror $0xe,%10;"
859 : "mov %6,%11;"
860 : "xor %9,%10;"
861 : "ror $0x9,%11;"
862 : "mov %3,%12;"
863 : "xor %6,%11;"
864 : "ror $0x5,%10;"
865 : "xor %4,%12;"
866 : "xor %9,%10;"
867 : "ror $0xb,%11;"
868 : "and %9,%12;"
869 : "xor %6,%11;"
870 : "ror $0x6,%10;"
871 : "xor %4,%12;"
872 : "add %10,%12;"
873 : "ror $0x2,%11;"
874 : "add 4+%16,%12;"
875 : "mov %6,%10;"
876 : "add %12,%5;"
877 : "mov %6,%12;"
878 : "or %7,%10;"
879 : "add %5,%8;"
880 : "and %7,%12;"
881 : "and %k2,%10;"
882 : "add %11,%5;"
883 : "or %12,%10;"
884 : "add %10,%5;"
885 : "mov %8,%10;"
886 : "ror $0xe,%10;"
887 : "mov %5,%11;"
888 : "xor %8,%10;"
889 : "ror $0x9,%11;"
890 : "mov %9,%12;"
891 : "xor %5,%11;"
892 : "ror $0x5,%10;"
893 : "xor %3,%12;"
894 : "xor %8,%10;"
895 : "ror $0xb,%11;"
896 : "and %8,%12;"
897 : "xor %5,%11;"
898 : "ror $0x6,%10;"
899 : "xor %3,%12;"
900 : "add %10,%12;"
901 : "ror $0x2,%11;"
902 : "add 8+%16,%12;"
903 : "mov %5,%10;"
904 : "add %12,%4;"
905 : "mov %5,%12;"
906 : "or %k2,%10;"
907 : "add %4,%7;"
908 : "and %k2,%12;"
909 : "and %6,%10;"
910 : "add %11,%4;"
911 : "or %12,%10;"
912 : "add %10,%4;"
913 : "mov %7,%10;"
914 : "ror $0xe,%10;"
915 : "mov %4,%11;"
916 : "xor %7,%10;"
917 : "ror $0x9,%11;"
918 : "mov %8,%12;"
919 : "xor %4,%11;"
920 : "ror $0x5,%10;"
921 : "xor %9,%12;"
922 : "xor %7,%10;"
923 : "ror $0xb,%11;"
924 : "and %7,%12;"
925 : "xor %4,%11;"
926 : "ror $0x6,%10;"
927 : "xor %9,%12;"
928 : "add %10,%12;"
929 : "ror $0x2,%11;"
930 : "add 12+%16,%12;"
931 : "mov %4,%10;"
932 : "add %12,%3;"
933 : "mov %4,%12;"
934 : "or %6,%10;"
935 : "add %3,%k2;"
936 : "and %6,%12;"
937 : "and %5,%10;"
938 : "add %11,%3;"
939 : "or %12,%10;"
940 : "add %10,%3;"
941 : "movdqa %%xmm6,%%xmm4;"
942 : "movdqa %%xmm7,%%xmm5;"
943 : "sub $0x1,%1;"
944 : "jne Lloop2_%=;"
945 : "add (%0),%3;"
946 : "mov %3,(%0);"
947 : "add 0x4(%0),%4;"
948 : "mov %4,0x4(%0);"
949 : "add 0x8(%0),%5;"
950 : "mov %5,0x8(%0);"
951 : "add 0xc(%0),%6;"
952 : "mov %6,0xc(%0);"
953 : "add 0x10(%0),%k2;"
954 : "mov %k2,0x10(%0);"
955 : "add 0x14(%0),%7;"
956 : "mov %7,0x14(%0);"
957 : "add 0x18(%0),%8;"
958 : "mov %8,0x18(%0);"
959 : "add 0x1c(%0),%9;"
960 : "mov %9,0x1c(%0);"
961 : "mov %15,%1;"
962 : "add $0x40,%1;"
963 : "cmp %14,%1;"
964 : "jne Lloop0_%=;"
965 :
966 : "Ldone_hash_%=:"
967 :
968 : : "+r"(s), "+r"(chunk), "+r"(blocks), "=r"(a), "=r"(b), "=r"(c), "=r"(d), /* e = chunk */ "=r"(f), "=r"(g), "=r"(h), "=r"(y0), "=r"(y1), "=r"(y2), "=r"(tbl), "+m"(inp_end), "+m"(inp), "+m"(xfer)
969 : : "m"(K256), "m"(FLIP_MASK), "m"(SHUF_00BA), "m"(SHUF_DC00)
970 : : "cc", "memory", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", "xmm8", "xmm9", "xmm10", "xmm11", "xmm12"
971 : );
972 0 : }
973 : }
974 :
975 : /*
976 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
977 : ; Copyright (c) 2012, Intel Corporation
978 : ;
979 : ; All rights reserved.
980 : ;
981 : ; Redistribution and use in source and binary forms, with or without
982 : ; modification, are permitted provided that the following conditions are
983 : ; met:
984 : ;
985 : ; * Redistributions of source code must retain the above copyright
986 : ; notice, this list of conditions and the following disclaimer.
987 : ;
988 : ; * Redistributions in binary form must reproduce the above copyright
989 : ; notice, this list of conditions and the following disclaimer in the
990 : ; documentation and/or other materials provided with the
991 : ; distribution.
992 : ;
993 : ; * Neither the name of the Intel Corporation nor the names of its
994 : ; contributors may be used to endorse or promote products derived from
995 : ; this software without specific prior written permission.
996 : ;
997 : ;
998 : ; THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION "AS IS" AND ANY
999 : ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1000 : ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1001 : ; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
1002 : ; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1003 : ; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1004 : ; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1005 : ; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1006 : ; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1007 : ; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1008 : ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1009 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1010 : ;
1011 : ; Example YASM command lines:
1012 : ; Windows: yasm -Xvc -f x64 -rnasm -pnasm -o sha256_sse4.obj -g cv8 sha256_sse4.asm
1013 : ; Linux: yasm -f x64 -f elf64 -X gnu -g dwarf2 -D LINUX -o sha256_sse4.o sha256_sse4.asm
1014 : ;
1015 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1016 : ;
1017 : ; This code is described in an Intel White-Paper:
1018 : ; "Fast SHA-256 Implementations on Intel Architecture Processors"
1019 : ;
1020 : ; To find it, surf to https://www.intel.com/p/en_US/embedded
1021 : ; and search for that title.
1022 : ; The paper is expected to be released roughly at the end of April, 2012
1023 : ;
1024 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1025 : ; This code schedules 1 blocks at a time, with 4 lanes per block
1026 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1027 :
1028 : %define MOVDQ movdqu ;; assume buffers not aligned
1029 :
1030 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Define Macros
1031 :
1032 : ; addm [mem], reg
1033 : ; Add reg to mem using reg-mem add and store
1034 : %macro addm 2
1035 : add %2, %1
1036 : mov %1, %2
1037 : %endm
1038 :
1039 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1040 :
1041 : ; COPY_XMM_AND_BSWAP xmm, [mem], byte_flip_mask
1042 : ; Load xmm with mem and byte swap each dword
1043 : %macro COPY_XMM_AND_BSWAP 3
1044 : MOVDQ %1, %2
1045 : pshufb %1, %3
1046 : %endmacro
1047 :
1048 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1049 :
1050 : %define X0 xmm4
1051 : %define X1 xmm5
1052 : %define X2 xmm6
1053 : %define X3 xmm7
1054 :
1055 : %define XTMP0 xmm0
1056 : %define XTMP1 xmm1
1057 : %define XTMP2 xmm2
1058 : %define XTMP3 xmm3
1059 : %define XTMP4 xmm8
1060 : %define XFER xmm9
1061 :
1062 : %define SHUF_00BA xmm10 ; shuffle xBxA -> 00BA
1063 : %define SHUF_DC00 xmm11 ; shuffle xDxC -> DC00
1064 : %define BYTE_FLIP_MASK xmm12
1065 :
1066 : %ifdef LINUX
1067 : %define NUM_BLKS rdx ; 3rd arg
1068 : %define CTX rsi ; 2nd arg
1069 : %define INP rdi ; 1st arg
1070 :
1071 : %define SRND rdi ; clobbers INP
1072 : %define c ecx
1073 : %define d r8d
1074 : %define e edx
1075 : %else
1076 : %define NUM_BLKS r8 ; 3rd arg
1077 : %define CTX rdx ; 2nd arg
1078 : %define INP rcx ; 1st arg
1079 :
1080 : %define SRND rcx ; clobbers INP
1081 : %define c edi
1082 : %define d esi
1083 : %define e r8d
1084 :
1085 : %endif
1086 : %define TBL rbp
1087 : %define a eax
1088 : %define b ebx
1089 :
1090 : %define f r9d
1091 : %define g r10d
1092 : %define h r11d
1093 :
1094 : %define y0 r13d
1095 : %define y1 r14d
1096 : %define y2 r15d
1097 :
1098 :
1099 :
1100 : _INP_END_SIZE equ 8
1101 : _INP_SIZE equ 8
1102 : _XFER_SIZE equ 8
1103 : %ifdef LINUX
1104 : _XMM_SAVE_SIZE equ 0
1105 : %else
1106 : _XMM_SAVE_SIZE equ 7*16
1107 : %endif
1108 : ; STACK_SIZE plus pushes must be an odd multiple of 8
1109 : _ALIGN_SIZE equ 8
1110 :
1111 : _INP_END equ 0
1112 : _INP equ _INP_END + _INP_END_SIZE
1113 : _XFER equ _INP + _INP_SIZE
1114 : _XMM_SAVE equ _XFER + _XFER_SIZE + _ALIGN_SIZE
1115 : STACK_SIZE equ _XMM_SAVE + _XMM_SAVE_SIZE
1116 :
1117 : ; rotate_Xs
1118 : ; Rotate values of symbols X0...X3
1119 : %macro rotate_Xs 0
1120 : %xdefine X_ X0
1121 : %xdefine X0 X1
1122 : %xdefine X1 X2
1123 : %xdefine X2 X3
1124 : %xdefine X3 X_
1125 : %endm
1126 :
1127 : ; ROTATE_ARGS
1128 : ; Rotate values of symbols a...h
1129 : %macro ROTATE_ARGS 0
1130 : %xdefine TMP_ h
1131 : %xdefine h g
1132 : %xdefine g f
1133 : %xdefine f e
1134 : %xdefine e d
1135 : %xdefine d c
1136 : %xdefine c b
1137 : %xdefine b a
1138 : %xdefine a TMP_
1139 : %endm
1140 :
1141 : %macro FOUR_ROUNDS_AND_SCHED 0
1142 : ;; compute s0 four at a time and s1 two at a time
1143 : ;; compute W[-16] + W[-7] 4 at a time
1144 : movdqa XTMP0, X3
1145 : mov y0, e ; y0 = e
1146 : ror y0, (25-11) ; y0 = e >> (25-11)
1147 : mov y1, a ; y1 = a
1148 : palignr XTMP0, X2, 4 ; XTMP0 = W[-7]
1149 : ror y1, (22-13) ; y1 = a >> (22-13)
1150 : xor y0, e ; y0 = e ^ (e >> (25-11))
1151 : mov y2, f ; y2 = f
1152 : ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6))
1153 : movdqa XTMP1, X1
1154 : xor y1, a ; y1 = a ^ (a >> (22-13)
1155 : xor y2, g ; y2 = f^g
1156 : paddd XTMP0, X0 ; XTMP0 = W[-7] + W[-16]
1157 : xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
1158 : and y2, e ; y2 = (f^g)&e
1159 : ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2))
1160 : ;; compute s0
1161 : palignr XTMP1, X0, 4 ; XTMP1 = W[-15]
1162 : xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
1163 : ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
1164 : xor y2, g ; y2 = CH = ((f^g)&e)^g
1165 : movdqa XTMP2, XTMP1 ; XTMP2 = W[-15]
1166 : ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
1167 : add y2, y0 ; y2 = S1 + CH
1168 : add y2, [rsp + _XFER + 0*4] ; y2 = k + w + S1 + CH
1169 : movdqa XTMP3, XTMP1 ; XTMP3 = W[-15]
1170 : mov y0, a ; y0 = a
1171 : add h, y2 ; h = h + S1 + CH + k + w
1172 : mov y2, a ; y2 = a
1173 : pslld XTMP1, (32-7)
1174 : or y0, c ; y0 = a|c
1175 : add d, h ; d = d + h + S1 + CH + k + w
1176 : and y2, c ; y2 = a&c
1177 : psrld XTMP2, 7
1178 : and y0, b ; y0 = (a|c)&b
1179 : add h, y1 ; h = h + S1 + CH + k + w + S0
1180 : por XTMP1, XTMP2 ; XTMP1 = W[-15] ror 7
1181 : or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c)
1182 : add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ
1183 :
1184 : ROTATE_ARGS
1185 : movdqa XTMP2, XTMP3 ; XTMP2 = W[-15]
1186 : mov y0, e ; y0 = e
1187 : mov y1, a ; y1 = a
1188 : movdqa XTMP4, XTMP3 ; XTMP4 = W[-15]
1189 : ror y0, (25-11) ; y0 = e >> (25-11)
1190 : xor y0, e ; y0 = e ^ (e >> (25-11))
1191 : mov y2, f ; y2 = f
1192 : ror y1, (22-13) ; y1 = a >> (22-13)
1193 : pslld XTMP3, (32-18)
1194 : xor y1, a ; y1 = a ^ (a >> (22-13)
1195 : ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6))
1196 : xor y2, g ; y2 = f^g
1197 : psrld XTMP2, 18
1198 : ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2))
1199 : xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
1200 : and y2, e ; y2 = (f^g)&e
1201 : ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
1202 : pxor XTMP1, XTMP3
1203 : xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
1204 : xor y2, g ; y2 = CH = ((f^g)&e)^g
1205 : psrld XTMP4, 3 ; XTMP4 = W[-15] >> 3
1206 : add y2, y0 ; y2 = S1 + CH
1207 : add y2, [rsp + _XFER + 1*4] ; y2 = k + w + S1 + CH
1208 : ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
1209 : pxor XTMP1, XTMP2 ; XTMP1 = W[-15] ror 7 ^ W[-15] ror 18
1210 : mov y0, a ; y0 = a
1211 : add h, y2 ; h = h + S1 + CH + k + w
1212 : mov y2, a ; y2 = a
1213 : pxor XTMP1, XTMP4 ; XTMP1 = s0
1214 : or y0, c ; y0 = a|c
1215 : add d, h ; d = d + h + S1 + CH + k + w
1216 : and y2, c ; y2 = a&c
1217 : ;; compute low s1
1218 : pshufd XTMP2, X3, 11111010b ; XTMP2 = W[-2] {BBAA}
1219 : and y0, b ; y0 = (a|c)&b
1220 : add h, y1 ; h = h + S1 + CH + k + w + S0
1221 : paddd XTMP0, XTMP1 ; XTMP0 = W[-16] + W[-7] + s0
1222 : or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c)
1223 : add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ
1224 :
1225 : ROTATE_ARGS
1226 : movdqa XTMP3, XTMP2 ; XTMP3 = W[-2] {BBAA}
1227 : mov y0, e ; y0 = e
1228 : mov y1, a ; y1 = a
1229 : ror y0, (25-11) ; y0 = e >> (25-11)
1230 : movdqa XTMP4, XTMP2 ; XTMP4 = W[-2] {BBAA}
1231 : xor y0, e ; y0 = e ^ (e >> (25-11))
1232 : ror y1, (22-13) ; y1 = a >> (22-13)
1233 : mov y2, f ; y2 = f
1234 : xor y1, a ; y1 = a ^ (a >> (22-13)
1235 : ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6))
1236 : psrlq XTMP2, 17 ; XTMP2 = W[-2] ror 17 {xBxA}
1237 : xor y2, g ; y2 = f^g
1238 : psrlq XTMP3, 19 ; XTMP3 = W[-2] ror 19 {xBxA}
1239 : xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
1240 : and y2, e ; y2 = (f^g)&e
1241 : psrld XTMP4, 10 ; XTMP4 = W[-2] >> 10 {BBAA}
1242 : ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2))
1243 : xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
1244 : xor y2, g ; y2 = CH = ((f^g)&e)^g
1245 : ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
1246 : pxor XTMP2, XTMP3
1247 : add y2, y0 ; y2 = S1 + CH
1248 : ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
1249 : add y2, [rsp + _XFER + 2*4] ; y2 = k + w + S1 + CH
1250 : pxor XTMP4, XTMP2 ; XTMP4 = s1 {xBxA}
1251 : mov y0, a ; y0 = a
1252 : add h, y2 ; h = h + S1 + CH + k + w
1253 : mov y2, a ; y2 = a
1254 : pshufb XTMP4, SHUF_00BA ; XTMP4 = s1 {00BA}
1255 : or y0, c ; y0 = a|c
1256 : add d, h ; d = d + h + S1 + CH + k + w
1257 : and y2, c ; y2 = a&c
1258 : paddd XTMP0, XTMP4 ; XTMP0 = {..., ..., W[1], W[0]}
1259 : and y0, b ; y0 = (a|c)&b
1260 : add h, y1 ; h = h + S1 + CH + k + w + S0
1261 : ;; compute high s1
1262 : pshufd XTMP2, XTMP0, 01010000b ; XTMP2 = W[-2] {DDCC}
1263 : or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c)
1264 : add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ
1265 :
1266 : ROTATE_ARGS
1267 : movdqa XTMP3, XTMP2 ; XTMP3 = W[-2] {DDCC}
1268 : mov y0, e ; y0 = e
1269 : ror y0, (25-11) ; y0 = e >> (25-11)
1270 : mov y1, a ; y1 = a
1271 : movdqa X0, XTMP2 ; X0 = W[-2] {DDCC}
1272 : ror y1, (22-13) ; y1 = a >> (22-13)
1273 : xor y0, e ; y0 = e ^ (e >> (25-11))
1274 : mov y2, f ; y2 = f
1275 : ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6))
1276 : psrlq XTMP2, 17 ; XTMP2 = W[-2] ror 17 {xDxC}
1277 : xor y1, a ; y1 = a ^ (a >> (22-13)
1278 : xor y2, g ; y2 = f^g
1279 : psrlq XTMP3, 19 ; XTMP3 = W[-2] ror 19 {xDxC}
1280 : xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
1281 : and y2, e ; y2 = (f^g)&e
1282 : ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2))
1283 : psrld X0, 10 ; X0 = W[-2] >> 10 {DDCC}
1284 : xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
1285 : ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
1286 : xor y2, g ; y2 = CH = ((f^g)&e)^g
1287 : pxor XTMP2, XTMP3
1288 : ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
1289 : add y2, y0 ; y2 = S1 + CH
1290 : add y2, [rsp + _XFER + 3*4] ; y2 = k + w + S1 + CH
1291 : pxor X0, XTMP2 ; X0 = s1 {xDxC}
1292 : mov y0, a ; y0 = a
1293 : add h, y2 ; h = h + S1 + CH + k + w
1294 : mov y2, a ; y2 = a
1295 : pshufb X0, SHUF_DC00 ; X0 = s1 {DC00}
1296 : or y0, c ; y0 = a|c
1297 : add d, h ; d = d + h + S1 + CH + k + w
1298 : and y2, c ; y2 = a&c
1299 : paddd X0, XTMP0 ; X0 = {W[3], W[2], W[1], W[0]}
1300 : and y0, b ; y0 = (a|c)&b
1301 : add h, y1 ; h = h + S1 + CH + k + w + S0
1302 : or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c)
1303 : add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ
1304 :
1305 : ROTATE_ARGS
1306 : rotate_Xs
1307 : %endm
1308 :
1309 : ;; input is [rsp + _XFER + %1 * 4]
1310 : %macro DO_ROUND 1
1311 : mov y0, e ; y0 = e
1312 : ror y0, (25-11) ; y0 = e >> (25-11)
1313 : mov y1, a ; y1 = a
1314 : xor y0, e ; y0 = e ^ (e >> (25-11))
1315 : ror y1, (22-13) ; y1 = a >> (22-13)
1316 : mov y2, f ; y2 = f
1317 : xor y1, a ; y1 = a ^ (a >> (22-13)
1318 : ror y0, (11-6) ; y0 = (e >> (11-6)) ^ (e >> (25-6))
1319 : xor y2, g ; y2 = f^g
1320 : xor y0, e ; y0 = e ^ (e >> (11-6)) ^ (e >> (25-6))
1321 : ror y1, (13-2) ; y1 = (a >> (13-2)) ^ (a >> (22-2))
1322 : and y2, e ; y2 = (f^g)&e
1323 : xor y1, a ; y1 = a ^ (a >> (13-2)) ^ (a >> (22-2))
1324 : ror y0, 6 ; y0 = S1 = (e>>6) & (e>>11) ^ (e>>25)
1325 : xor y2, g ; y2 = CH = ((f^g)&e)^g
1326 : add y2, y0 ; y2 = S1 + CH
1327 : ror y1, 2 ; y1 = S0 = (a>>2) ^ (a>>13) ^ (a>>22)
1328 : add y2, [rsp + _XFER + %1 * 4] ; y2 = k + w + S1 + CH
1329 : mov y0, a ; y0 = a
1330 : add h, y2 ; h = h + S1 + CH + k + w
1331 : mov y2, a ; y2 = a
1332 : or y0, c ; y0 = a|c
1333 : add d, h ; d = d + h + S1 + CH + k + w
1334 : and y2, c ; y2 = a&c
1335 : and y0, b ; y0 = (a|c)&b
1336 : add h, y1 ; h = h + S1 + CH + k + w + S0
1337 : or y0, y2 ; y0 = MAJ = (a|c)&b)|(a&c)
1338 : add h, y0 ; h = h + S1 + CH + k + w + S0 + MAJ
1339 : ROTATE_ARGS
1340 : %endm
1341 :
1342 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1343 : ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1344 : ;; void sha256_sse4(void *input_data, UINT32 digest[8], UINT64 num_blks)
1345 : ;; arg 1 : pointer to input data
1346 : ;; arg 2 : pointer to digest
1347 : ;; arg 3 : Num blocks
1348 : section .text
1349 : global sha256_sse4
1350 : align 32
1351 : sha256_sse4:
1352 : push rbx
1353 : %ifndef LINUX
1354 : push rsi
1355 : push rdi
1356 : %endif
1357 : push rbp
1358 : push r13
1359 : push r14
1360 : push r15
1361 :
1362 : sub rsp,STACK_SIZE
1363 : %ifndef LINUX
1364 : movdqa [rsp + _XMM_SAVE + 0*16],xmm6
1365 : movdqa [rsp + _XMM_SAVE + 1*16],xmm7
1366 : movdqa [rsp + _XMM_SAVE + 2*16],xmm8
1367 : movdqa [rsp + _XMM_SAVE + 3*16],xmm9
1368 : movdqa [rsp + _XMM_SAVE + 4*16],xmm10
1369 : movdqa [rsp + _XMM_SAVE + 5*16],xmm11
1370 : movdqa [rsp + _XMM_SAVE + 6*16],xmm12
1371 : %endif
1372 :
1373 : shl NUM_BLKS, 6 ; convert to bytes
1374 : jz done_hash
1375 : add NUM_BLKS, INP ; pointer to end of data
1376 : mov [rsp + _INP_END], NUM_BLKS
1377 :
1378 : ;; load initial digest
1379 : mov a,[4*0 + CTX]
1380 : mov b,[4*1 + CTX]
1381 : mov c,[4*2 + CTX]
1382 : mov d,[4*3 + CTX]
1383 : mov e,[4*4 + CTX]
1384 : mov f,[4*5 + CTX]
1385 : mov g,[4*6 + CTX]
1386 : mov h,[4*7 + CTX]
1387 :
1388 : movdqa BYTE_FLIP_MASK, [PSHUFFLE_BYTE_FLIP_MASK wrt rip]
1389 : movdqa SHUF_00BA, [_SHUF_00BA wrt rip]
1390 : movdqa SHUF_DC00, [_SHUF_DC00 wrt rip]
1391 :
1392 : loop0:
1393 : lea TBL,[K256 wrt rip]
1394 :
1395 : ;; byte swap first 16 dwords
1396 : COPY_XMM_AND_BSWAP X0, [INP + 0*16], BYTE_FLIP_MASK
1397 : COPY_XMM_AND_BSWAP X1, [INP + 1*16], BYTE_FLIP_MASK
1398 : COPY_XMM_AND_BSWAP X2, [INP + 2*16], BYTE_FLIP_MASK
1399 : COPY_XMM_AND_BSWAP X3, [INP + 3*16], BYTE_FLIP_MASK
1400 :
1401 : mov [rsp + _INP], INP
1402 :
1403 : ;; schedule 48 input dwords, by doing 3 rounds of 16 each
1404 : mov SRND, 3
1405 : align 16
1406 : loop1:
1407 : movdqa XFER, [TBL + 0*16]
1408 : paddd XFER, X0
1409 : movdqa [rsp + _XFER], XFER
1410 : FOUR_ROUNDS_AND_SCHED
1411 :
1412 : movdqa XFER, [TBL + 1*16]
1413 : paddd XFER, X0
1414 : movdqa [rsp + _XFER], XFER
1415 : FOUR_ROUNDS_AND_SCHED
1416 :
1417 : movdqa XFER, [TBL + 2*16]
1418 : paddd XFER, X0
1419 : movdqa [rsp + _XFER], XFER
1420 : FOUR_ROUNDS_AND_SCHED
1421 :
1422 : movdqa XFER, [TBL + 3*16]
1423 : paddd XFER, X0
1424 : movdqa [rsp + _XFER], XFER
1425 : add TBL, 4*16
1426 : FOUR_ROUNDS_AND_SCHED
1427 :
1428 : sub SRND, 1
1429 : jne loop1
1430 :
1431 : mov SRND, 2
1432 : loop2:
1433 : paddd X0, [TBL + 0*16]
1434 : movdqa [rsp + _XFER], X0
1435 : DO_ROUND 0
1436 : DO_ROUND 1
1437 : DO_ROUND 2
1438 : DO_ROUND 3
1439 : paddd X1, [TBL + 1*16]
1440 : movdqa [rsp + _XFER], X1
1441 : add TBL, 2*16
1442 : DO_ROUND 0
1443 : DO_ROUND 1
1444 : DO_ROUND 2
1445 : DO_ROUND 3
1446 :
1447 : movdqa X0, X2
1448 : movdqa X1, X3
1449 :
1450 : sub SRND, 1
1451 : jne loop2
1452 :
1453 : addm [4*0 + CTX],a
1454 : addm [4*1 + CTX],b
1455 : addm [4*2 + CTX],c
1456 : addm [4*3 + CTX],d
1457 : addm [4*4 + CTX],e
1458 : addm [4*5 + CTX],f
1459 : addm [4*6 + CTX],g
1460 : addm [4*7 + CTX],h
1461 :
1462 : mov INP, [rsp + _INP]
1463 : add INP, 64
1464 : cmp INP, [rsp + _INP_END]
1465 : jne loop0
1466 :
1467 : done_hash:
1468 : %ifndef LINUX
1469 : movdqa xmm6,[rsp + _XMM_SAVE + 0*16]
1470 : movdqa xmm7,[rsp + _XMM_SAVE + 1*16]
1471 : movdqa xmm8,[rsp + _XMM_SAVE + 2*16]
1472 : movdqa xmm9,[rsp + _XMM_SAVE + 3*16]
1473 : movdqa xmm10,[rsp + _XMM_SAVE + 4*16]
1474 : movdqa xmm11,[rsp + _XMM_SAVE + 5*16]
1475 : movdqa xmm12,[rsp + _XMM_SAVE + 6*16]
1476 : %endif
1477 :
1478 : add rsp, STACK_SIZE
1479 :
1480 : pop r15
1481 : pop r14
1482 : pop r13
1483 : pop rbp
1484 : %ifndef LINUX
1485 : pop rdi
1486 : pop rsi
1487 : %endif
1488 : pop rbx
1489 :
1490 : ret
1491 :
1492 :
1493 : section .data
1494 : align 64
1495 : K256:
1496 : dd 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5
1497 : dd 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5
1498 : dd 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3
1499 : dd 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174
1500 : dd 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc
1501 : dd 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da
1502 : dd 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7
1503 : dd 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967
1504 : dd 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13
1505 : dd 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85
1506 : dd 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3
1507 : dd 0xd192e819,0xd6990624,0xf40e3585,0x106aa070
1508 : dd 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5
1509 : dd 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3
1510 : dd 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208
1511 : dd 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
1512 :
1513 : PSHUFFLE_BYTE_FLIP_MASK: ddq 0x0c0d0e0f08090a0b0405060700010203
1514 :
1515 : ; shuffle xBxA -> 00BA
1516 : _SHUF_00BA: ddq 0xFFFFFFFFFFFFFFFF0b0a090803020100
1517 :
1518 : ; shuffle xDxC -> DC00
1519 : _SHUF_DC00: ddq 0x0b0a090803020100FFFFFFFFFFFFFFFF
1520 : */
1521 :
1522 : #endif
|