chf/
sha256.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! SHA-256 implementation.
4
5#[cfg(all(feature = "std", target_arch = "x86"))]
6use core::arch::x86::*;
7#[cfg(all(feature = "std", target_arch = "x86_64"))]
8use core::arch::x86_64::*;
9use core::ops::Index;
10use core::slice::SliceIndex;
11use core::str;
12
13use crate::{FromSliceError, HashEngine};
14
15crate::internal_macros::hash_type! {
16    256,
17    "Output of the SHA-256 hash function."
18}
19
20/// Length of the SHA-256 hash's internal block size, in bytes.
21pub const BLOCK_SIZE: usize = 64;
22
23/// Engine to compute SHA-256 hash function.
24#[derive(Clone)]
25pub struct Engine {
26    buffer: [u8; BLOCK_SIZE],
27    h: [u32; 8],
28    length: usize,
29}
30
31impl Default for Engine {
32    fn default() -> Self {
33        Engine {
34            h: [
35                0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
36                0x5be0cd19,
37            ],
38            length: 0,
39            buffer: [0; BLOCK_SIZE],
40        }
41    }
42}
43
44impl HashEngine for Engine {
45    type Digest = [u8; 32];
46    type Midstate = Midstate;
47    const BLOCK_SIZE: usize = BLOCK_SIZE;
48
49    #[inline]
50    fn n_bytes_hashed(&self) -> usize { self.length }
51
52    crate::internal_macros::engine_input_impl!(32);
53
54    #[cfg(not(hashes_fuzz))]
55    #[inline]
56    fn finalize(mut self) -> Self::Digest {
57        // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
58        let data_len = self.length as u64;
59
60        let zeroes = [0; BLOCK_SIZE - 8];
61        self.input(&[0x80]);
62        if self.length % BLOCK_SIZE > zeroes.len() {
63            self.input(&zeroes);
64        }
65        let pad_length = zeroes.len() - (self.length % BLOCK_SIZE);
66        self.input(&zeroes[..pad_length]);
67        debug_assert_eq!(self.length % BLOCK_SIZE, zeroes.len());
68
69        self.input(&(8 * data_len).to_be_bytes());
70        debug_assert_eq!(self.length % BLOCK_SIZE, 0);
71
72        self.midstate().to_byte_array()
73    }
74
75    #[cfg(hashes_fuzz)]
76    fn finalize(mut self) -> Self::Digest {
77        let mut hash = e.midstate().to_byte_array();
78        if hash == [0; 32] {
79            // Assume sha256 is secure and never generate 0-hashes (which represent invalid
80            // secp256k1 secret keys, causing downstream application breakage).
81            hash[0] = 1;
82        }
83        hash
84    }
85
86    #[cfg(not(hashes_fuzz))]
87    #[inline]
88    fn midstate(&self) -> Midstate {
89        let mut ret = [0; 32];
90        for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
91            ret_bytes.copy_from_slice(&val.to_be_bytes());
92        }
93        Midstate(ret)
94    }
95
96    #[cfg(hashes_fuzz)]
97    fn midstate(&self) -> Midstate {
98        let mut ret = [0; 32];
99        ret.copy_from_slice(&self.buffer[..32]);
100        Midstate(ret)
101    }
102
103    #[inline]
104    fn from_midstate(midstate: Midstate, length: usize) -> Engine {
105        assert!(length % BLOCK_SIZE == 0, "length is no multiple of the block size");
106
107        let mut ret = [0; 8];
108        for (ret_val, midstate_bytes) in ret.iter_mut().zip(midstate[..].chunks_exact(4)) {
109            *ret_val = u32::from_be_bytes(midstate_bytes.try_into().expect("4 byte slice"));
110        }
111
112        Engine { buffer: [0; BLOCK_SIZE], h: ret, length }
113    }
114}
115
116impl Hash {
117    /// Computes hash from `bytes` in `const` context.
118    ///
119    /// Warning: this function is inefficient. It should be only used in `const` context.
120    pub const fn const_hash(bytes: &[u8]) -> Self { Hash(Midstate::const_hash(bytes, true).0) }
121}
122
123/// Output of the SHA-256 hash function.
124#[derive(Copy, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
125pub struct Midstate(pub [u8; 32]);
126
127crate::internal_macros::arr_newtype_fmt_impl!(Midstate, 32);
128serde_impl!(Midstate, 32);
129crate::internal_macros::as_ref_impl!(Midstate);
130
131impl<I: SliceIndex<[u8]>> Index<I> for Midstate {
132    type Output = I::Output;
133
134    #[inline]
135    fn index(&self, index: I) -> &Self::Output { &self.0[index] }
136}
137
138impl str::FromStr for Midstate {
139    type Err = hex::HexToArrayError;
140    fn from_str(s: &str) -> Result<Self, Self::Err> { hex::FromHex::from_hex(s) }
141}
142
143impl Midstate {
144    /// Length of the midstate, in bytes.
145    const LEN: usize = 32;
146
147    /// Construct a new [`Midstate`] from the inner value.
148    pub const fn from_byte_array(inner: [u8; 32]) -> Self { Midstate(inner) }
149
150    /// Copies a byte slice into the [`Midstate`] object.
151    pub fn from_slice(sl: &[u8]) -> Result<Midstate, FromSliceError> {
152        if sl.len() != Self::LEN {
153            Err(FromSliceError { expected: Self::LEN, got: sl.len() })
154        } else {
155            let mut ret = [0; 32];
156            ret.copy_from_slice(sl);
157            Ok(Midstate(ret))
158        }
159    }
160
161    /// Unwraps the [`Midstate`] and returns the underlying byte array.
162    pub fn to_byte_array(self) -> [u8; 32] { self.0 }
163
164    /// Creates midstate for tagged hashes.
165    ///
166    /// Warning: this function is inefficient. It should be only used in `const` context.
167    ///
168    /// Computes non-finalized hash of `sha256(tag) || sha256(tag)` for use in Bitcoin tagged hashes.
169    pub const fn hash_tag(tag: &[u8]) -> Self {
170        let hash = Hash::const_hash(tag);
171        let mut buf = [0u8; 64];
172        let mut i = 0usize;
173        while i < buf.len() {
174            buf[i] = hash.0[i % hash.0.len()];
175            i += 1;
176        }
177        Self::const_hash(&buf, false)
178    }
179}
180
181impl hex::FromHex for Midstate {
182    type Error = hex::HexToArrayError;
183
184    fn from_hex(s: &str) -> Result<Self, Self::Error> {
185        let bytes = <[u8; 32]>::from_hex(s)?;
186        Ok(Midstate(bytes))
187    }
188}
189
190#[allow(non_snake_case)]
191const fn Ch(x: u32, y: u32, z: u32) -> u32 { z ^ (x & (y ^ z)) }
192#[allow(non_snake_case)]
193const fn Maj(x: u32, y: u32, z: u32) -> u32 { (x & y) | (z & (x | y)) }
194#[allow(non_snake_case)]
195const fn Sigma0(x: u32) -> u32 { x.rotate_left(30) ^ x.rotate_left(19) ^ x.rotate_left(10) }
196#[allow(non_snake_case)]
197const fn Sigma1(x: u32) -> u32 { x.rotate_left(26) ^ x.rotate_left(21) ^ x.rotate_left(7) }
198const fn sigma0(x: u32) -> u32 { x.rotate_left(25) ^ x.rotate_left(14) ^ (x >> 3) }
199const fn sigma1(x: u32) -> u32 { x.rotate_left(15) ^ x.rotate_left(13) ^ (x >> 10) }
200
201#[cfg(feature = "small-hash")]
202#[macro_use]
203mod small_hash {
204    use super::*;
205
206    #[rustfmt::skip]
207    pub(super) const fn round(a: u32, b: u32, c: u32, d: u32, e: u32,
208                              f: u32, g: u32, h: u32, k: u32, w: u32) -> (u32, u32) {
209        let t1 =
210            h.wrapping_add(Sigma1(e)).wrapping_add(Ch(e, f, g)).wrapping_add(k).wrapping_add(w);
211        let t2 = Sigma0(a).wrapping_add(Maj(a, b, c));
212        (d.wrapping_add(t1), t1.wrapping_add(t2))
213    }
214    #[rustfmt::skip]
215    pub(super) const fn later_round(a: u32, b: u32, c: u32, d: u32, e: u32,
216                                    f: u32, g: u32, h: u32, k: u32, w: u32,
217                                    w1: u32, w2: u32, w3: u32,
218    ) -> (u32, u32, u32) {
219        let w = w.wrapping_add(sigma1(w1)).wrapping_add(w2).wrapping_add(sigma0(w3));
220        let (d, h) = round(a, b, c, d, e, f, g, h, k, w);
221        (d, h, w)
222    }
223
224    macro_rules! round(
225        // first round
226        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
227            let updates = small_hash::round($a, $b, $c, $d, $e, $f, $g, $h, $k, $w);
228            $d = updates.0;
229            $h = updates.1;
230        );
231        // later rounds we reassign $w before doing the first-round computation
232        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr, $w1:expr, $w2:expr, $w3:expr) => (
233            let updates = small_hash::later_round($a, $b, $c, $d, $e, $f, $g, $h, $k, $w, $w1, $w2, $w3);
234            $d = updates.0;
235            $h = updates.1;
236            $w = updates.2;
237        )
238    );
239}
240
241#[cfg(not(feature = "small-hash"))]
242#[macro_use]
243mod fast_hash {
244    macro_rules! round(
245        // first round
246        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
247            let t1 = $h.wrapping_add(Sigma1($e)).wrapping_add(Ch($e, $f, $g)).wrapping_add($k).wrapping_add($w);
248            let t2 = Sigma0($a).wrapping_add(Maj($a, $b, $c));
249            $d = $d.wrapping_add(t1);
250            $h = t1.wrapping_add(t2);
251        );
252        // later rounds we reassign $w before doing the first-round computation
253        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr, $w1:expr, $w2:expr, $w3:expr) => (
254            $w = $w.wrapping_add(sigma1($w1)).wrapping_add($w2).wrapping_add(sigma0($w3));
255            round!($a, $b, $c, $d, $e, $f, $g, $h, $k, $w);
256        )
257    );
258}
259
260impl Midstate {
261    #[allow(clippy::identity_op)] // more readble
262    const fn read_u32(bytes: &[u8], index: usize) -> u32 {
263        ((bytes[index + 0] as u32) << 24)
264            | ((bytes[index + 1] as u32) << 16)
265            | ((bytes[index + 2] as u32) << 8)
266            | ((bytes[index + 3] as u32) << 0)
267    }
268
269    const fn copy_w(bytes: &[u8], index: usize) -> [u32; 16] {
270        let mut w = [0u32; 16];
271        let mut i = 0;
272        while i < 16 {
273            w[i] = Self::read_u32(bytes, index + i * 4);
274            i += 1;
275        }
276        w
277    }
278
279    const fn const_hash(bytes: &[u8], finalize: bool) -> Self {
280        let mut state = [
281            0x6a09e667u32,
282            0xbb67ae85,
283            0x3c6ef372,
284            0xa54ff53a,
285            0x510e527f,
286            0x9b05688c,
287            0x1f83d9ab,
288            0x5be0cd19,
289        ];
290
291        let num_chunks = (bytes.len() + 9 + 63) / 64;
292        let mut chunk = 0;
293        #[allow(clippy::precedence)]
294        while chunk < num_chunks {
295            if !finalize && chunk + 1 == num_chunks {
296                break;
297            }
298            let mut w = if chunk * 64 + 64 <= bytes.len() {
299                Self::copy_w(bytes, chunk * 64)
300            } else {
301                let mut buf = [0; 64];
302                let mut i = 0;
303                let offset = chunk * 64;
304                while offset + i < bytes.len() {
305                    buf[i] = bytes[offset + i];
306                    i += 1;
307                }
308                if (bytes.len() % 64 <= 64 - 9) || (chunk + 2 == num_chunks) {
309                    buf[i] = 0x80;
310                }
311                #[allow(clippy::identity_op)] // more readble
312                #[allow(clippy::erasing_op)]
313                if chunk + 1 == num_chunks {
314                    let bit_len = bytes.len() as u64 * 8;
315                    buf[64 - 8] = ((bit_len >> 8 * 7) & 0xFF) as u8;
316                    buf[64 - 7] = ((bit_len >> 8 * 6) & 0xFF) as u8;
317                    buf[64 - 6] = ((bit_len >> 8 * 5) & 0xFF) as u8;
318                    buf[64 - 5] = ((bit_len >> 8 * 4) & 0xFF) as u8;
319                    buf[64 - 4] = ((bit_len >> 8 * 3) & 0xFF) as u8;
320                    buf[64 - 3] = ((bit_len >> 8 * 2) & 0xFF) as u8;
321                    buf[64 - 2] = ((bit_len >> 8 * 1) & 0xFF) as u8;
322                    buf[64 - 1] = ((bit_len >> 8 * 0) & 0xFF) as u8;
323                }
324                Self::copy_w(&buf, 0)
325            };
326            chunk += 1;
327
328            let mut a = state[0];
329            let mut b = state[1];
330            let mut c = state[2];
331            let mut d = state[3];
332            let mut e = state[4];
333            let mut f = state[5];
334            let mut g = state[6];
335            let mut h = state[7];
336
337            round!(a, b, c, d, e, f, g, h, 0x428a2f98, w[0]);
338            round!(h, a, b, c, d, e, f, g, 0x71374491, w[1]);
339            round!(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w[2]);
340            round!(f, g, h, a, b, c, d, e, 0xe9b5dba5, w[3]);
341            round!(e, f, g, h, a, b, c, d, 0x3956c25b, w[4]);
342            round!(d, e, f, g, h, a, b, c, 0x59f111f1, w[5]);
343            round!(c, d, e, f, g, h, a, b, 0x923f82a4, w[6]);
344            round!(b, c, d, e, f, g, h, a, 0xab1c5ed5, w[7]);
345            round!(a, b, c, d, e, f, g, h, 0xd807aa98, w[8]);
346            round!(h, a, b, c, d, e, f, g, 0x12835b01, w[9]);
347            round!(g, h, a, b, c, d, e, f, 0x243185be, w[10]);
348            round!(f, g, h, a, b, c, d, e, 0x550c7dc3, w[11]);
349            round!(e, f, g, h, a, b, c, d, 0x72be5d74, w[12]);
350            round!(d, e, f, g, h, a, b, c, 0x80deb1fe, w[13]);
351            round!(c, d, e, f, g, h, a, b, 0x9bdc06a7, w[14]);
352            round!(b, c, d, e, f, g, h, a, 0xc19bf174, w[15]);
353
354            round!(a, b, c, d, e, f, g, h, 0xe49b69c1, w[0], w[14], w[9], w[1]);
355            round!(h, a, b, c, d, e, f, g, 0xefbe4786, w[1], w[15], w[10], w[2]);
356            round!(g, h, a, b, c, d, e, f, 0x0fc19dc6, w[2], w[0], w[11], w[3]);
357            round!(f, g, h, a, b, c, d, e, 0x240ca1cc, w[3], w[1], w[12], w[4]);
358            round!(e, f, g, h, a, b, c, d, 0x2de92c6f, w[4], w[2], w[13], w[5]);
359            round!(d, e, f, g, h, a, b, c, 0x4a7484aa, w[5], w[3], w[14], w[6]);
360            round!(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w[6], w[4], w[15], w[7]);
361            round!(b, c, d, e, f, g, h, a, 0x76f988da, w[7], w[5], w[0], w[8]);
362            round!(a, b, c, d, e, f, g, h, 0x983e5152, w[8], w[6], w[1], w[9]);
363            round!(h, a, b, c, d, e, f, g, 0xa831c66d, w[9], w[7], w[2], w[10]);
364            round!(g, h, a, b, c, d, e, f, 0xb00327c8, w[10], w[8], w[3], w[11]);
365            round!(f, g, h, a, b, c, d, e, 0xbf597fc7, w[11], w[9], w[4], w[12]);
366            round!(e, f, g, h, a, b, c, d, 0xc6e00bf3, w[12], w[10], w[5], w[13]);
367            round!(d, e, f, g, h, a, b, c, 0xd5a79147, w[13], w[11], w[6], w[14]);
368            round!(c, d, e, f, g, h, a, b, 0x06ca6351, w[14], w[12], w[7], w[15]);
369            round!(b, c, d, e, f, g, h, a, 0x14292967, w[15], w[13], w[8], w[0]);
370
371            round!(a, b, c, d, e, f, g, h, 0x27b70a85, w[0], w[14], w[9], w[1]);
372            round!(h, a, b, c, d, e, f, g, 0x2e1b2138, w[1], w[15], w[10], w[2]);
373            round!(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w[2], w[0], w[11], w[3]);
374            round!(f, g, h, a, b, c, d, e, 0x53380d13, w[3], w[1], w[12], w[4]);
375            round!(e, f, g, h, a, b, c, d, 0x650a7354, w[4], w[2], w[13], w[5]);
376            round!(d, e, f, g, h, a, b, c, 0x766a0abb, w[5], w[3], w[14], w[6]);
377            round!(c, d, e, f, g, h, a, b, 0x81c2c92e, w[6], w[4], w[15], w[7]);
378            round!(b, c, d, e, f, g, h, a, 0x92722c85, w[7], w[5], w[0], w[8]);
379            round!(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w[8], w[6], w[1], w[9]);
380            round!(h, a, b, c, d, e, f, g, 0xa81a664b, w[9], w[7], w[2], w[10]);
381            round!(g, h, a, b, c, d, e, f, 0xc24b8b70, w[10], w[8], w[3], w[11]);
382            round!(f, g, h, a, b, c, d, e, 0xc76c51a3, w[11], w[9], w[4], w[12]);
383            round!(e, f, g, h, a, b, c, d, 0xd192e819, w[12], w[10], w[5], w[13]);
384            round!(d, e, f, g, h, a, b, c, 0xd6990624, w[13], w[11], w[6], w[14]);
385            round!(c, d, e, f, g, h, a, b, 0xf40e3585, w[14], w[12], w[7], w[15]);
386            round!(b, c, d, e, f, g, h, a, 0x106aa070, w[15], w[13], w[8], w[0]);
387
388            round!(a, b, c, d, e, f, g, h, 0x19a4c116, w[0], w[14], w[9], w[1]);
389            round!(h, a, b, c, d, e, f, g, 0x1e376c08, w[1], w[15], w[10], w[2]);
390            round!(g, h, a, b, c, d, e, f, 0x2748774c, w[2], w[0], w[11], w[3]);
391            round!(f, g, h, a, b, c, d, e, 0x34b0bcb5, w[3], w[1], w[12], w[4]);
392            round!(e, f, g, h, a, b, c, d, 0x391c0cb3, w[4], w[2], w[13], w[5]);
393            round!(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w[5], w[3], w[14], w[6]);
394            round!(c, d, e, f, g, h, a, b, 0x5b9cca4f, w[6], w[4], w[15], w[7]);
395            round!(b, c, d, e, f, g, h, a, 0x682e6ff3, w[7], w[5], w[0], w[8]);
396            round!(a, b, c, d, e, f, g, h, 0x748f82ee, w[8], w[6], w[1], w[9]);
397            round!(h, a, b, c, d, e, f, g, 0x78a5636f, w[9], w[7], w[2], w[10]);
398            round!(g, h, a, b, c, d, e, f, 0x84c87814, w[10], w[8], w[3], w[11]);
399            round!(f, g, h, a, b, c, d, e, 0x8cc70208, w[11], w[9], w[4], w[12]);
400            round!(e, f, g, h, a, b, c, d, 0x90befffa, w[12], w[10], w[5], w[13]);
401            round!(d, e, f, g, h, a, b, c, 0xa4506ceb, w[13], w[11], w[6], w[14]);
402            round!(c, d, e, f, g, h, a, b, 0xbef9a3f7, w[14], w[12], w[7], w[15]);
403            round!(b, c, d, e, f, g, h, a, 0xc67178f2, w[15], w[13], w[8], w[0]);
404
405            state[0] = state[0].wrapping_add(a);
406            state[1] = state[1].wrapping_add(b);
407            state[2] = state[2].wrapping_add(c);
408            state[3] = state[3].wrapping_add(d);
409            state[4] = state[4].wrapping_add(e);
410            state[5] = state[5].wrapping_add(f);
411            state[6] = state[6].wrapping_add(g);
412            state[7] = state[7].wrapping_add(h);
413        }
414        let mut output = [0u8; 32];
415        let mut i = 0;
416        #[allow(clippy::identity_op)] // more readble
417        while i < 8 {
418            output[i * 4 + 0] = (state[i + 0] >> 24) as u8;
419            output[i * 4 + 1] = (state[i + 0] >> 16) as u8;
420            output[i * 4 + 2] = (state[i + 0] >> 8) as u8;
421            output[i * 4 + 3] = (state[i + 0] >> 0) as u8;
422            i += 1;
423        }
424        Midstate(output)
425    }
426}
427
428impl Engine {
429    /// Create a new [`Engine`] from a [`Midstate`].
430    ///
431    /// # Panics
432    ///
433    /// If `length` is not a multiple of the block size.
434    pub fn from_midstate(midstate: Midstate, length: usize) -> Engine {
435        assert!(length % BLOCK_SIZE == 0, "length is no multiple of the block size");
436
437        let mut ret = [0; 8];
438        for (ret_val, midstate_bytes) in ret.iter_mut().zip(midstate[..].chunks_exact(4)) {
439            *ret_val = u32::from_be_bytes(midstate_bytes.try_into().expect("4 byte slice"));
440        }
441
442        Engine { buffer: [0; BLOCK_SIZE], h: ret, length }
443    }
444
445    fn process_block(&mut self) {
446        #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
447        {
448            if is_x86_feature_detected!("sse4.1")
449                && is_x86_feature_detected!("sha")
450                && is_x86_feature_detected!("sse2")
451                && is_x86_feature_detected!("ssse3")
452            {
453                return unsafe { self.process_block_simd_x86_intrinsics() };
454            }
455        }
456
457        // fallback implementation without using any intrinsics
458        self.software_process_block()
459    }
460
461    #[cfg(all(feature = "std", any(target_arch = "x86", target_arch = "x86_64")))]
462    #[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
463    unsafe fn process_block_simd_x86_intrinsics(&mut self) {
464        // Code translated and based on from
465        // https://github.com/noloader/SHA-Intrinsics/blob/4899efc81d1af159c1fd955936c673139f35aea9/sha256-x86.c
466
467        /* sha256-x86.c - Intel SHA extensions using C intrinsics  */
468        /*   Written and place in public domain by Jeffrey Walton  */
469        /*   Based on code from Intel, and by Sean Gulley for      */
470        /*   the miTLS project.                                    */
471
472        // Variable names are also kept the same as in the original C code for easier comparison.
473        let (mut state0, mut state1);
474        let (mut msg, mut tmp);
475
476        let (mut msg0, mut msg1, mut msg2, mut msg3);
477
478        let (abef_save, cdgh_save);
479
480        #[allow(non_snake_case)]
481        let MASK: __m128i =
482            _mm_set_epi64x(0x0c0d_0e0f_0809_0a0bu64 as i64, 0x0405_0607_0001_0203u64 as i64);
483
484        let block_offset = 0;
485
486        // Load initial values
487        // CAST SAFETY: loadu_si128 documentation states that mem_addr does not
488        // need to be aligned on any particular boundary.
489        tmp = _mm_loadu_si128(self.h.as_ptr().add(0) as *const __m128i);
490        state1 = _mm_loadu_si128(self.h.as_ptr().add(4) as *const __m128i);
491
492        tmp = _mm_shuffle_epi32(tmp, 0xB1); // CDAB
493        state1 = _mm_shuffle_epi32(state1, 0x1B); // EFGH
494        state0 = _mm_alignr_epi8(tmp, state1, 8); // ABEF
495        state1 = _mm_blend_epi16(state1, tmp, 0xF0); // CDGH
496
497        // Process a single block
498        {
499            // Save current state
500            abef_save = state0;
501            cdgh_save = state1;
502
503            // Rounds 0-3
504            msg = _mm_loadu_si128(self.buffer.as_ptr().add(block_offset) as *const __m128i);
505            msg0 = _mm_shuffle_epi8(msg, MASK);
506            msg = _mm_add_epi32(
507                msg0,
508                _mm_set_epi64x(0xE9B5DBA5B5C0FBCFu64 as i64, 0x71374491428A2F98u64 as i64),
509            );
510            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
511            msg = _mm_shuffle_epi32(msg, 0x0E);
512            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
513
514            // Rounds 4-7
515            msg1 = _mm_loadu_si128(self.buffer.as_ptr().add(block_offset + 16) as *const __m128i);
516            msg1 = _mm_shuffle_epi8(msg1, MASK);
517            msg = _mm_add_epi32(
518                msg1,
519                _mm_set_epi64x(0xAB1C5ED5923F82A4u64 as i64, 0x59F111F13956C25Bu64 as i64),
520            );
521            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
522            msg = _mm_shuffle_epi32(msg, 0x0E);
523            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
524            msg0 = _mm_sha256msg1_epu32(msg0, msg1);
525
526            // Rounds 8-11
527            msg2 = _mm_loadu_si128(self.buffer.as_ptr().add(block_offset + 32) as *const __m128i);
528            msg2 = _mm_shuffle_epi8(msg2, MASK);
529            msg = _mm_add_epi32(
530                msg2,
531                _mm_set_epi64x(0x550C7DC3243185BEu64 as i64, 0x12835B01D807AA98u64 as i64),
532            );
533            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
534            msg = _mm_shuffle_epi32(msg, 0x0E);
535            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
536            msg1 = _mm_sha256msg1_epu32(msg1, msg2);
537
538            // Rounds 12-15
539            msg3 = _mm_loadu_si128(self.buffer.as_ptr().add(block_offset + 48) as *const __m128i);
540            msg3 = _mm_shuffle_epi8(msg3, MASK);
541            msg = _mm_add_epi32(
542                msg3,
543                _mm_set_epi64x(0xC19BF1749BDC06A7u64 as i64, 0x80DEB1FE72BE5D74u64 as i64),
544            );
545            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
546            tmp = _mm_alignr_epi8(msg3, msg2, 4);
547            msg0 = _mm_add_epi32(msg0, tmp);
548            msg0 = _mm_sha256msg2_epu32(msg0, msg3);
549            msg = _mm_shuffle_epi32(msg, 0x0E);
550            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
551            msg2 = _mm_sha256msg1_epu32(msg2, msg3);
552
553            // Rounds 16-19
554            msg = _mm_add_epi32(
555                msg0,
556                _mm_set_epi64x(0x240CA1CC0FC19DC6u64 as i64, 0xEFBE4786E49B69C1u64 as i64),
557            );
558            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
559            tmp = _mm_alignr_epi8(msg0, msg3, 4);
560            msg1 = _mm_add_epi32(msg1, tmp);
561            msg1 = _mm_sha256msg2_epu32(msg1, msg0);
562            msg = _mm_shuffle_epi32(msg, 0x0E);
563            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
564            msg3 = _mm_sha256msg1_epu32(msg3, msg0);
565
566            // Rounds 20-23
567            msg = _mm_add_epi32(
568                msg1,
569                _mm_set_epi64x(0x76F988DA5CB0A9DCu64 as i64, 0x4A7484AA2DE92C6Fu64 as i64),
570            );
571            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
572            tmp = _mm_alignr_epi8(msg1, msg0, 4);
573            msg2 = _mm_add_epi32(msg2, tmp);
574            msg2 = _mm_sha256msg2_epu32(msg2, msg1);
575            msg = _mm_shuffle_epi32(msg, 0x0E);
576            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
577            msg0 = _mm_sha256msg1_epu32(msg0, msg1);
578
579            // Rounds 24-27
580            msg = _mm_add_epi32(
581                msg2,
582                _mm_set_epi64x(0xBF597FC7B00327C8u64 as i64, 0xA831C66D983E5152u64 as i64),
583            );
584            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
585            tmp = _mm_alignr_epi8(msg2, msg1, 4);
586            msg3 = _mm_add_epi32(msg3, tmp);
587            msg3 = _mm_sha256msg2_epu32(msg3, msg2);
588            msg = _mm_shuffle_epi32(msg, 0x0E);
589            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
590            msg1 = _mm_sha256msg1_epu32(msg1, msg2);
591
592            // Rounds 28-31
593            msg = _mm_add_epi32(
594                msg3,
595                _mm_set_epi64x(0x1429296706CA6351u64 as i64, 0xD5A79147C6E00BF3u64 as i64),
596            );
597            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
598            tmp = _mm_alignr_epi8(msg3, msg2, 4);
599            msg0 = _mm_add_epi32(msg0, tmp);
600            msg0 = _mm_sha256msg2_epu32(msg0, msg3);
601            msg = _mm_shuffle_epi32(msg, 0x0E);
602            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
603            msg2 = _mm_sha256msg1_epu32(msg2, msg3);
604
605            // Rounds 32-35
606            msg = _mm_add_epi32(
607                msg0,
608                _mm_set_epi64x(0x53380D134D2C6DFCu64 as i64, 0x2E1B213827B70A85u64 as i64),
609            );
610            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
611            tmp = _mm_alignr_epi8(msg0, msg3, 4);
612            msg1 = _mm_add_epi32(msg1, tmp);
613            msg1 = _mm_sha256msg2_epu32(msg1, msg0);
614            msg = _mm_shuffle_epi32(msg, 0x0E);
615            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
616            msg3 = _mm_sha256msg1_epu32(msg3, msg0);
617
618            // Rounds 36-39
619            msg = _mm_add_epi32(
620                msg1,
621                _mm_set_epi64x(0x92722C8581C2C92Eu64 as i64, 0x766A0ABB650A7354u64 as i64),
622            );
623            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
624            tmp = _mm_alignr_epi8(msg1, msg0, 4);
625            msg2 = _mm_add_epi32(msg2, tmp);
626            msg2 = _mm_sha256msg2_epu32(msg2, msg1);
627            msg = _mm_shuffle_epi32(msg, 0x0E);
628            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
629            msg0 = _mm_sha256msg1_epu32(msg0, msg1);
630
631            // Rounds 40-43
632            msg = _mm_add_epi32(
633                msg2,
634                _mm_set_epi64x(0xC76C51A3C24B8B70u64 as i64, 0xA81A664BA2BFE8A1u64 as i64),
635            );
636            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
637            tmp = _mm_alignr_epi8(msg2, msg1, 4);
638            msg3 = _mm_add_epi32(msg3, tmp);
639            msg3 = _mm_sha256msg2_epu32(msg3, msg2);
640            msg = _mm_shuffle_epi32(msg, 0x0E);
641            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
642            msg1 = _mm_sha256msg1_epu32(msg1, msg2);
643
644            // Rounds 44-47
645            msg = _mm_add_epi32(
646                msg3,
647                _mm_set_epi64x(0x106AA070F40E3585u64 as i64, 0xD6990624D192E819u64 as i64),
648            );
649            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
650            tmp = _mm_alignr_epi8(msg3, msg2, 4);
651            msg0 = _mm_add_epi32(msg0, tmp);
652            msg0 = _mm_sha256msg2_epu32(msg0, msg3);
653            msg = _mm_shuffle_epi32(msg, 0x0E);
654            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
655            msg2 = _mm_sha256msg1_epu32(msg2, msg3);
656
657            // Rounds 48-51
658            msg = _mm_add_epi32(
659                msg0,
660                _mm_set_epi64x(0x34B0BCB52748774Cu64 as i64, 0x1E376C0819A4C116u64 as i64),
661            );
662            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
663            tmp = _mm_alignr_epi8(msg0, msg3, 4);
664            msg1 = _mm_add_epi32(msg1, tmp);
665            msg1 = _mm_sha256msg2_epu32(msg1, msg0);
666            msg = _mm_shuffle_epi32(msg, 0x0E);
667            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
668            msg3 = _mm_sha256msg1_epu32(msg3, msg0);
669
670            // Rounds 52-55
671            msg = _mm_add_epi32(
672                msg1,
673                _mm_set_epi64x(0x682E6FF35B9CCA4Fu64 as i64, 0x4ED8AA4A391C0CB3u64 as i64),
674            );
675            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
676            tmp = _mm_alignr_epi8(msg1, msg0, 4);
677            msg2 = _mm_add_epi32(msg2, tmp);
678            msg2 = _mm_sha256msg2_epu32(msg2, msg1);
679            msg = _mm_shuffle_epi32(msg, 0x0E);
680            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
681
682            // Rounds 56-59
683            msg = _mm_add_epi32(
684                msg2,
685                _mm_set_epi64x(0x8CC7020884C87814u64 as i64, 0x78A5636F748F82EEu64 as i64),
686            );
687            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
688            tmp = _mm_alignr_epi8(msg2, msg1, 4);
689            msg3 = _mm_add_epi32(msg3, tmp);
690            msg3 = _mm_sha256msg2_epu32(msg3, msg2);
691            msg = _mm_shuffle_epi32(msg, 0x0E);
692            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
693
694            // Rounds 60-63
695            msg = _mm_add_epi32(
696                msg3,
697                _mm_set_epi64x(0xC67178F2BEF9A3F7u64 as i64, 0xA4506CEB90BEFFFAu64 as i64),
698            );
699            state1 = _mm_sha256rnds2_epu32(state1, state0, msg);
700            msg = _mm_shuffle_epi32(msg, 0x0E);
701            state0 = _mm_sha256rnds2_epu32(state0, state1, msg);
702
703            // Combine state
704            state0 = _mm_add_epi32(state0, abef_save);
705            state1 = _mm_add_epi32(state1, cdgh_save);
706        }
707
708        tmp = _mm_shuffle_epi32(state0, 0x1B); // FEBA
709        state1 = _mm_shuffle_epi32(state1, 0xB1); // DCHG
710        state0 = _mm_blend_epi16(tmp, state1, 0xF0); // DCBA
711        state1 = _mm_alignr_epi8(state1, tmp, 8); // ABEF
712
713        // Save state
714        // CAST SAFETY: storeu_si128 documentation states that mem_addr does not
715        // need to be aligned on any particular boundary.
716        _mm_storeu_si128(self.h.as_mut_ptr().add(0) as *mut __m128i, state0);
717        _mm_storeu_si128(self.h.as_mut_ptr().add(4) as *mut __m128i, state1);
718    }
719
720    // Algorithm copied from libsecp256k1
721    fn software_process_block(&mut self) {
722        debug_assert_eq!(self.buffer.len(), BLOCK_SIZE);
723
724        let mut w = [0u32; 16];
725        for (w_val, buff_bytes) in w.iter_mut().zip(self.buffer.chunks_exact(4)) {
726            *w_val = u32::from_be_bytes(buff_bytes.try_into().expect("4 byte slice"));
727        }
728
729        let mut a = self.h[0];
730        let mut b = self.h[1];
731        let mut c = self.h[2];
732        let mut d = self.h[3];
733        let mut e = self.h[4];
734        let mut f = self.h[5];
735        let mut g = self.h[6];
736        let mut h = self.h[7];
737
738        round!(a, b, c, d, e, f, g, h, 0x428a2f98, w[0]);
739        round!(h, a, b, c, d, e, f, g, 0x71374491, w[1]);
740        round!(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w[2]);
741        round!(f, g, h, a, b, c, d, e, 0xe9b5dba5, w[3]);
742        round!(e, f, g, h, a, b, c, d, 0x3956c25b, w[4]);
743        round!(d, e, f, g, h, a, b, c, 0x59f111f1, w[5]);
744        round!(c, d, e, f, g, h, a, b, 0x923f82a4, w[6]);
745        round!(b, c, d, e, f, g, h, a, 0xab1c5ed5, w[7]);
746        round!(a, b, c, d, e, f, g, h, 0xd807aa98, w[8]);
747        round!(h, a, b, c, d, e, f, g, 0x12835b01, w[9]);
748        round!(g, h, a, b, c, d, e, f, 0x243185be, w[10]);
749        round!(f, g, h, a, b, c, d, e, 0x550c7dc3, w[11]);
750        round!(e, f, g, h, a, b, c, d, 0x72be5d74, w[12]);
751        round!(d, e, f, g, h, a, b, c, 0x80deb1fe, w[13]);
752        round!(c, d, e, f, g, h, a, b, 0x9bdc06a7, w[14]);
753        round!(b, c, d, e, f, g, h, a, 0xc19bf174, w[15]);
754
755        round!(a, b, c, d, e, f, g, h, 0xe49b69c1, w[0], w[14], w[9], w[1]);
756        round!(h, a, b, c, d, e, f, g, 0xefbe4786, w[1], w[15], w[10], w[2]);
757        round!(g, h, a, b, c, d, e, f, 0x0fc19dc6, w[2], w[0], w[11], w[3]);
758        round!(f, g, h, a, b, c, d, e, 0x240ca1cc, w[3], w[1], w[12], w[4]);
759        round!(e, f, g, h, a, b, c, d, 0x2de92c6f, w[4], w[2], w[13], w[5]);
760        round!(d, e, f, g, h, a, b, c, 0x4a7484aa, w[5], w[3], w[14], w[6]);
761        round!(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w[6], w[4], w[15], w[7]);
762        round!(b, c, d, e, f, g, h, a, 0x76f988da, w[7], w[5], w[0], w[8]);
763        round!(a, b, c, d, e, f, g, h, 0x983e5152, w[8], w[6], w[1], w[9]);
764        round!(h, a, b, c, d, e, f, g, 0xa831c66d, w[9], w[7], w[2], w[10]);
765        round!(g, h, a, b, c, d, e, f, 0xb00327c8, w[10], w[8], w[3], w[11]);
766        round!(f, g, h, a, b, c, d, e, 0xbf597fc7, w[11], w[9], w[4], w[12]);
767        round!(e, f, g, h, a, b, c, d, 0xc6e00bf3, w[12], w[10], w[5], w[13]);
768        round!(d, e, f, g, h, a, b, c, 0xd5a79147, w[13], w[11], w[6], w[14]);
769        round!(c, d, e, f, g, h, a, b, 0x06ca6351, w[14], w[12], w[7], w[15]);
770        round!(b, c, d, e, f, g, h, a, 0x14292967, w[15], w[13], w[8], w[0]);
771
772        round!(a, b, c, d, e, f, g, h, 0x27b70a85, w[0], w[14], w[9], w[1]);
773        round!(h, a, b, c, d, e, f, g, 0x2e1b2138, w[1], w[15], w[10], w[2]);
774        round!(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w[2], w[0], w[11], w[3]);
775        round!(f, g, h, a, b, c, d, e, 0x53380d13, w[3], w[1], w[12], w[4]);
776        round!(e, f, g, h, a, b, c, d, 0x650a7354, w[4], w[2], w[13], w[5]);
777        round!(d, e, f, g, h, a, b, c, 0x766a0abb, w[5], w[3], w[14], w[6]);
778        round!(c, d, e, f, g, h, a, b, 0x81c2c92e, w[6], w[4], w[15], w[7]);
779        round!(b, c, d, e, f, g, h, a, 0x92722c85, w[7], w[5], w[0], w[8]);
780        round!(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w[8], w[6], w[1], w[9]);
781        round!(h, a, b, c, d, e, f, g, 0xa81a664b, w[9], w[7], w[2], w[10]);
782        round!(g, h, a, b, c, d, e, f, 0xc24b8b70, w[10], w[8], w[3], w[11]);
783        round!(f, g, h, a, b, c, d, e, 0xc76c51a3, w[11], w[9], w[4], w[12]);
784        round!(e, f, g, h, a, b, c, d, 0xd192e819, w[12], w[10], w[5], w[13]);
785        round!(d, e, f, g, h, a, b, c, 0xd6990624, w[13], w[11], w[6], w[14]);
786        round!(c, d, e, f, g, h, a, b, 0xf40e3585, w[14], w[12], w[7], w[15]);
787        round!(b, c, d, e, f, g, h, a, 0x106aa070, w[15], w[13], w[8], w[0]);
788
789        round!(a, b, c, d, e, f, g, h, 0x19a4c116, w[0], w[14], w[9], w[1]);
790        round!(h, a, b, c, d, e, f, g, 0x1e376c08, w[1], w[15], w[10], w[2]);
791        round!(g, h, a, b, c, d, e, f, 0x2748774c, w[2], w[0], w[11], w[3]);
792        round!(f, g, h, a, b, c, d, e, 0x34b0bcb5, w[3], w[1], w[12], w[4]);
793        round!(e, f, g, h, a, b, c, d, 0x391c0cb3, w[4], w[2], w[13], w[5]);
794        round!(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w[5], w[3], w[14], w[6]);
795        round!(c, d, e, f, g, h, a, b, 0x5b9cca4f, w[6], w[4], w[15], w[7]);
796        round!(b, c, d, e, f, g, h, a, 0x682e6ff3, w[7], w[5], w[0], w[8]);
797        round!(a, b, c, d, e, f, g, h, 0x748f82ee, w[8], w[6], w[1], w[9]);
798        round!(h, a, b, c, d, e, f, g, 0x78a5636f, w[9], w[7], w[2], w[10]);
799        round!(g, h, a, b, c, d, e, f, 0x84c87814, w[10], w[8], w[3], w[11]);
800        round!(f, g, h, a, b, c, d, e, 0x8cc70208, w[11], w[9], w[4], w[12]);
801        round!(e, f, g, h, a, b, c, d, 0x90befffa, w[12], w[10], w[5], w[13]);
802        round!(d, e, f, g, h, a, b, c, 0xa4506ceb, w[13], w[11], w[6], w[14]);
803        round!(c, d, e, f, g, h, a, b, 0xbef9a3f7, w[14], w[12], w[7], w[15]);
804        round!(b, c, d, e, f, g, h, a, 0xc67178f2, w[15], w[13], w[8], w[0]);
805
806        self.h[0] = self.h[0].wrapping_add(a);
807        self.h[1] = self.h[1].wrapping_add(b);
808        self.h[2] = self.h[2].wrapping_add(c);
809        self.h[3] = self.h[3].wrapping_add(d);
810        self.h[4] = self.h[4].wrapping_add(e);
811        self.h[5] = self.h[5].wrapping_add(f);
812        self.h[6] = self.h[6].wrapping_add(g);
813        self.h[7] = self.h[7].wrapping_add(h);
814    }
815}
816
817#[cfg(test)]
818mod tests {
819    use super::*;
820    use crate::sha256;
821
822    #[test]
823    #[cfg(feature = "alloc")]
824    fn test() {
825        #[derive(Clone)]
826        struct Test {
827            input: &'static str,
828            output: Vec<u8>,
829            output_str: &'static str,
830        }
831
832        #[rustfmt::skip]
833        let tests = vec![
834            // Examples from wikipedia
835            Test {
836                input: "",
837                output: vec![
838                    0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
839                    0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
840                    0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
841                    0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
842                ],
843                output_str: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
844            },
845            Test {
846                input: "The quick brown fox jumps over the lazy dog",
847                output: vec![
848                    0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94,
849                    0x69, 0xca, 0x9a, 0xbc, 0xb0, 0x08, 0x2e, 0x4f,
850                    0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76,
851                    0x2d, 0x02, 0xd0, 0xbf, 0x37, 0xc9, 0xe5, 0x92,
852                ],
853                output_str: "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
854            },
855            Test {
856                input: "The quick brown fox jumps over the lazy dog.",
857                output: vec![
858                    0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7,
859                    0x82, 0x52, 0x65, 0x29, 0xa9, 0xb6, 0x3d, 0x97,
860                    0xaa, 0x63, 0x15, 0x64, 0xd5, 0xd7, 0x89, 0xc2,
861                    0xb7, 0x65, 0x44, 0x8c, 0x86, 0x35, 0xfb, 0x6c,
862                ],
863                output_str: "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c",
864            },
865        ];
866
867        for test in tests {
868            // Hash through high-level API, check hex encoding/decoding
869            let hash = sha256::Hash::hash(test.input.as_bytes());
870            assert_eq!(hash, test.output_str.parse::<sha256::Hash>().expect("parse hex"));
871            assert_eq!(&hash[..], &test.output[..]);
872            assert_eq!(&hash.to_string(), &test.output_str);
873
874            // Hash through engine, checking that we can input byte by byte
875            let mut engine = sha256::Engine::new();
876            for ch in test.input.as_bytes() {
877                engine.input(&[*ch]);
878            }
879            let manual_hash = sha256::Hash::from_engine(engine);
880            assert_eq!(hash, manual_hash);
881            assert_eq!(hash.to_byte_array()[..].as_ref(), test.output.as_slice());
882        }
883    }
884
885    #[test]
886    fn fmt_roundtrips() {
887        let hash = sha256::Hash::hash(b"some arbitrary bytes");
888        let hex = format!("{}", hash);
889        let rinsed = hex.parse::<sha256::Hash>().expect("failed to parse hex");
890        assert_eq!(rinsed, hash)
891    }
892
893    #[test]
894    #[rustfmt::skip]
895    fn midstate() {
896        // Test vector obtained by doing an asset issuance on Elements
897        let mut engine = sha256::Engine::new();
898        // sha256dhash of outpoint
899        // 73828cbc65fd68ab78dc86992b76ae50ae2bf8ceedbe8de0483172f0886219f7:0
900        engine.input(&[
901            0x9d, 0xd0, 0x1b, 0x56, 0xb1, 0x56, 0x45, 0x14,
902            0x3e, 0xad, 0x15, 0x8d, 0xec, 0x19, 0xf8, 0xce,
903            0xa9, 0x0b, 0xd0, 0xa9, 0xb2, 0xf8, 0x1d, 0x21,
904            0xff, 0xa3, 0xa4, 0xc6, 0x44, 0x81, 0xd4, 0x1c,
905        ]);
906        // 32 bytes of zeroes representing "new asset"
907        engine.input(&[0; 32]);
908        assert_eq!(
909            engine.midstate(),
910            // RPC output
911            sha256::Midstate::from_byte_array([
912                0x0b, 0xcf, 0xe0, 0xe5, 0x4e, 0x6c, 0xc7, 0xd3,
913                0x4f, 0x4f, 0x7c, 0x1d, 0xf0, 0xb0, 0xf5, 0x03,
914                0xf2, 0xf7, 0x12, 0x91, 0x2a, 0x06, 0x05, 0xb4,
915                0x14, 0xed, 0x33, 0x7f, 0x7f, 0x03, 0x2e, 0x03,
916            ])
917        );
918    }
919
920    #[test]
921    fn engine_with_state() {
922        let mut engine = sha256::Hash::engine();
923        let midstate_engine = sha256::Engine::from_midstate(engine.midstate(), 0);
924        // Fresh engine and engine initialized with fresh state should have same state
925        assert_eq!(engine.h, midstate_engine.h);
926
927        // Midstate changes after writing 64 bytes
928        engine.input(&[1; 63]);
929        assert_eq!(engine.h, midstate_engine.h);
930        engine.input(&[2; 1]);
931        assert_ne!(engine.h, midstate_engine.h);
932
933        // Initializing an engine with midstate from another engine should result in
934        // both engines producing the same hashes
935        let data_vec = vec![vec![3; 1], vec![4; 63], vec![5; 65], vec![6; 66]];
936        for data in data_vec {
937            let mut engine = engine.clone();
938            let mut midstate_engine =
939                sha256::Engine::from_midstate(engine.midstate(), engine.length);
940            assert_eq!(engine.h, midstate_engine.h);
941            assert_eq!(engine.length, midstate_engine.length);
942            engine.input(&data);
943            midstate_engine.input(&data);
944            assert_eq!(engine.h, midstate_engine.h);
945            let hash1 = sha256::Hash::from_engine(engine);
946            let hash2 = sha256::Hash::from_engine(midstate_engine);
947            assert_eq!(hash1, hash2);
948        }
949
950        // Test that a specific midstate results in a specific hash. Midstate was
951        // obtained by applying sha256 to sha256("MuSig coefficient")||sha256("MuSig
952        // coefficient").
953        #[rustfmt::skip]
954        static MIDSTATE: [u8; 32] = [
955            0x0f, 0xd0, 0x69, 0x0c, 0xfe, 0xfe, 0xae, 0x97,
956            0x99, 0x6e, 0xac, 0x7f, 0x5c, 0x30, 0xd8, 0x64,
957            0x8c, 0x4a, 0x05, 0x73, 0xac, 0xa1, 0xa2, 0x2f,
958            0x6f, 0x43, 0xb8, 0x01, 0x85, 0xce, 0x27, 0xcd,
959        ];
960        #[rustfmt::skip]
961        static HASH_EXPECTED: [u8; 32] = [
962            0x18, 0x84, 0xe4, 0x72, 0x40, 0x4e, 0xf4, 0x5a,
963            0xb4, 0x9c, 0x4e, 0xa4, 0x9a, 0xe6, 0x23, 0xa8,
964            0x88, 0x52, 0x7f, 0x7d, 0x8a, 0x06, 0x94, 0x20,
965            0x8f, 0xf1, 0xf7, 0xa9, 0xd5, 0x69, 0x09, 0x59,
966        ];
967        let midstate_engine =
968            sha256::Engine::from_midstate(sha256::Midstate::from_byte_array(MIDSTATE), 64);
969        let hash = sha256::Hash::from_engine(midstate_engine);
970        assert_eq!(hash, sha256::Hash(HASH_EXPECTED));
971    }
972
973    #[test]
974    fn const_hash() {
975        assert_eq!(Hash::hash(&[]), Hash::const_hash(&[]));
976
977        let mut bytes = Vec::new();
978        for i in 0..256 {
979            bytes.push(i as u8);
980            assert_eq!(
981                Hash::hash(&bytes),
982                Hash::const_hash(&bytes),
983                "hashes don't match for length {}",
984                i + 1
985            );
986        }
987    }
988
989    #[test]
990    fn const_midstate() {
991        assert_eq!(
992            Midstate::hash_tag(b"TapLeaf"),
993            Midstate([
994                156, 224, 228, 230, 124, 17, 108, 57, 56, 179, 202, 242, 195, 15, 80, 137, 211,
995                243, 147, 108, 71, 99, 110, 96, 125, 179, 62, 234, 221, 198, 240, 201,
996            ])
997        )
998    }
999
1000    #[test]
1001    fn midstate_fmt_roundtrip() {
1002        let midstate = Midstate::hash_tag(b"ArbitraryTag");
1003        let hex = format!("{}", midstate);
1004        let rinsed = hex.parse::<Midstate>().expect("failed to parse hex");
1005        assert_eq!(rinsed, midstate)
1006    }
1007
1008    #[cfg(feature = "serde")]
1009    #[test]
1010    fn sha256_serde() {
1011        use serde_test::{assert_tokens, Configure, Token};
1012
1013        #[rustfmt::skip]
1014        static HASH_BYTES: [u8; 32] = [
1015            0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7,
1016            0x82, 0x52, 0x65, 0x29, 0xa9, 0xb6, 0x3d, 0x97,
1017            0xaa, 0x63, 0x15, 0x64, 0xd5, 0xd7, 0x89, 0xc2,
1018            0xb7, 0x65, 0x44, 0x8c, 0x86, 0x35, 0xfb, 0x6c,
1019        ];
1020
1021        let hash = sha256::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
1022        assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
1023        assert_tokens(
1024            &hash.readable(),
1025            &[Token::Str("ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c")],
1026        );
1027    }
1028
1029    #[cfg(target_arch = "wasm32")]
1030    mod wasm_tests {
1031        extern crate wasm_bindgen_test;
1032        use self::wasm_bindgen_test::*;
1033        use super::*;
1034        #[wasm_bindgen_test]
1035        fn sha256_tests() {
1036            test();
1037            midstate();
1038            engine_with_state();
1039        }
1040    }
1041}
1042
1043#[cfg(bench)]
1044mod benches {
1045    use test::Bencher;
1046
1047    use super::*;
1048    use crate::sha256;
1049
1050    #[bench]
1051    pub fn sha256_10(bh: &mut Bencher) {
1052        let mut engine = sha256::Hash::engine();
1053        let bytes = [1u8; 10];
1054        bh.iter(|| {
1055            engine.input(&bytes);
1056        });
1057        bh.bytes = bytes.len() as u64;
1058    }
1059
1060    #[bench]
1061    pub fn sha256_1k(bh: &mut Bencher) {
1062        let mut engine = sha256::Hash::engine();
1063        let bytes = [1u8; 1024];
1064        bh.iter(|| {
1065            engine.input(&bytes);
1066        });
1067        bh.bytes = bytes.len() as u64;
1068    }
1069
1070    #[bench]
1071    pub fn sha256_64k(bh: &mut Bencher) {
1072        let mut engine = sha256::Hash::engine();
1073        let bytes = [1u8; 65536];
1074        bh.iter(|| {
1075            engine.input(&bytes);
1076        });
1077        bh.bytes = bytes.len() as u64;
1078    }
1079}