Skip to content

SHA-2

The SHA-2 extension guest provides functions that are meant to be linked to other external libraries. The external libraries can use these functions as a hook for SHA-2 intrinsics. This is enabled only when the target is zkvm. We support the SHA-256 and SHA-512 hash functions.

We provide the following functions to compute the SHA-2 compression function.

  • unsafe extern "C" fn zkvm_shaXXX_impl(state: *const u8, input: *const u8, output: *mut u8) where XXX is 256 or 512. These functions have C ABI. They take in a pointer to the current hasher state (state), a pointer to the next block of the message (input), and a pointer where the new hasher state will be written (output). state is expected to be a pointer to 8 little-endian words, even though its type is *const u8. For Sha256 that means it is a pointer to [u32; 8], and for Sha512 it's [u64; 8].

In the external library, you can do something like the following:

unsafe extern "C" {
    unsafe fn zkvm_sha256_impl(state: *const u8, input: *const u8, output: *mut u8);
}
 
fn sha256(input: &[u8]) -> [u8; 32] {
    #[cfg(target_os = "zkvm")]
    {
        let mut state = [
            0x6a09e667,
            0xbb67ae85,
            0x3c6ef372,
            0xa54ff53a,
            0x510e527f,
            0x9b05688c,
            0x1f83d9ab,
            0x5be0cd19,
        ];
        let padded_input = add_padding(input);
        for input_block in padded_input.chunks_exact(64) {
            let mut output = [0u32; 8];
            unsafe {
                zkvm_sha256_impl(
                    state.as_ptr() as *const u8,
                    input_block.as_ptr(),
                    output.as_mut_ptr() as *mut u8,
                );
            }
            state = output;
        }
 
        let mut digest = [0u8; 32];
        for (i, word) in state.iter().enumerate() {
            digest[i * 4..(i + 1) * 4].copy_from_slice(&word.to_be_bytes());
        }
        digest
    }
    #[cfg(not(target_os = "zkvm"))] {
        unimplemented!("native sha256 is only available on zkvm target")
    }
}

Here, add_padding applies the standard SHA-2 padding (append a 1 bit, pad with 0 bits, then append the message length) so the input is a multiple of the block size, since zkvm_shaXXX_impl only operates on full blocks.

Config parameters

For the guest program to build successfully add the following to your .toml file:

[app_vm_config.sha2]