sha2.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. /// ```
  39. /// use crypto::digest::Sha256;
  40. ///
  41. /// let 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. /// ```
  60. /// use crypto::digest::Sha256;
  61. ///
  62. /// let hasher: Sha256 = Sha256::default();
  63. ///
  64. /// hasher.process(b"foo");
  65. /// hasher.process(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. /// ```
  99. /// use crypto::digest::Sha512;
  100. ///
  101. /// let hasher: Sha256 = 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. /// ```
  120. /// use crypto::digest::Sha512;
  121. ///
  122. /// let hasher: Sha512 = Sha512::default();
  123. ///
  124. /// hasher.process(b"foo");
  125. /// hasher.process(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 = U32;
  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. h.input(b"foo");
  158. h.input(b"bar");
  159. h.input(b"baz");
  160. result.copy_from_slice(h.fixed_result().as_slice());
  161. println!("{:?}", &result[..]);
  162. assert_eq!(&result[..], &b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"[..]);
  163. }
  164. #[test]
  165. fn sha512_default() {
  166. let _: Sha512 = Sha512::default();
  167. }
  168. #[test]
  169. fn sha512_digest() {
  170. let mut h: Sha512 = Sha512::new();
  171. let mut result: [u8; DIGEST512_LEN] = [0u8; DIGEST512_LEN];
  172. h.input(b"foo");
  173. h.input(b"bar");
  174. h.input(b"baz");
  175. result.copy_from_slice(h.fixed_result().as_slice());
  176. println!("{:?}", &result[..]);
  177. assert_eq!(&result[..], &b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"[..]);
  178. }
  179. }