use proofman_fields::PrimeField64;
use zisk_precomp_common::{MemBusHelpers, MemProcessor, PrecompileMemInputs};
use zisk_common::OPERATION_PRECOMPILED_BUS_DATA_SIZE;
use zisk_core::blake2br;
use crate::blake2_constants::{
DIRECT_READ_PARAMS, PARAMS, PARAM_CHUNKS, READ_PARAMS, START_READ_PARAMS,
};
use crate::Blake2SM;
impl<F: PrimeField64> PrecompileMemInputs for Blake2SM<F> {
fn generate<P: MemProcessor>(
addr_main: u32,
step_main: u64,
data: &[u64],
only_counters: bool,
mem_processors: &mut P,
) {
for iparam in 0..PARAMS {
MemBusHelpers::mem_aligned_read(
addr_main + iparam as u32 * 8,
step_main,
data[OPERATION_PRECOMPILED_BUS_DATA_SIZE + iparam],
mem_processors,
);
}
for iparam in 0..READ_PARAMS {
let param_idx = iparam + 1;
let param_addr = data[OPERATION_PRECOMPILED_BUS_DATA_SIZE + param_idx] as u32;
for ichunk in 0..PARAM_CHUNKS {
MemBusHelpers::mem_aligned_read(
param_addr + ichunk as u32 * 8,
step_main,
data[START_READ_PARAMS + iparam * PARAM_CHUNKS + ichunk],
mem_processors,
);
}
}
let mut write_data = [0u64; PARAM_CHUNKS];
if !only_counters {
let index = data[OPERATION_PRECOMPILED_BUS_DATA_SIZE];
let mut state: [u64; 16] =
data[START_READ_PARAMS..START_READ_PARAMS + PARAM_CHUNKS].try_into().unwrap();
let input: [u64; 16] = data
[START_READ_PARAMS + PARAM_CHUNKS..START_READ_PARAMS + 2 * PARAM_CHUNKS]
.try_into()
.unwrap();
blake2br(index, &mut state, &input);
write_data.copy_from_slice(&state);
}
let write_addr = data[OPERATION_PRECOMPILED_BUS_DATA_SIZE + DIRECT_READ_PARAMS] as u32;
for (ichunk, write_data) in write_data.iter().enumerate().take(PARAM_CHUNKS) {
let param_addr = write_addr + ichunk as u32 * 8;
MemBusHelpers::mem_aligned_write(param_addr, step_main, *write_data, mem_processors);
}
}
fn should_skip<P: MemProcessor>(addr_main: u32, data: &[u64], mem_processors: &mut P) -> bool {
for iparam in 0..PARAMS {
let addr = addr_main + iparam as u32 * 8;
if !mem_processors.skip_addr(addr) {
return false;
}
}
for iparam in 0..READ_PARAMS {
let param_idx = iparam + 1;
let param_addr = data[OPERATION_PRECOMPILED_BUS_DATA_SIZE + param_idx] as u32;
for ichunk in 0..PARAM_CHUNKS {
let addr = param_addr + ichunk as u32 * 8;
if !mem_processors.skip_addr(addr) {
return false;
}
}
}
let write_addr = data[OPERATION_PRECOMPILED_BUS_DATA_SIZE + DIRECT_READ_PARAMS] as u32;
for ichunk in 0..PARAM_CHUNKS {
let addr = write_addr + ichunk as u32 * 8;
if !mem_processors.skip_addr(addr) {
return false;
}
}
true
}
}