Line data Source code
1 : #ifndef HEADER_fd_src_ballet_keccak256_fd_keccak256_private_h
2 : #define HEADER_fd_src_ballet_keccak256_fd_keccak256_private_h
3 :
4 : #include "../fd_ballet_base.h"
5 :
6 : FD_PROTOTYPES_BEGIN
7 :
8 : /* The implementation below was derived from the original Keccak spec.
9 : See in particular:
10 :
11 : https://keccak.team/keccak_specs_summary.html
12 :
13 : It is straightforward to replace these implementations with HPC
14 : implementations that target specific machine capabilities without
15 : requiring any changes to caller code. */
16 :
17 : static inline void
18 7206801 : fd_keccak256_core( ulong * state ) {
19 7206801 : ulong const round_consts[24] = {
20 7206801 : 0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL, 0x8000000080008000UL,
21 7206801 : 0x000000000000808BUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL,
22 7206801 : 0x000000000000008AUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL,
23 7206801 : 0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL, 0x8000000000008003UL,
24 7206801 : 0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800AUL, 0x800000008000000AUL,
25 7206801 : 0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
26 7206801 : };
27 :
28 7206801 : static uchar const rho_consts[24] = {
29 7206801 : 1, 3, 6, 10,
30 7206801 : 15, 21, 28, 36,
31 7206801 : 45, 55, 2, 14,
32 7206801 : 27, 41, 56, 8,
33 7206801 : 25, 43, 62, 18,
34 7206801 : 39, 61, 20, 44
35 7206801 : };
36 :
37 7206801 : static uchar const pi_consts[24] = {
38 7206801 : 10, 7, 11, 17,
39 7206801 : 18, 3, 5, 16,
40 7206801 : 8, 21, 24, 4,
41 7206801 : 15, 23, 19, 13,
42 7206801 : 12, 2, 20, 14,
43 7206801 : 22, 9, 6, 1
44 7206801 : };
45 :
46 180170025 : # define NUM_ROUNDS (24)
47 5015933496 : # define ROTATE fd_ulong_rotate_left
48 :
49 7206801 : ulong b[5];
50 7206801 : ulong t;
51 :
52 180170025 : for( ulong round = 0; round < NUM_ROUNDS; round++ ) {
53 : // Theta step
54 1037779344 : for( ulong i = 0; i < 5; i++ ) {
55 864816120 : b[i] = (state[i] ^ state[i+5] ^ state[i+10] ^ state[i+15] ^ state[i+20]);
56 864816120 : }
57 :
58 1037779344 : for( ulong i = 0; i < 5; i++ ) {
59 864816120 : t = b[(i+4) % 5] ^ ROTATE(b[(i+1) % 5], 1);
60 :
61 5188896720 : for( ulong j = 0; j < 25; j += 5 ) {
62 4324080600 : state[i+j] ^= t;
63 4324080600 : }
64 864816120 : }
65 :
66 : // Rho and pi steps
67 172963224 : t = state[1];
68 4324080600 : for( ulong i = 0; i < 24; i++ ) {
69 4151117376 : ulong pi_val = pi_consts[i];
70 4151117376 : int rho_val = rho_consts[i];
71 4151117376 : b[0] = state[pi_val];
72 4151117376 : state[pi_val] = ROTATE(t, rho_val);
73 4151117376 : t = b[0];
74 4151117376 : }
75 :
76 : // Chi step
77 1037779344 : for( ulong i = 0; i < 25; i += 5 ) {
78 5188896720 : for( ulong j = 0; j < 5; j++ ) {
79 4324080600 : b[j] = state[i+j];
80 4324080600 : }
81 5188896720 : for( ulong j = 0; j < 5; j++ ) {
82 4324080600 : state[i+j] ^= (~b[(j+1) % 5]) & (b[(j+2) % 5]);
83 4324080600 : }
84 864816120 : }
85 :
86 : // Iota step
87 172963224 : state[0] ^= round_consts[round];
88 172963224 : }
89 :
90 7206801 : # undef NUM_ROUNDS
91 7206801 : # undef ROTATE
92 7206801 : }
93 :
94 : FD_PROTOTYPES_END
95 :
96 : #endif /* HEADER_fd_src_ballet_keccak256_fd_keccak256_private_h */
|