diff --git a/src/main.rs b/src/main.rs index 6c3eeb0..040cc57 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,18 +1,23 @@ -mod sha256; +mod sha; fn main() { - - println!("Input is: \"\""); - println!("Expected is: 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); - sha256::sha256(""); - - println!("##########################################"); - println!("Input is: \"abc\""); - println!("Expected is: 0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); - sha256::sha256("abc"); - - println!("##########################################"); - println!("Input is: \"The quick brown fox jumps over the lazy dog\""); - println!("Expected is: 0xd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"); - sha256::sha256("The quick brown fox jumps over the lazy dog"); + test_sha(); } + +fn test_sha(){ + println!("Input: \"\""); + println!("Expected: 0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + println!("Result Hash: 0x{}", sha::sha256("".to_string())); + + println!("\n##########################################\n"); + + println!("Input: \"abc\""); + println!("Expected: 0xba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + println!("Result Hash: 0x{}", sha::sha256("abc".to_string())); + + println!("\n##########################################\n"); + + println!("Input: \"The quick brown fox jumps over the lazy dog\""); + println!("Expected: 0xd7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"); + println!("Result Hash: 0x{}", sha::sha256("The quick brown fox jumps over the lazy dog".to_string())); +} \ No newline at end of file diff --git a/src/sha256.rs b/src/sha/mod.rs similarity index 80% rename from src/sha256.rs rename to src/sha/mod.rs index 798ff99..809c4fe 100644 --- a/src/sha256.rs +++ b/src/sha/mod.rs @@ -1,5 +1,3 @@ -use std::str; - //////////// HELPER FUNCTIONS ///////////// fn ch(x: u32, y: u32, z: u32) -> u32 { let ret: u32 = (x & y) ^ (!x & z); @@ -31,7 +29,7 @@ fn ssig1(x: u32) -> u32 { return ret; } -fn pad_message(message: &str) -> Vec { +fn pad_message(message: String) -> Vec { let mut msg_bytes = message.as_bytes().to_vec(); let l = (msg_bytes.len() as u64) * 8; @@ -60,7 +58,9 @@ fn pad_message(message: &str) -> Vec { } //////////// END HELPER FUNCTIONS ///////////// -pub fn sha256(message: &str) { +pub fn sha256(message: String) -> String{ + + // Fill constants array with values const K: [u32; 64] = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, @@ -74,22 +74,28 @@ pub fn sha256(message: &str) { 0xc67178f2, ]; + // Set initial hash values let mut hash: [u32; 8] = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ]; - let msg_vec = pad_message(message); + // Pad message as required + let msg_vec: Vec = pad_message(message); + // Process each chunk 64 Byte of message vector for chunk in msg_vec.chunks(64) { + // Initialize temp variables and the word vector let mut w: Vec = Vec::with_capacity(64); let mut t1: u32; let mut t2: u32; + // Fill first 16 Byte of the word vector with the chunk values for t in 0..16 { w.push(chunk[t]); } + // Fill the remaining bytes with the calculated values from the word vector for t in 16..64 { w.push( ssig1(w[t - 2]) @@ -99,6 +105,7 @@ pub fn sha256(message: &str) { ); } + // Fill swapping variables with corresponding values. let mut a = hash[0]; let mut b = hash[1]; let mut c = hash[2]; @@ -108,6 +115,7 @@ pub fn sha256(message: &str) { let mut g = hash[6]; let mut h = hash[7]; + // Do the required shuffling while mixing in the word values from the message for t in 0..64 { t1 = h .wrapping_add(bsig1(e)) @@ -125,6 +133,7 @@ pub fn sha256(message: &str) { a = t1.wrapping_add(t2); } + // Add the swapping variable back into the hash array hash[0] = a.wrapping_add(hash[0]); hash[1] = b.wrapping_add(hash[1]); hash[2] = c.wrapping_add(hash[2]); @@ -133,14 +142,11 @@ pub fn sha256(message: &str) { hash[5] = f.wrapping_add(hash[5]); hash[6] = g.wrapping_add(hash[6]); hash[7] = h.wrapping_add(hash[7]); - } - - let sha256_str: String = hash - .iter() - .map(|&num| format!("{:X}", num)) // Use {:X} for uppercase hex, or {:x} for lowercase - .collect::>() // Collect into a vector of strings - .join(""); // Join with a space or any separator you prefer - - println!("Result Hash is: 0x{}", sha256_str); + } // End of chunk processing + // After processing the entire message concatenate the result into the final variable + return hash.iter() + .map(|&num| format!("{:08x}", num)) + .collect::>() + .join(""); }