Key Derivation
S5 uses a very simple and fast (but secure) key derivation function for identity, accounts and the file system (only scoped to a single directory).
The base
key is always random; in the file system it's randomly generated for every newly created directory, for accounts it's derived in multiple steps from the identity root secret (which is randomly generated).
fn derive_hash(base: &[u8; 32], tweak: &[u8; 32]) -> [u8; 32] {
let mut hasher = blake3::Hasher::new();
hasher.update(base);
hasher.update(tweak);
*hasher.finalize().as_bytes()
}
fn derive_hash_string(base: &[u8; 32], tweak: &[u8]) -> [u8; 32] {
derive_hash(base, blake3::hash(tweak).as_bytes())
}
fn derive_hash_int(base: &[u8; 32], tweak: u16) -> [u8; 32] {
let mut tweak_bytes = [0u8; 32];
tweak_bytes[..2].copy_from_slice(&tweak.to_le_bytes());
derive_hash(base, &tweak_bytes)
}