diff options
| author | Marijn Haverbeke <[email protected]> | 2011-05-06 22:13:13 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <[email protected]> | 2011-05-06 22:51:19 +0200 |
| commit | a3ec0b1f643d00b9418e4884bd7caa07bf052201 (patch) | |
| tree | 82000510ac9c9cf3f0c7cf4ae5f3c6b123b559cb /src/lib/sha1.rs | |
| parent | Register new snapshots. (diff) | |
| download | rust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.tar.xz rust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.zip | |
Rename std modules to be camelcased
(Have fun mergining your stuff with this.)
Diffstat (limited to 'src/lib/sha1.rs')
| -rw-r--r-- | src/lib/sha1.rs | 294 |
1 files changed, 0 insertions, 294 deletions
diff --git a/src/lib/sha1.rs b/src/lib/sha1.rs deleted file mode 100644 index e84787a2..00000000 --- a/src/lib/sha1.rs +++ /dev/null @@ -1,294 +0,0 @@ -/* - * A SHA-1 implementation derived from Paul E. Jones's reference - * implementation, which is written for clarity, not speed. At some - * point this will want to be rewritten. - */ - -export sha1; -export mk_sha1; - -state type sha1 = state obj { - // Provide message input as bytes - fn input(&vec[u8]); - - // Provide message input as string - fn input_str(&str); - - // Read the digest as a vector of 20 bytes. After - // calling this no further input may provided - // until reset is called - fn result() -> vec[u8]; - - // Same as above, just a hex-string version. - fn result_str() -> str; - - // Reset the sha1 state for reuse. This is called - // automatically during construction - fn reset(); -}; - -// Some unexported constants -const uint digest_buf_len = 5; -const uint msg_block_len = 64; - -// Builds a sha1 object -fn mk_sha1() -> sha1 { - - state type sha1state = rec(vec[mutable u32] h, - mutable u32 len_low, - mutable u32 len_high, - vec[mutable u8] msg_block, - mutable uint msg_block_idx, - mutable bool computed); - - fn add_input(&sha1state st, &vec[u8] msg) { - // FIXME: Should be typestate precondition - assert (!st.computed); - - for (u8 element in msg) { - st.msg_block.(st.msg_block_idx) = element; - st.msg_block_idx += 1u; - - st.len_low += 8u32; - if (st.len_low == 0u32) { - st.len_high += 1u32; - if (st.len_high == 0u32) { - // FIXME: Need better failure mode - fail; - } - } - - if (st.msg_block_idx == msg_block_len) { - process_msg_block(st); - } - } - } - - fn process_msg_block(&sha1state st) { - - // FIXME: Make precondition - assert (_vec.len(st.h) == digest_buf_len); - - // Constants - auto k = vec(0x5A827999u32, - 0x6ED9EBA1u32, - 0x8F1BBCDCu32, - 0xCA62C1D6u32); - - let int t; // Loop counter - let vec[mutable u32] w = _vec.init_elt_mut[u32](0u32, 80u); - - // Initialize the first 16 words of the vector w - t = 0; - while (t < 16) { - w.(t) = (st.msg_block.(t * 4) as u32) << 24u32; - w.(t) = w.(t) | ((st.msg_block.(t * 4 + 1) as u32) << 16u32); - w.(t) = w.(t) | ((st.msg_block.(t * 4 + 2) as u32) << 8u32); - w.(t) = w.(t) | (st.msg_block.(t * 4 + 3) as u32); - t += 1; - } - - // Initialize the rest of vector w - while (t < 80) { - auto val = w.(t-3) ^ w.(t-8) ^ w.(t-14) ^ w.(t-16); - w.(t) = circular_shift(1u32, val); - t += 1; - } - - auto a = st.h.(0); - auto b = st.h.(1); - auto c = st.h.(2); - auto d = st.h.(3); - auto e = st.h.(4); - - let u32 temp; - - t = 0; - while (t < 20) { - temp = circular_shift(5u32, a) - + ((b & c) | ((~b) & d)) + e + w.(t) + k.(0); - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - - while (t < 40) { - temp = circular_shift(5u32, a) - + (b ^ c ^ d) + e + w.(t) + k.(1); - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - - while (t < 60) { - temp = circular_shift(5u32, a) - + ((b & c) | (b & d) | (c & d)) + e + w.(t) + k.(2); - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - - while (t < 80) { - temp = circular_shift(5u32, a) - + (b ^ c ^ d) + e + w.(t) + k.(3); - e = d; - d = c; - c = circular_shift(30u32, b); - b = a; - a = temp; - t += 1; - } - - st.h.(0) = st.h.(0) + a; - st.h.(1) = st.h.(1) + b; - st.h.(2) = st.h.(2) + c; - st.h.(3) = st.h.(3) + d; - st.h.(4) = st.h.(4) + e; - - st.msg_block_idx = 0u; - } - - fn circular_shift(u32 bits, u32 word) -> u32 { - // FIXME: This is a workaround for a rustboot - // "unrecognized quads" codegen bug - auto bits_hack = bits; - ret (word << bits_hack) | (word >> (32u32 - bits)); - } - - fn mk_result(&sha1state st) -> vec[u8] { - if (!st.computed) { - pad_msg(st); - st.computed = true; - } - - let vec[u8] res = vec(); - for (u32 hpart in st.h) { - auto a = (hpart >> 24u32) & 0xFFu32 as u8; - auto b = (hpart >> 16u32) & 0xFFu32 as u8; - auto c = (hpart >> 8u32) & 0xFFu32 as u8; - auto d = (hpart & 0xFFu32 as u8); - res += vec(a,b,c,d); - } - ret res; - } - - /* - * According to the standard, the message must be padded to an even - * 512 bits. The first padding bit must be a '1'. The last 64 bits - * represent the length of the original message. All bits in between - * should be 0. This function will pad the message according to those - * rules by filling the msg_block vector accordingly. It will also - * call process_msg_block() appropriately. When it returns, it - * can be assumed that the message digest has been computed. - */ - fn pad_msg(&sha1state st) { - // FIXME: Should be a precondition - assert (_vec.len(st.msg_block) == msg_block_len); - - /* - * Check to see if the current message block is too small to hold - * the initial padding bits and length. If so, we will pad the - * block, process it, and then continue padding into a second block. - */ - if (st.msg_block_idx > 55u) { - st.msg_block.(st.msg_block_idx) = 0x80u8; - st.msg_block_idx += 1u; - - while (st.msg_block_idx < msg_block_len) { - st.msg_block.(st.msg_block_idx) = 0u8; - st.msg_block_idx += 1u; - } - - process_msg_block(st); - } else { - st.msg_block.(st.msg_block_idx) = 0x80u8; - st.msg_block_idx += 1u; - } - - while (st.msg_block_idx < 56u) { - st.msg_block.(st.msg_block_idx) = 0u8; - st.msg_block_idx += 1u; - } - - // Store the message length as the last 8 octets - st.msg_block.(56) = (st.len_high >> 24u32) & 0xFFu32 as u8; - st.msg_block.(57) = (st.len_high >> 16u32) & 0xFFu32 as u8; - st.msg_block.(58) = (st.len_high >> 8u32) & 0xFFu32 as u8; - st.msg_block.(59) = st.len_high & 0xFFu32 as u8; - st.msg_block.(60) = (st.len_low >> 24u32) & 0xFFu32 as u8; - st.msg_block.(61) = (st.len_low >> 16u32) & 0xFFu32 as u8; - st.msg_block.(62) = (st.len_low >> 8u32) & 0xFFu32 as u8; - st.msg_block.(63) = st.len_low & 0xFFu32 as u8; - - process_msg_block(st); - } - - state obj sha1(sha1state st) { - - fn reset() { - // FIXME: Should be typestate precondition - assert (_vec.len(st.h) == digest_buf_len); - - st.len_low = 0u32; - st.len_high = 0u32; - st.msg_block_idx = 0u; - - st.h.(0) = 0x67452301u32; - st.h.(1) = 0xEFCDAB89u32; - st.h.(2) = 0x98BADCFEu32; - st.h.(3) = 0x10325476u32; - st.h.(4) = 0xC3D2E1F0u32; - - st.computed = false; - } - - fn input(&vec[u8] msg) { - add_input(st, msg); - } - - fn input_str(&str msg) { - add_input(st, _str.bytes(msg)); - } - - fn result() -> vec[u8] { - ret mk_result(st); - } - - fn result_str() -> str { - auto r = mk_result(st); - auto s = ""; - for (u8 b in r) { - s += _uint.to_str(b as uint, 16u); - } - ret s; - } - } - - auto st = rec(h = _vec.init_elt_mut[u32](0u32, digest_buf_len), - mutable len_low = 0u32, - mutable len_high = 0u32, - msg_block = _vec.init_elt_mut[u8](0u8, msg_block_len), - mutable msg_block_idx = 0u, - mutable computed = false); - auto sh = sha1(st); - sh.reset(); - ret sh; -} - -// Local Variables: -// mode: rust; -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; -// End: |