Crypto and randomness

Crypto and randomness

import std::crypto;
import std::random;

Which one to use

std::random is a fast CMWC generator and is not cryptographically secure. Use it for sampling, shuffling, and jitter. Use std::crypto for anything a attacker would benefit from predicting: tokens, keys, nonces, identifiers.

let token: string = crypto::random_hex(16)   // secure
let roll: number = random::next_int(1, 7)    // not secure, upper bound exclusive

random::next_int has an exclusive upper bound and silently returns min when max <= min. random::choice returns None for an empty array. An Rng instance must be released with free().

Setting up crypto

Call crypto::init() once before anything else. It is safe to call repeatedly.

What the module covers

Area Functions
Random random_u32, random_bytes, random_hex
Encoding to_hex, from_hex, to_base64, from_base64
Hashing sha256, sha512, blake2b, plus streaming Sha256 / Sha512
Secretbox secretbox_keygen, secretbox_nonce, secretbox_encrypt, secretbox_decrypt
ChaCha20-Poly1305 chacha_keygen, chacha_nonce, chacha_encrypt, chacha_decrypt
AES-256-GCM aesgcm_available, aesgcm_keygen, aesgcm_nonce, aesgcm_encrypt, aesgcm_decrypt
Public key box_keypair, box_nonce, box_encrypt, box_decrypt
Signatures sign_keypair, sign, sign_verify
HMAC hmac256, hmac512, and their keygen and verify pairs
Passwords pwhash_salt, pwhash, pwhash_str, pwhash_verify
Legacy md5, sha1

Working with the values

Keys, nonces, and ciphertexts are raw binary strings, not hex. Encode them with to_hex or to_base64 before storing or displaying:

let key: string = crypto::secretbox_keygen()
let nonce: string = crypto::secretbox_nonce()
let cipher: string = crypto::secretbox_encrypt(secret, nonce, key)
let stored: string = `${crypto::to_base64(nonce)}:${crypto::to_base64(cipher)}`

The hash functions are the exception: sha256, sha512, blake2b, md5, and sha1 return hex.

Every decrypt returns an optional, and None means authentication failed. That is indistinguishable from malformed input, and deliberately so.

Use a fresh nonce for every message and a fresh salt for every password. A streaming hasher must not be used after finalize().

md5 and sha1 are broken and present only for compatibility with existing formats.