proc main(): void {
echo hive.crypto.sha256("hive")
echo hive.crypto.sha512("hive")
echo hive.crypto.hmacSha256("hive", bypass("secret"))
}proc main(): void {
password := bypass("password")
sealed := hive.crypto.encrypt(bypass("a secret"), password)
echo sealed
if hive.crypto.decrypt(sealed, password) is Result.Ok(plain) {
echo reveal(plain)
}
}proc main(): void {
encoded := hive.crypto.base64Encode("hive")
if hive.crypto.base64Decode(encoded) is Result.Ok(decoded) {
echo decoded
}
echo hive.crypto.randomHex(8)
if hive.crypto.randomSecret(8) is Result.Ok(key) {
echo len(reveal(key)) // 16
}
}type Claims { user: Str }
proc main(): void {
token := encode(Claims("ada"), hive.crypto.jwtCodec(bypass("secret")))
// Checks the signature and the times, then reads the claims.
if Claims.decode(token, hive.crypto.jwtCodec(bypass("secret"))) is Result.Ok(claims) {
echo claims.user
}
echo hive.crypto.jwtHeader(token)
}hive.crypto is pure, so it works in a func as well as a proc.
sha256(input) and sha512(input) hash, and hmacSha256(input, key) authenticates with a Secret key — each answering in lowercase hex.encrypt(plaintext, password) seals a Secret under a Secret password with AES-256-GCM, the key stretched with 600,000 rounds of PBKDF2 and a fresh salt and nonce every call, so the same text never encrypts alike twice. The ciphertext is a Str, safe to print and store, and decrypt(ciphertext, password) opens it into a Secret without the plaintext ever being a Str.base64Encode(input) and base64Decode(input) use standard base64 with padding; randomHex(bytes) draws that many random bytes, as twice as many hex digits, and randomSecret(bytes) does the same straight into a Secret, answering a Result<Secret, SecretError>.JSON Web Tokens are a codec, jwtCodec(secret) with a Secret, in the same two places as JSON's: encode(claims, hive.crypto.jwtCodec(secret)) signs a value of your own type, and Claims.decode(token, hive.crypto.jwtCodec(secret)) checks the signature before reading the claims back. Only HS256 is accepted, which closes the classic algorithm-confusion attack outright. A token expires only if its claims type declares exp: Int — or nbf, not before — in Unix seconds, which are then checked; encode adds neither. A failure is a hive.crypto.JwtError, its path $ for a token that does not check out and a field's path for claims of the wrong shape. jwtDecode(token) reads the claims as JSON without verifying anything, for inspection only, and jwtHeader(token) reads alg, typ and kid — kid being empty on the tokens Hive signs, which carry a fixed header.
What can fail — decrypt, base64Decode, jwtDecode, jwtHeader — answers with a Result whose hive.crypto.CryptoError has a reason, such as "Malformed", "BadSignature" (a wrong password, or a message somebody changed), "Expired", "NotYetValid", "AlgorithmMismatch" or, from decrypt, a SecretError's "LimitExceeded", and a message.