ASCON Suite
ascon-xofa.c
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 #include <ascon/xof.h>
24 #include "core/ascon-util-snp.h"
25 
26 void ascon_xofa(unsigned char *out, const unsigned char *in, size_t inlen)
27 {
30  ascon_xofa_absorb(&state, in, inlen);
33 }
34 
36 {
37  /* IV for ASCON-XOFA after processing it with the permutation */
38 #if defined(ASCON_BACKEND_SLICED64)
39  static uint64_t const iv[5] = {
40  0x44906568b77b9832ULL, 0xcd8d6cae53455532ULL,
41  0xf7b5212756422129ULL, 0x246885e1de0d225bULL,
42  0xa8cb5ce33449973fULL
43  };
44  memcpy(state->state.S, iv, sizeof(iv));
45 #elif defined(ASCON_BACKEND_SLICED32)
46  static uint32_t const iv[10] = {
47  0xa4b87d44, 0x0846d7a5, 0xb3a2dbf4, 0xaa6f1005,
48  0xf713e811, 0xdc451146, 0x2839e30d, 0x468cb253,
49  0x09e96977, 0xeb2d4297
50  };
51  memcpy(state->state.W, iv, sizeof(iv));
52 #else
53  static uint8_t const iv[40] = {
54  0x44, 0x90, 0x65, 0x68, 0xb7, 0x7b, 0x98, 0x32,
55  0xcd, 0x8d, 0x6c, 0xae, 0x53, 0x45, 0x55, 0x32,
56  0xf7, 0xb5, 0x21, 0x27, 0x56, 0x42, 0x21, 0x29,
57  0x24, 0x68, 0x85, 0xe1, 0xde, 0x0d, 0x22, 0x5b,
58  0xa8, 0xcb, 0x5c, 0xe3, 0x34, 0x49, 0x97, 0x3f
59  };
60 #if defined(ASCON_BACKEND_DIRECT_XOR)
61  memcpy(state->state.B, iv, sizeof(iv));
62 #else
63  ascon_init(&(state->state));
64  ascon_overwrite_bytes(&(state->state), iv, sizeof(iv));
65  ascon_release(&(state->state));
66 #endif
67 #endif
68  state->count = 0;
69  state->mode = 0;
70 }
71 
73 {
74 #if !defined(__SIZEOF_SIZE_T__) || __SIZEOF_SIZE_T__ >= 4
75  if (outlen >= (((size_t)1) << 29))
76  outlen = 0; /* Too large, so switch to arbitrary-length output */
77 #endif
78  if (outlen == 0U) {
79  /* Output length of zero is equivalent to regular XOF */
81  } else if (outlen == 32U) {
82  /* Output length of 32 is equivalent to ASCON-HASHA */
83 #if defined(ASCON_BACKEND_SLICED64)
84  static uint64_t const iv[5] = {
85  0x01470194fc6528a6ULL, 0x738ec38ac0adffa7ULL,
86  0x2ec8e3296c76384cULL, 0xd6f6a54d7f52377dULL,
87  0xa13c42a223be8d87ULL
88  };
89  memcpy(state->state.S, iv, sizeof(iv));
90 #elif defined(ASCON_BACKEND_SLICED32)
91  static uint32_t const iv[10] = {
92  0x1b16eb02, 0x0108e46d, 0xd29083f3, 0x5b9b8efd,
93  0x2891ae4a, 0x7ad66562, 0xee3bfc7f, 0x9dc27156,
94  0x16801633, 0xc61d5fa9
95  };
96  memcpy(state->state.W, iv, sizeof(iv));
97 #else
98  static uint8_t const iv[40] = {
99  0x01, 0x47, 0x01, 0x94, 0xfc, 0x65, 0x28, 0xa6,
100  0x73, 0x8e, 0xc3, 0x8a, 0xc0, 0xad, 0xff, 0xa7,
101  0x2e, 0xc8, 0xe3, 0x29, 0x6c, 0x76, 0x38, 0x4c,
102  0xd6, 0xf6, 0xa5, 0x4d, 0x7f, 0x52, 0x37, 0x7d,
103  0xa1, 0x3c, 0x42, 0xa2, 0x23, 0xbe, 0x8d, 0x87
104  };
105 #if defined(ASCON_BACKEND_DIRECT_XOR)
106  memcpy(state->state.B, iv, sizeof(iv));
107 #else
108  ascon_init(&(state->state));
109  ascon_overwrite_bytes(&(state->state), iv, sizeof(iv));
110  ascon_release(&(state->state));
111 #endif
112 #endif
113  state->count = 0;
114  state->mode = 0;
115  } else {
116  /* For all other lengths, we need to run the permutation
117  * to get the initial block for the XOF process */
118  uint8_t iv[8];
119  ascon_init(&(state->state));
120  be_store_word64(iv, 0x00400c0400000000ULL | (outlen * 8UL));
121  ascon_overwrite_bytes(&(state->state), iv, 0, 8);
122  ascon_permute(&(state->state), 0);
123  ascon_release(&(state->state));
124  state->count = 0;
125  state->mode = 0;
126  }
127 }
128 
130  (ascon_xofa_state_t *state, const unsigned char *custom, size_t customlen)
131 {
132  if (customlen > 0) {
133  ascon_xofa_absorb(state, custom, customlen);
134  ascon_acquire(&(state->state));
135  ascon_pad(&(state->state), state->count);
136  ascon_permute(&(state->state), 4);
137  ascon_separator(&(state->state));
138  ascon_release(&(state->state));
139  state->count = 0;
140  }
141 }
142 
144  (ascon_xofa_state_t *state, const char *function_name,
145  const unsigned char *custom, size_t customlen, size_t outlen)
146 {
147  /* Format the initial block with the function name and output length */
148  uint8_t temp[ASCON_HASHA_SIZE];
149  size_t len = function_name ? strlen(function_name) : 0;
150 #if !defined(__SIZEOF_SIZE_T__) || __SIZEOF_SIZE_T__ >= 4
151  if (outlen >= (((size_t)1) << 29))
152  outlen = 0; /* Too large, so switch to arbitrary-length output */
153 #endif
154  if (len == 0) {
155  /* No function name specified */
156  memset(temp, 0, ASCON_HASHA_SIZE);
157  } else if (len <= 32) {
158  /* Pad the function name with zeroes */
159  memcpy(temp, function_name, len);
160  memset(temp + len, 0, ASCON_HASHA_SIZE - len);
161  } else {
162  /* Compute ASCON-HASHA(function_name) */
164  ascon_xofa_absorb(state, (const unsigned char *)function_name, len);
167  }
168  ascon_init(&(state->state));
169  ascon_overwrite_bytes(&(state->state), temp, 8, ASCON_HASHA_SIZE);
170  be_store_word64(temp, 0x00400c0400000000ULL | (outlen * 8UL));
171  ascon_overwrite_bytes(&(state->state), temp, 0, 8);
172  ascon_permute(&(state->state), 0);
173  ascon_release(&(state->state));
174  state->count = 0;
175  state->mode = 0;
176 
177  /* Absorb the customization string */
178  ascon_xofa_absorb_custom(state, custom, customlen);
179 }
180 
182 {
183 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
184  defined(ASCON_BACKEND_DIRECT_XOR)
186 #else
189 #endif
190 }
191 
193 {
194 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
195  defined(ASCON_BACKEND_DIRECT_XOR)
196  ascon_xofa_init_fixed(state, outlen);
197 #else
199  ascon_xofa_init_fixed(state, outlen);
200 #endif
201 }
202 
204  (ascon_xofa_state_t *state, const char *function_name,
205  const unsigned char *custom, size_t customlen, size_t outlen)
206 {
207 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
208  defined(ASCON_BACKEND_DIRECT_XOR)
209  ascon_xofa_init_custom(state, function_name, custom, customlen, outlen);
210 #else
212  ascon_xofa_init_custom(state, function_name, custom, customlen, outlen);
213 #endif
214 }
215 
217 {
218  if (state) {
219  ascon_acquire(&(state->state));
220  ascon_free(&(state->state));
221  state->count = 0;
222  state->mode = 0;
223  }
224 }
225 
227  (ascon_xofa_state_t *state, const unsigned char *in, size_t inlen)
228 {
229  unsigned temp;
230 
231  /* Acquire access to shared hardware if necessary */
232  ascon_acquire(&(state->state));
233 
234  /* If we were squeezing output, then go back to the absorb phase */
235  if (state->mode) {
236  state->mode = 0;
237  state->count = 0;
238  ascon_permute(&(state->state), 0);
239  }
240 
241  /* Handle the partial left-over block from last time */
242  if (state->count) {
243  temp = ASCON_XOF_RATE - state->count;
244  if (temp > inlen) {
245  temp = (unsigned)inlen;
246  ascon_absorb_partial(&(state->state), in, state->count, temp);
247  state->count += temp;
248  ascon_release(&(state->state));
249  return;
250  }
251  ascon_absorb_partial(&(state->state), in, state->count, temp);
252  state->count = 0;
253  in += temp;
254  inlen -= temp;
255  ascon_permute(&(state->state), 4);
256  }
257 
258  /* Process full blocks that are aligned at state->s.count == 0 */
259  while (inlen >= ASCON_XOF_RATE) {
260  ascon_absorb_8(&(state->state), in, 0);
261  in += ASCON_XOF_RATE;
262  inlen -= ASCON_XOF_RATE;
263  ascon_permute(&(state->state), 4);
264  }
265 
266  /* Process the left-over block at the end of the input */
267  temp = (unsigned)inlen;
268  if (temp > 0)
269  ascon_absorb_partial(&(state->state), in, 0, temp);
270  state->count = temp;
271 
272  /* Release access to the shared hardware */
273  ascon_release(&(state->state));
274 }
275 
277  (ascon_xofa_state_t *state, unsigned char *out, size_t outlen)
278 {
279  unsigned temp;
280 
281  /* Acquire access to shared hardware if necessary */
282  ascon_acquire(&(state->state));
283 
284  /* Pad the final input block if we were still in the absorb phase */
285  if (!state->mode) {
286  ascon_pad(&(state->state), state->count);
287  state->count = 0;
288  state->mode = 1;
289  ascon_permute(&(state->state), 0);
290  }
291 
292  /* Handle left-over partial blocks from last time */
293  if (state->count) {
294  temp = ASCON_XOF_RATE - state->count;
295  if (temp > outlen) {
296  temp = (unsigned)outlen;
297  ascon_squeeze_partial(&(state->state), out, state->count, temp);
298  state->count += temp;
299  ascon_release(&(state->state));
300  return;
301  }
302  ascon_squeeze_partial(&(state->state), out, state->count, temp);
303  out += temp;
304  outlen -= temp;
305  state->count = 0;
306  ascon_permute(&(state->state), 4);
307  }
308 
309  /* Handle full blocks */
310  while (outlen >= ASCON_XOF_RATE) {
311  ascon_squeeze_8(&(state->state), out, 0);
312  ascon_permute(&(state->state), 4);
313  out += ASCON_XOF_RATE;
314  outlen -= ASCON_XOF_RATE;
315  }
316 
317  /* Handle the left-over block */
318  if (outlen > 0) {
319  temp = (unsigned)outlen;
320  ascon_squeeze_partial(&(state->state), out, 0, temp);
321  state->count = temp;
322  }
323 
324  /* Release access to the shared hardware */
325  ascon_release(&(state->state));
326 }
327 
329 {
330  if (state->mode) {
331  /* We were squeezing output, so re-enter the absorb phase
332  * which will implicitly align on a rate block boundary */
333  ascon_xofa_absorb(state, 0, 0);
334  } else if (state->count != 0) {
335  /* Not currently aligned, so invoke the permutation */
336  ascon_acquire(&(state->state));
337  ascon_permute(&(state->state), 4);
338  ascon_release(&(state->state));
339  state->count = 0;
340  }
341 }
342 
344 {
345  if (dest != src) {
346  ascon_init(&(dest->state));
347  ascon_copy(&(dest->state), &(src->state));
348  ascon_release(&(dest->state));
349  dest->count = src->count;
350  dest->mode = src->mode;
351  }
352 }
#define ascon_absorb_8(state, data, offset)
#define ascon_pad(state, offset)
#define ascon_squeeze_8(state, data, offset)
#define ascon_squeeze_partial(state, data, offset, count)
#define ascon_absorb_partial(state, data, offset, count)
#define ascon_separator(state)
#define be_store_word64(ptr, x)
Definition: ascon-util.h:118
void ascon_xofa_squeeze(ascon_xofa_state_t *state, unsigned char *out, size_t outlen)
Squeezes output data from an ASCON-XOFA state.
Definition: ascon-xofa.c:277
void ascon_xofa_reinit(ascon_xofa_state_t *state)
Re-initializes the state for an ASCON-XOFA hashing operation.
Definition: ascon-xofa.c:181
void ascon_xofa_reinit_fixed(ascon_xofa_state_t *state, size_t outlen)
Re-initializes the state for an incremental ASCON-XOFA operation, with a fixed output length.
Definition: ascon-xofa.c:192
void ascon_xofa(unsigned char *out, const unsigned char *in, size_t inlen)
Hashes a block of input data with ASCON-XOFA and generates a fixed-length 32 byte output.
Definition: ascon-xofa.c:26
void ascon_xofa_reinit_custom(ascon_xofa_state_t *state, const char *function_name, const unsigned char *custom, size_t customlen, size_t outlen)
Re-nitializes the state for an incremental ASCON-XOFA operation, with a named function,...
Definition: ascon-xofa.c:204
void ascon_xofa_absorb(ascon_xofa_state_t *state, const unsigned char *in, size_t inlen)
Absorbs more input data into an ASCON-XOFA state.
Definition: ascon-xofa.c:227
void ascon_xofa_init_custom(ascon_xofa_state_t *state, const char *function_name, const unsigned char *custom, size_t customlen, size_t outlen)
Initializes the state for an incremental ASCON-XOFA operation, with a named function,...
Definition: ascon-xofa.c:144
void ascon_xofa_init_fixed(ascon_xofa_state_t *state, size_t outlen)
Initializes the state for an incremental ASCON-XOFA operation, with a fixed output length.
Definition: ascon-xofa.c:72
void ascon_xofa_absorb_custom(ascon_xofa_state_t *state, const unsigned char *custom, size_t customlen)
Absorbs a customization string into an ASCON-XOFA state.
Definition: ascon-xofa.c:130
void ascon_xofa_pad(ascon_xofa_state_t *state)
Absorbs enough zeroes into an ASCON-XOFA state to pad the input to the next multiple of the block rat...
Definition: ascon-xofa.c:328
void ascon_xofa_init(ascon_xofa_state_t *state)
Initializes the state for an ASCON-XOFA hashing operation.
Definition: ascon-xofa.c:35
void ascon_xofa_copy(ascon_xofa_state_t *dest, const ascon_xofa_state_t *src)
Clones a copy of an ASCON-XOFA state.
Definition: ascon-xofa.c:343
void ascon_xofa_free(ascon_xofa_state_t *state)
Frees the ASCON-XOFA state and destroys any sensitive material.
Definition: ascon-xofa.c:216
void ascon_free(ascon_state_t *state)
Frees an ASCON permutation state and attempts to destroy any sensitive material.
void ascon_release(ascon_state_t *state)
Temporarily releases access to any shared hardware resources that a permutation state was using.
void ascon_overwrite_bytes(ascon_state_t *state, const uint8_t *data, unsigned offset, unsigned size)
Overwrites existing bytes in the ASCON state.
void ascon_copy(ascon_state_t *dest, const ascon_state_t *src)
Copies the entire ASCON permutation state from a source to a destination.
void ascon_permute(ascon_state_t *state, uint8_t first_round)
Permutes the ASCON state with a specified number of rounds.
Definition: ascon-c32.c:36
void ascon_acquire(ascon_state_t *state)
Re-acquires access to any shared hardware resources that a permutation state was using.
void ascon_init(ascon_state_t *state)
Initializes the words of the ASCON permutation state to zero.
ascon_state_t state
[snippet_key]
Definition: snippets.c:2
State information for ASCON-XOFA incremental mode.
Definition: xof.h:72
unsigned char mode
Definition: xof.h:75
unsigned char count
Definition: xof.h:74
ascon_state_t state
Definition: xof.h:73
uint32_t W[10]
Definition: permutation.h:65
uint64_t S[5]
Definition: permutation.h:64
uint8_t B[40]
Definition: permutation.h:66
ASCON-XOF and ASCON-XOFA extensible output functions (XOF's).
#define ASCON_XOF_RATE
Rate of absorbing and squeezing data for ASCON-XOF, ASCON-XOFA, ASCON-HASH, and ASCON-HASHA.
Definition: xof.h:55
#define ASCON_HASHA_SIZE
Size of the hash output for ASCON-HASHA and the default hash output size for ASCON-XOFA.
Definition: xof.h:49