core/stdarch/crates/core_arch/src/riscv32/zk.rs
1#[cfg(test)]
2use stdarch_test::assert_instr;
3
4unsafe extern "unadjusted" {
5 #[link_name = "llvm.riscv.aes32esi"]
6 fn _aes32esi(rs1: i32, rs2: i32, bs: i32) -> i32;
7
8 #[link_name = "llvm.riscv.aes32esmi"]
9 fn _aes32esmi(rs1: i32, rs2: i32, bs: i32) -> i32;
10
11 #[link_name = "llvm.riscv.aes32dsi"]
12 fn _aes32dsi(rs1: i32, rs2: i32, bs: i32) -> i32;
13
14 #[link_name = "llvm.riscv.aes32dsmi"]
15 fn _aes32dsmi(rs1: i32, rs2: i32, bs: i32) -> i32;
16
17 #[link_name = "llvm.riscv.zip.i32"]
18 fn _zip(rs1: i32) -> i32;
19
20 #[link_name = "llvm.riscv.unzip.i32"]
21 fn _unzip(rs1: i32) -> i32;
22
23 #[link_name = "llvm.riscv.sha512sig0h"]
24 fn _sha512sig0h(rs1: i32, rs2: i32) -> i32;
25
26 #[link_name = "llvm.riscv.sha512sig0l"]
27 fn _sha512sig0l(rs1: i32, rs2: i32) -> i32;
28
29 #[link_name = "llvm.riscv.sha512sig1h"]
30 fn _sha512sig1h(rs1: i32, rs2: i32) -> i32;
31
32 #[link_name = "llvm.riscv.sha512sig1l"]
33 fn _sha512sig1l(rs1: i32, rs2: i32) -> i32;
34
35 #[link_name = "llvm.riscv.sha512sum0r"]
36 fn _sha512sum0r(rs1: i32, rs2: i32) -> i32;
37
38 #[link_name = "llvm.riscv.sha512sum1r"]
39 fn _sha512sum1r(rs1: i32, rs2: i32) -> i32;
40}
41
42/// AES final round encryption instruction for RV32.
43///
44/// This instruction sources a single byte from rs2 according to bs. To this it applies the
45/// forward AES SBox operation, before XOR’ing the result with rs1. This instruction must
46/// always be implemented such that its execution latency does not depend on the data being
47/// operated on.
48///
49/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
50///
51/// Version: v1.0.1
52///
53/// Section: 3.3
54///
55/// # Note
56///
57/// The `BS` parameter is expected to be a constant value and only the bottom 2 bits of `bs` are
58/// used.
59#[target_feature(enable = "zkne")]
60#[rustc_legacy_const_generics(2)]
61// See #1464
62// #[cfg_attr(test, assert_instr(aes32esi, BS = 0))]
63#[inline]
64#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
65pub fn aes32esi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
66 static_assert!(BS < 4);
67
68 unsafe { _aes32esi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
69}
70
71/// AES middle round encryption instruction for RV32 with.
72///
73/// This instruction sources a single byte from rs2 according to bs. To this it applies the
74/// forward AES SBox operation, and a partial forward MixColumn, before XOR’ing the result with
75/// rs1. This instruction must always be implemented such that its execution latency does not
76/// depend on the data being operated on.
77///
78/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
79///
80/// Version: v1.0.1
81///
82/// Section: 3.4
83///
84/// # Note
85///
86/// The `bs` parameter is expected to be a constant value and only the bottom 2 bits of `bs` are
87/// used.
88#[target_feature(enable = "zkne")]
89#[rustc_legacy_const_generics(2)]
90// See #1464
91// #[cfg_attr(test, assert_instr(aes32esmi, BS = 0))]
92#[inline]
93#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
94pub fn aes32esmi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
95 static_assert!(BS < 4);
96
97 unsafe { _aes32esmi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
98}
99
100/// AES final round decryption instruction for RV32.
101///
102/// This instruction sources a single byte from rs2 according to bs. To this it applies the
103/// inverse AES SBox operation, and XOR’s the result with rs1. This instruction must always be
104/// implemented such that its execution latency does not depend on the data being operated on.
105///
106/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
107///
108/// Version: v1.0.1
109///
110/// Section: 3.1
111///
112/// # Note
113///
114/// The `BS` parameter is expected to be a constant value and only the bottom 2 bits of `bs` are
115/// used.
116#[target_feature(enable = "zknd")]
117#[rustc_legacy_const_generics(2)]
118// See #1464
119// #[cfg_attr(test, assert_instr(aes32dsi, BS = 0))]
120#[inline]
121#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
122pub fn aes32dsi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
123 static_assert!(BS < 4);
124
125 unsafe { _aes32dsi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
126}
127
128/// AES middle round decryption instruction for RV32.
129///
130/// This instruction sources a single byte from rs2 according to bs. To this it applies the
131/// inverse AES SBox operation, and a partial inverse MixColumn, before XOR’ing the result with
132/// rs1. This instruction must always be implemented such that its execution latency does not
133/// depend on the data being operated on.
134///
135/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
136///
137/// Version: v1.0.1
138///
139/// Section: 3.2
140///
141/// # Note
142///
143/// The `BS` parameter is expected to be a constant value and only the bottom 2 bits of `bs` are
144/// used.
145#[target_feature(enable = "zknd")]
146#[rustc_legacy_const_generics(2)]
147// See #1464
148// #[cfg_attr(test, assert_instr(aes32dsmi, BS = 0))]
149#[inline]
150#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
151pub fn aes32dsmi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
152 static_assert!(BS < 4);
153
154 unsafe { _aes32dsmi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
155}
156
157/// Place upper/lower halves of the source register into odd/even bits of the destination
158/// respectivley.
159///
160/// This instruction places bits in the low half of the source register into the even bit
161/// positions of the destination, and bits in the high half of the source register into the odd
162/// bit positions of the destination. It is the inverse of the unzip instruction. This
163/// instruction is available only on RV32.
164///
165/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
166///
167/// Version: v1.0.1
168///
169/// Section: 3.49
170#[target_feature(enable = "zbkb")]
171// See #1464
172// #[cfg_attr(test, assert_instr(zip))]
173#[inline]
174#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
175pub fn zip(rs: u32) -> u32 {
176 unsafe { _zip(rs as i32) as u32 }
177}
178
179/// Place odd and even bits of the source word into upper/lower halves of the destination.
180///
181/// This instruction places the even bits of the source register into the low half of the
182/// destination, and the odd bits of the source into the high bits of the destination. It is
183/// the inverse of the zip instruction. This instruction is available only on RV32.
184///
185/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
186///
187/// Version: v1.0.1
188///
189/// Section: 3.45
190#[target_feature(enable = "zbkb")]
191#[cfg_attr(test, assert_instr(unzip))]
192#[inline]
193#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
194pub fn unzip(rs: u32) -> u32 {
195 unsafe { _unzip(rs as i32) as u32 }
196}
197
198/// Implements the high half of the Sigma0 transformation, as used in the SHA2-512 hash
199/// function \[49\] (Section 4.1.3).
200///
201/// This instruction is implemented on RV32 only. Used to compute the Sigma0 transform of the
202/// SHA2-512 hash function in conjunction with the sha512sig0l instruction. The transform is a
203/// 64-bit to 64-bit function, so the input and output are each represented by two 32-bit
204/// registers. This instruction must always be implemented such that its execution latency does
205/// not depend on the data being operated on.
206///
207/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
208///
209/// Version: v1.0.1
210///
211/// Section: 3.31
212#[target_feature(enable = "zknh")]
213// See #1464
214// #[cfg_attr(test, assert_instr(sha512sig0h))]
215#[inline]
216#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
217pub fn sha512sig0h(rs1: u32, rs2: u32) -> u32 {
218 unsafe { _sha512sig0h(rs1 as i32, rs2 as i32) as u32 }
219}
220
221/// Implements the low half of the Sigma0 transformation, as used in the SHA2-512 hash function
222/// \[49\] (Section 4.1.3).
223///
224/// This instruction is implemented on RV32 only. Used to compute the Sigma0 transform of the
225/// SHA2-512 hash function in conjunction with the sha512sig0h instruction. The transform is a
226/// 64-bit to 64-bit function, so the input and output are each represented by two 32-bit
227/// registers. This instruction must always be implemented such that its execution latency does
228/// not depend on the data being operated on.
229///
230/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
231///
232/// Version: v1.0.1
233///
234/// Section: 3.32
235#[target_feature(enable = "zknh")]
236// See #1464
237// #[cfg_attr(test, assert_instr(sha512sig0l))]
238#[inline]
239#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
240pub fn sha512sig0l(rs1: u32, rs2: u32) -> u32 {
241 unsafe { _sha512sig0l(rs1 as i32, rs2 as i32) as u32 }
242}
243
244/// Implements the high half of the Sigma1 transformation, as used in the SHA2-512 hash
245/// function \[49\] (Section 4.1.3).
246///
247/// This instruction is implemented on RV32 only. Used to compute the Sigma1 transform of the
248/// SHA2-512 hash function in conjunction with the sha512sig1l instruction. The transform is a
249/// 64-bit to 64-bit function, so the input and output are each represented by two 32-bit
250/// registers. This instruction must always be implemented such that its execution latency does
251/// not depend on the data being operated on.
252///
253/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
254///
255/// Version: v1.0.1
256///
257/// Section: 3.33
258#[target_feature(enable = "zknh")]
259// See #1464
260// #[cfg_attr(test, assert_instr(sha512sig1h))]
261#[inline]
262#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
263pub fn sha512sig1h(rs1: u32, rs2: u32) -> u32 {
264 unsafe { _sha512sig1h(rs1 as i32, rs2 as i32) as u32 }
265}
266
267/// Implements the low half of the Sigma1 transformation, as used in the SHA2-512 hash function
268/// \[49\] (Section 4.1.3).
269///
270/// This instruction is implemented on RV32 only. Used to compute the Sigma1 transform of the
271/// SHA2-512 hash function in conjunction with the sha512sig1h instruction. The transform is a
272/// 64-bit to 64-bit function, so the input and output are each represented by two 32-bit
273/// registers. This instruction must always be implemented such that its execution latency does
274/// not depend on the data being operated on.
275///
276/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
277///
278/// Version: v1.0.1
279///
280/// Section: 3.34
281#[target_feature(enable = "zknh")]
282#[cfg_attr(test, assert_instr(sha512sig1l))]
283#[inline]
284#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
285pub fn sha512sig1l(rs1: u32, rs2: u32) -> u32 {
286 unsafe { _sha512sig1l(rs1 as i32, rs2 as i32) as u32 }
287}
288
289/// Implements the Sum0 transformation, as used in the SHA2-512 hash function \[49\] (Section
290/// 4.1.3).
291///
292/// This instruction is implemented on RV32 only. Used to compute the Sum0 transform of the
293/// SHA2-512 hash function. The transform is a 64-bit to 64-bit function, so the input and
294/// output is represented by two 32-bit registers. This instruction must always be implemented
295/// such that its execution latency does not depend on the data being operated on.
296///
297/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
298///
299/// Version: v1.0.1
300///
301/// Section: 3.35
302#[target_feature(enable = "zknh")]
303// See #1464
304// #[cfg_attr(test, assert_instr(sha512sum0r))]
305#[inline]
306#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
307pub fn sha512sum0r(rs1: u32, rs2: u32) -> u32 {
308 unsafe { _sha512sum0r(rs1 as i32, rs2 as i32) as u32 }
309}
310
311/// Implements the Sum1 transformation, as used in the SHA2-512 hash function \[49\] (Section
312/// 4.1.3).
313///
314/// This instruction is implemented on RV32 only. Used to compute the Sum1 transform of the
315/// SHA2-512 hash function. The transform is a 64-bit to 64-bit function, so the input and
316/// output is represented by two 32-bit registers. This instruction must always be implemented
317/// such that its execution latency does not depend on the data being operated on.
318///
319/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
320///
321/// Version: v1.0.1
322///
323/// Section: 3.36
324#[target_feature(enable = "zknh")]
325// See #1464
326// #[cfg_attr(test, assert_instr(sha512sum1r))]
327#[inline]
328#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
329pub fn sha512sum1r(rs1: u32, rs2: u32) -> u32 {
330 unsafe { _sha512sum1r(rs1 as i32, rs2 as i32) as u32 }
331}