round5 0.1.2

Implementation of Round5 post-quantum PKE and KEM algorithms
Documentation
// TO-DO implement AES_DRBG

use std::io::Cursor;
use std::mem::size_of;
use crate::tiny_keccak::{Xof, Hasher, cshake::{CShake, cshake128, cshake256}};
use byteorder::{ReadBytesExt, LittleEndian};


pub struct DRBG {
    shaker: CShake
}

impl DRBG {

    pub fn new(seed: &[u8], customization: Option<&[u8]>) -> DRBG {
        let mut shaker = if seed.len() > 16 {
            CShake::v256(None, customization)
        } else {
            CShake::v128(None, customization)
        };
        shaker.absorb(seed);
        DRBG { shaker }
    }

    fn drbg(&mut self, output: &mut [u8]){
        self.shaker.squeeze(output);
    }

    pub fn sampler16(&mut self, range: u32) -> u16 {
        let range_divisor = 0x10000u32 / range;
        let range_limit = range * range_divisor;
        let mut rnd: [u8; 2] = [0, 0];
        while {
            self.drbg(&mut rnd);
            // TO-DO little-endian
            u8_to_u16!(rnd) as u32 >= range_limit
        } {};
        (u8_to_u16!(rnd) as u32 / range_divisor) as u16
    }

    pub fn sampler16_2(&mut self, range: u32) -> u16 {
        let mut rnd: [u8; 2] = [0, 0];
        self.drbg(&mut rnd);
        // TO-DO little-endian
        (u8_to_u16!(rnd) as u32 & (range - 1)) as u16
    }

    pub fn sampler16_2_once(xlen: usize, seed: &[u8], range: u32) -> Vec<u16> {
        let mut x = vec![0u8; xlen * size_of::<u16>()];
        if seed.len() > 16 {
            cshake256(x.as_mut_slice(), seed, None, None);
        } else {
            cshake128(x.as_mut_slice(), seed, None, None);
        }

        // TO-DO LITTLE_ENDIAN check
        let mut a: Vec<u16> = Vec::with_capacity(xlen);
        let mut rdr = Cursor::new(x);
        for _ in 0..xlen {
            a.push(rdr.read_u16::<LittleEndian>().unwrap() & (range - 1) as u16);
        }

        a
    }
}