blob: 177ec2ede2e0ab16b28c7814bc65ecd53a9933cd [file] [log] [blame]
package org.bouncycastle.jce.provider.test;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
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 javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.IEKeySpec;
import org.bouncycastle.jce.spec.IESParameterSpec;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.test.SimpleTest;
/**
* test for ECIES - Elliptic Curve Integrated Encryption Scheme
*/
public class IESTest
extends SimpleTest
{
private BigInteger g512 = new BigInteger("153d5d6172adb43045b68ae8e1de1070b6137005686d29d3d73a7749199681ee5b212c9b96bfdcfa5b20cd5e3fd2044895d609cf9b410b7a0f12ca1cb9a428cc", 16);
private BigInteger p512 = new BigInteger("9494fec095f3b85ee286542b3836fc81a5dd0a0349b4c239dd38744d488cf8e31db8bcb7d33b41abb9e5a33cca9144b1cef332c94bf0573bf047a3aca98cdf3b", 16);
IESTest()
{
}
public String getName()
{
return "IES";
}
public void performTest()
throws Exception
{
KeyPairGenerator g = KeyPairGenerator.getInstance("ECIES", "BC");
ECCurve curve = new ECCurve.Fp(
new BigInteger("883423532389192164791648750360308885314476597252960362792450860609699839"), // q
new BigInteger("7fffffffffffffffffffffff7fffffffffff8000000000007ffffffffffc", 16), // a
new BigInteger("6b016c3bdcf18941d0d654921475ca71a9db2fb27d1d37796185c2942c0a", 16)); // b
ECParameterSpec ecSpec = new ECParameterSpec(
curve,
curve.decodePoint(Hex.decode("020ffa963cdca8816ccc33b8642bedf905c3d358573d3f27fbbd3b3cb9aaaf")), // G
new BigInteger("883423532389192164791648750360308884807550341691627752275345424702807307")); // n
g.initialize(ecSpec, new SecureRandom());
Cipher c1 = Cipher.getInstance("ECIES", "BC");
Cipher c2 = Cipher.getInstance("ECIES", "BC");
doTest(g, c1, c2);
g = KeyPairGenerator.getInstance("ECIES", "BC");
g.initialize(192, new SecureRandom());
doTest(g, c1, c2);
g = KeyPairGenerator.getInstance("ECIES", "BC");
g.initialize(239, new SecureRandom());
doTest(g, c1, c2);
g = KeyPairGenerator.getInstance("ECIES", "BC");
g.initialize(256, new SecureRandom());
doTest(g, c1, c2);
doDefTest(g, c1, c2);
DHParameterSpec dhParams = new DHParameterSpec(p512, g512);
c1 = Cipher.getInstance("IES", "BC");
c2 = Cipher.getInstance("IES", "BC");
g = KeyPairGenerator.getInstance("DH", "BC");
g.initialize(dhParams);
doTest(g, c1, c2);
doDefTest(g, c1, c2);
}
public void doTest(
KeyPairGenerator g,
Cipher c1,
Cipher c2)
throws Exception
{
//
// a side
//
KeyPair aKeyPair = g.generateKeyPair();
PublicKey aPub = aKeyPair.getPublic();
PrivateKey aPriv = aKeyPair.getPrivate();
//
// b side
//
KeyPair bKeyPair = g.generateKeyPair();
PublicKey bPub = bKeyPair.getPublic();
PrivateKey bPriv = bKeyPair.getPrivate();
//
// stream test
//
IEKeySpec c1Key = new IEKeySpec(aPriv, bPub);
IEKeySpec c2Key = new IEKeySpec(bPriv, aPub);
byte[] d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
byte[] e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
IESParameterSpec param = new IESParameterSpec(d, e, 128);
c1.init(Cipher.ENCRYPT_MODE, c1Key, param);
c2.init(Cipher.DECRYPT_MODE, c2Key, param);
byte[] message = Hex.decode("1234567890abcdef");
int estLen1 = c1.getOutputSize(message.length);
byte[] out1 = c1.doFinal(message, 0, message.length);
if (estLen1 < out1.length)
{
fail("output size incorrect");
}
int estLen2 = c2.getOutputSize(out1.length);
byte[] out2 = c2.doFinal(out1, 0, out1.length);
if (estLen2 < out2.length)
{
fail("output size incorrect");
}
if (!areEqual(out2, message))
{
fail("stream cipher test failed");
}
}
public void doDefTest(
KeyPairGenerator g,
Cipher c1,
Cipher c2)
throws Exception
{
//
// a side
//
KeyPair aKeyPair = g.generateKeyPair();
PublicKey aPub = aKeyPair.getPublic();
PrivateKey aPriv = aKeyPair.getPrivate();
//
// b side
//
KeyPair bKeyPair = g.generateKeyPair();
PublicKey bPub = bKeyPair.getPublic();
PrivateKey bPriv = bKeyPair.getPrivate();
//
// stream test
//
IEKeySpec c1Key = new IEKeySpec(aPriv, bPub);
IEKeySpec c2Key = new IEKeySpec(bPriv, aPub);
c1.init(Cipher.ENCRYPT_MODE, c1Key);
AlgorithmParameters param = c1.getParameters();
c2.init(Cipher.DECRYPT_MODE, c2Key, param);
byte[] message = Hex.decode("1234567890abcdef");
int estLen1 = c1.getOutputSize(message.length);
byte[] out1 = c1.doFinal(message, 0, message.length);
if (estLen1 < out1.length)
{
fail("output size incorrect");
}
int estLen2 = c2.getOutputSize(out1.length);
byte[] out2 = c2.doFinal(out1, 0, out1.length);
if (estLen2 < out2.length)
{
fail("output size incorrect");
}
if (!areEqual(out2, message))
{
fail("stream cipher test failed");
}
//
// int doFinal
//
int len1 = c1.doFinal(message, 0, message.length, out1, 0);
if (len1 != out1.length)
{
fail("encryption length wrong");
}
int len2 = c2.doFinal(out1, 0, out1.length, out2, 0);
if (len2 != out2.length)
{
fail("decryption length wrong");
}
if (!areEqual(out2, message))
{
fail("stream cipher test failed");
}
//
// int doFinal with update
//
len1 = c1.update(message, 0, 2, out1, 0);
len1 += c1.doFinal(message, 2, message.length - 2, out1, len1);
if (len1 != out1.length)
{
fail("update encryption length wrong");
}
len2 = c2.update(out1, 0, 2, out2, 0);
len2 += c2.doFinal(out1, 2, out1.length - 2, out2, len2);
if (len2 != out2.length)
{
fail("update decryption length wrong");
}
if (!areEqual(out2, message))
{
fail("update stream cipher test failed");
}
}
public static void main(
String[] args)
{
Security.addProvider(new BouncyCastleProvider());
runTest(new IESTest());
}
}