ab_riscv_interpreter/rv32/zk/zkn/zkne/
rv32_zkne_helpers.rs1use ab_riscv_primitives::prelude::*;
4
5#[cfg(not(all(not(miri), target_arch = "riscv32", target_feature = "zkne")))]
10#[expect(
11 clippy::inline_modules,
12 reason = "Small internal API, it is more readable this way"
13)]
14pub(in super::super) mod soft {
15 use crate::rv32::zk::zkn::zknd::rv32_zknd_helpers::{SBOX, gmul};
16
17 #[inline(always)]
31 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
32 pub(super) fn mix_col_byte(b: u8) -> u32 {
33 let r0 = u32::from(gmul(b, 0x02));
34 let r1 = u32::from(b);
35 let r2 = u32::from(b);
36 let r3 = u32::from(gmul(b, 0x03));
37 r0 | (r1 << 8) | (r2 << 16) | (r3 << 24)
38 }
39
40 #[inline(always)]
50 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
51 pub(super) fn aes32esi(rs1: u32, rs2: u32, bs: u8) -> u32 {
52 let shamt = u32::from(bs) * 8;
53 let si = ((rs2 >> shamt) & 0xff) as u8;
54 let so = u32::from(SBOX[usize::from(si)]);
55 rs1 ^ so.rotate_left(shamt)
56 }
57
58 #[inline(always)]
69 #[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
70 pub(super) fn aes32esmi(rs1: u32, rs2: u32, bs: u8) -> u32 {
71 let shamt = u32::from(bs) * 8;
72 let si = ((rs2 >> shamt) & 0xff) as u8;
73 let so = SBOX[usize::from(si)];
74 let mixed = mix_col_byte(so);
75 rs1 ^ mixed.rotate_left(shamt)
76 }
77}
78
79#[inline(always)]
80#[doc(hidden)]
81#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
82pub fn aes32esi(rs1: u32, rs2: u32, bs: Rv32AesBs) -> u32 {
83 cfg_select! {
85 all(
86 not(miri),
87 target_arch = "riscv32",
88 target_feature = "zkne"
89 ) => {
90 unsafe {
92 core::arch::riscv32::aes32esi(rs1, rs2, u8::from(bs))
93 }
94 }
95 _ => { soft::aes32esi(rs1, rs2, u8::from(bs)) }
96 }
97}
98
99#[inline(always)]
100#[doc(hidden)]
101#[cfg_attr(feature = "no-panic", no_panic_const::no_panic)]
102pub fn aes32esmi(rs1: u32, rs2: u32, bs: Rv32AesBs) -> u32 {
103 cfg_select! {
105 all(
106 not(miri),
107 target_arch = "riscv32",
108 target_feature = "zkne"
109 ) => {
110 unsafe {
112 core::arch::riscv32::aes32esmi(rs1, rs2, u8::from(bs))
113 }
114 }
115 _ => { soft::aes32esmi(rs1, rs2, u8::from(bs)) }
116 }
117}