hashes
hashes copied to clipboard
Blake2 missing functionality while migrating from `blake2-rfc`
Not sure if this is a feature request or a question...
I was previously using the blake2-rfc crate and now I want to migrate to the blake2 crate. However previously I was using the Blake2b::with_key constructor (as per https://docs.rs/blake2-rfc/0.2.18/blake2_rfc/blake2b/struct.Blake2b.html#method.with_key) and I can't seem to find the proper equivalent in case of the blake2 crate.
There seems to exist Blake2bVarCore::new_with_params (as per https://docs.rs/blake2/0.10.2/blake2/struct.Blake2bVarCore.html#method.new_with_params), however I can't seem to convert that into a Blake2bVar (which I need to get variable hash output).
Based on the current blake2b implementation, it seems I should be able to just replace the core member of the Blake2bVar with the Blake2bVarCore instance, which indeed works if I "hack my way" by using pointers. However there is no "official" (as per the public API) way of doing this.
A simple From implementation, or even an unsafe constructor that takes a Blake2bVarCore and yields a Blake2bVar would seem to suffice.
Unfortunately, how BLAKE2 handles keys does not map well to the API exposed by digest. Because it always processes blocks lazily and padded key is hashed as data, it's not possible to create a key-initialized "core" state. In other words, key first must be written into block buffer first and consumed only when first bytes of data will be supplied or finalizaiton will be performed.
I think the most practical solution right now will be to introduce Blake2sVarMac/Blake2bVarMac types similarly to the existing Blake2sMac/Blake2bMac types.
Currently I'm able to reproduce the output of:
use blake2_rfc::blake2b::Blake2;
let ctx = Blake2::with_key(32, KEY);
ctx.update(DATA);
let hash = ctx.finalize();
With:
use blake2::{Blake2Mac, digest::{typenum::U32, Update, FixedOutput}};
let ctx = Blake2Mac::<U32>::new_with_salt_and_personal(KEY, &[], &[]);
ctx.update(DATA);
let hash = ctx.finalize_fixed();
@davxy solution works for me
use blake2::{
digest::{typenum::U32, FixedOutput, Update},
Blake2bMac,
};
use blake2_rfc::blake2b::Blake2b;
fn main() {
let data = b"hello world";
let key = b"somekey";
let mut ctx = Blake2b::with_key(32, key);
ctx.update(data);
let hash = ctx.finalize();
// hash to string
let hash_str1 = hash
.as_bytes()
.iter()
.map(|b| format!("{:02x}", b))
.collect::<String>();
let mut ctx = Blake2bMac::<U32>::new_with_salt_and_personal(key, &[], &[]).unwrap();
ctx.update(data);
let hash = ctx.finalize_fixed();
// hash to string
let hash_str2 = hash
.iter()
.map(|b| format!("{:02x}", b))
.collect::<String>();
assert_eq!(hash_str1, hash_str2);
}