sha256加密

  1. //! SHA-2 (256 Bit)
  2. struct BufState {
  3. data: Vec<u8>,
  4. len: usize,
  5. total_len: usize,
  6. single: bool,
  7. total: bool,
  8. }
  9. pub fn sha256(data: &[u8]) -> [u8; 32] {
  10. let mut hash: [u8; 32] = [0; 32];
  11. let mut h: [u32; 8] = [
  12. 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
  13. 0x5be0cd19,
  14. ];
  15. let k: [u32; 64] = [
  16. 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
  17. 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
  18. 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
  19. 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
  20. 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
  21. 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
  22. 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
  23. 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  24. 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
  25. 0xc67178f2,
  26. ];
  27. let mut chunk: [u8; 64] = [0; 64];
  28. let mut state: BufState = BufState {
  29. data: (*data).to_owned(),
  30. len: data.len(),
  31. total_len: data.len(),
  32. single: false,
  33. total: false,
  34. };
  35. while calc_chunk(&mut chunk, &mut state) {
  36. let mut ah: [u32; 8] = h;
  37. let mut w: [u32; 16] = [0; 16];
  38. for i in 0..4 {
  39. for j in 0..16 {
  40. if i == 0 {
  41. w[j] = ((chunk[j * 4] as u32) << 24)
  42. | ((chunk[j * 4 + 1] as u32) << 16)
  43. | ((chunk[j * 4 + 2] as u32) << 8)
  44. | (chunk[j * 4 + 3] as u32);
  45. } else {
  46. let s0 = (w[(j + 1) & 0xf].rotate_right(7) ^ w[(j + 1) & 0xf].rotate_right(18))
  47. ^ (w[(j + 1) & 0xf] >> 3);
  48. let s1 = w[(j + 14) & 0xf].rotate_right(17)
  49. ^ w[(j + 14) & 0xf].rotate_right(19)
  50. ^ (w[(j + 14) & 0xf] >> 10);
  51. w[j] = w[j]
  52. .wrapping_add(s0)
  53. .wrapping_add(w[(j + 9) & 0xf])
  54. .wrapping_add(s1);
  55. }
  56. let s1: u32 =
  57. ah[4].rotate_right(6) ^ ah[4].rotate_right(11) ^ ah[4].rotate_right(25);
  58. let ch: u32 = (ah[4] & ah[5]) ^ (!ah[4] & ah[6]);
  59. let temp1: u32 = ah[7]
  60. .wrapping_add(s1)
  61. .wrapping_add(ch)
  62. .wrapping_add(k[i << 4 | j])
  63. .wrapping_add(w[j]);
  64. let s0: u32 =
  65. ah[0].rotate_right(2) ^ ah[0].rotate_right(13) ^ ah[0].rotate_right(22);
  66. let maj: u32 = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
  67. let temp2: u32 = s0.wrapping_add(maj);
  68. ah[7] = ah[6];
  69. ah[6] = ah[5];
  70. ah[5] = ah[4];
  71. ah[4] = ah[3].wrapping_add(temp1);
  72. ah[3] = ah[2];
  73. ah[2] = ah[1];
  74. ah[1] = ah[0];
  75. ah[0] = temp1.wrapping_add(temp2);
  76. }
  77. }
  78. for i in 0..8 {
  79. h[i] = h[i].wrapping_add(ah[i]);
  80. }
  81. chunk = [0; 64];
  82. }
  83. for i in 0..8 {
  84. hash[i * 4] = (h[i] >> 24) as u8;
  85. hash[i * 4 + 1] = (h[i] >> 16) as u8;
  86. hash[i * 4 + 2] = (h[i] >> 8) as u8;
  87. hash[i * 4 + 3] = h[i] as u8;
  88. }
  89. hash
  90. }
  91. fn calc_chunk(chunk: &mut [u8; 64], state: &mut BufState) -> bool {
  92. if state.total {
  93. return false;
  94. }
  95. if state.len >= 64 {
  96. for x in chunk {
  97. *x = state.data[0];
  98. state.data.remove(0);
  99. }
  100. state.len -= 64;
  101. return true;
  102. }
  103. let remaining: usize = state.data.len();
  104. let space: usize = 64 - remaining;
  105. for x in chunk.iter_mut().take(state.data.len()) {
  106. *x = state.data[0];
  107. state.data.remove(0);
  108. }
  109. if !state.single {
  110. chunk[remaining] = 0x80;
  111. state.single = true;
  112. }
  113. if space >= 8 {
  114. let mut len = state.total_len;
  115. chunk[63] = (len << 3) as u8;
  116. len >>= 5;
  117. for i in 1..8 {
  118. chunk[(63 - i)] = len as u8;
  119. len >>= 8;
  120. }
  121. state.total = true;
  122. }
  123. true
  124. }
  125. #[cfg(test)]
  126. mod tests {
  127. use super::*;
  128. #[test]
  129. fn empty() {
  130. assert_eq!(
  131. sha256(&Vec::new()),
  132. [
  133. 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f,
  134. 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b,
  135. 0x78, 0x52, 0xb8, 0x55
  136. ]
  137. );
  138. }
  139. #[test]
  140. fn ascii() {
  141. assert_eq!(
  142. sha256(&b"The quick brown fox jumps over the lazy dog".to_vec()),
  143. [
  144. 0xD7, 0xA8, 0xFB, 0xB3, 0x07, 0xD7, 0x80, 0x94, 0x69, 0xCA, 0x9A, 0xBC, 0xB0, 0x08,
  145. 0x2E, 0x4F, 0x8D, 0x56, 0x51, 0xE4, 0x6D, 0x3C, 0xDB, 0x76, 0x2D, 0x02, 0xD0, 0xBF,
  146. 0x37, 0xC9, 0xE5, 0x92
  147. ]
  148. )
  149. }
  150. #[test]
  151. fn ascii_avalanche() {
  152. assert_eq!(
  153. sha256(&b"The quick brown fox jumps over the lazy dog.".to_vec()),
  154. [
  155. 0xEF, 0x53, 0x7F, 0x25, 0xC8, 0x95, 0xBF, 0xA7, 0x82, 0x52, 0x65, 0x29, 0xA9, 0xB6,
  156. 0x3D, 0x97, 0xAA, 0x63, 0x15, 0x64, 0xD5, 0xD7, 0x89, 0xC2, 0xB7, 0x65, 0x44, 0x8C,
  157. 0x86, 0x35, 0xFB, 0x6C
  158. ]
  159. )
  160. }
  161. }