|
1 | 1 | // AArch64 NEON implementation of Argon2 FillBlock (BlaMka round function). |
2 | 2 | // |
3 | | -// Reference: HashLib Argon2FillBlockSse2_x86_64.inc (FillBlock semantics); |
4 | | -// libsodium blamka-round-neon.h (fBlaMka, vext diagonalize on AArch64). |
| 3 | +// Reference: jedisct1/libsodium crypto_pwhash/argon2/argon2-fill-block-neon.c, |
| 4 | +// crypto_pwhash/argon2/blamka-round-neon.h; HashLib Argon2FillBlockSse2_x86_64.inc. |
5 | 5 | // |
6 | 6 | // Expects AAPCS64: x0 = Left ptr, x1 = Right ptr, x2 = Current ptr, w3 = WithXor. |
7 | 7 | // Each pointer addresses 128 UInt64 (1024 bytes). |
8 | 8 | // Uses v0-v7 (A/B/C/D pairs), v16-v18 temps; caller-saved only, leaf nostackframe. |
9 | | -// Stack: 2128 bytes (R_buf + Z_buf + AAPCS64 16-byte SP alignment padding). |
| 9 | +// Stack: 2128 bytes — R_buf at [sp+64], Z_buf at [sp+1088], plus 16-byte SP pad. |
10 | 10 | // x9 = R_buf, x11 = Z_buf during rounds; x2/w3 survive all loops. |
11 | 11 | // |
12 | | -// Steps (match SSE2): |
| 12 | +// Steps (same semantics as SSE2): |
13 | 13 | // 1. R_buf = Left XOR Right |
14 | 14 | // 2. Z_buf = copy(R_buf) |
15 | 15 | // 3. Eight column rounds on Z_buf (128-byte slices) |
16 | 16 | // 4. Eight row rounds on Z_buf (stride-16 qword access) |
17 | 17 | // 5. Current = R_buf XOR Z_buf [XOR Current if WithXor <> 0] |
| 18 | +// Indexed loads/stores in steps 1/2/5: ldr/str qN, [xBase, x10]. |
| 19 | +// Column/row slices: x12 = x11 + x10, then ldr/str qN, [x12, #imm]. |
| 20 | +// Diagonalize uses vext #8 (blamka-round-neon.h), not SSE2 shufpd. |
18 | 21 | // |
19 | 22 | // Instruction encodings (for assembler compatibility): |
20 | 23 | // FPC 3.2.2's inline assembler cannot encode AArch64 vector mnemonics |
21 | 24 | // (subscripted vector regs require FPC 3.3+, and ldr/str/ldp with qN crash the |
22 | 25 | // 3.2.2 assembler). Each such instruction is therefore emitted as its raw 32-bit |
23 | 26 | // '.long' opcode, with the equivalent mnemonic in the trailing comment; only |
24 | | -// stack/loop/branch/ret mnemonics stay as text. |
| 27 | +// add/mov/cmp/sub/cbz/b.lo/b/ret stay as text (never ldr/str/ldp with qN). |
25 | 28 | // |
26 | | -// Register map during G rounds: |
| 29 | +// Register map: |
27 | 30 | // v0-v1 = A0, A1 |
28 | 31 | // v2-v3 = B0, B1 |
29 | 32 | // v4-v5 = C0, C1 |
30 | 33 | // v6-v7 = D0, D1 |
31 | 34 | // v16-v18 = fBlaMka / rotr temps |
32 | | -// x9 = R_buf base |
33 | | -// x11 = Z_buf base |
34 | | -// x10 = loop offset |
| 35 | +// x9 = R_buf base ([sp+64]) |
| 36 | +// x10 = loop byte offset (steps 1-5) |
| 37 | +// x11 = Z_buf base ([sp+1088]) |
| 38 | +// x12 = Z slice pointer (column/row load/store) |
35 | 39 | // w3 = WithXor (0 or 1) |
36 | 40 | sub sp, sp, #2128 |
37 | 41 | add x9, sp, #64 |
38 | 42 | mov x10, #0 |
39 | 43 | .Largon2_xor_loop: |
40 | | - ldr q0, [x0, x10] |
41 | | - ldr q1, [x1, x10] |
| 44 | + .long 0x3cea6800 // ldr q0, [x0, x10] |
| 45 | + .long 0x3cea6821 // ldr q1, [x1, x10] |
42 | 46 | .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b |
43 | | - str q0, [x9, x10] |
| 47 | + .long 0x3caa6920 // str q0, [x9, x10] |
44 | 48 | add x10, x10, #16 |
45 | 49 | cmp x10, #1024 |
46 | 50 | b.lo .Largon2_xor_loop |
47 | 51 | add x11, sp, #1088 |
48 | 52 | mov x10, #0 |
49 | 53 | .Largon2_copy_loop: |
50 | | - ldr q0, [x9, x10] |
51 | | - str q0, [x11, x10] |
| 54 | + .long 0x3cea6920 // ldr q0, [x9, x10] |
| 55 | + .long 0x3caa6960 // str q0, [x11, x10] |
52 | 56 | add x10, x10, #16 |
53 | 57 | cmp x10, #1024 |
54 | 58 | b.lo .Largon2_copy_loop |
|
449 | 453 | cbz w3, .Largon2_final_noxor |
450 | 454 | mov x10, #0 |
451 | 455 | .Largon2_final_xor_loop: |
452 | | - ldr q0, [x9, x10] |
453 | | - ldr q1, [x11, x10] |
454 | | - ldr q2, [x2, x10] |
| 456 | + .long 0x3cea6920 // ldr q0, [x9, x10] |
| 457 | + .long 0x3cea6961 // ldr q1, [x11, x10] |
| 458 | + .long 0x3cea6842 // ldr q2, [x2, x10] |
455 | 459 | .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b |
456 | 460 | .long 0x6e221c00 // eor v0.16b, v0.16b, v2.16b |
457 | | - str q0, [x2, x10] |
| 461 | + .long 0x3caa6840 // str q0, [x2, x10] |
458 | 462 | add x10, x10, #16 |
459 | 463 | cmp x10, #1024 |
460 | 464 | b.lo .Largon2_final_xor_loop |
461 | 465 | b .Largon2_epilogue |
462 | 466 | .Largon2_final_noxor: |
463 | 467 | mov x10, #0 |
464 | 468 | .Largon2_final_noxor_loop: |
465 | | - ldr q0, [x9, x10] |
466 | | - ldr q1, [x11, x10] |
| 469 | + .long 0x3cea6920 // ldr q0, [x9, x10] |
| 470 | + .long 0x3cea6961 // ldr q1, [x11, x10] |
467 | 471 | .long 0x6e211c00 // eor v0.16b, v0.16b, v1.16b |
468 | | - str q0, [x2, x10] |
| 472 | + .long 0x3caa6840 // str q0, [x2, x10] |
469 | 473 | add x10, x10, #16 |
470 | 474 | cmp x10, #1024 |
471 | 475 | b.lo .Largon2_final_noxor_loop |
|
0 commit comments