cryptoxide/
sha2.rs

1//! An implementation of the SHA-2 cryptographic hash algorithms.
2//!
3//! There are 6 standard algorithms specified in the SHA-2 standard:
4//!
5//!  * `Sha224`, which is the 32-bit `Sha256` algorithm with the result truncated to 224 bits.
6//!  * `Sha256`, which is the 32-bit `Sha256` algorithm.
7//!  * `Sha384`, which is the 64-bit `Sha512` algorithm with the result truncated to 384 bits.
8//!  * `Sha512`, which is the 64-bit `Sha512` algorithm.
9//!  * `Sha512Trunc224`, which is the 64-bit `Sha512` algorithm with the result truncated to 224 bits.
10//!  * `Sha512Trunc256`, which is the 64-bit `Sha512` algorithm with the result truncated to 256 bits.
11//!
12//! Algorithmically, there are only 2 core algorithms: `Sha256` and `Sha512`.
13//! All other algorithms are just applications of these with different initial hash
14//! values, and truncated to different digest bit lengths.
15//!
16//! # Usage
17//!
18//! An example of using `Sha256` is:
19//!
20//! ```rust
21//! use self::cryptoxide::digest::Digest;
22//! use self::cryptoxide::sha2::Sha256;
23//!
24//! // create a Sha256 object
25//! let mut hasher = Sha256::new();
26//!
27//! // write input message
28//! hasher.input_str("hello world");
29//!
30//! // read hash digest
31//! let hex = hasher.result_str();
32//!
33//! assert_eq!(hex,
34//!            concat!("b94d27b9934d3e08a52e52d7da7dabfa",
35//!                    "c484efe37a5380ee9088f7ace2efcde9"));
36//! ```
37//!
38//! An example of using `Sha512` is:
39//!
40//! ```rust
41//! use self::cryptoxide::digest::Digest;
42//! use self::cryptoxide::sha2::Sha512;
43//!
44//! // create a Sha512 object
45//! let mut hasher = Sha512::new();
46//!
47//! // write input message
48//! hasher.input_str("hello world");
49//!
50//! // read hash digest
51//! let hex = hasher.result_str();
52//!
53//! assert_eq!(hex,
54//!            concat!("309ecc489c12d6eb4cc40f50c902f2b4",
55//!                    "d0ed77ee511a7c7a9bcd3ca86d4cd86f",
56//!                    "989dd35bc5ff499670da34255b45b0cf",
57//!                    "d830e81f605dcf7dc5542e93ae9cd76f"));
58//! ```
59
60use crate::digest::Digest;
61use crate::hashing::sha2;
62
63macro_rules! digest {
64    ($name: ident, $ctx: ident) => {
65        /// The hash algorithm context
66        #[derive(Clone)]
67        pub struct $name {
68            ctx: sha2::$ctx,
69            computed: bool,
70        }
71
72        impl $name {
73            /// Create a new hashing algorithm context
74            pub const fn new() -> Self {
75                Self {
76                    ctx: sha2::$ctx::new(),
77                    computed: false,
78                }
79            }
80        }
81
82        impl Digest for $name {
83            fn reset(&mut self) {
84                self.ctx.reset();
85                self.computed = false;
86            }
87            fn input(&mut self, msg: &[u8]) {
88                assert!(!self.computed, "context is already finalized, needs reset");
89                self.ctx.update_mut(msg);
90            }
91            fn result(&mut self, slice: &mut [u8]) {
92                assert!(!self.computed, "context is already finalized, needs reset");
93                self.computed = true;
94                slice.copy_from_slice(&self.ctx.finalize_reset());
95            }
96            fn output_bits(&self) -> usize {
97                sha2::$name::OUTPUT_BITS
98            }
99            fn block_size(&self) -> usize {
100                sha2::$name::BLOCK_BYTES
101            }
102        }
103    };
104}
105
106digest!(Sha512, Context512);
107digest!(Sha384, Context384);
108digest!(Sha512Trunc256, Context512_256);
109digest!(Sha512Trunc224, Context512_224);
110digest!(Sha256, Context256);
111digest!(Sha224, Context224);