ASCON Suite
ascon-xof.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"
26 #include <string.h>
27 
28 void ascon_xof(unsigned char *out, const unsigned char *in, size_t inlen)
29 {
32  ascon_xof_absorb(&state, in, inlen);
35 }
36 
38 {
39  /* IV for ASCON-XOF after processing it with the permutation */
40 #if defined(ASCON_BACKEND_SLICED64)
41  static uint64_t const iv[5] = {
42  0xb57e273b814cd416ULL, 0x2b51042562ae2420ULL,
43  0x66a3a7768ddf2218ULL, 0x5aad0a7a8153650cULL,
44  0x4f3e0e32539493b6ULL
45  };
46  memcpy(state->state.S, iv, sizeof(iv));
47 #elif defined(ASCON_BACKEND_SLICED32)
48  static uint32_t const iv[10] = {
49  0x7e351ae6, 0xc7578281, 0x1d238220, 0x70045f44,
50  0xa13e3f04, 0x5dd5ab52, 0xc30c1db2, 0x3e378142,
51  0xb624d656, 0x3735189d
52  };
53  memcpy(state->state.W, iv, sizeof(iv));
54 #else
55  static uint8_t const iv[40] = {
56  0xb5, 0x7e, 0x27, 0x3b, 0x81, 0x4c, 0xd4, 0x16,
57  0x2b, 0x51, 0x04, 0x25, 0x62, 0xae, 0x24, 0x20,
58  0x66, 0xa3, 0xa7, 0x76, 0x8d, 0xdf, 0x22, 0x18,
59  0x5a, 0xad, 0x0a, 0x7a, 0x81, 0x53, 0x65, 0x0c,
60  0x4f, 0x3e, 0x0e, 0x32, 0x53, 0x94, 0x93, 0xb6
61  };
62 #if defined(ASCON_BACKEND_DIRECT_XOR)
63  memcpy(state->state.B, iv, sizeof(iv));
64 #else
65  ascon_init(&(state->state));
66  ascon_overwrite_bytes(&(state->state), iv, sizeof(iv));
67  ascon_release(&(state->state));
68 #endif
69 #endif
70  state->count = 0;
71  state->mode = 0;
72 }
73 
75 {
76 #if !defined(__SIZEOF_SIZE_T__) || __SIZEOF_SIZE_T__ >= 4
77  if (outlen >= (((size_t)1) << 29))
78  outlen = 0; /* Too large, so switch to arbitrary-length output */
79 #endif
80  if (outlen == 0U) {
81  /* Output length of zero is equivalent to regular XOF */
83  } else if (outlen == 32U) {
84  /* Output length of 32 is equivalent to ASCON-HASH */
85 #if defined(ASCON_BACKEND_SLICED64)
86  static uint64_t const iv[5] = {
87  0xee9398aadb67f03dULL, 0x8bb21831c60f1002ULL,
88  0xb48a92db98d5da62ULL, 0x43189921b8f8e3e8ULL,
89  0x348fa5c9d525e140ULL
90  };
91  memcpy(state->state.S, iv, sizeof(iv));
92 #elif defined(ASCON_BACKEND_SLICED32)
93  static uint32_t const iv[10] = {
94  0xa540dbc7, 0xf9afb5c6, 0x1445a340, 0xbd249301,
95  0x604d4fc8, 0xcb9ba8b5, 0x94514c98, 0x12a4eede,
96  0x6339f398, 0x4bca84c0
97  };
98  memcpy(state->state.W, iv, sizeof(iv));
99 #else
100  static uint8_t const iv[40] = {
101  0xee, 0x93, 0x98, 0xaa, 0xdb, 0x67, 0xf0, 0x3d,
102  0x8b, 0xb2, 0x18, 0x31, 0xc6, 0x0f, 0x10, 0x02,
103  0xb4, 0x8a, 0x92, 0xdb, 0x98, 0xd5, 0xda, 0x62,
104  0x43, 0x18, 0x99, 0x21, 0xb8, 0xf8, 0xe3, 0xe8,
105  0x34, 0x8f, 0xa5, 0xc9, 0xd5, 0x25, 0xe1, 0x40
106  };
107 #if defined(ASCON_BACKEND_DIRECT_XOR)
108  memcpy(state->state.B, iv, sizeof(iv));
109 #else
110  ascon_init(&(state->state));
111  ascon_overwrite_bytes(&(state->state), iv, sizeof(iv));
112  ascon_release(&(state->state));
113 #endif
114 #endif
115  state->count = 0;
116  state->mode = 0;
117  } else {
118  /* For all other lengths, we need to run the permutation
119  * to get the initial block for the XOF process */
120  uint8_t iv[8];
121  ascon_init(&(state->state));
122  be_store_word64(iv, 0x00400c0000000000ULL | (outlen * 8UL));
123  ascon_overwrite_bytes(&(state->state), iv, 0, 8);
124  ascon_permute(&(state->state), 0);
125  ascon_release(&(state->state));
126  state->count = 0;
127  state->mode = 0;
128  }
129 }
130 
132  (ascon_xof_state_t *state, const unsigned char *custom, size_t customlen)
133 {
134  if (customlen > 0) {
135  ascon_xof_absorb(state, custom, customlen);
136  ascon_acquire(&(state->state));
137  ascon_pad(&(state->state), state->count);
138  ascon_permute(&(state->state), 0);
139  ascon_separator(&(state->state));
140  ascon_release(&(state->state));
141  state->count = 0;
142  }
143 }
144 
146  (ascon_xof_state_t *state, const char *function_name,
147  const unsigned char *custom, size_t customlen, size_t outlen)
148 {
149  /* Format the initial block with the function name and output length */
150  uint8_t temp[ASCON_HASH_SIZE];
151  size_t len = function_name ? strlen(function_name) : 0;
152 #if !defined(__SIZEOF_SIZE_T__) || __SIZEOF_SIZE_T__ >= 4
153  if (outlen >= (((size_t)1) << 29))
154  outlen = 0; /* Too large, so switch to arbitrary-length output */
155 #endif
156  if (len == 0) {
157  /* No function name specified */
158  memset(temp, 0, ASCON_HASH_SIZE);
159  } else if (len <= 32) {
160  /* Pad the function name with zeroes */
161  memcpy(temp, function_name, len);
162  memset(temp + len, 0, ASCON_HASH_SIZE - len);
163  } else {
164  /* Compute ASCON-HASH(function_name) */
166  ascon_xof_absorb(state, (const unsigned char *)function_name, len);
169  }
170  ascon_init(&(state->state));
171  ascon_overwrite_bytes(&(state->state), temp, 8, ASCON_HASH_SIZE);
172  be_store_word64(temp, 0x00400c0000000000ULL | (outlen * 8UL));
173  ascon_overwrite_bytes(&(state->state), temp, 0, 8);
174  ascon_permute(&(state->state), 0);
175  ascon_release(&(state->state));
176  state->count = 0;
177  state->mode = 0;
178 
179  /* Absorb the customization string */
180  ascon_xof_absorb_custom(state, custom, customlen);
181 }
182 
184 {
185 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
186  defined(ASCON_BACKEND_DIRECT_XOR)
188 #else
191 #endif
192 }
193 
195 {
196 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
197  defined(ASCON_BACKEND_DIRECT_XOR)
198  ascon_xof_init_fixed(state, outlen);
199 #else
201  ascon_xof_init_fixed(state, outlen);
202 #endif
203 }
204 
206  (ascon_xof_state_t *state, const char *function_name,
207  const unsigned char *custom, size_t customlen, size_t outlen)
208 {
209 #if defined(ASCON_BACKEND_SLICED64) || defined(ASCON_BACKEND_SLICED32) || \
210  defined(ASCON_BACKEND_DIRECT_XOR)
211  ascon_xof_init_custom(state, function_name, custom, customlen, outlen);
212 #else
214  ascon_xof_init_custom(state, function_name, custom, customlen, outlen);
215 #endif
216 }
217 
219 {
220  if (state) {
221  ascon_acquire(&(state->state));
222  ascon_free(&(state->state));
223  state->count = 0;
224  state->mode = 0;
225  }
226 }
227 
229  (ascon_xof_state_t *state, const unsigned char *in, size_t inlen)
230 {
231  unsigned temp;
232 
233  /* Acquire access to shared hardware if necessary */
234  ascon_acquire(&(state->state));
235 
236  /* If we were squeezing output, then go back to the absorb phase */
237  if (state->mode) {
238  state->mode = 0;
239  state->count = 0;
240  ascon_permute(&(state->state), 0);
241  }
242 
243  /* Handle the partial left-over block from last time */
244  if (state->count) {
245  temp = ASCON_XOF_RATE - state->count;
246  if (temp > inlen) {
247  temp = (unsigned)inlen;
248  ascon_absorb_partial(&(state->state), in, state->count, temp);
249  state->count += temp;
250  ascon_release(&(state->state));
251  return;
252  }
253  ascon_absorb_partial(&(state->state), in, state->count, temp);
254  state->count = 0;
255  in += temp;
256  inlen -= temp;
257  ascon_permute(&(state->state), 0);
258  }
259 
260  /* Process full blocks that are aligned at state->s.count == 0 */
261  while (inlen >= ASCON_XOF_RATE) {
262  ascon_absorb_8(&(state->state), in, 0);
263  in += ASCON_XOF_RATE;
264  inlen -= ASCON_XOF_RATE;
265  ascon_permute(&(state->state), 0);
266  }
267 
268  /* Process the left-over block at the end of the input */
269  temp = (unsigned)inlen;
270  if (temp > 0)
271  ascon_absorb_partial(&(state->state), in, 0, temp);
272  state->count = temp;
273 
274  /* Release access to the shared hardware */
275  ascon_release(&(state->state));
276 }
277 
279  (ascon_xof_state_t *state, unsigned char *out, size_t outlen)
280 {
281  unsigned temp;
282 
283  /* Acquire access to shared hardware if necessary */
284  ascon_acquire(&(state->state));
285 
286  /* Pad the final input block if we were still in the absorb phase */
287  if (!state->mode) {
288  ascon_pad(&(state->state), state->count);
289  state->count = 0;
290  state->mode = 1;
291  }
292 
293  /* Handle left-over partial blocks from last time */
294  if (state->count) {
295  temp = ASCON_XOF_RATE - state->count;
296  if (temp > outlen) {
297  temp = (unsigned)outlen;
298  ascon_squeeze_partial(&(state->state), out, state->count, temp);
299  state->count += temp;
300  ascon_release(&(state->state));
301  return;
302  }
303  ascon_squeeze_partial(&(state->state), out, state->count, temp);
304  out += temp;
305  outlen -= temp;
306  state->count = 0;
307  }
308 
309  /* Handle full blocks */
310  while (outlen >= ASCON_XOF_RATE) {
311  ascon_permute(&(state->state), 0);
312  ascon_squeeze_8(&(state->state), out, 0);
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_permute(&(state->state), 0);
321  ascon_squeeze_partial(&(state->state), out, 0, temp);
322  state->count = temp;
323  }
324 
325  /* Release access to the shared hardware */
326  ascon_release(&(state->state));
327 }
328 
330 {
331  if (state->mode) {
332  /* We were squeezing output, so re-enter the absorb phase
333  * which will implicitly align on a rate block boundary */
334  ascon_xof_absorb(state, 0, 0);
335  } else if (state->count != 0) {
336  /* Not currently aligned, so invoke the permutation */
337  ascon_acquire(&(state->state));
338  ascon_permute(&(state->state), 0);
339  ascon_release(&(state->state));
340  state->count = 0;
341  }
342 }
343 
345 {
346  if (dest != src) {
347  ascon_init(&(dest->state));
348  ascon_copy(&(dest->state), &(src->state));
349  ascon_release(&(dest->state));
350  dest->count = src->count;
351  dest->mode = src->mode;
352  }
353 }
#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_xof_free(ascon_xof_state_t *state)
Frees the ASCON-XOF state and destroys any sensitive material.
Definition: ascon-xof.c:218
void ascon_xof_pad(ascon_xof_state_t *state)
Absorbs enough zeroes into an ASCON-XOF state to pad the input to the next multiple of the block rate...
Definition: ascon-xof.c:329
void ascon_xof_reinit(ascon_xof_state_t *state)
Re-initializes the state for an ASCON-XOF hashing operation.
Definition: ascon-xof.c:183
void ascon_xof_absorb_custom(ascon_xof_state_t *state, const unsigned char *custom, size_t customlen)
Absorbs a customization string into an ASCON-XOF state.
Definition: ascon-xof.c:132
void ascon_xof_absorb(ascon_xof_state_t *state, const unsigned char *in, size_t inlen)
Absorbs more input data into an ASCON-XOF state.
Definition: ascon-xof.c:229
void ascon_xof_init(ascon_xof_state_t *state)
Initializes the state for an ASCON-XOF hashing operation.
Definition: ascon-xof.c:37
void ascon_xof_init_custom(ascon_xof_state_t *state, const char *function_name, const unsigned char *custom, size_t customlen, size_t outlen)
Initializes the state for an incremental ASCON-XOF operation, with a named function,...
Definition: ascon-xof.c:146
void ascon_xof_reinit_fixed(ascon_xof_state_t *state, size_t outlen)
Re-initializes the state for an incremental ASCON-XOF operation, with a fixed output length.
Definition: ascon-xof.c:194
void ascon_xof_reinit_custom(ascon_xof_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-XOF operation, with a named function,...
Definition: ascon-xof.c:206
void ascon_xof_copy(ascon_xof_state_t *dest, const ascon_xof_state_t *src)
Clones a copy of an ASCON-XOF state.
Definition: ascon-xof.c:344
void ascon_xof_squeeze(ascon_xof_state_t *state, unsigned char *out, size_t outlen)
Squeezes output data from an ASCON-XOF state.
Definition: ascon-xof.c:279
void ascon_xof(unsigned char *out, const unsigned char *in, size_t inlen)
Hashes a block of input data with ASCON-XOF and generates a fixed-length 32 byte output.
Definition: ascon-xof.c:28
void ascon_xof_init_fixed(ascon_xof_state_t *state, size_t outlen)
Initializes the state for an incremental ASCON-XOF operation, with a fixed output length.
Definition: ascon-xof.c:74
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-XOF incremental mode.
Definition: xof.h:61
ascon_state_t state
Definition: xof.h:62
unsigned char mode
Definition: xof.h:64
unsigned char count
Definition: xof.h:63
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_HASH_SIZE
Size of the hash output for ASCON-HASH and the default hash output size for ASCON-XOF.
Definition: xof.h:43