Module crypto/hmac

crypto/hmac
Stability: unstable — the values are right and tested against the RFC 2202 and RFC 4231 vectors, including the key-longer-than-the-block case (`tests/crypto/digest.test.yo`), and the naming follows the `hmac_<hash>` / `hmac_<hash>_hex` pattern the rest of `std/crypto` uses. What is not settled is everything around the one-shot: HMAC here is one call over a whole message, so there is no way to authenticate a stream too large to hold (the `Digest` trait it is written over has no `reset`, which is the same open row). Key material is an ordinary `ArrayList(u8)` and is never zeroized — the `K'`, `ikey` and `okey` buffers are left to the allocator — so this is not the module to build a long-lived key store on. `constant_time_eq` also lives here for want of a `subtle`-style home; it is a byte comparison with no timing dependence on the CONTENTS, and it is what verification must use instead of `==` on a hex `String`. — stable modules only change additively; this one may still change.

HMAC (RFC 2104) — generic over any Digest implementor (plans/archive/STD_API_AUDIT.md §7 P0 item 7: "blocks JWT/SigV4/webhooks").

{ hmac_sha256_hex } :: import("std/crypto/hmac");
sig := hmac_sha256_hex(key_bytes, message_bytes);

Stability

unstable — the values are right and tested against the RFC 2202 and RFC 4231 vectors, including the key-longer-than-the-block case (tests/crypto/digest.test.yo), and the naming follows the hmac_<hash> / hmac_<hash>_hex pattern the rest of std/crypto uses. What is not settled is everything around the one-shot: HMAC here is one call over a whole message, so there is no way to authenticate a stream too large to hold (the Digest trait it is written over has no reset, which is the same open row). Key material is an ordinary ArrayList(u8) and is never zeroized — the K', ikey and okey buffers are left to the allocator — so this is not the module to build a long-lived key store on. constant_time_eq also lives here for want of a subtle-style home; it is a byte comparison with no timing dependence on the CONTENTS, and it is what verification must use instead of == on a hex String.

Functions

hmac function
fn(comptime(D) : Type, key : ArrayList(u8), message : ArrayList(u8), where(D <: Digest)) -> ArrayList(u8)

HMAC over any Digest: H((K' ^ opad) || H((K' ^ ipad) || message)), with K' the key hashed down (if longer than the block) then zero-padded to the block size.

Parameters

NameTypeNotes
DTypecomptime
keyArrayList(u8)
messageArrayList(u8)

Returns: ArrayList(u8)

hmac_sha256 function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> ArrayList(u8)

HMAC-SHA256.

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: ArrayList(u8)

hmac_sha256_hex function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> String

HMAC-SHA256, lowercase hex.

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: String

hmac_sha512 function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> ArrayList(u8)

HMAC-SHA512.

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: ArrayList(u8)

hmac_sha512_hex function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> String

HMAC-SHA512, lowercase hex.

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: String

hmac_sha1 function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> ArrayList(u8)

HMAC-SHA1 (for protocols that still require it — see std/crypto/sha1's security note).

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: ArrayList(u8)

hmac_sha1_hex function
fn(key : ArrayList(u8), message : ArrayList(u8)) -> String

HMAC-SHA1, lowercase hex.

Parameters

NameTypeNotes
keyArrayList(u8)
messageArrayList(u8)

Returns: String

constant_time_eq function
fn(a : ArrayList(u8), b : ArrayList(u8)) -> bool

Constant-time byte comparison — verify MACs with this, never ==: an early-exit compare leaks WHERE the first mismatch sits, which lets an attacker forge a MAC byte-by-byte over the network.

Parameters

NameTypeNotes
aArrayList(u8)
bArrayList(u8)

Returns: bool