Skip to content

Commit 7324d9a

Browse files
committed
added support for ML-DSA, attempted to avoid getting private key encoding.
updated CMP test to use ML-DSA, ML-KEM.
1 parent 108fcf5 commit 7324d9a

File tree

2 files changed

+59
-52
lines changed

2 files changed

+59
-52
lines changed

pkix/src/main/java/org/bouncycastle/operator/jcajce/JcaContentSignerBuilder.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,15 @@
4646
public class JcaContentSignerBuilder
4747
{
4848
private static final Set isAlgIdFromPrivate = new HashSet();
49+
private static final DefaultSignatureAlgorithmIdentifierFinder SIGNATURE_ALGORITHM_IDENTIFIER_FINDER = new DefaultSignatureAlgorithmIdentifierFinder();
4950

5051
static
5152
{
5253
isAlgIdFromPrivate.add("DILITHIUM");
5354
isAlgIdFromPrivate.add("SPHINCS+");
5455
isAlgIdFromPrivate.add("SPHINCSPlus");
56+
isAlgIdFromPrivate.add("ML-DSA");
57+
isAlgIdFromPrivate.add("SLH-DSA");
5558
}
5659

5760
private final String signatureAlgorithm;
@@ -130,12 +133,16 @@ public ContentSigner build(PrivateKey privateKey)
130133
{
131134
if (isAlgIdFromPrivate.contains(Strings.toUpperCase(signatureAlgorithm)))
132135
{
133-
sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm();
136+
this.sigAlgId = SIGNATURE_ALGORITHM_IDENTIFIER_FINDER.find(privateKey.getAlgorithm());
137+
if (this.sigAlgId == null)
138+
{
139+
this.sigAlgId = PrivateKeyInfo.getInstance(privateKey.getEncoded()).getPrivateKeyAlgorithm();
140+
}
134141
this.sigAlgSpec = null;
135142
}
136143
else
137144
{
138-
this.sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find(signatureAlgorithm);
145+
this.sigAlgId = SIGNATURE_ALGORITHM_IDENTIFIER_FINDER.find(signatureAlgorithm);
139146
this.sigAlgSpec = null;
140147
}
141148
}

pkix/src/test/java/org/bouncycastle/cert/cmp/test/PQCTest.java

+50-50
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
5353
import org.bouncycastle.cms.jcajce.JceKEMEnvelopedRecipient;
5454
import org.bouncycastle.cms.jcajce.JceKEMRecipientInfoGenerator;
55+
import org.bouncycastle.jcajce.spec.MLDSAParameterSpec;
56+
import org.bouncycastle.jcajce.spec.MLKEMParameterSpec;
5557
import org.bouncycastle.jce.provider.BouncyCastleProvider;
5658
import org.bouncycastle.operator.ContentSigner;
5759
import org.bouncycastle.operator.ContentVerifierProvider;
@@ -66,9 +68,7 @@
6668
import org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider;
6769
import org.bouncycastle.pqc.jcajce.spec.BIKEParameterSpec;
6870
import org.bouncycastle.pqc.jcajce.spec.CMCEParameterSpec;
69-
import org.bouncycastle.pqc.jcajce.spec.DilithiumParameterSpec;
7071
import org.bouncycastle.pqc.jcajce.spec.HQCParameterSpec;
71-
import org.bouncycastle.pqc.jcajce.spec.KyberParameterSpec;
7272
import org.bouncycastle.pqc.jcajce.spec.NTRUParameterSpec;
7373
import org.bouncycastle.util.BigIntegers;
7474

@@ -86,24 +86,24 @@ public void tearDown()
8686

8787
}
8888

89-
public void testKyberRequestWithDilithiumCA()
89+
public void testMlKemRequestWithMlDsaCA()
9090
throws Exception
9191
{
9292
char[] senderMacPassword = "secret".toCharArray();
93-
GeneralName sender = new GeneralName(new X500Name("CN=Kyber Subject"));
94-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
93+
GeneralName sender = new GeneralName(new X500Name("CN=ML-KEM Subject"));
94+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
9595

96-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
96+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
9797

98-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
98+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_65);
9999

100100
KeyPair dilKp = dilKpGen.generateKeyPair();
101101

102-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
102+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
103103

104-
KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("Kyber", "BCPQC");
104+
KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("ML-KEM", "BC");
105105

106-
kybKpGen.initialize(KyberParameterSpec.kyber512);
106+
kybKpGen.initialize(MLKEMParameterSpec.ml_kem_768);
107107

108108
KeyPair kybKp = kybKpGen.generateKeyPair();
109109

@@ -140,7 +140,7 @@ public void testKyberRequestWithDilithiumCA()
140140
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
141141
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
142142

143-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
143+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
144144

145145
// Send response with encrypted certificate
146146
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -163,7 +163,7 @@ public void testKyberRequestWithDilithiumCA()
163163

164164
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
165165

166-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
166+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
167167

168168
CertificateRepMessage repMessage = repMessageBuilder.build();
169169

@@ -210,7 +210,7 @@ public void testKyberRequestWithDilithiumCA()
210210

211211
RecipientInformation recInfo = (RecipientInformation)c.iterator().next();
212212

213-
assertEquals(recInfo.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_alg_ml_kem_512.getId());
213+
assertEquals(recInfo.getKeyEncryptionAlgOID(), NISTObjectIdentifiers.id_alg_ml_kem_768.getId());
214214

215215
// Note: we don't specify the provider here as we're actually using both BC and BCPQC
216216

@@ -248,20 +248,20 @@ public void testKyberRequestWithDilithiumCA()
248248
assertTrue(recContent.getStatusMessages()[0].isVerified(receivedCert, new JcaDigestCalculatorProviderBuilder().build()));
249249
}
250250

251-
public void testNTRURequestWithDilithiumCA()
251+
public void testNTRURequestWithMlDsaCA()
252252
throws Exception
253253
{
254254
char[] senderMacPassword = "secret".toCharArray();
255255
GeneralName sender = new GeneralName(new X500Name("CN=NTRU Subject"));
256-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
256+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
257257

258-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
258+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
259259

260-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
260+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
261261

262262
KeyPair dilKp = dilKpGen.generateKeyPair();
263263

264-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
264+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
265265

266266
KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("NTRU", "BCPQC");
267267

@@ -302,7 +302,7 @@ public void testNTRURequestWithDilithiumCA()
302302
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
303303
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
304304

305-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
305+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
306306

307307
// Send response with encrypted certificate
308308
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -325,7 +325,7 @@ public void testNTRURequestWithDilithiumCA()
325325

326326
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
327327

328-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
328+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
329329

330330
CertificateRepMessage repMessage = repMessageBuilder.build();
331331

@@ -420,20 +420,20 @@ public void testNTRURequestWithDilithiumCA()
420420
// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure()));
421421
}
422422

423-
public void testBIKERequestWithDilithiumCA()
423+
public void testBIKERequestWithMlDsaCA()
424424
throws Exception
425425
{
426426
char[] senderMacPassword = "secret".toCharArray();
427427
GeneralName sender = new GeneralName(new X500Name("CN=Bike128 Subject"));
428-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
428+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
429429

430-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
430+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
431431

432-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
432+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
433433

434434
KeyPair dilKp = dilKpGen.generateKeyPair();
435435

436-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
436+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
437437

438438
KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("BIKE", "BCPQC");
439439

@@ -474,7 +474,7 @@ public void testBIKERequestWithDilithiumCA()
474474
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
475475
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
476476

477-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
477+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
478478

479479
// Send response with encrypted certificate
480480
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -497,7 +497,7 @@ public void testBIKERequestWithDilithiumCA()
497497

498498
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
499499

500-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
500+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
501501

502502
CertificateRepMessage repMessage = repMessageBuilder.build();
503503

@@ -592,20 +592,20 @@ public void testBIKERequestWithDilithiumCA()
592592
// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure()));
593593
}
594594

595-
public void testHQCRequestWithDilithiumCA()
595+
public void testHQCRequestWithMlDsaCA()
596596
throws Exception
597597
{
598598
char[] senderMacPassword = "secret".toCharArray();
599599
GeneralName sender = new GeneralName(new X500Name("CN=HQC128 Subject"));
600-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
600+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
601601

602-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
602+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
603603

604-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
604+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
605605

606606
KeyPair dilKp = dilKpGen.generateKeyPair();
607607

608-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
608+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
609609

610610
KeyPairGenerator kybKpGen = KeyPairGenerator.getInstance("HQC", "BCPQC");
611611

@@ -646,7 +646,7 @@ public void testHQCRequestWithDilithiumCA()
646646
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
647647
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
648648

649-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
649+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
650650

651651
// Send response with encrypted certificate
652652
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -669,7 +669,7 @@ public void testHQCRequestWithDilithiumCA()
669669

670670
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
671671

672-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
672+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
673673

674674
CertificateRepMessage repMessage = repMessageBuilder.build();
675675

@@ -764,20 +764,20 @@ public void testHQCRequestWithDilithiumCA()
764764
// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure()));
765765
}
766766

767-
public void testCMCERequestWithDilithiumCA()
767+
public void testCMCERequestWithMlDsaCA()
768768
throws Exception
769769
{
770770
char[] senderMacPassword = "secret".toCharArray();
771771
GeneralName sender = new GeneralName(new X500Name("CN=mceliece3488864 Subject"));
772-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
772+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
773773

774-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
774+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
775775

776-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
776+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
777777

778778
KeyPair dilKp = dilKpGen.generateKeyPair();
779779

780-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
780+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
781781

782782
KeyPairGenerator cmceKpGen = KeyPairGenerator.getInstance("CMCE", "BCPQC");
783783

@@ -818,7 +818,7 @@ public void testCMCERequestWithDilithiumCA()
818818
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
819819
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
820820

821-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
821+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
822822

823823
// Send response with encrypted certificate
824824
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -841,7 +841,7 @@ public void testCMCERequestWithDilithiumCA()
841841

842842
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
843843

844-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
844+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
845845

846846
CertificateRepMessage repMessage = repMessageBuilder.build();
847847

@@ -936,20 +936,20 @@ public void testCMCERequestWithDilithiumCA()
936936
// System.err.println(ASN1Dump.dumpAsString(receivedEnvelope.toASN1Structure()));
937937
}
938938

939-
public void testExternalCMCERequestWithDilithiumCA()
939+
public void testExternalCMCERequestWithMlDsaCA()
940940
throws Exception
941941
{
942942
char[] senderMacPassword = "secret".toCharArray();
943943
GeneralName sender = new GeneralName(new X500Name("CN=mceliece3488864 Subject"));
944-
GeneralName recipient = new GeneralName(new X500Name("CN=Dilithium Issuer"));
944+
GeneralName recipient = new GeneralName(new X500Name("CN=ML-DSA Issuer"));
945945

946-
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("Dilithium", "BCPQC");
946+
KeyPairGenerator dilKpGen = KeyPairGenerator.getInstance("ML-DSA", "BC");
947947

948-
dilKpGen.initialize(DilithiumParameterSpec.dilithium2);
948+
dilKpGen.initialize(MLDSAParameterSpec.ml_dsa_44);
949949

950950
KeyPair dilKp = dilKpGen.generateKeyPair();
951951

952-
X509CertificateHolder caCert = makeV3Certificate("CN=Dilithium Issuer", dilKp);
952+
X509CertificateHolder caCert = makeV3Certificate("CN=ML-DSA Issuer", dilKp);
953953

954954
KeyPairGenerator cmceKpGen = KeyPairGenerator.getInstance("CMCE", "BCPQC");
955955

@@ -990,7 +990,7 @@ public void testExternalCMCERequestWithDilithiumCA()
990990
CertificateRequestMessage senderReqMessage = requestMessages.getRequests()[0];
991991
CertTemplate certTemplate = senderReqMessage.getCertTemplate();
992992

993-
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=Dilithium Issuer");
993+
X509CertificateHolder cert = makeV3Certificate(certTemplate.getPublicKey(), certTemplate.getSubject(), dilKp, "CN=ML-DSA Issuer");
994994

995995
// Send response with encrypted certificate
996996
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
@@ -1013,7 +1013,7 @@ public void testExternalCMCERequestWithDilithiumCA()
10131013

10141014
repMessageBuilder.addCertificateResponse(certRespBuilder.build());
10151015

1016-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").setProvider("BCPQC").build(dilKp.getPrivate());
1016+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").setProvider("BC").build(dilKp.getPrivate());
10171017

10181018
CertificateRepMessage repMessage = repMessageBuilder.build();
10191019

@@ -1124,7 +1124,7 @@ private static X509CertificateHolder makeV3Certificate(String _subDN, KeyPair is
11241124

11251125
certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));
11261126

1127-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").build(issPriv);
1127+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").build(issPriv);
11281128

11291129
X509CertificateHolder certHolder = certGen.build(signer);
11301130

@@ -1151,7 +1151,7 @@ private static X509CertificateHolder makeV3Certificate(SubjectPublicKeyInfo pubK
11511151

11521152
certGen.addExtension(Extension.basicConstraints, true, new BasicConstraints(false));
11531153

1154-
ContentSigner signer = new JcaContentSignerBuilder("Dilithium").build(issPriv);
1154+
ContentSigner signer = new JcaContentSignerBuilder("ML-DSA").build(issPriv);
11551155

11561156
X509CertificateHolder certHolder = certGen.build(signer);
11571157

0 commit comments

Comments
 (0)