@@ -124,6 +124,54 @@ public void emptyMessage_works() throws Exception {
124124 assertTrue (signature .verify (sig2 ));
125125 }
126126
127+ /** Helper class to test KeyFactory.translateKey. */
128+ static class TestPublicKey implements PublicKey {
129+ public TestPublicKey (byte [] x509encoded ) {
130+ this .x509encoded = x509encoded ;
131+ }
132+
133+ private final byte [] x509encoded ;
134+
135+ @ Override
136+ public String getAlgorithm () {
137+ return "ML-DSA" ;
138+ }
139+
140+ @ Override
141+ public String getFormat () {
142+ return "X.509" ;
143+ }
144+
145+ @ Override
146+ public byte [] getEncoded () {
147+ return x509encoded ;
148+ }
149+ }
150+
151+ /** Helper class to test KeyFactory.translateKey. */
152+ static class TestPrivateKey implements PrivateKey {
153+ public TestPrivateKey (byte [] pkcs8encoded ) {
154+ this .pkcs8encoded = pkcs8encoded ;
155+ }
156+
157+ private final byte [] pkcs8encoded ;
158+
159+ @ Override
160+ public String getAlgorithm () {
161+ return "ML-DSA" ;
162+ }
163+
164+ @ Override
165+ public String getFormat () {
166+ return "PKCS#8" ;
167+ }
168+
169+ @ Override
170+ public byte [] getEncoded () {
171+ return pkcs8encoded ;
172+ }
173+ }
174+
127175 @ Test
128176 public void mldsa65KeyPair_signVerify_works () throws Exception {
129177 KeyPairGenerator keyGen = KeyPairGenerator .getInstance ("ML-DSA-65" , conscryptProvider );
@@ -190,6 +238,36 @@ public void mldsa87KeyPair_signVerify_works() throws Exception {
190238 assertThrows (InvalidKeyException .class , () -> s65 .initVerify (publicKey ));
191239 }
192240
241+ @ Test
242+ public void foreignMldsa65KeyPair_signVerify_works () throws Exception {
243+ KeyPairGenerator keyGen = KeyPairGenerator .getInstance ("ML-DSA-65" , conscryptProvider );
244+ KeyPair keyPair = keyGen .generateKeyPair ();
245+ PrivateKey privateKey = new TestPrivateKey (keyPair .getPrivate ().getEncoded ());
246+ PublicKey publicKey = new TestPublicKey (keyPair .getPublic ().getEncoded ());
247+
248+ for (String signAlgorithm : new String [] {"ML-DSA-65" , "ML-DSA" }) {
249+ byte [] msg = new byte [123 ];
250+ Signature ss = Signature .getInstance (signAlgorithm , conscryptProvider );
251+ ss .initSign (privateKey );
252+ ss .update (msg );
253+ byte [] sig = ss .sign ();
254+ assertEquals (3309 , sig .length );
255+
256+ for (String verifyAlgorithm : new String [] {"ML-DSA-65" , "ML-DSA" }) {
257+ Signature sv = Signature .getInstance (verifyAlgorithm , conscryptProvider );
258+ sv .initVerify (publicKey );
259+ sv .update (msg );
260+ boolean verified = sv .verify (sig );
261+ assertTrue (verified );
262+ }
263+ }
264+
265+ // ML-DSA-87 does not support ML-DSA-65 keys.
266+ Signature s87 = Signature .getInstance ("ML-DSA-87" , conscryptProvider );
267+ assertThrows (InvalidKeyException .class , () -> s87 .initSign (privateKey ));
268+ assertThrows (InvalidKeyException .class , () -> s87 .initVerify (publicKey ));
269+ }
270+
193271 @ Test
194272 public void mldsa65KeyPair_toAndFromRaw_works () throws Exception {
195273 KeyPairGenerator keyGen = KeyPairGenerator .getInstance ("ML-DSA-65" , conscryptProvider );
@@ -296,54 +374,6 @@ public void generateFromInvalidRawKey_throws() throws Exception {
296374 }
297375 }
298376
299- /** Helper class to test KeyFactory.translateKey. */
300- static class TestPublicKey implements PublicKey {
301- public TestPublicKey (byte [] x509encoded ) {
302- this .x509encoded = x509encoded ;
303- }
304-
305- private final byte [] x509encoded ;
306-
307- @ Override
308- public String getAlgorithm () {
309- return "ML-DSA" ;
310- }
311-
312- @ Override
313- public String getFormat () {
314- return "X.509" ;
315- }
316-
317- @ Override
318- public byte [] getEncoded () {
319- return x509encoded ;
320- }
321- }
322-
323- /** Helper class to test KeyFactory.translateKey. */
324- static class TestPrivateKey implements PrivateKey {
325- public TestPrivateKey (byte [] pkcs8encoded ) {
326- this .pkcs8encoded = pkcs8encoded ;
327- }
328-
329- private final byte [] pkcs8encoded ;
330-
331- @ Override
332- public String getAlgorithm () {
333- return "ML-DSA" ;
334- }
335-
336- @ Override
337- public String getFormat () {
338- return "PKCS#8" ;
339- }
340-
341- @ Override
342- public byte [] getEncoded () {
343- return pkcs8encoded ;
344- }
345- }
346-
347377 @ Test
348378 public void mldsa65KeyPair_x509AndPkcs8 () throws Exception {
349379 KeyPairGenerator keyGen = KeyPairGenerator .getInstance ("ML-DSA-65" , conscryptProvider );
0 commit comments