poplog docs / help
HELP CRYPTO                    Digests, HMAC and secure random bytes

LIB * CRYPTO gives Pop-11 access to cryptographic primitives from
OpenSSL's libcrypto, through a small vendored C shim (never
hand-rolled implementations).  One-time setup, then load:

    $ tools/build-popcrypto.sh          (needs libssl-dev / OpenSSL)

    uses crypto;
    sha256('hello') =>
    ** 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

CONTENTS

 -- Procedures
 -- Examples
 -- Notes
 -- See also

-- Procedures ---------------------------------------------------------

sha256(DATA) -> HEXSTRING
    SHA-256 of the string DATA as lowercase hex — the everyday call.

crypto_digest(ALG, DATA) -> RAWSTRING
crypto_digest_hex(ALG, DATA) -> HEXSTRING
    Digest of DATA using the named algorithm — any digest libcrypto
    knows: 'sha256', 'sha512', 'sha1', 'md5', 'sha3-256', ...
    The raw form returns the digest bytes (e.g. 32 for sha256);
    the hex form the usual lowercase hex rendering.  An unknown
    algorithm name causes a mishap.

crypto_hmac(ALG, KEY, DATA) -> RAWSTRING
crypto_hmac_hex(ALG, KEY, DATA) -> HEXSTRING
    HMAC of DATA with KEY using the named digest (RFC 2104), for API
    signing and message authentication.

crypto_random(N) -> STRING
    N cryptographically secure random bytes (libcrypto's RAND_bytes).
    Mishaps if the system RNG is unavailable.

crypto_encrypt(KEY, DATA) -> BLOB
    Authenticated encryption (AES-256-GCM).  KEY must be exactly 32
    bytes — from crypto_random(32), or crypto_pbkdf2 for passwords.
    Returns a self-contained blob (12-byte random nonce, ciphertext,
    16-byte authentication tag); its length is length(DATA) + 28.

crypto_decrypt(KEY, BLOB) -> DATA or false
    The inverse.  Returns *false* — not a mishap — if the blob was
    tampered with, truncated, or the key is wrong: callers must check
    the result before trusting it.

crypto_pbkdf2(ALG, PASSWORD, SALT, ITERATIONS, DKLEN) -> KEY
    Derives a DKLEN-byte key from a password (PBKDF2-HMAC, RFC 2898),
    e.g. crypto_pbkdf2('sha256', pw, salt, 600000, 32) for a
    crypto_encrypt key.  Use a random per-user SALT and iterations in
    the hundreds of thousands for real passwords.

crypto_version() -> STRING
    The underlying library's version, e.g. 'OpenSSL 3.0.2 15 Mar 2022'.

-- Examples -----------------------------------------------------------

    uses crypto;

    ;;; content checksum
    crypto_digest_hex('sha256', 'abc') =>
    ** ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad

    ;;; API request signing
    crypto_hmac_hex('sha256', secret_key, request_body) -> signature;

    ;;; a 128-bit session token, hex-encoded
    uses json;   ;;; unrelated, just showing they compose
    crypto_hmac_hex('sha256', crypto_random(16), json_generate(payload))

-- Notes --------------------------------------------------------------

  * All DATA/KEY arguments are byte strings and binary-safe: embedded
    null bytes are handled correctly (lengths are passed explicitly).

  * The shim (pop/extern/popcrypto/popcrypto_shim.c) exposes only
    non-variadic, explicit-length entry points — the same design as
    the popcurl shim, avoiding the variadic-FFI hazards documented in
    PORTING-ARM64-M-SILICON-OSX.md.  Algorithms and implementations
    all come from the system libcrypto; this library adds no
    cryptography of its own, so security fixes arrive with OS updates.

  * md5 and sha1 are provided for interoperability (checksums, legacy
    protocols); do not use them where collision resistance matters.

  * crypto_encrypt generates a fresh random nonce per call, so
    encrypting the same data twice yields different blobs — this is
    correct and required.  Never reuse a key+nonce pair; letting the
    library pick the nonce guarantees that.

  * Higher-level protocols (certificates, TLS, signatures) are not
    covered.  Extend the shim (pcr_* entry points) rather than
    composing primitives in Pop-11 where security matters.  A worked
    demo of what is covered: examples/secure_notes.p.

-- See also -----------------------------------------------------------

    LIB   * CRYPTO           pop/lib/lib/crypto.p
    tools/build-popcrypto.sh build the shim (one time)
    tools/test-crypto.sh     acceptance suite (published test vectors)
    HELP  * JSON             frequent companion for API work
    TEACH * JSON             how to build a library like this one

--- pop/help/crypto
Authors: D.Kordsmeier (@truedat101) and Claude (@claude), Aug 2026