ASCON Suite
ascon-sliced32.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2022 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #ifndef ASCON_SLICED32_H
24 #define ASCON_SLICED32_H
25 
26 /* Utilities for the 32-bit sliced implementation of the ASCON permutation */
27 
28 #include <ascon/permutation.h>
29 #include "ascon-select-backend.h"
30 
31 #if defined(ASCON_BACKEND_SLICED32)
32 
35 /* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
36 #define ascon_bit_permute_step(_y, mask, shift) \
37  do { \
38  uint32_t y = (_y); \
39  uint32_t t = ((y >> (shift)) ^ y) & (mask); \
40  (_y) = (y ^ t) ^ (t << (shift)); \
41  } while (0)
42 
43 /* Separates a 32-bit word into two 16-bit halves with all the even
44  * bits in the bottom half and all the odd bits in the top half.
45  *
46  * Permutation generated with "http://programming.sirrida.de/calcperm.php"
47  *
48  * P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
49  * 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
50  */
51 #define ascon_separate(x) \
52  do { \
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); \
57  } while (0)
58 #define ascon_combine(x) \
59  do { \
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); \
64  } while (0)
65 
76 #define ascon_set_sliced(state, data, offset) \
77  do { \
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); \
85  } while (0)
86 
87 /*
88  * \brief Sets a 64-bit word into the ASCON state in sliced form.
89  *
90  * \param state The ASCON state for the data to be absorbed into.
91  * \param value The 64-bit word.
92  * \param offset Offset of the 64-bit word within the state to set at,
93  * between 0 and 4.
94  */
95 #define ascon_set_word64(state, value, offset) \
96  do { \
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); \
104  } while (0)
105 
114 #define ascon_absorb_sliced(state, data, offset) \
115  do { \
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); \
123  } while (0)
124 
133 #define ascon_absorb_word64(state, value, offset) \
134  do { \
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); \
142  } while (0)
143 
154 #define ascon_absorb32_low_sliced(state, data, offset) \
155  do { \
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); \
161  } while (0)
162 
173 #define ascon_absorb32_high_sliced(state, data, offset) \
174  do { \
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); \
180  } while (0)
181 
190 #define ascon_squeeze_sliced(state, data, offset) \
191  do { \
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); \
202  } while (0)
203 
212 #define ascon_squeeze_word64(state, value, offset) \
213  do { \
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; \
223  } while (0)
224 
234 #define ascon_encrypt_sliced(state, c, m, offset) \
235  do { \
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); \
251  } while (0)
252 
262 #define ascon_decrypt_sliced(state, m, c, offset) \
263  do { \
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); \
280  } while (0)
281 
292 #define ascon_decrypt_sliced_no_insert(state, m, c, offset) \
293  do { \
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); \
308  } while (0)
309 
310 #endif /* ASCON_BACKEND_SLICED32 */
311 
312 #endif /* ASCON_SLICED32_H */
Direct access to the ASCON permutation primitive.