enigma/hashes/
md4.rs

1/// Struct storing the necessary state for the Message Digest 4 (MD4) hash function
2/// Code is ported and `rustified` from libtomcrypt
3#[allow(non_camel_case_types)]
4pub struct MD4 {
5    state   : [u32; 4],
6    buffer  : [u8; 64],
7    len     : u64,
8    cur_len : u32
9}
10
11/// Helper function as described in the RFC
12#[inline(always)]
13fn f(x: u32, y: u32, z: u32) -> u32 {
14    z ^ (x & (y ^ z))
15}
16
17/// Helper function as described in the RFC
18#[inline(always)]
19fn g(x: u32, y: u32, z: u32) -> u32 {
20    (x & y) | (z & (x | y))
21}
22
23/// Helper function as described in the RFC
24#[inline(always)]
25fn h(x: u32, y: u32, z: u32) -> u32 {
26    x ^ y ^ z
27}
28
29impl MD4 {
30    /// Creates a new MD4 instance
31    ///
32    /// # Returns
33    /// * The created instance
34    pub fn new() -> MD4 {
35        MD4 {
36            state   : [0; 4],
37            buffer  : [0; 64],
38            len     : 0,
39            cur_len : 0
40        }
41    }
42
43    fn reset(&mut self) {
44        self.state   = [0; 4];
45        self.buffer  = [0; 64];
46        self.len     = 0;
47        self.cur_len = 0;
48    }
49}
50
51impl ::hashes::HashFunction for MD4 {
52    fn set_input(&mut self, input: &[u8]) {
53
54        // First reset the hash state
55        self.reset();
56    }
57
58    fn hash(&mut self) {
59
60    }
61
62    fn get_output(&mut self, output: &mut [u8]) {
63        assert!(output.len() >= self.get_output_length())
64    }
65
66    fn get_blocksize(&self) -> u32 { 64 }
67
68    fn get_output_length_in_bits(&self) -> u32 { 128 }
69}
70
71#[cfg(test)]
72mod tests {
73    use hashes::md4::MD4;
74    use hashes::test::{HashTestCase, perform_hash_test};
75
76    #[test]
77    fn test_md4() {
78        let tests = vec![
79            hash_test!(
80                "",
81                vec![0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0],
82                "31d6cfe0d16ae931b73c59d7e0c089c0"),
83            hash_test!(
84                "a",
85                vec![0xbd,0xe5,0x2c,0xb3,0x1d,0xe3,0x3e,0x46,0x24,0x5e,0x05,0xfb,0xdb,0xd6,0xfb,0x24],
86                "bde52cb31de33e46245e05fbdbd6fb24"),
87            hash_test!(
88                "abc",
89                vec![0xa4,0x48,0x01,0x7a,0xaf,0x21,0xd8,0x52,0x5f,0xc1,0x0a,0xe8,0x7a,0xa6,0x72,0x9d],
90                "a448017aaf21d8525fc10ae87aa6729d"
91            ),
92            hash_test!(
93                "message digest",
94                vec![0xd9,0x13,0x0a,0x81,0x64,0x54,0x9f,0xe8,0x18,0x87,0x48,0x06,0xe1,0xc7,0x01,0x4b],
95                "d9130a8164549fe818874806e1c7014b"
96            ),
97            hash_test!(
98                "abcdefghijklmnopqrstuvwxyz",
99                vec![0xd7,0x9e,0x1c,0x30,0x8a,0xa5,0xbb,0xcd,0xee,0xa8,0xed,0x63,0xdf,0x41,0x2d,0xa9],
100                "d79e1c308aa5bbcdeea8ed63df412da9"
101            ),
102            hash_test!(
103                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
104                vec![0x04,0x3f,0x85,0x82,0xf2,0x41,0xdb,0x35,0x1c,0xe6,0x27,0xe1,0x53,0xe7,0xf0,0xe4],
105                "043f8582f241db351ce627e153e7f0e4"
106            ),
107            hash_test!(
108                "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
109                vec![0xe3,0x3b,0x4d,0xdc,0x9c,0x38,0xf2,0x19,0x9c,0x3e,0x7b,0x16,0x4f,0xcc,0x05,0x36],
110                "e33b4ddc9c38f2199c3e7b164fcc0536"
111            )
112        ];
113
114        let mut md4 = MD4::new();
115        for t in tests.iter() {
116            perform_hash_test(&mut md4, t);
117        }
118    }
119}