diff --git a/common/fips202.c b/common/fips202.c index d61c28fd..ceeb6a5c 100644 --- a/common/fips202.c +++ b/common/fips202.c @@ -675,6 +675,25 @@ void shake256(uint8_t *output, size_t outlen, } } +void sha3_256_inc_init(uint64_t *s_inc) { + keccak_inc_init(s_inc); +} + +void sha3_256_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen) { + keccak_inc_absorb(s_inc, SHA3_256_RATE, input, inlen); +} + +void sha3_256_inc_finalize(uint8_t *output, uint64_t *s_inc) { + uint8_t t[SHA3_256_RATE]; + keccak_inc_finalize(s_inc, SHA3_256_RATE, 0x06); + + keccak_squeezeblocks(t, 1, s_inc, SHA3_256_RATE); + + for (size_t i = 0; i < 32; i++) { + output[i] = t[i]; + } +} + /************************************************* * Name: sha3_256 * @@ -699,6 +718,25 @@ void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen) { } } +void sha3_512_inc_init(uint64_t *s_inc) { + keccak_inc_init(s_inc); +} + +void sha3_512_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen) { + keccak_inc_absorb(s_inc, SHA3_512_RATE, input, inlen); +} + +void sha3_512_inc_finalize(uint8_t *output, uint64_t *s_inc) { + uint8_t t[SHA3_512_RATE]; + keccak_inc_finalize(s_inc, SHA3_512_RATE, 0x06); + + keccak_squeezeblocks(t, 1, s_inc, SHA3_512_RATE); + + for (size_t i = 0; i < 32; i++) { + output[i] = t[i]; + } +} + /************************************************* * Name: sha3_512 * diff --git a/common/fips202.h b/common/fips202.h index 4a28d67b..8971cf5c 100644 --- a/common/fips202.h +++ b/common/fips202.h @@ -32,7 +32,16 @@ void shake128(uint8_t *output, size_t outlen, void shake256(uint8_t *output, size_t outlen, const uint8_t *input, size_t inlen); +void sha3_256_inc_init(uint64_t *s_inc); +void sha3_256_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen); +void sha3_256_inc_finalize(uint8_t *output, uint64_t *s_inc); + void sha3_256(uint8_t *output, const uint8_t *input, size_t inlen); + +void sha3_512_inc_init(uint64_t *s_inc); +void sha3_512_inc_absorb(uint64_t *s_inc, const uint8_t *input, size_t inlen); +void sha3_512_inc_finalize(uint8_t *output, uint64_t *s_inc); + void sha3_512(uint8_t *output, const uint8_t *input, size_t inlen); #endif diff --git a/test/common/fips202.c b/test/common/fips202.c index e559d07f..7c28672f 100644 --- a/test/common/fips202.c +++ b/test/common/fips202.c @@ -52,6 +52,50 @@ const unsigned char expected[512] = { 0x6b, 0xf5, 0xf6, 0x0b, 0x21, 0xb5, 0x82, 0x2d }; +static int test_sha3_256_incremental(void) { + unsigned char input[512]; + unsigned char check[512]; + unsigned char output[512]; + uint64_t s_inc[26]; + int i; + int absorbed; + int returncode = 0; + + for (i = 0; i < 512; i++) { + input[i] = i; + } + + sha3_256(check, input, 512); + + sha3_256_inc_init(s_inc); + + absorbed = 0; + for (i = 0; i < 512 && absorbed + i <= 512; i++) { + sha3_256_inc_absorb(s_inc, input + absorbed, i); + absorbed += i; + } + sha3_256_inc_absorb(s_inc, input + absorbed, 512 - absorbed); + + sha3_256_inc_finalize(output, s_inc); + + if (memcmp(check, output, 512)) { + printf("ERROR sha3_256 incremental did not match sha3_256.\n"); + printf(" Expected: "); + for (i = 0; i < 512; i++) { + printf("%02X", check[i]); + } + printf("\n"); + printf(" Received: "); + for (i = 0; i < 512; i++) { + printf("%02X", output[i]); + } + printf("\n"); + returncode = 1; + } + + return returncode; +} + static int test_shake128_incremental(void) { unsigned char input[512]; unsigned char check[512]; @@ -228,6 +272,7 @@ int main(void) { int result = 0; result += test_shake128(); result += test_shake128_incremental(); + result += test_sha3_256_incremental(); if (result != 0) { puts("Errors occurred");