forge_hasher 0.1.3

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

use tiny_keccak::Keccak;

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

    fn skeccak_f1600_inner(ret: &mut [u8], hash: &mut Keccak, round: u8) -> Result<Vec<u8>> {
        if round <= 0 {
            return Ok(ret.to_owned());
        }
        (*hash).update(ret);
        (*hash).clone().finalize(ret);

        skeccak_f1600_inner(ret, hash, round - 1)
    }

    let mut content = vec![0; size];
    hasher.update(input);
    hasher.clone().finalize(&mut content);

    skeccak_f1600_inner(&mut content, &mut hasher, round - 1)
}

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

    let expect_256_1 = vec![
        197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83,
        202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112,
    ];
    assert_eq!(hash("".as_bytes(), HashLen::Len256, 1)?, expect_256_1);

    let expect_256_1 = vec![
        28, 138, 255, 149, 6, 133, 194, 237, 75, 195, 23, 79, 52, 114, 40, 123, 86, 217, 81, 123,
        156, 148, 129, 39, 49, 154, 9, 167, 163, 109, 234, 200,
    ];
    assert_eq!(hash(input, HashLen::Len256, 1)?, expect_256_1);

    let expect_384_1 = vec![
        220, 239, 111, 183, 144, 143, 213, 43, 162, 106, 171, 167, 81, 33, 82, 106, 187, 241, 33,
        127, 28, 10, 49, 2, 70, 82, 209, 52, 211, 227, 47, 180, 205, 142, 156, 112, 59, 143, 67,
        231, 39, 123, 89, 165, 205, 64, 33, 117,
    ];
    assert_eq!(hash(input, HashLen::Len384, 1)?, expect_384_1);

    Ok(())
}