Skip to main content

fluentbase_runtime/syscall_handler/hashing/
sha256_extend.rs

1/// Extend the SHA-256 message schedule in place.
2/// `w[0..16]` must be pre-filled with the message block (big-endian words).
3/// Fills `w[16..64]` according to the standard recurrence.
4use crate::RuntimeContext;
5use rwasm::{StoreTr, TrapCode, Value};
6
7pub fn syscall_hashing_sha256_extend_handler(
8    ctx: &mut impl StoreTr<RuntimeContext>,
9    params: &[Value],
10    _result: &mut [Value],
11) -> Result<(), TrapCode> {
12    let w_ptr: u32 = params[0].i32().unwrap() as u32;
13    let mut w = [0u32; 64];
14    let mut block = [0u8; 64];
15    ctx.memory_read(w_ptr as usize, &mut block)?;
16    for i in 0..16 {
17        w[i] = u32::from_le_bytes([
18            block[i * 4],
19            block[i * 4 + 1],
20            block[i * 4 + 2],
21            block[i * 4 + 3],
22        ]);
23    }
24    syscall_hashing_sha256_extend_impl(&mut w);
25    // Write W[0..64] back as big-endian words (256 bytes)
26    let mut out = [0u8; 64 * 4];
27    for i in 0..64 {
28        out[i * 4..i * 4 + 4].copy_from_slice(&w[i].to_le_bytes());
29    }
30    ctx.memory_write(w_ptr as usize, &out)?;
31    Ok(())
32}
33
34pub fn syscall_hashing_sha256_extend_impl(w: &mut [u32; 64]) {
35    for i in 16..64 {
36        let x = w[i - 15];
37        let y = w[i - 2];
38        let s0 = x.rotate_right(7) ^ x.rotate_right(18) ^ (x >> 3);
39        let s1 = y.rotate_right(17) ^ y.rotate_right(19) ^ (y >> 10);
40        w[i] = w[i - 16]
41            .wrapping_add(s0)
42            .wrapping_add(w[i - 7])
43            .wrapping_add(s1);
44    }
45}