shuttle_core/crypto/
sha.rs

1use sodiumoxide::crypto::auth::hmacsha256;
2
3/// HMAC key
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct HmacSha256Key(pub [u8; 32]);
6
7impl HmacSha256Key {
8    /// Create a key filled with zero.
9    fn zero() -> HmacSha256Key {
10        HmacSha256Key([0; 32])
11    }
12
13    /// `hkdf-extract(data) == HMAC(<zero>, data)`
14    pub fn hkdf_extract(data: &[u8]) -> HmacSha256Key {
15        let zero = HmacSha256Key::zero();
16        let mac = HmacSha256Mac::authenticate(&data, &zero);
17        HmacSha256Key(mac.0)
18    }
19
20    /// `hkdf-expand(key, data) == HMAC(key, data|0x1)`
21    pub fn hkdf_expand(key: &HmacSha256Key, data: &[u8]) -> HmacSha256Key {
22        let mut bytes = Vec::new();
23        bytes.extend_from_slice(&data);
24        bytes.push(1);
25        let mac = HmacSha256Mac::authenticate(&bytes, &key);
26        HmacSha256Key(mac.0)
27    }
28}
29
30/// HMAC mac.
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct HmacSha256Mac(pub [u8; 32]);
33
34impl HmacSha256Mac {
35    /// Create a mac filled with zero.
36    pub fn zero() -> HmacSha256Mac {
37        HmacSha256Mac([0; 32])
38    }
39
40    /// Authenticate the message with the key.
41    pub fn authenticate(data: &[u8], key: &HmacSha256Key) -> HmacSha256Mac {
42        let hkey = hmacsha256::Key(key.0);
43        let tag = hmacsha256::authenticate(&data, &hkey);
44        HmacSha256Mac(tag.0)
45    }
46}