diff --git a/test/default/xof_shake128.c b/test/default/xof_shake128.c index 1d21dc2d..fabe107b 100644 --- a/test/default/xof_shake128.c +++ b/test/default/xof_shake128.c @@ -9,6 +9,66 @@ typedef struct { size_t out_len; } testvector; +static void +shake128_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, + size_t inlen, unsigned char domain) +{ + unsigned char state[crypto_core_keccak1600_STATEBYTES]; + size_t rate = crypto_xof_shake128_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; + + crypto_core_keccak1600_init(state); + + while (consumed < inlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > inlen - consumed) { + chunk_size = inlen - consumed; + } + crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + offset += chunk_size; + consumed += chunk_size; + } + + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + + if (offset == rate - 1) { + pad = (unsigned char) (domain ^ 0x80); + crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + } else { + crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + pad = 0x80; + crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + } + + crypto_core_keccak1600_permute_24(state); + offset = 0; + + while (extracted < outlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > outlen - extracted) { + chunk_size = outlen - extracted; + } + crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + offset += chunk_size; + extracted += chunk_size; + } +} + int main(void) { @@ -129,6 +189,27 @@ main(void) return 1; } + /* Test domain byte with MSB set when padding overlaps */ + { + unsigned char msg[crypto_xof_shake128_BLOCKBYTES - 1]; + unsigned char out_manual[32]; + unsigned char out_impl[32]; + const unsigned char domain = 0x99; + + memset(msg, 0xAA, sizeof msg); + + shake128_manual_with_domain(out_manual, sizeof out_manual, msg, sizeof msg, domain); + + crypto_xof_shake128_init_with_domain(&state, domain); + crypto_xof_shake128_update(&state, msg, sizeof msg); + crypto_xof_shake128_squeeze(&state, out_impl, sizeof out_impl); + + if (memcmp(out_manual, out_impl, sizeof out_manual) != 0) { + printf("Domain MSB padding test failed\n"); + return 1; + } + } + printf("All SHAKE-128 tests passed\n"); return 0; } diff --git a/test/default/xof_shake256.c b/test/default/xof_shake256.c index 765f213d..112b783b 100644 --- a/test/default/xof_shake256.c +++ b/test/default/xof_shake256.c @@ -9,6 +9,66 @@ typedef struct { size_t out_len; } testvector; +static void +shake256_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, + size_t inlen, unsigned char domain) +{ + unsigned char state[crypto_core_keccak1600_STATEBYTES]; + size_t rate = crypto_xof_shake256_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; + + crypto_core_keccak1600_init(state); + + while (consumed < inlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > inlen - consumed) { + chunk_size = inlen - consumed; + } + crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + offset += chunk_size; + consumed += chunk_size; + } + + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + + if (offset == rate - 1) { + pad = (unsigned char) (domain ^ 0x80); + crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + } else { + crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + pad = 0x80; + crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + } + + crypto_core_keccak1600_permute_24(state); + offset = 0; + + while (extracted < outlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_24(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > outlen - extracted) { + chunk_size = outlen - extracted; + } + crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + offset += chunk_size; + extracted += chunk_size; + } +} + int main(void) { @@ -130,6 +190,27 @@ main(void) return 1; } + /* Test domain byte with MSB set when padding overlaps */ + { + unsigned char msg[crypto_xof_shake256_BLOCKBYTES - 1]; + unsigned char out_manual[32]; + unsigned char out_impl[32]; + const unsigned char domain = 0x99; + + memset(msg, 0xAA, sizeof msg); + + shake256_manual_with_domain(out_manual, sizeof out_manual, msg, sizeof msg, domain); + + crypto_xof_shake256_init_with_domain(&state, domain); + crypto_xof_shake256_update(&state, msg, sizeof msg); + crypto_xof_shake256_squeeze(&state, out_impl, sizeof out_impl); + + if (memcmp(out_manual, out_impl, sizeof out_manual) != 0) { + printf("Domain MSB padding test failed\n"); + return 1; + } + } + printf("All SHAKE-256 tests passed\n"); return 0; } diff --git a/test/default/xof_turboshake128.c b/test/default/xof_turboshake128.c index 42e6852f..c03f5ec1 100644 --- a/test/default/xof_turboshake128.c +++ b/test/default/xof_turboshake128.c @@ -9,6 +9,66 @@ typedef struct { size_t out_len; } testvector; +static void +turboshake128_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, + size_t inlen, unsigned char domain) +{ + unsigned char state[crypto_core_keccak1600_STATEBYTES]; + size_t rate = crypto_xof_turboshake128_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; + + crypto_core_keccak1600_init(state); + + while (consumed < inlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > inlen - consumed) { + chunk_size = inlen - consumed; + } + crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + offset += chunk_size; + consumed += chunk_size; + } + + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + + if (offset == rate - 1) { + pad = (unsigned char) (domain ^ 0x80); + crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + } else { + crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + pad = 0x80; + crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + } + + crypto_core_keccak1600_permute_12(state); + offset = 0; + + while (extracted < outlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > outlen - extracted) { + chunk_size = outlen - extracted; + } + crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + offset += chunk_size; + extracted += chunk_size; + } +} + int main(void) { @@ -129,6 +189,27 @@ main(void) return 1; } + /* Test domain byte with MSB set when padding overlaps */ + { + unsigned char msg[crypto_xof_turboshake128_BLOCKBYTES - 1]; + unsigned char out_manual[32]; + unsigned char out_impl[32]; + const unsigned char domain = 0x99; + + memset(msg, 0xAA, sizeof msg); + + turboshake128_manual_with_domain(out_manual, sizeof out_manual, msg, sizeof msg, domain); + + crypto_xof_turboshake128_init_with_domain(&state, domain); + crypto_xof_turboshake128_update(&state, msg, sizeof msg); + crypto_xof_turboshake128_squeeze(&state, out_impl, sizeof out_impl); + + if (memcmp(out_manual, out_impl, sizeof out_manual) != 0) { + printf("Domain MSB padding test failed\n"); + return 1; + } + } + printf("All TurboSHAKE-128 tests passed\n"); return 0; } diff --git a/test/default/xof_turboshake256.c b/test/default/xof_turboshake256.c index 88799f38..43c9ab0d 100644 --- a/test/default/xof_turboshake256.c +++ b/test/default/xof_turboshake256.c @@ -9,6 +9,66 @@ typedef struct { size_t out_len; } testvector; +static void +turboshake256_manual_with_domain(unsigned char *out, size_t outlen, const unsigned char *in, + size_t inlen, unsigned char domain) +{ + unsigned char state[crypto_core_keccak1600_STATEBYTES]; + size_t rate = crypto_xof_turboshake256_blockbytes(); + size_t offset = 0; + size_t consumed = 0; + size_t chunk_size; + size_t extracted = 0; + unsigned char pad; + + crypto_core_keccak1600_init(state); + + while (consumed < inlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > inlen - consumed) { + chunk_size = inlen - consumed; + } + crypto_core_keccak1600_xor_bytes(state, &in[consumed], offset, chunk_size); + offset += chunk_size; + consumed += chunk_size; + } + + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + + if (offset == rate - 1) { + pad = (unsigned char) (domain ^ 0x80); + crypto_core_keccak1600_xor_bytes(state, &pad, offset, 1); + } else { + crypto_core_keccak1600_xor_bytes(state, &domain, offset, 1); + pad = 0x80; + crypto_core_keccak1600_xor_bytes(state, &pad, rate - 1, 1); + } + + crypto_core_keccak1600_permute_12(state); + offset = 0; + + while (extracted < outlen) { + if (offset == rate) { + crypto_core_keccak1600_permute_12(state); + offset = 0; + } + chunk_size = rate - offset; + if (chunk_size > outlen - extracted) { + chunk_size = outlen - extracted; + } + crypto_core_keccak1600_extract_bytes(state, &out[extracted], offset, chunk_size); + offset += chunk_size; + extracted += chunk_size; + } +} + int main(void) { @@ -129,6 +189,27 @@ main(void) return 1; } + /* Test domain byte with MSB set when padding overlaps */ + { + unsigned char msg[crypto_xof_turboshake256_BLOCKBYTES - 1]; + unsigned char out_manual[32]; + unsigned char out_impl[32]; + const unsigned char domain = 0x99; + + memset(msg, 0xAA, sizeof msg); + + turboshake256_manual_with_domain(out_manual, sizeof out_manual, msg, sizeof msg, domain); + + crypto_xof_turboshake256_init_with_domain(&state, domain); + crypto_xof_turboshake256_update(&state, msg, sizeof msg); + crypto_xof_turboshake256_squeeze(&state, out_impl, sizeof out_impl); + + if (memcmp(out_manual, out_impl, sizeof out_manual) != 0) { + printf("Domain MSB padding test failed\n"); + return 1; + } + } + printf("All TurboSHAKE-256 tests passed\n"); return 0; }