Skip to main content

ab_riscv_interpreter/rv32/zk/zkn/zknh/
rv32_zknh_helpers.rs

1//! Opaque helpers for RV32 Zknh extension
2
3#[inline(always)]
4#[doc(hidden)]
5#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
6pub fn sha256sig0(x: u32) -> u32 {
7    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
8    cfg_select! {
9        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
10            // SAFETY: Compile-time checked for supported feature
11            unsafe { core::arch::riscv32::sha256sig0(x) }
12        }
13        _ => {
14            x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3)
15        }
16    }
17}
18
19#[inline(always)]
20#[doc(hidden)]
21#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
22pub fn sha256sig1(x: u32) -> u32 {
23    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
24    cfg_select! {
25        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
26            // SAFETY: Compile-time checked for supported feature
27            unsafe { core::arch::riscv32::sha256sig1(x) }
28        }
29        _ => {
30            x.rotate_right(17) ^ x.rotate_right(19) ^ (x >> 10)
31        }
32    }
33}
34
35#[inline(always)]
36#[doc(hidden)]
37#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
38pub fn sha256sum0(x: u32) -> u32 {
39    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
40    cfg_select! {
41        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
42            // SAFETY: Compile-time checked for supported feature
43            unsafe { core::arch::riscv32::sha256sum0(x) }
44        }
45        _ => {
46            x.rotate_right(2) ^ x.rotate_right(13) ^ x.rotate_right(22)
47        }
48    }
49}
50
51#[inline(always)]
52#[doc(hidden)]
53#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
54pub fn sha256sum1(x: u32) -> u32 {
55    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
56    cfg_select! {
57        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
58            // SAFETY: Compile-time checked for supported feature
59            unsafe { core::arch::riscv32::sha256sum1(x) }
60        }
61        _ => {
62            x.rotate_right(6) ^ x.rotate_right(11) ^ x.rotate_right(25)
63        }
64    }
65}
66
67// SHA-512 sigma0: ROR64(x,1) ^ ROR64(x,8) ^ SHR64(x,7)
68
69/// High 32 bits of SHA-512 sigma0. rs1 = HIGH word, rs2 = LOW word.
70///
71/// ```text
72/// ROR64(x,1).hi  = (rs1>>1)  ^ (rs2<<31)
73/// ROR64(x,8).hi  = (rs1>>8)  ^ (rs2<<24)
74/// SHR64(x,7).hi  =  rs1>>7              <- shift: no rs2 contribution
75/// ```
76#[inline(always)]
77#[doc(hidden)]
78#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
79pub fn sha512sig0h(rs1: u32, rs2: u32) -> u32 {
80    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
81    cfg_select! {
82        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
83            // SAFETY: Compile-time checked for supported feature
84            unsafe { core::arch::riscv32::sha512sig0h(rs1, rs2) }
85        }
86        _ => {
87            (rs1 >> 1) ^ (rs2 << 31) ^ (rs1 >> 8) ^ (rs2 << 24) ^ (rs1 >> 7)
88        }
89    }
90}
91
92/// Low 32 bits of SHA-512 sigma0. rs1 = LOW word, rs2 = HIGH word.
93///
94/// ```text
95/// ROR64(x,1).lo  = (rs1>>1)  ^ (rs2<<31)
96/// ROR64(x,8).lo  = (rs1>>8)  ^ (rs2<<24)
97/// SHR64(x,7).lo  = (rs1>>7)  ^ (rs2<<25)  <- cross-boundary bits from hi
98/// ```
99#[inline(always)]
100#[doc(hidden)]
101#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
102pub fn sha512sig0l(rs1: u32, rs2: u32) -> u32 {
103    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
104    cfg_select! {
105        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
106            // SAFETY: Compile-time checked for supported feature
107            unsafe { core::arch::riscv32::sha512sig0l(rs1, rs2) }
108        }
109        _ => {
110            (rs1 >> 1) ^ (rs2 << 31) ^ (rs1 >> 8) ^ (rs2 << 24) ^ (rs1 >> 7) ^ (rs2 << 25)
111        }
112    }
113}
114
115// SHA-512 sigma1: ROR64(x,19) ^ ROR64(x,61) ^ SHR64(x,6)
116
117/// High 32 bits of SHA-512 sigma1. rs1 = HIGH word, rs2 = LOW word.
118///
119/// ```text
120/// ROR64(x,19).hi = (rs1>>19) ^ (rs2<<13)
121/// ROR64(x,61).hi = ROR64(x,32+29).hi = (rs2>>29) ^ (rs1<<3)
122/// SHR64(x,6).hi  =  rs1>>6              <- shift: no rs2 contribution
123/// ```
124#[inline(always)]
125#[doc(hidden)]
126#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
127pub fn sha512sig1h(rs1: u32, rs2: u32) -> u32 {
128    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
129    cfg_select! {
130        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
131            // SAFETY: Compile-time checked for supported feature
132            unsafe { core::arch::riscv32::sha512sig1h(rs1, rs2) }
133        }
134        _ => {
135            (rs1 >> 19) ^ (rs2 << 13) ^ (rs2 >> 29) ^ (rs1 << 3) ^ (rs1 >> 6)
136        }
137    }
138}
139
140/// Low 32 bits of SHA-512 sigma1. rs1 = LOW word, rs2 = HIGH word.
141///
142/// ```text
143/// ROR64(x,19).lo = (rs1>>19) ^ (rs2<<13)
144/// ROR64(x,61).lo = ROR64(x,32+29).lo = (rs2>>29) ^ (rs1<<3)
145/// SHR64(x,6).lo  = (rs1>>6)  ^ (rs2<<26)  <- cross-boundary bits from hi
146/// ```
147#[inline(always)]
148#[doc(hidden)]
149#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
150pub fn sha512sig1l(rs1: u32, rs2: u32) -> u32 {
151    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
152    cfg_select! {
153        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
154            // SAFETY: Compile-time checked for supported feature
155            unsafe { core::arch::riscv32::sha512sig1l(rs1, rs2) }
156        }
157        _ => {
158            (rs1 >> 19) ^ (rs2 << 13) ^ (rs2 >> 29) ^ (rs1 << 3) ^ (rs1 >> 6) ^ (rs2 << 26)
159        }
160    }
161}
162
163// SHA-512 Sum0: ROR64(x,28) ^ ROR64(x,34) ^ ROR64(x,39)
164//
165// Sail: let x = X(rs2) @ X(rs1)  =>  x[63:32] = rs2 (HIGH), x[31:0] = rs1 (LOW)
166// sum0r produces the LOW half of the result.
167//
168// ROR64({hi=rs2, lo=rs1}, 28).lo  = (rs1>>28) ^ (rs2<<4)   [n=28 < 32]
169// ROR64({hi=rs2, lo=rs1}, 34).lo  = (rs2>>2)  ^ (rs1<<30)  [n=34 = 32+2]
170// ROR64({hi=rs2, lo=rs1}, 39).lo  = (rs2>>7)  ^ (rs1<<25)  [n=39 = 32+7]
171
172/// Low 32 bits of SHA-512 Sum0. rs1 = LOW word, rs2 = HIGH word.
173///
174/// All three terms are rotations, so no asymmetric shift contribution.
175///
176/// ```text
177/// ROR64(x,28).lo = (rs1>>28) ^ (rs2<<4)
178/// ROR64(x,34).lo = ROR64(x,32+2).lo  = (rs2>>2)  ^ (rs1<<30)
179/// ROR64(x,39).lo = ROR64(x,32+7).lo  = (rs2>>7)  ^ (rs1<<25)
180/// ```
181#[inline(always)]
182#[doc(hidden)]
183#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
184pub fn sha512sum0r(rs1: u32, rs2: u32) -> u32 {
185    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
186    cfg_select! {
187        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
188            // SAFETY: Compile-time checked for supported feature
189            unsafe { core::arch::riscv32::sha512sum0r(rs1, rs2) }
190        }
191        _ => {
192            (rs1 >> 28) ^ (rs2 << 4) ^ (rs2 >> 2) ^ (rs1 << 30) ^ (rs2 >> 7) ^ (rs1 << 25)
193        }
194    }
195}
196
197// SHA-512 Sum1: ROR64(x,14) ^ ROR64(x,18) ^ ROR64(x,41)
198//
199// Sail: let x = X(rs2) @ X(rs1)  =>  x[63:32] = rs2 (HIGH), x[31:0] = rs1 (LOW)
200// sum1r produces the LOW half of the result.
201//
202// ROR64({hi=rs2, lo=rs1}, 14).lo  = (rs1>>14) ^ (rs2<<18)  [n=14 < 32]
203// ROR64({hi=rs2, lo=rs1}, 18).lo  = (rs1>>18) ^ (rs2<<14)  [n=18 < 32]
204// ROR64({hi=rs2, lo=rs1}, 41).lo  = (rs2>>9)  ^ (rs1<<23)  [n=41 = 32+9]
205
206/// Low 32 bits of SHA-512 Sum1. rs1 = LOW word, rs2 = HIGH word.
207///
208/// All three terms are rotations.
209///
210/// ```text
211/// ROR64(x,14).lo = (rs1>>14) ^ (rs2<<18)
212/// ROR64(x,18).lo = (rs1>>18) ^ (rs2<<14)
213/// ROR64(x,41).lo = ROR64(x,32+9).lo = (rs2>>9)  ^ (rs1<<23)
214/// ```
215#[inline(always)]
216#[doc(hidden)]
217#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
218pub fn sha512sum1r(rs1: u32, rs2: u32) -> u32 {
219    // TODO: Miri is excluded because corresponding intrinsic is not implemented there
220    cfg_select! {
221        all(not(miri), target_arch = "riscv32", target_feature = "zknh") => {
222            // SAFETY: Compile-time checked for supported feature
223            unsafe { core::arch::riscv32::sha512sum1r(rs1, rs2) }
224        }
225        _ => {
226            (rs1 >> 14) ^ (rs2 << 18) ^ (rs1 >> 18) ^ (rs2 << 14) ^ (rs2 >> 9) ^ (rs1 << 23)
227        }
228    }
229}