field-encryption 0.0.1

A library for formattable field encyption.
Documentation
use crate::error::Error;
use crate::prf::Prf;

pub(crate) struct Fiestal {
    prfs: Vec<Prf>,
}

impl Fiestal {
    pub(crate) fn new(prfs: Vec<Prf>) -> Result<Self, Error> {
        if prfs.len() % 2 == 0 {
            Err(Error::EvenFiestalRounds)
        } else {
            Ok(Self { prfs })
        }
    }

    pub(crate) fn encrypt(&self, msg: &mut [u8], bits: u32) {
        let shift = bits / 2;
        let mut zero_right = 0xFF >> (8 - shift);
        let mut zero_left = zero_right << shift;

        let mut left = 0xF0;
        let mut right = 0x0F;

        for prf in self.prfs.iter() {
            prf.execute(msg, zero_left, left, zero_right, right);
            let tmp = left;
            left = right;
            right = tmp;

            let tmp = zero_left;
            zero_left = zero_right;
            zero_right = tmp;
        }
    }

    pub fn decrypt(&self, msg: &mut [u8], bits: u32) {
        let shift = bits / 2;
        let mut zero_right = 0xFF >> (8 - shift);
        let mut zero_left = zero_right << shift;

        let mut left = 0xF0;
        let mut right = 0x0F;

        for prf in self.prfs.iter().rev() {
            prf.execute(msg, zero_left, left, zero_right, right);
            let tmp = left;
            left = right;
            right = tmp;

            let tmp = zero_left;
            zero_left = zero_right;
            zero_right = tmp;
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn round_trip() {
        let mut prfs = vec![];
        for i in 0..7 {
            let prf = Prf::new(vec![i]);
            prfs.push(prf);
        }
        let fiestal = Fiestal::new(prfs).unwrap();
        let mut string = String::from("Hello, World! Hello, World? Hello?");
        let msg: &mut [u8] = unsafe { string.as_bytes_mut() };
        fiestal.encrypt(msg, 8);
        println!("cipher text: {:?}", msg);
        fiestal.decrypt(msg, 8);
        println!("plain text: {}", std::str::from_utf8(msg).unwrap());
    }
}