sha2_const_stable/lib.rs
1//! `const fn` implementation of the SHA-2 family of hash functions.
2//!
3//! This crate allows you to use the SHA-2 hash functions as constant
4//! expressions in Rust. For all other usages, the [`sha2`] crate includes more
5//! optimized implementations of these hash functions.
6//!
7//! [`sha2`]: https://crates.io/crates/sha2
8//!
9//! # Examples
10//!
11//! Compute the SHA-256 hash of the Bitcoin genesis block at compile time:
12//!
13//! ```rust
14//! # use sha2_const_stable::Sha256;
15//! const VERSION: u32 = 1;
16//! const HASH_PREV_BLOCK: [u8; 32] = [0; 32];
17//! const HASH_MERKLE_ROOT: [u8; 32] = [
18//! 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f,
19//! 0x61, 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e,
20//! 0x5e, 0x4a,
21//! ];
22//! const TIME: u32 = 1231006505;
23//! const BITS: u32 = 0x1d00ffff;
24//! const NONCE: u32 = 0x7c2bac1d;
25//!
26//! const BLOCK_HASH: [u8; 32] = Sha256::new()
27//! .update(
28//! &Sha256::new()
29//! .update(&VERSION.to_le_bytes())
30//! .update(&HASH_PREV_BLOCK)
31//! .update(&HASH_MERKLE_ROOT)
32//! .update(&TIME.to_le_bytes())
33//! .update(&BITS.to_le_bytes())
34//! .update(&NONCE.to_le_bytes())
35//! .finalize(),
36//! )
37//! .finalize();
38//!
39//! assert_eq!(
40//! hex::encode(&BLOCK_HASH[..]),
41//! "6fe28c0ab6f1b372c1a6a246ae63f74f931e8365e15a089c68d6190000000000"
42//! );
43//! ```
44#![no_std]
45
46mod constants;
47mod sha;
48mod util;
49
50use constants::{H224, H256, H384, H512, H512_224, H512_256};
51use util::memcpy;
52
53macro_rules! sha {
54 (
55 $(#[$doc:meta])* $name:ident,
56 $size:literal,
57 $inner:ty,
58 $iv:ident
59 ) => {
60 $(#[$doc])*
61 #[derive(Clone)]
62 pub struct $name {
63 inner: $inner,
64 }
65
66 impl $name {
67 /// The internal block size of the hash function.
68 pub const BLOCK_SIZE: usize = <$inner>::BLOCK_SIZE;
69 /// The digest size of the hash function.
70 pub const DIGEST_SIZE: usize = $size;
71
72 /// Construct a new instance.
73 pub const fn new() -> Self {
74 Self {
75 inner: <$inner>::new($iv),
76 }
77 }
78
79 /// Add input data to the hash context.
80 #[must_use]
81 pub const fn update(mut self, input: &[u8]) -> Self {
82 self.inner = self.inner.update(&input);
83 self
84 }
85
86 /// Finalize the context and compute the digest.
87 #[must_use]
88 pub const fn finalize(self) -> [u8; Self::DIGEST_SIZE] {
89 let digest = self.inner.finalize();
90 let mut truncated = [0; Self::DIGEST_SIZE];
91 truncated = memcpy(truncated, 0, &digest, 0, Self::DIGEST_SIZE);
92 truncated
93 }
94 }
95 };
96}
97
98sha!(
99 /// The SHA-224 hash function.
100 ///
101 /// The SHA-256 algorithm with the SHA-224 initialization vector, truncated
102 /// to 224 bits.
103 ///
104 /// # Examples
105 ///
106 /// ```rust
107 /// # use sha2_const_stable::Sha224;
108 /// const DIGEST: [u8; 28] = Sha224::new()
109 /// .update(b"The quick brown fox ")
110 /// .update(b"jumps over the lazy dog")
111 /// .finalize();
112 ///
113 /// assert_eq!(
114 /// hex::encode(&DIGEST[..]),
115 /// "730e109bd7a8a32b1cb9d9a09aa2325d2430587ddbc0c38bad911525"
116 /// );
117 /// ```
118 Sha224,
119 28,
120 sha::Sha256,
121 H224
122);
123
124sha!(
125 /// The SHA-256 hash function.
126 ///
127 /// # Examples
128 ///
129 /// ```rust
130 /// # use sha2_const_stable::Sha256;
131 /// const DIGEST: [u8; 32] = Sha256::new()
132 /// .update(b"The quick brown fox ")
133 /// .update(b"jumps over the lazy dog")
134 /// .finalize();
135 ///
136 /// assert_eq!(
137 /// hex::encode(&DIGEST[..]),
138 /// "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592"
139 /// );
140 /// ```
141 Sha256,
142 32,
143 sha::Sha256,
144 H256
145);
146
147sha!(
148 /// The SHA-384 hash function.
149 ///
150 /// The SHA-512 algorithm with the SHA-384 initialization vector, truncated
151 /// to 384 bits.
152 ///
153 /// # Examples
154 ///
155 /// ```rust
156 /// # use sha2_const_stable::Sha384;
157 /// const DIGEST: [u8; 48] = Sha384::new()
158 /// .update(b"The quick brown fox ")
159 /// .update(b"jumps over the lazy dog")
160 /// .finalize();
161 ///
162 /// assert_eq!(
163 /// hex::encode(&DIGEST[..]),
164 /// concat!(
165 /// "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c49",
166 /// "4011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1"
167 /// )
168 /// );
169 /// ```
170 Sha384,
171 48,
172 sha::Sha512,
173 H384
174);
175
176sha!(
177 /// The SHA-512 hash function.
178 ///
179 /// # Examples
180 ///
181 /// ```rust
182 /// # use sha2_const_stable::Sha512;
183 /// const DIGEST: [u8; 64] = Sha512::new()
184 /// .update(b"The quick brown fox ")
185 /// .update(b"jumps over the lazy dog")
186 /// .finalize();
187 ///
188 /// assert_eq!(
189 /// hex::encode(&DIGEST[..]),
190 /// concat!(
191 /// "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb64",
192 /// "2e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6"
193 /// )
194 /// );
195 /// ```
196 Sha512,
197 64,
198 sha::Sha512,
199 H512
200);
201
202sha!(
203 /// The SHA-512/224 hash function.
204 ///
205 /// The SHA-512 algorithm with the SHA-512/224 initialization vector,
206 /// truncated to 224 bits.
207 ///
208 /// # Examples
209 ///
210 /// ```rust
211 /// # use sha2_const_stable::Sha512_224;
212 /// const DIGEST: [u8; 28] = Sha512_224::new()
213 /// .update(b"The quick brown fox ")
214 /// .update(b"jumps over the lazy dog")
215 /// .finalize();
216 ///
217 /// assert_eq!(
218 /// hex::encode(&DIGEST[..]),
219 /// "944cd2847fb54558d4775db0485a50003111c8e5daa63fe722c6aa37"
220 /// );
221 /// ```
222 Sha512_224,
223 28,
224 sha::Sha512,
225 H512_224
226);
227
228sha!(
229 /// The SHA-512/256 hash function.
230 ///
231 /// The SHA-512 algorithm with the SHA-512/256 initialization vector,
232 /// truncated to 256 bits.
233 ///
234 /// # Examples
235 ///
236 /// ```rust
237 /// # use sha2_const_stable::Sha512_256;
238 /// const DIGEST: [u8; 32] = Sha512_256::new()
239 /// .update(b"The quick brown fox ")
240 /// .update(b"jumps over the lazy dog")
241 /// .finalize();
242 ///
243 /// assert_eq!(
244 /// hex::encode(&DIGEST[..]),
245 /// "dd9d67b371519c339ed8dbd25af90e976a1eeefd4ad3d889005e532fc5bef04d"
246 /// );
247 /// ```
248 Sha512_256,
249 32,
250 sha::Sha512,
251 H512_256
252);