aboutsummaryrefslogtreecommitdiff
path: root/reference_impl
diff options
context:
space:
mode:
authorJack O'Connor <[email protected]>2019-12-27 16:20:38 -0600
committerJack O'Connor <[email protected]>2019-12-28 17:56:29 -0600
commit2fac7447e02aa0f532ebcacbfffc71565b691aea (patch)
treeb8819de7a86b79a41b9104e616418c8cee35d8e2 /reference_impl
parentba2806496360aa61cc2aa64204a39d923cb13895 (diff)
make derive_key take a key of any length
The previous version of this API called for a key of exactly 256 bits. That's good for optimal performance, but it would mean losing the use-with-other-algorithms property for applications whose input keys are a different size. There's no way for an abstraction over the previous version to provide reliable domain separation for the "extract" step.
Diffstat (limited to 'reference_impl')
-rw-r--r--reference_impl/reference_impl.rs18
1 files changed, 12 insertions, 6 deletions
diff --git a/reference_impl/reference_impl.rs b/reference_impl/reference_impl.rs
index bb8b511..d97256e 100644
--- a/reference_impl/reference_impl.rs
+++ b/reference_impl/reference_impl.rs
@@ -12,7 +12,8 @@ const CHUNK_END: u32 = 1 << 1;
const PARENT: u32 = 1 << 2;
const ROOT: u32 = 1 << 3;
const KEYED_HASH: u32 = 1 << 4;
-const DERIVE_KEY: u32 = 1 << 5;
+const DERIVE_KEY_CONTEXT: u32 = 1 << 5;
+const DERIVE_KEY_MATERIAL: u32 = 1 << 6;
const IV: [u32; 8] = [
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19,
@@ -272,11 +273,16 @@ impl Hasher {
Self::new_internal(key_words, KEYED_HASH)
}
- /// Construct a new `Hasher` for the key derivation function.
- pub fn new_derive_key(key: &[u8; KEY_LEN]) -> Self {
- let mut key_words = [0; 8];
- words_from_litte_endian_bytes(key, &mut key_words);
- Self::new_internal(key_words, DERIVE_KEY)
+ /// Construct a new `Hasher` for the key derivation function. The context
+ /// string should be hardcoded, globally unique, and application-specific.
+ pub fn new_derive_key(context: &str) -> Self {
+ let mut context_hasher = Hasher::new_internal(IV, DERIVE_KEY_CONTEXT);
+ context_hasher.update(context.as_bytes());
+ let mut context_key = [0; KEY_LEN];
+ context_hasher.finalize(&mut context_key);
+ let mut context_key_words = [0; 8];
+ words_from_litte_endian_bytes(&context_key, &mut context_key_words);
+ Self::new_internal(context_key_words, DERIVE_KEY_MATERIAL)
}
fn push_stack(&mut self, cv: [u32; 8]) {