1313import java .security .Signature ;
1414import java .security .cert .CertificateFactory ;
1515import java .security .cert .X509Certificate ;
16+ import java .security .interfaces .RSAPrivateKey ;
17+ import java .security .interfaces .RSAPublicKey ;
18+ import java .security .spec .ECGenParameterSpec ;
1619import java .security .spec .PKCS8EncodedKeySpec ;
1720import java .security .spec .X509EncodedKeySpec ;
1821import java .util .ArrayList ;
2326
2427import junit .framework .TestCase ;
2528import org .bouncycastle .asn1 .ASN1ObjectIdentifier ;
29+ import org .bouncycastle .asn1 .ASN1Primitive ;
2630import org .bouncycastle .asn1 .DEROctetString ;
31+ import org .bouncycastle .asn1 .bc .BCObjectIdentifiers ;
2732import org .bouncycastle .asn1 .pkcs .PrivateKeyInfo ;
33+ import org .bouncycastle .asn1 .util .ASN1Dump ;
2834import org .bouncycastle .asn1 .x509 .AlgorithmIdentifier ;
2935import org .bouncycastle .asn1 .x509 .SubjectPublicKeyInfo ;
36+ import org .bouncycastle .internal .asn1 .misc .MiscObjectIdentifiers ;
3037import org .bouncycastle .jcajce .CompositePrivateKey ;
3138import org .bouncycastle .jcajce .CompositePublicKey ;
3239import org .bouncycastle .jcajce .interfaces .MLDSAPrivateKey ;
3340import org .bouncycastle .jcajce .provider .asymmetric .compositesignatures .CompositeIndex ;
3441import org .bouncycastle .jcajce .provider .asymmetric .mldsa .BCMLDSAPublicKey ;
35- import org .bouncycastle .jcajce .provider .asymmetric .rsa .BCRSAPublicKey ;
3642import org .bouncycastle .jcajce .spec .ContextParameterSpec ;
3743import org .bouncycastle .jcajce .spec .MLDSAParameterSpec ;
3844import org .bouncycastle .jcajce .spec .MLDSAPrivateKeySpec ;
@@ -122,26 +128,72 @@ public void testKeyPairGeneration()
122128 CompositePublicKey compositePublicKey = (CompositePublicKey )keyPair .getPublic ();
123129 CompositePrivateKey compositePrivateKey = (CompositePrivateKey )keyPair .getPrivate ();
124130
125- String firstPublicKeyAlgorithm = Strings .toUpperCase (compositePublicKey .getPublicKeys ().get (0 ).getAlgorithm ());
126- String secondPublicKeyAlgorithm = Strings .toUpperCase (compositePublicKey .getPublicKeys ().get (1 ).getAlgorithm ());
127- String firstPrivateKeyAlgorithm = Strings .toUpperCase (compositePrivateKey .getPrivateKeys ().get (0 ).getAlgorithm ());
128- String secondPrivateKeyAlgorithm = Strings .toUpperCase (compositePrivateKey .getPrivateKeys ().get (1 ).getAlgorithm ());
129-
130- BCRSAPublicKey rsaPublicKey = null ;
131- BCRSAPublicKey rsaPrivateKey = null ;
132-
131+ ASN1ObjectIdentifier compAlg = compositePrivateKey .getAlgorithmIdentifier ().getAlgorithm ();
132+ if (compAlg .equals (BCObjectIdentifiers .id_MLDSA44_RSA2048_PKCS15_SHA256 ))
133+ {
134+ check_RSA_Composite ("ML-DSA-44" , 2048 , compositePublicKey , compositePrivateKey );
135+ }
136+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA65_RSA3072_PKCS15_SHA512 ))
137+ {
138+ check_RSA_Composite ("ML-DSA-65" , 3072 , compositePublicKey , compositePrivateKey );
139+ }
140+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_RSA3072_PSS_SHA512 ))
141+ {
142+ check_RSA_Composite ("ML-DSA-87" , 3072 , compositePublicKey , compositePrivateKey );
143+ }
144+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_RSA4096_PSS_SHA512 ))
145+ {
146+ check_RSA_Composite ("ML-DSA-87" , 4096 , compositePublicKey , compositePrivateKey );
147+ }
148+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA44_Ed25519_SHA512 ))
149+ {
150+ check_EdDSA_Composite ("ML-DSA-44" , "Ed25519" , compositePublicKey , compositePrivateKey );
151+ }
152+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA65_Ed25519_SHA512 ))
153+ {
154+ check_EdDSA_Composite ("ML-DSA-65" , "Ed25519" , compositePublicKey , compositePrivateKey );
155+ }
156+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_Ed448_SHAKE256 ))
157+ {
158+ check_EdDSA_Composite ("ML-DSA-87" , "Ed448" , compositePublicKey , compositePrivateKey );
159+ }
160+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA44_ECDSA_P256_SHA256 ))
161+ {
162+ check_ECDSA_Composite ("ML-DSA-44" , compositePublicKey , compositePrivateKey );
163+ }
164+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA65_ECDSA_P256_SHA512 ))
165+ {
166+ check_ECDSA_Composite ("ML-DSA-65" , compositePublicKey , compositePrivateKey );
167+ }
168+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA65_ECDSA_P384_SHA512 ))
169+ {
170+ check_ECDSA_Composite ("ML-DSA-65" , compositePublicKey , compositePrivateKey );
171+ }
172+ else if (compAlg .equals (MiscObjectIdentifiers .id_MLDSA65_ECDSA_P384_SHA384 ))
173+ {
174+ check_ECDSA_Composite ("ML-DSA-65" , compositePublicKey , compositePrivateKey );
175+ }
176+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_ECDSA_brainpoolP384r1_SHA512 ))
177+ {
178+ check_ECDSA_Composite ("ML-DSA-87" , compositePublicKey , compositePrivateKey );
179+ }
180+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_ECDSA_P384_SHA512 ))
181+ {
182+ check_ECDSA_Composite ("ML-DSA-87" , compositePublicKey , compositePrivateKey );
183+ }
184+ else if (compAlg .equals (BCObjectIdentifiers .id_MLDSA87_ECDSA_P521_SHA512 ))
185+ {
186+ check_ECDSA_Composite ("ML-DSA-87" , compositePublicKey , compositePrivateKey );
187+ }
188+ else
189+ {
190+ System .out .println (CompositeIndex .getAlgorithmName (compAlg ));
191+ }
133192// switch (CompositeSignaturesConstants.ASN1IdentifierCompositeNameMap.get(new ASN1ObjectIdentifier(oid)))
134193// {
135194// case MLDSA44_RSA2048_PSS_SHA256:
136195// case MLDSA44_RSA2048_PKCS15_SHA256:
137- // TestCase.assertEquals("ML-DSA-44", firstPublicKeyAlgorithm);
138- // TestCase.assertEquals("ML-DSA-44", firstPrivateKeyAlgorithm);
139- // TestCase.assertEquals("RSA", secondPublicKeyAlgorithm);
140- // TestCase.assertEquals("RSA", secondPrivateKeyAlgorithm);
141- // rsaPublicKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1);
142- // rsaPrivateKey = (BCRSAPublicKey)compositePublicKey.getPublicKeys().get(1);
143- // TestCase.assertEquals(2048, rsaPublicKey.getModulus().bitLength());
144- // TestCase.assertEquals(2048, rsaPrivateKey.getModulus().bitLength());
196+ //
145197// break;
146198// case MLDSA44_Ed25519_SHA512:
147199// TestCase.assertEquals("ML-DSA-44", firstPublicKeyAlgorithm);
@@ -174,7 +226,7 @@ public void testKeyPairGeneration()
174226// TestCase.assertEquals("ED25519", secondPrivateKeyAlgorithm);
175227// break;
176228// case MLDSA65_ECDSA_P256_SHA512:
177- // case MLDSA65_ECDSA_brainpoolP256r1_SHA512: ompositeK
229+ // case MLDSA65_ECDSA_brainpoolP256r1_SHA512:
178230// TestCase.assertEquals("ML-DSA-65", firstPublicKeyAlgorithm);
179231// TestCase.assertEquals("ML-DSA-65", firstPrivateKeyAlgorithm);
180232// TestCase.assertEquals("ECDSA", secondPublicKeyAlgorithm);
@@ -200,6 +252,74 @@ public void testKeyPairGeneration()
200252 }
201253 }
202254
255+ private void check_RSA_Composite (String firstAlg , int rsaKeySize , CompositePublicKey compPub , CompositePrivateKey compPriv )
256+ {
257+ TestCase .assertEquals (firstAlg , compPub .getPublicKeys ().get (0 ).getAlgorithm ());
258+ TestCase .assertEquals ("RSA" , compPub .getPublicKeys ().get (1 ).getAlgorithm ());
259+ RSAPublicKey rsaPublicKey = (RSAPublicKey )compPub .getPublicKeys ().get (1 );
260+ RSAPrivateKey rsaPrivateKey = (RSAPrivateKey )compPriv .getPrivateKeys ().get (1 );
261+ TestCase .assertEquals (rsaKeySize , rsaPublicKey .getModulus ().bitLength ());
262+ TestCase .assertEquals (rsaKeySize , rsaPrivateKey .getModulus ().bitLength ());
263+ }
264+
265+ private void check_EdDSA_Composite (String firstAlg , String edDSAAlg , CompositePublicKey compPub , CompositePrivateKey compPriv )
266+ {
267+ TestCase .assertEquals (firstAlg , compPub .getPublicKeys ().get (0 ).getAlgorithm ());
268+ TestCase .assertEquals (edDSAAlg , compPub .getPublicKeys ().get (1 ).getAlgorithm ());
269+ TestCase .assertEquals (firstAlg , compPriv .getPrivateKeys ().get (0 ).getAlgorithm ());
270+ TestCase .assertEquals (edDSAAlg , compPriv .getPrivateKeys ().get (1 ).getAlgorithm ());
271+ }
272+
273+ private void check_ECDSA_Composite (String firstAlg , CompositePublicKey compPub , CompositePrivateKey compPriv )
274+ {
275+ TestCase .assertEquals (firstAlg , compPub .getPublicKeys ().get (0 ).getAlgorithm ());
276+ TestCase .assertEquals ("EC" , compPub .getPublicKeys ().get (1 ).getAlgorithm ());
277+ TestCase .assertEquals (firstAlg , compPriv .getPrivateKeys ().get (0 ).getAlgorithm ());
278+ TestCase .assertEquals ("EC" , compPriv .getPrivateKeys ().get (1 ).getAlgorithm ());
279+ }
280+
281+ public void testSelfComposition ()
282+ throws Exception
283+ {
284+ KeyPairGenerator mldsaKpGen = KeyPairGenerator .getInstance ("ML-DSA" , "BC" );
285+
286+ mldsaKpGen .initialize (MLDSAParameterSpec .ml_dsa_44 );
287+
288+ KeyPair mldsaKp = mldsaKpGen .generateKeyPair ();
289+
290+ KeyPairGenerator ecKpGen = KeyPairGenerator .getInstance ("EC" , "BC" );
291+
292+ ecKpGen .initialize (new ECGenParameterSpec ("P-256" ));
293+
294+ KeyPair ecKp = ecKpGen .generateKeyPair ();
295+
296+ CompositePublicKey compPublicKey = new CompositePublicKey (BCObjectIdentifiers .id_MLDSA44_ECDSA_P256_SHA256 , mldsaKp .getPublic (), ecKp .getPublic ());
297+ CompositePrivateKey compPrivateKey = new CompositePrivateKey (BCObjectIdentifiers .id_MLDSA44_ECDSA_P256_SHA256 , mldsaKp .getPrivate (), ecKp .getPrivate ());
298+
299+ Signature signature = Signature .getInstance (BCObjectIdentifiers .id_MLDSA44_ECDSA_P256_SHA256 .getId (), "BC" );
300+ signature .initSign (compPrivateKey );
301+ signature .update (Strings .toUTF8ByteArray (messageToBeSigned ));
302+ byte [] signatureValue = signature .sign ();
303+
304+ signature .initVerify (compPublicKey );
305+ signature .update (Strings .toUTF8ByteArray (messageToBeSigned ));
306+ TestCase .assertTrue (signature .verify (signatureValue ));
307+
308+ KeyFactory compFact = KeyFactory .getInstance (BCObjectIdentifiers .id_MLDSA44_ECDSA_P256_SHA256 .getId (), "BC" );
309+ System .err .println (ASN1Dump .dumpAsString (ASN1Primitive .fromByteArray (compPrivateKey .getEncoded ())));
310+ PrivateKey compPriv = compFact .generatePrivate (new PKCS8EncodedKeySpec (compPrivateKey .getEncoded ()));
311+ PublicKey compPub = compFact .generatePublic (new X509EncodedKeySpec (compPublicKey .getEncoded ()));
312+
313+ signature .initSign (compPriv );
314+ signature .update (Strings .toUTF8ByteArray (messageToBeSigned ));
315+ signatureValue = signature .sign ();
316+
317+ signature .initVerify (compPub );
318+ signature .update (Strings .toUTF8ByteArray (messageToBeSigned ));
319+ TestCase .assertTrue (signature .verify (signatureValue ));
320+
321+ }
322+
203323 public void testSigningAndVerificationInternal ()
204324 throws Exception
205325 {
0 commit comments