diff --git a/docs/.Doxyfile b/docs/.Doxyfile index 708244008..8d150a338 100644 --- a/docs/.Doxyfile +++ b/docs/.Doxyfile @@ -793,6 +793,7 @@ WARN_LOGFILE = INPUT = src/common/common.h \ src/common/rand.h \ + src/crypto/sha3/sha3.h \ src/kem/kem.h \ src/sig/sig.h \ README.md diff --git a/src/crypto/sha3/sha3.h b/src/crypto/sha3/sha3.h index 75d31af75..6dac9d872 100644 --- a/src/crypto/sha3/sha3.h +++ b/src/crypto/sha3/sha3.h @@ -1,12 +1,14 @@ /** -* \file sha3.h -* \brief SHA3 header definition \n -* Contains the public api and documentation for SHA3 digest and SHAKE implementations. -* -* \author John Underhill -* \date December 29, 2017 -* \remarks For usage examples, see sha3_test.h -*/ + * \file sha3.h + * \brief SHA3, SHAKE, and cSHAKE functions; not part of the OQS public API + * + * Contains the API and documentation for SHA3 digest and SHAKE implementations. + * + * Note this is not part of the OQS public API: implementations within liboqs can use these + * functions, but external consumers of liboqs should not use these functions. + * + * \author John Underhill, Douglas Stebila + */ #ifndef OQS_SHA3_H #define OQS_SHA3_H @@ -20,245 +22,457 @@ extern "C" { /* SHA3 */ +/** The SHA-256 byte absorption rate */ #define OQS_SHA3_SHA3_256_RATE 136 /** -* \brief Process a message with SHA3-256 and return the hash code in the output byte array. -* -* \warning The output array must be at least 32 bytes in length. -* -* \param output The output byte array -* \param input The message input byte array -* \param inplen The number of message bytes to process -*/ + * \brief Process a message with SHA3-256 and return the hash code in the output byte array. + * + * \warning The output array must be at least 32 bytes in length. + * + * \param output The output byte array + * \param input The message input byte array + * \param inplen The number of message bytes to process + */ void OQS_SHA3_sha3_256(uint8_t *output, const uint8_t *input, size_t inplen); +/** Data structure for the state of the SHA3-256 incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[26]; } OQS_SHA3_sha3_256_inc_ctx; +/** + * \brief Initialize the state for the SHA3-256 incremental hashing API. + * + * \param state The function state to be initialized; must be allocated + */ void OQS_SHA3_sha3_256_inc_init(OQS_SHA3_sha3_256_inc_ctx *state); + +/** + * \brief The SHA3-256 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. + * + * \param state The function state; must be initialized + * \param input The input message byte array + * \param inlen The number of message bytes to process + */ void OQS_SHA3_sha3_256_inc_absorb(OQS_SHA3_sha3_256_inc_ctx *state, const uint8_t *input, size_t inlen); + +/** + * \brief The SHA3-256 squeeze/finalize function. + * Permutes and extracts the state to an output byte array. + * + * \warning Output array must be allocated. + * + * \param output The output byte array + * \param state The function state; must be initialized + */ void OQS_SHA3_sha3_256_inc_finalize(uint8_t *output, OQS_SHA3_sha3_256_inc_ctx *state); +/** The SHA-384 byte absorption rate */ #define OQS_SHA3_SHA3_384_RATE 104 /** -* \brief Process a message with SHA3-384 and return the hash code in the output byte array. -* -* \warning The output array must be at least 32 bytes in length. -* -* \param output The output byte array -* \param input The message input byte array -* \param inplen The number of message bytes to process -*/ + * \brief Process a message with SHA3-384 and return the hash code in the output byte array. + * + * \warning The output array must be at least 32 bytes in length. + * + * \param output The output byte array + * \param input The message input byte array + * \param inplen The number of message bytes to process + */ void OQS_SHA3_sha3_384(uint8_t *output, const uint8_t *input, size_t inplen); +/** Data structure for the state of the SHA3-384 incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[26]; } OQS_SHA3_sha3_384_inc_ctx; +/** + * \brief Initialize the state for the SHA3-384 incremental hashing API. + * + * \param state The function state to be initialized; must be allocated + */ void OQS_SHA3_sha3_384_inc_init(OQS_SHA3_sha3_384_inc_ctx *state); + +/** + * \brief The SHA3-384 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. + * + * \param state The function state; must be initialized + * \param input The input message byte array + * \param inlen The number of message bytes to process + */ void OQS_SHA3_sha3_384_inc_absorb(OQS_SHA3_sha3_384_inc_ctx *state, const uint8_t *input, size_t inlen); + +/** + * \brief The SHA3-384 squeeze/finalize function. + * Permutes and extracts the state to an output byte array. + * + * \warning Output array must be allocated. + * + * \param output The output byte array + * \param state The function state; must be initialized + */ void OQS_SHA3_sha3_384_inc_finalize(uint8_t *output, OQS_SHA3_sha3_384_inc_ctx *state); +/** The SHA-512 byte absorption rate */ #define OQS_SHA3_SHA3_512_RATE 72 /** -* \brief Process a message with SHA3-512 and return the hash code in the output byte array. -* -* \warning The output array must be at least 64 bytes in length. -* -* \param output The output byte array -* \param input The message input byte array -* \param inplen The number of message bytes to process -*/ + * \brief Process a message with SHA3-512 and return the hash code in the output byte array. + * + * \warning The output array must be at least 64 bytes in length. + * + * \param output The output byte array + * \param input The message input byte array + * \param inplen The number of message bytes to process + */ void OQS_SHA3_sha3_512(uint8_t *output, const uint8_t *input, size_t inplen); +/** Data structure for the state of the SHA3-512 incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[26]; } OQS_SHA3_sha3_512_inc_ctx; +/** + * \brief Initialize the state for the SHA3-512 incremental hashing API. + * + * \param state The function state to be initialized; must be allocated + */ void OQS_SHA3_sha3_512_inc_init(OQS_SHA3_sha3_512_inc_ctx *state); + +/** + * \brief The SHA3-512 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. + * + * \param state The function state; must be initialized + * \param input The input message byte array + * \param inlen The number of message bytes to process + */ void OQS_SHA3_sha3_512_inc_absorb(OQS_SHA3_sha3_512_inc_ctx *state, const uint8_t *input, size_t inlen); + +/** + * \brief The SHA3-512 finalize/squeeze function. + * Permutes and extracts the state to an output byte array. + * + * \warning Output array must be allocated. + * + * \param output The output byte array + * \param state The function state; must be initialized + */ void OQS_SHA3_sha3_512_inc_finalize(uint8_t *output, OQS_SHA3_sha3_512_inc_ctx *state); /* SHAKE */ +/** The SHAKE-128 byte absorption rate */ #define OQS_SHA3_SHAKE128_RATE 168 /** -* \brief Seed a SHAKE-128 instance, and generate an array of pseudo-random bytes. -* -* \warning The output array length must not be zero. -* -* \param output The output byte array -* \param outlen The number of output bytes to generate -* \param input The input seed byte array -* \param inplen The number of seed bytes to process -*/ + * \brief Seed a SHAKE-128 instance, and generate an array of pseudo-random bytes. + * + * \warning The output array length must not be zero. + * + * \param output The output byte array + * \param outlen The number of output bytes to generate + * \param input The input seed byte array + * \param inplen The number of seed bytes to process + */ void OQS_SHA3_shake128(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen); +/** Data structure for the state of the SHAKE128 non-incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[25]; } OQS_SHA3_shake128_ctx; /** -* \brief The SHAKE-128 absorb function. -* Absorb and finalize an input seed byte array. -* Should be used in conjunction with the shake128_squeezeblocks function. -* -* \warning Finalizes the seed state, should not be used in consecutive calls. \n -* State must be initialized (and zeroed) by the caller. -* -* \param state The function state; must be pre-initialized -* \param input The input seed byte array -* \param inplen The number of seed bytes to process -*/ + * \brief The SHAKE-128 absorb function. + * Absorb and finalize an input seed byte array. + * Should be used in conjunction with the shake128_squeezeblocks function. + * + * \warning Finalizes the seed state, should not be used in consecutive calls. \n + * State must be allocated by the caller. + * + * \param state The function state; must be allocated + * \param input The input seed byte array + * \param inplen The number of seed bytes to process + */ void OQS_SHA3_shake128_absorb(OQS_SHA3_shake128_ctx *state, const uint8_t *input, size_t inplen); /** -* \brief The SHAKE-128 squeeze function. -* Permutes and extracts the state to an output byte array. -* Should be used in conjunction with the shake128_absorb function. -* -* \warning Output array must be initialized to a multiple of the byte rate. -* -* \param output The output byte array -* \param nblocks The number of blocks to extract -* \param state The function state; must be pre-initialized -*/ + * \brief The SHAKE-128 squeeze function. + * Permutes and extracts the state to an output byte array. + * Should be used in conjunction with the shake128_absorb function. + * + * \warning Output array must be initialized to a multiple of the byte rate. + * + * \param output The output byte array + * \param nblocks The number of blocks to extract + * \param state The function state; must be allocated + */ void OQS_SHA3_shake128_squeezeblocks(uint8_t *output, size_t nblocks, OQS_SHA3_shake128_ctx *state); +/** Data structure for the state of the SHAKE-128 incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[26]; } OQS_SHA3_shake128_inc_ctx; /** - * \brief Initialize the incremental hashing API state + * \brief Initialize the state for the SHAKE-128 incremental hashing API. + * + * \param s_inc The function state to be initialized; must be allocated */ void OQS_SHA3_shake128_inc_init(OQS_SHA3_shake128_inc_ctx *s_inc); /** - * \brief Absorb into the state + * \brief The SHAKE-128 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. * * \param s_inc state * \param input input buffer * \param inlen length of input buffer */ void OQS_SHA3_shake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *s_inc, const uint8_t *input, size_t inlen); -/* - * \brief Finalizes output + +/** + * \brief The SHAKE-128 finalize function. * - * \param s_inc Incremental hashing state + * \param s_inc The function state; must be initialized */ void OQS_SHA3_shake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *s_inc); /** - * \brief Obtains output + * \brief The SHAKE-128 squeeze function. + * Extracts to an output byte array. * * \param output output buffer * \param outlen bytes of outbut buffer - * \param state + * \param s_inc */ void OQS_SHA3_shake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *s_inc); +/** The SHAKE-256 byte absorption rate */ #define OQS_SHA3_SHAKE256_RATE 136 /** -* \brief Seed a SHAKE-256 instance, and generate an array of pseudo-random bytes. -* -* \warning The output array length must not be zero. -* -* \param output The output byte array -* \param outlen The number of output bytes to generate -* \param input The input seed byte array -* \param inplen The number of seed bytes to process -*/ + * \brief Seed a SHAKE-256 instance, and generate an array of pseudo-random bytes. + * + * \warning The output array length must not be zero. + * + * \param output The output byte array + * \param outlen The number of output bytes to generate + * \param input The input seed byte array + * \param inplen The number of seed bytes to process + */ void OQS_SHA3_shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inplen); +/** Data structure for the state of the SHAKE-256 non-incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[25]; } OQS_SHA3_shake256_ctx; /** -* \brief The SHAKE-256 absorb function. -* Absorb and finalize an input seed byte array. -* Should be used in conjunction with the shake256_squeezeblocks function. -* -* \warning Finalizes the seed state, should not be used in consecutive calls. \n -* State must be initialized (and zeroed) by the caller. -* -* \param state The function state; must be pre-initialized -* \param input The input seed byte array -* \param inplen The number of seed bytes to process -*/ + * \brief The SHAKE-256 absorb function. + * Absorb and finalize an input seed byte array. + * Should be used in conjunction with the shake256_squeezeblocks function. + * + * \warning Finalizes the seed state, should not be used in consecutive calls. \n + * State must be initialized (and zeroed) by the caller. + * + * \param state The function state; must be pre-initialized + * \param input The input seed byte array + * \param inplen The number of seed bytes to process + */ void OQS_SHA3_shake256_absorb(OQS_SHA3_shake256_ctx *state, const uint8_t *input, size_t inplen); /** -* \brief The SHAKE-256 squeeze function. -* Permutes and extracts the state to an output byte array. -* -* \warning Output array must be initialized to a multiple of the byte rate. -* -* \param output The output byte array -* \param nblocks The number of blocks to extract -* \param state The function state; must be pre-initialized -*/ + * \brief The SHAKE-256 squeeze function. + * Permutes and extracts the state to an output byte array. + * + * \warning Output array must be initialized to a multiple of the byte rate. + * + * \param output The output byte array + * \param nblocks The number of blocks to extract + * \param state The function state; must be pre-initialized + */ void OQS_SHA3_shake256_squeezeblocks(uint8_t *output, size_t nblocks, OQS_SHA3_shake256_ctx *state); +/** Data structure for the state of the SHAKE-256 incremental hashing API. */ typedef struct { + /** Internal state. */ uint64_t ctx[26]; } OQS_SHA3_shake256_inc_ctx; /** - * \brief Initialize the incremental hashing API state + * \brief Initialize the state for the SHAKE-256 incremental hashing API. + * + * \param s_inc The function state to be initialized; must be allocated */ void OQS_SHA3_shake256_inc_init(OQS_SHA3_shake256_inc_ctx *s_inc); /** - * \brief Absorb into the state + * \brief The SHAKE-256 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. * * \param s_inc state * \param input input buffer * \param inlen length of input buffer */ void OQS_SHA3_shake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *s_inc, const uint8_t *input, size_t inlen); -/* - * \brief Finalizes output + +/** + * \brief The SHAKE-256 finalize function. * - * \param s_inc Incremental hashing state + * \param s_inc The function state; must be initialized */ void OQS_SHA3_shake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *s_inc); /** - * \brief Obtains output + * \brief The SHAKE-256 squeeze function. + * Extracts to an output byte array. * * \param output output buffer * \param outlen bytes of outbut buffer - * \param state + * \param s_inc state */ void OQS_SHA3_shake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *s_inc); /* cSHAKE */ +/** + * \brief Seed a cSHAKE-128 instance and generate pseudo-random output. + * Permutes and extracts the state to an output byte array. + * + * \warning This function has a counter period of 2^16. + * + * \param output The output byte array + * \param outlen The number of output bytes to generate + * \param name The function name input as a byte array + * \param namelen The length of the function name byte array + * \param cstm The customization string as a byte array + * \param cstmlen The length of the customization string byte array + * \param input The input seed byte array + * \param inlen The number of seed bytes to process + */ void OQS_SHA3_cshake128(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen, const uint8_t *input, size_t inlen); +/** + * \brief Initialize the state for the cSHAKE-128 incremental hashing API. + * + * \param state The function state to be initialized; must be allocated + * \param name The function name input as a byte array + * \param namelen The length of the function name byte array + * \param cstm The customization string as a byte array + * \param cstmlen The length of the customization string byte array + */ void OQS_SHA3_cshake128_inc_init(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen); + +/** + * \brief The cSHAKE-128 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. + * + * \param state state + * \param input input buffer + * \param inlen length of input buffer + */ void OQS_SHA3_cshake128_inc_absorb(OQS_SHA3_shake128_inc_ctx *state, const uint8_t *input, size_t inlen); + +/** + * \brief The cSHAKE-128 finalize function. + * + * \param state The function state; must be initialized + */ void OQS_SHA3_cshake128_inc_finalize(OQS_SHA3_shake128_inc_ctx *state); + +/** + * \brief The cSHAKE-128 squeeze function. + * Extracts to an output byte array. + * + * \param output output buffer + * \param outlen bytes of outbut buffer + * \param state + */ void OQS_SHA3_cshake128_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake128_inc_ctx *state); +/** + * \brief Seed a cSHAKE-256 instance and generate pseudo-random output. + * Permutes and extracts the state to an output byte array. + * + * \warning This function has a counter period of 2^16. + * + * \param output The output byte array + * \param outlen The number of output bytes to generate + * \param name The function name input as a byte array + * \param namelen The length of the function name byte array + * \param cstm The customization string as a byte array + * \param cstmlen The length of the customization string byte array + * \param input The input seed byte array + * \param inlen The number of seed bytes to process + */ void OQS_SHA3_cshake256(uint8_t *output, size_t outlen, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen, const uint8_t *input, size_t inlen); +/** + * \brief Initialize the state for the cSHAKE-256 incremental hashing API. + * + * \param state The function state to be initialized; must be allocated + * \param name The function name input as a byte array + * \param namelen The length of the function name byte array + * \param cstm The customization string as a byte array + * \param cstmlen The length of the customization string byte array + */ void OQS_SHA3_cshake256_inc_init(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen); + +/** + * \brief The cSHAKE-256 absorb function. + * Absorb an input message array directly into the state. + * + * \warning State must be initialized by the caller. + * + * \param state state + * \param input input buffer + * \param inlen length of input buffer + */ void OQS_SHA3_cshake256_inc_absorb(OQS_SHA3_shake256_inc_ctx *state, const uint8_t *input, size_t inlen); + +/** + * \brief The cSHAKE-256 finalize function. + * + * \param state The function state; must be initialized + */ void OQS_SHA3_cshake256_inc_finalize(OQS_SHA3_shake256_inc_ctx *state); + +/** + * \brief The cSHAKE-256 squeeze function. + * Extracts to an output byte array. + * + * \param output output buffer + * \param outlen bytes of outbut buffer + * \param state + */ void OQS_SHA3_cshake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_shake256_inc_ctx *state); /** -* \brief Seed a cSHAKE-128 instance and generate pseudo-random output. +* \brief Seed a cSHAKE-128 instance and generate pseudo-random output, using a "simplified" customization string. * Permutes and extracts the state to an output byte array. +* The "simplified" customization string procedure is ad hoc but used in several NIST candidates. * * \warning This function has a counter period of 2^16. * @@ -271,8 +485,9 @@ void OQS_SHA3_cshake256_inc_squeeze(uint8_t *output, size_t outlen, OQS_SHA3_sha void OQS_SHA3_cshake128_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen); /** -* \brief Seed a cSHAKE-256 instance and generate pseudo-random output. +* \brief Seed a cSHAKE-256 instance and generate pseudo-random output, using a "simplified" customization string. * Permutes and extracts the state to an output byte array. +* The "simplified" customization string procedure is ad hoc but used in several NIST candidates. * * \warning This function has a counter period of 2^16. * @@ -284,35 +499,6 @@ void OQS_SHA3_cshake128_simple(uint8_t *output, size_t outlen, uint16_t cstm, co */ void OQS_SHA3_cshake256_simple(uint8_t *output, size_t outlen, uint16_t cstm, const uint8_t *input, size_t inplen); -#if 0 -/** -* \brief The cSHAKE-256 simple absorb function. -* Absorb and finalize an input seed directly into the state. -* Should be used in conjunction with the cshake256_simple_squeezeblocks function. -* -* \warning Finalizes the seed state, should not be used in consecutive calls. \n -* State must be initialized (and zeroed) by the caller. -* -* \param state The function state; must be pre-initialized -* \param cstm The 16bit customization integer -* \param input The input seed byte array -* \param inplen The number of seed bytes to process -*/ -void OQS_SHA3_cshake256_simple_absorb(uint64_t *state, uint16_t cstm, const uint8_t *input, size_t inplen); - -/** -* \brief The cSHAKE-256 simple squeeze function. -* Permutes and extracts blocks of state to an output byte array. -* -* \warning Output array must be initialized to a multiple of the byte rate. -* -* \param output The output byte array -* \param nblocks The number of blocks to extract -* \param state The function state; must be pre-initialized -*/ -void OQS_SHA3_cshake256_simple_squeezeblocks(uint8_t *output, size_t nblocks, uint64_t *state); -#endif - #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/crypto/sha3/sha3_c.c b/src/crypto/sha3/sha3_c.c index 3896e2d95..e9938e215 100644 --- a/src/crypto/sha3/sha3_c.c +++ b/src/crypto/sha3/sha3_c.c @@ -1,4 +1,10 @@ -#include +/** +* \file sha3_c.c +* \brief Implementation of the OQS SHA3 API via the files fips202.c and sp800-185.c +* from PQClean (https://github.com/PQClean/PQClean/tree/master/common) +*/ + +#include "sha3.h" #define SHA3_256_RATE OQS_SHA3_SHA3_256_RATE #define sha3_256 OQS_SHA3_sha3_256