calendar
All repositories: gitoria
4.5 KB
\* hl:crypto — passwords first. Native realm wrapper (see server.js for the JS twin).The whole surface is eight calls, and six of them exist to serve the first two.What this plugin is FOR is that an application never stores a password: itstores the answer to "could this password have produced that", and the answercarries its own algorithm and cost so it stays readable when both change.hash(password, options) the stored value — a PHC stringverify(password, stored) true / false, in constant timeparsePhc(stored) what a stored value says about itselfkdf() which algorithm THIS host hashes withsha256(data) content hashing (fast on purpose — not for passwords)randomBytes(n, encoding) n bytes from the kernel CSPRNGtoBase64(data) a String's or a Bytes' bytes as base64 textfromBase64(text) base64 text back to a Bytes (null if it is not base64)The realm is SERVER (plugin.json). A password never crosses to the client, soimporting this file is also a declaration about where the importing code runs. *\\* Hash a password for storage. Returns a self-describing PHC string:$argon2id$v=19$m=32768,t=2,p=1$<salt>$<hash>$scrypt$ln=15,r=8,p=1$<salt>$<hash>Every call salts freshly, so hashing the same password twice gives twodifferent strings and both verify.`options` is optional: { cost = 15; kdf = "argon2id" }cost base-2 log of the working memory in KiB — 15 is 32 MiB, the default.CAPPED to 10..17 (1 MiB .. 128 MiB); the string records what wasactually used, so asking for 999 and reading the result back is howyou see the cap rather than being told about it.kdf force an algorithm instead of taking the host's best one. Normallyunnecessary: `hash` picks argon2id when the system libcrypto has it(OpenSSL >= 3.2) and scrypt otherwise, and `verify` reads both. *\hash(password, options) {return __native("crypto.hash", password, options)}\* Check a password against a stored PHC string. The comparison is constant-timeand the answer is a plain boolean: a wrong password, a truncated string, aflipped character and a string that is not PHC at all are all `false`. Astored string whose ALGORITHM this host cannot compute is a loud errorinstead, because answering `false` to that would read as "wrong password". *\verify(password, stored) {return __native("crypto.verify", password, stored)}\* Read a stored string without the password:{ kdf = "argon2id"; version = 19; params = { m; t; p }; saltLen; hashLen }{ kdf = "scrypt"; version = null; params = { ln; r; p }; saltLen; hashLen }`null` when the string is not a PHC string this plugin understands — which isalso the cheapest way to spot a store that was never migrated. *\parsePhc(stored) {return __native("crypto.parse", stored)}\* Which algorithm `hash()` writes with on this host. Reporting only — nothingneeds to branch on it, because every stored string names its own. *\kdf() {return __native("crypto.kdf")}\* SHA-256 of a string, as 64 lowercase hex characters. Content hashing: fast bydesign, and therefore exactly the wrong tool for a password. *\sha256(data) {return __native("crypto.sha256", data)}\* n random bytes from the kernel CSPRNG, rendered as "hex" (the default) or"base64". n is 1..1024. Suitable for session ids, one-time tokens and nonces. *\randomBytes(n, encoding) {return __native("crypto.random_bytes", n, encoding)}\* Base64 (the standard alphabet, padded) of a String's bytes — its UTF-8 — orof a Bytes, byte for byte:toBase64('user:pa55') \\ "dXNlcjpwYTU1"toBase64(req.bytes) \\ any bytes at all, NUL and 0xff included *\toBase64(data \\ a String or a Bytes) {if (hlTypeName(data) == 'Bytes') {return __native("crypto.base64_encode_hex", data.hex())}return __native("crypto.base64_encode", data)}\* Base64 text back to its bytes, as a Bytes; `.toString()` of it is the textwhen the bytes are UTF-8. Padded and unpadded text both decode; anythingthat is not base64 in the standard alphabet is null, not an error — amalformed `Authorization: Basic` header is an answer, not a crash:let b = fromBase64(req.headers.authorization.slice(6))if (b != null) { let pair = b.toString() } \\ "user:pa55" *\fromBase64(String text) {let raw = __native("crypto.base64_decode", text)if (raw == null) {return null}return toBytes(raw)}
Branches
- mainmain branch
Latest commits
- 14ba08c7antcolony#40: mission references point to the moved missionsmre
- 99c73346antcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
- 76edaa62calendar: Hybriel master ff51cf46 (re-vendor round, static workaround removed)mre
- 90a3fc2cdeploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
- 6722b72ddeploy.sh: never send .git or .gitignore to Byrodinmre
- be099807State of 2026-09-27, before the move to gitoriamre