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 1254 : fd_keccak256_core( ulong * state ) {
19 1254 : ulong const round_consts[24] = {
20 1254 : 0x0000000000000001UL, 0x0000000000008082UL, 0x800000000000808AUL, 0x8000000080008000UL,
21 1254 : 0x000000000000808BUL, 0x0000000080000001UL, 0x8000000080008081UL, 0x8000000000008009UL,
22 1254 : 0x000000000000008AUL, 0x0000000000000088UL, 0x0000000080008009UL, 0x000000008000000AUL,
23 1254 : 0x000000008000808BUL, 0x800000000000008BUL, 0x8000000000008089UL, 0x8000000000008003UL,
24 1254 : 0x8000000000008002UL, 0x8000000000000080UL, 0x000000000000800AUL, 0x800000008000000AUL,
25 1254 : 0x8000000080008081UL, 0x8000000000008080UL, 0x0000000080000001UL, 0x8000000080008008UL
26 1254 : };
27 :
28 1254 : static uchar const rho_consts[24] = {
29 1254 : 1, 3, 6, 10,
30 1254 : 15, 21, 28, 36,
31 1254 : 45, 55, 2, 14,
32 1254 : 27, 41, 56, 8,
33 1254 : 25, 43, 62, 18,
34 1254 : 39, 61, 20, 44
35 1254 : };
36 :
37 1254 : static uchar const pi_consts[24] = {
38 1254 : 10, 7, 11, 17,
39 1254 : 18, 3, 5, 16,
40 1254 : 8, 21, 24, 4,
41 1254 : 15, 23, 19, 13,
42 1254 : 12, 2, 20, 14,
43 1254 : 22, 9, 6, 1
44 1254 : };
45 :
46 30924 : # define NUM_ROUNDS (24)
47 833911 : # define ROTATE fd_ulong_rotate_left
48 :
49 1254 : ulong b[5];
50 1254 : ulong t;
51 :
52 30924 : for( ulong round = 0; round < NUM_ROUNDS; round++ ) {
53 : // Theta step
54 178370 : for( ulong i = 0; i < 5; i++ ) {
55 148700 : b[i] = (state[i] ^ state[i+5] ^ state[i+10] ^ state[i+15] ^ state[i+20]);
56 148700 : }
57 :
58 172872 : for( ulong i = 0; i < 5; i++ ) {
59 143202 : t = b[(i+4) % 5] ^ ROTATE(b[(i+1) % 5], 1);
60 :
61 852026 : for( ulong j = 0; j < 25; j += 5 ) {
62 708824 : state[i+j] ^= t;
63 708824 : }
64 143202 : }
65 :
66 : // Rho and pi steps
67 29670 : t = state[1];
68 720379 : for( ulong i = 0; i < 24; i++ ) {
69 690709 : ulong pi_val = pi_consts[i];
70 690709 : int rho_val = rho_consts[i];
71 690709 : b[0] = state[pi_val];
72 690709 : state[pi_val] = ROTATE(t, rho_val);
73 690709 : t = b[0];
74 690709 : }
75 :
76 : // Chi step
77 175316 : for( ulong i = 0; i < 25; i += 5 ) {
78 872679 : for( ulong j = 0; j < 5; j++ ) {
79 727033 : b[j] = state[i+j];
80 727033 : }
81 860999 : for( ulong j = 0; j < 5; j++ ) {
82 715353 : state[i+j] ^= (~b[(j+1) % 5]) & (b[(j+2) % 5]);
83 715353 : }
84 145646 : }
85 :
86 : // Iota step
87 29670 : state[0] ^= round_consts[round];
88 29670 : }
89 :
90 1254 : # undef NUM_ROUNDS
91 1254 : # undef ROTATE
92 1254 : }
93 :
94 : FD_PROTOTYPES_END
95 :
96 : #endif /* HEADER_fd_src_ballet_keccak256_fd_keccak256_private_h */
|