1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! Keccak-f[1600] s390x KIMD hardware kernel.
//!
//! The KIMD (Compute Intermediate Message Digest) instruction processes one or
//! more rate-sized blocks: XOR data into the Keccak state and apply the
//! Keccak-f[1600] permutation in hardware. This replaces both the absorb-XOR
//! and the permutation steps of the sponge core.
//!
//! SHA-3/SHAKE function codes (z14+ with MSA8):
//!
//! | Code | Algorithm | Rate (bytes) |
//! |------|-----------|-------------|
//! | 32 | SHA3-224 | 144 |
//! | 33 | SHA3-256 | 136 |
//! | 34 | SHA3-384 | 104 |
//! | 35 | SHA3-512 | 72 |
//! | 36 | SHAKE-128 | 168 |
//! | 37 | SHAKE-256 | 136 |
//!
//! The 200-byte parameter block at GR1 holds the Keccak state in FIPS 202 byte
//! order (each lane stored as 8 little-endian bytes). GR2/GR3 form an even/odd
//! pair for data address/length. CC=2 means partial completion (kernel
//! preemption) — retry the instruction.
//!
//! # Safety
//!
//! Requires MSA8 facility (CPACF, z14+). Caller must verify `s390x::MSA8`.
/// Map Keccak rate (bytes) to KIMD function code.
///
/// For rate=136 (shared by SHA3-256 and SHAKE-256), returns SHA3-256's code (33).
/// Both produce identical results for intermediate (non-final) blocks since KIMD
/// only XORs rate bytes into state + permutes.
pub const
/// Absorb one or more rate-sized blocks into the Keccak state via KIMD.
///
/// `blocks` must be a multiple of the rate corresponding to `func_code`.
/// The state is updated in place.
///
/// # Endianness
///
/// KIMD operates on the 200-byte parameter block in FIPS 202 byte order:
/// each Keccak lane is stored as 8 little-endian bytes. Our portable sponge
/// core stores lanes as native `u64` values (big-endian on s390x). We
/// byte-swap every lane before the KIMD call (native BE → LE bytes) and
/// swap back afterward (LE bytes → native BE), so the rest of the sponge
/// pipeline (portable `absorb_block`, `finalize_into_fixed`) works
/// unchanged.
///
/// # Safety
///
/// - Caller must ensure the MSA8 (CPACF) facility is available.
/// - `blocks.len()` must be a multiple of the algorithm's rate.
pub unsafe