Lightweight Cryptography Primitives
 All Data Structures Files Functions Variables Typedefs Macros Pages
internal-ascon.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 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 LW_INTERNAL_ASCON_H
24 #define LW_INTERNAL_ASCON_H
25 
26 #include "internal-util.h"
27 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
43 #if !defined(__AVR__)
44 #define ASCON_SLICED 1
45 #else
46 #define ASCON_SLICED 0
47 #endif
48 
52 typedef union
53 {
54  uint64_t S[5];
55  uint32_t W[10];
56  uint8_t B[40];
59 
68 void ascon_permute(ascon_state_t *state, uint8_t first_round);
69 
70 #if ASCON_SLICED
71 
78 void ascon_to_sliced(ascon_state_t *state);
79 
86 void ascon_from_sliced(ascon_state_t *state);
87 
96 void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round);
97 
100 /* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
101 #define ascon_bit_permute_step(_y, mask, shift) \
102  do { \
103  uint32_t y = (_y); \
104  uint32_t t = ((y >> (shift)) ^ y) & (mask); \
105  (_y) = (y ^ t) ^ (t << (shift)); \
106  } while (0)
107 
108 /* Separates a 32-bit word into two 16-bit halves with all the even
109  * bits in the bottom half and all the odd bits in the top half.
110  *
111  * Permutation generated with "http://programming.sirrida.de/calcperm.php"
112  *
113  * P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
114  * 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
115  */
116 #define ascon_separate(x) \
117  do { \
118  ascon_bit_permute_step((x), 0x22222222, 1); \
119  ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
120  ascon_bit_permute_step((x), 0x00f000f0, 4); \
121  ascon_bit_permute_step((x), 0x0000ff00, 8); \
122  } while (0)
123 #define ascon_combine(x) \
124  do { \
125  ascon_bit_permute_step((x), 0x0000aaaa, 15); \
126  ascon_bit_permute_step((x), 0x0000cccc, 14); \
127  ascon_bit_permute_step((x), 0x0000f0f0, 12); \
128  ascon_bit_permute_step((x), 0x0000ff00, 8); \
129  } while (0)
130 
141 #define ascon_set_sliced(state, data, offset) \
142  do { \
143  ascon_state_t *s = (state); \
144  uint32_t high = be_load_word32((data)); \
145  uint32_t low = be_load_word32((data) + 4); \
146  ascon_separate(high); \
147  ascon_separate(low); \
148  s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
149  s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
150  } while (0)
151 
160 #define ascon_absorb_sliced(state, data, offset) \
161  do { \
162  ascon_state_t *s = (state); \
163  uint32_t high = be_load_word32((data)); \
164  uint32_t low = be_load_word32((data) + 4); \
165  ascon_separate(high); \
166  ascon_separate(low); \
167  s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
168  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
169  } while (0)
170 
181 #define ascon_absorb32_low_sliced(state, data, offset) \
182  do { \
183  ascon_state_t *s = (state); \
184  uint32_t low = be_load_word32((data)); \
185  ascon_separate(low); \
186  s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
187  s->W[(offset) * 2 + 1] ^= (low >> 16); \
188  } while (0)
189 
200 #define ascon_absorb32_high_sliced(state, data, offset) \
201  do { \
202  ascon_state_t *s = (state); \
203  uint32_t high = be_load_word32((data)); \
204  ascon_separate(high); \
205  s->W[(offset) * 2] ^= (high << 16); \
206  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
207  } while (0)
208 
217 #define ascon_squeeze_sliced(state, data, offset) \
218  do { \
219  ascon_state_t *s = (state); \
220  uint32_t high, low; \
221  high = (s->W[(offset) * 2] >> 16) | \
222  (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
223  low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
224  (s->W[(offset) * 2 + 1] << 16); \
225  ascon_combine(high); \
226  ascon_combine(low); \
227  be_store_word32((data), high); \
228  be_store_word32((data) + 4, low); \
229  } while (0)
230 
240 #define ascon_encrypt_sliced(state, c, m, offset) \
241  do { \
242  ascon_state_t *s = (state); \
243  uint32_t high = be_load_word32((m)); \
244  uint32_t low = be_load_word32((m) + 4); \
245  ascon_separate(high); \
246  ascon_separate(low); \
247  s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
248  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
249  high = (s->W[(offset) * 2] >> 16) | \
250  (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
251  low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
252  (s->W[(offset) * 2 + 1] << 16); \
253  ascon_combine(high); \
254  ascon_combine(low); \
255  be_store_word32((c), high); \
256  be_store_word32((c) + 4, low); \
257  } while (0)
258 
268 #define ascon_decrypt_sliced(state, m, c, offset) \
269  do { \
270  ascon_state_t *s = (state); \
271  uint32_t high, low, high2, low2; \
272  high = be_load_word32((c)); \
273  low = be_load_word32((c) + 4); \
274  ascon_separate(high); \
275  ascon_separate(low); \
276  high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
277  (s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
278  low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
279  (s->W[(offset) * 2 + 1] << 16)); \
280  s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
281  s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
282  ascon_combine(high2); \
283  ascon_combine(low2); \
284  be_store_word32((m), high2); \
285  be_store_word32((m) + 4, low2); \
286  } while (0)
287 
288 #endif /* ASCON_SLICED */
289 
290 #ifdef __cplusplus
291 }
292 #endif
293 
294 #endif
void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round)
Permutes the ASCON state in sliced form.
Definition: internal-ascon.c:124
Structure of the internal state of the ASCON permutation.
Definition: internal-ascon.h:52
void ascon_permute(ascon_state_t *state, uint8_t first_round)
Permutes the ASCON state.
Definition: internal-ascon.c:39
void ascon_to_sliced(ascon_state_t *state)
Converts an ASCON state from byte form into sliced form.
Definition: internal-ascon.c:96
void ascon_from_sliced(ascon_state_t *state)
Converts an ASCON state from sliced form into byte form.
Definition: internal-ascon.c:110