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