4 * Based on CC0 code by David Leon Gil, 2015 \n
5 * Copyright (c) 2015 Cryptography Research, Inc. \n
6 * Released under the MIT License. See LICENSE.txt for license information.
8 * @brief SHA-3-n and DECAF_SHAKE-n instances.
11 #ifndef __DECAF_SHAKE_H__
12 #define __DECAF_SHAKE_H__
15 #include <sys/types.h>
16 #include <stdlib.h> /* for NULL */
18 #include <decaf/common.h>
24 #ifndef INTERNAL_SPONGE_STRUCT
25 /** Sponge container object for the various primitives. */
26 typedef struct decaf_keccak_sponge_s {
30 } decaf_keccak_sponge_s;
32 /** Convenience GMP-style one-element array version */
33 typedef struct decaf_keccak_sponge_s decaf_keccak_sponge_t[1];
35 /** Parameters for sponge construction, distinguishing DECAF_SHA3 and
36 * DECAF_SHAKE instances.
38 struct decaf_kparams_s;
42 * @brief Initialize a sponge context object.
43 * @param [out] sponge The object to initialize.
44 * @param [in] params The sponge's parameter description.
46 void decaf_sha3_init (
47 decaf_keccak_sponge_t sponge,
48 const struct decaf_kparams_s *params
52 * @brief Absorb data into a DECAF_SHA3 or DECAF_SHAKE hash context.
53 * @param [inout] sponge The context.
54 * @param [in] in The input data.
55 * @param [in] len The input data's length in bytes.
56 * @return DECAF_FAILURE if the sponge has already been used for output.
57 * @return DECAF_SUCCESS otherwise.
59 decaf_error_t decaf_sha3_update (
60 struct decaf_keccak_sponge_s * __restrict__ sponge,
66 * @brief Squeeze output data from a DECAF_SHA3 or DECAF_SHAKE hash context.
67 * This does not destroy or re-initialize the hash context, and
68 * decaf_sha3 output can be called more times.
70 * @param [inout] sponge The context.
71 * @param [out] out The output data.
72 * @param [in] len The requested output data length in bytes.
73 * @return DECAF_FAILURE if the sponge has exhausted its output capacity.
74 * @return DECAF_SUCCESS otherwise.
76 decaf_error_t decaf_sha3_output (
77 decaf_keccak_sponge_t sponge,
78 uint8_t * __restrict__ out,
83 * @brief Squeeze output data from a DECAF_SHA3 or DECAF_SHAKE hash context.
84 * This re-initializes the context to its starting parameters.
86 * @param [inout] sponge The context.
87 * @param [out] out The output data.
88 * @param [in] len The requested output data length in bytes.
90 decaf_error_t decaf_sha3_final (
91 decaf_keccak_sponge_t sponge,
92 uint8_t * __restrict__ out,
97 * @brief Reset the sponge to the empty string.
99 * @param [inout] sponge The context.
101 void decaf_sha3_reset (
102 decaf_keccak_sponge_t sponge
106 * @brief Return the default output length of the sponge construction,
107 * for the purpose of C++ default operators.
109 * Returns n/8 for DECAF_SHA3-n and 2n/8 for DECAF_SHAKE-n.
111 size_t decaf_sha3_default_output_bytes (
112 const decaf_keccak_sponge_t sponge /**< [inout] The context. */
116 * @brief Return the default output length of the sponge construction,
117 * for the purpose of C++ default operators.
119 * Returns n/8 for DECAF_SHA3-n and SIZE_MAX for DECAF_SHAKE-n.
121 size_t decaf_sha3_max_output_bytes (
122 const decaf_keccak_sponge_t sponge /**< [inout] The context. */
126 * @brief Destroy a DECAF_SHA3 or DECAF_SHAKE sponge context by overwriting it with 0.
127 * @param [out] sponge The context.
129 void decaf_sha3_destroy (
130 decaf_keccak_sponge_t sponge
134 * @brief Hash (in) to (out)
135 * @param [in] in The input data.
136 * @param [in] inlen The length of the input data.
137 * @param [out] out A buffer for the output data.
138 * @param [in] outlen The length of the output data.
139 * @param [in] params The parameters of the sponge hash.
141 decaf_error_t decaf_sha3_hash (
146 const struct decaf_kparams_s *params
149 /* FUTURE: expand/doxygenate individual DECAF_SHAKE/DECAF_SHA3 instances? */
151 /** @cond internal */
152 #define DECAF_DEC_SHAKE(n) \
153 extern const struct decaf_kparams_s DECAF_SHAKE##n##_params_s DECAF_API_VIS; \
154 typedef struct decaf_shake##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_shake##n##_ctx_t[1]; \
155 static inline void DECAF_NONNULL decaf_shake##n##_init(decaf_shake##n##_ctx_t sponge) { \
156 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \
158 static inline void DECAF_NONNULL decaf_shake##n##_gen_init(decaf_keccak_sponge_t sponge) { \
159 decaf_sha3_init(sponge, &DECAF_SHAKE##n##_params_s); \
161 static inline decaf_error_t DECAF_NONNULL decaf_shake##n##_update(decaf_shake##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \
162 return decaf_sha3_update(sponge->s, in, inlen); \
164 static inline void DECAF_NONNULL decaf_shake##n##_final(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \
165 decaf_sha3_output(sponge->s, out, outlen); \
166 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \
168 static inline void DECAF_NONNULL decaf_shake##n##_output(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \
169 decaf_sha3_output(sponge->s, out, outlen); \
171 static inline void DECAF_NONNULL decaf_shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
172 decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHAKE##n##_params_s); \
174 static inline void DECAF_NONNULL decaf_shake##n##_destroy( decaf_shake##n##_ctx_t sponge ) { \
175 decaf_sha3_destroy(sponge->s); \
178 #define DECAF_DEC_SHA3(n) \
179 extern const struct decaf_kparams_s DECAF_SHA3_##n##_params_s DECAF_API_VIS; \
180 typedef struct decaf_sha3_##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_sha3_##n##_ctx_t[1]; \
181 static inline void DECAF_NONNULL decaf_sha3_##n##_init(decaf_sha3_##n##_ctx_t sponge) { \
182 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \
184 static inline void DECAF_NONNULL decaf_sha3_##n##_gen_init(decaf_keccak_sponge_t sponge) { \
185 decaf_sha3_init(sponge, &DECAF_SHA3_##n##_params_s); \
187 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_update(decaf_sha3_##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \
188 return decaf_sha3_update(sponge->s, in, inlen); \
190 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_final(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \
191 decaf_error_t ret = decaf_sha3_output(sponge->s, out, outlen); \
192 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \
195 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_output(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \
196 return decaf_sha3_output(sponge->s, out, outlen); \
198 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \
199 return decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHA3_##n##_params_s); \
201 static inline void DECAF_NONNULL decaf_sha3_##n##_destroy(decaf_sha3_##n##_ctx_t sponge) { \
202 decaf_sha3_destroy(sponge->s); \
212 #undef DECAF_DEC_SHAKE
213 #undef DECAF_DEC_SHA3
219 #endif /* __DECAF_SHAKE_H__ */