core/stdarch/crates/core_arch/src/riscv64/
zk.rs

1#[cfg(test)]
2use stdarch_test::assert_instr;
3
4use crate::arch::asm;
5
6unsafe extern "unadjusted" {
7    #[link_name = "llvm.riscv.aes64es"]
8    fn _aes64es(rs1: i64, rs2: i64) -> i64;
9
10    #[link_name = "llvm.riscv.aes64esm"]
11    fn _aes64esm(rs1: i64, rs2: i64) -> i64;
12
13    #[link_name = "llvm.riscv.aes64ds"]
14    fn _aes64ds(rs1: i64, rs2: i64) -> i64;
15
16    #[link_name = "llvm.riscv.aes64dsm"]
17    fn _aes64dsm(rs1: i64, rs2: i64) -> i64;
18
19    #[link_name = "llvm.riscv.aes64im"]
20    fn _aes64im(rs1: i64) -> i64;
21
22    #[link_name = "llvm.riscv.sha512sig0"]
23    fn _sha512sig0(rs1: i64) -> i64;
24
25    #[link_name = "llvm.riscv.sha512sig1"]
26    fn _sha512sig1(rs1: i64) -> i64;
27
28    #[link_name = "llvm.riscv.sha512sum0"]
29    fn _sha512sum0(rs1: i64) -> i64;
30
31    #[link_name = "llvm.riscv.sha512sum1"]
32    fn _sha512sum1(rs1: i64) -> i64;
33}
34
35/// AES final round encryption instruction for RV64.
36///
37/// Uses the two 64-bit source registers to represent the entire AES state, and produces half
38/// of the next round output, applying the ShiftRows and SubBytes steps. This instruction must
39/// always be implemented such that its execution latency does not depend on the data being
40/// operated on.
41///
42/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
43///
44/// Version: v1.0.1
45///
46/// Section: 3.7
47#[target_feature(enable = "zkne")]
48#[cfg_attr(test, assert_instr(aes64es))]
49#[inline]
50#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
51pub fn aes64es(rs1: u64, rs2: u64) -> u64 {
52    unsafe { _aes64es(rs1 as i64, rs2 as i64) as u64 }
53}
54
55/// AES middle round encryption instruction for RV64.
56///
57/// Uses the two 64-bit source registers to represent the entire AES state, and produces half
58/// of the next round output, applying the ShiftRows, SubBytes and MixColumns steps. This
59/// instruction must always be implemented such that its execution latency does not depend on
60/// the data being operated on.
61///
62/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
63///
64/// Version: v1.0.1
65///
66/// Section: 3.8
67#[target_feature(enable = "zkne")]
68#[cfg_attr(test, assert_instr(aes64esm))]
69#[inline]
70#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
71pub fn aes64esm(rs1: u64, rs2: u64) -> u64 {
72    unsafe { _aes64esm(rs1 as i64, rs2 as i64) as u64 }
73}
74
75/// AES final round decryption instruction for RV64.
76///
77/// Uses the two 64-bit source registers to represent the entire AES state, and produces half
78/// of the next round output, applying the Inverse ShiftRows and SubBytes steps. This
79/// instruction must always be implemented such that its execution latency does not depend on
80/// the data being operated on.
81///
82/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
83///
84/// Version: v1.0.1
85///
86/// Section: 3.5
87#[target_feature(enable = "zknd")]
88#[cfg_attr(test, assert_instr(aes64ds))]
89#[inline]
90#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
91pub fn aes64ds(rs1: u64, rs2: u64) -> u64 {
92    unsafe { _aes64ds(rs1 as i64, rs2 as i64) as u64 }
93}
94
95/// AES middle round decryption instruction for RV64.
96///
97/// Uses the two 64-bit source registers to represent the entire AES state, and produces half
98/// of the next round output, applying the Inverse ShiftRows, SubBytes and MixColumns steps.
99/// This instruction must always be implemented such that its execution latency does not depend
100/// on the data being operated on.
101///
102/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
103///
104/// Version: v1.0.1
105///
106/// Section: 3.6
107#[target_feature(enable = "zknd")]
108#[cfg_attr(test, assert_instr(aes64dsm))]
109#[inline]
110#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
111pub fn aes64dsm(rs1: u64, rs2: u64) -> u64 {
112    unsafe { _aes64dsm(rs1 as i64, rs2 as i64) as u64 }
113}
114
115/// This instruction implements part of the KeySchedule operation for the AES Block cipher
116/// involving the SBox operation.
117///
118/// This instruction implements the rotation, SubBytes and Round Constant addition steps of the
119/// AES block cipher Key Schedule. This instruction must always be implemented such that its
120/// execution latency does not depend on the data being operated on. Note that rnum must be in
121/// the range 0x0..0xA. The values 0xB..0xF are reserved.
122///
123/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
124///
125/// Version: v1.0.1
126///
127/// Section: 3.10
128///
129/// # Note
130///
131/// The `RNUM` parameter is expected to be a constant value inside the range of `0..=10`.
132#[target_feature(enable = "zkne_or_zknd")]
133#[rustc_legacy_const_generics(1)]
134#[inline]
135#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
136pub fn aes64ks1i<const RNUM: u8>(rs1: u64) -> u64 {
137    static_assert!(RNUM <= 10);
138    unsafe {
139        let rd: u64;
140        asm!(
141            ".option push",
142            ".option arch, +zkne",
143            "aes64ks1i {}, {}, {}",
144            ".option pop",
145            lateout(reg) rd,
146            in(reg) rs1,
147            const RNUM,
148            options(pure, nomem, nostack, preserves_flags)
149        );
150        rd
151    }
152}
153
154/// This instruction implements part of the KeySchedule operation for the AES Block cipher.
155///
156/// This instruction implements the additional XOR’ing of key words as part of the AES block
157/// cipher Key Schedule. This instruction must always be implemented such that its execution
158/// latency does not depend on the data being operated on.
159///
160/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
161///
162/// Version: v1.0.1
163///
164/// Section: 3.11
165#[target_feature(enable = "zkne_or_zknd")]
166#[inline]
167#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
168pub fn aes64ks2(rs1: u64, rs2: u64) -> u64 {
169    unsafe {
170        let rd: u64;
171        asm!(
172            ".option push",
173            ".option arch, +zkne",
174            "aes64ks2 {}, {}, {}",
175            ".option pop",
176            lateout(reg) rd,
177            in(reg) rs1,
178            in(reg) rs2,
179            options(pure, nomem, nostack, preserves_flags)
180        );
181        rd
182    }
183}
184
185/// This instruction accelerates the inverse MixColumns step of the AES Block Cipher, and is used to aid creation of
186/// the decryption KeySchedule.
187///
188/// The instruction applies the inverse MixColumns transformation to two columns of the state array, packed
189/// into a single 64-bit register. It is used to create the inverse cipher KeySchedule, according to the equivalent
190/// inverse cipher construction in (Page 23, Section 5.3.5). This instruction must always be implemented
191/// such that its execution latency does not depend on the data being operated on.
192///
193/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
194///
195/// Version: v1.0.1
196///
197/// Section: 3.9
198#[target_feature(enable = "zknd")]
199#[cfg_attr(test, assert_instr(aes64im))]
200#[inline]
201#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
202pub fn aes64im(rs1: u64) -> u64 {
203    unsafe { _aes64im(rs1 as i64) as u64 }
204}
205
206/// Implements the Sigma0 transformation function as used in the SHA2-512 hash function \[49\]
207/// (Section 4.1.3).
208///
209/// This instruction is supported for the RV64 base architecture. It implements the Sigma0
210/// transform of the SHA2-512 hash function. \[49\]. This instruction must always be
211/// implemented such that its execution latency does not depend on the data being operated on.
212///
213/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
214///
215/// Version: v1.0.1
216///
217/// Section: 3.37
218#[target_feature(enable = "zknh")]
219#[cfg_attr(test, assert_instr(sha512sig0))]
220#[inline]
221#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
222pub fn sha512sig0(rs1: u64) -> u64 {
223    unsafe { _sha512sig0(rs1 as i64) as u64 }
224}
225
226/// Implements the Sigma1 transformation function as used in the SHA2-512 hash function \[49\]
227/// (Section 4.1.3).
228///
229/// This instruction is supported for the RV64 base architecture. It implements the Sigma1
230/// transform of the SHA2-512 hash function. \[49\]. This instruction must always be
231/// implemented such that its execution latency does not depend on the data being operated on.
232///
233/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
234///
235/// Version: v1.0.1
236///
237/// Section: 3.38
238#[target_feature(enable = "zknh")]
239#[cfg_attr(test, assert_instr(sha512sig1))]
240#[inline]
241#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
242pub fn sha512sig1(rs1: u64) -> u64 {
243    unsafe { _sha512sig1(rs1 as i64) as u64 }
244}
245
246/// Implements the Sum0 transformation function as used in the SHA2-512 hash function \[49\]
247/// (Section 4.1.3).
248///
249/// This instruction is supported for the RV64 base architecture. It implements the Sum0
250/// transform of the SHA2-512 hash function. \[49\]. This instruction must always be
251/// implemented such that its execution latency does 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.39
258#[target_feature(enable = "zknh")]
259#[cfg_attr(test, assert_instr(sha512sum0))]
260#[inline]
261#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
262pub fn sha512sum0(rs1: u64) -> u64 {
263    unsafe { _sha512sum0(rs1 as i64) as u64 }
264}
265
266/// Implements the Sum1 transformation function as used in the SHA2-512 hash function \[49\]
267/// (Section 4.1.3).
268///
269/// This instruction is supported for the RV64 base architecture. It implements the Sum1
270/// transform of the SHA2-512 hash function. \[49\]. This instruction must always be
271/// implemented such that its execution latency does not depend on the data being operated on.
272///
273/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
274///
275/// Version: v1.0.1
276///
277/// Section: 3.40
278#[target_feature(enable = "zknh")]
279#[cfg_attr(test, assert_instr(sha512sum1))]
280#[inline]
281#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
282pub fn sha512sum1(rs1: u64) -> u64 {
283    unsafe { _sha512sum1(rs1 as i64) as u64 }
284}