bitcoin_hashes/
sha256.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! SHA256 implementation.
4//!
5
6#[cfg(all(feature = "std", target_arch = "x86"))]
7use core::arch::x86::*;
8#[cfg(all(feature = "std", target_arch = "x86_64"))]
9use core::arch::x86_64::*;
10use core::ops::Index;
11use core::slice::SliceIndex;
12use core::{cmp, str};
13
14use crate::{sha256d, FromSliceError, HashEngine as _};
15
16crate::internal_macros::hash_type! {
17    256,
18    false,
19    "Output of the SHA256 hash function."
20}
21
22#[cfg(not(hashes_fuzz))]
23fn from_engine(mut e: HashEngine) -> Hash {
24    // pad buffer with a single 1-bit then all 0s, until there are exactly 8 bytes remaining
25    let data_len = e.length as u64;
26
27    let zeroes = [0; BLOCK_SIZE - 8];
28    e.input(&[0x80]);
29    if e.length % BLOCK_SIZE > zeroes.len() {
30        e.input(&zeroes);
31    }
32    let pad_length = zeroes.len() - (e.length % BLOCK_SIZE);
33    e.input(&zeroes[..pad_length]);
34    debug_assert_eq!(e.length % BLOCK_SIZE, zeroes.len());
35
36    e.input(&(8 * data_len).to_be_bytes());
37    debug_assert_eq!(e.length % BLOCK_SIZE, 0);
38
39    Hash(e.midstate().to_byte_array())
40}
41
42#[cfg(hashes_fuzz)]
43fn from_engine(e: HashEngine) -> Hash {
44    let mut hash = e.midstate().to_byte_array();
45    if hash == [0; 32] {
46        // Assume sha256 is secure and never generate 0-hashes (which represent invalid
47        // secp256k1 secret keys, causing downstream application breakage).
48        hash[0] = 1;
49    }
50    Hash(hash)
51}
52
53const BLOCK_SIZE: usize = 64;
54
55/// Engine to compute SHA256 hash function.
56#[derive(Clone)]
57pub struct HashEngine {
58    buffer: [u8; BLOCK_SIZE],
59    h: [u32; 8],
60    length: usize,
61}
62
63impl Default for HashEngine {
64    fn default() -> Self {
65        HashEngine {
66            h: [
67                0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
68                0x5be0cd19,
69            ],
70            length: 0,
71            buffer: [0; BLOCK_SIZE],
72        }
73    }
74}
75
76impl crate::HashEngine for HashEngine {
77    type MidState = Midstate;
78
79    #[cfg(not(hashes_fuzz))]
80    fn midstate(&self) -> Midstate {
81        let mut ret = [0; 32];
82        for (val, ret_bytes) in self.h.iter().zip(ret.chunks_exact_mut(4)) {
83            ret_bytes.copy_from_slice(&val.to_be_bytes());
84        }
85        Midstate(ret)
86    }
87
88    #[cfg(hashes_fuzz)]
89    fn midstate(&self) -> Midstate {
90        let mut ret = [0; 32];
91        ret.copy_from_slice(&self.buffer[..32]);
92        Midstate(ret)
93    }
94
95    const BLOCK_SIZE: usize = 64;
96
97    fn n_bytes_hashed(&self) -> usize { self.length }
98
99    engine_input_impl!();
100}
101
102impl Hash {
103    /// Iterate the sha256 algorithm to turn a sha256 hash into a sha256d hash
104    pub fn hash_again(&self) -> sha256d::Hash {
105        crate::Hash::from_byte_array(<Self as crate::Hash>::hash(&self.0).0)
106    }
107
108    /// Computes hash from `bytes` in `const` context.
109    ///
110    /// Warning: this function is inefficient. It should be only used in `const` context.
111    pub const fn const_hash(bytes: &[u8]) -> Self { Hash(Midstate::const_hash(bytes, true).0) }
112}
113
114/// Output of the SHA256 hash function.
115#[derive(Copy, Clone, PartialEq, Eq, Default, PartialOrd, Ord, Hash)]
116pub struct Midstate(pub [u8; 32]);
117
118crate::internal_macros::arr_newtype_fmt_impl!(Midstate, 32);
119serde_impl!(Midstate, 32);
120borrow_slice_impl!(Midstate);
121
122impl<I: SliceIndex<[u8]>> Index<I> for Midstate {
123    type Output = I::Output;
124
125    #[inline]
126    fn index(&self, index: I) -> &Self::Output { &self.0[index] }
127}
128
129impl str::FromStr for Midstate {
130    type Err = hex::HexToArrayError;
131    fn from_str(s: &str) -> Result<Self, Self::Err> { hex::FromHex::from_hex(s) }
132}
133
134impl Midstate {
135    /// Length of the midstate, in bytes.
136    const LEN: usize = 32;
137
138    /// Flag indicating whether user-visible serializations of this hash
139    /// should be backward. For some reason Satoshi decided this should be
140    /// true for `Sha256dHash`, so here we are.
141    const DISPLAY_BACKWARD: bool = true;
142
143    /// Construct a new [`Midstate`] from the inner value.
144    pub const fn from_byte_array(inner: [u8; 32]) -> Self { Midstate(inner) }
145
146    /// Copies a byte slice into the [`Midstate`] object.
147    pub fn from_slice(sl: &[u8]) -> Result<Midstate, FromSliceError> {
148        if sl.len() != Self::LEN {
149            Err(FromSliceError { expected: Self::LEN, got: sl.len() })
150        } else {
151            let mut ret = [0; 32];
152            ret.copy_from_slice(sl);
153            Ok(Midstate(ret))
154        }
155    }
156
157    /// Unwraps the [`Midstate`] and returns the underlying byte array.
158    pub fn to_byte_array(self) -> [u8; 32] { self.0 }
159
160    /// Creates midstate for tagged hashes.
161    ///
162    /// Warning: this function is inefficient. It should be only used in `const` context.
163    ///
164    /// Computes non-finalized hash of `sha256(tag) || sha256(tag)` for use in
165    /// [`sha256t`](super::sha256t). It's provided for use with [`sha256t`](crate::sha256t).
166    pub const fn hash_tag(tag: &[u8]) -> Self {
167        let hash = Hash::const_hash(tag);
168        let mut buf = [0u8; 64];
169        let mut i = 0usize;
170        while i < buf.len() {
171            buf[i] = hash.0[i % hash.0.len()];
172            i += 1;
173        }
174        Self::const_hash(&buf, false)
175    }
176}
177
178impl hex::FromHex for Midstate {
179    type Error = hex::HexToArrayError;
180
181    fn from_hex(s: &str) -> Result<Self, Self::Error> {
182        // DISPLAY_BACKWARD is true
183        let mut bytes = <[u8; 32]>::from_hex(s)?;
184        bytes.reverse();
185        Ok(Midstate(bytes))
186    }
187}
188
189#[allow(non_snake_case)]
190const fn Ch(x: u32, y: u32, z: u32) -> u32 { z ^ (x & (y ^ z)) }
191#[allow(non_snake_case)]
192const fn Maj(x: u32, y: u32, z: u32) -> u32 { (x & y) | (z & (x | y)) }
193#[allow(non_snake_case)]
194const fn Sigma0(x: u32) -> u32 { x.rotate_left(30) ^ x.rotate_left(19) ^ x.rotate_left(10) }
195#[allow(non_snake_case)]
196const fn Sigma1(x: u32) -> u32 { x.rotate_left(26) ^ x.rotate_left(21) ^ x.rotate_left(7) }
197const fn sigma0(x: u32) -> u32 { x.rotate_left(25) ^ x.rotate_left(14) ^ (x >> 3) }
198const fn sigma1(x: u32) -> u32 { x.rotate_left(15) ^ x.rotate_left(13) ^ (x >> 10) }
199
200#[cfg(feature = "small-hash")]
201#[macro_use]
202mod small_hash {
203    use super::*;
204
205    #[rustfmt::skip]
206    pub(super) const fn round(a: u32, b: u32, c: u32, d: u32, e: u32,
207                              f: u32, g: u32, h: u32, k: u32, w: u32) -> (u32, u32) {
208        let t1 =
209            h.wrapping_add(Sigma1(e)).wrapping_add(Ch(e, f, g)).wrapping_add(k).wrapping_add(w);
210        let t2 = Sigma0(a).wrapping_add(Maj(a, b, c));
211        (d.wrapping_add(t1), t1.wrapping_add(t2))
212    }
213    #[rustfmt::skip]
214    pub(super) const fn later_round(a: u32, b: u32, c: u32, d: u32, e: u32,
215                                    f: u32, g: u32, h: u32, k: u32, w: u32,
216                                    w1: u32, w2: u32, w3: u32,
217    ) -> (u32, u32, u32) {
218        let w = w.wrapping_add(sigma1(w1)).wrapping_add(w2).wrapping_add(sigma0(w3));
219        let (d, h) = round(a, b, c, d, e, f, g, h, k, w);
220        (d, h, w)
221    }
222
223    macro_rules! round(
224        // first round
225        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
226            let updates = small_hash::round($a, $b, $c, $d, $e, $f, $g, $h, $k, $w);
227            $d = updates.0;
228            $h = updates.1;
229        );
230        // later rounds we reassign $w before doing the first-round computation
231        ($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) => (
232            let updates = small_hash::later_round($a, $b, $c, $d, $e, $f, $g, $h, $k, $w, $w1, $w2, $w3);
233            $d = updates.0;
234            $h = updates.1;
235            $w = updates.2;
236        )
237    );
238}
239
240#[cfg(not(feature = "small-hash"))]
241#[macro_use]
242mod fast_hash {
243    macro_rules! round(
244        // first round
245        ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr, $f:expr, $g:expr, $h:expr, $k:expr, $w:expr) => (
246            let t1 = $h.wrapping_add(Sigma1($e)).wrapping_add(Ch($e, $f, $g)).wrapping_add($k).wrapping_add($w);
247            let t2 = Sigma0($a).wrapping_add(Maj($a, $b, $c));
248            $d = $d.wrapping_add(t1);
249            $h = t1.wrapping_add(t2);
250        );
251        // later rounds we reassign $w before doing the first-round computation
252        ($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) => (
253            $w = $w.wrapping_add(sigma1($w1)).wrapping_add($w2).wrapping_add(sigma0($w3));
254            round!($a, $b, $c, $d, $e, $f, $g, $h, $k, $w);
255        )
256    );
257}
258
259impl Midstate {
260    #[allow(clippy::identity_op)] // more readble
261    const fn read_u32(bytes: &[u8], index: usize) -> u32 {
262        ((bytes[index + 0] as u32) << 24)
263            | ((bytes[index + 1] as u32) << 16)
264            | ((bytes[index + 2] as u32) << 8)
265            | ((bytes[index + 3] as u32) << 0)
266    }
267
268    const fn copy_w(bytes: &[u8], index: usize) -> [u32; 16] {
269        let mut w = [0u32; 16];
270        let mut i = 0;
271        while i < 16 {
272            w[i] = Self::read_u32(bytes, index + i * 4);
273            i += 1;
274        }
275        w
276    }
277
278    const fn const_hash(bytes: &[u8], finalize: bool) -> Self {
279        let mut state = [
280            0x6a09e667u32,
281            0xbb67ae85,
282            0x3c6ef372,
283            0xa54ff53a,
284            0x510e527f,
285            0x9b05688c,
286            0x1f83d9ab,
287            0x5be0cd19,
288        ];
289
290        let num_chunks = (bytes.len() + 9).div_ceil(64);
291        let mut chunk = 0;
292        #[allow(clippy::precedence)]
293        while chunk < num_chunks {
294            if !finalize && chunk + 1 == num_chunks {
295                break;
296            }
297            let mut w = if chunk * 64 + 64 <= bytes.len() {
298                Self::copy_w(bytes, chunk * 64)
299            } else {
300                let mut buf = [0; 64];
301                let mut i = 0;
302                let offset = chunk * 64;
303                while offset + i < bytes.len() {
304                    buf[i] = bytes[offset + i];
305                    i += 1;
306                }
307                if (bytes.len() % 64 <= 64 - 9) || (chunk + 2 == num_chunks) {
308                    buf[i] = 0x80;
309                }
310                #[allow(clippy::identity_op)] // more readble
311                #[allow(clippy::erasing_op)]
312                if chunk + 1 == num_chunks {
313                    let bit_len = bytes.len() as u64 * 8;
314                    buf[64 - 8] = ((bit_len >> 8 * 7) & 0xFF) as u8;
315                    buf[64 - 7] = ((bit_len >> 8 * 6) & 0xFF) as u8;
316                    buf[64 - 6] = ((bit_len >> 8 * 5) & 0xFF) as u8;
317                    buf[64 - 5] = ((bit_len >> 8 * 4) & 0xFF) as u8;
318                    buf[64 - 4] = ((bit_len >> 8 * 3) & 0xFF) as u8;
319                    buf[64 - 3] = ((bit_len >> 8 * 2) & 0xFF) as u8;
320                    buf[64 - 2] = ((bit_len >> 8 * 1) & 0xFF) as u8;
321                    buf[64 - 1] = ((bit_len >> 8 * 0) & 0xFF) as u8;
322                }
323                Self::copy_w(&buf, 0)
324            };
325            chunk += 1;
326
327            let mut a = state[0];
328            let mut b = state[1];
329            let mut c = state[2];
330            let mut d = state[3];
331            let mut e = state[4];
332            let mut f = state[5];
333            let mut g = state[6];
334            let mut h = state[7];
335
336            round!(a, b, c, d, e, f, g, h, 0x428a2f98, w[0]);
337            round!(h, a, b, c, d, e, f, g, 0x71374491, w[1]);
338            round!(g, h, a, b, c, d, e, f, 0xb5c0fbcf, w[2]);
339            round!(f, g, h, a, b, c, d, e, 0xe9b5dba5, w[3]);
340            round!(e, f, g, h, a, b, c, d, 0x3956c25b, w[4]);
341            round!(d, e, f, g, h, a, b, c, 0x59f111f1, w[5]);
342            round!(c, d, e, f, g, h, a, b, 0x923f82a4, w[6]);
343            round!(b, c, d, e, f, g, h, a, 0xab1c5ed5, w[7]);
344            round!(a, b, c, d, e, f, g, h, 0xd807aa98, w[8]);
345            round!(h, a, b, c, d, e, f, g, 0x12835b01, w[9]);
346            round!(g, h, a, b, c, d, e, f, 0x243185be, w[10]);
347            round!(f, g, h, a, b, c, d, e, 0x550c7dc3, w[11]);
348            round!(e, f, g, h, a, b, c, d, 0x72be5d74, w[12]);
349            round!(d, e, f, g, h, a, b, c, 0x80deb1fe, w[13]);
350            round!(c, d, e, f, g, h, a, b, 0x9bdc06a7, w[14]);
351            round!(b, c, d, e, f, g, h, a, 0xc19bf174, w[15]);
352
353            round!(a, b, c, d, e, f, g, h, 0xe49b69c1, w[0], w[14], w[9], w[1]);
354            round!(h, a, b, c, d, e, f, g, 0xefbe4786, w[1], w[15], w[10], w[2]);
355            round!(g, h, a, b, c, d, e, f, 0x0fc19dc6, w[2], w[0], w[11], w[3]);
356            round!(f, g, h, a, b, c, d, e, 0x240ca1cc, w[3], w[1], w[12], w[4]);
357            round!(e, f, g, h, a, b, c, d, 0x2de92c6f, w[4], w[2], w[13], w[5]);
358            round!(d, e, f, g, h, a, b, c, 0x4a7484aa, w[5], w[3], w[14], w[6]);
359            round!(c, d, e, f, g, h, a, b, 0x5cb0a9dc, w[6], w[4], w[15], w[7]);
360            round!(b, c, d, e, f, g, h, a, 0x76f988da, w[7], w[5], w[0], w[8]);
361            round!(a, b, c, d, e, f, g, h, 0x983e5152, w[8], w[6], w[1], w[9]);
362            round!(h, a, b, c, d, e, f, g, 0xa831c66d, w[9], w[7], w[2], w[10]);
363            round!(g, h, a, b, c, d, e, f, 0xb00327c8, w[10], w[8], w[3], w[11]);
364            round!(f, g, h, a, b, c, d, e, 0xbf597fc7, w[11], w[9], w[4], w[12]);
365            round!(e, f, g, h, a, b, c, d, 0xc6e00bf3, w[12], w[10], w[5], w[13]);
366            round!(d, e, f, g, h, a, b, c, 0xd5a79147, w[13], w[11], w[6], w[14]);
367            round!(c, d, e, f, g, h, a, b, 0x06ca6351, w[14], w[12], w[7], w[15]);
368            round!(b, c, d, e, f, g, h, a, 0x14292967, w[15], w[13], w[8], w[0]);
369
370            round!(a, b, c, d, e, f, g, h, 0x27b70a85, w[0], w[14], w[9], w[1]);
371            round!(h, a, b, c, d, e, f, g, 0x2e1b2138, w[1], w[15], w[10], w[2]);
372            round!(g, h, a, b, c, d, e, f, 0x4d2c6dfc, w[2], w[0], w[11], w[3]);
373            round!(f, g, h, a, b, c, d, e, 0x53380d13, w[3], w[1], w[12], w[4]);
374            round!(e, f, g, h, a, b, c, d, 0x650a7354, w[4], w[2], w[13], w[5]);
375            round!(d, e, f, g, h, a, b, c, 0x766a0abb, w[5], w[3], w[14], w[6]);
376            round!(c, d, e, f, g, h, a, b, 0x81c2c92e, w[6], w[4], w[15], w[7]);
377            round!(b, c, d, e, f, g, h, a, 0x92722c85, w[7], w[5], w[0], w[8]);
378            round!(a, b, c, d, e, f, g, h, 0xa2bfe8a1, w[8], w[6], w[1], w[9]);
379            round!(h, a, b, c, d, e, f, g, 0xa81a664b, w[9], w[7], w[2], w[10]);
380            round!(g, h, a, b, c, d, e, f, 0xc24b8b70, w[10], w[8], w[3], w[11]);
381            round!(f, g, h, a, b, c, d, e, 0xc76c51a3, w[11], w[9], w[4], w[12]);
382            round!(e, f, g, h, a, b, c, d, 0xd192e819, w[12], w[10], w[5], w[13]);
383            round!(d, e, f, g, h, a, b, c, 0xd6990624, w[13], w[11], w[6], w[14]);
384            round!(c, d, e, f, g, h, a, b, 0xf40e3585, w[14], w[12], w[7], w[15]);
385            round!(b, c, d, e, f, g, h, a, 0x106aa070, w[15], w[13], w[8], w[0]);
386
387            round!(a, b, c, d, e, f, g, h, 0x19a4c116, w[0], w[14], w[9], w[1]);
388            round!(h, a, b, c, d, e, f, g, 0x1e376c08, w[1], w[15], w[10], w[2]);
389            round!(g, h, a, b, c, d, e, f, 0x2748774c, w[2], w[0], w[11], w[3]);
390            round!(f, g, h, a, b, c, d, e, 0x34b0bcb5, w[3], w[1], w[12], w[4]);
391            round!(e, f, g, h, a, b, c, d, 0x391c0cb3, w[4], w[2], w[13], w[5]);
392            round!(d, e, f, g, h, a, b, c, 0x4ed8aa4a, w[5], w[3], w[14], w[6]);
393            round!(c, d, e, f, g, h, a, b, 0x5b9cca4f, w[6], w[4], w[15], w[7]);
394            round!(b, c, d, e, f, g, h, a, 0x682e6ff3, w[7], w[5], w[0], w[8]);
395            round!(a, b, c, d, e, f, g, h, 0x748f82ee, w[8], w[6], w[1], w[9]);
396            round!(h, a, b, c, d, e, f, g, 0x78a5636f, w[9], w[7], w[2], w[10]);
397            round!(g, h, a, b, c, d, e, f, 0x84c87814, w[10], w[8], w[3], w[11]);
398            round!(f, g, h, a, b, c, d, e, 0x8cc70208, w[11], w[9], w[4], w[12]);
399            round!(e, f, g, h, a, b, c, d, 0x90befffa, w[12], w[10], w[5], w[13]);
400            round!(d, e, f, g, h, a, b, c, 0xa4506ceb, w[13], w[11], w[6], w[14]);
401            round!(c, d, e, f, g, h, a, b, 0xbef9a3f7, w[14], w[12], w[7], w[15]);
402            round!(b, c, d, e, f, g, h, a, 0xc67178f2, w[15], w[13], w[8], w[0]);
403            let _ = w[15]; // silence "unnecessary assignment" lint in macro
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 HashEngine {
429    /// Create a new [`HashEngine`] 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) -> HashEngine {
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        HashEngine { 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        let _ = w[15]; // silence "unnecessary assignment" lint in macro
806
807        self.h[0] = self.h[0].wrapping_add(a);
808        self.h[1] = self.h[1].wrapping_add(b);
809        self.h[2] = self.h[2].wrapping_add(c);
810        self.h[3] = self.h[3].wrapping_add(d);
811        self.h[4] = self.h[4].wrapping_add(e);
812        self.h[5] = self.h[5].wrapping_add(f);
813        self.h[6] = self.h[6].wrapping_add(g);
814        self.h[7] = self.h[7].wrapping_add(h);
815    }
816}
817
818#[cfg(test)]
819mod tests {
820    use super::*;
821    use crate::{sha256, Hash as _, HashEngine};
822
823    #[test]
824    #[cfg(feature = "alloc")]
825    fn test() {
826        #[derive(Clone)]
827        struct Test {
828            input: &'static str,
829            output: Vec<u8>,
830            output_str: &'static str,
831        }
832
833        #[rustfmt::skip]
834        let tests = vec![
835            // Examples from wikipedia
836            Test {
837                input: "",
838                output: vec![
839                    0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
840                    0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
841                    0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
842                    0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
843                ],
844                output_str: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
845            },
846            Test {
847                input: "The quick brown fox jumps over the lazy dog",
848                output: vec![
849                    0xd7, 0xa8, 0xfb, 0xb3, 0x07, 0xd7, 0x80, 0x94,
850                    0x69, 0xca, 0x9a, 0xbc, 0xb0, 0x08, 0x2e, 0x4f,
851                    0x8d, 0x56, 0x51, 0xe4, 0x6d, 0x3c, 0xdb, 0x76,
852                    0x2d, 0x02, 0xd0, 0xbf, 0x37, 0xc9, 0xe5, 0x92,
853                ],
854                output_str: "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
855            },
856            Test {
857                input: "The quick brown fox jumps over the lazy dog.",
858                output: vec![
859                    0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7,
860                    0x82, 0x52, 0x65, 0x29, 0xa9, 0xb6, 0x3d, 0x97,
861                    0xaa, 0x63, 0x15, 0x64, 0xd5, 0xd7, 0x89, 0xc2,
862                    0xb7, 0x65, 0x44, 0x8c, 0x86, 0x35, 0xfb, 0x6c,
863                ],
864                output_str: "ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c",
865            },
866        ];
867
868        for test in tests {
869            // Hash through high-level API, check hex encoding/decoding
870            let hash = sha256::Hash::hash(test.input.as_bytes());
871            assert_eq!(hash, test.output_str.parse::<sha256::Hash>().expect("parse hex"));
872            assert_eq!(&hash[..], &test.output[..]);
873            assert_eq!(&hash.to_string(), &test.output_str);
874
875            // Hash through engine, checking that we can input byte by byte
876            let mut engine = sha256::Hash::engine();
877            for ch in test.input.as_bytes() {
878                engine.input(&[*ch]);
879            }
880            let manual_hash = sha256::Hash::from_engine(engine);
881            assert_eq!(hash, manual_hash);
882            assert_eq!(hash.to_byte_array()[..].as_ref(), test.output.as_slice());
883        }
884    }
885
886    #[test]
887    fn fmt_roundtrips() {
888        let hash = sha256::Hash::hash(b"some arbitrary bytes");
889        let hex = format!("{}", hash);
890        let rinsed = hex.parse::<sha256::Hash>().expect("failed to parse hex");
891        assert_eq!(rinsed, hash)
892    }
893
894    #[test]
895    #[rustfmt::skip]
896    fn midstate() {
897        // Test vector obtained by doing an asset issuance on Elements
898        let mut engine = sha256::Hash::engine();
899        // sha256dhash of outpoint
900        // 73828cbc65fd68ab78dc86992b76ae50ae2bf8ceedbe8de0483172f0886219f7:0
901        engine.input(&[
902            0x9d, 0xd0, 0x1b, 0x56, 0xb1, 0x56, 0x45, 0x14,
903            0x3e, 0xad, 0x15, 0x8d, 0xec, 0x19, 0xf8, 0xce,
904            0xa9, 0x0b, 0xd0, 0xa9, 0xb2, 0xf8, 0x1d, 0x21,
905            0xff, 0xa3, 0xa4, 0xc6, 0x44, 0x81, 0xd4, 0x1c,
906        ]);
907        // 32 bytes of zeroes representing "new asset"
908        engine.input(&[0; 32]);
909        assert_eq!(
910            engine.midstate(),
911            // RPC output
912            sha256::Midstate::from_byte_array([
913                0x0b, 0xcf, 0xe0, 0xe5, 0x4e, 0x6c, 0xc7, 0xd3,
914                0x4f, 0x4f, 0x7c, 0x1d, 0xf0, 0xb0, 0xf5, 0x03,
915                0xf2, 0xf7, 0x12, 0x91, 0x2a, 0x06, 0x05, 0xb4,
916                0x14, 0xed, 0x33, 0x7f, 0x7f, 0x03, 0x2e, 0x03,
917            ])
918        );
919    }
920
921    #[test]
922    fn engine_with_state() {
923        let mut engine = sha256::Hash::engine();
924        let midstate_engine = sha256::HashEngine::from_midstate(engine.midstate(), 0);
925        // Fresh engine and engine initialized with fresh state should have same state
926        assert_eq!(engine.h, midstate_engine.h);
927
928        // Midstate changes after writing 64 bytes
929        engine.input(&[1; 63]);
930        assert_eq!(engine.h, midstate_engine.h);
931        engine.input(&[2; 1]);
932        assert_ne!(engine.h, midstate_engine.h);
933
934        // Initializing an engine with midstate from another engine should result in
935        // both engines producing the same hashes
936        let data_vec = vec![vec![3; 1], vec![4; 63], vec![5; 65], vec![6; 66]];
937        for data in data_vec {
938            let mut engine = engine.clone();
939            let mut midstate_engine =
940                sha256::HashEngine::from_midstate(engine.midstate(), engine.length);
941            assert_eq!(engine.h, midstate_engine.h);
942            assert_eq!(engine.length, midstate_engine.length);
943            engine.input(&data);
944            midstate_engine.input(&data);
945            assert_eq!(engine.h, midstate_engine.h);
946            let hash1 = sha256::Hash::from_engine(engine);
947            let hash2 = sha256::Hash::from_engine(midstate_engine);
948            assert_eq!(hash1, hash2);
949        }
950
951        // Test that a specific midstate results in a specific hash. Midstate was
952        // obtained by applying sha256 to sha256("MuSig coefficient")||sha256("MuSig
953        // coefficient").
954        #[rustfmt::skip]
955        static MIDSTATE: [u8; 32] = [
956            0x0f, 0xd0, 0x69, 0x0c, 0xfe, 0xfe, 0xae, 0x97,
957            0x99, 0x6e, 0xac, 0x7f, 0x5c, 0x30, 0xd8, 0x64,
958            0x8c, 0x4a, 0x05, 0x73, 0xac, 0xa1, 0xa2, 0x2f,
959            0x6f, 0x43, 0xb8, 0x01, 0x85, 0xce, 0x27, 0xcd,
960        ];
961        #[rustfmt::skip]
962        static HASH_EXPECTED: [u8; 32] = [
963            0x18, 0x84, 0xe4, 0x72, 0x40, 0x4e, 0xf4, 0x5a,
964            0xb4, 0x9c, 0x4e, 0xa4, 0x9a, 0xe6, 0x23, 0xa8,
965            0x88, 0x52, 0x7f, 0x7d, 0x8a, 0x06, 0x94, 0x20,
966            0x8f, 0xf1, 0xf7, 0xa9, 0xd5, 0x69, 0x09, 0x59,
967        ];
968        let midstate_engine =
969            sha256::HashEngine::from_midstate(sha256::Midstate::from_byte_array(MIDSTATE), 64);
970        let hash = sha256::Hash::from_engine(midstate_engine);
971        assert_eq!(hash, sha256::Hash(HASH_EXPECTED));
972    }
973
974    #[test]
975    fn const_hash() {
976        assert_eq!(Hash::hash(&[]), Hash::const_hash(&[]));
977
978        let mut bytes = Vec::new();
979        for i in 0..256 {
980            bytes.push(i as u8);
981            assert_eq!(
982                Hash::hash(&bytes),
983                Hash::const_hash(&bytes),
984                "hashes don't match for length {}",
985                i + 1
986            );
987        }
988    }
989
990    #[test]
991    fn const_midstate() {
992        assert_eq!(
993            Midstate::hash_tag(b"TapLeaf"),
994            Midstate([
995                156, 224, 228, 230, 124, 17, 108, 57, 56, 179, 202, 242, 195, 15, 80, 137, 211,
996                243, 147, 108, 71, 99, 110, 96, 125, 179, 62, 234, 221, 198, 240, 201,
997            ])
998        )
999    }
1000
1001    #[test]
1002    fn midstate_fmt_roundtrip() {
1003        let midstate = Midstate::hash_tag(b"ArbitraryTag");
1004        let hex = format!("{}", midstate);
1005        let rinsed = hex.parse::<Midstate>().expect("failed to parse hex");
1006        assert_eq!(rinsed, midstate)
1007    }
1008
1009    #[cfg(feature = "serde")]
1010    #[test]
1011    fn sha256_serde() {
1012        use serde_test::{assert_tokens, Configure, Token};
1013
1014        #[rustfmt::skip]
1015        static HASH_BYTES: [u8; 32] = [
1016            0xef, 0x53, 0x7f, 0x25, 0xc8, 0x95, 0xbf, 0xa7,
1017            0x82, 0x52, 0x65, 0x29, 0xa9, 0xb6, 0x3d, 0x97,
1018            0xaa, 0x63, 0x15, 0x64, 0xd5, 0xd7, 0x89, 0xc2,
1019            0xb7, 0x65, 0x44, 0x8c, 0x86, 0x35, 0xfb, 0x6c,
1020        ];
1021
1022        let hash = sha256::Hash::from_slice(&HASH_BYTES).expect("right number of bytes");
1023        assert_tokens(&hash.compact(), &[Token::BorrowedBytes(&HASH_BYTES[..])]);
1024        assert_tokens(
1025            &hash.readable(),
1026            &[Token::Str("ef537f25c895bfa782526529a9b63d97aa631564d5d789c2b765448c8635fb6c")],
1027        );
1028    }
1029
1030    #[cfg(target_arch = "wasm32")]
1031    mod wasm_tests {
1032        extern crate wasm_bindgen_test;
1033        use self::wasm_bindgen_test::*;
1034        use super::*;
1035        #[wasm_bindgen_test]
1036        fn sha256_tests() {
1037            test();
1038            midstate();
1039            engine_with_state();
1040        }
1041    }
1042}
1043
1044#[cfg(bench)]
1045mod benches {
1046    use test::Bencher;
1047
1048    use crate::{sha256, Hash, HashEngine};
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}