Skip to content

Clausal Prolog — Crypto Modules (hash, hmac, pbkdf2)

Overview

Three small modules wrapping Python's hashlib and hmac stdlib for cryptographic hashing, message authentication, and key derivation. All modules use only the standard library — no third-party dependencies.

-import_from(py.hash, [hash])
-import_from(py.hmac, [sign, verify])
-import_from(py.pbkdf2, [derive])

check_integrity(DATA, EXPECTED) <- (
    hash("sha256", DATA, COMPUTED),
    COMPUTED == EXPECTED
)

sign_message(KEY, MSG, SIG) <- sign(KEY, MSG, SIG)

verify_message(KEY, MSG, SIG) <- verify(KEY, MSG, SIG)

py.hash — Cryptographic Hashing

-import_from(py.hash, [hash, hash_bytes])
Predicate Mode Description
hash(Algorithm, Data, Hex) +Algo, +Data, -Hex Hex digest via hashlib, as a string
hash_bytes(Algorithm, Data, Bytes) +Algo, +Data, -Bytes Raw digest bytes

Supported algorithms: "sha256", "sha512", "md5", "sha1", "sha384", "sha3_256", "sha3_512", "blake2b", "blake2s" (anything hashlib.new() accepts).

Data can be a string (UTF-8 encoded) or bytes.

hash("sha256", "abc", HEX)
# HEX = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"

hash("md5", "", HEX)
# HEX = "d41d8cd98f00b204e9800998ecf8427e"

hash_bytes("sha256", "abc", RAW)
# RAW is 32 bytes

Fails silently if the algorithm is unknown, or if Algorithm or Data is unbound.


py.hmac — Message Authentication

-import_from(py.hmac, [sign, verify])
Predicate Mode Description
sign(Key, Data, Hex) +Key, +Data, -Hex HMAC-SHA256 signature
sign(Algorithm, Key, Data, Hex) +Algo, +Key, +Data, -Hex HMAC with specified algorithm
verify(Key, Data, Hex) +Key, +Data, +Hex verify HMAC-SHA256 (constant-time)
verify(Algorithm, Key, Data, Hex) +Algo, +Key, +Data, +Hex verify with specified algorithm

Key and Data can be strings (UTF-8 encoded) or bytes. verify uses hmac.compare_digest for constant-time comparison.

sign("secret-key", "message", SIG)
verify("secret-key", "message", SIG)   # succeeds

sign("sha512", "key", "data", SIG)     # SHA-512 HMAC

py.pbkdf2 — Key Derivation

-import_from(py.pbkdf2, [derive])
Predicate Mode Description
derive(Password, Salt, Iterations, DerivedKey) +Pw, +Salt, +Iter, -DK PBKDF2-HMAC-SHA256, 32-byte key
derive(Password, Salt, Iterations, KeyLength, DerivedKey) +Pw, +Salt, +Iter, +KL, -DK Custom key length

DerivedKey is a hex string. Password and Salt can be strings, atoms or bytes. Iterations must be a positive integer.

derive("password", "salt", 100000, HASH)
# HASH is a 64-character hex string (32 bytes)

derive("password", "salt", 100000, 64, HASH)
# HASH is a 128-character hex string (64 bytes)

Examples

File integrity check (using the Files module)

-import_from(py.hash, [hash])
-import_from(py.files, [read_file_to_string])

file_hash(PATH, HASH) <- (
    read_file_to_string(PATH, CONTENT),
    hash("sha256", CONTENT, HASH)
)

API request signing

-import_from(py.hmac, [sign])

signed_request(KEY, BODY, SIGNATURE) <- (
    sign("sha256", KEY, BODY, SIGNATURE)
)

Password hashing

-import_from(py.pbkdf2, [derive])

hash_password(PASSWORD, SALT, HASH) <- derive(PASSWORD, SALT, 100000, HASH)

See also: Python Interop — ++() escape for additional cryptography operations · UUID — UUID generation with hash-based variants (v3, v5).