1 /** 2 * @file decaf/shake.h 3 * @copyright 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. 7 * @author Mike Hamburg 8 * @brief SHA-3-n and DECAF_SHAKE-n instances. 9 */ 10 11 #ifndef __DECAF_SHAKE_H__ 12 #define __DECAF_SHAKE_H__ 13 14 #include <stdint.h> 15 #include <sys/types.h> 16 #include <stdlib.h> /* for NULL */ 17 18 #include <decaf/common.h> 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 #ifndef INTERNAL_SPONGE_STRUCT 25 /** Sponge container object for the various primitives. */ 26 typedef struct decaf_keccak_sponge_s { 27 /** @cond internal */ 28 uint64_t opaque[26]; 29 /** @endcond */ 30 } decaf_keccak_sponge_s; 31 32 /** Convenience GMP-style one-element array version */ 33 typedef struct decaf_keccak_sponge_s decaf_keccak_sponge_t[1]; 34 35 /** Parameters for sponge construction, distinguishing DECAF_SHA3 and 36 * DECAF_SHAKE instances. 37 */ 38 struct decaf_kparams_s; 39 #endif 40 41 /** 42 * @brief Initialize a sponge context object. 43 * @param [out] sponge The object to initialize. 44 * @param [in] params The sponge's parameter description. 45 */ 46 void DECAF_API_VIS decaf_sha3_init ( 47 decaf_keccak_sponge_t sponge, 48 const struct decaf_kparams_s *params 49 ); 50 51 /** 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. 58 */ 59 decaf_error_t DECAF_API_VIS decaf_sha3_update ( 60 struct decaf_keccak_sponge_s * __restrict__ sponge, 61 const uint8_t *in, 62 size_t len 63 ); 64 65 /** 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. 69 * 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. 75 */ 76 decaf_error_t DECAF_API_VIS decaf_sha3_output ( 77 decaf_keccak_sponge_t sponge, 78 uint8_t * __restrict__ out, 79 size_t len 80 ); 81 82 /** 83 * @brief Squeeze output data from a DECAF_SHA3 or DECAF_SHAKE hash context. 84 * This re-initializes the context to its starting parameters. 85 * 86 * @param [inout] sponge The context. 87 * @param [out] out The output data. 88 * @param [in] len The requested output data length in bytes. 89 */ 90 decaf_error_t DECAF_API_VIS decaf_sha3_final ( 91 decaf_keccak_sponge_t sponge, 92 uint8_t * __restrict__ out, 93 size_t len 94 ); 95 96 /** 97 * @brief Reset the sponge to the empty string. 98 * 99 * @param [inout] sponge The context. 100 */ 101 void DECAF_API_VIS decaf_sha3_reset ( 102 decaf_keccak_sponge_t sponge 103 ); 104 105 /** 106 * @brief Return the default output length of the sponge construction, 107 * for the purpose of C++ default operators. 108 * 109 * Returns n/8 for DECAF_SHA3-n and 2n/8 for DECAF_SHAKE-n. 110 */ 111 size_t DECAF_API_VIS decaf_sha3_default_output_bytes ( 112 const decaf_keccak_sponge_t sponge /**< [inout] The context. */ 113 ); 114 115 /** 116 * @brief Return the default output length of the sponge construction, 117 * for the purpose of C++ default operators. 118 * 119 * Returns n/8 for DECAF_SHA3-n and SIZE_MAX for DECAF_SHAKE-n. 120 */ 121 size_t DECAF_API_VIS decaf_sha3_max_output_bytes ( 122 const decaf_keccak_sponge_t sponge /**< [inout] The context. */ 123 ); 124 125 /** 126 * @brief Destroy a DECAF_SHA3 or DECAF_SHAKE sponge context by overwriting it with 0. 127 * @param [out] sponge The context. 128 */ 129 void DECAF_API_VIS decaf_sha3_destroy ( 130 decaf_keccak_sponge_t sponge 131 ); 132 133 /** 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. 140 */ 141 decaf_error_t DECAF_API_VIS decaf_sha3_hash ( 142 uint8_t *out, 143 size_t outlen, 144 const uint8_t *in, 145 size_t inlen, 146 const struct decaf_kparams_s *params 147 ); 148 149 /* FUTURE: expand/doxygenate individual DECAF_SHAKE/DECAF_SHA3 instances? */ 150 151 #if defined _MSC_VER 152 153 /** @cond internal */ 154 #define DECAF_DEC_SHAKE(n) \ 155 extern const struct DECAF_API_VIS decaf_kparams_s DECAF_SHAKE##n##_params_s; \ 156 typedef struct decaf_shake##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_shake##n##_ctx_t[1]; \ 157 static inline void DECAF_NONNULL decaf_shake##n##_init(decaf_shake##n##_ctx_t sponge) { \ 158 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ 159 } \ 160 static inline void DECAF_NONNULL decaf_shake##n##_gen_init(decaf_keccak_sponge_t sponge) { \ 161 decaf_sha3_init(sponge, &DECAF_SHAKE##n##_params_s); \ 162 } \ 163 static inline decaf_error_t DECAF_NONNULL decaf_shake##n##_update(decaf_shake##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ 164 return decaf_sha3_update(sponge->s, in, inlen); \ 165 } \ 166 static inline void DECAF_NONNULL decaf_shake##n##_final(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 167 decaf_sha3_output(sponge->s, out, outlen); \ 168 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ 169 } \ 170 static inline void DECAF_NONNULL decaf_shake##n##_output(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 171 decaf_sha3_output(sponge->s, out, outlen); \ 172 } \ 173 static inline void DECAF_NONNULL decaf_shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ 174 decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHAKE##n##_params_s); \ 175 } \ 176 static inline void DECAF_NONNULL decaf_shake##n##_destroy( decaf_shake##n##_ctx_t sponge ) { \ 177 decaf_sha3_destroy(sponge->s); \ 178 } 179 180 #define DECAF_DEC_SHA3(n) \ 181 extern const struct DECAF_API_VIS decaf_kparams_s DECAF_SHA3_##n##_params_s; \ 182 typedef struct decaf_sha3_##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_sha3_##n##_ctx_t[1]; \ 183 static inline void DECAF_NONNULL decaf_sha3_##n##_init(decaf_sha3_##n##_ctx_t sponge) { \ 184 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ 185 } \ 186 static inline void DECAF_NONNULL decaf_sha3_##n##_gen_init(decaf_keccak_sponge_t sponge) { \ 187 decaf_sha3_init(sponge, &DECAF_SHA3_##n##_params_s); \ 188 } \ 189 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_update(decaf_sha3_##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ 190 return decaf_sha3_update(sponge->s, in, inlen); \ 191 } \ 192 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_final(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 193 decaf_error_t ret = decaf_sha3_output(sponge->s, out, outlen); \ 194 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ 195 return ret; \ 196 } \ 197 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_output(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 198 return decaf_sha3_output(sponge->s, out, outlen); \ 199 } \ 200 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ 201 return decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHA3_##n##_params_s); \ 202 } \ 203 static inline void DECAF_NONNULL decaf_sha3_##n##_destroy(decaf_sha3_##n##_ctx_t sponge) { \ 204 decaf_sha3_destroy(sponge->s); \ 205 } 206 /** @endcond */ 207 208 #else // _MSC_VER 209 210 /** @cond internal */ 211 #define DECAF_DEC_SHAKE(n) \ 212 DECAF_API_VIS extern const struct decaf_kparams_s DECAF_SHAKE##n##_params_s; \ 213 typedef struct decaf_shake##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_shake##n##_ctx_t[1]; \ 214 static inline void DECAF_NONNULL decaf_shake##n##_init(decaf_shake##n##_ctx_t sponge) { \ 215 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ 216 } \ 217 static inline void DECAF_NONNULL decaf_shake##n##_gen_init(decaf_keccak_sponge_t sponge) { \ 218 decaf_sha3_init(sponge, &DECAF_SHAKE##n##_params_s); \ 219 } \ 220 static inline decaf_error_t DECAF_NONNULL decaf_shake##n##_update(decaf_shake##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ 221 return decaf_sha3_update(sponge->s, in, inlen); \ 222 } \ 223 static inline void DECAF_NONNULL decaf_shake##n##_final(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 224 decaf_sha3_output(sponge->s, out, outlen); \ 225 decaf_sha3_init(sponge->s, &DECAF_SHAKE##n##_params_s); \ 226 } \ 227 static inline void DECAF_NONNULL decaf_shake##n##_output(decaf_shake##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 228 decaf_sha3_output(sponge->s, out, outlen); \ 229 } \ 230 static inline void DECAF_NONNULL decaf_shake##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ 231 decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHAKE##n##_params_s); \ 232 } \ 233 static inline void DECAF_NONNULL decaf_shake##n##_destroy( decaf_shake##n##_ctx_t sponge ) { \ 234 decaf_sha3_destroy(sponge->s); \ 235 } 236 237 #define DECAF_DEC_SHA3(n) \ 238 DECAF_API_VIS extern const struct decaf_kparams_s DECAF_SHA3_##n##_params_s; \ 239 typedef struct decaf_sha3_##n##_ctx_s { decaf_keccak_sponge_t s; } decaf_sha3_##n##_ctx_t[1]; \ 240 static inline void DECAF_NONNULL decaf_sha3_##n##_init(decaf_sha3_##n##_ctx_t sponge) { \ 241 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ 242 } \ 243 static inline void DECAF_NONNULL decaf_sha3_##n##_gen_init(decaf_keccak_sponge_t sponge) { \ 244 decaf_sha3_init(sponge, &DECAF_SHA3_##n##_params_s); \ 245 } \ 246 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_update(decaf_sha3_##n##_ctx_t sponge, const uint8_t *in, size_t inlen ) { \ 247 return decaf_sha3_update(sponge->s, in, inlen); \ 248 } \ 249 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_final(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 250 decaf_error_t ret = decaf_sha3_output(sponge->s, out, outlen); \ 251 decaf_sha3_init(sponge->s, &DECAF_SHA3_##n##_params_s); \ 252 return ret; \ 253 } \ 254 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_output(decaf_sha3_##n##_ctx_t sponge, uint8_t *out, size_t outlen ) { \ 255 return decaf_sha3_output(sponge->s, out, outlen); \ 256 } \ 257 static inline decaf_error_t DECAF_NONNULL decaf_sha3_##n##_hash(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen) { \ 258 return decaf_sha3_hash(out,outlen,in,inlen,&DECAF_SHA3_##n##_params_s); \ 259 } \ 260 static inline void DECAF_NONNULL decaf_sha3_##n##_destroy(decaf_sha3_##n##_ctx_t sponge) { \ 261 decaf_sha3_destroy(sponge->s); \ 262 } 263 /** @endcond */ 264 265 #endif // _MSC_VER 266 267 268 269 DECAF_DEC_SHAKE(128) 270 DECAF_DEC_SHAKE(256) 271 DECAF_DEC_SHA3(224) 272 DECAF_DEC_SHA3(256) 273 DECAF_DEC_SHA3(384) 274 DECAF_DEC_SHA3(512) 275 #undef DECAF_DEC_SHAKE 276 #undef DECAF_DEC_SHA3 277 278 #ifdef __cplusplus 279 } /* extern "C" */ 280 #endif 281 282 #endif /* __DECAF_SHAKE_H__ */ 283