Skip to content

Hashes (std::hash)

std::hash gathers deterministic digest functions: SHA and MD5 algorithms for content fingerprinting, CRC32 for fast checksums, and HMAC for secret-key message authentication. All functions are pure computations and run in the sandbox.


SHA-256, SHA-512, SHA-1 and MD5

Each function returns the digest as a lowercase hexadecimal string. SHA-256 is the standard choice; MD5 and SHA-1 are for compatibility with legacy systems only. Determinism guarantees the same input always produces the same output.

Deterministic digests with SHA-256/512/1, MD5 and CRC32.

01-sha-md5.zolo
Playground
// Feature: hash.sha256 / hash.sha1 / hash.md5 — hash functions
// When to use: content identity (caching, dedupe), checksums.
// SHA-256 is the default choice; MD5 and SHA-1 only for legacy compatibility.

use std::hash

// Each function returns the lowercase hexadecimal digest representation.
print(hash.sha256("hello"))  // expected: 64 hex chars (2cf24...e9c8c)
print(hash.sha512("hello").len())  // expected: 128
print(hash.sha1("hello"))  // expected: aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
print(hash.md5("hello"))  // expected: 5d41402abc4b2a76b9719d911017c592

// Hashes are deterministic: same input -> same output.
print(hash.sha256("zolo") == hash.sha256("zolo"))  // expected: true
print(hash.sha256("a") == hash.sha256("b"))  // expected: false

// CRC32: fast, non-cryptographic — good for detecting corruption, bad
// for security.
print(hash.crc32("hello"))  // expected: int

HMAC — keyed authentication

hash.hmac(algo, key, message) produces an authentication code that cannot be forged without the secret key, even if the attacker knows the hash algorithm. Typical uses: webhook validation, signed cookies and HS256 tokens.

HMAC-SHA256 for validating webhooks; MAC comparison with different keys.

02-hmac.zolo
Playground
// Feature: hash.hmac — Hash-based Message Authentication Code
// When to use: authenticate payloads (webhooks, HS* JWTs, signed cookies).
// Tamper-resistant — even knowing the hash, you can't forge it without the key.

use std::hash

let secret = "my-secret-key"
let payload = "user_id=42&action=transfer"

// hmac(algo, key, message) -> hex digest.
let mac = hash.hmac("sha256", secret, payload)
print(mac.len())  // expected: 64 hex chars

// A different key produces a completely different HMAC (avalanche effect).
let mac2 = hash.hmac("sha256", "another-key", payload)
print(mac == mac2)  // expected: false

// Useful to validate webhooks: compare the header against the expected HMAC.
fn validate_webhook(body: str, signature: str, key: str) -> bool {
  return hash.hmac("sha256", key, body) == signature
}

let ok = validate_webhook(payload, mac, secret)
print(ok)  // expected: true

Challenge

Implement a sign_jwt_payload(payload, secret) function that returns base64_url(header) + "." + base64_url(payload) + "." + hmac_sha256(...). Use std::hash and std::base64 together.

enespt-br