Skip to main content

mldsa_native_rs/wrapper/
parameter_sets.rs

1use super::utils::typenum;
2use super::{
3    FFIFunctionPointers, ParameterSet, SeedLen, SignatureLen, SigningKeyLen, VerifyingKeyLen,
4};
5use crate::ffi;
6use ffi::c_int;
7
8/// Length of the signing seed in bytes.
9///
10/// This is the same for all parameter sets.
11pub const SIGNING_SEED_LEN: usize = ffi::MLDSA_SEEDBYTES as usize;
12
13/// [`SIGNING_SEED_LEN`] as a type.
14///
15/// This is the same for all parameter sets.
16pub type SigningSeedLen = typenum::U32;
17
18#[allow(non_camel_case_types)]
19#[derive(Clone, Eq, PartialEq, Debug)]
20pub struct ML_DSA_44;
21
22impl SigningKeyLen for ML_DSA_44 {
23    const SIGNING_KEY_LEN: usize = ffi::MLDSA44_SECRETKEYBYTES as usize;
24
25    type LEN = typenum::U2560;
26}
27
28impl VerifyingKeyLen for ML_DSA_44 {
29    const VERIFYING_KEY_LEN: usize = ffi::MLDSA44_PUBLICKEYBYTES as usize;
30
31    type LEN = typenum::U1312;
32}
33
34impl SignatureLen for ML_DSA_44 {
35    const SIGNATURE_LEN: usize = ffi::MLDSA44_BYTES as usize;
36
37    type LEN = typenum::U2420;
38}
39
40impl SeedLen for ML_DSA_44 {
41    const SEED_LEN: usize = ffi::MLDSA44_SEEDBYTES as usize;
42
43    type LEN = typenum::U32;
44}
45
46impl FFIFunctionPointers for ML_DSA_44 {
47    const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
48        pk: *mut u8,
49        sk: *mut u8,
50        seed: *const u8,
51    ) -> ffi::c_int = ffi::mldsa44_keypair_internal;
52
53    const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
54        ffi::mldsa44_pk_from_sk;
55
56    const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
57        sig: *mut u8,
58        siglen: *mut usize,
59        m: *const u8,
60        mlen: usize,
61        pre: *const u8,
62        prelen: usize,
63        rnd: *const u8,
64        sk: *const u8,
65        externalmu: c_int,
66    ) -> c_int = ffi::mldsa44_signature_internal;
67
68    const VERIFY_FN: unsafe extern "C" fn(
69        sig: *const u8,
70        siglen: usize,
71        m: *const u8,
72        mlen: usize,
73        ctx: *const u8,
74        ctxlen: usize,
75        pk: *const u8,
76    ) -> c_int = ffi::mldsa44_verify;
77
78    const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
79        prefix: *mut u8,
80        ph: *const u8,
81        phlen: usize,
82        ctx: *const u8,
83        ctxlen: usize,
84        hashalg: c_int,
85    ) -> usize = ffi::mldsa44_prepare_domain_separation_prefix;
86}
87
88impl ParameterSet for ML_DSA_44 {
89    const NAME: &'static str = "ML-DSA-44";
90}
91
92#[allow(non_camel_case_types)]
93#[derive(Clone, Eq, PartialEq, Debug)]
94pub struct ML_DSA_65;
95
96impl SigningKeyLen for ML_DSA_65 {
97    const SIGNING_KEY_LEN: usize = ffi::MLDSA65_SECRETKEYBYTES as usize;
98
99    type LEN = typenum::U4032;
100}
101
102impl VerifyingKeyLen for ML_DSA_65 {
103    const VERIFYING_KEY_LEN: usize = ffi::MLDSA65_PUBLICKEYBYTES as usize;
104
105    type LEN = typenum::U1952;
106}
107
108impl SignatureLen for ML_DSA_65 {
109    const SIGNATURE_LEN: usize = ffi::MLDSA65_BYTES as usize;
110
111    type LEN = typenum::U3309;
112}
113
114impl SeedLen for ML_DSA_65 {
115    const SEED_LEN: usize = ffi::MLDSA65_SEEDBYTES as usize;
116
117    type LEN = typenum::U32;
118}
119
120impl FFIFunctionPointers for ML_DSA_65 {
121    const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
122        pk: *mut u8,
123        sk: *mut u8,
124        seed: *const u8,
125    ) -> ffi::c_int = ffi::mldsa65_keypair_internal;
126
127    const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
128        ffi::mldsa65_pk_from_sk;
129
130    const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
131        sig: *mut u8,
132        siglen: *mut usize,
133        m: *const u8,
134        mlen: usize,
135        pre: *const u8,
136        prelen: usize,
137        rnd: *const u8,
138        sk: *const u8,
139        externalmu: c_int,
140    ) -> c_int = ffi::mldsa65_signature_internal;
141
142    const VERIFY_FN: unsafe extern "C" fn(
143        sig: *const u8,
144        siglen: usize,
145        m: *const u8,
146        mlen: usize,
147        ctx: *const u8,
148        ctxlen: usize,
149        pk: *const u8,
150    ) -> c_int = ffi::mldsa65_verify;
151
152    const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
153        prefix: *mut u8,
154        ph: *const u8,
155        phlen: usize,
156        ctx: *const u8,
157        ctxlen: usize,
158        hashalg: c_int,
159    ) -> usize = ffi::mldsa65_prepare_domain_separation_prefix;
160}
161
162impl ParameterSet for ML_DSA_65 {
163    const NAME: &'static str = "ML-DSA-65";
164}
165
166#[allow(non_camel_case_types)]
167#[derive(Clone, Eq, PartialEq, Debug)]
168pub struct ML_DSA_87;
169
170impl SigningKeyLen for ML_DSA_87 {
171    const SIGNING_KEY_LEN: usize = ffi::MLDSA87_SECRETKEYBYTES as usize;
172
173    type LEN = typenum::U4896;
174}
175
176impl VerifyingKeyLen for ML_DSA_87 {
177    const VERIFYING_KEY_LEN: usize = ffi::MLDSA87_PUBLICKEYBYTES as usize;
178
179    type LEN = typenum::U2592;
180}
181
182impl SignatureLen for ML_DSA_87 {
183    const SIGNATURE_LEN: usize = ffi::MLDSA87_BYTES as usize;
184
185    type LEN = typenum::U4627;
186}
187
188impl SeedLen for ML_DSA_87 {
189    const SEED_LEN: usize = ffi::MLDSA87_SEEDBYTES as usize;
190
191    type LEN = typenum::U32;
192}
193
194impl FFIFunctionPointers for ML_DSA_87 {
195    const KEYGEN_FROM_SEED_FN: unsafe extern "C" fn(
196        pk: *mut u8,
197        sk: *mut u8,
198        seed: *const u8,
199    ) -> ffi::c_int = ffi::mldsa87_keypair_internal;
200
201    const PK_FROM_SK_FN: unsafe extern "C" fn(pk: *mut u8, sk: *const u8) -> c_int =
202        ffi::mldsa87_pk_from_sk;
203
204    const SIGN_WITH_SEED_FN: unsafe extern "C" fn(
205        sig: *mut u8,
206        siglen: *mut usize,
207        m: *const u8,
208        mlen: usize,
209        pre: *const u8,
210        prelen: usize,
211        rnd: *const u8,
212        sk: *const u8,
213        externalmu: c_int,
214    ) -> c_int = ffi::mldsa87_signature_internal;
215
216    const VERIFY_FN: unsafe extern "C" fn(
217        sig: *const u8,
218        siglen: usize,
219        m: *const u8,
220        mlen: usize,
221        ctx: *const u8,
222        ctxlen: usize,
223        pk: *const u8,
224    ) -> c_int = ffi::mldsa87_verify;
225
226    const PREPARE_DOMAIN_SEPARATION_PREFIX_FN: unsafe extern "C" fn(
227        prefix: *mut u8,
228        ph: *const u8,
229        phlen: usize,
230        ctx: *const u8,
231        ctxlen: usize,
232        hashalg: c_int,
233    ) -> usize = ffi::mldsa87_prepare_domain_separation_prefix;
234}
235
236impl ParameterSet for ML_DSA_87 {
237    const NAME: &'static str = "ML-DSA-87";
238}
239
240#[cfg(test)]
241mod tests {
242    use super::typenum::Unsigned;
243    use super::*;
244
245    fn test_type_level_constants_generic<P: ParameterSet>() {
246        assert_eq!(P::SIGNATURE_LEN, <P as SignatureLen>::LEN::USIZE);
247
248        assert_eq!(P::SIGNING_KEY_LEN, <P as SigningKeyLen>::LEN::USIZE);
249        assert_eq!(P::SIGNING_KEY_LEN, P::SECRET_KEY_LEN);
250
251        assert_eq!(P::VERIFYING_KEY_LEN, <P as VerifyingKeyLen>::LEN::USIZE);
252        assert_eq!(P::VERIFYING_KEY_LEN, P::PUBLIC_KEY_LEN);
253
254        assert_eq!(P::SEED_LEN, <P as SeedLen>::LEN::USIZE);
255    }
256
257    #[test]
258    fn test_type_level_constants() {
259        test_type_level_constants_generic::<ML_DSA_44>();
260        test_type_level_constants_generic::<ML_DSA_65>();
261        test_type_level_constants_generic::<ML_DSA_87>();
262    }
263
264    #[test]
265    #[rustfmt::skip]
266    fn test_constants_match_ffi_values() {
267        assert_eq!(ML_DSA_44::SIGNATURE_LEN, ffi::MLDSA44_BYTES as usize);
268        assert_eq!(ML_DSA_44::SECRET_KEY_LEN, ffi::MLDSA44_SECRETKEYBYTES as usize);
269        assert_eq!(ML_DSA_44::PUBLIC_KEY_LEN, ffi::MLDSA44_PUBLICKEYBYTES as usize);
270        assert_eq!(ML_DSA_44::SEED_LEN, ffi::MLDSA44_SEEDBYTES as usize);
271
272        assert_eq!(ML_DSA_65::SIGNATURE_LEN, ffi::MLDSA65_BYTES as usize);
273        assert_eq!(ML_DSA_65::SECRET_KEY_LEN, ffi::MLDSA65_SECRETKEYBYTES as usize);
274        assert_eq!(ML_DSA_65::PUBLIC_KEY_LEN, ffi::MLDSA65_PUBLICKEYBYTES as usize);
275        assert_eq!(ML_DSA_65::SEED_LEN, ffi::MLDSA65_SEEDBYTES as usize);
276
277        assert_eq!(ML_DSA_87::SIGNATURE_LEN, ffi::MLDSA87_BYTES as usize);
278        assert_eq!(ML_DSA_87::SECRET_KEY_LEN, ffi::MLDSA87_SECRETKEYBYTES as usize);
279        assert_eq!(ML_DSA_87::PUBLIC_KEY_LEN, ffi::MLDSA87_PUBLICKEYBYTES as usize);
280        assert_eq!(ML_DSA_87::SEED_LEN, ffi::MLDSA87_SEEDBYTES as usize);
281    }
282}