round5 0.1.2

Implementation of Round5 post-quantum PKE and KEM algorithms
Documentation
mod a_random;
mod a_fixed;
mod permutations;
pub mod matrix;

use crate::drbg::DRBG;
use a_fixed::get_a_fixed;
use a_random::create_a_random;
use crate::parameters::Parameters;
use permutations::{permutation_tau_1, permutation_tau_2};


pub fn create_a(sigma: &[u8], params: &Parameters) -> Vec<u16> {
    let mut a_master: Vec<u16>;
    let a_permutation: Vec<u32>;
    let els_row = params.k as u16 * params.n as u16;

    match params.tau {
        0 => {
            create_a_random(sigma, params)
        }
        1 => {
            a_master = get_a_fixed();
            a_permutation = permutation_tau_1(sigma, params);
            let mut a = vec![0u16; params.k as usize * params.k as usize * params.n as usize];
            for i in 0u16..params.k as u16 {
                let dst_from = i as usize * els_row as usize;
                let src_from = a_permutation[i as usize] as usize;

                let mod_d = a_permutation[i as usize] % params.d as u32;
                if mod_d == 0 {
                    let dst_to = dst_from + els_row as usize;
                    let src_to = src_from + els_row as usize;
                    a[dst_from..dst_to].copy_from_slice(&a_master[src_from..src_to]);
                }
                else {
                    let dst_to = (els_row - mod_d as u16) as usize;
                    let src_to = src_from + els_row as usize;
                    a[dst_from..dst_to].copy_from_slice(&a_master[src_from..src_to]);
                    let dst_from = dst_from + (els_row - mod_d as u16) as usize;
                    let src_from = src_from - mod_d as usize;
                    let dst_to = dst_from + mod_d as usize;
                    let src_to = src_to + mod_d as usize;
                    a[dst_from..dst_to].copy_from_slice(&a_master[src_from..src_to]);
                }
            }
            a
        },
        2 => {
            a_master = create_a_random(sigma, params);
            a_master.reserve_exact(params.d as usize);
            let slice = &a_master[..params.d as usize].to_vec();
            a_master.extend_from_slice(slice);
            a_permutation = permutation_tau_2(sigma, params);
            let mut a = vec![0u16; params.k as usize * params.k as usize * params.n as usize];
            for i in 0u16..params.k as u16 {
                let dst_from = i as usize * els_row as usize;
                let dst_to = dst_from + els_row as usize;
                let src_from = a_permutation[i as usize] as usize;
                let src_to = src_from + els_row as usize; 
                a[dst_from..dst_to].copy_from_slice(&a_master[src_from..src_to]);
            }
            a
        }
        _ => {
            panic!()
        }
    }
}

pub fn create_s_t(sk: &[u8], params: &Parameters) -> Vec<u16> {
    let mut drbg = DRBG::new(sk, None);

    let mut s_t = vec![0u16; params.k as usize * params.n_bar as usize * params.n as usize];
    let len = params.k as usize * params.n as usize;
    for i in 0..params.n_bar {
        let from = i as usize * len;
        let to = from + len;
        create_secret_vector(&mut s_t[from..to], &mut drbg, params.h);
    }
    s_t
}

pub fn create_r_t(rho: &[u8], params: &Parameters) -> Vec<u16> {
    let mut drbg = DRBG::new(rho, None);

    let mut r_t = vec![0u16; params.k as usize * params.m_bar as usize * params.n as usize];
    let len = params.k as usize * params.n as usize;
    for i in 0..params.m_bar {
        let from = i as usize * len;
        let to = from + len;
        create_secret_vector(&mut r_t[from..to], &mut drbg, params.h);
    }
    r_t
}

fn create_secret_vector(vector: &mut [u16], drbg: &mut DRBG, h: u16) {
    let mut idx: u16;
    for i in 0..h {
        while {
            idx = drbg.sampler16(vector.len() as u32);
            vector[idx as usize] != 0
        } {};
        vector[idx as usize] = if i & 1 != 0 { std::u16::MAX } else { 1u16 };
    }
}