diff options
Diffstat (limited to 'prov/src/test/java/org/spongycastle/pqc')
11 files changed, 1021 insertions, 0 deletions
diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AllTests.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AllTests.java new file mode 100644 index 00000000..5c91aa58 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AllTests.java @@ -0,0 +1,35 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.Security; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; +import org.spongycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; + +public class AllTests + extends TestCase +{ + public static void main (String[] args) + { + junit.textui.TestRunner.run(suite()); + } + + public static Test suite() + { + TestSuite suite = new TestSuite("PQC JCE Tests"); + + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + + suite.addTestSuite(RainbowSignatureTest.class); + suite.addTestSuite(McElieceFujisakiCipherTest.class); + suite.addTestSuite(McElieceKobaraImaiCipherTest.class); + suite.addTestSuite(McEliecePointchevalCipherTest.class); + suite.addTestSuite(McEliecePKCSCipherTest.class); + + return suite; + } +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricBlockCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricBlockCipherTest.java new file mode 100644 index 00000000..9507c8a7 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricBlockCipherTest.java @@ -0,0 +1,82 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.math.linearalgebra.ByteUtils; + + +public abstract class AsymmetricBlockCipherTest + extends FlexiTest +{ + + protected Cipher cipher; + + protected KeyPair keyPair; + + protected PublicKey pubKey; + + protected PrivateKey privKey; + + protected KeyPairGenerator kpg; + + private byte[] mBytes; + + private byte[] cBytes; + + private byte[] dBytes; + + protected final void performEnDecryptionTest(int numPassesKPG, + int numPassesEncDec, AlgorithmParameterSpec params) + { + + try + { + for (int j = 0; j < numPassesKPG; j++) + { + keyPair = kpg.genKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + + for (int k = 1; k <= numPassesEncDec; k++) + { + // initialize for encryption + cipher.init(Cipher.ENCRYPT_MODE, pubKey, params, sr); + + // generate random message + final int plainTextSize = cipher.getBlockSize(); + int mLength = rand.nextInt(plainTextSize) + 1; + mBytes = new byte[mLength]; + rand.nextBytes(mBytes); + + // encrypt + cBytes = cipher.doFinal(mBytes); + + // initialize for decryption + cipher.init(Cipher.DECRYPT_MODE, privKey, params); + + // decrypt + dBytes = cipher.doFinal(cBytes); + + // compare + assertEquals("Encryption and Decryption test failed:\n" + + " actual decrypted text: " + + ByteUtils.toHexString(dBytes) + + "\n expected plain text: " + + ByteUtils.toHexString(mBytes), mBytes, dBytes); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + fail(e); + } + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricHybridCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricHybridCipherTest.java new file mode 100644 index 00000000..85125e65 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/AsymmetricHybridCipherTest.java @@ -0,0 +1,91 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.jcajce.provider.util.AsymmetricHybridCipher; +import org.spongycastle.pqc.math.linearalgebra.ByteUtils; + +/** + * Base class for unit tests of {@link AsymmetricHybridCipher}s. + */ +public abstract class AsymmetricHybridCipherTest + extends FlexiTest +{ + + /** + * the {@link KeyPairGenerator} to use for the test + */ + protected KeyPairGenerator kpg; + + /** + * the {@link AsymmetricHybridCipher} to use for the test + */ + protected Cipher cipher; + + private KeyPair keyPair; + + private PublicKey pubKey; + + private PrivateKey privKey; + + private byte[] mBytes, cBytes, dBytes; + + protected final void performEnDecryptionTest(int numPassesKPG, + int numPassesEncDec, int plainTextSize, + AlgorithmParameterSpec params) + { + + try + { + for (int j = 0; j < numPassesKPG; j++) + { + // generate key pair + //kpg.initialize(params); + keyPair = kpg.genKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + + for (int k = 1; k <= numPassesEncDec; k++) + { + // initialize for encryption + cipher.init(Cipher.ENCRYPT_MODE, pubKey, params, sr); + + // generate random message + int mLength = rand.nextInt(plainTextSize) + 1; + mBytes = new byte[mLength]; + rand.nextBytes(mBytes); + + // encrypt + cBytes = cipher.doFinal(mBytes); + + + // initialize for decryption + cipher.init(Cipher.DECRYPT_MODE, privKey, params); + // decrypt + dBytes = cipher.doFinal(cBytes); + // compare + assertEquals( + "Encryption/decryption test failed for message \"" + + ByteUtils.toHexString(mBytes) + + "\":\n actual decrypted text: " + + ByteUtils.toHexString(dBytes) + + "\n expected plain text: " + + ByteUtils.toHexString(mBytes), mBytes, + dBytes); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + fail(e); + } + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/FlexiTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/FlexiTest.java new file mode 100644 index 00000000..c076091e --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/FlexiTest.java @@ -0,0 +1,68 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.SecureRandom; +import java.security.Security; +import java.util.Arrays; +import java.util.Random; + +import junit.framework.TestCase; +import org.spongycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; + +public abstract class FlexiTest + extends TestCase +{ + + /** + * Source of randomness + */ + protected Random rand; + + /** + * Secure source of randomness + */ + protected SecureRandom sr; + + protected void setUp() + { + Security.addProvider(new BouncyCastlePQCProvider()); + // initialize sources of randomness + rand = new Random(); + sr = new SecureRandom(); + // TODO need it? + sr.setSeed(sr.generateSeed(20)); + } + + protected static final void assertEquals(byte[] expected, byte[] actual) + { + assertTrue(Arrays.equals(expected, actual)); + } + + protected static final void assertEquals(String message, byte[] expected, + byte[] actual) + { + assertTrue(message, Arrays.equals(expected, actual)); + } + + protected static final void assertEquals(int[] expected, int[] actual) + { + assertTrue(Arrays.equals(expected, actual)); + } + + protected static final void assertEquals(String message, int[] expected, + int[] actual) + { + assertTrue(message, Arrays.equals(expected, actual)); + } + + /** + * Method used to report test failure when in exception is thrown. + * + * @param e the exception + */ + protected static final void fail(Exception e) + { + fail("Exception thrown: " + e.getClass().getName() + ":\n" + + e.getMessage()); + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/KeyPairGeneratorTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/KeyPairGeneratorTest.java new file mode 100644 index 00000000..2d7807d5 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/KeyPairGeneratorTest.java @@ -0,0 +1,47 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +public abstract class KeyPairGeneratorTest + extends FlexiTest +{ + + protected KeyPairGenerator kpg; + + protected KeyFactory kf; + + protected final void performKeyPairEncodingTest() + { + try + { + KeyPair keyPair = kpg.genKeyPair(); + PublicKey pubKey = keyPair.getPublic(); + PrivateKey privKey = keyPair.getPrivate(); + + byte[] encPubKey = pubKey.getEncoded(); + byte[] encPrivKey = privKey.getEncoded(); + + X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encPubKey); + PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec( + encPrivKey); + + PublicKey decPubKey = kf.generatePublic(pubKeySpec); + PrivateKey decPrivKey = kf.generatePrivate(privKeySpec); + + assertEquals(pubKey, decPubKey); + assertEquals(privKey, decPrivKey); + } + catch (Exception e) + { + e.printStackTrace(); + fail(e); + } + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceCCA2PrimitivesTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceCCA2PrimitivesTest.java new file mode 100644 index 00000000..5444a0db --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceCCA2PrimitivesTest.java @@ -0,0 +1,71 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.NoSuchAlgorithmException; + +import org.spongycastle.pqc.jcajce.provider.mceliece.BCMcElieceCCA2PrivateKey; +import org.spongycastle.pqc.jcajce.provider.mceliece.BCMcElieceCCA2PublicKey; +import org.spongycastle.pqc.jcajce.provider.mceliece.McElieceCCA2Primitives; +import org.spongycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; +import org.spongycastle.pqc.math.linearalgebra.GF2Vector; + + +public class McElieceCCA2PrimitivesTest + extends FlexiTest +{ + + KeyPairGenerator kpg; + + protected void setUp() + { + super.setUp(); + try + { + kpg = KeyPairGenerator.getInstance("McElieceKobaraImai"); + } + catch (NoSuchAlgorithmException e) + { + e.printStackTrace(); + } + } + + public void testPrimitives() + throws Exception + { + int m = 11; + int t = 50; + initKPG(m, t); + int n = 1 << m; + + KeyPair pair = kpg.genKeyPair(); + BCMcElieceCCA2PublicKey pubKey = (BCMcElieceCCA2PublicKey)pair.getPublic(); + BCMcElieceCCA2PrivateKey privKey = (BCMcElieceCCA2PrivateKey)pair + .getPrivate(); + + GF2Vector plaintext = new GF2Vector(pubKey.getK(), sr); + GF2Vector errors = new GF2Vector(n, t, sr); + + GF2Vector ciphertext = McElieceCCA2Primitives.encryptionPrimitive( + pubKey, plaintext, errors); + + GF2Vector[] dec = McElieceCCA2Primitives.decryptionPrimitive(privKey, + ciphertext); + GF2Vector plaintextAgain = dec[0]; + GF2Vector errorsAgain = dec[1]; + + assertEquals(plaintext, plaintextAgain); + assertEquals(errors, errorsAgain); + } + + /** + * Initialize the key pair generator with the given parameters. + */ + private void initKPG(int m, int t) + throws Exception + { + ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(m, t); + kpg.initialize(params); + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceFujisakiCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceFujisakiCipherTest.java new file mode 100644 index 00000000..e8a20b85 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceFujisakiCipherTest.java @@ -0,0 +1,44 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPairGenerator; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; + + +public class McElieceFujisakiCipherTest + extends AsymmetricHybridCipherTest +{ + + protected void setUp() + { + super.setUp(); + try + { + kpg = KeyPairGenerator.getInstance("McElieceFujisaki"); + cipher = Cipher.getInstance("McElieceFujisakiWithSHA256"); + } + catch (Exception e) + { + e.printStackTrace(); + } + + } + + /** + * Test encryption and decryption performance for SHA256 message digest and parameters + * m=11, t=50. + */ + public void testEnDecryption_SHA256_11_50() + throws Exception + { + // initialize key pair generator + ECCKeyGenParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); + kpg.initialize(kpgParams); + + // perform test + performEnDecryptionTest(1, 10, 32, null); + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceKobaraImaiCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceKobaraImaiCipherTest.java new file mode 100644 index 00000000..844efb52 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McElieceKobaraImaiCipherTest.java @@ -0,0 +1,43 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPairGenerator; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; + + +public class McElieceKobaraImaiCipherTest + extends AsymmetricHybridCipherTest +{ + + protected void setUp() + { + super.setUp(); + try + { + kpg = KeyPairGenerator.getInstance("McElieceKobaraImai"); + cipher = Cipher.getInstance("McElieceKobaraImaiWithSHA256"); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Test encryption and decryption performance for SHA256 message digest and parameters + * m=11, t=50. + */ + public void testEnDecryption_SHA256_11_50() + throws Exception + { + // initialize key pair generator + AlgorithmParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); + kpg.initialize(kpgParams); + + performEnDecryptionTest(1, 10, 32, null); + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePKCSCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePKCSCipherTest.java new file mode 100644 index 00000000..263b9e5d --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePKCSCipherTest.java @@ -0,0 +1,47 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPairGenerator; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; + +public class McEliecePKCSCipherTest + extends AsymmetricBlockCipherTest +{ + + protected void setUp() + { + super.setUp(); + + try + { + kpg = KeyPairGenerator.getInstance("McEliecePKCS"); + cipher = Cipher.getInstance("McEliecePKCSwithSHA256"); + } + catch (Exception e) + { + e.printStackTrace(); + } + + + } + + public void testEnDecryption_9_33() + throws Exception + { + ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(9, 33); + kpg.initialize(params); + performEnDecryptionTest(2, 10, params); + } + + public void testEnDecryption_11_50() + throws Exception + { + ECCKeyGenParameterSpec params = new ECCKeyGenParameterSpec(11, 50); + kpg.initialize(params); + performEnDecryptionTest(2, 10, params); + } + + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePointchevalCipherTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePointchevalCipherTest.java new file mode 100644 index 00000000..0dd8a2b2 --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/McEliecePointchevalCipherTest.java @@ -0,0 +1,43 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.security.KeyPairGenerator; +import java.security.spec.AlgorithmParameterSpec; + +import javax.crypto.Cipher; + +import org.spongycastle.pqc.jcajce.spec.ECCKeyGenParameterSpec; + +public class McEliecePointchevalCipherTest + extends AsymmetricHybridCipherTest +{ + + protected void setUp() + { + super.setUp(); + try + { + kpg = KeyPairGenerator.getInstance("McEliecePointcheval"); + cipher = Cipher.getInstance("McEliecePointchevalWithSHA256"); + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + /** + * Test encryption and decryption performance for SHA256 message digest and parameters + * m=11, t=50. + */ + public void testEnDecryption_SHA256_11_50() + throws Exception + { + // initialize key pair generator + AlgorithmParameterSpec kpgParams = new ECCKeyGenParameterSpec(11, 50); + kpg.initialize(kpgParams); + + // perform test + performEnDecryptionTest(1, 10, 32, null); + } + +} diff --git a/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/RainbowSignatureTest.java b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/RainbowSignatureTest.java new file mode 100644 index 00000000..c710d46a --- /dev/null +++ b/prov/src/test/java/org/spongycastle/pqc/jcajce/provider/test/RainbowSignatureTest.java @@ -0,0 +1,450 @@ +package org.spongycastle.pqc.jcajce.provider.test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.SecureRandom; +import java.security.Security; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Random; + +import junit.framework.TestCase; +import org.spongycastle.pqc.jcajce.provider.BouncyCastlePQCProvider; +import org.spongycastle.pqc.jcajce.spec.RainbowParameterSpec; +import org.spongycastle.util.encoders.Hex; + +public class RainbowSignatureTest + extends TestCase +{ + + protected KeyPairGenerator kpg; + + protected Signature sig; + + private Signature sigVerify; + + private KeyPair keyPair; + + private PublicKey pubKey; + + private PrivateKey privKey; + + private byte[] mBytes; + + private byte[] sigBytes; + + private boolean valid; + + Random rand = new Random(); + + private KeyFactory kf; + + + public void setUp() + { + if (Security.getProvider(BouncyCastlePQCProvider.PROVIDER_NAME) == null) + { + Security.addProvider(new BouncyCastlePQCProvider()); + } + } + + /** + * Test signature generation and verification + * + * @param numPassesKPG the number of key pair generation passes + * @param numPassesSigVer the number of sign/verify passes + * @param kpgParams the parameters for the key pair generator + */ + protected final void performSignVerifyTest(int numPassesKPG, + int numPassesSigVer, AlgorithmParameterSpec kpgParams) + throws Exception + { + this.performSignVerifyTest(numPassesKPG, numPassesSigVer, + kpgParams, 100); + } + + /** + * Test signature generation and verification + * + * @param numPassesKPG the number of key pair generation passes + * @param numPassesSigVer the number of sign/verify passes + * @param kpgParams the parameters for the key pair generator + * @param messageSize length of the messages which are signed in bytes + */ + protected final void performSignVerifyTest(int numPassesKPG, + int numPassesSigVer, AlgorithmParameterSpec kpgParams, + int messageSize) + throws Exception + { + // generate new signature instance for verification + // sigVerify = (Signature) sig.getClass().newInstance(); + sigVerify = Signature.getInstance("SHA384WITHRainbow"); + + for (int j = 0; j < numPassesKPG; j++) + { + // generate key pair + if (kpgParams != null) + { + kpg.initialize(kpgParams); + } + keyPair = kpg.genKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + + // initialize signature instances + sig.initSign(privKey); + sigVerify.initVerify(pubKey); + + for (int k = 1; k <= numPassesSigVer; k++) + { + // generate random message + mBytes = new byte[messageSize]; + rand.nextBytes(mBytes); + + // sign + sig.update(mBytes); + sigBytes = sig.sign(); + + // verify + sigVerify.update(mBytes); + valid = sigVerify.verify(sigBytes); + + // compare + assertTrue( + "Signature generation and verification test failed.\n" + + "Message: \"" + + new String(Hex.encode(mBytes)) + "\"\n" + + privKey + "\n" + pubKey, valid); + } + } + } + + /** + * Test signature generation and verification + * + * @param numPassesKPG the number of key pair generation passes + * @param numPassesSigVer the number of sign/verify passes + * @param keySize the key size for the key pair generator + */ + protected final void performSignVerifyTest(int numPassesKPG, + int numPassesSigVer, int keySize) + throws Exception + { + + System.out.println("=== TEST ==="); + System.out.println(numPassesKPG + " Tests"); + System.out.println("KeySize: " + keySize + ""); + for (int j = 0; j < numPassesKPG; j++) + { + // generate key pair + + kpg.initialize(keySize); + keyPair = kpg.genKeyPair(); + pubKey = keyPair.getPublic(); + //writeKey("RainbowPubKey", pubKey); + privKey = keyPair.getPrivate(); + // it causes errors! cause RainbowParameters will be null + //pubKey = getPublicKey("RainbowPubKey"); + + // initialize signature instances + sig.initSign(privKey, new SecureRandom()); + sigVerify.initVerify(pubKey); + + for (int k = 1; k <= numPassesSigVer; k++) + { + // generate random message + final int messageSize = 100; + mBytes = new byte[messageSize]; + rand.nextBytes(mBytes); + + sig.update(mBytes, 0, mBytes.length); + sigBytes = sig.sign(); + + // verify + sigVerify.update(mBytes, 0, mBytes.length); + valid = sigVerify.verify(sigBytes); + + // compare + assertTrue( + "Signature generation and verification test failed.\n" + + "Message: \"" + + new String(Hex.encode(mBytes)) + "\"\n" + + privKey + "\n" + pubKey, valid); + } + } + + } + + protected final void performSignVerifyTest(int numPassesSigVer, PublicKey pubKey, PrivateKey privKey) + throws Exception + { + // initialize signature instances + sig.initSign(privKey); + sigVerify.initVerify(pubKey); + + for (int k = 1; k <= numPassesSigVer; k++) + { + // generate random message + final int messageSize = 100; + mBytes = new byte[messageSize]; + rand.nextBytes(mBytes); + + // sign + sig.update(mBytes); + sigBytes = sig.sign(); + + // verify + sigVerify.update(mBytes); + valid = sigVerify.verify(sigBytes); + + + // compare + assertTrue( + "Signature generation and verification test failed.\n" + + "Message: \"" + + new String(Hex.encode(mBytes)) + "\"\n" + + privKey + "\n" + pubKey, valid); + } + } + + protected final void performVerifyTest(PublicKey pk, byte[] signature, byte[] message) + { + try + { + sig.initVerify(pk); + sig.update(message); + valid = sig.verify(signature); + assertTrue("Signature generation and verification test failed.\n" + "Message: \"" + new String(Hex.encode(mBytes)) + "\"\n" + privKey + "\n" + pubKey, valid); + } + catch (InvalidKeyException e) + { + e.printStackTrace(); + } + catch (SignatureException e) + { + e.printStackTrace(); + } + } + + + /** + * Using ParameterSpecs to initialize the key pair generator without initialization. + */ + + public void testRainbowWithSHA224() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow", BouncyCastlePQCProvider.PROVIDER_NAME); + sig = Signature.getInstance("SHA224WITHRainbow", BouncyCastlePQCProvider.PROVIDER_NAME); + sigVerify = Signature.getInstance("SHA224WITHRainbow", BouncyCastlePQCProvider.PROVIDER_NAME); + performSignVerifyTest(1, 1, 28); + } + + public void testRainbowithSHA256() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + sig = Signature.getInstance("SHA256WITHRainbow"); + sigVerify = Signature.getInstance("SHA256WITHRainbow"); + performSignVerifyTest(1, 1, 32); + } + + public void testRainbowWithSHA384() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + sig = Signature.getInstance("SHA384WITHRainbow"); + sigVerify = Signature.getInstance("SHA384WITHRainbow"); + performSignVerifyTest(1, 1, 48); + } + + public void testRainbowWithSHA512() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + sig = Signature.getInstance("SHA512WITHRainbow"); + sigVerify = Signature.getInstance("SHA512WITHRainbow"); + performSignVerifyTest(1, 1, 64); + } + + public void test_KeyFactory() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + + KeyFactory kf = KeyFactory.getInstance("Rainbow"); + + AlgorithmParameterSpec specs = new RainbowParameterSpec(); + try + { + kpg.initialize(specs); + } + catch (InvalidAlgorithmParameterException e) + { + e.printStackTrace(); + } + // XXX + kpg.initialize(5); + keyPair = kpg.genKeyPair(); + pubKey = keyPair.getPublic(); + privKey = keyPair.getPrivate(); + + byte[] pubKeyBytes = pubKey.getEncoded(); + X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes); + PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKey.getEncoded()); + + PublicKey publicKeyKF = kf.generatePublic(pubKeySpec); + + assertEquals(pubKey, publicKeyKF); + assertEquals(pubKey.hashCode(), publicKeyKF.hashCode()); + + PrivateKey privKeyKF = kf.generatePrivate(privKeySpec); + + assertEquals(privKey, privKeyKF); + assertEquals(privKey.hashCode(), privKeyKF.hashCode()); + } + + public PrivateKey getPrivateKey(String file) + throws Exception + { + byte[] privKeyBytes = getBytesFromFile(new File(file)); + PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(privKeyBytes); + return kf.generatePrivate(privKeySpec); + } + + public void writeToFile(String filename, String data) + throws IOException + { + FileOutputStream fos = new FileOutputStream(filename); + fos.write(data.getBytes()); + fos.close(); + } + + public void testSignVerifyWithRandomParams() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + sig = Signature.getInstance("SHA384WITHRainbow"); + int[] vi; + + for (int kgen = 1; kgen <= 10; kgen++) + { + vi = chooseRandomParams(); + RainbowParameterSpec rbParams = new RainbowParameterSpec(vi); + performSignVerifyTest(1, 100, rbParams); + } + } + + + /** + * build up the set of vinegars per layer (vi) + * + * @return parameters vi + */ + private int[] chooseRandomParams() + { + int n = rand.nextInt(10) + 2; + int[] vi = new int[n]; + + vi[0] = rand.nextInt(10) + 2; + for (int i = 1; i < n; i++) + { + vi[i] = vi[i - 1]; + vi[i] += rand.nextInt(10) + 1; + } + return vi; + } + + /* + public void testSignVerifyWithSpecialParams() throws Exception { + kpg = KeyPairGenerator.getInstance("RainbowWithSHA384"); + sig = Signature.getInstance("SHA384WITHRainbow"); + int[] vi = { 3, 20, 25, 30, 40, 60, 80, 100 }; + performSignVerifyTest(10, 200, new RainbowParameterSpec(vi)); + } + */ + + public void testSignVerifyWithDefaultParams() + throws Exception + { + kpg = KeyPairGenerator.getInstance("Rainbow"); + sig = Signature.getInstance("SHA384WITHRainbow"); + performSignVerifyTest(15, 100, new RainbowParameterSpec()); + } + + + public void writeKey(String file, Key key) + throws IOException + { + byte[] privKeyBytes = key.getEncoded(); + FileOutputStream fos = new FileOutputStream(file); + fos.write(privKeyBytes); + fos.close(); + } + + public PublicKey getPublicKey(String file) + throws Exception + { + kf = KeyFactory.getInstance("Rainbow"); + byte[] pubKeyBytes = getBytesFromFile(new File(file)); + X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(pubKeyBytes); + return kf.generatePublic(pubKeySpec); + } + + + public byte[] getBytesFromFile(File file) + throws IOException + { + InputStream is = new FileInputStream(file); + + // Get the size of the file + long length = file.length(); + + // You cannot create an array using a long type. + // It needs to be an int type. + // Before converting to an int type, check + // to ensure that file is not larger than Integer.MAX_VALUE. + if (length > Integer.MAX_VALUE) + { + // File is too large + } + + // Create the byte array to hold the data + byte[] bytes = new byte[(int)length]; + + // Read in the bytes + int offset = 0; + int numRead = 0; + while (offset < bytes.length + && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) + { + offset += numRead; + } + + // Ensure all the bytes have been read in + if (offset < bytes.length) + { + throw new IOException("Could not completely read file " + file.getName()); + } + + // Close the input stream and return bytes + is.close(); + return bytes; + } + +} + |