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);