1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package io.github.tonywasher.joceanus.gordianknot.impl.jca;
18
19 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianException;
20 import io.github.tonywasher.joceanus.gordianknot.api.base.GordianLength;
21 import io.github.tonywasher.joceanus.gordianknot.api.keypair.GordianKeyPair;
22 import io.github.tonywasher.joceanus.gordianknot.api.keypair.spec.GordianKeyPairSpec;
23 import io.github.tonywasher.joceanus.gordianknot.api.keypair.spec.GordianXMSSSpec.GordianXMSSDigestType;
24 import io.github.tonywasher.joceanus.gordianknot.impl.core.base.GordianBaseFactory;
25 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianCryptoException;
26 import io.github.tonywasher.joceanus.gordianknot.impl.core.exc.GordianLogicException;
27 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianCoreKeyPairGenerator;
28 import io.github.tonywasher.joceanus.gordianknot.impl.core.keypair.GordianKeyPairValidity;
29 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreDHSpec;
30 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreDSASpec;
31 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreKeyPairSpec;
32 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreLMSSpec;
33 import io.github.tonywasher.joceanus.gordianknot.impl.core.spec.keypair.GordianCoreXMSSSpec;
34 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaDHPrivateKey;
35 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaDHPublicKey;
36 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaPrivateKey;
37 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaPublicKey;
38 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaStateAwareKeyPair;
39 import io.github.tonywasher.joceanus.gordianknot.impl.jca.JcaKeyPair.JcaStateAwarePrivateKey;
40 import org.bouncycastle.crypto.params.DHParameters;
41 import org.bouncycastle.jcajce.provider.asymmetric.dh.BCDHPrivateKey;
42 import org.bouncycastle.jcajce.provider.asymmetric.dh.BCDHPublicKey;
43 import org.bouncycastle.jcajce.spec.DHDomainParameterSpec;
44 import org.bouncycastle.jcajce.spec.EdDSAParameterSpec;
45 import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
46 import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
47 import org.bouncycastle.jcajce.spec.SLHDSAParameterSpec;
48 import org.bouncycastle.jcajce.spec.XDHParameterSpec;
49 import org.bouncycastle.jce.spec.ElGamalParameterSpec;
50 import org.bouncycastle.pqc.crypto.lms.LMSParameters;
51 import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec;
52 import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec;
53 import org.bouncycastle.pqc.jcajce.spec.FalconParameterSpec;
54 import org.bouncycastle.pqc.jcajce.spec.FrodoParameterSpec;
55 import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec;
56 import org.bouncycastle.pqc.jcajce.spec.LMSHSSKeyGenParameterSpec;
57 import org.bouncycastle.pqc.jcajce.spec.LMSKeyGenParameterSpec;
58 import org.bouncycastle.pqc.jcajce.spec.MayoParameterSpec;
59 import org.bouncycastle.pqc.jcajce.spec.NTRULPRimeParameterSpec;
60 import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec;
61 import org.bouncycastle.pqc.jcajce.spec.NTRUPlusParameterSpec;
62 import org.bouncycastle.pqc.jcajce.spec.PicnicParameterSpec;
63 import org.bouncycastle.pqc.jcajce.spec.SABERParameterSpec;
64 import org.bouncycastle.pqc.jcajce.spec.SNTRUPrimeParameterSpec;
65 import org.bouncycastle.pqc.jcajce.spec.SnovaParameterSpec;
66 import org.bouncycastle.pqc.jcajce.spec.XMSSMTParameterSpec;
67 import org.bouncycastle.pqc.jcajce.spec.XMSSParameterSpec;
68
69 import java.security.InvalidAlgorithmParameterException;
70 import java.security.KeyFactory;
71 import java.security.KeyPair;
72 import java.security.KeyPairGenerator;
73 import java.security.NoSuchAlgorithmException;
74 import java.security.PrivateKey;
75 import java.security.PublicKey;
76 import java.security.spec.AlgorithmParameterSpec;
77 import java.security.spec.ECGenParameterSpec;
78 import java.security.spec.InvalidKeySpecException;
79 import java.security.spec.PKCS8EncodedKeySpec;
80 import java.security.spec.X509EncodedKeySpec;
81 import java.util.Arrays;
82
83
84
85
86 public abstract class JcaKeyPairGenerator
87 extends GordianCoreKeyPairGenerator {
88
89
90
91 private static final String PARSE_ERROR = "Failed to parse encoding";
92
93
94
95
96 private KeyFactory theFactory;
97
98
99
100
101
102
103
104 JcaKeyPairGenerator(final GordianBaseFactory pFactory,
105 final GordianKeyPairSpec pKeySpec) {
106 super(pFactory, pKeySpec);
107 }
108
109
110
111
112
113
114 KeyFactory getKeyFactory() {
115 return theFactory;
116 }
117
118
119
120
121
122
123 void setKeyFactory(final KeyFactory pFactory) {
124 theFactory = pFactory;
125 }
126
127 @Override
128 public PKCS8EncodedKeySpec getPKCS8Encoding(final GordianKeyPair pKeyPair) throws GordianException {
129
130 JcaKeyPair.checkKeyPair(pKeyPair);
131
132
133 final JcaPrivateKey myPrivateKey = (JcaPrivateKey) getPrivateKey(pKeyPair);
134 return new PKCS8EncodedKeySpec(myPrivateKey.getPrivateKey().getEncoded());
135 }
136
137 @Override
138 public X509EncodedKeySpec getX509Encoding(final GordianKeyPair pKeyPair) throws GordianException {
139
140 JcaKeyPair.checkKeyPair(pKeyPair);
141
142
143 final JcaPublicKey myPublicKey = (JcaPublicKey) getPublicKey(pKeyPair);
144 return new X509EncodedKeySpec(myPublicKey.getPublicKey().getEncoded());
145 }
146
147 @Override
148 public JcaKeyPair deriveKeyPair(final X509EncodedKeySpec pPublicKey,
149 final PKCS8EncodedKeySpec pPrivateKey) throws GordianException {
150
151 try {
152
153 checkKeySpec(pPrivateKey);
154
155
156 final JcaPublicKey myPublic = derivePublicKey(pPublicKey);
157 final JcaPrivateKey myPrivate = createPrivate(theFactory.generatePrivate(pPrivateKey));
158 final JcaKeyPair myPair = new JcaKeyPair(myPublic, myPrivate);
159
160
161 GordianKeyPairValidity.checkValidity(getFactory(), myPair);
162
163
164 return myPair;
165
166 } catch (InvalidKeySpecException e) {
167 throw new GordianCryptoException(PARSE_ERROR, e);
168 }
169 }
170
171
172
173
174
175
176
177 protected JcaPrivateKey createPrivate(final PrivateKey pPrivateKey) {
178 return new JcaPrivateKey(getKeySpec(), pPrivateKey);
179 }
180
181
182
183
184
185
186
187 protected JcaPublicKey createPublic(final PublicKey pPublicKey) {
188 return new JcaPublicKey(getKeySpec(), pPublicKey);
189 }
190
191 @Override
192 public JcaKeyPair derivePublicOnlyKeyPair(final X509EncodedKeySpec pPublicKey) throws GordianException {
193 final JcaPublicKey myPublic = derivePublicKey(pPublicKey);
194 return new JcaKeyPair(myPublic);
195 }
196
197
198
199
200
201
202
203
204 protected JcaPublicKey derivePublicKey(final X509EncodedKeySpec pEncodedKey) throws GordianException {
205
206 try {
207
208 checkKeySpec(pEncodedKey);
209
210
211 return createPublic(theFactory.generatePublic(pEncodedKey));
212
213 } catch (InvalidKeySpecException e) {
214 throw new GordianCryptoException(PARSE_ERROR, e);
215 }
216 }
217
218
219
220
221 public static class JcaRSAKeyPairGenerator
222 extends JcaKeyPairGenerator {
223
224
225
226 private static final String RSA_ALGO = "RSA";
227
228
229
230
231 private final KeyPairGenerator theGenerator;
232
233
234
235
236
237
238
239
240 JcaRSAKeyPairGenerator(final GordianBaseFactory pFactory,
241 final GordianKeyPairSpec pKeySpec) throws GordianException {
242
243 super(pFactory, pKeySpec);
244
245
246 theGenerator = getJavaKeyPairGenerator(RSA_ALGO, false);
247 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
248 theGenerator.initialize(myKeySpec.getRSASpec().getLength(), getRandom());
249
250
251 setKeyFactory(getJavaKeyFactory(RSA_ALGO, false));
252 }
253
254 @Override
255 public JcaKeyPair generateKeyPair() {
256
257 final KeyPair myPair = theGenerator.generateKeyPair();
258 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
259 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
260 return new JcaKeyPair(myPublic, myPrivate);
261 }
262 }
263
264
265
266
267 public static class JcaElGamalKeyPairGenerator
268 extends JcaKeyPairGenerator {
269
270
271
272 private static final String ELGAMAL_ALGO = "ELGAMAL";
273
274
275
276
277 private final KeyPairGenerator theGenerator;
278
279
280
281
282
283
284
285
286 JcaElGamalKeyPairGenerator(final GordianBaseFactory pFactory,
287 final GordianKeyPairSpec pKeySpec) throws GordianException {
288
289 super(pFactory, pKeySpec);
290
291
292 try {
293
294 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
295 final GordianCoreDHSpec myGroup = myKeySpec.getDHSpec();
296 final DHParameters myParms = myGroup.getParameters();
297 final ElGamalParameterSpec mySpec = new ElGamalParameterSpec(myParms.getP(), myParms.getQ());
298
299
300 theGenerator = getJavaKeyPairGenerator(ELGAMAL_ALGO, false);
301 theGenerator.initialize(mySpec, getRandom());
302
303
304 setKeyFactory(getJavaKeyFactory(ELGAMAL_ALGO, false));
305
306 } catch (InvalidAlgorithmParameterException e) {
307 throw new GordianCryptoException("Failed to create ElGamalGenerator", e);
308 }
309 }
310
311 @Override
312 public JcaKeyPair generateKeyPair() {
313
314 final KeyPair myPair = theGenerator.generateKeyPair();
315 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
316 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
317 return new JcaKeyPair(myPublic, myPrivate);
318 }
319 }
320
321
322
323
324 public static class JcaECKeyPairGenerator
325 extends JcaKeyPairGenerator {
326
327
328
329 private final KeyPairGenerator theGenerator;
330
331
332
333
334
335
336
337
338 JcaECKeyPairGenerator(final GordianBaseFactory pFactory,
339 final GordianKeyPairSpec pKeySpec) throws GordianException {
340
341 super(pFactory, pKeySpec);
342
343
344 try {
345
346 final String myAlgo = getAlgorithm();
347 theGenerator = getJavaKeyPairGenerator(myAlgo, false);
348 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
349 final ECGenParameterSpec myParms = new ECGenParameterSpec(myKeySpec.getElliptic().getCurveName());
350 theGenerator.initialize(myParms, getRandom());
351
352
353 setKeyFactory(getJavaKeyFactory(myAlgo, false));
354
355 } catch (InvalidAlgorithmParameterException e) {
356 throw new GordianCryptoException("Failed to create ECgenerator for: " + pKeySpec, e);
357 }
358 }
359
360 @Override
361 public JcaKeyPair generateKeyPair() {
362
363 final KeyPair myPair = theGenerator.generateKeyPair();
364 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
365 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
366 return new JcaKeyPair(myPublic, myPrivate);
367 }
368
369
370
371
372
373
374 private String getAlgorithm() {
375 return switch (this.getKeySpec().getKeyPairType()) {
376 case DSTU -> "DSTU4145";
377 case GOST -> "ECGOST3410-2012";
378 default -> "EC";
379 };
380 }
381 }
382
383
384
385
386 public static class JcaDSAKeyPairGenerator
387 extends JcaKeyPairGenerator {
388
389
390
391 private static final String DSA_ALGO = "DSA";
392
393
394
395
396 private final KeyPairGenerator theGenerator;
397
398
399
400
401
402
403
404
405 JcaDSAKeyPairGenerator(final GordianBaseFactory pFactory,
406 final GordianKeyPairSpec pKeySpec) throws GordianException {
407
408 super(pFactory, pKeySpec);
409
410
411 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
412 final GordianCoreDSASpec myKeyType = myKeySpec.getDSASpec();
413 theGenerator = getJavaKeyPairGenerator(DSA_ALGO, false);
414 theGenerator.initialize(myKeyType.getKeySize(), getRandom());
415
416
417 setKeyFactory(getJavaKeyFactory(DSA_ALGO, false));
418 }
419
420 @Override
421 public JcaKeyPair generateKeyPair() {
422
423 final KeyPair myPair = theGenerator.generateKeyPair();
424 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
425 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
426 return new JcaKeyPair(myPublic, myPrivate);
427 }
428 }
429
430
431
432
433 public static class JcaDHKeyPairGenerator
434 extends JcaKeyPairGenerator {
435
436
437
438 private static final String DH_ALGO = "DH";
439
440
441
442
443 private final KeyPairGenerator theGenerator;
444
445
446
447
448
449
450
451
452 JcaDHKeyPairGenerator(final GordianBaseFactory pFactory,
453 final GordianKeyPairSpec pKeySpec) throws GordianException {
454
455 super(pFactory, pKeySpec);
456
457
458 try {
459
460 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
461 final GordianCoreDHSpec myGroup = myKeySpec.getDHSpec();
462 final DHParameters myParms = myGroup.getParameters();
463 final DHDomainParameterSpec mySpec = new DHDomainParameterSpec(myParms);
464
465
466 theGenerator = getJavaKeyPairGenerator(DH_ALGO, false);
467 theGenerator.initialize(mySpec, getRandom());
468
469
470 setKeyFactory(getJavaKeyFactory(DH_ALGO, false));
471
472 } catch (InvalidAlgorithmParameterException e) {
473 throw new GordianCryptoException("Failed to create DHgenerator", e);
474 }
475 }
476
477 @Override
478 public JcaKeyPair generateKeyPair() {
479
480 final KeyPair myPair = theGenerator.generateKeyPair();
481 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
482 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
483 return new JcaKeyPair(myPublic, myPrivate);
484 }
485
486 @Override
487 protected JcaPrivateKey createPrivate(final PrivateKey pPrivateKey) {
488 return new JcaDHPrivateKey(getKeySpec(), (BCDHPrivateKey) pPrivateKey);
489 }
490
491 @Override
492 protected JcaPublicKey createPublic(final PublicKey pPublicKey) {
493 return new JcaDHPublicKey(getKeySpec(), (BCDHPublicKey) pPublicKey);
494 }
495 }
496
497
498
499
500 public static class JcaSLHDSAKeyPairGenerator
501 extends JcaKeyPairGenerator {
502
503
504
505 private static final String SLHDSA_ALGO = "SLH-DSA";
506
507
508
509
510 private static final String SLHDSA_HASH = "HASH-" + SLHDSA_ALGO;
511
512
513
514
515 private final KeyPairGenerator theGenerator;
516
517
518
519
520
521
522
523
524 JcaSLHDSAKeyPairGenerator(final GordianBaseFactory pFactory,
525 final GordianKeyPairSpec pKeySpec) throws GordianException {
526
527 super(pFactory, pKeySpec);
528
529
530 try {
531
532 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
533 final String myAlgo = myKeySpec.getSLHDSASpec().isHash() ? SLHDSA_HASH : SLHDSA_ALGO;
534
535
536 theGenerator = getJavaKeyPairGenerator(myAlgo, false);
537 final SLHDSAParameterSpec myParms = myKeySpec.getSLHDSASpec().getParameterSpec();
538 theGenerator.initialize(myParms, getRandom());
539
540
541 setKeyFactory(getJavaKeyFactory(myAlgo, false));
542
543 } catch (InvalidAlgorithmParameterException e) {
544 throw new GordianCryptoException("Failed to create SLHDSAgenerator", e);
545 }
546 }
547
548 @Override
549 public JcaKeyPair generateKeyPair() {
550
551 final KeyPair myPair = theGenerator.generateKeyPair();
552 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
553 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
554 return new JcaKeyPair(myPublic, myPrivate);
555 }
556 }
557
558
559
560
561 public static class JcaCMCEKeyPairGenerator
562 extends JcaKeyPairGenerator {
563
564
565
566 private static final String CMCE_ALGO = "CMCE";
567
568
569
570
571 private final KeyPairGenerator theGenerator;
572
573
574
575
576
577
578
579
580 JcaCMCEKeyPairGenerator(final GordianBaseFactory pFactory,
581 final GordianKeyPairSpec pKeySpec) throws GordianException {
582
583 super(pFactory, pKeySpec);
584
585
586 try {
587
588 theGenerator = getJavaKeyPairGenerator(CMCE_ALGO, true);
589 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
590 final CMCEParameterSpec myParms = myKeySpec.getCMCESpec().getParameterSpec();
591 theGenerator.initialize(myParms, getRandom());
592
593
594 setKeyFactory(getJavaKeyFactory(CMCE_ALGO, true));
595
596 } catch (InvalidAlgorithmParameterException e) {
597 throw new GordianCryptoException("Failed to create CMCEgenerator", e);
598 }
599 }
600
601 @Override
602 public JcaKeyPair generateKeyPair() {
603
604 final KeyPair myPair = theGenerator.generateKeyPair();
605 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
606 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
607 return new JcaKeyPair(myPublic, myPrivate);
608 }
609 }
610
611
612
613
614 public static class JcaFrodoKeyPairGenerator
615 extends JcaKeyPairGenerator {
616
617
618
619 private static final String FRODO_ALGO = "FRODO";
620
621
622
623
624 private final KeyPairGenerator theGenerator;
625
626
627
628
629
630
631
632
633 JcaFrodoKeyPairGenerator(final GordianBaseFactory pFactory,
634 final GordianKeyPairSpec pKeySpec) throws GordianException {
635
636 super(pFactory, pKeySpec);
637
638
639 try {
640
641 theGenerator = getJavaKeyPairGenerator(FRODO_ALGO, true);
642 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
643 final FrodoParameterSpec myParms = myKeySpec.getFRODOSpec().getParameterSpec();
644 theGenerator.initialize(myParms, getRandom());
645
646
647 setKeyFactory(getJavaKeyFactory(FRODO_ALGO, true));
648
649 } catch (InvalidAlgorithmParameterException e) {
650 throw new GordianCryptoException("Failed to create FRODOgenerator", e);
651 }
652 }
653
654 @Override
655 public JcaKeyPair generateKeyPair() {
656
657 final KeyPair myPair = theGenerator.generateKeyPair();
658 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
659 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
660 return new JcaKeyPair(myPublic, myPrivate);
661 }
662 }
663
664
665
666
667 public static class JcaSABERKeyPairGenerator
668 extends JcaKeyPairGenerator {
669
670
671
672 private static final String SABER_ALGO = "SABER";
673
674
675
676
677 private final KeyPairGenerator theGenerator;
678
679
680
681
682
683
684
685
686 JcaSABERKeyPairGenerator(final GordianBaseFactory pFactory,
687 final GordianKeyPairSpec pKeySpec) throws GordianException {
688
689 super(pFactory, pKeySpec);
690
691
692 try {
693
694 theGenerator = getJavaKeyPairGenerator(SABER_ALGO, true);
695 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
696 final SABERParameterSpec myParms = myKeySpec.getSABERSpec().getParameterSpec();
697 theGenerator.initialize(myParms, getRandom());
698
699
700 setKeyFactory(getJavaKeyFactory(SABER_ALGO, true));
701
702 } catch (InvalidAlgorithmParameterException e) {
703 throw new GordianCryptoException("Failed to create SABERgenerator", e);
704 }
705 }
706
707 @Override
708 public JcaKeyPair generateKeyPair() {
709
710 final KeyPair myPair = theGenerator.generateKeyPair();
711 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
712 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
713 return new JcaKeyPair(myPublic, myPrivate);
714 }
715 }
716
717
718
719
720 public static class JcaMLKEMKeyPairGenerator
721 extends JcaKeyPairGenerator {
722
723
724
725 private static final String MLKEM_ALGO = "MLKEM";
726
727
728
729
730 private final KeyPairGenerator theGenerator;
731
732
733
734
735
736
737
738
739 JcaMLKEMKeyPairGenerator(final GordianBaseFactory pFactory,
740 final GordianKeyPairSpec pKeySpec) throws GordianException {
741
742 super(pFactory, pKeySpec);
743
744
745 try {
746
747 theGenerator = getJavaKeyPairGenerator(MLKEM_ALGO, false);
748 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
749 final MLKEMParameterSpec myParms = myKeySpec.getMLKEMSpec().getParameterSpec();
750 theGenerator.initialize(myParms, getRandom());
751
752
753 setKeyFactory(getJavaKeyFactory(MLKEM_ALGO, false));
754
755 } catch (InvalidAlgorithmParameterException e) {
756 throw new GordianCryptoException("Failed to create MLKEMgenerator", e);
757 }
758 }
759
760 @Override
761 public JcaKeyPair generateKeyPair() {
762
763 final KeyPair myPair = theGenerator.generateKeyPair();
764 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
765 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
766 return new JcaKeyPair(myPublic, myPrivate);
767 }
768 }
769
770
771
772
773 public static class JcaMLDSAKeyPairGenerator
774 extends JcaKeyPairGenerator {
775
776
777
778 private static final String MLDSA_ALGO = "ML-DSA";
779
780
781
782
783 private static final String MLDSA_HASH = "HASH-" + MLDSA_ALGO;
784
785
786
787
788 private final KeyPairGenerator theGenerator;
789
790
791
792
793
794
795
796
797 JcaMLDSAKeyPairGenerator(final GordianBaseFactory pFactory,
798 final GordianKeyPairSpec pKeySpec) throws GordianException {
799
800 super(pFactory, pKeySpec);
801
802
803 try {
804
805 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
806 final String myAlgo = myKeySpec.getMLDSASpec().isHash() ? MLDSA_HASH : MLDSA_ALGO;
807
808
809 theGenerator = getJavaKeyPairGenerator(myAlgo, false);
810 final MLDSAParameterSpec myParms = myKeySpec.getMLDSASpec().getParameterSpec();
811 theGenerator.initialize(myParms, getRandom());
812
813
814 setKeyFactory(getJavaKeyFactory(myAlgo, false));
815
816 } catch (InvalidAlgorithmParameterException e) {
817 throw new GordianCryptoException("Failed to create MLDSAGenerator", e);
818 }
819 }
820
821 @Override
822 public JcaKeyPair generateKeyPair() {
823
824 final KeyPair myPair = theGenerator.generateKeyPair();
825 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
826 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
827 return new JcaKeyPair(myPublic, myPrivate);
828 }
829 }
830
831
832
833
834 public static class JcaHQCKeyPairGenerator
835 extends JcaKeyPairGenerator {
836
837
838
839 private static final String HQC_ALGO = "HQC";
840
841
842
843
844 private final KeyPairGenerator theGenerator;
845
846
847
848
849
850
851
852
853 JcaHQCKeyPairGenerator(final GordianBaseFactory pFactory,
854 final GordianKeyPairSpec pKeySpec) throws GordianException {
855
856 super(pFactory, pKeySpec);
857
858
859 try {
860
861 theGenerator = getJavaKeyPairGenerator(HQC_ALGO, true);
862 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
863 final HQCParameterSpec myParms = myKeySpec.getHQCSpec().getParameterSpec();
864 theGenerator.initialize(myParms, getRandom());
865
866
867 setKeyFactory(getJavaKeyFactory(HQC_ALGO, true));
868
869 } catch (InvalidAlgorithmParameterException e) {
870 throw new GordianCryptoException("Failed to create HQCgenerator", e);
871 }
872 }
873
874 @Override
875 public JcaKeyPair generateKeyPair() {
876
877 final KeyPair myPair = theGenerator.generateKeyPair();
878 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
879 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
880 return new JcaKeyPair(myPublic, myPrivate);
881 }
882 }
883
884
885
886
887 public static class JcaBIKEKeyPairGenerator
888 extends JcaKeyPairGenerator {
889
890
891
892 private static final String BIKE_ALGO = "BIKE";
893
894
895
896
897 private final KeyPairGenerator theGenerator;
898
899
900
901
902
903
904
905
906 JcaBIKEKeyPairGenerator(final GordianBaseFactory pFactory,
907 final GordianKeyPairSpec pKeySpec) throws GordianException {
908
909 super(pFactory, pKeySpec);
910
911
912 try {
913
914 theGenerator = getJavaKeyPairGenerator(BIKE_ALGO, true);
915 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
916 final BIKEParameterSpec myParms = myKeySpec.getBIKESpec().getParameterSpec();
917 theGenerator.initialize(myParms, getRandom());
918
919
920 setKeyFactory(getJavaKeyFactory(BIKE_ALGO, true));
921
922 } catch (InvalidAlgorithmParameterException e) {
923 throw new GordianCryptoException("Failed to create BIKEgenerator", e);
924 }
925 }
926
927 @Override
928 public JcaKeyPair generateKeyPair() {
929
930 final KeyPair myPair = theGenerator.generateKeyPair();
931 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
932 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
933 return new JcaKeyPair(myPublic, myPrivate);
934 }
935 }
936
937
938
939
940 public static class JcaNTRUKeyPairGenerator
941 extends JcaKeyPairGenerator {
942
943
944
945 private static final String NTRU_ALGO = "NTRU";
946
947
948
949
950 private final KeyPairGenerator theGenerator;
951
952
953
954
955
956
957
958
959 JcaNTRUKeyPairGenerator(final GordianBaseFactory pFactory,
960 final GordianKeyPairSpec pKeySpec) throws GordianException {
961
962 super(pFactory, pKeySpec);
963
964
965 try {
966
967 theGenerator = getJavaKeyPairGenerator(NTRU_ALGO, true);
968 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
969 final NTRUParameterSpec myParms = myKeySpec.getNTRUSpec().getParameterSpec();
970 theGenerator.initialize(myParms, getRandom());
971
972
973 setKeyFactory(getJavaKeyFactory(NTRU_ALGO, true));
974
975 } catch (InvalidAlgorithmParameterException e) {
976 throw new GordianCryptoException("Failed to create NTRUgenerator", e);
977 }
978 }
979
980 @Override
981 public JcaKeyPair generateKeyPair() {
982
983 final KeyPair myPair = theGenerator.generateKeyPair();
984 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
985 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
986 return new JcaKeyPair(myPublic, myPrivate);
987 }
988 }
989
990
991
992
993 public static class JcaNTRUPlusKeyPairGenerator
994 extends JcaKeyPairGenerator {
995
996
997
998 private static final String NTRUPLUS_ALGO = "NTRUPLUS";
999
1000
1001
1002
1003 private final KeyPairGenerator theGenerator;
1004
1005
1006
1007
1008
1009
1010
1011
1012 JcaNTRUPlusKeyPairGenerator(final GordianBaseFactory pFactory,
1013 final GordianKeyPairSpec pKeySpec) throws GordianException {
1014
1015 super(pFactory, pKeySpec);
1016
1017
1018 try {
1019
1020 theGenerator = getJavaKeyPairGenerator(NTRUPLUS_ALGO, true);
1021 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1022 final NTRUPlusParameterSpec myParms = myKeySpec.getNTRUPlusSpec().getParameterSpec();
1023 theGenerator.initialize(myParms, getRandom());
1024
1025
1026 setKeyFactory(getJavaKeyFactory(NTRUPLUS_ALGO, true));
1027
1028 } catch (InvalidAlgorithmParameterException e) {
1029 throw new GordianCryptoException("Failed to create NTRUPlusGenerator", e);
1030 }
1031 }
1032
1033 @Override
1034 public JcaKeyPair generateKeyPair() {
1035
1036 final KeyPair myPair = theGenerator.generateKeyPair();
1037 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1038 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1039 return new JcaKeyPair(myPublic, myPrivate);
1040 }
1041 }
1042
1043
1044
1045
1046 public static class JcaFalconKeyPairGenerator
1047 extends JcaKeyPairGenerator {
1048
1049
1050
1051 private static final String FALCON_ALGO = "FALCON";
1052
1053
1054
1055
1056 private final KeyPairGenerator theGenerator;
1057
1058
1059
1060
1061
1062
1063
1064
1065 JcaFalconKeyPairGenerator(final GordianBaseFactory pFactory,
1066 final GordianKeyPairSpec pKeySpec) throws GordianException {
1067
1068 super(pFactory, pKeySpec);
1069
1070
1071 try {
1072
1073 theGenerator = getJavaKeyPairGenerator(FALCON_ALGO, true);
1074 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1075 final FalconParameterSpec myParms = myKeySpec.getFalconSpec().getParameterSpec();
1076 theGenerator.initialize(myParms, getRandom());
1077
1078
1079 setKeyFactory(getJavaKeyFactory(FALCON_ALGO, true));
1080
1081 } catch (InvalidAlgorithmParameterException e) {
1082 throw new GordianCryptoException("Failed to create FALCONgenerator", e);
1083 }
1084 }
1085
1086 @Override
1087 public JcaKeyPair generateKeyPair() {
1088
1089 final KeyPair myPair = theGenerator.generateKeyPair();
1090 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1091 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1092 return new JcaKeyPair(myPublic, myPrivate);
1093 }
1094 }
1095
1096
1097
1098
1099 public static class JcaMayoKeyPairGenerator
1100 extends JcaKeyPairGenerator {
1101
1102
1103
1104 private static final String MAYO_ALGO = "MAYO";
1105
1106
1107
1108
1109 private final KeyPairGenerator theGenerator;
1110
1111
1112
1113
1114
1115
1116
1117
1118 JcaMayoKeyPairGenerator(final GordianBaseFactory pFactory,
1119 final GordianKeyPairSpec pKeySpec) throws GordianException {
1120
1121 super(pFactory, pKeySpec);
1122
1123
1124 try {
1125
1126 theGenerator = getJavaKeyPairGenerator(MAYO_ALGO, true);
1127 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1128 final MayoParameterSpec myParms = myKeySpec.getMayoSpec().getParameterSpec();
1129 theGenerator.initialize(myParms, getRandom());
1130
1131
1132 setKeyFactory(getJavaKeyFactory(MAYO_ALGO, true));
1133
1134 } catch (InvalidAlgorithmParameterException e) {
1135 throw new GordianCryptoException("Failed to create MayoGenerator", e);
1136 }
1137 }
1138
1139 @Override
1140 public JcaKeyPair generateKeyPair() {
1141
1142 final KeyPair myPair = theGenerator.generateKeyPair();
1143 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1144 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1145 return new JcaKeyPair(myPublic, myPrivate);
1146 }
1147 }
1148
1149
1150
1151
1152 public static class JcaSnovaKeyPairGenerator
1153 extends JcaKeyPairGenerator {
1154
1155
1156
1157 private static final String SNOVA_ALGO = "SNOVA";
1158
1159
1160
1161
1162 private final KeyPairGenerator theGenerator;
1163
1164
1165
1166
1167
1168
1169
1170
1171 JcaSnovaKeyPairGenerator(final GordianBaseFactory pFactory,
1172 final GordianKeyPairSpec pKeySpec) throws GordianException {
1173
1174 super(pFactory, pKeySpec);
1175
1176
1177 try {
1178
1179 theGenerator = getJavaKeyPairGenerator(SNOVA_ALGO, true);
1180 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1181 final SnovaParameterSpec myParms = myKeySpec.getSnovaSpec().getParameterSpec();
1182 theGenerator.initialize(myParms, getRandom());
1183
1184
1185 setKeyFactory(getJavaKeyFactory(SNOVA_ALGO, true));
1186
1187 } catch (InvalidAlgorithmParameterException e) {
1188 throw new GordianCryptoException("Failed to create SnovaGenerator", e);
1189 }
1190 }
1191
1192 @Override
1193 public JcaKeyPair generateKeyPair() {
1194
1195 final KeyPair myPair = theGenerator.generateKeyPair();
1196 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1197 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1198 return new JcaKeyPair(myPublic, myPrivate);
1199 }
1200 }
1201
1202
1203
1204
1205 public static class JcaNTRULPrimeKeyPairGenerator
1206 extends JcaKeyPairGenerator {
1207
1208
1209
1210 private static final String NTRU_ALGO = "NTRULPRIME";
1211
1212
1213
1214
1215 private final KeyPairGenerator theGenerator;
1216
1217
1218
1219
1220
1221
1222
1223
1224 JcaNTRULPrimeKeyPairGenerator(final GordianBaseFactory pFactory,
1225 final GordianKeyPairSpec pKeySpec) throws GordianException {
1226
1227 super(pFactory, pKeySpec);
1228
1229
1230 try {
1231
1232 theGenerator = getJavaKeyPairGenerator(NTRU_ALGO, true);
1233 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1234 final NTRULPRimeParameterSpec myParms = myKeySpec.getNTRUPrimeSpec().getCoreParams().getNTRULParameterSpec();
1235 theGenerator.initialize(myParms, getRandom());
1236
1237
1238 setKeyFactory(getJavaKeyFactory(NTRU_ALGO, true));
1239
1240 } catch (InvalidAlgorithmParameterException e) {
1241 throw new GordianCryptoException("Failed to create NTRULPrimeGenerator", e);
1242 }
1243 }
1244
1245 @Override
1246 public JcaKeyPair generateKeyPair() {
1247
1248 final KeyPair myPair = theGenerator.generateKeyPair();
1249 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1250 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1251 return new JcaKeyPair(myPublic, myPrivate);
1252 }
1253 }
1254
1255
1256
1257
1258 public static class JcaSNTRUPrimeKeyPairGenerator
1259 extends JcaKeyPairGenerator {
1260
1261
1262
1263 private static final String NTRU_ALGO = "SNTRUPRIME";
1264
1265
1266
1267
1268 private final KeyPairGenerator theGenerator;
1269
1270
1271
1272
1273
1274
1275
1276
1277 JcaSNTRUPrimeKeyPairGenerator(final GordianBaseFactory pFactory,
1278 final GordianKeyPairSpec pKeySpec) throws GordianException {
1279
1280 super(pFactory, pKeySpec);
1281
1282
1283 try {
1284
1285 theGenerator = getJavaKeyPairGenerator(NTRU_ALGO, true);
1286 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1287 final SNTRUPrimeParameterSpec myParms = myKeySpec.getNTRUPrimeSpec().getCoreParams().getSNTRUParameterSpec();
1288 theGenerator.initialize(myParms, getRandom());
1289
1290
1291 setKeyFactory(getJavaKeyFactory(NTRU_ALGO, true));
1292
1293 } catch (InvalidAlgorithmParameterException e) {
1294 throw new GordianCryptoException("Failed to create SNTRUPrimeGenerator", e);
1295 }
1296 }
1297
1298 @Override
1299 public JcaKeyPair generateKeyPair() {
1300
1301 final KeyPair myPair = theGenerator.generateKeyPair();
1302 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1303 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1304 return new JcaKeyPair(myPublic, myPrivate);
1305 }
1306 }
1307
1308
1309
1310
1311 public static class JcaPicnicKeyPairGenerator
1312 extends JcaKeyPairGenerator {
1313
1314
1315
1316 private static final String PICNIC_ALGO = "PICNIC";
1317
1318
1319
1320
1321 private final KeyPairGenerator theGenerator;
1322
1323
1324
1325
1326
1327
1328
1329
1330 JcaPicnicKeyPairGenerator(final GordianBaseFactory pFactory,
1331 final GordianKeyPairSpec pKeySpec) throws GordianException {
1332
1333 super(pFactory, pKeySpec);
1334
1335
1336 try {
1337
1338 theGenerator = getJavaKeyPairGenerator(PICNIC_ALGO, true);
1339 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1340 final PicnicParameterSpec myParms = myKeySpec.getPicnicSpec().getParameterSpec();
1341 theGenerator.initialize(myParms, getRandom());
1342
1343
1344 setKeyFactory(getJavaKeyFactory(PICNIC_ALGO, true));
1345
1346 } catch (InvalidAlgorithmParameterException e) {
1347 throw new GordianCryptoException("Failed to create PICNICgenerator", e);
1348 }
1349 }
1350
1351 @Override
1352 public JcaKeyPair generateKeyPair() {
1353
1354 final KeyPair myPair = theGenerator.generateKeyPair();
1355 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1356 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1357 return new JcaKeyPair(myPublic, myPrivate);
1358 }
1359 }
1360
1361
1362
1363
1364 public static class JcaXMSSKeyPairGenerator
1365 extends JcaKeyPairGenerator {
1366
1367
1368
1369 private final KeyPairGenerator theGenerator;
1370
1371
1372
1373
1374
1375
1376
1377
1378 JcaXMSSKeyPairGenerator(final GordianBaseFactory pFactory,
1379 final GordianKeyPairSpec pKeySpec) throws GordianException {
1380
1381 super(pFactory, pKeySpec);
1382
1383
1384 try {
1385
1386 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1387 final GordianCoreXMSSSpec myXMSSKeySpec = myKeySpec.getXMSSSpec();
1388 final boolean isXMSSMT = myXMSSKeySpec.isMT();
1389 final GordianXMSSDigestType myType = myXMSSKeySpec.getDigestType();
1390
1391
1392 final AlgorithmParameterSpec myAlgo = isXMSSMT
1393 ? new XMSSMTParameterSpec(myXMSSKeySpec.getHeight().getHeight(),
1394 myXMSSKeySpec.getLayers().getLayers(), myType.name())
1395 : new XMSSParameterSpec(myXMSSKeySpec.getHeight().getHeight(), myType.name());
1396
1397
1398 final String myJavaType = myXMSSKeySpec.getKeyType().name();
1399 theGenerator = getJavaKeyPairGenerator(myJavaType, true);
1400 theGenerator.initialize(myAlgo, getRandom());
1401
1402
1403 setKeyFactory(getJavaKeyFactory(myJavaType, true));
1404
1405 } catch (InvalidAlgorithmParameterException e) {
1406 throw new GordianCryptoException("Failed to create XMSSgenerator", e);
1407 }
1408 }
1409
1410 @Override
1411 public JcaKeyPair generateKeyPair() {
1412
1413 final KeyPair myPair = theGenerator.generateKeyPair();
1414 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1415 final JcaStateAwarePrivateKey myPrivate = createPrivate(myPair.getPrivate());
1416 return new JcaStateAwareKeyPair(myPublic, myPrivate);
1417 }
1418
1419 @Override
1420 protected JcaStateAwarePrivateKey createPrivate(final PrivateKey pPrivateKey) {
1421 return new JcaStateAwarePrivateKey(getKeySpec(), pPrivateKey);
1422 }
1423
1424 @Override
1425 public JcaKeyPair deriveKeyPair(final X509EncodedKeySpec pPublicKey,
1426 final PKCS8EncodedKeySpec pPrivateKey) throws GordianException {
1427
1428 try {
1429
1430 checkKeySpec(pPrivateKey);
1431
1432
1433 final JcaPublicKey myPublic = derivePublicKey(pPublicKey);
1434 JcaStateAwarePrivateKey myPrivate = createPrivate(getKeyFactory().generatePrivate(pPrivateKey));
1435 final JcaKeyPair myPair = new JcaStateAwareKeyPair(myPublic, myPrivate);
1436
1437
1438 GordianKeyPairValidity.checkValidity(getFactory(), myPair);
1439
1440
1441 myPrivate = createPrivate(getKeyFactory().generatePrivate(pPrivateKey));
1442 return new JcaStateAwareKeyPair(myPublic, myPrivate);
1443
1444 } catch (InvalidKeySpecException e) {
1445 throw new GordianCryptoException(PARSE_ERROR, e);
1446 }
1447 }
1448 }
1449
1450
1451
1452
1453 public static class JcaEdKeyPairGenerator
1454 extends JcaKeyPairGenerator {
1455
1456
1457
1458 private final KeyPairGenerator theGenerator;
1459
1460
1461
1462
1463
1464
1465
1466
1467 protected JcaEdKeyPairGenerator(final GordianBaseFactory pFactory,
1468 final GordianKeyPairSpec pKeySpec) throws GordianException {
1469
1470 super(pFactory, pKeySpec);
1471
1472
1473 try {
1474
1475 final AlgorithmParameterSpec myAlgo;
1476 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1477 final boolean is25519 = myKeySpec.getEdwardsSpec().is25519();
1478 myAlgo = switch (pKeySpec.getKeyPairType()) {
1479 case XDH -> is25519
1480 ? new XDHParameterSpec(XDHParameterSpec.X25519)
1481 : new XDHParameterSpec(XDHParameterSpec.X448);
1482 case EDDSA -> is25519
1483 ? new EdDSAParameterSpec(EdDSAParameterSpec.Ed25519)
1484 : new EdDSAParameterSpec(EdDSAParameterSpec.Ed448);
1485 default -> throw new GordianLogicException("Invalid KeySpec" + pKeySpec);
1486 };
1487
1488
1489 final String myJavaType = pKeySpec.toString();
1490 theGenerator = getJavaKeyPairGenerator(myJavaType, false);
1491 theGenerator.initialize(myAlgo, getRandom());
1492
1493
1494 setKeyFactory(getJavaKeyFactory(myJavaType, false));
1495
1496 } catch (InvalidAlgorithmParameterException e) {
1497 throw new GordianCryptoException("Failed to create EdwardsGenerator", e);
1498 }
1499 }
1500
1501 @Override
1502 public JcaKeyPair generateKeyPair() {
1503
1504 final KeyPair myPair = theGenerator.generateKeyPair();
1505 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1506 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1507 return new JcaKeyPair(myPublic, myPrivate);
1508 }
1509 }
1510
1511
1512
1513
1514 public static class JcaNewHopeKeyPairGenerator
1515 extends JcaKeyPairGenerator {
1516
1517
1518
1519 private static final String NEWHOPE_ALGO = "NH";
1520
1521
1522
1523
1524 private final KeyPairGenerator theGenerator;
1525
1526
1527
1528
1529
1530
1531
1532
1533 JcaNewHopeKeyPairGenerator(final GordianBaseFactory pFactory,
1534 final GordianKeyPairSpec pKeySpec) throws GordianException {
1535
1536 super(pFactory, pKeySpec);
1537
1538
1539 theGenerator = getJavaKeyPairGenerator(NEWHOPE_ALGO, true);
1540 theGenerator.initialize(GordianLength.LEN_1024.getLength(), getRandom());
1541
1542
1543 setKeyFactory(getJavaKeyFactory(NEWHOPE_ALGO, true));
1544 }
1545
1546 @Override
1547 public JcaKeyPair generateKeyPair() {
1548
1549 final KeyPair myPair = theGenerator.generateKeyPair();
1550 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1551 final JcaPrivateKey myPrivate = createPrivate(myPair.getPrivate());
1552 return new JcaKeyPair(myPublic, myPrivate);
1553 }
1554 }
1555
1556
1557
1558
1559 public static class JcaLMSKeyPairGenerator
1560 extends JcaKeyPairGenerator {
1561
1562
1563
1564 private final KeyPairGenerator theGenerator;
1565
1566
1567
1568
1569
1570
1571
1572
1573 JcaLMSKeyPairGenerator(final GordianBaseFactory pFactory,
1574 final GordianKeyPairSpec pKeySpec) throws GordianException {
1575
1576 super(pFactory, pKeySpec);
1577
1578
1579 final String myJavaType = pKeySpec.getKeyPairType().toString();
1580 theGenerator = getJavaKeyPairGenerator(myJavaType, true);
1581
1582
1583 try {
1584 final GordianCoreKeyPairSpec myKeySpec = (GordianCoreKeyPairSpec) pKeySpec;
1585 final AlgorithmParameterSpec myParms = deriveParameters(myKeySpec.getLMSSpec());
1586 theGenerator.initialize(myParms, getRandom());
1587
1588 } catch (InvalidAlgorithmParameterException e) {
1589 throw new GordianCryptoException("Failed to initialize generator", e);
1590 }
1591
1592
1593 setKeyFactory(getJavaKeyFactory(myJavaType, true));
1594 }
1595
1596
1597
1598
1599
1600
1601
1602 private static LMSHSSKeyGenParameterSpec deriveParameters(final GordianCoreLMSSpec pKeySpec) {
1603
1604 final LMSKeyGenParameterSpec[] myParams = new LMSKeyGenParameterSpec[pKeySpec.getTreeDepth()];
1605 final LMSParameters myParms = pKeySpec.getParameters();
1606 final LMSKeyGenParameterSpec myKeyGen = new LMSKeyGenParameterSpec(myParms.getLMSigParam(), myParms.getLMOTSParam());
1607 Arrays.fill(myParams, myKeyGen);
1608 return new LMSHSSKeyGenParameterSpec(myParams);
1609 }
1610
1611 @Override
1612 public JcaKeyPair generateKeyPair() {
1613
1614 final KeyPair myPair = theGenerator.generateKeyPair();
1615 final JcaPublicKey myPublic = createPublic(myPair.getPublic());
1616 final JcaStateAwarePrivateKey myPrivate = createPrivate(myPair.getPrivate());
1617 return new JcaStateAwareKeyPair(myPublic, myPrivate);
1618 }
1619
1620 @Override
1621 protected JcaStateAwarePrivateKey createPrivate(final PrivateKey pPrivateKey) {
1622 return new JcaStateAwarePrivateKey(getKeySpec(), pPrivateKey);
1623 }
1624
1625 @Override
1626 public JcaKeyPair deriveKeyPair(final X509EncodedKeySpec pPublicKey,
1627 final PKCS8EncodedKeySpec pPrivateKey) throws GordianException {
1628
1629 try {
1630
1631 checkKeySpec(pPrivateKey);
1632
1633
1634 final JcaPublicKey myPublic = derivePublicKey(pPublicKey);
1635 JcaStateAwarePrivateKey myPrivate = createPrivate(getKeyFactory().generatePrivate(pPrivateKey));
1636 final JcaKeyPair myPair = new JcaStateAwareKeyPair(myPublic, myPrivate);
1637
1638
1639 GordianKeyPairValidity.checkValidity(getFactory(), myPair);
1640
1641
1642 myPrivate = createPrivate(getKeyFactory().generatePrivate(pPrivateKey));
1643 return new JcaStateAwareKeyPair(myPublic, myPrivate);
1644
1645 } catch (InvalidKeySpecException e) {
1646 throw new GordianCryptoException(PARSE_ERROR, e);
1647 }
1648 }
1649 }
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659 static KeyFactory getJavaKeyFactory(final String pAlgorithm,
1660 final boolean postQuantum) throws GordianException {
1661
1662 try {
1663
1664 return KeyFactory.getInstance(pAlgorithm, postQuantum
1665 ? JcaProvider.BCPQPROV
1666 : JcaProvider.BCPROV);
1667
1668
1669 } catch (NoSuchAlgorithmException e) {
1670
1671 throw new GordianCryptoException("Failed to create KeyFactory", e);
1672 }
1673 }
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683 static KeyPairGenerator getJavaKeyPairGenerator(final String pAlgorithm,
1684 final boolean postQuantum) throws GordianException {
1685
1686 try {
1687
1688 return KeyPairGenerator.getInstance(pAlgorithm, postQuantum
1689 ? JcaProvider.BCPQPROV
1690 : JcaProvider.BCPROV);
1691
1692
1693 } catch (NoSuchAlgorithmException e) {
1694
1695 throw new GordianCryptoException("Failed to create KeyPairGenerator", e);
1696 }
1697 }
1698 }