#![no_std]
pub mod codec;
pub mod mq;
pub mod shake;
#[cfg(all(not(feature = "no_avx2"),
any(target_arch = "x86_64", target_arch = "x86")))]
pub mod mq_avx2;
pub use rand_core::{CryptoRng, RngCore, Error as RngError};
pub const FN_DSA_LOGN_512: u32 = 9;
pub const FN_DSA_LOGN_1024: u32 = 10;
pub const fn sign_key_size(logn: u32) -> usize {
let n = 1usize << logn;
let nbits_fg = match logn {
2..=5 => 8,
6..=7 => 7,
8..=9 => 6,
_ => 5,
};
1 + (nbits_fg << (logn - 2)) + n
}
pub const fn vrfy_key_size(logn: u32) -> usize {
1 + (7 << (logn - 2))
}
pub const fn signature_size(logn: u32) -> usize {
44 + 3 * (256 >> (10 - logn)) + 2 * (128 >> (10 - logn))
+ 3 * (64 >> (10 - logn)) + 2 * (16 >> (10 - logn))
- 2 * (2 >> (10 - logn)) - 8 * (1 >> (10 - logn))
}
pub struct HashIdentifier<'a>(pub &'a [u8]);
pub const HASH_ID_RAW: HashIdentifier = HashIdentifier(&[0x00]);
pub const HASH_ID_ORIGINAL_FALCON: HashIdentifier = HashIdentifier(&[0xFF]);
pub const HASH_ID_SHA256: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01]);
pub const HASH_ID_SHA384: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02]);
pub const HASH_ID_SHA512: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03]);
pub const HASH_ID_SHA512_256: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x06]);
pub const HASH_ID_SHA3_256: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x08]);
pub const HASH_ID_SHA3_384: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x09]);
pub const HASH_ID_SHA3_512: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0A]);
pub const HASH_ID_SHAKE128: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0B]);
pub const HASH_ID_SHAKE256: HashIdentifier = HashIdentifier(
&[0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x0C]);
pub struct DomainContext<'a>(pub &'a [u8]);
pub const DOMAIN_NONE: DomainContext = DomainContext(b"");
pub fn hash_to_point(nonce: &[u8], hashed_vrfy_key: &[u8],
ctx: &DomainContext, id: &HashIdentifier, hv: &[u8], c: &mut [u16])
{
assert!(nonce.len() == 40);
assert!(hashed_vrfy_key.len() == 64);
assert!(ctx.0.len() <= 255);
let orig_falcon = id.0.len() == 1 && id.0[0] == 0xFF;
let raw_message = id.0.len() == 1 && id.0[0] == 0x00;
let mut sh = shake::SHAKE256::new();
sh.inject(nonce);
if orig_falcon {
sh.inject(hv);
} else {
sh.inject(hashed_vrfy_key);
sh.inject(&[if raw_message { 0u8 } else { 1u8 }]);
sh.inject(&[ctx.0.len() as u8]);
sh.inject(ctx.0);
if !raw_message {
sh.inject(id.0);
}
sh.inject(hv);
}
sh.flip();
let mut i = 0;
while i < c.len() {
let mut v = [0u8; 2];
sh.extract(&mut v);
let mut w = ((v[0] as u16) << 8) | (v[1] as u16);
if w < 61445 {
while w >= 12289 {
w -= 12289;
}
c[i] = w;
i += 1;
}
}
}
pub trait PRNG: Copy + Clone {
fn new(seed: &[u8]) -> Self;
fn next_u8(&mut self) -> u8;
fn next_u16(&mut self) -> u16;
fn next_u64(&mut self) -> u64;
}
#[cfg(all(not(feature = "no_avx2"),
any(target_arch = "x86_64", target_arch = "x86")))]
cpufeatures::new!(cpuid_avx2, "avx2");
#[cfg(all(not(feature = "no_avx2"),
any(target_arch = "x86_64", target_arch = "x86")))]
pub fn has_avx2() -> bool {
cpuid_avx2::get()
}