LIBKECCAK_FAST_DIGEST(3)

πŸ“¦ version 1.4.3, in arch rolling, opensuse-leap 16.0

πŸ’– LIBKECCAK_FAST_DIGEST(3) πŸ’–

okay bestie, so this is a libkeccak situation, and if you don't know what that is yet, don't even worry β€” it's the library for Keccak/SHA-3 hashing and it's lowkey iconic. this page explains libkeccak_fast_digest from <libkeccak.h> (✿ manual page for the LIBKECCAK_FAST_DIGEST family, live from the LIBKECCAK source tree).


✨ NAME ✨

libkeccak_fast_digest β€” finish hashing your message, no erasure, no drama πŸ’…


🌸 SYNOPSIS 🌸

#include <libkeccak.h>

int libkeccak_fast_digest(struct libkeccak_state *state, const void *msg, size_t msglen,
                          size_t bits, const char *suffix, void *hashsum);

and like, don't forget:

Link with -lkeccak

πŸ¦‹ DESCRIPTION πŸ¦‹

so the libkeccak_fast_digest() function is the finisher β€” it absorbs the last part of a message (or literally all of it, no cap) and hands you back the hash of the entire message. the last chunk is passed in via the msg parameter, and its byte-size lives in msglen.

if you've already fed the whole message through earlier calls to libkeccak_update(3), libkeccak_fast_update(3), or libkeccak_zerocopy_update(3) (and you used the same pointer for state, okay?), then you just set msg and msglen to NULL and 0, respectively. bestie, it's that simple.

now β€” if your message isn't a whole number of bytes, the leftover number of bits (modulus 8, so like the remainder fam) goes in the bits parameter. and heads up: msglen must only count the whole bytes, aka the floor of the number of bits divided by 8. floor math, periodt.

suffix? it's a NUL-terminated string of ASCII '1's and '0's representing the bits you wanna append to the message. if that string is empty, you can just pass NULL instead β€” iconic. this is what picks your hash algorithm:

  • pure Keccak β†’ use NULL or ""
  • SHA-3 β†’ LIBKECCAK_SHA3_SUFFIX
  • RawSHAKE β†’ LIBKECCAK_RAWSHAKE_SUFFIX
  • SHAKE β†’ LIBKECCAK_SHAKE_SUFFIX
  • cSHAKE β†’ whatever the libkeccak_cshake_suffix(3) function returns

the final hash gets stored into hashsum, unless hashsum is NULL (which honestly makes the whole call faster, go off). a total of ((state->n + 7) / 8) bytes gets written to the beginning of hashsum, so like β€” hashsum needs at least that much allocated space. don't skimp on the memory bestie, it's giving segfault energy otherwise 😭

also important: libkeccak_fast_digest() may reallocate the state's message chunk buffer. and when it does, it's speedrunning it β€” it tries to go as fast as humanly possible rather than making sure the old allocation's info gets securely wiped before the new one's allocated. so like, if you need secure erasure, this is not the vibe 🌈


πŸ”₯ RETURN VALUES πŸ”₯

  • 0 β€” slayed, successful completion ✨
  • -1 β€” it flopped, and errno is set to describe the error πŸ’€

πŸ’œ ERRORS πŸ’œ

libkeccak_fast_digest() may fail for any reason realloc(3) specifies. that's it, that's the list.


πŸ‘‘ EXAMPLE πŸ‘‘

okay so this example calculates the Keccak[b = 1024, c = 576, n = 256] hash of whatever you pipe into stdin, and prints the hash in hexadecimal form to stdout. cute, right?

struct libkeccak_state state;
struct libkeccak_spec spec;
char binhash[256 / 8];
char hexhash[256 / 8 * 2 + 1];
char chunk[4 << 10];
ssize_t len;

spec.bitrate = 1024;
spec.capacity = 576;
spec.output = 256;
if (libkeccak_state_initialise(&state, &spec) < 0)
     goto fail;

for (;;) {
     len = read(STDIN_FILENO, chunk, sizeof(chunk));

     if ((len < 0) && (errno == EINTR))
          continue;
     if (len < 0)
          goto fail;
     if (len == 0)
          break;

     if (libkeccak_fast_update(&state, chunk, (size_t)len) < 0)
          goto fail;
}
if (libkeccak_fast_digest(&state, NULL, 0, 0, "", binhash) < 0)
     goto fail;

libkeccak_behex_lower(hexhash, binhash, sizeof(binhash));
printf("%s\n", hexhash);
libkeccak_state_fast_destroy(&state);

🫢 NOTES 🫢

for cSHAKE, you must call libkeccak_cshake_initialise(3) once, immediately after state initialisation β€” before the first call to any of libkeccak_fast_update(), libkeccak_zerocopy_update(), libkeccak_update(), or libkeccak_digest_digest(). order matters, don't skip it, iykyk πŸ’…


πŸŽ€ SEE ALSO πŸŽ€


quick vibe check 🧚: this whole page is LIBKECCAK library functions manual material, LIBKECCAK_FAST_DIGEST(3) version, and it ate. no notes. πŸ’–βœ¨πŸŒ·

that's the whole manual bestie β€” go hash something gorgeous πŸ¦‹πŸ’œπŸ“

πŸ“¦ where this page comes from