zest4096 0.1.21

ChaCha based hash for faster, larger blocks
Documentation
use crate::{zest_block::ZestBlock, zest_hash::zest4096};

//Can be parallelized. Keep in mind that the key,
//init_ctr_enc, init_result_dgst, and init_ctr_dgst
//should be consistent across encoding and decoding.

//The key should be unique for every single message (as a nonce in itself)
//for maximum protection.

pub fn zest_dec(
    cipher_blocks: Vec<ZestBlock>,
    key: ZestBlock,
    init_ctr_dec: Option<ZestBlock>,
    init_result_dgst: Option<ZestBlock>,
    init_ctr_dgst: Option<ZestBlock>,
) -> Option<Vec<ZestBlock>> {
    //Variables needed for decryption
    let mut text_out = vec![];
    let mut counter = init_ctr_dec.unwrap_or_else(ZestBlock::new);
    //Variables needed for calculating digest
    let mut result_dgst = init_result_dgst.unwrap_or_else(ZestBlock::new);
    let mut ctr_dgst = init_ctr_dgst.unwrap_or_else(ZestBlock::new);
    for block in cipher_blocks.iter().take(cipher_blocks.len() - 1) {
        //Generate CSPRNG data stream and extract data.
        let mut hashed_out = zest4096(key ^ counter);
        hashed_out ^= *block;
        counter.increment_block();
        text_out.push(hashed_out);

        //Compute partial digest
        result_dgst ^= zest4096(hashed_out + ctr_dgst);
        ctr_dgst.increment_block();
    }
    //Check if there *is* a encoded digest attached to the recieved data
    if let Some(digest_enc) = cipher_blocks.last() {
        if *digest_enc == result_dgst {
            return Some(text_out);
        }
    }
    //If there is no digest, or the digest matched is not identical to the
    //calculated digest, then the message can't be verified.
    None
}