1313import org .bouncycastle .asn1 .ASN1Sequence ;
1414import org .bouncycastle .asn1 .DEROctetString ;
1515import org .bouncycastle .asn1 .bc .BCObjectIdentifiers ;
16+ import org .bouncycastle .asn1 .nist .NISTObjectIdentifiers ;
1617import org .bouncycastle .asn1 .pkcs .PKCSObjectIdentifiers ;
1718import org .bouncycastle .asn1 .pkcs .PrivateKeyInfo ;
1819import org .bouncycastle .asn1 .x509 .AlgorithmIdentifier ;
3132import org .bouncycastle .pqc .crypto .crystals .dilithium .DilithiumParameters ;
3233import org .bouncycastle .pqc .crypto .crystals .dilithium .DilithiumPrivateKeyParameters ;
3334import org .bouncycastle .pqc .crypto .crystals .dilithium .DilithiumPublicKeyParameters ;
34- import org .bouncycastle .pqc .crypto .mlkem .KyberParameters ;
35- import org .bouncycastle .pqc .crypto .mlkem .KyberPrivateKeyParameters ;
3635import org .bouncycastle .pqc .crypto .falcon .FalconParameters ;
3736import org .bouncycastle .pqc .crypto .falcon .FalconPrivateKeyParameters ;
3837import org .bouncycastle .pqc .crypto .frodo .FrodoParameters ;
3938import org .bouncycastle .pqc .crypto .frodo .FrodoPrivateKeyParameters ;
4039import org .bouncycastle .pqc .crypto .hqc .HQCParameters ;
4140import org .bouncycastle .pqc .crypto .hqc .HQCPrivateKeyParameters ;
41+ import org .bouncycastle .pqc .crypto .mldsa .MLDSAParameters ;
42+ import org .bouncycastle .pqc .crypto .mldsa .MLDSAPrivateKeyParameters ;
43+ import org .bouncycastle .pqc .crypto .mldsa .MLDSAPublicKeyParameters ;
44+ import org .bouncycastle .pqc .crypto .mlkem .MLKEMParameters ;
45+ import org .bouncycastle .pqc .crypto .mlkem .MLKEMPrivateKeyParameters ;
4246import org .bouncycastle .pqc .crypto .newhope .NHPrivateKeyParameters ;
4347import org .bouncycastle .pqc .crypto .ntru .NTRUParameters ;
4448import org .bouncycastle .pqc .crypto .ntru .NTRUPrivateKeyParameters ;
5054import org .bouncycastle .pqc .crypto .picnic .PicnicPrivateKeyParameters ;
5155import org .bouncycastle .pqc .crypto .saber .SABERParameters ;
5256import org .bouncycastle .pqc .crypto .saber .SABERPrivateKeyParameters ;
57+ import org .bouncycastle .pqc .crypto .slhdsa .SLHDSAParameters ;
58+ import org .bouncycastle .pqc .crypto .slhdsa .SLHDSAPrivateKeyParameters ;
5359import org .bouncycastle .pqc .crypto .sphincs .SPHINCSPrivateKeyParameters ;
5460import org .bouncycastle .pqc .crypto .sphincsplus .SPHINCSPlusParameters ;
5561import org .bouncycastle .pqc .crypto .sphincsplus .SPHINCSPlusPrivateKeyParameters ;
62+ import org .bouncycastle .pqc .legacy .crypto .mceliece .McElieceCCA2PrivateKeyParameters ;
5663import org .bouncycastle .util .Arrays ;
5764import org .bouncycastle .util .Pack ;
5865
@@ -140,6 +147,23 @@ else if (algOID.on(BCObjectIdentifiers.sphincsPlus) || algOID.on(BCObjectIdentif
140147 return new SPHINCSPlusPrivateKeyParameters (spParams , ASN1OctetString .getInstance (obj ).getOctets ());
141148 }
142149 }
150+ else if (Utils .shldsaParams .containsKey (algOID ))
151+ {
152+ SLHDSAParameters spParams = Utils .slhdsaParamsLookup (algOID );
153+
154+ ASN1Encodable obj = keyInfo .parsePrivateKey ();
155+ if (obj instanceof ASN1Sequence )
156+ {
157+ SPHINCSPLUSPrivateKey spKey = SPHINCSPLUSPrivateKey .getInstance (obj );
158+ SPHINCSPLUSPublicKey publicKey = spKey .getPublicKey ();
159+ return new SLHDSAPrivateKeyParameters (spParams , spKey .getSkseed (), spKey .getSkprf (),
160+ publicKey .getPkseed (), publicKey .getPkroot ());
161+ }
162+ else
163+ {
164+ return new SLHDSAPrivateKeyParameters (spParams , ASN1OctetString .getInstance (obj ).getOctets ());
165+ }
166+ }
143167 else if (algOID .on (BCObjectIdentifiers .picnic ))
144168 {
145169 byte [] keyEnc = ASN1OctetString .getInstance (keyInfo .parsePrivateKey ()).getOctets ();
@@ -175,12 +199,14 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_ntru))
175199
176200 return new NTRUPrivateKeyParameters (spParams , keyEnc );
177201 }
178- else if (algOID .on (BCObjectIdentifiers .pqc_kem_kyber ))
202+ else if (algOID .equals (NISTObjectIdentifiers .id_alg_ml_kem_512 ) ||
203+ algOID .equals (NISTObjectIdentifiers .id_alg_ml_kem_768 ) ||
204+ algOID .equals (NISTObjectIdentifiers .id_alg_ml_kem_1024 ))
179205 {
180206 ASN1OctetString kyberKey = ASN1OctetString .getInstance (keyInfo .parsePrivateKey ());
181- KyberParameters kyberParams = Utils .kyberParamsLookup (algOID );
207+ MLKEMParameters kyberParams = Utils .mlkemParamsLookup (algOID );
182208
183- return new KyberPrivateKeyParameters (kyberParams , kyberKey .getOctets ());
209+ return new MLKEMPrivateKeyParameters (kyberParams , kyberKey .getOctets ());
184210 }
185211 else if (algOID .on (BCObjectIdentifiers .pqc_kem_ntrulprime ))
186212 {
@@ -207,11 +233,66 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_sntruprime))
207233 ASN1OctetString .getInstance (keyEnc .getObjectAt (3 )).getOctets (),
208234 ASN1OctetString .getInstance (keyEnc .getObjectAt (4 )).getOctets ());
209235 }
236+ else if (Utils .mldsaParams .containsKey (algOID ))
237+ {
238+ ASN1Encodable keyObj = keyInfo .parsePrivateKey ();
239+ MLDSAParameters spParams = Utils .mldsaParamsLookup (algOID );
240+
241+ if (keyObj instanceof ASN1Sequence )
242+ {
243+ ASN1Sequence keyEnc = ASN1Sequence .getInstance (keyObj );
244+
245+ int version = ASN1Integer .getInstance (keyEnc .getObjectAt (0 )).intValueExact ();
246+ if (version != 0 )
247+ {
248+ throw new IOException ("unknown private key version: " + version );
249+ }
250+
251+ if (keyInfo .getPublicKeyData () != null )
252+ {
253+ MLDSAPublicKeyParameters pubParams = PublicKeyFactory .MLDSAConverter .getPublicKeyParams (spParams , keyInfo .getPublicKeyData ());
254+
255+ return new MLDSAPrivateKeyParameters (spParams ,
256+ ASN1BitString .getInstance (keyEnc .getObjectAt (1 )).getOctets (),
257+ ASN1BitString .getInstance (keyEnc .getObjectAt (2 )).getOctets (),
258+ ASN1BitString .getInstance (keyEnc .getObjectAt (3 )).getOctets (),
259+ ASN1BitString .getInstance (keyEnc .getObjectAt (4 )).getOctets (),
260+ ASN1BitString .getInstance (keyEnc .getObjectAt (5 )).getOctets (),
261+ ASN1BitString .getInstance (keyEnc .getObjectAt (6 )).getOctets (),
262+ pubParams .getT1 ()); // encT1
263+ }
264+ else
265+ {
266+ return new MLDSAPrivateKeyParameters (spParams ,
267+ ASN1BitString .getInstance (keyEnc .getObjectAt (1 )).getOctets (),
268+ ASN1BitString .getInstance (keyEnc .getObjectAt (2 )).getOctets (),
269+ ASN1BitString .getInstance (keyEnc .getObjectAt (3 )).getOctets (),
270+ ASN1BitString .getInstance (keyEnc .getObjectAt (4 )).getOctets (),
271+ ASN1BitString .getInstance (keyEnc .getObjectAt (5 )).getOctets (),
272+ ASN1BitString .getInstance (keyEnc .getObjectAt (6 )).getOctets (),
273+ null );
274+ }
275+ }
276+ else if (keyObj instanceof DEROctetString )
277+ {
278+ byte [] data = ASN1OctetString .getInstance (keyObj ).getOctets ();
279+ if (keyInfo .getPublicKeyData () != null )
280+ {
281+ MLDSAPublicKeyParameters pubParams = PublicKeyFactory .MLDSAConverter .getPublicKeyParams (spParams , keyInfo .getPublicKeyData ());
282+ return new MLDSAPrivateKeyParameters (spParams , data , pubParams );
283+ }
284+ return new MLDSAPrivateKeyParameters (spParams , data );
285+ }
286+ else
287+ {
288+ throw new IOException ("not supported" );
289+ }
290+ }
210291 else if (algOID .equals (BCObjectIdentifiers .dilithium2 )
211292 || algOID .equals (BCObjectIdentifiers .dilithium3 ) || algOID .equals (BCObjectIdentifiers .dilithium5 ))
212293 {
213294 ASN1Encodable keyObj = keyInfo .parsePrivateKey ();
214- DilithiumParameters spParams = Utils .dilithiumParamsLookup (algOID );
295+ DilithiumParameters dilParams = Utils .dilithiumParamsLookup (algOID );
215296
216297 if (keyObj instanceof ASN1Sequence )
217298 {
@@ -225,9 +306,9 @@ else if (algOID.equals(BCObjectIdentifiers.dilithium2)
225306
226307 if (keyInfo .getPublicKeyData () != null )
227308 {
228- DilithiumPublicKeyParameters pubParams = PublicKeyFactory .DilithiumConverter .getPublicKeyParams (spParams , keyInfo .getPublicKeyData ());
309+ DilithiumPublicKeyParameters pubParams = PublicKeyFactory .DilithiumConverter .getPublicKeyParams (dilParams , keyInfo .getPublicKeyData ());
229310
230- return new DilithiumPrivateKeyParameters (spParams ,
311+ return new DilithiumPrivateKeyParameters (dilParams ,
231312 ASN1BitString .getInstance (keyEnc .getObjectAt (1 )).getOctets (),
232313 ASN1BitString .getInstance (keyEnc .getObjectAt (2 )).getOctets (),
233314 ASN1BitString .getInstance (keyEnc .getObjectAt (3 )).getOctets (),
@@ -238,7 +319,7 @@ else if (algOID.equals(BCObjectIdentifiers.dilithium2)
238319 }
239320 else
240321 {
241- return new DilithiumPrivateKeyParameters (spParams ,
322+ return new DilithiumPrivateKeyParameters (dilParams ,
242323 ASN1BitString .getInstance (keyEnc .getObjectAt (1 )).getOctets (),
243324 ASN1BitString .getInstance (keyEnc .getObjectAt (2 )).getOctets (),
244325 ASN1BitString .getInstance (keyEnc .getObjectAt (3 )).getOctets (),
@@ -253,10 +334,10 @@ else if (keyObj instanceof DEROctetString)
253334 byte [] data = ASN1OctetString .getInstance (keyObj ).getOctets ();
254335 if (keyInfo .getPublicKeyData () != null )
255336 {
256- DilithiumPublicKeyParameters pubParams = PublicKeyFactory .DilithiumConverter .getPublicKeyParams (spParams , keyInfo .getPublicKeyData ());
257- return new DilithiumPrivateKeyParameters (spParams , data , pubParams );
337+ DilithiumPublicKeyParameters pubParams = PublicKeyFactory .DilithiumConverter .getPublicKeyParams (dilParams , keyInfo .getPublicKeyData ());
338+ return new DilithiumPrivateKeyParameters (dilParams , data , pubParams );
258339 }
259- return new DilithiumPrivateKeyParameters (spParams , data , null );
340+ return new DilithiumPrivateKeyParameters (dilParams , data , null );
260341 }
261342 else
262343 {
@@ -287,6 +368,12 @@ else if (algOID.on(BCObjectIdentifiers.pqc_kem_hqc))
287368
288369 return new HQCPrivateKeyParameters (hqcParams , keyEnc );
289370 }
371+ else if (algOID .equals (PQCObjectIdentifiers .mcElieceCca2 ))
372+ {
373+ McElieceCCA2PrivateKey mKey = McElieceCCA2PrivateKey .getInstance (keyInfo .parsePrivateKey ());
374+
375+ return new McElieceCCA2PrivateKeyParameters (mKey .getN (), mKey .getK (), mKey .getField (), mKey .getGoppaPoly (), mKey .getP (), Utils .getDigestName (mKey .getDigest ().getAlgorithm ()));
376+ }
290377 else
291378 {
292379 throw new RuntimeException ("algorithm identifier in private key not recognised" );
0 commit comments