forge_hasher 0.1.3

The rust language implementation of forge_hasher
Documentation
use super::HashLen;
use super::Result;

use crypto::blake2b::Blake2b;
use crypto::digest::Digest;

/// len enum {160, 256, 384, 512}, default 256
/// round enum {1, 2, 3 ... 100}, default 1
/// input is hashed round times by blake2b, return [u8]
pub fn hash(input: &[u8], len: HashLen, round: u8) -> Result<Vec<u8>> {
    let (mut hasher, size) = match len {
        HashLen::Len160 => (Blake2b::new(20), 20),
        HashLen::Len256 => (Blake2b::new(32), 32),
        HashLen::Len384 => (Blake2b::new(48), 48),
        HashLen::Len512 => (Blake2b::new(64), 64),
        _ => bail!("blake2b not support hash algo {:?}", len),
    };

    fn blake2b_inner(ret: &mut [u8], hash: &mut Blake2b, round: u8) -> Result<Vec<u8>> {
        if round <= 0 {
            return Ok(ret.to_owned());
        }
        hash.input(ret);
        hash.result(ret);

        blake2b_inner(ret, hash, round - 1)
    }

    let mut content = vec![0; size];
    hasher.input(input);
    hasher.result(&mut content);
    blake2b_inner(&mut content, &mut hasher, round - 1)
}

#[test]
fn test_blake2b() -> Result<()> {
    let input = &"hello".as_bytes();

    let expect_160_1 = vec![
        181, 83, 28, 112, 55, 240, 108, 159, 41, 71, 19, 42, 106, 119, 32, 44, 48, 142, 137, 57,
    ];
    assert_eq!(hash(input, HashLen::Len160, 1)?, expect_160_1);

    let expect_256_1 = vec![
        14, 87, 81, 192, 38, 229, 67, 178, 232, 171, 46, 176, 96, 153, 218, 161, 209, 229, 223, 71,
        119, 143, 119, 135, 250, 171, 69, 205, 241, 47, 227, 168,
    ];
    assert_eq!(hash("".as_bytes(), HashLen::Len256, 1)?, expect_256_1);

    let expect_256_1 = vec![
        50, 77, 207, 2, 125, 212, 163, 10, 147, 44, 68, 31, 54, 90, 37, 232, 107, 23, 61, 239, 164,
        184, 229, 137, 72, 37, 52, 113, 184, 27, 114, 207,
    ];
    assert_eq!(hash(input, HashLen::Len256, 1)?, expect_256_1);

    let expect_384_1 = vec![
        133, 241, 145, 112, 190, 84, 30, 119, 116, 218, 25, 124, 18, 206, 149, 155, 145, 162, 128,
        178, 242, 62, 49, 19, 214, 99, 138, 51, 53, 80, 126, 215, 45, 220, 48, 248, 18, 68, 219,
        233, 250, 141, 25, 92, 35, 188, 235, 126,
    ];
    assert_eq!(hash(input, HashLen::Len384, 1)?, expect_384_1);

    let expect_512_1 = vec![
        228, 207, 163, 154, 61, 55, 190, 49, 197, 150, 9, 232, 7, 151, 7, 153, 202, 166, 138, 25,
        191, 170, 21, 19, 95, 22, 80, 133, 224, 29, 65, 166, 91, 161, 225, 177, 70, 174, 182, 189,
        0, 146, 180, 158, 172, 33, 76, 16, 60, 207, 163, 163, 101, 149, 75, 187, 229, 47, 116, 162,
        179, 98, 12, 148,
    ];
    assert_eq!(hash(input, HashLen::Len512, 1)?, expect_512_1);

    Ok(())
}