PageRenderTime 85ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libstd/md4.rs

http://github.com/eholk/rust
Rust | 115 lines | 97 code | 13 blank | 5 comment | 16 complexity | 80d19be08b2742043c099606f6cd09c3 MD5 | raw file
Possible License(s): AGPL-1.0, BSD-2-Clause, 0BSD, Apache-2.0, MIT, LGPL-2.0
  1. fn md4(msg: [u8]) -> {a: u32, b: u32, c: u32, d: u32} {
  2. // subtle: if orig_len is merely uint, then the code below
  3. // which performs shifts by 32 bits or more has undefined
  4. // results.
  5. let orig_len: u64 = (vec::len(msg) * 8u) as u64;
  6. // pad message
  7. let msg = msg + [0x80u8];
  8. let bitlen = orig_len + 8u64;
  9. while (bitlen + 64u64) % 512u64 > 0u64 {
  10. msg += [0u8];
  11. bitlen += 8u64;
  12. }
  13. // append length
  14. let i = 0u64;
  15. while i < 8u64 {
  16. msg += [(orig_len >> (i * 8u64)) as u8];
  17. i += 1u64;
  18. }
  19. let a = 0x67452301u32;
  20. let b = 0xefcdab89u32;
  21. let c = 0x98badcfeu32;
  22. let d = 0x10325476u32;
  23. fn rot(r: int, x: u32) -> u32 {
  24. let r = r as u32;
  25. (x << r) | (x >> (32u32 - r))
  26. }
  27. let i = 0u, e = vec::len(msg);
  28. let x = vec::init_elt_mut(16u, 0u32);
  29. while i < e {
  30. let aa = a, bb = b, cc = c, dd = d;
  31. let j = 0u, base = i;
  32. while j < 16u {
  33. x[j] = (msg[base] as u32) + (msg[base + 1u] as u32 << 8u32) +
  34. (msg[base + 2u] as u32 << 16u32) +
  35. (msg[base + 3u] as u32 << 24u32);
  36. j += 1u; base += 4u;
  37. }
  38. let j = 0u;
  39. while j < 16u {
  40. a = rot(3, a + ((b & c) | (!b & d)) + x[j]);
  41. j += 1u;
  42. d = rot(7, d + ((a & b) | (!a & c)) + x[j]);
  43. j += 1u;
  44. c = rot(11, c + ((d & a) | (!d & b)) + x[j]);
  45. j += 1u;
  46. b = rot(19, b + ((c & d) | (!c & a)) + x[j]);
  47. j += 1u;
  48. }
  49. let j = 0u, q = 0x5a827999u32;
  50. while j < 4u {
  51. a = rot(3, a + ((b & c) | ((b & d) | (c & d))) + x[j] + q);
  52. d = rot(5, d + ((a & b) | ((a & c) | (b & c))) + x[j + 4u] + q);
  53. c = rot(9, c + ((d & a) | ((d & b) | (a & b))) + x[j + 8u] + q);
  54. b = rot(13, b + ((c & d) | ((c & a) | (d & a))) + x[j + 12u] + q);
  55. j += 1u;
  56. }
  57. let j = 0u, q = 0x6ed9eba1u32;
  58. while j < 8u {
  59. let jj = if j > 2u { j - 3u } else { j };
  60. a = rot(3, a + (b ^ c ^ d) + x[jj] + q);
  61. d = rot(9, d + (a ^ b ^ c) + x[jj + 8u] + q);
  62. c = rot(11, c + (d ^ a ^ b) + x[jj + 4u] + q);
  63. b = rot(15, b + (c ^ d ^ a) + x[jj + 12u] + q);
  64. j += 2u;
  65. }
  66. a += aa; b += bb; c += cc; d += dd;
  67. i += 64u;
  68. }
  69. ret {a: a, b: b, c: c, d: d};
  70. }
  71. fn md4_str(msg: [u8]) -> str {
  72. let {a, b, c, d} = md4(msg);
  73. fn app(a: u32, b: u32, c: u32, d: u32, f: fn(u32)) {
  74. f(a); f(b); f(c); f(d);
  75. }
  76. let result = "";
  77. app(a, b, c, d) {|u|
  78. let i = 0u32;
  79. while i < 4u32 {
  80. let byte = (u >> (i * 8u32)) as u8;
  81. if byte <= 16u8 { result += "0"; }
  82. result += uint::to_str(byte as uint, 16u);
  83. i += 1u32;
  84. }
  85. }
  86. result
  87. }
  88. fn md4_text(msg: str) -> str { md4_str(str::bytes(msg)) }
  89. #[test]
  90. fn test_md4() {
  91. assert md4_text("") == "31d6cfe0d16ae931b73c59d7e0c089c0";
  92. assert md4_text("a") == "bde52cb31de33e46245e05fbdbd6fb24";
  93. assert md4_text("abc") == "a448017aaf21d8525fc10ae87aa6729d";
  94. assert md4_text("message digest") == "d9130a8164549fe818874806e1c7014b";
  95. assert md4_text("abcdefghijklmnopqrstuvwxyz") ==
  96. "d79e1c308aa5bbcdeea8ed63df412da9";
  97. assert md4_text("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123\
  98. 456789") == "043f8582f241db351ce627e153e7f0e4";
  99. assert md4_text("12345678901234567890123456789012345678901234567890123456\
  100. 789012345678901234567890") ==
  101. "e33b4ddc9c38f2199c3e7b164fcc0536";
  102. }