kryptos/crypto

Convenience wrappers for hashing, key derivation, random bytes, and constant-time comparison.

Example

import kryptos/crypto

// Generate 32 random bytes (suitable for a 256-bit key)
let key = crypto.random_bytes(32)

Values

pub fn concat_kdf(
  algorithm: hash.HashAlgorithm,
  secret secret: BitArray,
  info info: BitArray,
  length length: Int,
) -> Result(BitArray, Nil)

Derives key material using Concat KDF (NIST SP 800-56A). Also called the single-step or one-step key derivation function.

Concat KDF uses a hash function to derive key material from a shared secret and context-specific information. Supports SHA-1, SHA-2, and SHA-3 family algorithms. Maximum output length is 255 * hash_length bytes.

Example

import kryptos/crypto
import kryptos/hash

let secret = crypto.random_bytes(32)
let assert Ok(derived) =
  crypto.concat_kdf(hash.Sha256, secret:, info: <<"context":utf8>>, length: 32)
pub const constant_time_equal: fn(BitArray, BitArray) -> Bool

Compares two BitArray in constant time.

Use this function when comparing secrets like MACs, password hashes, API tokens, or any other security-sensitive data. The comparison takes the same amount of time regardless of where the arrays differ, preventing timing attacks.

Example

let expected_mac = compute_mac(message, key)
let received_mac = get_mac_from_request()

// Safe: constant-time comparison prevents timing attacks
case crypto.constant_time_equal(expected_mac, received_mac) {
  True -> accept_message()
  False -> reject_message()
}
pub fn hash(
  algorithm: hash.HashAlgorithm,
  data: BitArray,
) -> Result(BitArray, Nil)

Computes the hash digest of input data in one call.

Example

import kryptos/crypto
import kryptos/hash

let assert Ok(digest) = crypto.hash(hash.Sha256, <<"hello":utf8>>)
pub fn hkdf(
  algorithm: hash.HashAlgorithm,
  input ikm: BitArray,
  salt salt: option.Option(BitArray),
  info info: BitArray,
  length length: Int,
) -> Result(BitArray, Nil)

Derives key material using HKDF (RFC 5869).

HKDF combines an extract-then-expand approach to derive cryptographically strong key material from input key material. The algorithm must be HMAC-compatible. Maximum output length is 255 * hash_length bytes. A None salt uses hash-length zeros per RFC 5869.

Example

import gleam/option
import kryptos/crypto
import kryptos/hash

let ikm = crypto.random_bytes(32)
let salt = option.Some(crypto.random_bytes(16))
let assert Ok(derived) =
  crypto.hkdf(hash.Sha256, input: ikm, salt:, info: <<"app":utf8>>, length: 32)
pub fn hmac(
  algorithm: hash.HashAlgorithm,
  key key: BitArray,
  data data: BitArray,
) -> Result(BitArray, Nil)

Computes the HMAC of input data in one call.

Example

import kryptos/crypto
import kryptos/hash

let assert Ok(mac) = crypto.hmac(hash.Sha256, key: <<"secret":utf8>>, data: <<"hello":utf8>>)
pub fn pbkdf2(
  algorithm: hash.HashAlgorithm,
  password password: BitArray,
  salt salt: BitArray,
  iterations iterations: Int,
  length length: Int,
) -> Result(BitArray, Nil)

Derives key material from a password using PBKDF2 (RFC 8018).

PBKDF2 applies a pseudorandom function (HMAC) to derive keys from passwords. It is designed to be computationally expensive to resist brute-force attacks.

Note: For password hashing in production applications, consider using Argus which provides Argon2 an algorithm specifically designed for password storage. PBKDF2 is primarily useful for interoperability with systems that require it.

The algorithm must be HMAC-compatible. SHA-256 or stronger is recommended; MD5 and SHA-1 are weak for password hashing.

Example

import kryptos/crypto
import kryptos/hash

let salt = crypto.random_bytes(16)
let assert Ok(derived) =
  crypto.pbkdf2(
    hash.Sha256,
    password: <<"hunter2":utf8>>,
    salt:,
    iterations: 100_000,
    length: 32,
  )
pub fn random_bytes(length: Int) -> BitArray

Generates cryptographically secure random bytes using the platform’s cryptographically secure random number generator.

A negative length returns an empty BitArray.

pub fn random_uuid() -> String

Generates a cryptographically secure random UUID v4.

Search Document