cheatah
Module

hashlib

Cryptographic hashing and keyed primitives — self-contained SHA-256/SHA-512, HMAC, HKDF, and Base64, with no external crypto dependency. Each hash comes in a hex form and a raw-bytes form (like a digest vs hexdigest). These primitives back the tls and ed25519 modules and are equally usable directly.

import hashlib

hashlib.sha256("abc")
# "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"

Functions

  • sha256(data) — SHA-256 of data as a 64-character lowercase hex digest.

  • sha512(data) — SHA-512 of data as a 128-character lowercase hex digest.

  • sha256_digest(data) — the raw 32-byte SHA-256 (not hex).

  • sha512_digest(data) — the raw 64-byte SHA-512 (not hex); backs the ed25519 module, which uses SHA-512 internally per RFC 8032.

  • hmac_sha256(key, data) / hmac_sha512(key, data) — RFC 2104 keyed MAC, raw bytes.

  • hkdf_extract(salt, ikm) / hkdf_expand(prk, info, length) — RFC 5869 key derivation (the TLS 1.3 key schedule is built on these).

  • base64_encode(data) / base64_decode(text) — standard Base64 (RFC 4648).

The input length is carried, so an embedded NUL byte is hashed as part of the data. The implementation follows FIPS-180 and is checked against the standard NIST SHA-256 and SHA-512 test vectors (including the multi-block length-padding edge case).

Per-function docs (parameters, runtime complexity, heap behavior) are in hashlib.hpp. Tested in ../tests/hashlib_test.cpp; ASan + Valgrind clean via the QA gate (security/run-valgrind.sh).

Functions

fn std::string sha256(std::string_view data) source#

SHA-256 digest of data, as hex.

Computes the full SHA-256 of the byte view (standard padding plus 64-bit big-endian length) and formats the 32-byte hash as hex. Hashing the empty string is well-defined and returns the canonical e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.

Parameters
data

the bytes to hash (an embedded NUL is part of the input, since the length is carried).

Returns

a 64-char lowercase hex digest.

Complexity

O(n) in the input length.

Allocation

allocates the 64-char result string and a padded message buffer internally.

Compile-run testHashlibCompileRun.Sha256
Performance387 ns/call in cheatah · 454 ns/call in CPython 3.12.3 · ≈1.2× faster
fn std::string sha384(std::string_view data) source#

SHA-384 digest of data, as hex.

SHA-384 is SHA-512 (128-byte blocks, 80 rounds, 128-bit length field) with its own initial hash values, truncated to the leftmost 48 bytes — the hash of the ecdsa-with- SHA384 / sha384WithRSAEncryption certificate signatures the TLS client verifies. The empty string hashes to the canonical 38b060a751ac9638…4898b95b (96 hex chars).

Parameters
data

the bytes to hash (an embedded NUL is part of the input).

Returns

a 96-char lowercase hex digest.

Complexity

O(n) in the input length.

Allocation

allocates the 96-char result string and a padded message buffer internally.

Compile-run testHashlibCompileRun.Sha384
fn std::string sha512(std::string_view data) source#

SHA-512 digest of data, as hex.

The full SHA-512 (128-byte blocks, 80 rounds, 128-bit length field) of the byte view, formatted as hex. The empty string hashes to the canonical cf83e1357eefb8bd…3e85 (128 hex chars).

Parameters
data

the bytes to hash (an embedded NUL is part of the input).

Returns

a 128-char lowercase hex digest.

Complexity

O(n) in the input length.

Allocation

allocates the 128-char result string and a padded message buffer internally.

Compile-run testHashlibCompileRun.Sha512
fn std::string sha256_digest(std::string_view data) source#

SHA-256 of data as the raw 32 bytes (Python's .digest()), not hex.

Parameters
data

the bytes to hash.

Returns

a 32-byte string (may contain embedded NULs).

Complexity

O(n) in the input length.

Allocation

allocates the 32-byte result and a padded message buffer.

fn std::string sha384_digest(std::string_view data) source#

SHA-384 of data as the raw 48 bytes (Python's .digest()), not hex.

The digest the x509 chain validator and the TLS CertificateVerify check feed to the SHA-384 signature algorithms (ecdsa-with-SHA384, sha384WithRSAEncryption, ecdsa_secp384r1_sha384).

Parameters
data

the bytes to hash.

Returns

a 48-byte string (may contain embedded NULs).

Complexity

O(n) in the input length.

Allocation

allocates the 48-byte result and a padded message buffer.

fn std::string sha512_digest(std::string_view data) source#

SHA-512 of data as the raw 64 bytes (Python's .digest()), not hex.

Backs the ed25519 module, which uses SHA-512 internally per RFC 8032.

Parameters
data

the bytes to hash.

Returns

a 64-byte string (may contain embedded NULs).

Complexity

O(n) in the input length.

Allocation

allocates the 64-byte result and a padded message buffer.

fn std::string hmac_sha256(std::string_view key, std::string_view data) source#

HMAC-SHA-256 (RFC 2104) over raw bytes — the PRF under HKDF and the TLS 1.3 key schedule.

Parameters
key

raw key bytes (any length; hashed down when longer than the block).

data

raw message bytes.

Returns

the 32-byte MAC as raw bytes.

Complexity

O(|key| + |data|).

Allocation

the returned 32-byte digest plus fixed key/inner/outer scratch buffers and message-sized concatenation/padding temporaries.

fn std::string hmac_sha384(std::string_view key, std::string_view data) source#

HMAC-SHA-384 (RFC 2104) over raw bytes — the PRF under the SHA-384 HKDF / TLS 1.3 key schedule (the TLS_AES_256_GCM_SHA384 cipher suite).

SHA-384 shares SHA-512's 128-byte block; the MAC is 48 bytes.

Parameters
key

raw key bytes (any length; hashed down when longer than the 128-byte block).

data

raw message bytes.

Returns

the 48-byte MAC as raw bytes.

Complexity

O(|key| + |data|).

Allocation

the returned 48-byte digest plus fixed key/inner/outer scratch buffers and message-sized concatenation/padding temporaries.

fn std::string hmac_sha512(std::string_view key, std::string_view data) source#

HMAC-SHA-512 (RFC 2104) over raw bytes — the wider PRF (128-byte block, 64-byte MAC), e.g.

for authentication schemes that mandate SHA-512.

Parameters
key

raw key bytes (any length; hashed down when longer than the 128-byte block).

data

raw message bytes.

Returns

the 64-byte MAC as raw bytes.

Complexity

O(|key| + |data|).

Allocation

the returned 64-byte digest plus fixed key/inner/outer scratch buffers and message-sized concatenation/padding temporaries.

fn to_hex · 2 overloads
std::string to_hex(const std::uint8_t *data, std::size_t n)source#
std::string to_hex(std::string_view bytes)source#

Lowercase-hex ENCODE overload for a raw byte buffer (the form the digest and Ed25519 paths use).

Parameters
data

pointer to the bytes.

n

the number of bytes.

Returns

the lowercase hex text (length 2*n).

Complexity

O(n).

Allocation

the returned string.

fn std::string from_hex(std::string_view hex) source#

Hex DECODE — the inverse of to_hex.

Accepts an even-length hex string in either digit case.

Parameters
hex

the hex text (both a-f and A-F accepted; no 0x prefix).

Returns

the decoded raw bytes (may contain embedded NULs).

Parameters
std::invalid_argument

on an odd length or a non-hex character.

Complexity

O(|hex|).

Allocation

the returned bytes.

fn std::string base64_encode(std::string_view data) source#

Base64 ENCODE (RFC 4648, standard alphabet A–Za–z0–9+/, = padding) of raw bytes to ASCII.

Parameters
data

the raw bytes to encode (embedded NULs are encoded).

Returns

the base64 text (length 4*ceil(n/3)).

Complexity

O(n).

Allocation

the returned string.

fn std::string base64_decode(std::string_view text, bool strict=false) source#

Base64 DECODE (RFC 4648 standard alphabet) of ASCII to the raw bytes.

Whitespace/newlines are skipped; decoding stops at the first = pad; non-alphabet bytes are ignored (lenient, like Python's base64.b64decode on a clean stream).

Parameters
text

the base64 text.

strict

when true, a non-alphabet, non-whitespace byte makes the decode FAIL CLOSED (returns "") instead of being ignored — used by X.509 PEM parsing so a malformed body is rejected rather than decoded to garbage. Defaults to false (lenient, Python-like).

Returns

the decoded raw bytes (may contain embedded NULs); "" in strict mode on a bad byte.

Complexity

O(|text|).

Allocation

the returned string.

fn std::string hkdf_extract(std::string_view salt, std::string_view ikm) source#

HKDF-Extract (RFC 5869): PRK = HMAC-SHA-256(salt, ikm).

Parameters
salt

the (optional) salt; pass "" for the all-zero default salt.

ikm

the input keying material.

Returns

the 32-byte pseudorandom key (PRK) as raw bytes.

Complexity

O(|salt| + |ikm|).

Allocation

the returned 32-byte PRK plus HMAC scratch buffers (including ikm-sized concatenation/padding temporaries).

fn std::string hkdf_expand(std::string_view prk, std::string_view info, long long length) source#

HKDF-Expand (RFC 5869): derive length bytes of keying material from prk and info.

Parameters
prk

a pseudorandom key (e.g. from hkdf_extract()).

info

optional context/application-specific info binding the output ("" for none).

length

the number of output-keying-material bytes to produce.

Returns

the OKM as raw bytes, or "" when length is 0 (or negative) or exceeds 255*32 (the RFC bound).

Complexity

O(⌈length/32⌉ · (|prk| + |info| + 32)) — one HMAC per 32-byte output block.

Allocation

the returned keystream plus HMAC scratch buffers per 32-byte output block.

fn std::string hkdf_extract_sha384(std::string_view salt, std::string_view ikm) source#

HKDF-Extract over HMAC-SHA-384 — the SHA-384 variant for the TLS_AES_256_GCM_SHA384 key schedule.

Parameters
salt

the (optional) salt; "" is treated as HashLen zero bytes by the caller as needed.

ikm

the input keying material.

Returns

the 48-byte pseudorandom key (PRK) as raw bytes.

Complexity

O(|salt| + |ikm|).

Allocation

the returned 48-byte PRK plus HMAC scratch buffers (including ikm-sized concatenation/padding temporaries).

fn std::string hkdf_expand_sha384(std::string_view prk, std::string_view info, long long length) source#

HKDF-Expand over HMAC-SHA-384 — the SHA-384 variant for the TLS_AES_256_GCM_SHA384 key schedule.

Parameters
prk

a pseudorandom key (e.g. from hkdf_extract_sha384()).

info

optional context/application-specific info binding the output ("" for none).

length

the number of output-keying-material bytes to produce.

Returns

the OKM as raw bytes, or "" when length is 0 (or negative) or exceeds 255*48 (the RFC bound).

Complexity

O(⌈length/48⌉ · (|prk| + |info| + 48)) — one HMAC per 48-byte output block.

Allocation

the returned keystream plus HMAC scratch buffers per 48-byte output block.