23 #ifndef ASCON_SLICED32_H
24 #define ASCON_SLICED32_H
31 #if defined(ASCON_BACKEND_SLICED32)
36 #define ascon_bit_permute_step(_y, mask, shift) \
39 uint32_t t = ((y >> (shift)) ^ y) & (mask); \
40 (_y) = (y ^ t) ^ (t << (shift)); \
51 #define ascon_separate(x) \
53 ascon_bit_permute_step((x), 0x22222222, 1); \
54 ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
55 ascon_bit_permute_step((x), 0x00f000f0, 4); \
56 ascon_bit_permute_step((x), 0x0000ff00, 8); \
58 #define ascon_combine(x) \
60 ascon_bit_permute_step((x), 0x0000aaaa, 15); \
61 ascon_bit_permute_step((x), 0x0000cccc, 14); \
62 ascon_bit_permute_step((x), 0x0000f0f0, 12); \
63 ascon_bit_permute_step((x), 0x0000ff00, 8); \
76 #define ascon_set_sliced(state, data, offset) \
78 ascon_state_t *s = (state); \
79 uint32_t high = be_load_word32((data)); \
80 uint32_t low = be_load_word32((data) + 4); \
81 ascon_separate(high); \
82 ascon_separate(low); \
83 s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
84 s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
95 #define ascon_set_word64(state, value, offset) \
97 ascon_state_t *s = (state); \
98 uint32_t high = (uint32_t)((value) >> 32); \
99 uint32_t low = (uint32_t)(value); \
100 ascon_separate(high); \
101 ascon_separate(low); \
102 s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
103 s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
114 #define ascon_absorb_sliced(state, data, offset) \
116 ascon_state_t *s = (state); \
117 uint32_t high = be_load_word32((data)); \
118 uint32_t low = be_load_word32((data) + 4); \
119 ascon_separate(high); \
120 ascon_separate(low); \
121 s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
122 s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
133 #define ascon_absorb_word64(state, value, offset) \
135 ascon_state_t *s = (state); \
136 uint32_t high = (uint32_t)((value) >> 32); \
137 uint32_t low = (uint32_t)(value); \
138 ascon_separate(high); \
139 ascon_separate(low); \
140 s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
141 s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
154 #define ascon_absorb32_low_sliced(state, data, offset) \
156 ascon_state_t *s = (state); \
157 uint32_t low = be_load_word32((data)); \
158 ascon_separate(low); \
159 s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
160 s->W[(offset) * 2 + 1] ^= (low >> 16); \
173 #define ascon_absorb32_high_sliced(state, data, offset) \
175 ascon_state_t *s = (state); \
176 uint32_t high = be_load_word32((data)); \
177 ascon_separate(high); \
178 s->W[(offset) * 2] ^= (high << 16); \
179 s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
190 #define ascon_squeeze_sliced(state, data, offset) \
192 const ascon_state_t *s = (state); \
193 uint32_t high, low; \
194 high = (s->W[(offset) * 2] >> 16) | \
195 (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
196 low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
197 (s->W[(offset) * 2 + 1] << 16); \
198 ascon_combine(high); \
199 ascon_combine(low); \
200 be_store_word32((data), high); \
201 be_store_word32((data) + 4, low); \
212 #define ascon_squeeze_word64(state, value, offset) \
214 const ascon_state_t *s = (state); \
215 uint32_t high, low; \
216 high = (s->W[(offset) * 2] >> 16) | \
217 (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
218 low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
219 (s->W[(offset) * 2 + 1] << 16); \
220 ascon_combine(high); \
221 ascon_combine(low); \
222 (value) = (((uint64_t)high) << 32) | low; \
234 #define ascon_encrypt_sliced(state, c, m, offset) \
236 ascon_state_t *s = (state); \
237 uint32_t high = be_load_word32((m)); \
238 uint32_t low = be_load_word32((m) + 4); \
239 ascon_separate(high); \
240 ascon_separate(low); \
241 s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
242 s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
243 high = (s->W[(offset) * 2] >> 16) | \
244 (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
245 low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
246 (s->W[(offset) * 2 + 1] << 16); \
247 ascon_combine(high); \
248 ascon_combine(low); \
249 be_store_word32((c), high); \
250 be_store_word32((c) + 4, low); \
262 #define ascon_decrypt_sliced(state, m, c, offset) \
264 ascon_state_t *s = (state); \
265 uint32_t high, low, high2, low2; \
266 high = be_load_word32((c)); \
267 low = be_load_word32((c) + 4); \
268 ascon_separate(high); \
269 ascon_separate(low); \
270 high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
271 (s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
272 low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
273 (s->W[(offset) * 2 + 1] << 16)); \
274 s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
275 s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
276 ascon_combine(high2); \
277 ascon_combine(low2); \
278 be_store_word32((m), high2); \
279 be_store_word32((m) + 4, low2); \
292 #define ascon_decrypt_sliced_no_insert(state, m, c, offset) \
294 const ascon_state_t *s = (state); \
295 uint32_t high, low; \
296 high = be_load_word32((c)); \
297 low = be_load_word32((c) + 4); \
298 ascon_separate(high); \
299 ascon_separate(low); \
300 high ^= ((s->W[(offset) * 2] >> 16) | \
301 (s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
302 low ^= ((s->W[(offset) * 2] & 0x0000FFFFU) | \
303 (s->W[(offset) * 2 + 1] << 16)); \
304 ascon_combine(high); \
305 ascon_combine(low); \
306 be_store_word32((m), high); \
307 be_store_word32((m) + 4, low); \
Direct access to the ASCON permutation primitive.