Reforged C API <dplx/blake2.h>#

This page documents the public C API declared in <dplx/blake2.h>. The API provides streaming and one-shot interfaces for the BLAKE2s and BLAKE2b hash functions, including variable-length XOF style output variants (blake2xs/blake2xb) and runtime implementation selection.

Note

The descriptions below are concise summaries. For algorithmic details refer to the BLAKE2 specification.

Return Codes#

Unless specified otherwise functions return 0 on success and a non-zero value on error (e.g. invalid parameter).

State Structures#

The internal states are exposed to allow stack allocation and are used with the streaming API. Applications normally treat them as opaque except for zeroing after use if required for key hygiene.

struct dplx_blake2s_state#
struct dplx_blake2b_state#
struct dplx_blake2xs_state#
struct dplx_blake2xb_state#

Parameter Blocks#

Fine-grained customization (tree hashing, personalization, salt, inner hash length) is performed by initializing a parameter block and calling the *_init_param function. Fields not explicitly set MUST be zeroed.

struct dplx_blake2s_param#
struct dplx_blake2b_param#

BLAKE2s#

One-shot Convenience Function#

int dplx_blake2s(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)#
Parameters:

Streaming Initialization#

int dplx_blake2s_init(dplx_blake2s_state *S, size_t outlen)#
Parameters:
int dplx_blake2s_init_key(dplx_blake2s_state *S, size_t outlen, const void *key, size_t keylen)#
Parameters:
int dplx_blake2s_init_param(dplx_blake2s_state *S, const dplx_blake2s_param *P)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • P – Pointer to fully initialized parameter block.

Streaming Update and Finalization#

int dplx_blake2s_update(dplx_blake2s_state *S, const void *in, size_t inlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • in – Message chunk to absorb. Must be non-null if inlen is non-zero.

  • inlen – Length of message chunk in bytes. May be zero (no effect).

int dplx_blake2s_final(dplx_blake2s_state *S, void *out, size_t outlen)#

Multiple calls are not allowed. Subsequent calls will return an error and leave the output buffer unmodified.

Parameters:
  • S – Pointer to caller-allocated state structure.

  • out – Buffer receiving the digest. Must be non-null.

  • outlen – Length of output buffer in bytes. Must greater or equal to the length given at init. If greater, the extra bytes will not be modified.

BLAKE2b#

One-shot Convenience Function#

int dplx_blake2b(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)#
Parameters:

Streaming Initialization#

int dplx_blake2b_init(dplx_blake2b_state *S, size_t outlen)#
Parameters:
int dplx_blake2b_init_key(dplx_blake2b_state *S, size_t outlen, const void *key, size_t keylen)#
Parameters:
int dplx_blake2b_init_param(dplx_blake2b_state *S, const dplx_blake2b_param *P)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • P – Pointer to fully initialized parameter block.

Streaming Update and Finalization#

int dplx_blake2b_update(dplx_blake2b_state *S, const void *in, size_t inlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • in – Message chunk to absorb. Must be non-null if inlen is non-zero.

  • inlen – Length of message chunk in bytes. May be zero (no effect).

int dplx_blake2b_final(dplx_blake2b_state *S, void *out, size_t outlen)#

Multiple calls are not allowed. Subsequent calls will return an error and leave the output buffer unmodified.

Parameters:
  • S – Pointer to caller-allocated state structure.

  • out – Buffer receiving the digest. Must be non-null.

  • outlen – Length of output buffer in bytes. Must greater or equal to the length given at init. If greater, the extra bytes will not be modified.

BLAKE2xs#

One-shot Convenience Function#

int dplx_blake2xs(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)#
Parameters:
  • out – Output buffer of size outlen.

  • outlen – Desired digest length [ 1 .. 0xffff ].

  • in – Full message.

  • inlen – Message length in bytes.

  • key – Optional key (nullptr with len 0 for unkeyed hashing).

  • keylen – Key length in bytes [ 0 .. dplx_blake2b_constant.DPLX_BLAKE2S_KEYBYTES ].

Streaming Initialization#

int dplx_blake2xs_init(dplx_blake2xs_state *S, size_t outlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • outlen – Desired digest length [ 1 .. 0xffff ].

int dplx_blake2xs_init_key(dplx_blake2xs_state *S, size_t outlen, const void *key, size_t keylen)#
Parameters:

Streaming Update and Finalization#

int dplx_blake2xs_update(dplx_blake2xs_state *S, const void *in, size_t inlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • in – Message chunk to absorb. Must be non-null if inlen is non-zero.

  • inlen – Length of message chunk in bytes. May be zero (no effect).

int dplx_blake2xs_final(dplx_blake2xs_state *S, void *out, size_t outlen)#

Multiple calls are not allowed. Subsequent calls will return an error and leave the output buffer unmodified.

Parameters:
  • S – Pointer to caller-allocated state structure.

  • out – Buffer receiving the digest. Must be non-null.

  • outlen – Length of output buffer in bytes. Must greater or equal to the length given at init. If greater, the extra bytes will not be modified.

BLAKE2xb#

One-shot Convenience Function#

int dplx_blake2xb(void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen)#
Parameters:
  • out – Output buffer of size outlen.

  • outlen – Desired digest length [ 1 .. 0xffff ].

  • in – Full message.

  • inlen – Message length in bytes.

  • key – Optional key (nullptr with len 0 for unkeyed hashing).

  • keylen – Key length in bytes [ 0 .. dplx_blake2b_constant.DPLX_BLAKE2B_KEYBYTES ].

Streaming Initialization#

int dplx_blake2xb_init(dplx_blake2xb_state *S, size_t outlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • outlen – Desired digest length [ 1 .. 0xffff ].

int dplx_blake2xb_init_key(dplx_blake2xb_state *S, size_t outlen, const void *key, size_t keylen)#
Parameters:

Streaming Update and Finalization#

int dplx_blake2xb_update(dplx_blake2xb_state *S, const void *in, size_t inlen)#
Parameters:
  • S – Pointer to caller-allocated state structure.

  • in – Message chunk to absorb. Must be non-null if inlen is non-zero.

  • inlen – Length of message chunk in bytes. May be zero (no effect).

int dplx_blake2xb_final(dplx_blake2xb_state *S, void *out, size_t outlen)#

Multiple calls are not allowed. Subsequent calls will return an error and leave the output buffer unmodified.

Parameters:
  • S – Pointer to caller-allocated state structure.

  • out – Buffer receiving the digest. Must be non-null.

  • outlen – Length of output buffer in bytes. Must greater or equal to the length given at init. If greater, the extra bytes will not be modified.

Usage Example#

#include <string.h>
#include <stdint.h>
#include <dplx/blake2.h>

int demo(void)
{
    const char *msg = "abc";
    uint8_t digest[DPLX_BLAKE2S_OUTBYTES];
    if (dplx_blake2s(digest, sizeof(digest), msg, strlen(msg), nullptr, 0) != 0) {
        return -1; /* error */
    }
    return 0;
}

Implementation Selection#

By default the library will lazily select an optimized implementation at runtime. If however cpu feature detection is already handled by the application or lazy selection is not desired, the following functions can be used. Note that the implementation selection is global and affects all subsequent hashing operations. The selection is thread-safe in the sense that concurrent calls will not corrupt internal state. However, concurrent calls to the selection functions can lead to a mix of implementation flavors being used accross the API surface. This includes the lazy selection mechanism. Therefore it should be done once at program startup if needed. Furthermore there is no compile time API (eg macro) to query which implementations are available.

Warning

The fallback implementation is assumed to be always compatible with the CPU. If you compile the library without the generic implementation (eg to reduce code size), the fallback might be an optimized implementation that your CPU does not support. This can cause illegal instruction faults. So ensure that the fallback is compatible with your target environment.

enum dplx_blake2_implementation_id#

Stable implementation flavor IDs for use with the implementation selection functions.

enumerator DPLX_BLAKE2_IMPL_FALLBACK#

Pseudo-ID for the implementation which will be used in the case that runtime detection yields no optimized implementation flavor. This is always available. However, keep in mind that the aliased implementation may itself be optimized (eg using SSE2) if the library was compiled without the generic implementation.

Consider the following statements:

  • dplx_blake2_use_implementation(DPLX_BLAKE2_IMPL_FALLBACK) will always succeed.

  • dplx_blake2_use_implementation(DPLX_BLAKE2_IMPL_FALLBACK) is not equivalent to calling dplx_blake2_choose_implementation().

  • Depending on the build configuration this may or may not be an alias for DPLX_BLAKE2_IMPL_GENERIC.

enumerator DPLX_BLAKE2_IMPL_GENERIC#
enumerator DPLX_BLAKE2_IMPL_NEON#
enumerator DPLX_BLAKE2_IMPL_SSE2#
enumerator DPLX_BLAKE2_IMPL_SSE41#
enumerator DPLX_BLAKE2_IMPL_AVX#
enumerator DPLX_BLAKE2_IMPL_COUNT#

Not an implementation ID. Indicates the number of defined implementation IDs. It is only useful for iteration over the defined IDs, e.g. to query availability.

int dplx_blake2_choose_implementation(void)#

Runs the runtime cpu feature detection and selects the most optimized implementation available.

int dplx_blake2_use_implementation(enum dplx_blake2_implementation_id which)#

Tries to imbue the specified implementation flavor, may fail if the implementation is not available, i.e. compiled in.

bool dplx_blake2_has_implementation(enum dplx_blake2_implementation_id which)#

Checks if the specified implementation flavor is compiled in. Does not indicate CPU support.

Return values:

true – if implementation is compiled in.

Constants#

enum dplx_blake2s_constant#

Size and limit constants for BLAKE2s.

enumerator DPLX_BLAKE2S_OUTBYTES#

Maximum digest size in bytes for BLAKE2s.

enumerator DPLX_BLAKE2S_KEYBYTES#

Maximum key size in bytes for BLAKE2s.

enumerator DPLX_BLAKE2S_SALTBYTES#

Salt field size in bytes for BLAKE2s.

enumerator DPLX_BLAKE2S_PERSONALBYTES#

Personalization field size in bytes for BLAKE2s.

enumerator DPLX_BLAKE2S_BLOCKBYTES#

Block size in bytes for BLAKE2s. Not be relevant for most usages.

enum dplx_blake2b_constant#

Size and limit constants for BLAKE2b.

enumerator DPLX_BLAKE2B_OUTBYTES#

Maximum digest size in bytes for BLAKE2b.

enumerator DPLX_BLAKE2B_KEYBYTES#

Maximum key size in bytes for BLAKE2b.

enumerator DPLX_BLAKE2B_SALTBYTES#

Salt field size in bytes for BLAKE2b.

enumerator DPLX_BLAKE2B_PERSONALBYTES#

Personalization field size in bytes for BLAKE2b.

enumerator DPLX_BLAKE2B_BLOCKBYTES#

Block size in bytes for BLAKE2b. Not be relevant for most usages.

Security Considerations#

Zero sensitive material (keys, states) after use if required by your threat model. The library does not automatically cleanse externally owned memory.