Skip to main content

ling_crypto/
hash.rs

1//! Cryptographic hashing: BLAKE3, SHA3-256, SHA3-512, SHAKE-256.
2
3use sha3::digest::{ExtendableOutput, Update as XofUpdate};
4use sha3::{Digest, Sha3_256 as Sha3_256Inner, Sha3_512 as Sha3_512Inner};
5
6// ── BLAKE3 ────────────────────────────────────────────────────────────────────
7
8pub struct Blake3;
9
10impl Blake3 {
11    pub fn hash(data: &[u8]) -> [u8; 32] {
12        let hash = blake3::hash(data);
13        *hash.as_bytes()
14    }
15
16    pub fn keyed_hash(key: &[u8; 32], data: &[u8]) -> [u8; 32] {
17        let hash = blake3::keyed_hash(key, data);
18        *hash.as_bytes()
19    }
20
21    /// Derive a subkey from a context string and key material.
22    pub fn derive_key(context: &str, key_material: &[u8]) -> [u8; 32] {
23        blake3::derive_key(context, key_material)
24    }
25
26    /// Extended output (XOF): produce `len` bytes from `data`.
27    pub fn xof(data: &[u8], len: usize) -> Vec<u8> {
28        let mut hasher = blake3::Hasher::new();
29        hasher.update(data);
30        let mut out = vec![0u8; len];
31        let mut reader = hasher.finalize_xof();
32        reader.fill(&mut out);
33        out
34    }
35}
36
37// ── SHA3-256 ──────────────────────────────────────────────────────────────────
38
39pub struct Sha3_256;
40
41impl Sha3_256 {
42    pub fn hash(data: &[u8]) -> [u8; 32] {
43        let mut h = Sha3_256Inner::new();
44        Digest::update(&mut h, data);
45        h.finalize().into()
46    }
47
48    pub fn hash_many(parts: &[&[u8]]) -> [u8; 32] {
49        let mut h = Sha3_256Inner::new();
50        for part in parts {
51            Digest::update(&mut h, part);
52        }
53        h.finalize().into()
54    }
55}
56
57// ── SHA3-512 ──────────────────────────────────────────────────────────────────
58
59pub struct Sha3_512;
60
61impl Sha3_512 {
62    pub fn hash(data: &[u8]) -> [u8; 64] {
63        let mut h = Sha3_512Inner::new();
64        Digest::update(&mut h, data);
65        h.finalize().into()
66    }
67}
68
69// ── SHAKE-256 (XOF) ───────────────────────────────────────────────────────────
70
71pub struct Shake256;
72
73impl Shake256 {
74    /// Produce `len` bytes of output from `data`.
75    pub fn hash(data: &[u8], len: usize) -> Vec<u8> {
76        let mut h = sha3::Shake256::default();
77        XofUpdate::update(&mut h, data);
78        let mut out = vec![0u8; len];
79        h.finalize_xof_into(&mut out);
80        out
81    }
82}