kryptos/crypto

The crypto module provides cryptographic primitives.

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 is a single-step key derivation function that uses a hash function to derive key material from a shared secret and context-specific information.

Parameters

  • algorithm: The hash algorithm to use (SHA-1, SHA-2, or SHA-3 family)
  • secret: The shared secret from key agreement (e.g., ECDH)
  • info: Context and application specific information
  • length: Desired output length in bytes (max: 255 * hash_length)

Returns

Ok(BitArray) containing the derived key material of the requested length, or Error(Nil) if the algorithm is not supported or length is invalid.

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.

Parameters

  • a: The first bit array to compare
  • b: The second bit array to compare

Returns

True if a and b are equal, False otherwise. 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.

Parameters

  • algorithm: The hash algorithm to use
  • data: The data to hash

Returns

Ok(BitArray) containing the hash digest, or Error(Nil) if the hash algorithm is not supported by the runtime.

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.

Parameters

  • algorithm: The hash algorithm to use (must be HMAC-compatible)
  • input: Input key material (IKM) - the source keying material
  • salt: Optional salt value (None uses hash-length zeros per RFC 5869)
  • info: Context and application specific information
  • length: Desired output length in bytes (max: 255 * hash_length)

Returns

Ok(BitArray) containing the derived key material of the requested length, or Error(Nil) if the algorithm is not supported or length exceeds the maximum.

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.

Parameters

  • algorithm: The hash algorithm to use for the HMAC
  • key: The secret key for authentication
  • data: The data to authenticate

Returns

Ok(BitArray) containing the message authentication code, or Error(Nil) if the hash algorithm is not supported.

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.

Parameters

  • algorithm: The hash algorithm to use for HMAC (must be HMAC-compatible). SHA-256 or stronger is recommended; MD5 and SHA-1 are weak for password hashing.
  • password: The password to derive the key from
  • salt: A random salt value (should be unique per password)
  • iterations: Number of iterations (higher = slower but more secure)
  • length: Desired output length in bytes

Returns

Ok(BitArray) containing the derived key material of the requested length, or Error(Nil) if the algorithm is not supported, iterations <= 0, or length <= 0.

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.

Parameters

  • length: The number of random bytes to generate. If negative, returns an empty BitArray.

Returns

A BitArray containing the generated random bytes.

pub fn random_uuid() -> String

Generates a cryptographically secure random UUID v4.

Returns

A String containing a UUID v4.

Search Document