Skip to content

Commit e046360

Browse files
committed
Add an std::md4 module
1 parent d367cdf commit e046360

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

src/libstd/md4.rs

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
fn md4(msg: [u8]) -> {a: u32, b: u32, c: u32, d: u32} {
2+
let orig_len = vec::len(msg) * 8u;
3+
// pad message
4+
let msg = msg + [0x80u8];
5+
let bitlen = orig_len + 8u;
6+
while (bitlen + 64u) % 512u > 0u {
7+
msg += [0u8];
8+
bitlen += 8u;
9+
}
10+
// append length
11+
let i = 0u;
12+
while i < 8u {
13+
msg += [(orig_len >> (i * 8u)) as u8];
14+
i += 1u;
15+
}
16+
17+
let a = 0x67452301u32;
18+
let b = 0xefcdab89u32;
19+
let c = 0x98badcfeu32;
20+
let d = 0x10325476u32;
21+
22+
fn rot(r: int, x: u32) -> u32 {
23+
let r = r as u32;
24+
(x << r) | (x >> (32u32 - r))
25+
}
26+
27+
let i = 0u, e = vec::len(msg);
28+
let x = vec::init_elt_mut(0u32, 16u);
29+
while i < e {
30+
let aa = a, bb = b, cc = c, dd = d;
31+
32+
let j = 0u, base = i;
33+
while j < 16u {
34+
x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
35+
(msg[base + 2u] as u32 << 16u32) +
36+
(msg[base + 3u] as u32 << 24u32);
37+
j += 1u; base += 4u;
38+
}
39+
40+
let j = 0u;
41+
while j < 16u {
42+
a = rot(3, a + ((b & c) | (!b & d)) + x[j]);
43+
j += 1u;
44+
d = rot(7, d + ((a & b) | (!a & c)) + x[j]);
45+
j += 1u;
46+
c = rot(11, c + ((d & a) | (!d & b)) + x[j]);
47+
j += 1u;
48+
b = rot(19, b + ((c & d) | (!c & a)) + x[j]);
49+
j += 1u;
50+
}
51+
52+
let j = 0u, q = 0x5a827999u32;
53+
while j < 4u {
54+
a = rot(3, a + ((b & c) | ((b & d) | (c & d))) + x[j] + q);
55+
d = rot(5, d + ((a & b) | ((a & c) | (b & c))) + x[j + 4u] + q);
56+
c = rot(9, c + ((d & a) | ((d & b) | (a & b))) + x[j + 8u] + q);
57+
b = rot(13, b + ((c & d) | ((c & a) | (d & a))) + x[j + 12u] + q);
58+
j += 1u;
59+
}
60+
61+
let j = 0u, q = 0x6ed9eba1u32;
62+
while j < 8u {
63+
let jj = j > 2u ? j - 3u : j;
64+
a = rot(3, a + (b ^ c ^ d) + x[jj] + q);
65+
d = rot(9, d + (a ^ b ^ c) + x[jj + 8u] + q);
66+
c = rot(11, c + (d ^ a ^ b) + x[jj + 4u] + q);
67+
b = rot(15, b + (c ^ d ^ a) + x[jj + 12u] + q);
68+
j += 2u;
69+
}
70+
71+
a += aa; b += bb; c += cc; d += dd;
72+
i += 64u;
73+
}
74+
ret {a: a, b: b, c: c, d: d};
75+
}
76+
77+
fn md4_str(msg: [u8]) -> str {
78+
let {a, b, c, d} = md4(msg);
79+
fn app(a: u32, b: u32, c: u32, d: u32, f: block(u32)) {
80+
f(a); f(b); f(c); f(d);
81+
}
82+
let result = "";
83+
app(a, b, c, d) {|u|
84+
let i = 0u32;
85+
while i < 4u32 {
86+
let byte = (u >> (i * 8u32)) as u8;
87+
if byte <= 16u8 { result += "0"; }
88+
result += uint::to_str(byte as uint, 16u);
89+
i += 1u32;
90+
}
91+
}
92+
result
93+
}
94+
95+
fn md4_text(msg: str) -> str { md4_str(str::bytes(msg)) }
96+
97+
#[test]
98+
fn test_md4() {
99+
assert md4_text("") == "31d6cfe0d16ae931b73c59d7e0c089c0";
100+
assert md4_text("a") == "bde52cb31de33e46245e05fbdbd6fb24";
101+
assert md4_text("abc") == "a448017aaf21d8525fc10ae87aa6729d";
102+
assert md4_text("message digest") == "d9130a8164549fe818874806e1c7014b";
103+
assert md4_text("abcdefghijklmnopqrstuvwxyz") ==
104+
"d79e1c308aa5bbcdeea8ed63df412da9";
105+
assert md4_text("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123\
106+
456789") == "043f8582f241db351ce627e153e7f0e4";
107+
assert md4_text("12345678901234567890123456789012345678901234567890123456\
108+
789012345678901234567890") ==
109+
"e33b4ddc9c38f2199c3e7b164fcc0536";
110+
}

src/libstd/std.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ mod getopts;
5757
mod json;
5858
mod rand;
5959
mod sha1;
60+
mod md4;
6061
mod tempfile;
6162
mod term;
6263
mod time;

0 commit comments

Comments
 (0)