implement shake-128 and shake-256 (#6490)

This commit is contained in:
Ashish Kumar 2026-06-23 09:17:13 +05:30 committed by GitHub
parent 9d37b7cdf2
commit 53e8999271
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 480 additions and 2 deletions

View file

@ -28,7 +28,6 @@
/* ------------------------------------------------------------------------- /* -------------------------------------------------------------------------
* *
* TODO: Implement sha3-224
* This is based (copied) of https://github.com/brainhub/SHA3IUF * This is based (copied) of https://github.com/brainhub/SHA3IUF
* *
* Works when compiled for either 32-bit or 64-bit targets, optimized for * Works when compiled for either 32-bit or 64-bit targets, optimized for

View file

@ -0,0 +1,177 @@
// SPDX-FileCopyrightText: 2015 Andrey Jivsov <crypto@brainhub.org>
// SPDX-License-Identifier: MIT
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include "shake.h"
#define SHAKE_CONST(x) x##L
#ifndef SHAKE_ROTL64
#define SHAKE_ROTL64(x, y) \
(((x) << (y)) | ((x) >> ((sizeof(uint64_t) * 8) - (y))))
#endif
static const uint64_t keccakf_rndc[24] = {
SHAKE_CONST(0x0000000000000001UL), SHAKE_CONST(0x0000000000008082UL),
SHAKE_CONST(0x800000000000808aUL), SHAKE_CONST(0x8000000080008000UL),
SHAKE_CONST(0x000000000000808bUL), SHAKE_CONST(0x0000000080000001UL),
SHAKE_CONST(0x8000000080008081UL), SHAKE_CONST(0x8000000000008009UL),
SHAKE_CONST(0x000000000000008aUL), SHAKE_CONST(0x0000000000000088UL),
SHAKE_CONST(0x0000000080008009UL), SHAKE_CONST(0x000000008000000aUL),
SHAKE_CONST(0x000000008000808bUL), SHAKE_CONST(0x800000000000008bUL),
SHAKE_CONST(0x8000000000008089UL), SHAKE_CONST(0x8000000000008003UL),
SHAKE_CONST(0x8000000000008002UL), SHAKE_CONST(0x8000000000000080UL),
SHAKE_CONST(0x000000000000800aUL), SHAKE_CONST(0x800000008000000aUL),
SHAKE_CONST(0x8000000080008081UL), SHAKE_CONST(0x8000000000008080UL),
SHAKE_CONST(0x0000000080000001UL), SHAKE_CONST(0x8000000080008008UL)
};
static const unsigned keccakf_rotc[24] = {
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, 27, 41, 56, 8, 25, 43, 62,
18, 39, 61, 20, 44
};
static const unsigned keccakf_piln[24] = {
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, 15, 23, 19, 13, 12, 2, 20,
14, 22, 9, 6, 1
};
static void keccakf(uint64_t s[25]) {
int i, j, round;
uint64_t t, bc[5];
#define KECCAK_ROUNDS 24
for (round = 0; round < KECCAK_ROUNDS; round++) {
/* Theta */
for (i = 0; i < 5; i++)
bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20];
for (i = 0; i < 5; i++) {
t = bc[(i + 4) % 5] ^ SHAKE_ROTL64(bc[(i + 1) % 5], 1);
for (j = 0; j < 25; j += 5)
s[j + i] ^= t;
}
/* Rho Pi */
t = s[1];
for (i = 0; i < 24; i++) {
j = keccakf_piln[i];
bc[0] = s[j];
s[j] = SHAKE_ROTL64(t, keccakf_rotc[i]);
t = bc[0];
}
/* Chi */
for (j = 0; j < 25; j += 5) {
for (i = 0; i < 5; i++)
bc[i] = s[j + i];
for (i = 0; i < 5; i++)
s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
}
/* Iota */
s[0] ^= keccakf_rndc[round];
}
}
void shake_Init128(void *priv) {
shake_context *ctx = (shake_context *)priv;
memset(ctx, 0, sizeof(*ctx));
ctx->capacityWords = 4;
}
void shake_Init256(void *priv) {
shake_context *ctx = (shake_context *)priv;
memset(ctx, 0, sizeof(*ctx));
ctx->capacityWords = 8;
}
void shake_Update(void *priv, void const *bufIn, size_t len) {
shake_context *ctx = (shake_context *)priv;
/* 0...7 -- how much is needed to have a word */
unsigned old_tail = (8 - ctx->byteIndex) & 7;
size_t words;
unsigned tail;
size_t i;
const uint8_t *buf = bufIn;
if (len < old_tail) {
while (len--)
ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8);
return;
}
if (old_tail) { /* will have one word to process */
len -= old_tail;
while (old_tail--)
ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8);
/* now ready to add saved to the sponge */
ctx->u.s[ctx->wordIndex] ^= ctx->saved;
ctx->byteIndex = 0;
ctx->saved = 0;
if (++ctx->wordIndex == (SHAKE_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
keccakf(ctx->u.s);
ctx->wordIndex = 0;
}
}
/* now work in full words directly from input */
words = len / sizeof(uint64_t);
tail = len - words * sizeof(uint64_t);
for (i = 0; i < words; i++, buf += sizeof(uint64_t)) {
const uint64_t t = (uint64_t)(buf[0]) |
((uint64_t)(buf[1]) << 8 * 1) |
((uint64_t)(buf[2]) << 8 * 2) |
((uint64_t)(buf[3]) << 8 * 3) |
((uint64_t)(buf[4]) << 8 * 4) |
((uint64_t)(buf[5]) << 8 * 5) |
((uint64_t)(buf[6]) << 8 * 6) |
((uint64_t)(buf[7]) << 8 * 7);
ctx->u.s[ctx->wordIndex] ^= t;
if (++ctx->wordIndex == (SHAKE_KECCAK_SPONGE_WORDS - ctx->capacityWords)) {
keccakf(ctx->u.s);
ctx->wordIndex = 0;
}
}
/* finally, save the partial word */
while (tail--) {
ctx->saved |= (uint64_t)(*(buf++)) << ((ctx->byteIndex++) * 8);
}
}
void shake_Finalize(void *priv) {
shake_context *ctx = (shake_context *)priv;
uint64_t t = (uint64_t)(((uint64_t)0x1f) << (ctx->byteIndex * 8));
ctx->u.s[ctx->wordIndex] ^= ctx->saved ^ t;
ctx->u.s[SHAKE_KECCAK_SPONGE_WORDS - ctx->capacityWords - 1] ^=
SHAKE_CONST(0x8000000000000000UL);
keccakf(ctx->u.s);
ctx->byteIndex = 0;
}
void shake_Squeeze(void *priv, uint8_t *output, size_t outlen) {
shake_context *ctx = (shake_context *)priv;
size_t rate_bytes = (SHAKE_KECCAK_SPONGE_WORDS - ctx->capacityWords) * 8;
size_t i;
for (i = 0; i < outlen; i++) {
if (ctx->byteIndex >= rate_bytes) {
keccakf(ctx->u.s);
ctx->byteIndex = 0;
}
unsigned word_idx = ctx->byteIndex / 8;
unsigned byte_in_word = ctx->byteIndex % 8;
output[i] = (uint8_t)(ctx->u.s[word_idx] >> (byte_in_word * 8));
ctx->byteIndex++;
}
}

View file

@ -0,0 +1,32 @@
// SPDX-FileCopyrightText: 2015 Andrey Jivsov <crypto@brainhub.org>
// SPDX-License-Identifier: MIT
#ifndef __SHAKE_H__
#define __SHAKE_H__
#include <rz_types.h>
#include <stdint.h>
#define SHAKE_KECCAK_SPONGE_WORDS 25
typedef struct shake_context_ {
uint64_t saved; /* the portion of the input message that we
* didn't consume yet */
union { /* Keccak's state */
uint64_t s[SHAKE_KECCAK_SPONGE_WORDS];
uint8_t sb[SHAKE_KECCAK_SPONGE_WORDS * 8];
} u;
unsigned byteIndex; /* 0..7--the next byte after the set one
* (starts from 0; 0--none are buffered) */
unsigned wordIndex; /* 0..24--the next word to integrate input
* (starts from 0) */
unsigned capacityWords; /* capacity in words (e.g. 4 for SHAKE-128, 8 for SHAKE-256) */
} shake_context;
RZ_IPI void shake_Init128(void *priv);
RZ_IPI void shake_Init256(void *priv);
RZ_IPI void shake_Update(void *priv, void const *bufIn, size_t len);
RZ_IPI void shake_Finalize(void *priv);
RZ_IPI void shake_Squeeze(void *priv, uint8_t *output, size_t outlen);
#endif

View file

@ -13,6 +13,8 @@ hash_plugins_list = [
'keccak_256', 'keccak_256',
'keccak_384', 'keccak_384',
'keccak_512', 'keccak_512',
'shake_128',
'shake_256',
'murmur3_x86_32', 'murmur3_x86_32',
'murmur3_x86_128', 'murmur3_x86_128',
'murmur3_x64_128', 'murmur3_x64_128',
@ -134,6 +136,8 @@ rz_hash_sources = [
'p/algo_keccak_256.c', 'p/algo_keccak_256.c',
'p/algo_keccak_384.c', 'p/algo_keccak_384.c',
'p/algo_keccak_512.c', 'p/algo_keccak_512.c',
'p/algo_shake_128.c',
'p/algo_shake_256.c',
'p/algo_murmur3_x64_128.c', 'p/algo_murmur3_x64_128.c',
'p/algo_murmur3_x86_32.c', 'p/algo_murmur3_x86_32.c',
'p/algo_murmur3_x86_128.c', 'p/algo_murmur3_x86_128.c',
@ -166,6 +170,7 @@ rz_hash_sources = [
'algorithms/ssdeep/ssdeep.c', 'algorithms/ssdeep/ssdeep.c',
'algorithms/md2/md2.c', 'algorithms/md2/md2.c',
'algorithms/sha3/sha3.c', 'algorithms/sha3/sha3.c',
'algorithms/shake/shake.c',
'algorithms/murmur3/murmur3.c', 'algorithms/murmur3/murmur3.c',
] ]

View file

@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2026 Ashish Kumar <15678ashishk@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_hash.h>
#include <rz_util/rz_assert.h>
#include "../algorithms/shake/shake.h"
#define shake_128_BLOCK_LENGTH 168
#define shake_128_DIGEST_LENGTH 32
static void *plugin_shake_128_context_new() {
return RZ_NEW0(shake_context);
}
static void plugin_shake_128_context_free(void *context) {
free(context);
}
static RzHashSize plugin_shake_128_digest_size(void *context) {
return shake_128_DIGEST_LENGTH;
}
static RzHashSize plugin_shake_128_block_size(void *context) {
return shake_128_BLOCK_LENGTH;
}
static bool plugin_shake_128_init(void *context) {
rz_return_val_if_fail(context, false);
shake_Init128((shake_context *)context);
return true;
}
static bool plugin_shake_128_update(void *context, const ut8 *data, ut64 size) {
rz_return_val_if_fail(context, false);
shake_Update((shake_context *)context, data, (size_t)size);
return true;
}
static bool plugin_shake_128_final(void *context, ut8 *digest) {
rz_return_val_if_fail(context && digest, false);
shake_Finalize((shake_context *)context);
shake_Squeeze((shake_context *)context, digest, shake_128_DIGEST_LENGTH);
return true;
}
static bool plugin_shake_128_small_block(const ut8 *data, ut64 size, ut8 **digest, RzHashSize *digest_size) {
rz_return_val_if_fail(data && digest, false);
ut8 *dgst = malloc(shake_128_DIGEST_LENGTH);
if (!dgst) {
return false;
}
shake_context ctx;
shake_Init128(&ctx);
shake_Update(&ctx, data, size);
shake_Finalize(&ctx);
shake_Squeeze(&ctx, dgst, shake_128_DIGEST_LENGTH);
*digest = dgst;
if (digest_size) {
*digest_size = shake_128_DIGEST_LENGTH;
}
return true;
}
RzHashPlugin rz_hash_plugin_shake_128 = {
.name = "shake-128",
.author = "Andrey Jivsov",
.license = "BSD-3",
.description = "SHAKE-128 extendable-output function",
.support_hmac = false,
.context_new = plugin_shake_128_context_new,
.context_free = plugin_shake_128_context_free,
.digest_size = plugin_shake_128_digest_size,
.block_size = plugin_shake_128_block_size,
.init = plugin_shake_128_init,
.update = plugin_shake_128_update,
.final = plugin_shake_128_final,
.small_block = plugin_shake_128_small_block,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_HASH,
.data = &rz_hash_plugin_shake_128,
.version = RZ_VERSION
};
#endif

View file

@ -0,0 +1,89 @@
// SPDX-FileCopyrightText: 2026 Ashish Kumar <15678ashishk@gmail.com>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_hash.h>
#include <rz_util/rz_assert.h>
#include "../algorithms/shake/shake.h"
#define shake_256_BLOCK_LENGTH 136
#define shake_256_DIGEST_LENGTH 64
static void *plugin_shake_256_context_new() {
return RZ_NEW0(shake_context);
}
static void plugin_shake_256_context_free(void *context) {
free(context);
}
static RzHashSize plugin_shake_256_digest_size(void *context) {
return shake_256_DIGEST_LENGTH;
}
static RzHashSize plugin_shake_256_block_size(void *context) {
return shake_256_BLOCK_LENGTH;
}
static bool plugin_shake_256_init(void *context) {
rz_return_val_if_fail(context, false);
shake_Init256((shake_context *)context);
return true;
}
static bool plugin_shake_256_update(void *context, const ut8 *data, ut64 size) {
rz_return_val_if_fail(context, false);
shake_Update((shake_context *)context, data, (size_t)size);
return true;
}
static bool plugin_shake_256_final(void *context, ut8 *digest) {
rz_return_val_if_fail(context && digest, false);
shake_Finalize((shake_context *)context);
shake_Squeeze((shake_context *)context, digest, shake_256_DIGEST_LENGTH);
return true;
}
static bool plugin_shake_256_small_block(const ut8 *data, ut64 size, ut8 **digest, RzHashSize *digest_size) {
rz_return_val_if_fail(data && digest, false);
ut8 *dgst = malloc(shake_256_DIGEST_LENGTH);
if (!dgst) {
return false;
}
shake_context ctx;
shake_Init256(&ctx);
shake_Update(&ctx, data, size);
shake_Finalize(&ctx);
shake_Squeeze(&ctx, dgst, shake_256_DIGEST_LENGTH);
*digest = dgst;
if (digest_size) {
*digest_size = shake_256_DIGEST_LENGTH;
}
return true;
}
RzHashPlugin rz_hash_plugin_shake_256 = {
.name = "shake-256",
.author = "Andrey Jivsov",
.license = "BSD-3",
.description = "SHAKE-256 extendable-output function",
.support_hmac = false,
.context_new = plugin_shake_256_context_new,
.context_free = plugin_shake_256_context_free,
.digest_size = plugin_shake_256_digest_size,
.block_size = plugin_shake_256_block_size,
.init = plugin_shake_256_init,
.update = plugin_shake_256_update,
.final = plugin_shake_256_final,
.small_block = plugin_shake_256_small_block,
};
#ifndef RZ_PLUGIN_INCORE
RZ_API RzLibStruct rizin_plugin = {
.type = RZ_LIB_TYPE_HASH,
.data = &rz_hash_plugin_shake_256,
.version = RZ_VERSION
};
#endif

View file

@ -119,6 +119,8 @@ extern RzHashPlugin rz_hash_plugin_sha3_512;
extern RzHashPlugin rz_hash_plugin_keccak_256; extern RzHashPlugin rz_hash_plugin_keccak_256;
extern RzHashPlugin rz_hash_plugin_keccak_384; extern RzHashPlugin rz_hash_plugin_keccak_384;
extern RzHashPlugin rz_hash_plugin_keccak_512; extern RzHashPlugin rz_hash_plugin_keccak_512;
extern RzHashPlugin rz_hash_plugin_shake_128;
extern RzHashPlugin rz_hash_plugin_shake_256;
extern RzHashPlugin rz_hash_plugin_murmur3_x86_32; extern RzHashPlugin rz_hash_plugin_murmur3_x86_32;
extern RzHashPlugin rz_hash_plugin_murmur3_x86_128; extern RzHashPlugin rz_hash_plugin_murmur3_x86_128;
extern RzHashPlugin rz_hash_plugin_murmur3_x64_128; extern RzHashPlugin rz_hash_plugin_murmur3_x64_128;

File diff suppressed because one or more lines are too long

View file

@ -338,6 +338,8 @@ ____hm sha3-384 BSD-3 Andrey Jivsov SHA3-384 cryptog
____hm sha3-512 BSD-3 Andrey Jivsov SHA3-512 cryptographic hash ____hm sha3-512 BSD-3 Andrey Jivsov SHA3-512 cryptographic hash
____hm sha384 BSD-3 Aaron D. Gifford SHA-384 cryptographic hash ____hm sha384 BSD-3 Aaron D. Gifford SHA-384 cryptographic hash
____hm sha512 BSD-3 Aaron D. Gifford SHA-512 cryptographic hash ____hm sha512 BSD-3 Aaron D. Gifford SHA-512 cryptographic hash
____h_ shake-128 BSD-3 Andrey Jivsov SHAKE-128 extendable-output function
____h_ shake-256 BSD-3 Andrey Jivsov SHAKE-256 extendable-output function
____hm sm3 LGPL2 FSF/deroad ShangMi 3 (SM3) cryptographic hash ____hm sm3 LGPL2 FSF/deroad ShangMi 3 (SM3) cryptographic hash
____h_ ssdeep LGPL3 deroad SSDeep Context Triggered Piecewise Hash (CTPH, fuzzy hash) ____h_ ssdeep LGPL3 deroad SSDeep Context Triggered Piecewise Hash (CTPH, fuzzy hash)
____h_ temperature LGPL3 Seva Binary temperature [0.0-1.0] range ____h_ temperature LGPL3 Seva Binary temperature [0.0-1.0] range
@ -821,6 +823,8 @@ string: 0x00000000-0x00000005 sha3-384: computed hash doesn't match the expected
string: 0x00000000-0x00000005 sha3-512: computed hash doesn't match the expected one string: 0x00000000-0x00000005 sha3-512: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 sha384: computed hash doesn't match the expected one string: 0x00000000-0x00000005 sha384: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 sha512: computed hash doesn't match the expected one string: 0x00000000-0x00000005 sha512: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 shake-128: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 shake-256: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 sm3: computed hash doesn't match the expected one string: 0x00000000-0x00000005 sm3: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 ssdeep: computed hash doesn't match the expected one string: 0x00000000-0x00000005 ssdeep: computed hash doesn't match the expected one
string: 0x00000000-0x00000005 temperature: computed hash doesn't match the expected one string: 0x00000000-0x00000005 temperature: computed hash doesn't match the expected one

View file

@ -58,6 +58,8 @@ static hash_data_t hashes_to_test[] = {
{ INDATA("password"), .algo = "keccak-256", .expected = "b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b" }, { INDATA("password"), .algo = "keccak-256", .expected = "b68fe43f0d1a0d7aef123722670be50268e15365401c442f8806ef83b612976b" },
{ INDATA("password"), .algo = "keccak-384", .expected = "e0779e9bb200a589bc70e499a9f7db1006e181519394990ef41800bebe452c23b4a8372fd89df8d5e0d951af240be7bc" }, { INDATA("password"), .algo = "keccak-384", .expected = "e0779e9bb200a589bc70e499a9f7db1006e181519394990ef41800bebe452c23b4a8372fd89df8d5e0d951af240be7bc" },
{ INDATA("password"), .algo = "keccak-512", .expected = "a6818b8188b36c44d17784c5551f63accc5deaf8786f9d0ad1ae3cd8d887cbab4f777286dbb315fb14854c8774dc0d10b5567e4a705536cc2a1d61ec0a16a7a6" }, { INDATA("password"), .algo = "keccak-512", .expected = "a6818b8188b36c44d17784c5551f63accc5deaf8786f9d0ad1ae3cd8d887cbab4f777286dbb315fb14854c8774dc0d10b5567e4a705536cc2a1d61ec0a16a7a6" },
{ INDATA("password"), .algo = "shake-128", .expected = "0ac28ef634f3a8415ae5ef6e614bf11f1a18df4d1fa05a4dd1e6a0acd93bfc57" },
{ INDATA("password"), .algo = "shake-256", .expected = "a5ee08f8e3abe7d592f6de77f1d3298a1149eba68b97f091c90b7736a1be63ab2d425f94c5346cac64807f20f654c5ad9063a4d12902c5e45533491215754883" },
{ INDATA("password"), .algo = "sm3", .expected = "08594e140bcc046e345325435218f67a85c38c63de6443b197b544d70ee62f26" }, { INDATA("password"), .algo = "sm3", .expected = "08594e140bcc046e345325435218f67a85c38c63de6443b197b544d70ee62f26" },
{ INDATA("password"), .algo = "blake3", .expected = "7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787" }, { INDATA("password"), .algo = "blake3", .expected = "7f2611ba158b6dcea4a69c229c303358c5e04493abeadee106a4bfa464d55787" },
{ INDATA("password"), .algo = "blake2b", .expected = "7c863950ac93c93692995e4732ce1e1466ad74a775352ffbaaf2a4a4ce9b549d0b414a1f3150452be6c7c72c694a7cb46f76452917298d33e67611f0a42addb8" }, { INDATA("password"), .algo = "blake2b", .expected = "7c863950ac93c93692995e4732ce1e1466ad74a775352ffbaaf2a4a4ce9b549d0b414a1f3150452be6c7c72c694a7cb46f76452917298d33e67611f0a42addb8" },
@ -276,11 +278,84 @@ bool test_message_digest_small_block_stringified() {
mu_end; mu_end;
} }
bool test_shake_edge_cases() {
RzHash *rh = rz_hash_new();
mu_assert_notnull(rh, "rz_hash_new");
{
ut8 data[170];
for (size_t i = 0; i < 170; i++) {
data[i] = (ut8)i;
}
RzHashCfg *md = rz_hash_cfg_new_with_algo2(rh, "shake-128");
mu_assert_notnull(md, "shake-128 cfg");
rz_hash_cfg_update(md, data, 3);
rz_hash_cfg_update(md, data + 3, 2);
rz_hash_cfg_update(md, data + 5, 6);
rz_hash_cfg_update(md, data + 11, 152);
rz_hash_cfg_update(md, data + 163, 6);
rz_hash_cfg_update(md, data + 169, 1);
rz_hash_cfg_final(md);
RzHashCfg *md_ref = rz_hash_cfg_new_with_algo2(rh, "shake-128");
mu_assert_notnull(md_ref, "shake-128 ref cfg");
rz_hash_cfg_update(md_ref, data, 170);
rz_hash_cfg_final(md_ref);
RzHashSize size, size_ref;
char *res = rz_hash_cfg_get_result_string(md, "shake-128", &size, false);
char *res_ref = rz_hash_cfg_get_result_string(md_ref, "shake-128", &size_ref, false);
mu_assert_streq(res, res_ref, "shake-128 chunked matches reference");
free(res);
free(res_ref);
rz_hash_cfg_free(md);
rz_hash_cfg_free(md_ref);
}
{
ut8 data[138];
for (size_t i = 0; i < 138; i++) {
data[i] = (ut8)i;
}
RzHashCfg *md = rz_hash_cfg_new_with_algo2(rh, "shake-256");
mu_assert_notnull(md, "shake-256 cfg");
rz_hash_cfg_update(md, data, 3);
rz_hash_cfg_update(md, data + 3, 2);
rz_hash_cfg_update(md, data + 5, 6);
rz_hash_cfg_update(md, data + 11, 120);
rz_hash_cfg_update(md, data + 131, 6);
rz_hash_cfg_update(md, data + 137, 1);
rz_hash_cfg_final(md);
RzHashCfg *md_ref = rz_hash_cfg_new_with_algo2(rh, "shake-256");
mu_assert_notnull(md_ref, "shake-256 ref cfg");
rz_hash_cfg_update(md_ref, data, 138);
rz_hash_cfg_final(md_ref);
RzHashSize size, size_ref;
char *res = rz_hash_cfg_get_result_string(md, "shake-256", &size, false);
char *res_ref = rz_hash_cfg_get_result_string(md_ref, "shake-256", &size_ref, false);
mu_assert_streq(res, res_ref, "shake-256 chunked matches reference");
free(res);
free(res_ref);
rz_hash_cfg_free(md);
rz_hash_cfg_free(md_ref);
}
rz_hash_free(rh);
mu_end;
}
bool all_tests() { bool all_tests() {
mu_run_test(test_message_digest_configure); mu_run_test(test_message_digest_configure);
mu_run_test(test_message_digest_api_stringified); mu_run_test(test_message_digest_api_stringified);
mu_run_test(test_message_digest_hmac_stringified); mu_run_test(test_message_digest_hmac_stringified);
mu_run_test(test_message_digest_small_block_stringified); mu_run_test(test_message_digest_small_block_stringified);
mu_run_test(test_shake_edge_cases);
return tests_passed != tests_run; return tests_passed != tests_run;
} }