-
-
Save rust-play/a055e762285b6882c251e6125988d8ca to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // --- CONSTANTS --- | |
| const SHA256_K: [u32; 64] = [ | |
| 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
| 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
| 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
| 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
| 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
| 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
| 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
| 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, | |
| ]; | |
| /// SHA-1 Implementation (Git-compliant) | |
| fn git_sha1(data: &[u8]) -> String { | |
| let mut h0: u32 = 0x67452301; let mut h1: u32 = 0xEFCDAB89; | |
| let mut h2: u32 = 0x98BADCFE; let mut h3: u32 = 0x10325476; | |
| let mut h4: u32 = 0xC3D2E1F0; | |
| let mut padded = data.to_vec(); | |
| let bit_len = (padded.len() as u64) * 8; | |
| padded.push(0x80); | |
| while (padded.len() * 8) % 512 != 448 { padded.push(0); } | |
| padded.extend_from_slice(&bit_len.to_be_bytes()); | |
| for chunk in padded.chunks(64) { | |
| let mut w = [0u32; 80]; | |
| for i in 0..16 { w[i] = u32::from_be_bytes([chunk[i*4], chunk[i*4+1], chunk[i*4+2], chunk[i*4+3]]); } | |
| for i in 16..80 { w[i] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]).rotate_left(1); } | |
| let (mut a, mut b, mut c, mut d, mut e) = (h0, h1, h2, h3, h4); | |
| for i in 0..80 { | |
| let (f, k) = match i { | |
| 0..=19 => ((b & c) | ((!b) & d), 0x5A827999), | |
| 20..=39 => (b ^ c ^ d, 0x6ED9EBA1), | |
| 40..=59 => ((b & c) | (b & d) | (c & d), 0x8F1BBCDC), | |
| _ => (b ^ c ^ d, 0xCA62C1D6), | |
| }; | |
| let temp = a.rotate_left(5).wrapping_add(f).wrapping_add(e).wrapping_add(k).wrapping_add(w[i]); | |
| e = d; d = c; c = b.rotate_left(30); b = a; a = temp; | |
| } | |
| h0 = h0.wrapping_add(a); h1 = h1.wrapping_add(b); | |
| h2 = h2.wrapping_add(c); h3 = h3.wrapping_add(d); h4 = h4.wrapping_add(e); | |
| } | |
| format!("{:08x}{:08x}{:08x}{:08x}{:08x}", h0, h1, h2, h3, h4) | |
| } | |
| /// SHA-256 Implementation | |
| fn sha256(data: &[u8]) -> String { | |
| let mut h: [u32; 8] = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]; | |
| let mut padded = data.to_vec(); | |
| let bit_len = (padded.len() as u64) * 8; | |
| padded.push(0x80); | |
| while (padded.len() * 8) % 512 != 448 { padded.push(0); } | |
| padded.extend_from_slice(&bit_len.to_be_bytes()); | |
| for chunk in padded.chunks(64) { | |
| let mut w = [0u32; 64]; | |
| for i in 0..16 { w[i] = u32::from_be_bytes([chunk[i*4], chunk[i*4+1], chunk[i*4+2], chunk[i*4+3]]); } | |
| for i in 16..64 { | |
| let s0 = w[i-15].rotate_right(7) ^ w[i-15].rotate_right(18) ^ (w[i-15] >> 3); | |
| let s1 = w[i-2].rotate_right(17) ^ w[i-2].rotate_right(19) ^ (w[i-2] >> 10); | |
| w[i] = w[i-16].wrapping_add(s0).wrapping_add(w[i-7]).wrapping_add(s1); | |
| } | |
| let [mut a, mut b, mut c, mut d, mut e, mut f, mut g, mut h_val] = h; | |
| for i in 0..64 { | |
| let s1 = e.rotate_right(6) ^ e.rotate_right(11) ^ e.rotate_right(25); | |
| let ch = (e & f) ^ ((!e) & g); | |
| let temp1 = h_val.wrapping_add(s1).wrapping_add(ch).wrapping_add(SHA256_K[i]).wrapping_add(w[i]); | |
| let s0 = a.rotate_right(2) ^ a.rotate_right(13) ^ a.rotate_right(22); | |
| let maj = (a & b) ^ (a & c) ^ (b & c); | |
| let temp2 = s0.wrapping_add(maj); | |
| h_val = g; g = f; f = e; e = d.wrapping_add(temp1); d = c; c = b; b = a; a = temp1.wrapping_add(temp2); | |
| } | |
| h = [h[0].wrapping_add(a), h[1].wrapping_add(b), h[2].wrapping_add(c), h[3].wrapping_add(d), | |
| h[4].wrapping_add(e), h[5].wrapping_add(f), h[6].wrapping_add(g), h[7].wrapping_add(h_val)]; | |
| } | |
| h.iter().map(|x| format!("{:08x}", x)).collect() | |
| } | |
| fn main() { | |
| let input = b"hello world"; | |
| println!("Input: \"hello world\""); | |
| println!("SHA-1: {}", git_sha1(input)); | |
| println!("SHA-256: {}", sha256(input)); | |
| } | |
| #[cfg(test)] | |
| mod tests { | |
| use super::*; | |
| #[test] | |
| fn test_sha1_standard() { | |
| assert_eq!(git_sha1(b"hello world"), "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed"); | |
| } | |
| #[test] | |
| fn test_sha256_standard() { | |
| assert_eq!(sha256(b"hello world"), "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment