use crate::{
consts::INITIAL_STATE,
hashfns::{execute_from_rounds, execute_until_rounds},
structs::{PenisBlock, RawBlock, SecsParam, ToBeHashed},
utils::pad,
Penis, State,
};
use alloc::vec::Vec;
#[derive(Debug)]
pub struct PenisGenerator(pub SecsParam);
impl PenisGenerator {
pub fn execute_with_initial_state(&self, tbh: ToBeHashed, initial_state: &State) -> Penis {
tbh.check_datarange().unwrap();
let padded = pad(&tbh.data);
let block_count = padded.len() / 64;
let mut penis_blocks = Vec::<PenisBlock>::with_capacity(block_count);
let mut previous_state = initial_state.clone();
let n = self.0.n as usize;
for i in 0..block_count {
let block_range_start = i * 64;
let block_range_end = (i + 1) * 64;
let block = &padded[block_range_start..block_range_end];
let is_private = tbh.is_in_confidentials(block_range_start, block_range_end);
let private_block = execute_until_rounds(block, &previous_state, n);
previous_state = execute_from_rounds(&private_block, previous_state, n);
if is_private {
penis_blocks.push(PenisBlock::Private(private_block));
} else {
let mut block_owned: RawBlock = [0u8; 64];
block_owned.copy_from_slice(block);
penis_blocks.push(PenisBlock::Public(block_owned));
}
}
Penis(penis_blocks)
}
#[inline]
pub fn execute(&self, tbh: ToBeHashed) -> Penis {
self.execute_with_initial_state(tbh, &INITIAL_STATE)
}
}