forge_hasher 0.1.3

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

use crypto::digest::Digest;
use crypto::sha3::Sha3;

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

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

        sha3_inner(ret, hash, round - 1)
    }

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

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

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

    let expect_256_1 = vec![
        167, 255, 198, 248, 191, 30, 215, 102, 81, 193, 71, 86, 160, 97, 214, 98, 245, 128, 255,
        77, 228, 59, 73, 250, 130, 216, 10, 75, 128, 248, 67, 74,
    ];
    assert_eq!(hash("".as_bytes(), HashLen::Len256, 1)?, expect_256_1);

    let expect_256_1 = vec![
        51, 56, 190, 105, 79, 80, 197, 243, 56, 129, 73, 134, 205, 240, 104, 100, 83, 168, 136,
        184, 79, 66, 77, 121, 42, 244, 185, 32, 35, 152, 243, 146,
    ];
    assert_eq!(hash(input, HashLen::Len256, 1)?, expect_256_1);

    let expect_384_1 = vec![
        114, 10, 234, 17, 1, 158, 240, 100, 64, 251, 240, 93, 135, 170, 36, 104, 10, 33, 83, 223,
        57, 7, 178, 54, 49, 231, 23, 124, 230, 32, 250, 19, 48, 255, 7, 192, 253, 222, 229, 70,
        153, 164, 195, 238, 14, 233, 216, 135,
    ];
    assert_eq!(hash(input, HashLen::Len384, 1)?, expect_384_1);

    let data = [b'x'; 2_000_000];
    let expect_256_1 = vec![
        224, 237, 251, 95, 119, 8, 220, 204, 28, 189, 195, 121, 136, 89, 153, 106, 53, 20, 51, 50,
        63, 244, 194, 50, 57, 250, 41, 82, 18, 214, 30, 24,
    ];
    assert_eq!(hash(&data, HashLen::Len256, 1)?, expect_256_1);

    Ok(())
}