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) 2021 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__) && !defined(LW_UTIL_CPU_IS_64BIT)
44 #define ASCON_SLICED 1
45 #else
46 #define ASCON_SLICED 0
47 #endif
48 
52 #define ASCON128_IV 0x80400c0600000000ULL
53 
57 #define ASCON128a_IV 0x80800c0800000000ULL
58 
62 #define ASCON80PQ_IV 0xa0400c06U
63 
67 typedef union
68 {
69  uint64_t S[5];
70  uint32_t W[10];
71  uint8_t B[40];
74 
83 void ascon_permute(ascon_state_t *state, uint8_t first_round);
84 
85 #if ASCON_SLICED
86 
93 void ascon_to_sliced(ascon_state_t *state);
94 
101 void ascon_from_sliced(ascon_state_t *state);
102 
111 void ascon_permute_sliced(ascon_state_t *state, uint8_t first_round);
112 
115 /* http://programming.sirrida.de/perm_fn.html#bit_permute_step */
116 #define ascon_bit_permute_step(_y, mask, shift) \
117  do { \
118  uint32_t y = (_y); \
119  uint32_t t = ((y >> (shift)) ^ y) & (mask); \
120  (_y) = (y ^ t) ^ (t << (shift)); \
121  } while (0)
122 
123 /* Separates a 32-bit word into two 16-bit halves with all the even
124  * bits in the bottom half and all the odd bits in the top half.
125  *
126  * Permutation generated with "http://programming.sirrida.de/calcperm.php"
127  *
128  * P = [0 16 1 17 2 18 3 19 4 20 5 21 6 22 7 23 8 24
129  * 9 25 10 26 11 27 12 28 13 29 14 30 15 31]
130  */
131 #define ascon_separate(x) \
132  do { \
133  ascon_bit_permute_step((x), 0x22222222, 1); \
134  ascon_bit_permute_step((x), 0x0c0c0c0c, 2); \
135  ascon_bit_permute_step((x), 0x00f000f0, 4); \
136  ascon_bit_permute_step((x), 0x0000ff00, 8); \
137  } while (0)
138 #define ascon_combine(x) \
139  do { \
140  ascon_bit_permute_step((x), 0x0000aaaa, 15); \
141  ascon_bit_permute_step((x), 0x0000cccc, 14); \
142  ascon_bit_permute_step((x), 0x0000f0f0, 12); \
143  ascon_bit_permute_step((x), 0x0000ff00, 8); \
144  } while (0)
145 
156 #define ascon_set_sliced(state, data, offset) \
157  do { \
158  ascon_state_t *s = (state); \
159  uint32_t high = be_load_word32((data)); \
160  uint32_t low = be_load_word32((data) + 4); \
161  ascon_separate(high); \
162  ascon_separate(low); \
163  s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
164  s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
165  } while (0)
166 
175 #define ascon_absorb_sliced(state, data, offset) \
176  do { \
177  ascon_state_t *s = (state); \
178  uint32_t high = be_load_word32((data)); \
179  uint32_t low = be_load_word32((data) + 4); \
180  ascon_separate(high); \
181  ascon_separate(low); \
182  s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
183  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
184  } while (0)
185 
196 #define ascon_absorb32_low_sliced(state, data, offset) \
197  do { \
198  ascon_state_t *s = (state); \
199  uint32_t low = be_load_word32((data)); \
200  ascon_separate(low); \
201  s->W[(offset) * 2] ^= (low & 0x0000FFFFU); \
202  s->W[(offset) * 2 + 1] ^= (low >> 16); \
203  } while (0)
204 
215 #define ascon_absorb32_high_sliced(state, data, offset) \
216  do { \
217  ascon_state_t *s = (state); \
218  uint32_t high = be_load_word32((data)); \
219  ascon_separate(high); \
220  s->W[(offset) * 2] ^= (high << 16); \
221  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U); \
222  } while (0)
223 
232 #define ascon_squeeze_sliced(state, data, offset) \
233  do { \
234  ascon_state_t *s = (state); \
235  uint32_t high, low; \
236  high = (s->W[(offset) * 2] >> 16) | \
237  (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
238  low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
239  (s->W[(offset) * 2 + 1] << 16); \
240  ascon_combine(high); \
241  ascon_combine(low); \
242  be_store_word32((data), high); \
243  be_store_word32((data) + 4, low); \
244  } while (0)
245 
255 #define ascon_encrypt_sliced(state, c, m, offset) \
256  do { \
257  ascon_state_t *s = (state); \
258  uint32_t high = be_load_word32((m)); \
259  uint32_t low = be_load_word32((m) + 4); \
260  ascon_separate(high); \
261  ascon_separate(low); \
262  s->W[(offset) * 2] ^= (high << 16) | (low & 0x0000FFFFU); \
263  s->W[(offset) * 2 + 1] ^= (high & 0xFFFF0000U) | (low >> 16); \
264  high = (s->W[(offset) * 2] >> 16) | \
265  (s->W[(offset) * 2 + 1] & 0xFFFF0000U); \
266  low = (s->W[(offset) * 2] & 0x0000FFFFU) | \
267  (s->W[(offset) * 2 + 1] << 16); \
268  ascon_combine(high); \
269  ascon_combine(low); \
270  be_store_word32((c), high); \
271  be_store_word32((c) + 4, low); \
272  } while (0)
273 
283 #define ascon_decrypt_sliced(state, m, c, offset) \
284  do { \
285  ascon_state_t *s = (state); \
286  uint32_t high, low, high2, low2; \
287  high = be_load_word32((c)); \
288  low = be_load_word32((c) + 4); \
289  ascon_separate(high); \
290  ascon_separate(low); \
291  high2 = high ^ ((s->W[(offset) * 2] >> 16) | \
292  (s->W[(offset) * 2 + 1] & 0xFFFF0000U)); \
293  low2 = low ^ ((s->W[(offset) * 2] & 0x0000FFFFU) | \
294  (s->W[(offset) * 2 + 1] << 16)); \
295  s->W[(offset) * 2] = (high << 16) | (low & 0x0000FFFFU); \
296  s->W[(offset) * 2 + 1] = (high & 0xFFFF0000U) | (low >> 16); \
297  ascon_combine(high2); \
298  ascon_combine(low2); \
299  be_store_word32((m), high2); \
300  be_store_word32((m) + 4, low2); \
301  } while (0)
302 
303 #endif /* ASCON_SLICED */
304 
310 #if ASCON_SLICED
311 #define ascon_separator() (state.W[8] ^= 0x01)
312 #else
313 #define ascon_separator() (state.B[39] ^= 0x01)
314 #endif
315 
316 #ifdef __cplusplus
317 }
318 #endif
319 
320 #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:67
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