diff --git a/sha3/src/lib.rs b/sha3/src/lib.rs index 0f87ee580..e04caf73a 100644 --- a/sha3/src/lib.rs +++ b/sha3/src/lib.rs @@ -87,6 +87,13 @@ use digest::{ mod macros; mod state; +#[cfg(all( + target_os = "zkvm", + target_vendor = "succinct", + target_arch = "riscv32" +))] +pub mod succinct; + use crate::state::Sha3State; // Paddings diff --git a/sha3/src/state.rs b/sha3/src/state.rs index 1ba9f11bd..efd81a11e 100644 --- a/sha3/src/state.rs +++ b/sha3/src/state.rs @@ -3,6 +3,13 @@ use core::convert::TryInto; const PLEN: usize = 25; const DEFAULT_ROUND_COUNT: usize = 24; +#[cfg(all( + target_os = "zkvm", + target_vendor = "succinct", + target_arch = "riscv32" +))] +use crate::succinct; + #[derive(Clone)] pub(crate) struct Sha3State { pub state: [u64; PLEN], @@ -34,7 +41,7 @@ impl Sha3State { *s ^= u64::from_le_bytes(b.try_into().unwrap()); } - keccak::p1600(&mut self.state, self.round_count); + self.permute(); } #[inline(always)] @@ -46,6 +53,22 @@ impl Sha3State { #[inline(always)] pub(crate) fn permute(&mut self) { - keccak::p1600(&mut self.state, self.round_count); + #[cfg(all( + target_os = "zkvm", + target_vendor = "succinct", + target_arch = "riscv32" + ))] + { + succinct::keccak_permute(&mut self.state); + } + + #[cfg(not(all( + target_os = "zkvm", + target_vendor = "succinct", + target_arch = "riscv32" + )))] + { + keccak::p1600(&mut self.state, self.round_count); + } } } diff --git a/sha3/src/succinct.rs b/sha3/src/succinct.rs new file mode 100644 index 000000000..fd89a166b --- /dev/null +++ b/sha3/src/succinct.rs @@ -0,0 +1,10 @@ +extern "C" { + fn syscall_keccak_permute(state: *mut u64); +} + +#[inline] +pub(crate) fn keccak_permute(state: &mut [u64; 25]) { + unsafe { + syscall_keccak_permute(state.as_mut_ptr()); + } +}