From 615fab4e2dc769adbe3c6a5d98e1814730c034c1 Mon Sep 17 00:00:00 2001 From: Ian O'Neill Date: Sun, 22 Dec 2024 15:11:23 +0000 Subject: [PATCH] Add some tests --- .../eddsa/NetI2pCryptoEdDSASupport.java | 6 + .../BouncyCastleEdDSASupport.java | 12 +- .../security/eddsa/generic/EdDSASupport.java | 5 + .../security/eddsa/Ed25519VectorsTest.java | 331 +++++++++++------- 4 files changed, 217 insertions(+), 137 deletions(-) diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/NetI2pCryptoEdDSASupport.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/NetI2pCryptoEdDSASupport.java index e4e4c19d6..e88f5bdc0 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/NetI2pCryptoEdDSASupport.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/NetI2pCryptoEdDSASupport.java @@ -34,6 +34,7 @@ import org.apache.sshd.common.config.keys.PublicKeyEntryDecoder; import org.apache.sshd.common.signature.Signature; import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.security.SecurityUtils; import org.apache.sshd.common.util.security.eddsa.generic.EdDSASupport; public class NetI2pCryptoEdDSASupport implements EdDSASupport { @@ -126,4 +127,9 @@ public byte[] getPublicKeyData(EdDSAPublicKey publicKey) { public byte[] getPrivateKeyData(EdDSAPrivateKey privateKey) throws IOException { return privateKey.getSeed(); } + + @Override + public String getKeyFactoryAlgorithm() { + return SecurityUtils.EDDSA; + } } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/bouncycastle/BouncyCastleEdDSASupport.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/bouncycastle/BouncyCastleEdDSASupport.java index 8c42f9088..6663c2e45 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/bouncycastle/BouncyCastleEdDSASupport.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/bouncycastle/BouncyCastleEdDSASupport.java @@ -46,7 +46,6 @@ import org.bouncycastle.jcajce.interfaces.EdDSAKey; import org.bouncycastle.jcajce.interfaces.EdDSAPrivateKey; import org.bouncycastle.jcajce.interfaces.EdDSAPublicKey; -import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec; import org.bouncycastle.jcajce.spec.RawEncodedKeySpec; public class BouncyCastleEdDSASupport implements EdDSASupport { @@ -115,7 +114,7 @@ public EdDSAPublicKey recoverEDDSAPublicKey(PrivateKey key) throws GeneralSecuri @Override public EdDSAPublicKey generateEDDSAPublicKey(byte[] seed) throws GeneralSecurityException { RawEncodedKeySpec keySpec = new RawEncodedKeySpec(seed); - KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.ED25519); + KeyFactory factory = SecurityUtils.getKeyFactory(getKeyFactoryAlgorithm()); return (EdDSAPublicKey) factory.generatePublic(keySpec); } @@ -123,7 +122,7 @@ public EdDSAPublicKey generateEDDSAPublicKey(byte[] seed) throws GeneralSecurity public EdDSAPrivateKey generateEDDSAPrivateKey(byte[] seed) throws GeneralSecurityException, IOException { Ed25519PrivateKeyParameters parameters = new Ed25519PrivateKeyParameters(seed); PrivateKeyInfo info = PrivateKeyInfoFactory.createPrivateKeyInfo(parameters); - KeyFactory factory = SecurityUtils.getKeyFactory(SecurityUtils.ED25519); + KeyFactory factory = SecurityUtils.getKeyFactory(getKeyFactoryAlgorithm()); return (EdDSAPrivateKey) factory.generatePrivate(new PKCS8EncodedKeySpec(info.getEncoded())); } @@ -148,7 +147,7 @@ public KeySpec createPublicKeySpec(EdDSAPublicKey publicKey) { @Override public KeySpec createPrivateKeySpec(EdDSAPrivateKey privateKey) { - return new OpenSSHPrivateKeySpec(privateKey.getEncoded()); + return new PKCS8EncodedKeySpec(privateKey.getEncoded()); } @Override @@ -162,4 +161,9 @@ public byte[] getPrivateKeyData(EdDSAPrivateKey privateKey) throws IOException { = (Ed25519PrivateKeyParameters) PrivateKeyFactory.createKey(privateKey.getEncoded()); return parameters.getEncoded(); } + + @Override + public String getKeyFactoryAlgorithm() { + return SecurityUtils.ED25519; + } } diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/EdDSASupport.java b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/EdDSASupport.java index 8d45f649e..a8ed9ac54 100644 --- a/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/EdDSASupport.java +++ b/sshd-common/src/main/java/org/apache/sshd/common/util/security/eddsa/generic/EdDSASupport.java @@ -190,4 +190,9 @@ static PrivateKey decodeEdDSAPrivateKey(byte[] keyData) throws IOException, Gene */ byte[] getPrivateKeyData(PRV privateKey) throws IOException; + /** + * @return the algorithm name used by the provider's {@link java.security.KeyFactory}. + */ + String getKeyFactoryAlgorithm(); + } diff --git a/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java b/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java index 8b42895ce..4847e2b81 100644 --- a/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java +++ b/sshd-common/src/test/java/org/apache/sshd/common/util/security/eddsa/Ed25519VectorsTest.java @@ -19,19 +19,23 @@ package org.apache.sshd.common.util.security.eddsa; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.GeneralSecurityException; +import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; +import java.security.spec.KeySpec; import java.util.ArrayList; -import java.util.Arrays; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; -import net.i2p.crypto.eddsa.EdDSAPrivateKey; -import net.i2p.crypto.eddsa.EdDSAPublicKey; import org.apache.sshd.common.signature.Signature; import org.apache.sshd.common.util.buffer.BufferUtils; import org.apache.sshd.common.util.security.SecurityUtils; +import org.apache.sshd.common.util.security.eddsa.bouncycastle.BouncyCastleEdDSASupport; +import org.apache.sshd.common.util.security.eddsa.generic.EdDSASupport; import org.apache.sshd.util.test.JUnitTestSupport; import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.BeforeAll; @@ -41,9 +45,6 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - /** * @author Apache MINA SSHD Project * @see EdDSA and Ed25519 @@ -51,131 +52,145 @@ */ @TestMethodOrder(MethodName.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests @Tag("NoIoTestCase") -public class Ed25519VectorsTest extends JUnitTestSupport { +public class Ed25519VectorsTest extends JUnitTestSupport { private byte[] prvBytes; - private PrivateKey privateKey; + private PRV privateKey; private byte[] pubBytes; - private PublicKey publicKey; + private PUB publicKey; private byte[] msgBytes; private byte[] expSignature; - public void initEd25519VectorsTest(String name, String prvKey, String pubKey, String msg, String signature) - throws GeneralSecurityException { + public void initEd25519VectorsTest( + String name, EdDSASupport support, String prvKey, String pubKey, String msg, String signature) + throws GeneralSecurityException, IOException { prvBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, prvKey); - privateKey = EdDSASecurityProviderUtils.generateEDDSAPrivateKey(prvBytes.clone()); + privateKey = support.generateEDDSAPrivateKey(prvBytes.clone()); pubBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, pubKey); - publicKey = EdDSASecurityProviderUtils.generateEDDSAPublicKey(pubBytes.clone()); + publicKey = support.generateEDDSAPublicKey(pubBytes.clone()); msgBytes = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, msg); expSignature = BufferUtils.decodeHex(BufferUtils.EMPTY_HEX_SEPARATOR, signature); } - @SuppressWarnings("checkstyle:anoninnerlength") public static List parameters() { - return new ArrayList<>( - Arrays.asList( - new Object[] { - "TEST1 - empty message", - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", - "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", - "", - "e5564300c360ac729086e2cc806e828a" - + "84877f1eb8e5d974d873e06522490155" - + "5fb8821590a33bacc61e39701cf9b46b" - + "d25bf5f0595bbe24655141438e7a100b" - }, - new Object[] { - "TEST2 - one byte", - "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", - "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", - "72", - "92a009a9f0d4cab8720e820b5f642540" - + "a2b27b5416503f8fb3762223ebdb69da" - + "085ac1e43e15996e458f3613d0f11d8c" - + "387b2eaeb4302aeeb00d291612bb0c00" - }, - new Object[] { - "TEST3 - 2 bytes", - "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", - "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", - "af82", - "6291d657deec24024827e69c3abe01a3" - + "0ce548a284743a445e3680d7db5ac3ac" - + "18ff9b538d16f290ae67f760984dc659" - + "4a7c15e9716ed28dc027beceea1ec40a" - }, - new Object[] { - "TEST1024 - large message", - "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", - "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", - "08b8b2b733424243760fe426a4b54908" - + "632110a66c2f6591eabd3345e3e4eb98" - + "fa6e264bf09efe12ee50f8f54e9f77b1" - + "e355f6c50544e23fb1433ddf73be84d8" - + "79de7c0046dc4996d9e773f4bc9efe57" - + "38829adb26c81b37c93a1b270b20329d" - + "658675fc6ea534e0810a4432826bf58c" - + "941efb65d57a338bbd2e26640f89ffbc" - + "1a858efcb8550ee3a5e1998bd177e93a" - + "7363c344fe6b199ee5d02e82d522c4fe" - + "ba15452f80288a821a579116ec6dad2b" - + "3b310da903401aa62100ab5d1a36553e" - + "06203b33890cc9b832f79ef80560ccb9" - + "a39ce767967ed628c6ad573cb116dbef" - + "efd75499da96bd68a8a97b928a8bbc10" - + "3b6621fcde2beca1231d206be6cd9ec7" - + "aff6f6c94fcd7204ed3455c68c83f4a4" - + "1da4af2b74ef5c53f1d8ac70bdcb7ed1" - + "85ce81bd84359d44254d95629e9855a9" - + "4a7c1958d1f8ada5d0532ed8a5aa3fb2" - + "d17ba70eb6248e594e1a2297acbbb39d" - + "502f1a8c6eb6f1ce22b3de1a1f40cc24" - + "554119a831a9aad6079cad88425de6bd" - + "e1a9187ebb6092cf67bf2b13fd65f270" - + "88d78b7e883c8759d2c4f5c65adb7553" - + "878ad575f9fad878e80a0c9ba63bcbcc" - + "2732e69485bbc9c90bfbd62481d9089b" - + "eccf80cfe2df16a2cf65bd92dd597b07" - + "07e0917af48bbb75fed413d238f5555a" - + "7a569d80c3414a8d0859dc65a46128ba" - + "b27af87a71314f318c782b23ebfe808b" - + "82b0ce26401d2e22f04d83d1255dc51a" - + "ddd3b75a2b1ae0784504df543af8969b" - + "e3ea7082ff7fc9888c144da2af58429e" - + "c96031dbcad3dad9af0dcbaaaf268cb8" - + "fcffead94f3c7ca495e056a9b47acdb7" - + "51fb73e666c6c655ade8297297d07ad1" - + "ba5e43f1bca32301651339e22904cc8c" - + "42f58c30c04aafdb038dda0847dd988d" - + "cda6f3bfd15c4b4c4525004aa06eeff8" - + "ca61783aacec57fb3d1f92b0fe2fd1a8" - + "5f6724517b65e614ad6808d6f6ee34df" - + "f7310fdc82aebfd904b01e1dc54b2927" - + "094b2db68d6f903b68401adebf5a7e08" - + "d78ff4ef5d63653a65040cf9bfd4aca7" - + "984a74d37145986780fc0b16ac451649" - + "de6188a7dbdf191f64b5fc5e2ab47b57" - + "f7f7276cd419c17a3ca8e1b939ae49e4" - + "88acba6b965610b5480109c8b17b80e1" - + "b7b750dfc7598d5d5011fd2dcc5600a3" - + "2ef5b52a1ecc820e308aa342721aac09" - + "43bf6686b64b2579376504ccc493d97e" - + "6aed3fb0f9cd71a43dd497f01f17c0e2" - + "cb3797aa2a2f256656168e6c496afc5f" - + "b93246f6b1116398a346f1a641f3b041" - + "e989f7914f90cc2c7fff357876e506b5" - + "0d334ba77c225bc307ba537152f3f161" - + "0e4eafe595f6d9d90d11faa933a15ef1" - + "369546868a7f3a45a96768d40fd9d034" - + "12c091c6315cf4fde7cb68606937380d" - + "b2eaaa707b4c4185c32eddcdd306705e" - + "4dc1ffc872eeee475a64dfac86aba41c" - + "0618983f8741c5ef68d3a101e8a3b8ca" - + "c60c905c15fc910840b94c00a0b9d0", - "0aab4c900501b3e24d7cdf4663326a3a" - + "87df5e4843b2cbdb67cbf6e460fec350" - + "aa5371b1508f9f4528ecea23c436d94b" - + "5e8fcd4f681e30a6ac00a9704a188a03" - })); + List parameters = new ArrayList<>(); + Map> supportedSecurityProviders = new LinkedHashMap<>(); + supportedSecurityProviders.put(SecurityUtils.EDDSA, new NetI2pCryptoEdDSASupport()); + supportedSecurityProviders.put(SecurityUtils.BOUNCY_CASTLE, new BouncyCastleEdDSASupport()); + for (Map.Entry> entry : supportedSecurityProviders.entrySet()) { + String supportClassName = entry.getValue().getClass().getSimpleName(); + parameters.add(new Object[] { + supportClassName + " TEST1 - empty message", + entry.getValue(), + entry.getKey(), + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60", + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a", + "", + "e5564300c360ac729086e2cc806e828a" + + "84877f1eb8e5d974d873e06522490155" + + "5fb8821590a33bacc61e39701cf9b46b" + + "d25bf5f0595bbe24655141438e7a100b" + }); + parameters.add(new Object[] { + supportClassName + " TEST2 - one byte", + entry.getValue(), + entry.getKey(), + "4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb", + "3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c", + "72", + "92a009a9f0d4cab8720e820b5f642540" + + "a2b27b5416503f8fb3762223ebdb69da" + + "085ac1e43e15996e458f3613d0f11d8c" + + "387b2eaeb4302aeeb00d291612bb0c00" + }); + parameters.add(new Object[] { + supportClassName + " TEST3 - 2 bytes", + entry.getValue(), + entry.getKey(), + "c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7", + "fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025", + "af82", + "6291d657deec24024827e69c3abe01a3" + + "0ce548a284743a445e3680d7db5ac3ac" + + "18ff9b538d16f290ae67f760984dc659" + + "4a7c15e9716ed28dc027beceea1ec40a" + }); + parameters.add(new Object[] { + supportClassName + " TEST1024 - large message", + entry.getValue(), + entry.getKey(), + "f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5", + "278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e", + "08b8b2b733424243760fe426a4b54908" + + "632110a66c2f6591eabd3345e3e4eb98" + + "fa6e264bf09efe12ee50f8f54e9f77b1" + + "e355f6c50544e23fb1433ddf73be84d8" + + "79de7c0046dc4996d9e773f4bc9efe57" + + "38829adb26c81b37c93a1b270b20329d" + + "658675fc6ea534e0810a4432826bf58c" + + "941efb65d57a338bbd2e26640f89ffbc" + + "1a858efcb8550ee3a5e1998bd177e93a" + + "7363c344fe6b199ee5d02e82d522c4fe" + + "ba15452f80288a821a579116ec6dad2b" + + "3b310da903401aa62100ab5d1a36553e" + + "06203b33890cc9b832f79ef80560ccb9" + + "a39ce767967ed628c6ad573cb116dbef" + + "efd75499da96bd68a8a97b928a8bbc10" + + "3b6621fcde2beca1231d206be6cd9ec7" + + "aff6f6c94fcd7204ed3455c68c83f4a4" + + "1da4af2b74ef5c53f1d8ac70bdcb7ed1" + + "85ce81bd84359d44254d95629e9855a9" + + "4a7c1958d1f8ada5d0532ed8a5aa3fb2" + + "d17ba70eb6248e594e1a2297acbbb39d" + + "502f1a8c6eb6f1ce22b3de1a1f40cc24" + + "554119a831a9aad6079cad88425de6bd" + + "e1a9187ebb6092cf67bf2b13fd65f270" + + "88d78b7e883c8759d2c4f5c65adb7553" + + "878ad575f9fad878e80a0c9ba63bcbcc" + + "2732e69485bbc9c90bfbd62481d9089b" + + "eccf80cfe2df16a2cf65bd92dd597b07" + + "07e0917af48bbb75fed413d238f5555a" + + "7a569d80c3414a8d0859dc65a46128ba" + + "b27af87a71314f318c782b23ebfe808b" + + "82b0ce26401d2e22f04d83d1255dc51a" + + "ddd3b75a2b1ae0784504df543af8969b" + + "e3ea7082ff7fc9888c144da2af58429e" + + "c96031dbcad3dad9af0dcbaaaf268cb8" + + "fcffead94f3c7ca495e056a9b47acdb7" + + "51fb73e666c6c655ade8297297d07ad1" + + "ba5e43f1bca32301651339e22904cc8c" + + "42f58c30c04aafdb038dda0847dd988d" + + "cda6f3bfd15c4b4c4525004aa06eeff8" + + "ca61783aacec57fb3d1f92b0fe2fd1a8" + + "5f6724517b65e614ad6808d6f6ee34df" + + "f7310fdc82aebfd904b01e1dc54b2927" + + "094b2db68d6f903b68401adebf5a7e08" + + "d78ff4ef5d63653a65040cf9bfd4aca7" + + "984a74d37145986780fc0b16ac451649" + + "de6188a7dbdf191f64b5fc5e2ab47b57" + + "f7f7276cd419c17a3ca8e1b939ae49e4" + + "88acba6b965610b5480109c8b17b80e1" + + "b7b750dfc7598d5d5011fd2dcc5600a3" + + "2ef5b52a1ecc820e308aa342721aac09" + + "43bf6686b64b2579376504ccc493d97e" + + "6aed3fb0f9cd71a43dd497f01f17c0e2" + + "cb3797aa2a2f256656168e6c496afc5f" + + "b93246f6b1116398a346f1a641f3b041" + + "e989f7914f90cc2c7fff357876e506b5" + + "0d334ba77c225bc307ba537152f3f161" + + "0e4eafe595f6d9d90d11faa933a15ef1" + + "369546868a7f3a45a96768d40fd9d034" + + "12c091c6315cf4fde7cb68606937380d" + + "b2eaaa707b4c4185c32eddcdd306705e" + + "4dc1ffc872eeee475a64dfac86aba41c" + + "0618983f8741c5ef68d3a101e8a3b8ca" + + "c60c905c15fc910840b94c00a0b9d0", + "0aab4c900501b3e24d7cdf4663326a3a" + + "87df5e4843b2cbdb67cbf6e460fec350" + + "aa5371b1508f9f4528ecea23c436d94b" + + "5e8fcd4f681e30a6ac00a9704a188a03" + }); + } + return parameters; } @BeforeAll @@ -185,31 +200,38 @@ static void checkEDDSASupported() { @MethodSource("parameters") @ParameterizedTest(name = "{0}") - public void publicKeyBytes(String name, String prvKey, String pubKey, String msg, String signature) throws Exception { - initEd25519VectorsTest(name, prvKey, pubKey, msg, signature); - byte[] publicSeed = Ed25519PublicKeyDecoder.getSeedValue((EdDSAPublicKey) publicKey); + public void publicKeyBytes( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + byte[] publicSeed = support.getPublicKeyData(publicKey); assertArrayEquals(pubBytes, publicSeed, "Mismatched public seed value"); } @MethodSource("parameters") @ParameterizedTest(name = "{0}") - public void privateKeyBytes(String name, String prvKey, String pubKey, String msg, String signature) throws Exception { - initEd25519VectorsTest(name, prvKey, pubKey, msg, signature); - assertArrayEquals(prvBytes, ((EdDSAPrivateKey) privateKey).getSeed(), "Mismatched private seed value"); + public void privateKeyBytes( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + byte[] privateSeed = support.getPrivateKeyData(privateKey); + assertArrayEquals(prvBytes, privateSeed, "Mismatched private seed value"); } @MethodSource("parameters") @ParameterizedTest(name = "{0}") - public void signature(String name, String prvKey, String pubKey, String msg, String signature) throws Exception { - initEd25519VectorsTest(name, prvKey, pubKey, msg, signature); - Signature signer = EdDSASecurityProviderUtils.getEDDSASignature(); + public void signature( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + Signature signer = support.getEDDSASigner(); signer.initSigner(null, privateKey); signer.update(null, msgBytes.clone()); byte[] actSignature = signer.sign(null); assertArrayEquals(expSignature, actSignature, "Mismatched signature"); - Signature verifier = EdDSASecurityProviderUtils.getEDDSASignature(); + Signature verifier = support.getEDDSASigner(); verifier.initVerifier(null, publicKey); verifier.update(null, msgBytes.clone()); assertTrue(verifier.verify(null, expSignature), "Verification failed"); @@ -217,9 +239,11 @@ public void signature(String name, String prvKey, String pubKey, String msg, Str @MethodSource("parameters") @ParameterizedTest(name = "{0}") - public void partialBufferSignature(String name, String prvKey, String pubKey, String msg, String signature) + public void partialBufferSignature( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { - initEd25519VectorsTest(name, prvKey, pubKey, msg, signature); + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); byte[] extraData = getCurrentTestName().getBytes(StandardCharsets.UTF_8); byte[] dataBuf = new byte[msgBytes.length + extraData.length]; int offset = extraData.length / 2; @@ -227,16 +251,57 @@ public void partialBufferSignature(String name, String prvKey, String pubKey, St System.arraycopy(msgBytes, 0, dataBuf, offset, msgBytes.length); System.arraycopy(extraData, offset, dataBuf, offset + msgBytes.length, extraData.length - offset); - Signature signer = EdDSASecurityProviderUtils.getEDDSASignature(); + Signature signer = support.getEDDSASigner(); signer.initSigner(null, privateKey); signer.update(null, dataBuf.clone(), offset, msgBytes.length); byte[] actSignature = signer.sign(null); assertArrayEquals(expSignature, actSignature, "Mismatched signature"); - Signature verifier = EdDSASecurityProviderUtils.getEDDSASignature(); + Signature verifier = support.getEDDSASigner(); verifier.initVerifier(null, publicKey); verifier.update(null, dataBuf.clone(), offset, msgBytes.length); assertTrue(verifier.verify(null, expSignature), "Verification failed"); } + + @MethodSource("parameters") + @ParameterizedTest(name = "{0}") + public void recoverEDDSAPublicKey( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + PUB recoveredKey = support.recoverEDDSAPublicKey(privateKey); + assertTrue(support.compareEDDSAPPublicKeys(publicKey, recoveredKey), "Recovered key is not equal"); + byte[] recoveredBytes = support.getPublicKeyData(recoveredKey); + assertArrayEquals(pubBytes, recoveredBytes, "Mismatched public seed value"); + } + + @MethodSource("parameters") + @ParameterizedTest(name = "{0}") + public void createPublicKeySpec( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + KeySpec keySpec = support.createPublicKeySpec(publicKey); + KeyFactory keyFactory = KeyFactory.getInstance(support.getKeyFactoryAlgorithm(), provider); + PUB generatedKey = (PUB) keyFactory.generatePublic(keySpec); + assertTrue(support.compareEDDSAPPublicKeys(publicKey, generatedKey), "Generated key is not equal"); + byte[] generatedBytes = support.getPublicKeyData(generatedKey); + assertArrayEquals(pubBytes, generatedBytes, "Mismatched public seed value"); + } + + @MethodSource("parameters") + @ParameterizedTest(name = "{0}") + public void createPrivateKeySpec( + String name, EdDSASupport support, String provider, String prvKey, String pubKey, String msg, + String signature) throws Exception { + initEd25519VectorsTest(name, support, prvKey, pubKey, msg, signature); + KeySpec keySpec = support.createPrivateKeySpec(privateKey); + KeyFactory keyFactory = KeyFactory.getInstance(support.getKeyFactoryAlgorithm(), provider); + PRV generatedKey = (PRV) keyFactory.generatePrivate(keySpec); + assertTrue(support.compareEDDSAPrivateKeys(privateKey, generatedKey), "Generated key is not equal"); + byte[] generatedBytes = support.getPrivateKeyData(generatedKey); + assertArrayEquals(prvBytes, generatedBytes, "Mismatched private seed value"); + } + }