sha2.rs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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::generic_array::typenum::U32;
  7. use digest::generic_array::typenum::U64;
  8. use digest::generic_array::GenericArray;
  9. use digest::BlockInput;
  10. use digest::FixedOutput;
  11. use digest::Input;
  12. use external::crypto_digest::get_256_bit_digest;
  13. use external::crypto_digest::get_512_bit_digest;
  14. use external::crypto_digest::CryptoDigest;
  15. use external::crypto_digest::DigestAlgorithm;
  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 {
  50. engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_256)),
  51. }
  52. }
  53. }
  54. impl BlockInput for Sha256 {
  55. type BlockSize = BlockSize;
  56. }
  57. /// Input `msg` into the digest.
  58. ///
  59. /// # Examples
  60. ///
  61. /// ```rust,no_run
  62. /// use crypto::digests::sha2::{Sha256, Digest};
  63. ///
  64. /// let mut hasher: Sha256 = Sha256::default();
  65. ///
  66. /// hasher.input(b"foo");
  67. /// hasher.input(b"bar");
  68. /// ```
  69. impl Input for Sha256 {
  70. fn process(&mut self, msg: &[u8]) {
  71. self.engine.add_bytes(&msg);
  72. }
  73. }
  74. /// Retrieve the output hash from everything which has been fed into this
  75. /// `Sha256` digest thus far.
  76. ///
  77. //
  78. // FIXME: Once const generics land in Rust, we should genericise calling
  79. // crypto_digest_get_digest in external::crypto_digest.
  80. impl FixedOutput for Sha256 {
  81. type OutputSize = U32;
  82. fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
  83. let buffer: [u8; DIGEST256_LEN] = get_256_bit_digest(self.engine);
  84. GenericArray::from(buffer)
  85. }
  86. }
  87. /// A SHA2-512 digest.
  88. ///
  89. /// # C_RUST_COUPLED
  90. ///
  91. /// * `crypto_digest_dup`
  92. #[derive(Clone)]
  93. pub struct Sha512 {
  94. engine: CryptoDigest,
  95. }
  96. /// Construct a new, default instance of a `Sha512` hash digest function.
  97. ///
  98. /// # Examples
  99. ///
  100. /// ```rust,no_run
  101. /// use crypto::digests::sha2::{Sha512, Digest};
  102. ///
  103. /// let mut hasher: Sha512 = Sha512::default();
  104. /// ```
  105. ///
  106. /// # Returns
  107. ///
  108. /// A new `Sha512` digest.
  109. impl Default for Sha512 {
  110. fn default() -> Sha512 {
  111. Sha512 {
  112. engine: CryptoDigest::new(Some(DigestAlgorithm::SHA2_512)),
  113. }
  114. }
  115. }
  116. impl BlockInput for Sha512 {
  117. type BlockSize = BlockSize;
  118. }
  119. /// Input `msg` into the digest.
  120. ///
  121. /// # Examples
  122. ///
  123. /// ```rust,no_run
  124. /// use crypto::digests::sha2::{Sha512, Digest};
  125. ///
  126. /// let mut hasher: Sha512 = Sha512::default();
  127. ///
  128. /// hasher.input(b"foo");
  129. /// hasher.input(b"bar");
  130. /// ```
  131. impl Input for Sha512 {
  132. fn process(&mut self, msg: &[u8]) {
  133. self.engine.add_bytes(&msg);
  134. }
  135. }
  136. /// Retrieve the output hash from everything which has been fed into this
  137. /// `Sha512` digest thus far.
  138. ///
  139. //
  140. // FIXME: Once const generics land in Rust, we should genericise calling
  141. // crypto_digest_get_digest in external::crypto_digest.
  142. impl FixedOutput for Sha512 {
  143. type OutputSize = U64;
  144. fn fixed_result(self) -> GenericArray<u8, Self::OutputSize> {
  145. let buffer: [u8; DIGEST512_LEN] = get_512_bit_digest(self.engine);
  146. GenericArray::clone_from_slice(&buffer)
  147. }
  148. }
  149. #[cfg(test)]
  150. mod test {
  151. #[cfg(feature = "test-c-from-rust")]
  152. use digest::Digest;
  153. #[cfg(feature = "test-c-from-rust")]
  154. use super::*;
  155. #[cfg(feature = "test-c-from-rust")]
  156. #[test]
  157. fn sha256_default() {
  158. let _: Sha256 = Sha256::default();
  159. }
  160. #[cfg(feature = "test-c-from-rust")]
  161. #[test]
  162. fn sha256_digest() {
  163. let mut h: Sha256 = Sha256::new();
  164. let mut result: [u8; DIGEST256_LEN] = [0u8; DIGEST256_LEN];
  165. let expected = [
  166. 151, 223, 53, 136, 181, 163, 242, 75, 171, 195, 133, 27, 55, 47, 11, 167, 26, 157, 205,
  167. 222, 212, 59, 20, 185, 208, 105, 97, 191, 193, 112, 125, 157,
  168. ];
  169. h.input(b"foo");
  170. h.input(b"bar");
  171. h.input(b"baz");
  172. result.copy_from_slice(h.fixed_result().as_slice());
  173. println!("{:?}", &result[..]);
  174. assert_eq!(result, expected);
  175. }
  176. #[cfg(feature = "test-c-from-rust")]
  177. #[test]
  178. fn sha512_default() {
  179. let _: Sha512 = Sha512::default();
  180. }
  181. #[cfg(feature = "test-c-from-rust")]
  182. #[test]
  183. fn sha512_digest() {
  184. let mut h: Sha512 = Sha512::new();
  185. let mut result: [u8; DIGEST512_LEN] = [0u8; DIGEST512_LEN];
  186. let expected = [
  187. 203, 55, 124, 16, 176, 245, 166, 44, 128, 54, 37, 167, 153, 217, 233, 8, 190, 69, 231,
  188. 103, 245, 209, 71, 212, 116, 73, 7, 203, 5, 89, 122, 164, 237, 211, 41, 160, 175, 20,
  189. 122, 221, 12, 244, 24, 30, 211, 40, 250, 30, 121, 148, 38, 88, 38, 179, 237, 61, 126,
  190. 246, 240, 103, 202, 153, 24, 90,
  191. ];
  192. h.input(b"foo");
  193. h.input(b"bar");
  194. h.input(b"baz");
  195. result.copy_from_slice(h.fixed_result().as_slice());
  196. println!("{:?}", &result[..]);
  197. assert_eq!(&result[..], &expected[..]);
  198. }
  199. }