hashes icon indicating copy to clipboard operation
hashes copied to clipboard

Blake2 missing functionality while migrating from `blake2-rfc`

Open cipriancraciun opened this issue 3 years ago • 3 comments

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.

cipriancraciun avatar Feb 14 '22 08:02 cipriancraciun

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.

newpavlov avatar Feb 16 '22 19:02 newpavlov

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 avatar Sep 15 '22 13:09 davxy

@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);
}

eduardonunesp avatar Nov 18 '22 21:11 eduardonunesp