ludic/examples/library/crypto.ludic
Orkuncakilkaya 2ddf830f0b
All checks were successful
docs / build-and-deploy (push) Successful in 2s
feat(stdlib): finish Crypto (CSPRNG + base64) and add Uuid.* library (#19 #16)
Crypto (#19): add the OS cryptographically-secure random surface
(random_bytes/random_hex/random_u32, reading /dev/urandom) and a standard
base64 encoder, completing the library alongside the existing SHA-256/
HMAC-SHA256/verify_hmac/hex/ct_equal. All pure integer IR, C-free.

Uuid (#16): a new namespace for stable, collision-free IDs — v4 (random) and
v7 (time-ordered) generation, plus parse/is_valid/to_text/equals/nil. UUIDs are
canonical lowercase 36-char strings; v4 and v7's random tail draw from the
crypto CSPRNG, so both carry the documented determinism caveat (mint at the
edges, never inside lockstep simulation). Reuses the crypto prelude's
fn_secure_bytes / fn_hex_encode.

- examples/library/{crypto,uuid}.ludic: known-answer vectors (SHA-256, HMAC,
  base64 per RFC 4231/4648) and structural invariants (uuid version/variant
  bits, parse/equals), wired into `x test` (now 51 passed).
- docs: per-symbol pages for every new method + a new Uuid section; inventory
  and impl-vs-docs coverage check pass.
- seed regenerated; `x bootstrap-cfree` fixpoint holds.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-30 21:40:51 +03:00

30 lines
1.5 KiB
Text

# crypto.ludic — Crypto.* known-answer vectors + the secure-random surface.
# SHA-256 / HMAC-SHA256 / base64 are checked against published test vectors, so a
# regression in the integer IR shows up as a changed line. The secure-random
# helpers are non-deterministic, so we assert their SHAPE (length, distinctness),
# never a fixed value. Running it prints: 1 2 3 4 5 6 7 8 9
program Crypto {
entry {
# SHA-256 (FIPS 180-4 examples)
if Crypto.sha256("abc") == "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" { print(1) }
if Crypto.sha256("") == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" { print(2) }
# HMAC-SHA256 (RFC 4231 test case 2: key "Jefe", data "what do ya want for nothing?")
if Crypto.hmac_sha256("Jefe", "what do ya want for nothing?") == "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843" { print(3) }
# constant-time verify: the right MAC verifies, a tampered one does not
let mac = Crypto.hmac_sha256("k", "payload")
if Crypto.verify_hmac("k", "payload", mac) { print(4) }
if not Crypto.verify_hmac("k", "payload", "00") { print(5) }
# base64 (RFC 4648 vectors), covering every padding remainder
if Crypto.base64("") == "" { print(6) }
if Crypto.base64("f") == "Zg==" { print(7) }
if Crypto.base64("foobar") == "Zm9vYmFy" { print(8) }
# secure random: two 16-byte draws are 32 hex chars each and (near-certainly) differ
let a = Crypto.random_bytes(16)
let b = Crypto.random_bytes(16)
if len(a) == 32 and a != b { print(9) }
}
}