1use crate::aux_functions::{
2 bit_pack_eta, bit_pack_t0, bit_unpack_eta, bit_unpack_t0, bitlen_eta, expandA,
3 power_2_round_vec, simple_bit_pack_t1, simple_bit_unpack_t1,
4};
5use crate::matrix::{Matrix, Vector};
6use crate::mldsa::H;
7use crate::mldsa::{MLDSA44_ETA, MLDSA44_PK_LEN, MLDSA44_SK_LEN, MLDSA44_k, MLDSA44_l};
8use crate::mldsa::{MLDSA65_ETA, MLDSA65_PK_LEN, MLDSA65_SK_LEN, MLDSA65_k, MLDSA65_l};
9use crate::mldsa::{MLDSA87_ETA, MLDSA87_PK_LEN, MLDSA87_SK_LEN, MLDSA87_k, MLDSA87_l};
10use crate::mldsa::{POLY_T0PACKED_LEN, POLY_T1PACKED_LEN};
11use crate::{ML_DSA_44_NAME, ML_DSA_65_NAME, ML_DSA_87_NAME};
12use bouncycastle_core::errors::SignatureError;
13use bouncycastle_core::key_material::KeyMaterial;
14use bouncycastle_core::traits::{SignaturePrivateKey, SignaturePublicKey, XOF};
15use bouncycastle_utils::secret::Secret;
16use core::fmt;
17use core::fmt::{Debug, Display, Formatter};
18
19#[allow(unused_imports)]
21use crate::mldsa::MLDSATrait;
22#[allow(unused_imports)]
23use crate::polynomial::Polynomial;
24
25pub type MLDSA44PublicKey = MLDSAPublicKey<MLDSA44_k, MLDSA44_l, MLDSA44_PK_LEN>;
29pub type MLDSA44PrivateKey =
31 MLDSAPrivateKey<MLDSA44_k, MLDSA44_l, MLDSA44_ETA, MLDSA44_SK_LEN, MLDSA44_PK_LEN>;
32pub type MLDSA65PublicKey = MLDSAPublicKey<MLDSA65_k, MLDSA65_l, MLDSA65_PK_LEN>;
34pub type MLDSA65PrivateKey =
36 MLDSAPrivateKey<MLDSA65_k, MLDSA65_l, MLDSA65_ETA, MLDSA65_SK_LEN, MLDSA65_PK_LEN>;
37pub type MLDSA87PublicKey = MLDSAPublicKey<MLDSA87_k, MLDSA87_l, MLDSA87_PK_LEN>;
39pub type MLDSA87PrivateKey =
41 MLDSAPrivateKey<MLDSA87_k, MLDSA87_l, MLDSA87_ETA, MLDSA87_SK_LEN, MLDSA87_PK_LEN>;
42
43pub type MLDSA44PublicKeyExpanded =
47 MLDSAPublicKeyExpanded<MLDSA44_k, MLDSA44_l, MLDSA44PublicKey, MLDSA44_PK_LEN>;
48pub type MLDSA44PrivateKeyExpanded = MLDSAPrivateKeyExpanded<
50 MLDSA44_k,
51 MLDSA44_l,
52 MLDSA44_ETA,
53 MLDSA44PublicKey,
54 MLDSA44PrivateKey,
55 MLDSA44_SK_LEN,
56 MLDSA44_PK_LEN,
57>;
58pub type MLDSA65PublicKeyExpanded =
60 MLDSAPublicKeyExpanded<MLDSA65_k, MLDSA65_l, MLDSA65PublicKey, MLDSA65_PK_LEN>;
61pub type MLDSA65PrivateKeyExpanded = MLDSAPrivateKeyExpanded<
63 MLDSA65_k,
64 MLDSA65_l,
65 MLDSA65_ETA,
66 MLDSA65PublicKey,
67 MLDSA65PrivateKey,
68 MLDSA65_SK_LEN,
69 MLDSA65_PK_LEN,
70>;
71pub type MLDSA87PublicKeyExpanded =
73 MLDSAPublicKeyExpanded<MLDSA87_k, MLDSA87_l, MLDSA87PublicKey, MLDSA87_PK_LEN>;
74pub type MLDSA87PrivateKeyExpanded = MLDSAPrivateKeyExpanded<
76 MLDSA87_k,
77 MLDSA87_l,
78 MLDSA87_ETA,
79 MLDSA87PublicKey,
80 MLDSA87PrivateKey,
81 MLDSA87_SK_LEN,
82 MLDSA87_PK_LEN,
83>;
84
85#[derive(Clone)]
87pub struct MLDSAPublicKey<const k: usize, const l: usize, const PK_LEN: usize> {
88 rho: [u8; 32],
89 t1: Vector<k>,
90}
91
92impl<const k: usize, const l: usize, const PK_LEN: usize> MLDSAPublicKey<k, l, PK_LEN> {
93 fn pk_encode_out(&self, out: &mut [u8; PK_LEN]) -> usize {
98 out.fill(0);
99
100 out[0..32].copy_from_slice(&self.rho);
101
102 let (pk_chunks, last_chunk) = out[32..].as_chunks_mut::<POLY_T1PACKED_LEN>();
103
104 debug_assert_eq!(pk_chunks.len(), k);
106 debug_assert_eq!(last_chunk.len(), 0);
107
108 for (pk_chunk, t1_i) in pk_chunks.into_iter().zip(&self.t1.vec) {
109 pk_chunk.copy_from_slice(&simple_bit_pack_t1(&t1_i));
110 }
111
112 PK_LEN
113 }
114}
115
116pub trait MLDSAPublicKeyTrait<const k: usize, const l: usize, const PK_LEN: usize>:
118 SignaturePublicKey<PK_LEN>
119{
120 fn pk_decode(pk: &[u8; PK_LEN]) -> Self;
125
126 fn A_hat(&self) -> Matrix<k, l>;
128
129 fn compute_tr(&self) -> [u8; 64];
136}
137
138pub(crate) trait MLDSAPublicKeyInternalTrait<const k: usize, const PK_LEN: usize>:
139 SignaturePublicKey<PK_LEN>
140{
141 fn new(rho: [u8; 32], t1: Vector<k>) -> Self;
144
145 fn t1(&self) -> &Vector<k>;
147}
148
149impl<const k: usize, const l: usize, const PK_LEN: usize> MLDSAPublicKeyTrait<k, l, PK_LEN>
150 for MLDSAPublicKey<k, l, PK_LEN>
151{
152 fn pk_decode(pk: &[u8; PK_LEN]) -> Self {
154 let rho = pk[0..32].try_into().unwrap();
155 let mut t1 = Vector::<k>::new();
156
157 let (pk_chunks, last_chunk) = pk[32..].as_chunks::<POLY_T1PACKED_LEN>();
158
159 debug_assert_eq!(pk_chunks.len(), k);
161 debug_assert_eq!(last_chunk.len(), 0);
162
163 for (t1_i, pk_chunk) in t1.vec.iter_mut().zip(pk_chunks) {
164 t1_i.coeffs.copy_from_slice(&simple_bit_unpack_t1(pk_chunk).coeffs);
168 }
169
170 Self::new(rho, t1)
171 }
172
173 fn A_hat(&self) -> Matrix<k, l> {
174 expandA::<k, l>(&self.rho)
175 }
176
177 fn compute_tr(&self) -> [u8; 64] {
178 let mut tr = [0u8; 64];
179 H::new().hash_xof_out(&self.encode(), &mut tr);
180
181 tr
182 }
183}
184
185impl<const k: usize, const l: usize, const PK_LEN: usize> MLDSAPublicKeyInternalTrait<k, PK_LEN>
186 for MLDSAPublicKey<k, l, PK_LEN>
187{
188 fn new(rho: [u8; 32], t1: Vector<k>) -> Self {
189 Self { rho, t1 }
190 }
191
192 fn t1(&self) -> &Vector<k> {
193 &self.t1
194 }
195}
196
197impl<const k: usize, const l: usize, const PK_LEN: usize> SignaturePublicKey<PK_LEN>
198 for MLDSAPublicKey<k, l, PK_LEN>
199{
200 fn encode(&self) -> [u8; PK_LEN] {
201 let mut pk = [0u8; PK_LEN];
202 let bytes_written = self.encode_out(&mut pk);
203 debug_assert_eq!(bytes_written, PK_LEN);
204
205 pk
206 }
207
208 fn encode_out(&self, out: &mut [u8; PK_LEN]) -> usize {
209 out.fill(0);
210
211 self.pk_encode_out(out)
212 }
213
214 fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError> {
215 if bytes.len() != PK_LEN {
216 return Err(SignatureError::DecodingError(
217 "Provided key bytes are the incorrect length",
218 ));
219 }
220 let bytes_sized: [u8; PK_LEN] = bytes[..PK_LEN].try_into().unwrap();
221 Ok(Self::pk_decode(&bytes_sized))
222 }
223}
224
225impl<const k: usize, const l: usize, const PK_LEN: usize> Eq for MLDSAPublicKey<k, l, PK_LEN> {}
226
227impl<const k: usize, const l: usize, const PK_LEN: usize> PartialEq
228 for MLDSAPublicKey<k, l, PK_LEN>
229{
230 fn eq(&self, other: &Self) -> bool {
231 let self_encoded = self.encode();
232 let other_encoded = other.encode();
233 bouncycastle_utils::ct::ct_eq_bytes(self_encoded.as_ref(), other_encoded.as_ref())
234 }
235}
236
237impl<const k: usize, const l: usize, const PK_LEN: usize> Debug for MLDSAPublicKey<k, l, PK_LEN> {
238 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
239 let alg = match k {
240 4 => ML_DSA_44_NAME,
241 6 => ML_DSA_65_NAME,
242 8 => ML_DSA_87_NAME,
243 _ => panic!("Unsupported key length"),
244 };
245 write!(f, "MLDSAPublicKey {{ alg: {}, pub_key_hash (tr): {:x?} }}", alg, self.compute_tr(),)
246 }
247}
248
249impl<const k: usize, const l: usize, const PK_LEN: usize> Display for MLDSAPublicKey<k, l, PK_LEN> {
250 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
251 let alg = match k {
252 4 => ML_DSA_44_NAME,
253 6 => ML_DSA_65_NAME,
254 8 => ML_DSA_87_NAME,
255 _ => panic!("Unsupported key length"),
256 };
257 write!(f, "MLDSAPublicKey {{ alg: {}, pub_key_hash (tr): {:x?} }}", alg, self.compute_tr(),)
258 }
259}
260
261#[derive(Clone)]
265pub struct MLDSAPublicKeyExpanded<
266 const k: usize,
267 const l: usize,
268 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
269 const PK_LEN: usize,
270> {
271 pub(crate) pk: PK,
272 pub(crate) A_hat: Matrix<k, l>,
273}
274
275impl<
276 const k: usize,
277 const l: usize,
278 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
279 const PK_LEN: usize,
280> SignaturePublicKey<PK_LEN> for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
281{
282 fn encode(&self) -> [u8; PK_LEN] {
283 self.pk.encode()
284 }
285
286 fn encode_out(&self, out: &mut [u8; PK_LEN]) -> usize {
287 out.fill(0);
288
289 self.pk.encode_out(out)
290 }
291
292 fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError> {
293 if bytes.len() != PK_LEN {
294 return Err(SignatureError::DecodingError(
295 "Provided key bytes are the incorrect length",
296 ));
297 }
298 let bytes_sized: [u8; PK_LEN] = bytes[..PK_LEN].try_into().unwrap();
299 Ok(Self::pk_decode(&bytes_sized))
300 }
301}
302
303impl<
304 const k: usize,
305 const l: usize,
306 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
307 const PK_LEN: usize,
308> PartialEq for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
309{
310 fn eq(&self, other: &Self) -> bool {
311 self.pk.eq(&other.pk)
312 }
313}
314
315impl<
316 const k: usize,
317 const l: usize,
318 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
319 const PK_LEN: usize,
320> Eq for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
321{
322}
323
324impl<
325 const k: usize,
326 const l: usize,
327 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
328 const PK_LEN: usize,
329> Debug for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
330{
331 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
332 let alg = match k {
333 4 => ML_DSA_44_NAME,
334 6 => ML_DSA_65_NAME,
335 8 => ML_DSA_87_NAME,
336 _ => panic!("Unsupported key length"),
337 };
338 write!(
339 f,
340 "MLDSAPublicKeyExpanded {{ alg: {}, pub_key_hash (tr): {:x?} }}",
341 alg,
342 self.compute_tr(),
343 )
344 }
345}
346
347impl<
348 const k: usize,
349 const l: usize,
350 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
351 const PK_LEN: usize,
352> Display for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
353{
354 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
355 let alg = match k {
356 4 => ML_DSA_44_NAME,
357 6 => ML_DSA_65_NAME,
358 8 => ML_DSA_87_NAME,
359 _ => panic!("Unsupported key length"),
360 };
361 write!(
362 f,
363 "MLDSAPublicKeyExpanded {{ alg: {}, pub_key_hash (tr): {:x?} }}",
364 alg,
365 self.compute_tr(),
366 )
367 }
368}
369
370impl<
371 const k: usize,
372 const l: usize,
373 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
374 const PK_LEN: usize,
375> From<&PK> for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
376{
377 fn from(pk: &PK) -> Self {
380 let A_hat = pk.A_hat();
381
382 Self { pk: pk.clone(), A_hat }
383 }
384}
385
386impl<
387 const k: usize,
388 const l: usize,
389 PK: MLDSAPublicKeyTrait<k, l, PK_LEN> + MLDSAPublicKeyInternalTrait<k, PK_LEN>,
390 const PK_LEN: usize,
391> MLDSAPublicKeyTrait<k, l, PK_LEN> for MLDSAPublicKeyExpanded<k, l, PK, PK_LEN>
392{
393 fn pk_decode(pk: &[u8; PK_LEN]) -> Self {
394 let pk1 = PK::pk_decode(pk);
395 let A_hat = pk1.A_hat();
396 Self { pk: pk1, A_hat }
397 }
398
399 fn A_hat(&self) -> Matrix<k, l> {
400 self.A_hat.clone()
401 }
402
403 fn compute_tr(&self) -> [u8; 64] {
404 self.pk.compute_tr()
405 }
406}
407
408#[derive(Clone)]
412pub struct MLDSAPrivateKey<
413 const k: usize,
414 const l: usize,
415 const eta: usize,
416 const SK_LEN: usize,
417 const PK_LEN: usize,
418> {
419 rho: [u8; 32],
420 K: Secret<[u8; 32]>,
421 tr: [u8; 64],
422 s1_hat: Secret<Vector<l>>,
429 s2_hat: Secret<Vector<k>>,
430 t0_hat: Vector<k>,
431 seed: Option<KeyMaterial<32>>,
433}
434
435impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
436 MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
437{
438 fn sk_encode_out(&self, out: &mut [u8; SK_LEN]) -> usize {
444 out.fill(0);
445
446 let mut off: usize = 0;
448
449 out[0..32].copy_from_slice(&self.rho);
450 out[32..64].copy_from_slice(&*self.K);
451 out[64..128].copy_from_slice(&self.tr);
452 off += 128;
453
454 let mut buf = [0u8; 32 * 4]; let eta_pack_len = bitlen_eta(eta);
456
457 let sk_chunks = out[off..off + l * bitlen_eta(eta)].chunks_mut(bitlen_eta(eta));
458 debug_assert_eq!(sk_chunks.len(), l);
459 for (sk_chunk, s1_hat_i) in sk_chunks.into_iter().zip(&self.s1_hat.vec) {
460 let mut s1_hat_i = s1_hat_i.clone();
463 s1_hat_i.reduce();
464 s1_hat_i.inv_ntt();
465 let s1_i = s1_hat_i;
466
467 bit_pack_eta::<eta>(&s1_i, &mut buf);
468 sk_chunk.copy_from_slice(&buf[..eta_pack_len]);
469 }
470 off += l * bitlen_eta(eta);
471
472 let sk_chunks = out[off..off + k * bitlen_eta(eta)].chunks_mut(bitlen_eta(eta));
473 debug_assert_eq!(sk_chunks.len(), k);
474 for (sk_chunk, s2_hat_i) in sk_chunks.into_iter().zip(&self.s2_hat.vec) {
475 let mut s2_hat_i = s2_hat_i.clone();
478 s2_hat_i.reduce();
479 s2_hat_i.inv_ntt();
480 let s2_i = s2_hat_i;
481
482 bit_pack_eta::<eta>(&s2_i, &mut buf);
483 sk_chunk.copy_from_slice(&buf[..eta_pack_len]);
484 }
485 off += k * bitlen_eta(eta);
486
487 let sk_chunks = out[off..off + k * POLY_T0PACKED_LEN].chunks_mut(POLY_T0PACKED_LEN);
488 debug_assert_eq!(sk_chunks.len(), k);
489 for (sk_chunk, t0_hat_i) in sk_chunks.into_iter().zip(&self.t0_hat.vec) {
490 let mut t0_hat_i = t0_hat_i.clone();
493 t0_hat_i.reduce();
494 t0_hat_i.inv_ntt();
495 let t0_i = t0_hat_i;
496
497 sk_chunk.copy_from_slice(&bit_pack_t0(&t0_i));
498 }
499
500 SK_LEN
501 }
502}
503
504pub trait MLDSAPrivateKeyTrait<
506 const k: usize,
507 const l: usize,
508 const eta: usize,
509 const SK_LEN: usize,
510 const PK_LEN: usize,
511>: SignaturePrivateKey<SK_LEN>
512{
513 fn seed(&self) -> Option<&KeyMaterial<32>>;
515
516 fn tr(&self) -> &[u8; 64];
518
519 fn A_hat(&self) -> Matrix<k, l>;
521
522 fn derive_pk(&self) -> MLDSAPublicKey<k, l, PK_LEN>;
524 fn sk_decode(sk: &[u8; SK_LEN]) -> Result<Self, SignatureError>;
533}
534
535pub(crate) trait MLDSAPrivateKeyInternalTrait<
536 const k: usize,
537 const l: usize,
538 const eta: usize,
539 const SK_LEN: usize,
540 const PK_LEN: usize,
541>
542{
543 fn new(
546 rho: [u8; 32],
547 K: Secret<[u8; 32]>,
548 tr: [u8; 64],
549 s1_hat: Secret<Vector<l>>,
550 s2_hat: Secret<Vector<k>>,
551 t0_hat: Vector<k>,
552 seed: Option<KeyMaterial<32>>,
553 ) -> Self;
554 fn K(&self) -> &Secret<[u8; 32]>;
556 fn s1_hat(&self) -> &Vector<l>;
558 fn s2_hat(&self) -> &Vector<k>;
560 fn t0_hat(&self) -> &Vector<k>;
562}
563
564impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
565 MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN> for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
566{
567 fn seed(&self) -> Option<&KeyMaterial<32>> {
568 match self.seed {
569 Some(_) => self.seed.as_ref(),
570 None => None,
571 }
572 }
573
574 fn tr(&self) -> &[u8; 64] {
575 &self.tr
576 }
577
578 fn A_hat(&self) -> Matrix<k, l> {
579 expandA::<k, l>(&self.rho)
580 }
581
582 fn derive_pk(&self) -> MLDSAPublicKey<k, l, PK_LEN> {
583 let mut t = {
586 let A_hat = expandA::<k, l>(&self.rho);
590
591 let mut t_ntt = A_hat.matrix_vector_ntt(&self.s1_hat);
592 t_ntt.inv_ntt();
593 t_ntt
594 };
595
596 {
597 let mut s2 = self.s2_hat.clone();
600 s2.reduce();
601 s2.inv_ntt();
602
603 t.add_vector_ntt(&s2);
604 t.conditional_add_q();
605 }
606 let (t1, _) = power_2_round_vec::<k>(&t);
610
611 MLDSAPublicKey::<k, l, PK_LEN>::new(self.rho.clone(), t1)
612 }
613 fn sk_decode(sk: &[u8; SK_LEN]) -> Result<Self, SignatureError> {
614 let mut key = Self {
619 rho: sk[0..32].try_into().unwrap(),
620 K: Secret::new(),
621 tr: sk[64..128].try_into().unwrap(),
622 s1_hat: Secret::new(),
623 s2_hat: Secret::new(),
624 t0_hat: Vector::<k>::new(),
625 seed: None,
626 };
627 key.K.copy_from_slice(&sk[32..64]);
628 let mut off = 128;
629
630 let sk_chunks = sk[off..off + (l * bitlen_eta(eta))].chunks(bitlen_eta(eta));
632 debug_assert_eq!(sk_chunks.len(), l);
633 for (s1_i, sk_chunk) in key.s1_hat.vec.iter_mut().zip(sk_chunks) {
634 s1_i.coeffs.copy_from_slice(&bit_unpack_eta::<eta>(&sk_chunk).coeffs);
637
638 for coeff in s1_i.coeffs.iter() {
640 if *coeff < -(eta as i32) || *coeff > (eta as i32) {
641 return Err(SignatureError::DecodingError("Invalid or corrupted key"));
642 }
643 }
644 }
645 key.s1_hat.ntt();
648 off += l * bitlen_eta(eta);
649
650 let sk_chunks = sk[off..off + (k * bitlen_eta(eta))].chunks(bitlen_eta(eta));
652 debug_assert_eq!(sk_chunks.len(), k);
653 for (s2_i, sk_chunk) in key.s2_hat.vec.iter_mut().zip(sk_chunks) {
654 s2_i.coeffs.copy_from_slice(&bit_unpack_eta::<eta>(&sk_chunk).coeffs);
657
658 for coeff in s2_i.coeffs.iter() {
660 if *coeff < -(eta as i32) || *coeff > (eta as i32) {
661 return Err(SignatureError::DecodingError("Invalid or corrupted key"));
662 }
663 }
664 }
665 key.s2_hat.ntt();
668 off += k * bitlen_eta(eta);
669
670 let (sk_chunks, last_chunk) =
672 sk[off..off + (k * POLY_T0PACKED_LEN)].as_chunks::<POLY_T0PACKED_LEN>();
673
674 debug_assert_eq!(sk_chunks.len(), k);
676 debug_assert_eq!(last_chunk.len(), 0);
677
678 for (t0_i, sk_chunk) in key.t0_hat.vec.iter_mut().zip(sk_chunks) {
679 t0_i.coeffs.copy_from_slice(&bit_unpack_t0(sk_chunk).coeffs);
680 }
681 key.t0_hat.ntt();
684
685 Ok(key)
686 }
687}
688
689impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
690 MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>
691 for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
692{
693 fn new(
694 rho: [u8; 32],
695 K: Secret<[u8; 32]>,
696 tr: [u8; 64],
697 s1_hat: Secret<Vector<l>>,
698 s2_hat: Secret<Vector<k>>,
699 t0_hat: Vector<k>,
700 seed: Option<KeyMaterial<32>>,
701 ) -> Self {
702 Self {
703 rho: rho.clone(),
704 K: K.clone(),
705 tr: tr.clone(),
706 s1_hat: s1_hat.clone(),
707 s2_hat: s2_hat.clone(),
708 t0_hat: t0_hat.clone(),
709 seed: seed.clone(),
710 }
711 }
712
713 fn K(&self) -> &Secret<[u8; 32]> {
714 &self.K
715 }
716
717 fn s1_hat(&self) -> &Vector<l> {
718 &self.s1_hat
719 }
720
721 fn s2_hat(&self) -> &Vector<k> {
722 &self.s2_hat
723 }
724
725 fn t0_hat(&self) -> &Vector<k> {
726 &self.t0_hat
727 }
728}
729
730impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
731 SignaturePrivateKey<SK_LEN> for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
732{
733 fn encode(&self) -> [u8; SK_LEN] {
734 let mut out = [0u8; SK_LEN];
735 let bytes_written = self.sk_encode_out(&mut out);
736 debug_assert_eq!(bytes_written, SK_LEN);
737
738 out
739 }
740
741 fn encode_out(&self, out: &mut [u8; SK_LEN]) -> usize {
742 out.fill(0);
743
744 self.sk_encode_out(out)
745 }
746
747 fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError> {
748 if bytes.len() != SK_LEN {
749 return Err(SignatureError::DecodingError(
750 "Provided key bytes are the incorrect length",
751 ));
752 }
753 let bytes_sized: [u8; SK_LEN] = bytes[..SK_LEN].try_into().unwrap();
754
755 Ok(Self::sk_decode(&bytes_sized)?)
756 }
757}
758
759impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize> Eq
760 for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
761{
762}
763
764impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
765 PartialEq for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
766{
767 fn eq(&self, other: &Self) -> bool {
768 let self_encoded = self.encode();
769 let other_encoded = other.encode();
770 bouncycastle_utils::ct::ct_eq_bytes(self_encoded.as_ref(), other_encoded.as_ref())
771 }
772}
773
774impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
776 fmt::Debug for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
777{
778 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
779 let alg = match k {
780 4 => ML_DSA_44_NAME,
781 6 => ML_DSA_65_NAME,
782 8 => ML_DSA_87_NAME,
783 _ => panic!("Unsupported key length"),
784 };
785 write!(
786 f,
787 "MLDSAPrivateKey {{ alg: {}, pub_key_hash (tr): {:x?}, has_seed: {} }}",
788 alg,
789 self.tr,
790 self.seed.is_some(),
791 )
792 }
793}
794
795impl<const k: usize, const l: usize, const eta: usize, const SK_LEN: usize, const PK_LEN: usize>
797 Display for MLDSAPrivateKey<k, l, eta, SK_LEN, PK_LEN>
798{
799 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
800 let alg = match k {
801 4 => ML_DSA_44_NAME,
802 6 => ML_DSA_65_NAME,
803 8 => ML_DSA_87_NAME,
804 _ => panic!("Unsupported key length"),
805 };
806 write!(
807 f,
808 "MLDSAPrivateKey {{ alg: {}, pub_key_hash (tr): {:x?}, has_seed: {} }}",
809 alg,
810 self.tr,
811 self.seed.is_some(),
812 )
813 }
814}
815
816#[derive(Clone)]
820pub struct MLDSAPrivateKeyExpanded<
821 const k: usize,
822 const l: usize,
823 const eta: usize,
824 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
825 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
826 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
827 const SK_LEN: usize,
828 const PK_LEN: usize,
829> {
830 _phantom: core::marker::PhantomData<PK>,
831 pub(crate) sk: SK,
832 pub(crate) A_hat: Matrix<k, l>,
833}
834
835impl<
836 const k: usize,
837 const l: usize,
838 const eta: usize,
839 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
840 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
841 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
842 const SK_LEN: usize,
843 const PK_LEN: usize,
844> PartialEq for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
845{
846 fn eq(&self, other: &Self) -> bool {
847 self.sk.eq(&other.sk)
848 }
849}
850
851impl<
852 const k: usize,
853 const l: usize,
854 const eta: usize,
855 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
856 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
857 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
858 const SK_LEN: usize,
859 const PK_LEN: usize,
860> Eq for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
861{
862}
863
864impl<
865 const k: usize,
866 const l: usize,
867 const eta: usize,
868 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
869 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
870 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
871 const SK_LEN: usize,
872 const PK_LEN: usize,
873> Debug for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
874{
875 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
876 let alg = match k {
877 4 => ML_DSA_44_NAME,
878 6 => ML_DSA_65_NAME,
879 8 => ML_DSA_87_NAME,
880 _ => panic!("Unsupported key length"),
881 };
882 write!(
883 f,
884 "MLDSAPrivateKeyExpanded {{ alg: {}, pub_key_hash (tr): {:x?}, has_seed: {} }}",
885 alg,
886 self.sk.tr(),
887 self.sk.seed().is_some(),
888 )
889 }
890}
891
892impl<
893 const k: usize,
894 const l: usize,
895 const eta: usize,
896 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
897 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
898 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
899 const SK_LEN: usize,
900 const PK_LEN: usize,
901> Display for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
902{
903 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
904 let alg = match k {
905 4 => ML_DSA_44_NAME,
906 6 => ML_DSA_65_NAME,
907 8 => ML_DSA_87_NAME,
908 _ => panic!("Unsupported key length"),
909 };
910 write!(
911 f,
912 "MLDSAPrivateKeyExpanded {{ alg: {}, pub_key_hash (tr): {:x?}, has_seed: {} }}",
913 alg,
914 self.sk.tr(),
915 self.sk.seed().is_some(),
916 )
917 }
918}
919
920impl<
921 const k: usize,
922 const l: usize,
923 const eta: usize,
924 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
925 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
926 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
927 const SK_LEN: usize,
928 const PK_LEN: usize,
929> From<&SK> for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
930{
931 fn from(sk: &SK) -> Self {
934 let A_hat = sk.derive_pk().A_hat();
935
936 Self { _phantom: core::marker::PhantomData, sk: sk.clone(), A_hat }
937 }
938}
939
940impl<
941 const k: usize,
942 const l: usize,
943 const eta: usize,
944 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
945 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
946 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
947 const SK_LEN: usize,
948 const PK_LEN: usize,
949> SignaturePrivateKey<SK_LEN> for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
950{
951 fn encode(&self) -> [u8; SK_LEN] {
952 self.sk.encode()
953 }
954
955 fn encode_out(&self, out: &mut [u8; SK_LEN]) -> usize {
956 out.fill(0);
957
958 self.sk.encode_out(out)
959 }
960
961 fn from_bytes(bytes: &[u8]) -> Result<Self, SignatureError> {
962 let sk = SK::from_bytes(bytes)?;
963 Ok(Self::from(&sk))
964 }
965}
966
967impl<
968 const k: usize,
969 const l: usize,
970 const eta: usize,
971 PK: MLDSAPublicKeyInternalTrait<k, PK_LEN>,
972 SK: MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
973 + MLDSAPrivateKeyInternalTrait<k, l, eta, SK_LEN, PK_LEN>,
974 const SK_LEN: usize,
975 const PK_LEN: usize,
976> MLDSAPrivateKeyTrait<k, l, eta, SK_LEN, PK_LEN>
977 for MLDSAPrivateKeyExpanded<k, l, eta, PK, SK, SK_LEN, PK_LEN>
978{
979 fn seed(&self) -> Option<&KeyMaterial<32>> {
980 self.sk.seed()
981 }
982
983 fn tr(&self) -> &[u8; 64] {
984 self.sk.tr()
985 }
986
987 fn A_hat(&self) -> Matrix<k, l> {
988 self.sk.A_hat()
989 }
990
991 fn derive_pk(&self) -> MLDSAPublicKey<k, l, PK_LEN> {
992 self.sk.derive_pk()
993 }
994
995 fn sk_decode(sk: &[u8; SK_LEN]) -> Result<Self, SignatureError> {
996 let sk1 = SK::sk_decode(sk)?;
997 let A_hat = sk1.derive_pk().A_hat();
998
999 Ok(Self { _phantom: core::marker::PhantomData, sk: sk1, A_hat })
1000 }
1001}