use crate::ml_dsa::params::MlDsaParams;
pub const N: usize = 256;
pub const Q: i32 = 8380417;
pub trait ArcanumDsaParams: Clone + Send + Sync + 'static {
const K: usize;
const L: usize;
const ETA: usize;
const TAU: usize;
const BETA: u32;
const GAMMA1: u32;
const GAMMA2: u32;
const OMEGA: usize;
const LAMBDA: usize;
const ML_DSA_EQUIVALENT_DIM: usize;
const DIMENSION: usize = N * (Self::K + Self::L);
const SECURITY_MARGIN_PERCENT: usize =
(Self::DIMENSION * 100 / Self::ML_DSA_EQUIVALENT_DIM) - 100;
}
#[derive(Clone, Copy, Debug)]
pub struct Params44;
impl ArcanumDsaParams for Params44 {
const K: usize = 4;
const L: usize = 4; const ETA: usize = 2;
const TAU: usize = 39;
const BETA: u32 = 78; const GAMMA1: u32 = 1 << 17; const GAMMA2: u32 = (Q as u32 - 1) / 88;
const OMEGA: usize = 80;
const LAMBDA: usize = 32; const ML_DSA_EQUIVALENT_DIM: usize = 2048; }
impl MlDsaParams for Params44 {
const K: usize = 4;
const L: usize = 4;
const ETA: usize = 2;
const BETA: u32 = 78;
const GAMMA1: u32 = 1 << 17;
const GAMMA2: u32 = (Q as u32 - 1) / 88;
const TAU: usize = 39;
const LAMBDA: usize = 128; const OMEGA: usize = 80;
const PK_SIZE: usize = 1312; const SK_SIZE: usize = 2560; const SIG_SIZE: usize = 2420; const ALGORITHM: &'static str = "Arcanum-DSA-44";
const SECURITY_LEVEL: usize = 2;
}
#[derive(Clone, Copy, Debug)]
pub struct Params65;
impl ArcanumDsaParams for Params65 {
const K: usize = 7;
const L: usize = 4; const ETA: usize = 4;
const TAU: usize = 49;
const BETA: u32 = 196; const GAMMA1: u32 = 1 << 19; const GAMMA2: u32 = (Q as u32 - 1) / 32;
const OMEGA: usize = 55;
const LAMBDA: usize = 48; const ML_DSA_EQUIVALENT_DIM: usize = 2816; }
impl MlDsaParams for Params65 {
const K: usize = 7;
const L: usize = 4;
const ETA: usize = 4;
const BETA: u32 = 196;
const GAMMA1: u32 = 1 << 19;
const GAMMA2: u32 = (Q as u32 - 1) / 32;
const TAU: usize = 49;
const LAMBDA: usize = 192; const OMEGA: usize = 55;
const PK_SIZE: usize = 2272;
const SK_SIZE: usize = 4448;
const SIG_SIZE: usize = 2670;
const ALGORITHM: &'static str = "Arcanum-DSA-65";
const SECURITY_LEVEL: usize = 3;
}
#[derive(Clone, Debug)]
pub struct Params87;
impl ArcanumDsaParams for Params87 {
const K: usize = 8;
const L: usize = 8; const ETA: usize = 2;
const TAU: usize = 60;
const BETA: u32 = 120; const GAMMA1: u32 = 1 << 19; const GAMMA2: u32 = (Q as u32 - 1) / 32;
const OMEGA: usize = 75;
const LAMBDA: usize = 64; const ML_DSA_EQUIVALENT_DIM: usize = 3840; }
impl MlDsaParams for Params87 {
const K: usize = 8;
const L: usize = 8;
const ETA: usize = 2;
const BETA: u32 = 120;
const GAMMA1: u32 = 1 << 19;
const GAMMA2: u32 = (Q as u32 - 1) / 32;
const TAU: usize = 60;
const LAMBDA: usize = 256; const OMEGA: usize = 75;
const PK_SIZE: usize = 2592;
const SK_SIZE: usize = 4992;
const SIG_SIZE: usize = 5267;
const ALGORITHM: &'static str = "Arcanum-DSA-87";
const SECURITY_LEVEL: usize = 5;
}
const fn const_assert(condition: bool, _msg: &str) {
if !condition {
panic!("Compile-time assertion failed");
}
}
const fn validate_params<P: ArcanumDsaParams>() {
const_assert(P::L % 4 == 0, "L must be multiple of 4 for SIMD");
const_assert(
P::DIMENSION >= P::ML_DSA_EQUIVALENT_DIM,
"Dimension must meet ML-DSA security level",
);
const_assert(
P::BETA == (P::TAU * P::ETA) as u32,
"BETA must equal TAU * ETA",
);
const_assert(P::GAMMA1.is_power_of_two(), "GAMMA1 must be power of 2");
const_assert(
P::ETA == 2 || P::ETA == 4,
"ETA must be 2 or 4 per FIPS 204",
);
const_assert(P::TAU > 0 && P::TAU < N, "TAU must be in range (0, N)");
const_assert(P::K > 0, "K must be positive");
const_assert(P::L > 0, "L must be positive");
const_assert(P::OMEGA > 0, "OMEGA must be positive");
}
const _: () = validate_params::<Params44>();
const _: () = validate_params::<Params65>();
const _: () = validate_params::<Params87>();