use crate::crypto::{CryptoParameters, EncryptionAlgorithm, KemAlgorithm, SigAlgorithm};
use crate::errors::Error;
use std::fmt::Formatter;
use std::write;
pub(crate) mod mem;
pub fn print_tick(
f: &mut Formatter<'_>,
relative_group_id: usize,
total_groups: usize,
transfer_rate: f32,
) -> std::fmt::Result {
if can_print_progress(relative_group_id, total_groups) {
write!(
f,
" ({}% @ {} MB/s) ",
get_progress_percent(relative_group_id, total_groups),
transfer_rate
)
} else {
write!(f, "...")
}
}
fn can_print_progress(relative_group_id: usize, total_groups: usize) -> bool {
if relative_group_id != 0 && relative_group_id != total_groups.saturating_sub(1) {
const V: f32 = 0.1;
relative_group_id % (total_groups as f32 * V).ceil() as usize == 0
} else {
false
}
}
fn get_progress_percent(relative_group_id: usize, total_groups: usize) -> f32 {
100f32 * (relative_group_id as f32 / total_groups as f32)
}
pub fn const_time_compare(this: &[u8], other: &[u8]) -> bool {
let mut count = 0;
let this_len = this.len();
for idx in 0..this_len {
let val_this = this.get(idx);
let val_other = other.get(idx);
match (val_this, val_other) {
(Some(a), Some(b)) => count += (a == b) as usize,
_ => {
let _ = std::hint::black_box(count);
}
}
}
count == this.len() && count == other.len()
}
pub fn validate_crypto_params(params: &CryptoParameters) -> Result<(), Error> {
let uses_kyber_kem = params.kem_algorithm == KemAlgorithm::Kyber;
if params.encryption_algorithm == EncryptionAlgorithm::Kyber && !uses_kyber_kem {
return Err(Error::Generic(
"Invalid crypto parameter combination. Kyber encryption must be paired with Kyber KEM",
));
}
if params.encryption_algorithm == EncryptionAlgorithm::Kyber
&& params.sig_algorithm == SigAlgorithm::None
{
return Err(Error::Generic(
"A post-quantum signature scheme must be selected when using Kyber encryption",
));
}
Ok(())
}