round5 0.1.2

Implementation of Round5 post-quantum PKE and KEM algorithms
Documentation
use crate::r5_hash::hash;
use openssl::symm::{Cipher, Mode, Crypter};


pub fn round5_dem(c2: &mut [u8], key: &[u8], m: &[u8]) {
    let mut final_key_iv = [0u8; 48];
    let mut tag = [0u8; 16];
    let mut c2_length: usize = 0;

    hash(&mut final_key_iv, &key, key.len() as u8);

    let cipher = match key.len() {
        16 => Cipher::aes_128_gcm(),
        24 => Cipher::aes_192_gcm(),
        32 => Cipher::aes_256_gcm(),
        _ => panic!()
    };
    
    let mut crypter = Crypter::new(
            cipher, Mode::Encrypt,
            &final_key_iv[..key.len()],
            Some(&final_key_iv[key.len()..key.len() + cipher.iv_len().unwrap()])
        ).unwrap();

    crypter.pad(false);
    c2_length += crypter.update(m, c2).unwrap();
    c2_length += crypter.finalize(&mut c2[c2_length..]).unwrap();
    crypter.get_tag(&mut tag).unwrap();
    c2[c2_length..].copy_from_slice(&tag);
}

pub fn round5_dem_inverse(key: &[u8], c2: &[u8]) -> Vec<u8> {
    let mut final_key_iv = [0u8; 48];
    let mut m_length: usize = 0;
    let c2_len_no_tag = c2.len() - 16;

    hash(&mut final_key_iv, &key, key.len() as u8);

    let tag = &c2[c2_len_no_tag..].to_vec();

    let cipher = match key.len() {
        16 => Cipher::aes_128_gcm(),
        24 => Cipher::aes_192_gcm(),
        32 => Cipher::aes_256_gcm(),
        _ => panic!()
    };
    let mut decrypter = Crypter::new(
            cipher, Mode::Decrypt,
            &final_key_iv[..key.len()],
            Some(&final_key_iv[key.len()..key.len() + cipher.iv_len().unwrap()])
        ).unwrap();

    let mut output = vec![0u8; c2_len_no_tag + cipher.block_size()];
    decrypter.pad(false);
    m_length += decrypter.update(&c2[..c2_len_no_tag], &mut output).unwrap();
    decrypter.set_tag(tag).unwrap();
    m_length += decrypter.finalize(&mut output[m_length..]).unwrap();
    output.truncate(m_length);
    output
}