std/crypto

Message authentication, keys made from passwords and other keys, random values from the system, and authenticated encryption, in the runtime's C, which takes the same time whatever the secrets are: AES computes its S-box rather than looking it up, and uses the processor's AES instructions where x86-64 has them. Checked against the RFCs' vectors and Python's cryptography.

import "std/crypto"

bytes key = new_key()
bytes sealed = seal(key, to_bytes("the plan"))
print(from_utf8_lossy(open(key, sealed)?))
bytes mac = hmac("sha256", key, to_bytes("a message"))
str token = random_token()
Function Result
hmac(algorithm, key, data), hmac_verify(algorithm, key, data, mac) HMAC with a hash of std/hash, and its check in constant time
constant_time_equal(a, b) whether bytes are equal, in time that depends only on their lengths (a built-in)
hkdf(algorithm, secret, salt, info, length) HKDF (RFC 5869)
pbkdf2(algorithm, password, salt, iterations, length) PBKDF2 (RFC 8018)
scrypt(password, salt, n, r, p, length) scrypt (RFC 7914); 32,768, 8, 1, and 32 unless given
argon2id(password, salt, time, memory_kib, lanes, length, secret, data) Argon2id (RFC 9106), as passwords should be hashed; 3 passes over 64 MiB in 4 lanes unless given
secure_random_bytes(n) random bytes from the system: getrandom, arc4random_buf, BCryptGenRandom, or getentropy; a runtime error, never weaker bytes, when there are none (a built-in)
random_token(count) count random bytes (32) in unpadded base64url
random_int(low, high) a random i64 from low to high, each as likely, without modulo bias
random_choice(items), random_id(length) an item at random; an identifier of 21 letters, digits, _, and -
new_key() 32 random bytes
seal(key, plaintext, data), open(key, sealed, data) XChaCha20-Poly1305 with a new random nonce, carried in front of what seal gives; open gives an ERROR of kind "authentication" when the message, its tag, or data changed, or the key is not its key
encrypt(algorithm, key, nonce, plaintext, data), decrypt(...) one of CIPHERS: "xchacha20-poly1305" (a key of 32 bytes, a nonce of 24), "chacha20-poly1305" (32 and 12), or "aes-gcm" (16, 24, or 32, and 12); never use a nonce twice with one key
sign_value(key, value), verify_value(key, signed) a value with its HMAC-SHA256, as a cookie or a link carries it, and the value back; an ERROR of kind "authentication" when either changed
hash_password(password, time, memory_kib, lanes) Argon2id with a new random salt, in the PHC string format ($argon2id$v=19$m=65536,t=3,p=4$...), which says how to check it again
verify_password(password, hashed) whether the password is the one hashed, in constant time; false for a hash it cannot read. It reads Argon2id hashes other programs wrote in the PHC format

The random numbers of random and std/random are for games and samples, not secrets.