sha2.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright (c) 2018, The Tor Project, Inc.
  2. // Copyright (c) 2018, isis agora lovecruft
  3. // See LICENSE for licensing information
  4. //! Hash Digests and eXtendible Output Functions (XOFs)
  5. pub use digest::Digest;
  6. use digest::BlockInput;
  7. use digest::FixedOutput;
  8. use digest::Input;
  9. use digest::generic_array::GenericArray;
  10. use digest::generic_array::typenum::U32;
  11. use digest::generic_array::typenum::U64;
  12. use external::crypto_digest::CryptoDigest;
  13. use external::crypto_digest::DigestAlgorithm;
  14. use external::crypto_digest::get_256_bit_digest;
  15. use external::crypto_digest::get_512_bit_digest;
  16. pub use external::crypto_digest::DIGEST256_LEN;
  17. pub use external::crypto_digest::DIGEST512_LEN;
  18. /// The block size for both SHA-256 and SHA-512 digests is 512 bits/64 bytes.
  19. ///
  20. /// Unfortunately, we have to use the generic_array crate currently to express
  21. /// this at compile time. Later, in the future, when Rust implements const
  22. /// generics, we'll be able to remove this dependency (actually, it will get
  23. /// removed from the digest crate, which is currently `pub use`ing it).
  24. type BlockSize = U64;
  25. /// A SHA2-256 digest.
  26. ///
  27. /// # C_RUST_COUPLED
  28. ///
  29. /// * `crypto_digest_dup`
  30. #[derive(Clone)]
  31. pub struct Sha256 {
  32. engine: CryptoDigest,
  33. }
  34. /// Construct a new, default instance of a `Sha256` hash digest function.
  35. ///
  36. /// # Examples
  37. ///
  38. /// ```rust,no_run
  39. /// use crypto::digests::sha2::{Sha256, Digest};
  40. ///
  41. /// let mut hasher: Sha256 = Sha256::default();
  42. /// ```
  43. ///
  44. /// # Returns
  45. ///
  46. /// A new `Sha256` digest.
  47. impl Default for Sha256 {
  48. fn default() -> Sha256 {
  49. Sha256{ engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_256)) }
  50. }
  51. }
  52. impl BlockInput for Sha256 {
  53. type BlockSize = BlockSize;
  54. }
  55. /// Input `msg` into the digest.
  56. ///
  57. /// # Examples
  58. ///
  59. /// ```rust,no_run
  60. /// use crypto::digests::sha2::{Sha256, Digest};
  61. ///
  62. /// let mut hasher: Sha256 = Sha256::default();
  63. ///
  64. /// hasher.input(b"foo");
  65. /// hasher.input(b"bar");
  66. /// ```
  67. impl Input for Sha256 {
  68. fn process(&mut self, msg: &[u8]) {
  69. self.engine.add_bytes(&msg);
  70. }
  71. }
  72. /// Retrieve the output hash from everything which has been fed into this
  73. /// `Sha256` digest thus far.
  74. ///
  75. //
  76. // FIXME: Once const generics land in Rust, we should genericise calling
  77. // crypto_digest_get_digest in external::crypto_digest.
  78. impl FixedOutput for Sha256 {
  79. type OutputSize = U32;
  80. fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
  81. let buffer: [u8; DIGEST256_LEN] = get_256_bit_digest(self.engine);
  82. GenericArray::from(buffer)
  83. }
  84. }
  85. /// A SHA2-512 digest.
  86. ///
  87. /// # C_RUST_COUPLED
  88. ///
  89. /// * `crypto_digest_dup`
  90. #[derive(Clone)]
  91. pub struct Sha512 {
  92. engine: CryptoDigest,
  93. }
  94. /// Construct a new, default instance of a `Sha512` hash digest function.
  95. ///
  96. /// # Examples
  97. ///
  98. /// ```rust,no_run
  99. /// use crypto::digests::sha2::{Sha512, Digest};
  100. ///
  101. /// let mut hasher: Sha512 = Sha512::default();
  102. /// ```
  103. ///
  104. /// # Returns
  105. ///
  106. /// A new `Sha512` digest.
  107. impl Default for Sha512 {
  108. fn default() -> Sha512 {
  109. Sha512{ engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_512)) }
  110. }
  111. }
  112. impl BlockInput for Sha512 {
  113. type BlockSize = BlockSize;
  114. }
  115. /// Input `msg` into the digest.
  116. ///
  117. /// # Examples
  118. ///
  119. /// ```rust,no_run
  120. /// use crypto::digests::sha2::{Sha512, Digest};
  121. ///
  122. /// let mut hasher: Sha512 = Sha512::default();
  123. ///
  124. /// hasher.input(b"foo");
  125. /// hasher.input(b"bar");
  126. /// ```
  127. impl Input for Sha512 {
  128. fn process(&mut self, msg: &[u8]) {
  129. self.engine.add_bytes(&msg);
  130. }
  131. }
  132. /// Retrieve the output hash from everything which has been fed into this
  133. /// `Sha512` digest thus far.
  134. ///
  135. //
  136. // FIXME: Once const generics land in Rust, we should genericise calling
  137. // crypto_digest_get_digest in external::crypto_digest.
  138. impl FixedOutput for Sha512 {
  139. type OutputSize = U64;
  140. fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
  141. let buffer: [u8; DIGEST512_LEN] = get_512_bit_digest(self.engine);
  142. GenericArray::clone_from_slice(&buffer)
  143. }
  144. }
  145. #[cfg(test)]
  146. mod test {
  147. use digest::Digest;
  148. use super::*;
  149. #[test]
  150. fn sha256_default() {
  151. let _: Sha256 = Sha256::default();
  152. }
  153. #[test]
  154. fn sha256_digest() {
  155. let mut h: Sha256 = Sha256::new();
  156. let mut result: [u8; DIGEST256_LEN] = [0u8; DIGEST256_LEN];
  157. let expected = [151, 223, 53, 136, 181, 163, 242, 75, 171, 195,
  158. 133, 27, 55, 47, 11, 167, 26, 157, 205, 222, 212,
  159. 59, 20, 185, 208, 105, 97, 191, 193, 112, 125, 157];
  160. h.input(b"foo");
  161. h.input(b"bar");
  162. h.input(b"baz");
  163. result.copy_from_slice(h.fixed_result().as_slice());
  164. println!("{:?}", &result[..]);
  165. assert_eq!(result, expected);
  166. }
  167. #[test]
  168. fn sha512_default() {
  169. let _: Sha512 = Sha512::default();
  170. }
  171. #[test]
  172. fn sha512_digest() {
  173. let mut h: Sha512 = Sha512::new();
  174. let mut result: [u8; DIGEST512_LEN] = [0u8; DIGEST512_LEN];
  175. let expected = [203, 55, 124, 16, 176, 245, 166, 44, 128, 54, 37, 167,
  176. 153, 217, 233, 8, 190, 69, 231, 103, 245, 209, 71, 212, 116,
  177. 73, 7, 203, 5, 89, 122, 164, 237, 211, 41, 160, 175, 20, 122,
  178. 221, 12, 244, 24, 30, 211, 40, 250, 30, 121, 148, 38, 88, 38,
  179. 179, 237, 61, 126, 246, 240, 103, 202, 153, 24, 90];
  180. h.input(b"foo");
  181. h.input(b"bar");
  182. h.input(b"baz");
  183. result.copy_from_slice(h.fixed_result().as_slice());
  184. println!("{:?}", &result[..]);
  185. assert_eq!(&result[..], &expected[..]);
  186. }
  187. }