Skip to content

chore: use openvm guest library for zkvm target#3

Open
gdmlcjs wants to merge 1 commit intoopenvm/sha2-v0.11.0from
chore/sha2-v0.11.0-patch
Open

chore: use openvm guest library for zkvm target#3
gdmlcjs wants to merge 1 commit intoopenvm/sha2-v0.11.0from
chore/sha2-v0.11.0-patch

Conversation

@gdmlcjs
Copy link
Copy Markdown
Collaborator

@gdmlcjs gdmlcjs commented Apr 9, 2026

This is a patch of the sha2-0.11.0 tag that uses OpenVM at branch develop-v2.0.0-rc.1.

The Sha2 internal compress function, when compiled for ZKVM, is implemented using the OpenVM guest library openvm-sha2-guest. This is just an addition to the implementations for different the hardware/features that are supported in sha2.
A separate test directory is added to check that using the patched version gives the correct result and indeed calls the custom Sha2 opcodes.

closes INT-7392

@gdmlcjs gdmlcjs requested a review from jonathanpwang April 9, 2026 16:31
@gdmlcjs gdmlcjs self-assigned this Apr 9, 2026
@gdmlcjs gdmlcjs force-pushed the chore/sha2-v0.11.0-patch branch from 2dc4412 to 2977fd3 Compare April 9, 2026 18:33
Comment thread sha2/src/zkvm_impl.rs Outdated
Comment on lines +12 to +74
macro_rules! impl_zkvm_sha {
($name:ident, $inner:ty, $output_size:ty, $block_size:ty, $oid:expr) => {
/// Wrapper around the OpenVM zkVM implementation.
#[derive(Clone)]
pub struct $name {
inner: $inner,
}

impl Default for $name {
fn default() -> Self {
Self {
inner: <$inner>::new(),
}
}
}

impl BlockSizeUser for $name {
type BlockSize = $block_size;
}

impl Update for $name {
fn update(&mut self, data: &[u8]) {
self.inner.update(data);
}
}

impl OutputSizeUser for $name {
type OutputSize = $output_size;
}

impl FixedOutput for $name {
fn finalize_into(self, out: &mut Output<Self>) {
out.copy_from_slice(&self.inner.finalize());
}
}

impl HashMarker for $name {}

impl Reset for $name {
fn reset(&mut self) {
*self = Self::default();
}
}

impl FixedOutputReset for $name {
fn finalize_into_reset(&mut self, out: &mut Output<Self>) {
FixedOutput::finalize_into(self.clone(), out);
Reset::reset(self);
}
}

impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(concat!(stringify!($name), " { ... }"))
}
}

#[cfg(feature = "oid")]
impl AssociatedOid for $name {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid);
}
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 zkvm wrapper types don't implement SerializableState or zeroize

The buffer_fixed!-based types implement SerializableState (for state serialization/deserialization) and ZeroizeOnDrop (when the zeroize feature is enabled) through the underlying block_api core types. The zkvm wrapper types don't implement either. Users who depend on SerializableState for Sha256/Sha384/Sha512 will get compilation errors on zkvm. The zeroize gap is less concerning since zkvm environments typically don't have the same memory security model as standard OS processes, but it does mean the zeroize feature flag is silently ineffective for these three types on zkvm.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gdmlcjs were you aware of this? I'm not sure how easy it is to add those traits

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes there were a couple of traits that couldn't be implemented. I don't remember it all but I think SerializableState was only used internally, and I probably thought ZeroizeOnDrop was just not necessary / had no meaning.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized this PR needs some fixing, because there was some confusion where I thought the traits were the same as the versions I had seen for v0.10.

There are 4 traits missing from our sha struct that might affect users:

  • AlgorithmName: I should just add a few simple lines to implement it.
  • SerializableState, ZeroizeOnDrop: Any implementation should have information about (should be coupled with) the internal layout of our sha struct. The bare minimum is the size of the struct + the assumption that the data is just a slice of memory in the stack. It wouldn't be perfectly robust, but usable. Moving some parts of implementation to the openvm guest-lib might be a better option but possibly overkill.
  • CoreProxy: Only use is to expose the internal “core” type of the struct, not usable for our patched version, same situation for v0.10.

What should I do for SerializableState / ZeroizeOnDrop?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gdmlcjs on SerializableState / ZeroizeOnDrop, it seems like ideally these are just derived via some macro, but I don't know if such macros exist. It would be nice if we could derive them - I don't know how easy it is.

Considerations:

  • doing it in openvm guest libs would maybe be simpler or even necessary, but I'm not sure it will work with different sha2-v* versions
  • without macro, perhaps it becomes verbose

In all, it is preferred if we can implement them for compatibility.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SerializableState doesn't have a macro and everything is implemented by hand. ZeroizeOnDrop does have a macro but it doesn't save that much code for our structs. Also, importing those traits to openvm can make version mismatch issues. What if we made our own functions serialize, deserialize, zeroize in openvm instead and implemented the traits in the external patched crates?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry I missed this - yes exactly for the reasons you described, I think just implementing it simply makes sense. we will have to see how complicated the by hand code is

@gdmlcjs gdmlcjs force-pushed the chore/sha2-v0.11.0-patch branch from 2977fd3 to f429d7d Compare April 17, 2026 23:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants