pdc-rs 1.0.1

pdc (perfectly diffused cipher)
Documentation
use crate::{key_schedule, pdc::{decrypt_block, encrypt_block}};

pub fn encrypt_data(data: &Vec<u8>, key: &Vec<u8>, iv: &Vec<u8>) -> Vec<u8> {
    if data.len() % 16 != 0 {
        panic!("Data length must be a multiple of 16; You must pad your data before encrypting it")
    }
    if iv.len() != 16 {
        panic!("IV must be 16 bytes");
    }

    let mut ciphertext: Vec<u8> = Vec::new();
    let mut blocks: Vec<Vec<u8>> = Vec::new();
    let round_keys = key_schedule::get_round_keys(key);

    for i in (0..data.len()).step_by(16) {
        let mut block = data[i..i+16].to_vec();
        if i == 0 {
            for j in 0..16 {
                block[j] ^= iv[j];
            }
        } else {
            let previous_block = &blocks[i / 16 - 1];
            for j in 0..16 {
                block[j] ^= previous_block[j];
            }
        }
        encrypt_block(&mut block, &round_keys);
        blocks.push(block);
    }

    for mut block in blocks {
        ciphertext.append(&mut block);
    }

    return ciphertext;
}

pub fn decrypt_data(data: &Vec<u8>, key: &Vec<u8>, iv: &Vec<u8>) -> Vec<u8> {
    if data.len() % 16 != 0 {
        panic!("Data length must be a multiple of 16; You must pad your data before encrypting it")
    }
    if iv.len() != 16 {
        panic!("IV must be 16 bytes");
    }

    let mut ciphertext: Vec<u8> = Vec::new();
    let mut blocks: Vec<Vec<u8>> = Vec::new();
    let reversed_round_keys = key_schedule::reverse_round_keys(key_schedule::get_round_keys(key));

    for i in (0..data.len()).step_by(16).rev() {
        let mut block = data[i..i+16].to_vec();
        decrypt_block(&mut block, &reversed_round_keys);
        if i / 16 == 0 {
            for j in 0..16 {
                block[j] ^= iv[j];
            }
        } else {
            let previous_block = &data[i-16..i];
            for j in 0..16 {
                block[j] ^= previous_block[j];
            }
        }
        blocks.push(block);
    }
    for i in (0..blocks.len()).rev() {
        ciphertext.append(&mut blocks[i]);
    }

    return ciphertext;
}