use super::utils::typenum;
use super::{
FFIFunctionPointers, ParameterSet, SeedLen, SignatureLen, SigningKeyLen, VerifyingKeyLen,
};
use crate::ffi;
use ffi::c_int;
pub const SIGNING_SEED_LEN: usize = ffi::MLDSA_SEEDBYTES as usize;
pub type SigningSeedLen = typenum::U32;
#[allow(non_camel_case_types)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ML_DSA_44;
impl SigningKeyLen for ML_DSA_44 {
const SIGNING_KEY_LEN: usize = ffi::MLDSA44_SECRETKEYBYTES as usize;
type LEN = typenum::U2560;
}
impl VerifyingKeyLen for ML_DSA_44 {
const VERIFYING_KEY_LEN: usize = ffi::MLDSA44_PUBLICKEYBYTES as usize;
type LEN = typenum::U1312;
}
impl SignatureLen for ML_DSA_44 {
const SIGNATURE_LEN: usize = ffi::MLDSA44_BYTES as usize;
type LEN = typenum::U2420;
}
impl SeedLen for ML_DSA_44 {
const SEED_LEN: usize = ffi::MLDSA44_SEEDBYTES as usize;
type LEN = typenum::U32;
}
impl FFIFunctionPointers for ML_DSA_44 {
const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
pk: *mut u8,
sk: *mut u8,
seed: *const u8,
) -> ffi::c_int = ffi::mldsa44_keypair_internal;
const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
ffi::mldsa44_pk_from_sk;
const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
sig: *mut u8,
siglen: *mut usize,
m: *const u8,
mlen: usize,
pre: *const u8,
prelen: usize,
rnd: *const u8,
sk: *const u8,
externalmu: c_int,
) -> c_int = ffi::mldsa44_signature_internal;
const VERIFY_FN: unsafe extern "C" fn(
sig: *const u8,
siglen: usize,
m: *const u8,
mlen: usize,
ctx: *const u8,
ctxlen: usize,
pk: *const u8,
) -> c_int = ffi::mldsa44_verify;
const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
prefix: *mut u8,
ph: *const u8,
phlen: usize,
ctx: *const u8,
ctxlen: usize,
hashalg: c_int,
) -> usize = ffi::mldsa44_prepare_domain_separation_prefix;
}
impl ParameterSet for ML_DSA_44 {
const NAME: &'static str = "ML-DSA-44";
}
#[allow(non_camel_case_types)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ML_DSA_65;
impl SigningKeyLen for ML_DSA_65 {
const SIGNING_KEY_LEN: usize = ffi::MLDSA65_SECRETKEYBYTES as usize;
type LEN = typenum::U4032;
}
impl VerifyingKeyLen for ML_DSA_65 {
const VERIFYING_KEY_LEN: usize = ffi::MLDSA65_PUBLICKEYBYTES as usize;
type LEN = typenum::U1952;
}
impl SignatureLen for ML_DSA_65 {
const SIGNATURE_LEN: usize = ffi::MLDSA65_BYTES as usize;
type LEN = typenum::U3309;
}
impl SeedLen for ML_DSA_65 {
const SEED_LEN: usize = ffi::MLDSA65_SEEDBYTES as usize;
type LEN = typenum::U32;
}
impl FFIFunctionPointers for ML_DSA_65 {
const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
pk: *mut u8,
sk: *mut u8,
seed: *const u8,
) -> ffi::c_int = ffi::mldsa65_keypair_internal;
const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
ffi::mldsa65_pk_from_sk;
const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
sig: *mut u8,
siglen: *mut usize,
m: *const u8,
mlen: usize,
pre: *const u8,
prelen: usize,
rnd: *const u8,
sk: *const u8,
externalmu: c_int,
) -> c_int = ffi::mldsa65_signature_internal;
const VERIFY_FN: unsafe extern "C" fn(
sig: *const u8,
siglen: usize,
m: *const u8,
mlen: usize,
ctx: *const u8,
ctxlen: usize,
pk: *const u8,
) -> c_int = ffi::mldsa65_verify;
const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
prefix: *mut u8,
ph: *const u8,
phlen: usize,
ctx: *const u8,
ctxlen: usize,
hashalg: c_int,
) -> usize = ffi::mldsa65_prepare_domain_separation_prefix;
}
impl ParameterSet for ML_DSA_65 {
const NAME: &'static str = "ML-DSA-65";
}
#[allow(non_camel_case_types)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct ML_DSA_87;
impl SigningKeyLen for ML_DSA_87 {
const SIGNING_KEY_LEN: usize = ffi::MLDSA87_SECRETKEYBYTES as usize;
type LEN = typenum::U4896;
}
impl VerifyingKeyLen for ML_DSA_87 {
const VERIFYING_KEY_LEN: usize = ffi::MLDSA87_PUBLICKEYBYTES as usize;
type LEN = typenum::U2592;
}
impl SignatureLen for ML_DSA_87 {
const SIGNATURE_LEN: usize = ffi::MLDSA87_BYTES as usize;
type LEN = typenum::U4627;
}
impl SeedLen for ML_DSA_87 {
const SEED_LEN: usize = ffi::MLDSA87_SEEDBYTES as usize;
type LEN = typenum::U32;
}
impl FFIFunctionPointers for ML_DSA_87 {
const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
pk: *mut u8,
sk: *mut u8,
seed: *const u8,
) -> ffi::c_int = ffi::mldsa87_keypair_internal;
const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
ffi::mldsa87_pk_from_sk;
const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
sig: *mut u8,
siglen: *mut usize,
m: *const u8,
mlen: usize,
pre: *const u8,
prelen: usize,
rnd: *const u8,
sk: *const u8,
externalmu: c_int,
) -> c_int = ffi::mldsa87_signature_internal;
const VERIFY_FN: unsafe extern "C" fn(
sig: *const u8,
siglen: usize,
m: *const u8,
mlen: usize,
ctx: *const u8,
ctxlen: usize,
pk: *const u8,
) -> c_int = ffi::mldsa87_verify;
const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
prefix: *mut u8,
ph: *const u8,
phlen: usize,
ctx: *const u8,
ctxlen: usize,
hashalg: c_int,
) -> usize = ffi::mldsa87_prepare_domain_separation_prefix;
}
impl ParameterSet for ML_DSA_87 {
const NAME: &'static str = "ML-DSA-87";
}
#[cfg(test)]
mod tests {
use super::typenum::Unsigned;
use super::*;
fn test_type_level_constants_generic<P: ParameterSet>() {
assert_eq!(P::SIGNATURE_LEN, <P as SignatureLen>::LEN::USIZE);
assert_eq!(P::SIGNING_KEY_LEN, <P as SigningKeyLen>::LEN::USIZE);
assert_eq!(P::SIGNING_KEY_LEN, P::SECRET_KEY_LEN);
assert_eq!(P::VERIFYING_KEY_LEN, <P as VerifyingKeyLen>::LEN::USIZE);
assert_eq!(P::VERIFYING_KEY_LEN, P::PUBLIC_KEY_LEN);
assert_eq!(P::SEED_LEN, <P as SeedLen>::LEN::USIZE);
}
#[test]
fn test_type_level_constants() {
test_type_level_constants_generic::<ML_DSA_44>();
test_type_level_constants_generic::<ML_DSA_65>();
test_type_level_constants_generic::<ML_DSA_87>();
}
#[test]
#[rustfmt::skip]
fn test_constants_match_ffi_values() {
assert_eq!(ML_DSA_44::SIGNATURE_LEN, ffi::MLDSA44_BYTES as usize);
assert_eq!(ML_DSA_44::SECRET_KEY_LEN, ffi::MLDSA44_SECRETKEYBYTES as usize);
assert_eq!(ML_DSA_44::PUBLIC_KEY_LEN, ffi::MLDSA44_PUBLICKEYBYTES as usize);
assert_eq!(ML_DSA_44::SEED_LEN, ffi::MLDSA44_SEEDBYTES as usize);
assert_eq!(ML_DSA_65::SIGNATURE_LEN, ffi::MLDSA65_BYTES as usize);
assert_eq!(ML_DSA_65::SECRET_KEY_LEN, ffi::MLDSA65_SECRETKEYBYTES as usize);
assert_eq!(ML_DSA_65::PUBLIC_KEY_LEN, ffi::MLDSA65_PUBLICKEYBYTES as usize);
assert_eq!(ML_DSA_65::SEED_LEN, ffi::MLDSA65_SEEDBYTES as usize);
assert_eq!(ML_DSA_87::SIGNATURE_LEN, ffi::MLDSA87_BYTES as usize);
assert_eq!(ML_DSA_87::SECRET_KEY_LEN, ffi::MLDSA87_SECRETKEYBYTES as usize);
assert_eq!(ML_DSA_87::PUBLIC_KEY_LEN, ffi::MLDSA87_PUBLICKEYBYTES as usize);
assert_eq!(ML_DSA_87::SEED_LEN, ffi::MLDSA87_SEEDBYTES as usize);
}
}