Skip to main content

Overview

The std.crypto module provides cryptographic primitives including authenticated encryption, hashing, key derivation, digital signatures, and elliptic curve operations. All implementations follow modern cryptographic standards.

Authenticated Encryption (AEAD)

AEGIS

High-performance authenticated encryption.
const aegis = std.crypto.aead.aegis;

// 128-bit key variants
pub const Aegis128L = aegis.Aegis128L;
pub const Aegis128X2 = aegis.Aegis128X2;
pub const Aegis128X4 = aegis.Aegis128X4;

// 256-bit key variants
pub const Aegis256 = aegis.Aegis256;
pub const Aegis256X2 = aegis.Aegis256X2;
pub const Aegis256X4 = aegis.Aegis256X4;
Example:
const key: [32]u8 = ... ; // 256-bit key
const nonce: [32]u8 = ... ; // 256-bit nonce
const plaintext = "Secret message";
const ad = "Additional data";

var ciphertext: [plaintext.len]u8 = undefined;
var tag: [32]u8 = undefined;

std.crypto.aead.aegis.Aegis256.encrypt(
    &ciphertext,
    &tag,
    plaintext,
    ad,
    nonce,
    key
);

ChaCha20-Poly1305

Wide ly-used AEAD cipher.
const chacha_poly = std.crypto.aead.chacha_poly;

pub const ChaCha20Poly1305 = chacha_poly.ChaCha20Poly1305;
pub const XChaCha20Poly1305 = chacha_poly.XChaCha20Poly1305;
Example:
const key: [32]u8 = ... ; // 256-bit key
const nonce: [12]u8 = ... ; // 96-bit nonce

var ciphertext: [msg.len]u8 = undefined;
var tag: [16]u8 = undefined;

std.crypto.aead.chacha_poly.ChaCha20Poly1305.encrypt(
    &ciphertext,
    &tag,
    msg,
    additional_data,
    nonce,
    key
);

AES-GCM

const aes_gcm = std.crypto.aead.aes_gcm;

pub const Aes128Gcm = aes_gcm.Aes128Gcm;
pub const Aes256Gcm = aes_gcm.Aes256Gcm;

AES Variants

// AES-GCM-SIV (nonce-misuse resistant)
const Aes128GcmSiv = std.crypto.aead.aes_gcm_siv.Aes128GcmSiv;
const Aes256GcmSiv = std.crypto.aead.aes_gcm_siv.Aes256GcmSiv;

// AES-SIV
const Aes128Siv = std.crypto.aead.aes_siv.Aes128Siv;
const Aes256Siv = std.crypto.aead.aes_siv.Aes256Siv;

// AES-OCB
const Aes128Ocb = std.crypto.aead.aes_ocb.Aes128Ocb;
const Aes256Ocb = std.crypto.aead.aes_ocb.Aes256Ocb;

// AES-CCM
const aes_ccm = std.crypto.aead.aes_ccm;

Hash Functions

SHA-2 Family

const sha2 = std.crypto.hash.sha2;

pub const Sha224 = sha2.Sha224;
pub const Sha256 = sha2.Sha256;
pub const Sha384 = sha2.Sha384;
pub const Sha512 = sha2.Sha512;
pub const Sha512_224 = sha2.Sha512_224;
pub const Sha512_256 = sha2.Sha512_256;
Example:
const std = @import("std");

var hasher = std.crypto.hash.sha2.Sha256.init(.{});
hasher.update("Hello, ");
hasher.update("World!");

var digest: [32]u8 = undefined;
hasher.final(&digest);

// One-shot hashing
const hash = std.crypto.hash.sha2.Sha256.hash("Hello, World!", .{});

SHA-3 Family

const sha3 = std.crypto.hash.sha3;

pub const Sha3_224 = sha3.Sha3_224;
pub const Sha3_256 = sha3.Sha3_256;
pub const Sha3_384 = sha3.Sha3_384;
pub const Sha3_512 = sha3.Sha3_512;

// Extendable output functions
pub const Shake128 = sha3.Shake128;
pub const Shake256 = sha3.Shake256;

BLAKE Family

const blake2 = std.crypto.hash.blake2;

pub const Blake2b128 = blake2.Blake2b128;
pub const Blake2b256 = blake2.Blake2b256;
pub const Blake2b384 = blake2.Blake2b384;
pub const Blake2b512 = blake2.Blake2b512;

pub const Blake2s128 = blake2.Blake2s128;
pub const Blake2s224 = blake2.Blake2s224;
pub const Blake2s256 = blake2.Blake2s256;

const Blake3 = std.crypto.hash.Blake3;
Example:
var out: [32]u8 = undefined;
std.crypto.hash.Blake3.hash("message", &out, .{});

Other Hash Functions

const Md5 = std.crypto.hash.Md5;     // Legacy, DO NOT USE for security
const Sha1 = std.crypto.hash.Sha1;   // Legacy, DO NOT USE for security

Message Authentication Codes (MAC)

HMAC

const hmac = std.crypto.auth.hmac;

// Generic HMAC with any hash function
pub fn Hmac(comptime Hash: type) type;
Example:
const HmacSha256 = std.crypto.auth.hmac.Hmac(std.crypto.hash.sha2.Sha256);

const key = "secret_key";
var mac: [HmacSha256.mac_length]u8 = undefined;

HmacSha256.create(&mac, "message", key);

SipHash

const siphash = std.crypto.auth.siphash;

pub const SipHash64 = siphash.SipHash64;
pub const SipHash128 = siphash.SipHash128;

Poly1305

const Poly1305 = std.crypto.onetimeauth.Poly1305;

Password Hashing

Argon2

const argon2 = std.crypto.pwhash.argon2;

pub fn hash(
    allocator: Allocator,
    password: []const u8,
    salt: []const u8,
    params: Params,
    mode: Mode
) ![]u8;
Example:
const params = std.crypto.pwhash.argon2.Params{
    .t = 3,      // Time cost (iterations)
    .m = 65536,  // Memory cost (KiB)
    .p = 4,      // Parallelism
};

var hash_buf: [32]u8 = undefined;
try std.crypto.pwhash.argon2.kdf(
    allocator,
    &hash_buf,
    password,
    salt,
    params,
    .argon2id
);

bcrypt

const bcrypt = std.crypto.pwhash.bcrypt;

pub fn hash(
    password: []const u8,
    salt: [16]u8,
    params: Params
) ![60]u8;

scrypt

const scrypt = std.crypto.pwhash.scrypt;

pub fn kdf(
    allocator: Allocator,
    password: []const u8,
    salt: []const u8,
    params: Params,
    derived_key: []u8
) !void;

PBKDF2

pub fn pbkdf2(
    comptime Prf: type,
    password: []const u8,
    salt: []const u8,
    iterations: u32,
    derived_key: []u8
) void;
Example:
var key: [32]u8 = undefined;
std.crypto.pwhash.pbkdf2(
    std.crypto.auth.hmac.Hmac(std.crypto.hash.sha2.Sha256),
    password,
    salt,
    100000,
    &key
);

Key Derivation

HKDF

const hkdf = std.crypto.kdf.hkdf;

pub fn Hkdf(comptime Hmac: type) type;
Example:
const HkdfSha256 = std.crypto.kdf.hkdf.Hkdf(
    std.crypto.auth.hmac.Hmac(std.crypto.hash.sha2.Sha256)
);

const ikm = "input key material";
const salt = "optional salt";
const info = "app-specific info";

var okm: [32]u8 = undefined;
HkdfSha256.extract(&okm, ikm, salt);
HkdfSha256.expand(&okm, info, okm);

Digital Signatures

Ed25519

const Ed25519 = std.crypto.sign.Ed25519;

pub const KeyPair = struct {
    public_key: [32]u8,
    secret_key: [64]u8,
    
    pub fn create(seed: [32]u8) KeyPair;
    pub fn sign(self: KeyPair, msg: []const u8, noise: ?[32]u8) [64]u8;
};

pub fn verify(
    sig: [64]u8,
    msg: []const u8,
    public_key: [32]u8
) !void;
Example:
var seed: [32]u8 = undefined;
std.crypto.random.bytes(&seed);

const kp = std.crypto.sign.Ed25519.KeyPair.create(seed);
const msg = "Sign this message";
const sig = kp.sign(msg, null);

try std.crypto.sign.Ed25519.verify(sig, msg, kp.public_key);

ECDSA

const ecdsa = std.crypto.sign.ecdsa;

pub fn EcdsaP256Sha256() type;
pub fn EcdsaP384Sha384() type;
pub fn EcdsaSecp256k1Sha256() type;

ML-DSA (Post-Quantum)

const mldsa = std.crypto.sign.mldsa;

pub const MlDsa44 = mldsa.MlDsa44;
pub const MlDsa65 = mldsa.MlDsa65;
pub const MlDsa87 = mldsa.MlDsa87;

Elliptic Curves

Curve25519

const Curve25519 = std.crypto.ecc.Curve25519;
const Edwards25519 = std.crypto.ecc.Edwards25519;
const Ristretto255 = std.crypto.ecc.Ristretto255;

NIST Curves

const P256 = std.crypto.ecc.P256;
const P384 = std.crypto.ecc.P384;

Bitcoin Curve

const Secp256k1 = std.crypto.ecc.Secp256k1;

Diffie-Hellman

X25519

const X25519 = std.crypto.dh.X25519;

pub fn create(secret_key: [32]u8) [32]u8;  // Generate public key
pub fn scalarmult(secret_key: [32]u8, public_key: [32]u8) ![32]u8;  // Shared secret
Example:
var alice_secret: [32]u8 = undefined;
std.crypto.random.bytes(&alice_secret);
const alice_public = std.crypto.dh.X25519.create(alice_secret);

var bob_secret: [32]u8 = undefined;
std.crypto.random.bytes(&bob_secret);
const bob_public = std.crypto.dh.X25519.create(bob_secret);

const shared1 = try std.crypto.dh.X25519.scalarmult(alice_secret, bob_public);
const shared2 = try std.crypto.dh.X25519.scalarmult(bob_secret, alice_public);
// shared1 == shared2

Key Encapsulation (Post-Quantum)

ML-KEM (Kyber)

const ml_kem = std.crypto.kem.ml_kem;

pub const MlKem512 = ml_kem.MlKem512;
pub const MlKem768 = ml_kem.MlKem768;
pub const MlKem1024 = ml_kem.MlKem1024;

Random Number Generation

const random = std.crypto.random;

// Cryptographically secure RNG
pub fn bytes(buffer: []u8) void;
pub fn int(comptime T: type) T;
Example:
var key: [32]u8 = undefined;
std.crypto.random.bytes(&key);

const rand_num = std.crypto.random.int(u64);

Timing-Safe Operations

const timing_safe = std.crypto.timing_safe;

pub fn eql(comptime T: type, a: T, b: T) bool;
pub fn compare(comptime T: type, a: []const T, b: []const T, endian: std.builtin.Endian) std.math.Order;
Example:
// Constant-time comparison (prevents timing attacks)
if (std.crypto.timing_safe.eql([32]u8, computed_tag, expected_tag)) {
    // Tags match
}

Build docs developers (and LLMs) love