cochranblock 1.0.3

Zero-cloud website in a single Rust binary. 13MB on x86, 8.9MB on ARM. $10/month infrastructure. cargo install and run.
Documentation
#![allow(non_camel_case_types, non_snake_case, dead_code, unused_imports)]

// All Rights Reserved — The Cochran Block, LLC
// Contributors: Mattbusel (XFactor), GotEmCoach, KOVA, Claude Opus 4.6, SuperNinja, Composer 1.5, Google Gemini Pro 3

use hkdf::Hkdf;
use sha2::Sha256;

use crate::error::t18;

/// f31 = key_derive — HKDF, context-specific. Why: Kova forbids unwrap in lib; expand can fail.
pub fn f31(master: &str, context: &str) -> Result<[u8; 32], t18> {
    let salt = b"cochranblock-salt";
    let hk = Hkdf::<Sha256>::new(Some(salt), master.as_bytes());
    let mut out = [0u8; 32];
    hk.expand(context.as_bytes(), &mut out)
        .map_err(|e| t18::E5(e.to_string()))?;
    Ok(out)
}

/// f32 = key_derive_default — HKDF, default context. Why: session signing key derivation.
pub fn f32(master: &str) -> Result<[u8; 32], t18> {
    f31(master, "session-signing-key-v1")
}