// Encrypt a file with multiple starting IV states, determined by ivecs.len()
//
// Then sample each block at the offsets provided by samples argument with sha256
// and return the vec of sha states
Encrypt a file with multiple starting IV states, determined by ivecs.len()
Then sample each block at the offsets provided by samples argument with sha256
and return the vec of sha states
Encrypt a file with multiple starting IV states determined by ivecs . len () Then sample each block at the offsets provided by samples argument with sha256 and return the vec of sha states
pub fn chacha_cbc_encrypt_file_many_keys(
    blockstore: &Arc<Blockstore>,
    segment: u64,
    slots_per_segment: u64,
    ivecs: &mut [u8],
    samples: &[u64],
) -> io::Result<Vec<Hash>> {
    let api = perf_libs::api().expect("no perf libs");
    if ivecs.len() % CHACHA_BLOCK_SIZE != 0 {
        return Err(io::Error::new(
            io::ErrorKind::Other,
            format!(
                "bad IV length({}) not divisible by {} ",
                ivecs.len(),
                CHACHA_BLOCK_SIZE,
            ),
        ));
    }
    const BUFFER_SIZE: usize = 8 * 1024;
    let mut buffer = [0; BUFFER_SIZE];
    let num_keys = ivecs.len() / CHACHA_BLOCK_SIZE;
    let mut sha_states = vec![0; num_keys * size_of::<Hash>()];
    let mut int_sha_states = vec![0; num_keys * 112];
    let keys: Vec<u8> = vec![0; num_keys * CHACHA_KEY_SIZE]; // keys not used ATM, uniqueness comes from IV
    let mut current_slot = segment * slots_per_segment;
    let mut start_index = 0;
    let start_slot = current_slot;
    let mut total_size = 0;
    let mut time: f32 = 0.0;
    unsafe {
        (api.chacha_init_sha_state)(int_sha_states.as_mut_ptr(), num_keys as u32);
    }
    loop {
        match blockstore.get_data_shreds(current_slot, start_index, std::u64::MAX, &mut buffer) {
            Ok((last_index, mut size)) => {
                debug!(
                    "chacha_cuda: encrypting segment: {} num_shreds: {} data_len: {}",
                    segment,
                    last_index.saturating_sub(start_index),
                    size
                );
                if size == 0 {
                    if current_slot.saturating_sub(start_slot) < slots_per_segment {
                        current_slot += 1;
                        start_index = 0;
                        continue;
                    } else {
                        break;
                    }
                }
                if size < BUFFER_SIZE {
                    // round to the nearest key_size boundary
                    size = (size + CHACHA_KEY_SIZE - 1) & !(CHACHA_KEY_SIZE - 1);
                }
                unsafe {
                    (api.chacha_cbc_encrypt_many_sample)(
                        buffer[..size].as_ptr(),
                        int_sha_states.as_mut_ptr(),
                        size,
                        keys.as_ptr(),
                        ivecs.as_mut_ptr(),
                        num_keys as u32,
                        samples.as_ptr(),
                        samples.len() as u32,
                        total_size,
                        &mut time,
                    );
                }
                total_size += size as u64;
                start_index = last_index + 1;
            }
            Err(e) => {
                info!("Error encrypting file: {:?}", e);
                break;
            }
        }
    }
    unsafe {
        (api.chacha_end_sha_state)(
            int_sha_states.as_ptr(),
            sha_states.as_mut_ptr(),
            num_keys as u32,
        );
    }
    let mut res = Vec::new();
    for x in 0..num_keys {
        let start = x * size_of::<Hash>();
        let end = start + size_of::<Hash>();
        res.push(Hash::new(&sha_states[start..end]));
    }
    Ok(res)
}
pub fn chacha_cbc_encrypt_file_many_keys ( blockstore : & Arc < Blockstore > , segment : u64 , slots_per_segment : u64 , ivecs : & mut [ u8 ] , samples : & [ u64 ] , ) -> io :: Result < Vec < Hash > > { let api = perf_libs :: api ( ) . expect ( " " ) ; if ivecs . len ( ) % CHACHA_BLOCK_SIZE != 0 { return Err ( io :: Error :: new ( io :: ErrorKind :: Other , format ! ( " " ivecs len ( ) CHACHA_BLOCK_SIZE ) , ) ) ; } const BUFFER_SIZE : usize = 8 * 1024 ; let mut buffer = [ 0 ; BUFFER_SIZE ] ; let num_keys = ivecs . len ( ) / CHACHA_BLOCK_SIZE ; let mut sha_states = vec ! [ 0 num_keys size_of Hash ( ) ] ; let mut int_sha_states = vec ! [ 0 num_keys 112 ] ; let keys : Vec < u8 > = vec ! [ 0 num_keys CHACHA_KEY_SIZE ] ; // keys not used ATM, uniqueness comes from IV let mut current_slot = segment * slots_per_segment ; let mut start_index = 0 ; let start_slot = current_slot ; let mut total_size = 0 ; let mut time : f32 = 0.0 ; unsafe { ( api . chacha_init_sha_state ) ( int_sha_states . as_mut_ptr ( ) , num_keys as u32 ) ; } loop { match blockstore . get_data_shreds ( current_slot , start_index , std :: u64 :: MAX , & mut buffer ) { Ok ( ( last_index , mut size ) ) => { debug ! ( " " segment last_index saturating_sub ( start_index ) size ) ; if size == 0 { if current_slot . saturating_sub ( start_slot ) < slots_per_segment { current_slot += 1 ; start_index = 0 ; continue ; } else { break ; } } if size < BUFFER_SIZE { // round to the nearest key_size boundary size = ( size + CHACHA_KEY_SIZE - 1 ) & ! ( CHACHA_KEY_SIZE - 1 ) ; } unsafe { ( api . chacha_cbc_encrypt_many_sample ) ( buffer [ .. size ] . as_ptr ( ) , int_sha_states . as_mut_ptr ( ) , size , keys . as_ptr ( ) , ivecs . as_mut_ptr ( ) , num_keys as u32 , samples . as_ptr ( ) , samples . len ( ) as u32 , total_size , & mut time , ) ; } total_size += size as u64 ; start_index = last_index + 1 ; } Err ( e ) => { info ! ( " " e ) ; break ; } } } unsafe { ( api . chacha_end_sha_state ) ( int_sha_states . as_ptr ( ) , sha_states . as_mut_ptr ( ) , num_keys as u32 , ) ; } let mut res = Vec :: new ( ) ; for x in 0 .. num_keys { let start = x * size_of :: < Hash > ( ) ; let end = start + size_of :: < Hash > ( ) ; res . push ( Hash :: new ( & sha_states [ start .. end ] ) ) ; } Ok ( res ) }
Encrypt a file with multiple starting IV states, determined by ivecs.len()
Then sample each block at the offsets provided by samples argument with sha256
and return the vec of sha states
Encrypt a file with multiple starting IV states determined by ivecs . len () Then sample each block at the offsets provided by samples argument with sha256 and return the vec of sha states
blockstore
&Arc<Blockstore>
segment
u64
slots_per_segment
u64
ivecs
&mut [u8]
samples
&[u64]