| 21 | } // namespace |
| 22 | |
| 23 | void KeccakF(uint64_t (&st)[25]) |
| 24 | { |
| 25 | static constexpr uint64_t RNDC[24] = { |
| 26 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, 0x8000000080008000, |
| 27 | 0x000000000000808b, 0x0000000080000001, 0x8000000080008081, 0x8000000000008009, |
| 28 | 0x000000000000008a, 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, |
| 29 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, 0x8000000000008003, |
| 30 | 0x8000000000008002, 0x8000000000000080, 0x000000000000800a, 0x800000008000000a, |
| 31 | 0x8000000080008081, 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 |
| 32 | }; |
| 33 | static constexpr int ROUNDS = 24; |
| 34 | |
| 35 | for (int round = 0; round < ROUNDS; ++round) { |
| 36 | uint64_t bc0, bc1, bc2, bc3, bc4, t; |
| 37 | |
| 38 | // Theta |
| 39 | bc0 = st[0] ^ st[5] ^ st[10] ^ st[15] ^ st[20]; |
| 40 | bc1 = st[1] ^ st[6] ^ st[11] ^ st[16] ^ st[21]; |
| 41 | bc2 = st[2] ^ st[7] ^ st[12] ^ st[17] ^ st[22]; |
| 42 | bc3 = st[3] ^ st[8] ^ st[13] ^ st[18] ^ st[23]; |
| 43 | bc4 = st[4] ^ st[9] ^ st[14] ^ st[19] ^ st[24]; |
| 44 | t = bc4 ^ Rotl(bc1, 1); st[0] ^= t; st[5] ^= t; st[10] ^= t; st[15] ^= t; st[20] ^= t; |
| 45 | t = bc0 ^ Rotl(bc2, 1); st[1] ^= t; st[6] ^= t; st[11] ^= t; st[16] ^= t; st[21] ^= t; |
| 46 | t = bc1 ^ Rotl(bc3, 1); st[2] ^= t; st[7] ^= t; st[12] ^= t; st[17] ^= t; st[22] ^= t; |
| 47 | t = bc2 ^ Rotl(bc4, 1); st[3] ^= t; st[8] ^= t; st[13] ^= t; st[18] ^= t; st[23] ^= t; |
| 48 | t = bc3 ^ Rotl(bc0, 1); st[4] ^= t; st[9] ^= t; st[14] ^= t; st[19] ^= t; st[24] ^= t; |
| 49 | |
| 50 | // Rho Pi |
| 51 | t = st[1]; |
| 52 | bc0 = st[10]; st[10] = Rotl(t, 1); t = bc0; |
| 53 | bc0 = st[7]; st[7] = Rotl(t, 3); t = bc0; |
| 54 | bc0 = st[11]; st[11] = Rotl(t, 6); t = bc0; |
| 55 | bc0 = st[17]; st[17] = Rotl(t, 10); t = bc0; |
| 56 | bc0 = st[18]; st[18] = Rotl(t, 15); t = bc0; |
| 57 | bc0 = st[3]; st[3] = Rotl(t, 21); t = bc0; |
| 58 | bc0 = st[5]; st[5] = Rotl(t, 28); t = bc0; |
| 59 | bc0 = st[16]; st[16] = Rotl(t, 36); t = bc0; |
| 60 | bc0 = st[8]; st[8] = Rotl(t, 45); t = bc0; |
| 61 | bc0 = st[21]; st[21] = Rotl(t, 55); t = bc0; |
| 62 | bc0 = st[24]; st[24] = Rotl(t, 2); t = bc0; |
| 63 | bc0 = st[4]; st[4] = Rotl(t, 14); t = bc0; |
| 64 | bc0 = st[15]; st[15] = Rotl(t, 27); t = bc0; |
| 65 | bc0 = st[23]; st[23] = Rotl(t, 41); t = bc0; |
| 66 | bc0 = st[19]; st[19] = Rotl(t, 56); t = bc0; |
| 67 | bc0 = st[13]; st[13] = Rotl(t, 8); t = bc0; |
| 68 | bc0 = st[12]; st[12] = Rotl(t, 25); t = bc0; |
| 69 | bc0 = st[2]; st[2] = Rotl(t, 43); t = bc0; |
| 70 | bc0 = st[20]; st[20] = Rotl(t, 62); t = bc0; |
| 71 | bc0 = st[14]; st[14] = Rotl(t, 18); t = bc0; |
| 72 | bc0 = st[22]; st[22] = Rotl(t, 39); t = bc0; |
| 73 | bc0 = st[9]; st[9] = Rotl(t, 61); t = bc0; |
| 74 | bc0 = st[6]; st[6] = Rotl(t, 20); t = bc0; |
| 75 | st[1] = Rotl(t, 44); |
| 76 | |
| 77 | // Chi Iota |
| 78 | bc0 = st[0]; bc1 = st[1]; bc2 = st[2]; bc3 = st[3]; bc4 = st[4]; |
| 79 | st[0] = bc0 ^ (~bc1 & bc2) ^ RNDC[round]; |
| 80 | st[1] = bc1 ^ (~bc2 & bc3); |