scalar-perm.h (5733B)
1 #ifndef FINWO_SCALAR_PERM_H 2 #define FINWO_SCALAR_PERM_H 3 4 /* Keccak-p[1600] with the 25 lanes held in named locals rather than an indexed 5 array, so the scheduler can keep them in registers; theta is fused into the 6 previous round's chi (prepareTheta) and the round loop is unrolled 4x. */ 7 8 #define KFP_LOAD(P, S) \ 9 P##0 = S[0]; \ 10 P##1 = S[1]; \ 11 P##2 = S[2]; \ 12 P##3 = S[3]; \ 13 P##4 = S[4]; \ 14 P##5 = S[5]; \ 15 P##6 = S[6]; \ 16 P##7 = S[7]; \ 17 P##8 = S[8]; \ 18 P##9 = S[9]; \ 19 P##10 = S[10]; \ 20 P##11 = S[11]; \ 21 P##12 = S[12]; \ 22 P##13 = S[13]; \ 23 P##14 = S[14]; \ 24 P##15 = S[15]; \ 25 P##16 = S[16]; \ 26 P##17 = S[17]; \ 27 P##18 = S[18]; \ 28 P##19 = S[19]; \ 29 P##20 = S[20]; \ 30 P##21 = S[21]; \ 31 P##22 = S[22]; \ 32 P##23 = S[23]; \ 33 P##24 = S[24]; \ 34 35 #define KFP_STORE(S, P) \ 36 S[0] = P##0; \ 37 S[1] = P##1; \ 38 S[2] = P##2; \ 39 S[3] = P##3; \ 40 S[4] = P##4; \ 41 S[5] = P##5; \ 42 S[6] = P##6; \ 43 S[7] = P##7; \ 44 S[8] = P##8; \ 45 S[9] = P##9; \ 46 S[10] = P##10; \ 47 S[11] = P##11; \ 48 S[12] = P##12; \ 49 S[13] = P##13; \ 50 S[14] = P##14; \ 51 S[15] = P##15; \ 52 S[16] = P##16; \ 53 S[17] = P##17; \ 54 S[18] = P##18; \ 55 S[19] = P##19; \ 56 S[20] = P##20; \ 57 S[21] = P##21; \ 58 S[22] = P##22; \ 59 S[23] = P##23; \ 60 S[24] = P##24; \ 61 62 #define KFP_INIT_C(SRC) \ 63 c0 = SRC##0 ^ SRC##5 ^ SRC##10 ^ SRC##15 ^ SRC##20; \ 64 c1 = SRC##1 ^ SRC##6 ^ SRC##11 ^ SRC##16 ^ SRC##21; \ 65 c2 = SRC##2 ^ SRC##7 ^ SRC##12 ^ SRC##17 ^ SRC##22; \ 66 c3 = SRC##3 ^ SRC##8 ^ SRC##13 ^ SRC##18 ^ SRC##23; \ 67 c4 = SRC##4 ^ SRC##9 ^ SRC##14 ^ SRC##19 ^ SRC##24; \ 68 69 #define KFP_R(SRC, DST, RCIDX) \ 70 d0 = c4 ^ rol(c1, 1); \ 71 d1 = c0 ^ rol(c2, 1); \ 72 d2 = c1 ^ rol(c3, 1); \ 73 d3 = c2 ^ rol(c4, 1); \ 74 d4 = c3 ^ rol(c0, 1); \ 75 SRC##0 ^= d0; \ 76 b0 = SRC##0; \ 77 SRC##6 ^= d1; \ 78 b1 = rol(SRC##6, 44); \ 79 SRC##12 ^= d2; \ 80 b2 = rol(SRC##12, 43); \ 81 SRC##18 ^= d3; \ 82 b3 = rol(SRC##18, 21); \ 83 SRC##24 ^= d4; \ 84 b4 = rol(SRC##24, 14); \ 85 DST##0 = b0 ^ ((~b1) & b2); \ 86 DST##1 = b1 ^ ((~b2) & b3); \ 87 DST##2 = b2 ^ ((~b3) & b4); \ 88 DST##3 = b3 ^ ((~b4) & b0); \ 89 DST##4 = b4 ^ ((~b0) & b1); \ 90 DST##0 ^= RC[RCIDX]; \ 91 c0 = DST##0; \ 92 c1 = DST##1; \ 93 c2 = DST##2; \ 94 c3 = DST##3; \ 95 c4 = DST##4; \ 96 SRC##3 ^= d3; \ 97 b5 = rol(SRC##3, 28); \ 98 SRC##9 ^= d4; \ 99 b6 = rol(SRC##9, 20); \ 100 SRC##10 ^= d0; \ 101 b7 = rol(SRC##10, 3); \ 102 SRC##16 ^= d1; \ 103 b8 = rol(SRC##16, 45); \ 104 SRC##22 ^= d2; \ 105 b9 = rol(SRC##22, 61); \ 106 DST##5 = b5 ^ ((~b6) & b7); \ 107 DST##6 = b6 ^ ((~b7) & b8); \ 108 DST##7 = b7 ^ ((~b8) & b9); \ 109 DST##8 = b8 ^ ((~b9) & b5); \ 110 DST##9 = b9 ^ ((~b5) & b6); \ 111 c0 ^= DST##5; \ 112 c1 ^= DST##6; \ 113 c2 ^= DST##7; \ 114 c3 ^= DST##8; \ 115 c4 ^= DST##9; \ 116 SRC##1 ^= d1; \ 117 b10 = rol(SRC##1, 1); \ 118 SRC##7 ^= d2; \ 119 b11 = rol(SRC##7, 6); \ 120 SRC##13 ^= d3; \ 121 b12 = rol(SRC##13, 25); \ 122 SRC##19 ^= d4; \ 123 b13 = rol(SRC##19, 8); \ 124 SRC##20 ^= d0; \ 125 b14 = rol(SRC##20, 18); \ 126 DST##10 = b10 ^ ((~b11) & b12); \ 127 DST##11 = b11 ^ ((~b12) & b13); \ 128 DST##12 = b12 ^ ((~b13) & b14); \ 129 DST##13 = b13 ^ ((~b14) & b10); \ 130 DST##14 = b14 ^ ((~b10) & b11); \ 131 c0 ^= DST##10; \ 132 c1 ^= DST##11; \ 133 c2 ^= DST##12; \ 134 c3 ^= DST##13; \ 135 c4 ^= DST##14; \ 136 SRC##4 ^= d4; \ 137 b15 = rol(SRC##4, 27); \ 138 SRC##5 ^= d0; \ 139 b16 = rol(SRC##5, 36); \ 140 SRC##11 ^= d1; \ 141 b17 = rol(SRC##11, 10); \ 142 SRC##17 ^= d2; \ 143 b18 = rol(SRC##17, 15); \ 144 SRC##23 ^= d3; \ 145 b19 = rol(SRC##23, 56); \ 146 DST##15 = b15 ^ ((~b16) & b17); \ 147 DST##16 = b16 ^ ((~b17) & b18); \ 148 DST##17 = b17 ^ ((~b18) & b19); \ 149 DST##18 = b18 ^ ((~b19) & b15); \ 150 DST##19 = b19 ^ ((~b15) & b16); \ 151 c0 ^= DST##15; \ 152 c1 ^= DST##16; \ 153 c2 ^= DST##17; \ 154 c3 ^= DST##18; \ 155 c4 ^= DST##19; \ 156 SRC##2 ^= d2; \ 157 b20 = rol(SRC##2, 62); \ 158 SRC##8 ^= d3; \ 159 b21 = rol(SRC##8, 55); \ 160 SRC##14 ^= d4; \ 161 b22 = rol(SRC##14, 39); \ 162 SRC##15 ^= d0; \ 163 b23 = rol(SRC##15, 41); \ 164 SRC##21 ^= d1; \ 165 b24 = rol(SRC##21, 2); \ 166 DST##20 = b20 ^ ((~b21) & b22); \ 167 DST##21 = b21 ^ ((~b22) & b23); \ 168 DST##22 = b22 ^ ((~b23) & b24); \ 169 DST##23 = b23 ^ ((~b24) & b20); \ 170 DST##24 = b24 ^ ((~b20) & b21); \ 171 c0 ^= DST##20; \ 172 c1 ^= DST##21; \ 173 c2 ^= DST##22; \ 174 c3 ^= DST##23; \ 175 c4 ^= DST##24; \ 176 177 #define KFP_R2(SRC, DST, I) KFP_R(SRC, DST, I) KFP_R(DST, SRC, I + 1) 178 #define KFP_R4(SRC, DST, I) KFP_R2(SRC, DST, I) KFP_R2(SRC, DST, I + 2) 179 #define KFP_R12(SRC, DST, I) \ 180 KFP_R4(SRC, DST, I) KFP_R4(SRC, DST, I + 4) KFP_R4(SRC, DST, I + 8) 181 182 #define KFP_DECL(P) \ 183 uint64_t P##0, P##1, P##2, P##3, P##4, P##5, P##6, P##7, P##8, P##9, \ 184 P##10, P##11, P##12, P##13, P##14, P##15, P##16, P##17, P##18, P##19, \ 185 P##20, P##21, P##22, P##23, P##24 186 187 #define KFP_BODY(ROUNDS) \ 188 uint64_t *s = (uint64_t *)state; \ 189 KFP_DECL(a); \ 190 KFP_DECL(e); \ 191 KFP_DECL(b); \ 192 uint64_t c0, c1, c2, c3, c4, d0, d1, d2, d3, d4; \ 193 KFP_LOAD(a, s) \ 194 KFP_INIT_C(a) \ 195 ROUNDS \ 196 KFP_STORE(s, a) 197 198 static inline void keccakf(void *state) { 199 KFP_BODY(for (int i = 0; i < 24; i += 4) { KFP_R4(a, e, i) }) 200 } 201 202 static inline void keccak12(void *state) { 203 KFP_BODY(for (int i = 12; i < 24; i += 4) { KFP_R4(a, e, i) }) 204 } 205 206 #endif /* FINWO_SCALAR_PERM_H */