Luau Bindings — crypto

The require("crypto") script API — public-key signing (Ed25519), message authentication (HMAC-SHA256), and the TLS CA trust store. Split out of the P4 data library so data stays pure encoding/hashing/JSON. Every function is [antos]. Design & native core: antos_crypto. (Plain hashing — sha256, crc32 — stays in data.)

local crypto = require("crypto")
local sk, pk = crypto.keygen(seed32)
local sig    = crypto.sign(sk, "hello")
assert(crypto.verify(sig, pk, "hello"))

Signing & keys — Ed25519

Function Behaviour
crypto.keygen(seed) Derive a keypair from a 32-byte seed → secret_key (64 B), public_key (32 B). Deterministic — the same seed always yields the same keys.
crypto.sign(secret_key, msg) Sign msg → a 64-byte signature.
crypto.verify(sig, public_key, msg) Verify → true/false.

These are the same keys that identify a node on the gossip mesh (a node's identity is its Ed25519 public key), and that sign device artefacts. Seeds are raw bytes — generate one with data hashing or a random source, and keep the secret key secret.


Message authentication — HMAC

Function Behaviour
crypto.hmac(key, msg) HMAC-SHA256 over msg with a 32-byte key → a 32-byte MAC.

TLS CA trust store — crypto.ca.*

The certificate authorities the system trusts for HTTPS (net). Ships with a built-in firmware bundle; a user can add their own (a private CA, a corporate root).

Function Behaviour
crypto.ca.install(pem) Install user CA certificate(s) from PEM → count, or nil, err.
crypto.ca.is_user() true if the active bundle is user-installed, false if it's the built-in firmware bundle.
crypto.ca.list() Installed certificates (array of info tables).
crypto.ca.get(i) One certificate's info: { subject, issuer, not_before, not_after, expired, not_yet_valid }.
crypto.ca.count() Number of installed certificates.
crypto.ca.remove(i) Remove one.
crypto.ca.reset() Revert to the built-in firmware bundle.
crypto.ca.reload() Reload the store (after external changes).
crypto.ca.info() Store summary.
-- trust a private CA, then HTTPS to an internal host works
crypto.ca.install(io.open("D:/certs/corp-root.pem","r"):read("a"))
local r = require("net").get("https://internal.corp/status")

Certificate validity checks depend on the system clock — not_before/not_after only mean something once the clock is set (RTC or NTP). See net / os.rtc.


Related

Important: The Ant64 family of home computers are at early design/prototype stage, everything you see here is subject to change.