Coverage Report

Created: 2026-07-10 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.10.9/src/sha256/soft.rs
Line
Count
Source
1
#![allow(clippy::many_single_char_names)]
2
use crate::consts::BLOCK_LEN;
3
use core::convert::TryInto;
4
5
#[inline(always)]
6
35.2M
fn shl(v: [u32; 4], o: u32) -> [u32; 4] {
7
35.2M
    [v[0] >> o, v[1] >> o, v[2] >> o, v[3] >> o]
8
35.2M
}
9
10
#[inline(always)]
11
23.4M
fn shr(v: [u32; 4], o: u32) -> [u32; 4] {
12
23.4M
    [v[0] << o, v[1] << o, v[2] << o, v[3] << o]
13
23.4M
}
14
15
#[inline(always)]
16
23.4M
fn or(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
17
23.4M
    [a[0] | b[0], a[1] | b[1], a[2] | b[2], a[3] | b[3]]
18
23.4M
}
19
20
#[inline(always)]
21
23.4M
fn xor(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
22
23.4M
    [a[0] ^ b[0], a[1] ^ b[1], a[2] ^ b[2], a[3] ^ b[3]]
23
23.4M
}
24
25
#[inline(always)]
26
39.1M
fn add(a: [u32; 4], b: [u32; 4]) -> [u32; 4] {
27
39.1M
    [
28
39.1M
        a[0].wrapping_add(b[0]),
29
39.1M
        a[1].wrapping_add(b[1]),
30
39.1M
        a[2].wrapping_add(b[2]),
31
39.1M
        a[3].wrapping_add(b[3]),
32
39.1M
    ]
33
39.1M
}
34
35
23.4M
fn sha256load(v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
36
23.4M
    [v3[3], v2[0], v2[1], v2[2]]
37
23.4M
}
38
39
15.6M
fn sha256swap(v0: [u32; 4]) -> [u32; 4] {
40
15.6M
    [v0[2], v0[3], v0[0], v0[1]]
41
15.6M
}
42
43
11.7M
fn sha256msg1(v0: [u32; 4], v1: [u32; 4]) -> [u32; 4] {
44
    // sigma 0 on vectors
45
    #[inline]
46
11.7M
    fn sigma0x4(x: [u32; 4]) -> [u32; 4] {
47
11.7M
        let t1 = or(shl(x, 7), shr(x, 25));
48
11.7M
        let t2 = or(shl(x, 18), shr(x, 14));
49
11.7M
        let t3 = shl(x, 3);
50
11.7M
        xor(xor(t1, t2), t3)
51
11.7M
    }
52
53
11.7M
    add(v0, sigma0x4(sha256load(v0, v1)))
54
11.7M
}
55
56
11.7M
fn sha256msg2(v4: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
57
    macro_rules! sigma1 {
58
        ($a:expr) => {
59
            $a.rotate_right(17) ^ $a.rotate_right(19) ^ ($a >> 10)
60
        };
61
    }
62
63
11.7M
    let [x3, x2, x1, x0] = v4;
64
11.7M
    let [w15, w14, _, _] = v3;
65
66
11.7M
    let w16 = x0.wrapping_add(sigma1!(w14));
67
11.7M
    let w17 = x1.wrapping_add(sigma1!(w15));
68
11.7M
    let w18 = x2.wrapping_add(sigma1!(w16));
69
11.7M
    let w19 = x3.wrapping_add(sigma1!(w17));
70
71
11.7M
    [w19, w18, w17, w16]
72
11.7M
}
73
74
31.3M
fn sha256_digest_round_x2(cdgh: [u32; 4], abef: [u32; 4], wk: [u32; 4]) -> [u32; 4] {
75
    macro_rules! big_sigma0 {
76
        ($a:expr) => {
77
            ($a.rotate_right(2) ^ $a.rotate_right(13) ^ $a.rotate_right(22))
78
        };
79
    }
80
    macro_rules! big_sigma1 {
81
        ($a:expr) => {
82
            ($a.rotate_right(6) ^ $a.rotate_right(11) ^ $a.rotate_right(25))
83
        };
84
    }
85
    macro_rules! bool3ary_202 {
86
        ($a:expr, $b:expr, $c:expr) => {
87
            $c ^ ($a & ($b ^ $c))
88
        };
89
    } // Choose, MD5F, SHA1C
90
    macro_rules! bool3ary_232 {
91
        ($a:expr, $b:expr, $c:expr) => {
92
            ($a & $b) ^ ($a & $c) ^ ($b & $c)
93
        };
94
    } // Majority, SHA1M
95
96
31.3M
    let [_, _, wk1, wk0] = wk;
97
31.3M
    let [a0, b0, e0, f0] = abef;
98
31.3M
    let [c0, d0, g0, h0] = cdgh;
99
100
    // a round
101
31.3M
    let x0 = big_sigma1!(e0)
102
31.3M
        .wrapping_add(bool3ary_202!(e0, f0, g0))
103
31.3M
        .wrapping_add(wk0)
104
31.3M
        .wrapping_add(h0);
105
31.3M
    let y0 = big_sigma0!(a0).wrapping_add(bool3ary_232!(a0, b0, c0));
106
31.3M
    let (a1, b1, c1, d1, e1, f1, g1, h1) = (
107
31.3M
        x0.wrapping_add(y0),
108
31.3M
        a0,
109
31.3M
        b0,
110
31.3M
        c0,
111
31.3M
        x0.wrapping_add(d0),
112
31.3M
        e0,
113
31.3M
        f0,
114
31.3M
        g0,
115
31.3M
    );
116
117
    // a round
118
31.3M
    let x1 = big_sigma1!(e1)
119
31.3M
        .wrapping_add(bool3ary_202!(e1, f1, g1))
120
31.3M
        .wrapping_add(wk1)
121
31.3M
        .wrapping_add(h1);
122
31.3M
    let y1 = big_sigma0!(a1).wrapping_add(bool3ary_232!(a1, b1, c1));
123
31.3M
    let (a2, b2, _, _, e2, f2, _, _) = (
124
31.3M
        x1.wrapping_add(y1),
125
31.3M
        a1,
126
31.3M
        b1,
127
31.3M
        c1,
128
31.3M
        x1.wrapping_add(d1),
129
31.3M
        e1,
130
31.3M
        f1,
131
31.3M
        g1,
132
31.3M
    );
133
134
31.3M
    [a2, b2, e2, f2]
135
31.3M
}
136
137
11.7M
fn schedule(v0: [u32; 4], v1: [u32; 4], v2: [u32; 4], v3: [u32; 4]) -> [u32; 4] {
138
11.7M
    let t1 = sha256msg1(v0, v1);
139
11.7M
    let t2 = sha256load(v2, v3);
140
11.7M
    let t3 = add(t1, t2);
141
11.7M
    sha256msg2(t3, v3)
142
11.7M
}
143
144
macro_rules! rounds4 {
145
    ($abef:ident, $cdgh:ident, $rest:expr, $i:expr) => {{
146
        let t1 = add($rest, crate::consts::K32X4[$i]);
147
        $cdgh = sha256_digest_round_x2($cdgh, $abef, t1);
148
        let t2 = sha256swap(t1);
149
        $abef = sha256_digest_round_x2($abef, $cdgh, t2);
150
    }};
151
}
152
153
macro_rules! schedule_rounds4 {
154
    (
155
        $abef:ident, $cdgh:ident,
156
        $w0:expr, $w1:expr, $w2:expr, $w3:expr, $w4:expr,
157
        $i: expr
158
    ) => {{
159
        $w4 = schedule($w0, $w1, $w2, $w3);
160
        rounds4!($abef, $cdgh, $w4, $i);
161
    }};
162
}
163
164
/// Process a block with the SHA-256 algorithm.
165
978k
fn sha256_digest_block_u32(state: &mut [u32; 8], block: &[u32; 16]) {
166
978k
    let mut abef = [state[0], state[1], state[4], state[5]];
167
978k
    let mut cdgh = [state[2], state[3], state[6], state[7]];
168
169
    // Rounds 0..64
170
978k
    let mut w0 = [block[3], block[2], block[1], block[0]];
171
978k
    let mut w1 = [block[7], block[6], block[5], block[4]];
172
978k
    let mut w2 = [block[11], block[10], block[9], block[8]];
173
978k
    let mut w3 = [block[15], block[14], block[13], block[12]];
174
    let mut w4;
175
176
978k
    rounds4!(abef, cdgh, w0, 0);
177
978k
    rounds4!(abef, cdgh, w1, 1);
178
978k
    rounds4!(abef, cdgh, w2, 2);
179
978k
    rounds4!(abef, cdgh, w3, 3);
180
978k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 4);
181
978k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 5);
182
978k
    schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 6);
183
978k
    schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 7);
184
978k
    schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 8);
185
978k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 9);
186
978k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 10);
187
978k
    schedule_rounds4!(abef, cdgh, w2, w3, w4, w0, w1, 11);
188
978k
    schedule_rounds4!(abef, cdgh, w3, w4, w0, w1, w2, 12);
189
978k
    schedule_rounds4!(abef, cdgh, w4, w0, w1, w2, w3, 13);
190
978k
    schedule_rounds4!(abef, cdgh, w0, w1, w2, w3, w4, 14);
191
978k
    schedule_rounds4!(abef, cdgh, w1, w2, w3, w4, w0, 15);
192
193
978k
    let [a, b, e, f] = abef;
194
978k
    let [c, d, g, h] = cdgh;
195
196
978k
    state[0] = state[0].wrapping_add(a);
197
978k
    state[1] = state[1].wrapping_add(b);
198
978k
    state[2] = state[2].wrapping_add(c);
199
978k
    state[3] = state[3].wrapping_add(d);
200
978k
    state[4] = state[4].wrapping_add(e);
201
978k
    state[5] = state[5].wrapping_add(f);
202
978k
    state[6] = state[6].wrapping_add(g);
203
978k
    state[7] = state[7].wrapping_add(h);
204
978k
}
205
206
274k
pub fn compress(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
207
274k
    let mut block_u32 = [0u32; BLOCK_LEN];
208
    // since LLVM can't properly use aliasing yet it will make
209
    // unnecessary state stores without this copy
210
274k
    let mut state_cpy = *state;
211
1.25M
    for block in blocks {
212
15.6M
        for (o, chunk) in block_u32.iter_mut().zip(block.chunks_exact(4)) {
213
15.6M
            *o = u32::from_be_bytes(chunk.try_into().unwrap());
214
15.6M
        }
215
978k
        sha256_digest_block_u32(&mut state_cpy, &block_u32);
216
    }
217
274k
    *state = state_cpy;
218
274k
}