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 };
}
}