forked from I2P_Developers/i2p.i2p
2005-03-23 Comwiz
* Phase 1 of the unit test bounty completed. (The router build script was modified not to build the router tests because of a broken dependancy on the core tests. This should be fixed in phase 3 of the unit test bounty.)
This commit is contained in:
77
core/java/test/net/i2p/crypto/AES256Test.java
Normal file
77
core/java/test/net/i2p/crypto/AES256Test.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @author Comwiz
|
||||
*/
|
||||
public class AES256Test extends TestCase{
|
||||
private I2PAppContext _context;
|
||||
private byte[] iv;
|
||||
|
||||
protected void setUp() {
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
public void testMultiple(){
|
||||
for(int i = 0; i < 100; i++){
|
||||
|
||||
SessionKey key = _context.keyGenerator().generateSessionKey();
|
||||
|
||||
byte[] iv = new byte[16];
|
||||
_context.random().nextBytes(iv);
|
||||
|
||||
byte[] plain = new byte[256];
|
||||
_context.random().nextBytes(plain);
|
||||
|
||||
byte[] e = new byte[plain.length];
|
||||
_context.aes().encrypt(plain, 0, e, 0, key, iv, plain.length);
|
||||
byte[] d = new byte[e.length];
|
||||
_context.aes().decrypt(e, 0, d, 0, key, iv, d.length);
|
||||
boolean same = true;
|
||||
assertTrue(DataHelper.eq(plain, d));
|
||||
}
|
||||
}
|
||||
|
||||
public void testLong(){
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(iv);
|
||||
|
||||
|
||||
byte lbuf[] = new byte[1024];
|
||||
RandomSource.getInstance().nextBytes(lbuf);
|
||||
byte le[] = ctx.aes().safeEncrypt(lbuf, key, iv, 2048);
|
||||
byte ld[] = ctx.aes().safeDecrypt(le, key, iv);
|
||||
assertTrue(DataHelper.eq(ld, lbuf));
|
||||
}
|
||||
|
||||
public void testShort(){
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(iv);
|
||||
|
||||
byte sbuf[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(sbuf);
|
||||
byte se[] = new byte[16];
|
||||
ctx.aes().encrypt(sbuf, 0, se, 0, key, iv, sbuf.length);
|
||||
byte sd[] = new byte[16];
|
||||
ctx.aes().decrypt(se, 0, sd, 0, key, iv, se.length);
|
||||
assertTrue(DataHelper.eq(sd, sbuf));
|
||||
}
|
||||
}
|
111
core/java/test/net/i2p/crypto/AESInputStreamTest.java
Normal file
111
core/java/test/net/i2p/crypto/AESInputStreamTest.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
/**
|
||||
* @author Comwiz
|
||||
*/
|
||||
public class AESInputStreamTest extends TestCase {
|
||||
public void testMultiple() throws Exception{
|
||||
SessionKey key = KeyGenerator.getInstance().generateSessionKey();
|
||||
byte iv[] = "there once was a".getBytes();
|
||||
|
||||
int[] sizes = {1024 * 32, 20, 3, 0};
|
||||
|
||||
for(int j = 0; j < sizes.length; j++){
|
||||
byte orig[] = new byte[sizes[j]];
|
||||
for (int i = 0; i < 20; i++) {
|
||||
RandomSource.getInstance().nextBytes(orig);
|
||||
runTest(orig, key, iv);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void runTest(byte orig[], SessionKey key, byte[] iv) throws Exception{
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
|
||||
ByteArrayOutputStream origStream = new ByteArrayOutputStream(512);
|
||||
AESOutputStream out = new AESOutputStream(ctx, origStream, key, iv);
|
||||
out.write(orig);
|
||||
out.close();
|
||||
|
||||
byte encrypted[] = origStream.toByteArray();
|
||||
|
||||
ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encrypted);
|
||||
AESInputStream sin = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||
byte buf[] = new byte[1024 * 32];
|
||||
int read = DataHelper.read(sin, buf);
|
||||
if (read > 0) baos.write(buf, 0, read);
|
||||
sin.close();
|
||||
byte fin[] = baos.toByteArray();
|
||||
|
||||
Hash origHash = SHA256Generator.getInstance().calculateHash(orig);
|
||||
Hash newHash = SHA256Generator.getInstance().calculateHash(fin);
|
||||
|
||||
assertEquals(origHash, newHash);
|
||||
assertTrue(DataHelper.eq(orig, fin));
|
||||
}
|
||||
|
||||
public static void testOffset() throws Exception{
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
|
||||
byte[] orig = new byte[32];
|
||||
RandomSource.getInstance().nextBytes(orig);
|
||||
|
||||
SessionKey key = KeyGenerator.getInstance().generateSessionKey();
|
||||
byte iv[] = "there once was a".getBytes();
|
||||
|
||||
ByteArrayOutputStream origStream = new ByteArrayOutputStream(512);
|
||||
AESOutputStream out = new AESOutputStream(ctx, origStream, key, iv);
|
||||
out.write(orig);
|
||||
out.close();
|
||||
|
||||
byte encrypted[] = origStream.toByteArray();
|
||||
|
||||
byte encryptedSegment[] = new byte[40];
|
||||
System.arraycopy(encrypted, 0, encryptedSegment, 0, 40);
|
||||
|
||||
ByteArrayInputStream encryptedStream = new ByteArrayInputStream(encryptedSegment);
|
||||
AESInputStream sin = new AESInputStream(ctx, encryptedStream, key, iv);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
|
||||
byte buf[] = new byte[1024 * 32];
|
||||
int read = DataHelper.read(sin, buf);
|
||||
int remaining = sin.remainingBytes();
|
||||
int readyBytes = sin.readyBytes();
|
||||
|
||||
if (read > 0)
|
||||
baos.write(buf, 0, read);
|
||||
sin.close();
|
||||
byte fin[] = baos.toByteArray();
|
||||
|
||||
Hash origHash = SHA256Generator.getInstance().calculateHash(orig);
|
||||
Hash newHash = SHA256Generator.getInstance().calculateHash(fin);
|
||||
|
||||
assertFalse(origHash.equals(newHash));
|
||||
assertFalse(DataHelper.eq(orig, fin));
|
||||
}
|
||||
}
|
118
core/java/test/net/i2p/crypto/CryptixAESEngineTest.java
Normal file
118
core/java/test/net/i2p/crypto/CryptixAESEngineTest.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.security.InvalidKeyException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.ByteArray;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.util.ByteCache;
|
||||
import net.i2p.crypto.CryptixAESEngine;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CryptixAESEngineTest extends TestCase{
|
||||
public void testED() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[128];
|
||||
byte encrypted[] = new byte[128];
|
||||
byte decrypted[] = new byte[128];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encrypt(orig, 0, encrypted, 0, key, iv, orig.length);
|
||||
aes.decrypt(encrypted, 0, decrypted, 0, key, iv, encrypted.length);
|
||||
assertTrue(DataHelper.eq(decrypted,orig));
|
||||
}
|
||||
|
||||
public static void testED2() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[128];
|
||||
byte data[] = new byte[128];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encrypt(orig, 0, data, 0, key, iv, data.length);
|
||||
aes.decrypt(data, 0, data, 0, key, iv, data.length);
|
||||
assertTrue(DataHelper.eq(data,orig));
|
||||
}
|
||||
|
||||
public static void testFake() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
SessionKey wrongKey = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[128];
|
||||
byte encrypted[] = new byte[128];
|
||||
byte decrypted[] = new byte[128];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encrypt(orig, 0, encrypted, 0, key, iv, orig.length);
|
||||
aes.decrypt(encrypted, 0, decrypted, 0, wrongKey, iv, encrypted.length);
|
||||
assertFalse(DataHelper.eq(decrypted,orig));
|
||||
}
|
||||
|
||||
public static void testNull() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
SessionKey wrongKey = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[128];
|
||||
byte encrypted[] = new byte[128];
|
||||
byte decrypted[] = new byte[128];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encrypt(orig, 0, encrypted, 0, key, iv, orig.length);
|
||||
|
||||
boolean error = false;
|
||||
try {
|
||||
aes.decrypt(null, 0, null, 0, wrongKey, iv, encrypted.length);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
error = true;
|
||||
}
|
||||
assertTrue(error);
|
||||
}
|
||||
|
||||
public static void testEDBlock() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[16];
|
||||
byte encrypted[] = new byte[16];
|
||||
byte decrypted[] = new byte[16];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encryptBlock(orig, 0, key, encrypted, 0);
|
||||
aes.decryptBlock(encrypted, 0, key, decrypted, 0);
|
||||
assertTrue(DataHelper.eq(decrypted,orig));
|
||||
}
|
||||
|
||||
public static void testEDBlock2() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
SessionKey key = ctx.keyGenerator().generateSessionKey();
|
||||
byte iv[] = new byte[16];
|
||||
byte orig[] = new byte[16];
|
||||
byte data[] = new byte[16];
|
||||
ctx.random().nextBytes(iv);
|
||||
ctx.random().nextBytes(orig);
|
||||
CryptixAESEngine aes = new CryptixAESEngine(ctx);
|
||||
aes.encryptBlock(orig, 0, key, data, 0);
|
||||
aes.decryptBlock(data, 0, key, data, 0);
|
||||
assertTrue(DataHelper.eq(data,orig));
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class CryptixRijndael_AlgorithmTest extends TestCase {
|
||||
public void testCRA() throws Exception{
|
||||
int[] sizes = {16,24,32};
|
||||
for(int j = 0; j < sizes.length; j++){
|
||||
|
||||
byte[] kb = new byte[sizes[j]];
|
||||
byte[] pt = new byte[16];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizes[j]; i++)
|
||||
kb[i] = (byte) i;
|
||||
for (i = 0; i < 16; i++)
|
||||
pt[i] = (byte) i;
|
||||
|
||||
|
||||
Object key = CryptixRijndael_Algorithm.makeKey(kb, 16);
|
||||
|
||||
byte[] ct = new byte[16];
|
||||
CryptixRijndael_Algorithm.blockEncrypt(pt, ct, 0, 0, key, 16);
|
||||
|
||||
byte[] cpt = new byte[16];
|
||||
CryptixRijndael_Algorithm.blockDecrypt(ct, cpt, 0, 0, key, 16);
|
||||
|
||||
assertTrue(DataHelper.eq(pt, cpt));
|
||||
}
|
||||
}
|
||||
}
|
38
core/java/test/net/i2p/crypto/CryptoTestSuite.java
Normal file
38
core/java/test/net/i2p/crypto/CryptoTestSuite.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* @author comwiz
|
||||
*/
|
||||
public class CryptoTestSuite {
|
||||
|
||||
public static Test suite() {
|
||||
|
||||
TestSuite suite = new TestSuite("net.i2p.crypto.CryptoTestSuite");
|
||||
|
||||
suite.addTestSuite(AES256Test.class);
|
||||
suite.addTestSuite(AESInputStreamTest.class);
|
||||
suite.addTestSuite(CryptixAESEngineTest.class);
|
||||
suite.addTestSuite(CryptixRijndael_AlgorithmTest.class);
|
||||
suite.addTestSuite(DHSessionKeyBuilderTest.class);
|
||||
suite.addTestSuite(DSATest.class);
|
||||
suite.addTestSuite(ElGamalTest.class);
|
||||
suite.addTestSuite(HMACSHA256Test.class);
|
||||
suite.addTestSuite(KeyGeneratorTest.class);
|
||||
suite.addTestSuite(SessionEncryptionTest.class);
|
||||
suite.addTestSuite(SHA1HashTest.class);
|
||||
suite.addTestSuite(SHA256Test.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
}
|
47
core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java
Normal file
47
core/java/test/net/i2p/crypto/DHSessionKeyBuilderTest.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class DHSessionKeyBuilderTest extends TestCase {
|
||||
public void testDHSessionKeyBuilder(){
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
DHSessionKeyBuilder builder1 = new DHSessionKeyBuilder();
|
||||
DHSessionKeyBuilder builder2 = new DHSessionKeyBuilder();
|
||||
BigInteger pub1 = builder1.getMyPublicValue();
|
||||
builder2.setPeerPublicValue(pub1);
|
||||
BigInteger pub2 = builder2.getMyPublicValue();
|
||||
builder1.setPeerPublicValue(pub2);
|
||||
SessionKey key1 = builder1.getSessionKey();
|
||||
SessionKey key2 = builder2.getSessionKey();
|
||||
|
||||
assertEquals(key1, key2);
|
||||
|
||||
byte iv[] = new byte[16];
|
||||
RandomSource.getInstance().nextBytes(iv);
|
||||
String origVal = "1234567890123456"; // 16 bytes max using AESEngine
|
||||
byte enc[] = new byte[16];
|
||||
byte dec[] = new byte[16];
|
||||
ctx.aes().encrypt(origVal.getBytes(), 0, enc, 0, key1, iv, 16);
|
||||
ctx.aes().decrypt(enc, 0, dec, 0, key2, iv, 16);
|
||||
String tranVal = new String(dec);
|
||||
assertEquals(origVal, tranVal);
|
||||
}
|
||||
}
|
||||
}
|
44
core/java/test/net/i2p/crypto/DSATest.java
Normal file
44
core/java/test/net/i2p/crypto/DSATest.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.I2PAppContext;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class DSATest extends TestCase{
|
||||
private I2PAppContext _context;
|
||||
|
||||
protected void setUp() {
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
public void testMultiple(){
|
||||
for(int i = 0; i < 100; i++){
|
||||
byte[] message = new byte[256];
|
||||
_context.random().nextBytes(message);
|
||||
|
||||
Object[] keys = KeyGenerator.getInstance().generateSigningKeypair();
|
||||
SigningPublicKey pubkey = (SigningPublicKey)keys[0];
|
||||
SigningPrivateKey privkey = (SigningPrivateKey)keys[1];
|
||||
|
||||
Signature s = DSAEngine.getInstance().sign(message, privkey);
|
||||
Signature s1 = DSAEngine.getInstance().sign(new ByteArrayInputStream(message), privkey);
|
||||
|
||||
assertTrue(DSAEngine.getInstance().verifySignature(s, message, pubkey));
|
||||
assertTrue(DSAEngine.getInstance().verifySignature(s1, new ByteArrayInputStream(message), pubkey));
|
||||
assertTrue(DSAEngine.getInstance().verifySignature(s1, message, pubkey));
|
||||
assertTrue(DSAEngine.getInstance().verifySignature(s, new ByteArrayInputStream(message), pubkey));
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,243 +0,0 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.RandomSource;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
class ElGamalAESEngineTest {
|
||||
private final static Log _log = new Log(ElGamalAESEngineTest.class);
|
||||
private I2PAppContext _context;
|
||||
public ElGamalAESEngineTest(I2PAppContext ctx) {
|
||||
_context = ctx;
|
||||
}
|
||||
public void runRoundtripTest() {
|
||||
try {
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
|
||||
String msg = "Hello world";
|
||||
Set toBeDelivered = new HashSet();
|
||||
SessionKey key = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
if (key == null)
|
||||
key = _context.sessionKeyManager().createSession(pubKey);
|
||||
byte[] encrypted = _context.elGamalAESEngine().encrypt(msg.getBytes(), pubKey, key, 64);
|
||||
byte[] decrypted = _context.elGamalAESEngine().decrypt(encrypted, privKey);
|
||||
if (decrypted == null)
|
||||
throw new Exception("Failed to decrypt");
|
||||
String read = new String(decrypted);
|
||||
_log.debug("read: " + read);
|
||||
_log.debug("Match? " + msg.equals(read));
|
||||
} catch (Exception e) {
|
||||
_log.error("Error", e);
|
||||
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void runLoopTest(int runs) {
|
||||
try {
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
|
||||
long e0 = 0;
|
||||
long d0 = 0;
|
||||
long eTot = 0;
|
||||
long dTot = 0;
|
||||
for (int i = 0; i < runs; i++) {
|
||||
long times[] = runMessage(pubKey, privKey);
|
||||
_log.debug("E[" + i + "] time: " + times[0] + "ms");
|
||||
_log.debug("D["+i+"] time: " + times[1] + "ms");
|
||||
if (i == 0) {
|
||||
e0 = times[0];
|
||||
d0 = times[1];
|
||||
}
|
||||
eTot += times[0];
|
||||
dTot += times[1];
|
||||
}
|
||||
_log.debug("E average time: " + eTot/runs + "ms");
|
||||
_log.debug("D average time: " + dTot/runs + "ms");
|
||||
_log.debug("Total time to send and receive " + (runs) + "Kb: " + (eTot+dTot)+"ms");
|
||||
|
||||
} catch (Exception e) {
|
||||
_log.error("Error", e);
|
||||
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
private long[] runMessage(PublicKey pubKey, PrivateKey privKey) throws Exception {
|
||||
byte[] msg = new byte[400];
|
||||
RandomSource.getInstance().nextBytes(msg);
|
||||
SessionKey key = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
if (key == null)
|
||||
key = _context.sessionKeyManager().createSession(pubKey);
|
||||
|
||||
long beforeE = Clock.getInstance().now();
|
||||
byte[] encrypted = _context.elGamalAESEngine().encrypt(msg, pubKey, key, 1024);
|
||||
long afterE = Clock.getInstance().now();
|
||||
byte[] decrypted = _context.elGamalAESEngine().decrypt(encrypted, privKey);
|
||||
long afterD = Clock.getInstance().now();
|
||||
if (!DataHelper.eq(msg, decrypted)) {
|
||||
_log.error("WTF, D(E(val)) != val");
|
||||
return null;
|
||||
}
|
||||
|
||||
long rv[] = new long[2];
|
||||
rv[0] = afterE - beforeE;
|
||||
rv[1] = afterD - afterE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
public void runAESTest() {
|
||||
try {
|
||||
SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
|
||||
Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
|
||||
byte iv[] = new byte[16];
|
||||
System.arraycopy(h.getData(), 0, iv, 0, 16);
|
||||
|
||||
String msg = "Hello world";
|
||||
|
||||
byte encrypted[] = _context.elGamalAESEngine().encryptAESBlock(msg.getBytes(), sessionKey, iv, null, null, 64);
|
||||
_log.debug("** Encryption complete. Beginning decryption");
|
||||
Set foundTags = new HashSet();
|
||||
SessionKey foundKey = new SessionKey();
|
||||
byte decrypted[] = _context.elGamalAESEngine().decryptAESBlock(encrypted, 0, encrypted.length, sessionKey, iv, null, foundTags, foundKey);
|
||||
if (decrypted == null) throw new Exception("Decryption failed");
|
||||
String read = new String(decrypted);
|
||||
_log.debug("read: " + read);
|
||||
_log.debug("Match? " + msg.equals(read));
|
||||
} catch (Exception e) {
|
||||
_log.error("Error", e);
|
||||
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void runBasicAESTest() {
|
||||
try {
|
||||
SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
|
||||
Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
|
||||
byte iv[] = new byte[16];
|
||||
System.arraycopy(h.getData(), 0, iv, 0, 16);
|
||||
|
||||
String msg = "Hello world01234012345678901234501234567890123450123456789012345";
|
||||
h = SHA256Generator.getInstance().calculateHash(msg.getBytes());
|
||||
_log.debug("Hash of entire aes block before encryption: \n" + DataHelper.toString(h.getData(), 32));
|
||||
byte aesEncr[] = new byte[msg.getBytes().length];
|
||||
byte aesDecr[] = new byte[aesEncr.length];
|
||||
_context.aes().encrypt(msg.getBytes(), 0, aesEncr, 0, sessionKey, iv, aesEncr.length);
|
||||
_context.aes().decrypt(aesEncr, 0, aesDecr, 0, sessionKey, iv, aesEncr.length);
|
||||
h = SHA256Generator.getInstance().calculateHash(aesDecr);
|
||||
_log.debug("Hash of entire aes block after decryption: \n" + DataHelper.toString(h.getData(), 32));
|
||||
if (msg.equals(new String(aesDecr))) {
|
||||
_log.debug("**AES Basic test passed!\n\n");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
_log.error("Error", e);
|
||||
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void runElGamalTest(int numLoops) {
|
||||
|
||||
for (int i = 0; i < numLoops; i++) {
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
SessionKey key = KeyGenerator.getInstance().generateSessionKey();
|
||||
|
||||
runBasicElGamalTest(key, pubKey, privKey);
|
||||
}
|
||||
}
|
||||
|
||||
public void runBasicElGamalTest(SessionKey key, PublicKey pubKey, PrivateKey privKey) {
|
||||
try {
|
||||
ByteArrayOutputStream elgSrc = new ByteArrayOutputStream(256);
|
||||
key.writeBytes(elgSrc);
|
||||
byte preIV[] = new byte[32];
|
||||
RandomSource.getInstance().nextBytes(preIV);
|
||||
elgSrc.write(preIV);
|
||||
// byte rnd[] = new byte[191];
|
||||
// RandomSource.getInstance().nextBytes(rnd);
|
||||
// elgSrc.write(rnd);
|
||||
elgSrc.flush();
|
||||
|
||||
byte elgEncr[] = _context.elGamalEngine().encrypt(elgSrc.toByteArray(), pubKey);
|
||||
byte elgDecr[] = _context.elGamalEngine().decrypt(elgEncr, privKey);
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(elgDecr);
|
||||
SessionKey nk = new SessionKey();
|
||||
|
||||
nk.readBytes(bais);
|
||||
byte postpreIV[] = new byte[32];
|
||||
int read = bais.read(postpreIV);
|
||||
if (read != postpreIV.length) {
|
||||
// hmm, this can't really happen...
|
||||
throw new Exception("Somehow ElGamal broke and 256 bytes is less than 32 bytes...");
|
||||
}
|
||||
// ignore the next 192 bytes
|
||||
boolean eq = (DataHelper.eq(preIV, postpreIV) && DataHelper.eq(key, nk));
|
||||
if (!eq) {
|
||||
_log.error("elgEncr.length: " + elgEncr.length + " elgDecr.length: " + elgDecr.length);
|
||||
_log.error("Pre IV.................: " + DataHelper.toString(preIV, 32));
|
||||
_log.error("Pre IV after decryption: " + DataHelper.toString(postpreIV, 32));
|
||||
_log.error("SessionKey.................: " + DataHelper.toString(key.getData(), 32));
|
||||
_log.error("SessionKey after decryption: " + DataHelper.toString(nk.getData(), 32));
|
||||
_log.error("PublicKey: " + DataHelper.toDecimalString(pubKey.getData(), pubKey.getData().length));
|
||||
_log.error("PrivateKey: " + DataHelper.toDecimalString(privKey.getData(), privKey.getData().length));
|
||||
|
||||
throw new Exception("Not equal!");
|
||||
} else {
|
||||
_log.debug("Basic ElG D(E(val)) == val");
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
_log.error("Error", e);
|
||||
try { Thread.sleep(5000); } catch (InterruptedException ie) {}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
I2PAppContext context = new I2PAppContext();
|
||||
ElGamalAESEngineTest tst = new ElGamalAESEngineTest(context);
|
||||
Object o = YKGenerator.class;
|
||||
try { Thread.sleep(120*1000); } catch (InterruptedException ie) {}
|
||||
|
||||
tst.runBasicAESTest();
|
||||
tst.runAESTest();
|
||||
tst.runRoundtripTest();
|
||||
tst.runElGamalTest(2);
|
||||
// test bug
|
||||
for (int i = 0; i < 3; i++)
|
||||
tst.runLoopTest(1);
|
||||
// test throughput
|
||||
tst.runLoopTest(5);
|
||||
|
||||
net.i2p.stat.SimpleStatDumper.dumpStats(context, Log.CRIT);
|
||||
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
|
||||
}
|
||||
}
|
||||
|
383
core/java/test/net/i2p/crypto/ElGamalTest.java
Normal file
383
core/java/test/net/i2p/crypto/ElGamalTest.java
Normal file
@@ -0,0 +1,383 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.SessionTag;
|
||||
import net.i2p.util.RandomSource;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class ElGamalTest extends TestCase{
|
||||
private I2PAppContext _context;
|
||||
|
||||
// Following 4 String arrays for use with the testVerify* methods
|
||||
|
||||
private static final String UNENCRYPTED[] = new String[] {
|
||||
"",
|
||||
"hello world",
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"123456789012",
|
||||
"\0x00",
|
||||
"\0x00\0x00\0x00",
|
||||
"\0x00\0x01\0x02\0x00",
|
||||
};
|
||||
private static final String PUBLIC_KEY = new String(
|
||||
"pOvBUMrSUUeN5awynzbPbCAwe3MqWprhSpp3OR7pvdfm9PhWaNbPoKRLeEmDoUwyNDoHE0" +
|
||||
"E6mcZSG8qPQ8XUZFlczpilOl0MJBvsI9u9SMyi~bEqzSgzh9FNfS-NcGji3q2wI~Ux~q5B" +
|
||||
"KOjGlyMLgd1nxl5R5wIYL4uHKZNaYuArsRYmtV~MgMQPGvDtIbdGTV6aL6UbOYryzQSUMY" +
|
||||
"OuO3S~YoBjA6Nmi0SeJM3tyTxlI6U1EYjR6oQcI4SOFUW4L~8pfYWijcncCODAqpXVN6ZI" +
|
||||
"AJ3a6vjxGu56IDp4xCcKlOEHgdXvqmEC67dR5qf2btH6dtWoB3-Z6QPsS6tPTQ=="
|
||||
);
|
||||
private static final String PRIVATE_KEY = new String(
|
||||
"gMlIhURVXU8uPube20Xr8E1K11g-3qZxOj1riThHqt-rBx72MPq5ivT1rr28cE9mzOmsXi" +
|
||||
"bbsuBuQKYDvF7hGICRB3ROSPePYhcupV3j7XiXUIYjWNw9hvylHXK~nTT7jkpIBazBJZfr" +
|
||||
"LJPcDZTDB0YnCOHOL-KFn4N1R5B22g0iYRABN~O10AUjQmf1epklAXPqYlzmOYeJSfTPBI" +
|
||||
"E44nEccWJp0M0KynhKVbDI0v9VYm6sPFK7WrzRyWwHL~r735wiRkwywuMmKJtA7-PuJjcW" +
|
||||
"NLkJwx6WScH2msMzhzYPi8JSZJBl~PosX934l-L0T-KNV4jg1Ih6yoCnm1748A=="
|
||||
);
|
||||
private static final String ENCRYPTED[] = new String[] {
|
||||
"AMfISa8KvTpaC7KXZzSvC2axyiSk0xPexBAf29yU~IKq21DzaU19wQcGJg-ktpG4hjGSg7" +
|
||||
"u-mJ07b61yo-EGmVGZsv3nYuQYW-GjvsZQa9nm98VljlMtWrxu7TsRXw~SQlWQxMvthqJB" +
|
||||
"1A7Y7Qa~C7-UlRytkD-cpVdgUfM-esuMWmjGs6Vc33N5U-tce5Fywa-9y7PSn3ukBO8KGR" +
|
||||
"wm7T12~H2gvhgxrVeK2roOzsV7f5dGkvBQRZJ309Vg3j0kjaxWutgI3vli0pzDbSK9d5NR" +
|
||||
"-GUDtdOb6IIfLiOckBegcv6I-wlSXjYJe8mIoaK45Ok3rEpHwWKVKS2MeuI7AmsAWgkQmW" +
|
||||
"f8irmZaKc9X910VWSO5GYu6006hSc~r2TL3O7vwtW-Z9Oq~sAam9av1PPVJzAx8A4g~m~1" +
|
||||
"avtNnncwlChsGo6mZHXqz-QMdMJXXP57f4bx36ZomkvpM-ZLlFAn-a~42KQJAApo4LfEyk" +
|
||||
"7DPY2aTXL9ArOCNQIQB4f8QLyjvAvu6M3jzCoGo0wVX6oePfdiokGflriYOcD8rL4NbnCP" +
|
||||
"~MSnVzC8LKyRzQVN1tDYj8~njuFqekls6En8KFJ-qgtL4PiYxbnBQDUPoW6y61m-S9r9e9" +
|
||||
"y8qWd6~YtdAHAxVlw287~HEp9r7kqI-cjdo1337b7~5dm83KK45g5Nfw==",
|
||||
|
||||
"AIrd65mG1FJ~9J-DDSyhryVejJBSIjYOqV3GYmHDWgwLchTwq-bJS7dub3ENk9MZ-C6FIN" +
|
||||
"gjUFRaLBtfwJnySmNf8pIf1srmgdfqGV2h77ufG5Gs0jggKPmPV~7Z1kTcgsqpL8MyrfXr" +
|
||||
"Gi86X5ey-T0SZSFc0X1EhaE-47WlyWaGf-~xth6VOR~KG7clOxaOBpks-7WKZNQf7mpQRE" +
|
||||
"4IsPJyj5p1Rf-MeDbVKbK~52IfXSuUZQ8uZr34KMoy4chjn6e-jBhM4XuaQWhsM~a3Q-zE" +
|
||||
"pV-ea6t0bQTYfsbG9ch7pJuDPHM64o5mF9FS5-JGr7MOtfP7KDNHiYM2~-uC6BIAbiqBN8" +
|
||||
"WSLX1mrHVuhiM-hiJ7U4oq~HYB6N~U980sCIW0dgFBbhalzzQhJQSrC1DFDqGfL5-L25mj" +
|
||||
"ArP8dtvN0JY3LSnbcsm-pT9ttFHCPGomLfaAuP7ohknBoXK0j9e6~splg5sUA9TfLeBfqc" +
|
||||
"Lr0Sf8b3l~PvmrVkbVcaE8yUqSS6JFdt3pavjyyAQSmSlb2jVNKGPlrov5QLzlbH7G~AUv" +
|
||||
"IehsbGQX5ptRROtSojN~iYx3WQTOa-JLEC-AL7RbRu6B62p9I0pD0JgbUfCc4C4l9E9W~s" +
|
||||
"MuaJLAXxh0b2miF7C5bzZHxbt~MtZ7Ho5qpZMitXyoE3icb43B6Y1sbA==",
|
||||
|
||||
"ACjb0FkTIQbnEzCZlYXGxekznfJad5uW~F5Mbu~0wtsI1O2veqdr7Mb0N754xdIz7929Ti" +
|
||||
"1Kz-CxVEAkb3RBbVNcYHLfjy23oQ4BCioDKQaJcdkJqXa~Orm7Ta2tbkhM1Mx05MDrQaVF" +
|
||||
"gCVXtwTsPSLVK8VwScjPIFLXgQqqZ5osq~WhaMcYe2I2RCQLOx2VzaKbT21MMbtF70a-nK" +
|
||||
"WovkRUNfJEPeJosFwF2duAD0BHHrPiryK9BPDhyOiyN82ahOi2uim1Nt5yhlP3xo7cLV2p" +
|
||||
"6kTlR1BNC5pYjtsvetZf6wk-solNUrJWIzcuc18uRDNH5K90GTL6FXPMSulM~E4ATRQfhZ" +
|
||||
"fkW9xCrBIaIQM49ms2wONsp7fvI07b1r0rt7ZwCFOFit1HSAKl8UpsAYu-EsIO1qAK7vvO" +
|
||||
"UV~0OuBXkMZEyJT-uIVfbE~xrwPE0zPYE~parSVQgi~yNQBxukUM1smAM5xXVvJu8GjmE-" +
|
||||
"kJZw1cxaYLGsJjDHDk4HfEsyQVVPZ0V3bQvhB1tg5cCsTH~VNjts4taDTPWfDZmjtVaxxr" +
|
||||
"PRII4NEDKqEzg3JBevM~yft-RDfMc8RVlm-gCGANrRQORFii7uD3o9~y~4P2tLnO7Fy3m5" +
|
||||
"rdjRsOsWnCQZzw37mcBoT9rEZPrVpD8pjebJ1~HNc764xIpXDWVt8CbA==",
|
||||
|
||||
"AHDZBKiWeaIYQS9R1l70IlRnoplwKTkLP2dLlXmVh1gB33kx65uX8OMb3hdZEO0Bbzxkkx" +
|
||||
"quqlNn5w166nJO4nPbpEzVfgtY4ClUuv~W4H4CXBr0FcZM1COAkd6rtp6~lUp7cZ8FAkpH" +
|
||||
"spl95IxlFM-F1HwiPcbmTjRO1AwCal4sH8S5WmJCvBU6jH6pBPo~9B9vAtP7vX1EwsG2Jf" +
|
||||
"CQXkVkfvbWpSicbsWn77aECedS3HkIMrXrxojp7gAiPgQhX4NR387rcUPFsMHGeUraTUPZ" +
|
||||
"D7ctk5tpUuYYwRQc5cRKHa4zOq~AQyljx5w5~FByLda--6yCe7qDcILyTygudJ4AHRs1pJ" +
|
||||
"RU3uuRTHZx0XJQo~cPsoQ2piAOohITX9~yMCimCgv2EIhY3Z-mAgo8qQ4iMbItoE1cl93I" +
|
||||
"u2YV2n4wMq9laBx0shuKOJqO3rjRnszzCbqMuFAXfc3KgGDEaCpI7049s3i2yIcv4vT9uU" +
|
||||
"AlrM-dsrdw0JgJiFYl0JXh~TO0IyrcVcLpgZYgRhEvTAdkDNwTs-2GK4tzdPEd34os4a2c" +
|
||||
"DPL8joh3jhp~eGoRzrpcdRekxENdzheL4w3wD1fJ9W2-leil1FH6EPc3FSL6e~nqbw69gN" +
|
||||
"bsuXAMQ6CobukJdJEy37uKmEw4v6WPyfYMUUacchv1JoNfkHLpnAWifQ==",
|
||||
|
||||
"AGwvKAMJcPAliP-n7F0Rrj0JMRaFGjww~zvBjyzc~SPJrBF831cMqZFRmMHotgA7S5BrH2" +
|
||||
"6CL8okI2N-7as0F2l7OPx50dFEwSVSjqBjVV6SGRFC8oS-ii1FURMz2SCHSaj6kazAYq4s" +
|
||||
"DwyqR7vnUrOtPnZujHSU~a02jinyn-QOaHkxRiUp-Oo0jlZiU5xomXgLdkhtuz6725WUDj" +
|
||||
"3uVlMtIYfeKQsTdasujHe1oQhUmp58jfg5vgZ8g87cY8rn4p9DRwDBBuo6vi5on7T13sGx" +
|
||||
"tY9wz6HTpwzDhEqpNrj~h4JibElfi0Jo8ZllmNTO1ZCNpUQgASoTtyFLD5rk6cIAMK0R7A" +
|
||||
"7hjB0aelKM-V7AHkj-Fhrcm8xIgWhKaLn2wKbVNpAkllkiLALyfWJ9dhJ804RWQTMPE-GD" +
|
||||
"kBMIFOOJ9MhpEN533OBQDwUKcoxMjl0zOMNCLx8IdCE6cLtUDKJXLB0atnDpLkBer6FwXP" +
|
||||
"81EvKDYhtp1GsbiKvZDt8LSPJQnm2EdA3Pr9fpAisJ5Ocaxlfa6~uQCuqGA9nJ9n6w03u-" +
|
||||
"ZpSMhSh4zm2s1MqijmaJRc-QNKmN~u1hh3R2hwWNi7FoStMA87sutEBXMdFI8un7StHNSE" +
|
||||
"iCYwmmW2Nu3djkM-X8gGjSsdrphTU7uOXbwazmguobFGxI0JujYruM5Q==",
|
||||
|
||||
"ALFYtPSwEEW3eTO4hLw6PZNlBKoSIseQNBi034gq6FwYEZsJOAo-1VXcvMviKw2MCP9ZkH" +
|
||||
"lTNBfzc79ms2TU8kXxc7zwUc-l2HJLWh6dj2tIQLR8bbWM7U0iUx4XB1B-FEvdhbjz7dsu" +
|
||||
"6SBXVhxo2ulrk7Q7vX3kPrePhZZldcNZcS0t65DHYYwL~E~ROjQwOO4Cb~8FgiIUjb8CCN" +
|
||||
"w5zxJpBaEt7UvZffkVwj-EWTzFy3DIjWIRizxnsI~mUI-VspPE~xlmFX~TwPS9UbwJDpm8" +
|
||||
"-WzINFcehSzF3y9rzSMX-KbU8m4YZj07itZOiIbWgLeulTUB-UgwEkfJBG0xiSUAspZf2~" +
|
||||
"t~NthBlpcdrBLADXTJ7Jmkk4MIfysV~JpDB7IVg0v4WcUUwF3sYMmBCdPCwyYf0hTrl2Yb" +
|
||||
"L6kmm4u97WgQqf0TyzXtVZYwjct4LzZlyH591y6O6AQ4Fydqos9ABInzu-SbXq6S1Hi6vr" +
|
||||
"aNWU3mcy2myie32EEXtkX7P8eXWY35GCv9ThPEYHG5g1qKOk95ZCTYYwlpgeyaMKsnN3C~" +
|
||||
"x9TJA8K8T44v7vE6--Nw4Z4zjepwkIOht9iQsA6D6wRUQpeYX8bjIyYDPC7GUHq0WhXR6E" +
|
||||
"6Ojc9k8V5uh0SZ-rCQX6sccdk3JbyRhjGP4rSKr6MmvxVVsqBjcbpxsg=="
|
||||
};
|
||||
|
||||
protected void setUp() {
|
||||
_context = new I2PAppContext();
|
||||
Object o = YKGenerator.class;
|
||||
}
|
||||
|
||||
public void testBasicAES(){
|
||||
SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
|
||||
Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
|
||||
byte iv[] = new byte[16];
|
||||
System.arraycopy(h.getData(), 0, iv, 0, 16);
|
||||
|
||||
String msg = "Hello world01234012345678901234501234567890123450123456789012345";
|
||||
h = SHA256Generator.getInstance().calculateHash(msg.getBytes());
|
||||
|
||||
byte aesEncr[] = new byte[msg.getBytes().length];
|
||||
byte aesDecr[] = new byte[aesEncr.length];
|
||||
_context.aes().encrypt(msg.getBytes(), 0, aesEncr, 0, sessionKey, iv, aesEncr.length);
|
||||
_context.aes().decrypt(aesEncr, 0, aesDecr, 0, sessionKey, iv, aesEncr.length);
|
||||
h = SHA256Generator.getInstance().calculateHash(aesDecr);
|
||||
|
||||
assertEquals(msg, new String(aesDecr));
|
||||
}
|
||||
|
||||
public void testAES(){
|
||||
SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
|
||||
Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
|
||||
byte iv[] = new byte[16];
|
||||
System.arraycopy(h.getData(), 0, iv, 0, 16);
|
||||
|
||||
String msg = "Hello world";
|
||||
|
||||
byte encrypted[] = _context.elGamalAESEngine().encryptAESBlock(msg.getBytes(), sessionKey, iv, null, null, 64);
|
||||
Set foundTags = new HashSet();
|
||||
SessionKey foundKey = new SessionKey();
|
||||
byte decrypted[] = null;
|
||||
try{
|
||||
decrypted = _context.elGamalAESEngine().decryptAESBlock(encrypted, 0, encrypted.length, sessionKey, iv, null, foundTags, foundKey);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
assertNotNull(decrypted);
|
||||
String read = new String(decrypted);
|
||||
assertEquals(msg, read);
|
||||
}
|
||||
|
||||
public void testRoundTrip(){
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
|
||||
String msg = "Hello world";
|
||||
Set toBeDelivered = new HashSet();
|
||||
SessionKey key = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
if (key == null)
|
||||
key = _context.sessionKeyManager().createSession(pubKey);
|
||||
byte[] encrypted = _context.elGamalAESEngine().encrypt(msg.getBytes(), pubKey, key, 64);
|
||||
byte[] decrypted = null;
|
||||
try{
|
||||
decrypted = _context.elGamalAESEngine().decrypt(encrypted, privKey);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
assertNotNull(decrypted);
|
||||
String read = new String(decrypted);
|
||||
assertEquals(msg, read);
|
||||
}
|
||||
|
||||
public void testElGamal(){
|
||||
for (int i = 0; i < 2; i++) {
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
SessionKey key = KeyGenerator.getInstance().generateSessionKey();
|
||||
|
||||
ByteArrayOutputStream elgSrc = new ByteArrayOutputStream(256);
|
||||
try{
|
||||
key.writeBytes(elgSrc);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}catch(IOException ioe){
|
||||
ioe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
byte preIV[] = new byte[32];
|
||||
RandomSource.getInstance().nextBytes(preIV);
|
||||
try{
|
||||
elgSrc.write(preIV);
|
||||
elgSrc.flush();
|
||||
}catch(IOException ioe){
|
||||
ioe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
|
||||
byte elgEncr[] = _context.elGamalEngine().encrypt(elgSrc.toByteArray(), pubKey);
|
||||
byte elgDecr[] = _context.elGamalEngine().decrypt(elgEncr, privKey);
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(elgDecr);
|
||||
SessionKey nk = new SessionKey();
|
||||
|
||||
try{
|
||||
nk.readBytes(bais);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}catch(IOException ioe){
|
||||
ioe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
byte postpreIV[] = new byte[32];
|
||||
|
||||
int read = 0;
|
||||
try{
|
||||
read = bais.read(postpreIV);
|
||||
}catch(IOException ioe){
|
||||
ioe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
assertEquals(read, postpreIV.length);
|
||||
|
||||
|
||||
assertTrue(DataHelper.eq(preIV, postpreIV));
|
||||
assertEquals(key, nk);
|
||||
}
|
||||
}
|
||||
|
||||
public void testLoop(){
|
||||
for(int i = 0; i < 5; i++){
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
|
||||
byte[] msg = new byte[400];
|
||||
RandomSource.getInstance().nextBytes(msg);
|
||||
SessionKey key = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
if (key == null)
|
||||
key = _context.sessionKeyManager().createSession(pubKey);
|
||||
|
||||
byte[] encrypted = _context.elGamalAESEngine().encrypt(msg, pubKey, key, 1024);
|
||||
byte[] decrypted = null;
|
||||
try{
|
||||
decrypted = _context.elGamalAESEngine().decrypt(encrypted, privKey);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
assertTrue(DataHelper.eq(msg, decrypted));
|
||||
}
|
||||
}
|
||||
|
||||
public void testVerifySelf(){
|
||||
Object keypair[] = _context.keyGenerator().generatePKIKeypair();
|
||||
PublicKey pub = (PublicKey)keypair[0];
|
||||
PrivateKey priv = (PrivateKey)keypair[1];
|
||||
|
||||
for (int i = 0; i < UNENCRYPTED.length; i++) {
|
||||
byte orig[] = UNENCRYPTED[i].getBytes();
|
||||
|
||||
byte encrypted[] = _context.elGamalEngine().encrypt(orig, pub);
|
||||
byte decrypted[] = _context.elGamalEngine().decrypt(encrypted, priv);
|
||||
|
||||
assertTrue(DataHelper.eq(decrypted, orig));
|
||||
}
|
||||
}
|
||||
|
||||
public void testVerifyCompatability(){
|
||||
PublicKey pub = new PublicKey();
|
||||
PrivateKey priv = new PrivateKey();
|
||||
try{
|
||||
pub.fromBase64(PUBLIC_KEY);
|
||||
priv.fromBase64(PRIVATE_KEY);
|
||||
}catch(DataFormatException dfe){
|
||||
dfe.printStackTrace();
|
||||
fail();
|
||||
}
|
||||
|
||||
for (int i = 0; i < ENCRYPTED.length; i++) {
|
||||
byte enc[] = Base64.decode(ENCRYPTED[i]);
|
||||
byte decrypted[] = _context.elGamalEngine().decrypt(enc, priv);
|
||||
|
||||
assertTrue(DataHelper.eq(decrypted, UNENCRYPTED[i].getBytes()));
|
||||
}
|
||||
}
|
||||
|
||||
public void testMultiple(){
|
||||
Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
byte[] message = new byte[222];
|
||||
for (int x = 0; x < 25; x++) {
|
||||
_context.random().nextBytes(message);
|
||||
keys = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubkey = (PublicKey)keys[0];
|
||||
PrivateKey privkey = (PrivateKey)keys[1];
|
||||
|
||||
byte[] e = _context.elGamalEngine().encrypt(message, pubkey);
|
||||
byte[] d = _context.elGamalEngine().decrypt(e, privkey);
|
||||
|
||||
assertTrue(DataHelper.eq(d, message));
|
||||
}
|
||||
}
|
||||
|
||||
public void testElGamalAESEngine() throws Exception{
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
ElGamalAESEngine e = new ElGamalAESEngine(ctx);
|
||||
Object kp[] = ctx.keyGenerator().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)kp[0];
|
||||
PrivateKey privKey = (PrivateKey)kp[1];
|
||||
SessionKey sessionKey = ctx.keyGenerator().generateSessionKey();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Set tags = new HashSet(5);
|
||||
if (i == 0) {
|
||||
for (int j = 0; j < 5; j++)
|
||||
tags.add(new SessionTag(true));
|
||||
}
|
||||
byte encrypted[] = e.encrypt("blah".getBytes(), pubKey, sessionKey, tags, 1024);
|
||||
byte decrypted[] = e.decrypt(encrypted, privKey);
|
||||
assertEquals("blah", new String(decrypted));
|
||||
|
||||
ctx.sessionKeyManager().tagsDelivered(pubKey, sessionKey, tags);
|
||||
}
|
||||
}
|
||||
|
||||
public void testElGamalEngine(){
|
||||
int numRuns = 100;
|
||||
RandomSource.getInstance().nextBoolean();
|
||||
I2PAppContext context = new I2PAppContext();
|
||||
|
||||
for (int i = 0; i < numRuns; i++) {
|
||||
Object pair[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
|
||||
PublicKey pubkey = (PublicKey) pair[0];
|
||||
PrivateKey privkey = (PrivateKey) pair[1];
|
||||
byte buf[] = new byte[128];
|
||||
RandomSource.getInstance().nextBytes(buf);
|
||||
byte encr[] = context.elGamalEngine().encrypt(buf, pubkey);
|
||||
byte decr[] = context.elGamalEngine().decrypt(encr, privkey);
|
||||
|
||||
assertTrue(DataHelper.eq(decr, buf));
|
||||
}
|
||||
}
|
||||
|
||||
public void testYKGen(){
|
||||
RandomSource.getInstance().nextBoolean();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
YKGenerator.getNextYK();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,206 +0,0 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.PublicKey;
|
||||
|
||||
/**
|
||||
* Unit test verifying the ElGamal encryption/decryption with some test
|
||||
* data. The keys generated & data stored were generated by jrandom on
|
||||
* a pentium4 w/ an optimized jbigi installed and verified with pure java.
|
||||
*
|
||||
*/
|
||||
public class ElGamalVerify {
|
||||
private I2PAppContext _context;
|
||||
|
||||
private static final String UNENCRYPTED[] = new String[] {
|
||||
"",
|
||||
"hello world",
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"1234567890123456789012345678901234567890123456789012345678901234567890" +
|
||||
"123456789012",
|
||||
"\0x00",
|
||||
"\0x00\0x00\0x00",
|
||||
"\0x00\0x01\0x02\0x00",
|
||||
};
|
||||
private static final String PUBLIC_KEY = new String(
|
||||
"pOvBUMrSUUeN5awynzbPbCAwe3MqWprhSpp3OR7pvdfm9PhWaNbPoKRLeEmDoUwyNDoHE0" +
|
||||
"E6mcZSG8qPQ8XUZFlczpilOl0MJBvsI9u9SMyi~bEqzSgzh9FNfS-NcGji3q2wI~Ux~q5B" +
|
||||
"KOjGlyMLgd1nxl5R5wIYL4uHKZNaYuArsRYmtV~MgMQPGvDtIbdGTV6aL6UbOYryzQSUMY" +
|
||||
"OuO3S~YoBjA6Nmi0SeJM3tyTxlI6U1EYjR6oQcI4SOFUW4L~8pfYWijcncCODAqpXVN6ZI" +
|
||||
"AJ3a6vjxGu56IDp4xCcKlOEHgdXvqmEC67dR5qf2btH6dtWoB3-Z6QPsS6tPTQ=="
|
||||
);
|
||||
private static final String PRIVATE_KEY = new String(
|
||||
"gMlIhURVXU8uPube20Xr8E1K11g-3qZxOj1riThHqt-rBx72MPq5ivT1rr28cE9mzOmsXi" +
|
||||
"bbsuBuQKYDvF7hGICRB3ROSPePYhcupV3j7XiXUIYjWNw9hvylHXK~nTT7jkpIBazBJZfr" +
|
||||
"LJPcDZTDB0YnCOHOL-KFn4N1R5B22g0iYRABN~O10AUjQmf1epklAXPqYlzmOYeJSfTPBI" +
|
||||
"E44nEccWJp0M0KynhKVbDI0v9VYm6sPFK7WrzRyWwHL~r735wiRkwywuMmKJtA7-PuJjcW" +
|
||||
"NLkJwx6WScH2msMzhzYPi8JSZJBl~PosX934l-L0T-KNV4jg1Ih6yoCnm1748A=="
|
||||
);
|
||||
private static final String ENCRYPTED[] = new String[] {
|
||||
"AMfISa8KvTpaC7KXZzSvC2axyiSk0xPexBAf29yU~IKq21DzaU19wQcGJg-ktpG4hjGSg7" +
|
||||
"u-mJ07b61yo-EGmVGZsv3nYuQYW-GjvsZQa9nm98VljlMtWrxu7TsRXw~SQlWQxMvthqJB" +
|
||||
"1A7Y7Qa~C7-UlRytkD-cpVdgUfM-esuMWmjGs6Vc33N5U-tce5Fywa-9y7PSn3ukBO8KGR" +
|
||||
"wm7T12~H2gvhgxrVeK2roOzsV7f5dGkvBQRZJ309Vg3j0kjaxWutgI3vli0pzDbSK9d5NR" +
|
||||
"-GUDtdOb6IIfLiOckBegcv6I-wlSXjYJe8mIoaK45Ok3rEpHwWKVKS2MeuI7AmsAWgkQmW" +
|
||||
"f8irmZaKc9X910VWSO5GYu6006hSc~r2TL3O7vwtW-Z9Oq~sAam9av1PPVJzAx8A4g~m~1" +
|
||||
"avtNnncwlChsGo6mZHXqz-QMdMJXXP57f4bx36ZomkvpM-ZLlFAn-a~42KQJAApo4LfEyk" +
|
||||
"7DPY2aTXL9ArOCNQIQB4f8QLyjvAvu6M3jzCoGo0wVX6oePfdiokGflriYOcD8rL4NbnCP" +
|
||||
"~MSnVzC8LKyRzQVN1tDYj8~njuFqekls6En8KFJ-qgtL4PiYxbnBQDUPoW6y61m-S9r9e9" +
|
||||
"y8qWd6~YtdAHAxVlw287~HEp9r7kqI-cjdo1337b7~5dm83KK45g5Nfw==",
|
||||
|
||||
"AIrd65mG1FJ~9J-DDSyhryVejJBSIjYOqV3GYmHDWgwLchTwq-bJS7dub3ENk9MZ-C6FIN" +
|
||||
"gjUFRaLBtfwJnySmNf8pIf1srmgdfqGV2h77ufG5Gs0jggKPmPV~7Z1kTcgsqpL8MyrfXr" +
|
||||
"Gi86X5ey-T0SZSFc0X1EhaE-47WlyWaGf-~xth6VOR~KG7clOxaOBpks-7WKZNQf7mpQRE" +
|
||||
"4IsPJyj5p1Rf-MeDbVKbK~52IfXSuUZQ8uZr34KMoy4chjn6e-jBhM4XuaQWhsM~a3Q-zE" +
|
||||
"pV-ea6t0bQTYfsbG9ch7pJuDPHM64o5mF9FS5-JGr7MOtfP7KDNHiYM2~-uC6BIAbiqBN8" +
|
||||
"WSLX1mrHVuhiM-hiJ7U4oq~HYB6N~U980sCIW0dgFBbhalzzQhJQSrC1DFDqGfL5-L25mj" +
|
||||
"ArP8dtvN0JY3LSnbcsm-pT9ttFHCPGomLfaAuP7ohknBoXK0j9e6~splg5sUA9TfLeBfqc" +
|
||||
"Lr0Sf8b3l~PvmrVkbVcaE8yUqSS6JFdt3pavjyyAQSmSlb2jVNKGPlrov5QLzlbH7G~AUv" +
|
||||
"IehsbGQX5ptRROtSojN~iYx3WQTOa-JLEC-AL7RbRu6B62p9I0pD0JgbUfCc4C4l9E9W~s" +
|
||||
"MuaJLAXxh0b2miF7C5bzZHxbt~MtZ7Ho5qpZMitXyoE3icb43B6Y1sbA==",
|
||||
|
||||
"ACjb0FkTIQbnEzCZlYXGxekznfJad5uW~F5Mbu~0wtsI1O2veqdr7Mb0N754xdIz7929Ti" +
|
||||
"1Kz-CxVEAkb3RBbVNcYHLfjy23oQ4BCioDKQaJcdkJqXa~Orm7Ta2tbkhM1Mx05MDrQaVF" +
|
||||
"gCVXtwTsPSLVK8VwScjPIFLXgQqqZ5osq~WhaMcYe2I2RCQLOx2VzaKbT21MMbtF70a-nK" +
|
||||
"WovkRUNfJEPeJosFwF2duAD0BHHrPiryK9BPDhyOiyN82ahOi2uim1Nt5yhlP3xo7cLV2p" +
|
||||
"6kTlR1BNC5pYjtsvetZf6wk-solNUrJWIzcuc18uRDNH5K90GTL6FXPMSulM~E4ATRQfhZ" +
|
||||
"fkW9xCrBIaIQM49ms2wONsp7fvI07b1r0rt7ZwCFOFit1HSAKl8UpsAYu-EsIO1qAK7vvO" +
|
||||
"UV~0OuBXkMZEyJT-uIVfbE~xrwPE0zPYE~parSVQgi~yNQBxukUM1smAM5xXVvJu8GjmE-" +
|
||||
"kJZw1cxaYLGsJjDHDk4HfEsyQVVPZ0V3bQvhB1tg5cCsTH~VNjts4taDTPWfDZmjtVaxxr" +
|
||||
"PRII4NEDKqEzg3JBevM~yft-RDfMc8RVlm-gCGANrRQORFii7uD3o9~y~4P2tLnO7Fy3m5" +
|
||||
"rdjRsOsWnCQZzw37mcBoT9rEZPrVpD8pjebJ1~HNc764xIpXDWVt8CbA==",
|
||||
|
||||
"AHDZBKiWeaIYQS9R1l70IlRnoplwKTkLP2dLlXmVh1gB33kx65uX8OMb3hdZEO0Bbzxkkx" +
|
||||
"quqlNn5w166nJO4nPbpEzVfgtY4ClUuv~W4H4CXBr0FcZM1COAkd6rtp6~lUp7cZ8FAkpH" +
|
||||
"spl95IxlFM-F1HwiPcbmTjRO1AwCal4sH8S5WmJCvBU6jH6pBPo~9B9vAtP7vX1EwsG2Jf" +
|
||||
"CQXkVkfvbWpSicbsWn77aECedS3HkIMrXrxojp7gAiPgQhX4NR387rcUPFsMHGeUraTUPZ" +
|
||||
"D7ctk5tpUuYYwRQc5cRKHa4zOq~AQyljx5w5~FByLda--6yCe7qDcILyTygudJ4AHRs1pJ" +
|
||||
"RU3uuRTHZx0XJQo~cPsoQ2piAOohITX9~yMCimCgv2EIhY3Z-mAgo8qQ4iMbItoE1cl93I" +
|
||||
"u2YV2n4wMq9laBx0shuKOJqO3rjRnszzCbqMuFAXfc3KgGDEaCpI7049s3i2yIcv4vT9uU" +
|
||||
"AlrM-dsrdw0JgJiFYl0JXh~TO0IyrcVcLpgZYgRhEvTAdkDNwTs-2GK4tzdPEd34os4a2c" +
|
||||
"DPL8joh3jhp~eGoRzrpcdRekxENdzheL4w3wD1fJ9W2-leil1FH6EPc3FSL6e~nqbw69gN" +
|
||||
"bsuXAMQ6CobukJdJEy37uKmEw4v6WPyfYMUUacchv1JoNfkHLpnAWifQ==",
|
||||
|
||||
"AGwvKAMJcPAliP-n7F0Rrj0JMRaFGjww~zvBjyzc~SPJrBF831cMqZFRmMHotgA7S5BrH2" +
|
||||
"6CL8okI2N-7as0F2l7OPx50dFEwSVSjqBjVV6SGRFC8oS-ii1FURMz2SCHSaj6kazAYq4s" +
|
||||
"DwyqR7vnUrOtPnZujHSU~a02jinyn-QOaHkxRiUp-Oo0jlZiU5xomXgLdkhtuz6725WUDj" +
|
||||
"3uVlMtIYfeKQsTdasujHe1oQhUmp58jfg5vgZ8g87cY8rn4p9DRwDBBuo6vi5on7T13sGx" +
|
||||
"tY9wz6HTpwzDhEqpNrj~h4JibElfi0Jo8ZllmNTO1ZCNpUQgASoTtyFLD5rk6cIAMK0R7A" +
|
||||
"7hjB0aelKM-V7AHkj-Fhrcm8xIgWhKaLn2wKbVNpAkllkiLALyfWJ9dhJ804RWQTMPE-GD" +
|
||||
"kBMIFOOJ9MhpEN533OBQDwUKcoxMjl0zOMNCLx8IdCE6cLtUDKJXLB0atnDpLkBer6FwXP" +
|
||||
"81EvKDYhtp1GsbiKvZDt8LSPJQnm2EdA3Pr9fpAisJ5Ocaxlfa6~uQCuqGA9nJ9n6w03u-" +
|
||||
"ZpSMhSh4zm2s1MqijmaJRc-QNKmN~u1hh3R2hwWNi7FoStMA87sutEBXMdFI8un7StHNSE" +
|
||||
"iCYwmmW2Nu3djkM-X8gGjSsdrphTU7uOXbwazmguobFGxI0JujYruM5Q==",
|
||||
|
||||
"ALFYtPSwEEW3eTO4hLw6PZNlBKoSIseQNBi034gq6FwYEZsJOAo-1VXcvMviKw2MCP9ZkH" +
|
||||
"lTNBfzc79ms2TU8kXxc7zwUc-l2HJLWh6dj2tIQLR8bbWM7U0iUx4XB1B-FEvdhbjz7dsu" +
|
||||
"6SBXVhxo2ulrk7Q7vX3kPrePhZZldcNZcS0t65DHYYwL~E~ROjQwOO4Cb~8FgiIUjb8CCN" +
|
||||
"w5zxJpBaEt7UvZffkVwj-EWTzFy3DIjWIRizxnsI~mUI-VspPE~xlmFX~TwPS9UbwJDpm8" +
|
||||
"-WzINFcehSzF3y9rzSMX-KbU8m4YZj07itZOiIbWgLeulTUB-UgwEkfJBG0xiSUAspZf2~" +
|
||||
"t~NthBlpcdrBLADXTJ7Jmkk4MIfysV~JpDB7IVg0v4WcUUwF3sYMmBCdPCwyYf0hTrl2Yb" +
|
||||
"L6kmm4u97WgQqf0TyzXtVZYwjct4LzZlyH591y6O6AQ4Fydqos9ABInzu-SbXq6S1Hi6vr" +
|
||||
"aNWU3mcy2myie32EEXtkX7P8eXWY35GCv9ThPEYHG5g1qKOk95ZCTYYwlpgeyaMKsnN3C~" +
|
||||
"x9TJA8K8T44v7vE6--Nw4Z4zjepwkIOht9iQsA6D6wRUQpeYX8bjIyYDPC7GUHq0WhXR6E" +
|
||||
"6Ojc9k8V5uh0SZ-rCQX6sccdk3JbyRhjGP4rSKr6MmvxVVsqBjcbpxsg=="
|
||||
};
|
||||
|
||||
public static void main(String args[]) {
|
||||
ElGamalVerify verify = new ElGamalVerify();
|
||||
verify.verifySelf();
|
||||
verify.verifyCompatability();
|
||||
if (args.length > 0)
|
||||
verify.generateEncrypted();
|
||||
}
|
||||
|
||||
public ElGamalVerify() {
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
/** verify that we can decrypt what we encrypt */
|
||||
private void verifySelf() {
|
||||
try {
|
||||
Object keypair[] = _context.keyGenerator().generatePKIKeypair();
|
||||
PublicKey pub = (PublicKey)keypair[0];
|
||||
PrivateKey priv = (PrivateKey)keypair[1];
|
||||
|
||||
for (int i = 0; i < UNENCRYPTED.length; i++) {
|
||||
byte orig[] = UNENCRYPTED[i].getBytes();
|
||||
|
||||
byte encrypted[] = _context.elGamalEngine().encrypt(orig, pub);
|
||||
byte decrypted[] = _context.elGamalEngine().decrypt(encrypted, priv);
|
||||
|
||||
if (DataHelper.eq(decrypted, orig))
|
||||
log("OK : verifySelf[" + i + "] passed");
|
||||
else
|
||||
log("ERROR: verifySelf[" + i + "] failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log("ERROR: verifySelf blew up: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/** verify that we can decrypt what other people encrypt */
|
||||
private void verifyCompatability() {
|
||||
verifyDecrypt();
|
||||
}
|
||||
|
||||
private void verifyDecrypt() {
|
||||
try {
|
||||
PublicKey pub = new PublicKey();
|
||||
PrivateKey priv = new PrivateKey();
|
||||
pub.fromBase64(PUBLIC_KEY);
|
||||
priv.fromBase64(PRIVATE_KEY);
|
||||
|
||||
for (int i = 0; i < ENCRYPTED.length; i++) {
|
||||
byte enc[] = Base64.decode(ENCRYPTED[i]);
|
||||
byte decrypted[] = _context.elGamalEngine().decrypt(enc, priv);
|
||||
|
||||
if (DataHelper.eq(decrypted, UNENCRYPTED[i].getBytes()))
|
||||
log("OK : verifyDecrypt[" + i + "] passed");
|
||||
else
|
||||
log("ERROR: verifyDecrypt[" + i + "] failed");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log("ERROR: generateEncrypted blew up: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
private void generateEncrypted() {
|
||||
try {
|
||||
Object keypair[] = _context.keyGenerator().generatePKIKeypair();
|
||||
PublicKey pub = (PublicKey)keypair[0];
|
||||
PrivateKey priv = (PrivateKey)keypair[1];
|
||||
|
||||
log("PUBLIC : " + pub.toBase64());
|
||||
log("PRIVATE: " + priv.toBase64());
|
||||
|
||||
for (int i = 0; i < UNENCRYPTED.length; i++) {
|
||||
byte orig[] = UNENCRYPTED[i].getBytes();
|
||||
|
||||
byte encrypted[] = _context.elGamalEngine().encrypt(orig, pub);
|
||||
|
||||
System.out.println("Encrypted [" + i + "]: ");
|
||||
String enc = Base64.encode(encrypted);
|
||||
for (int j = 0; j < enc.length(); j++) {
|
||||
int remaining = enc.length() - j*70;
|
||||
if (remaining > 0) {
|
||||
String cur = enc.substring(j * 70, remaining > 70 ? (j+1)*70 : enc.length());
|
||||
System.out.println(cur);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log("ERROR: generateEncrypted blew up: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void log(String msg) {
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
|
35
core/java/test/net/i2p/crypto/HMACSHA256Test.java
Normal file
35
core/java/test/net/i2p/crypto/HMACSHA256Test.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.SessionKey;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class HMACSHA256Test extends TestCase{
|
||||
private I2PAppContext _context;
|
||||
|
||||
protected void setUp() {
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
public void testMultiple(){
|
||||
int size = 1;
|
||||
for(int i = 0; i < 24; i++){
|
||||
SessionKey key = _context.keyGenerator().generateSessionKey();
|
||||
|
||||
byte[] message = new byte[size];
|
||||
size*=2;
|
||||
_context.random().nextBytes(message);
|
||||
|
||||
_context.hmac().calculate(key, message);
|
||||
}
|
||||
}
|
||||
}
|
50
core/java/test/net/i2p/crypto/KeyGeneratorTest.java
Normal file
50
core/java/test/net/i2p/crypto/KeyGeneratorTest.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.util.RandomSource;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.PublicKey;
|
||||
import net.i2p.data.PrivateKey;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class KeyGeneratorTest extends TestCase{
|
||||
public void testKeyGen(){
|
||||
RandomSource.getInstance().nextBoolean();
|
||||
byte src[] = new byte[200];
|
||||
RandomSource.getInstance().nextBytes(src);
|
||||
|
||||
I2PAppContext ctx = new I2PAppContext();
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
byte ctext[] = ctx.elGamalEngine().encrypt(src, (PublicKey) keys[0]);
|
||||
byte ptext[] = ctx.elGamalEngine().decrypt(ctext, (PrivateKey) keys[1]);
|
||||
assertTrue(DataHelper.eq(ptext, src));
|
||||
}
|
||||
|
||||
Object obj[] = KeyGenerator.getInstance().generateSigningKeypair();
|
||||
SigningPublicKey fake = (SigningPublicKey) obj[0];
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Object keys[] = KeyGenerator.getInstance().generateSigningKeypair();
|
||||
|
||||
Signature sig = DSAEngine.getInstance().sign(src, (SigningPrivateKey) keys[1]);
|
||||
assertTrue(DSAEngine.getInstance().verifySignature(sig, src, (SigningPublicKey) keys[0]));
|
||||
assertFalse(DSAEngine.getInstance().verifySignature(sig, src, fake));
|
||||
}
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
KeyGenerator.getInstance().generateSessionKey();
|
||||
}
|
||||
}
|
||||
}
|
146
core/java/test/net/i2p/crypto/SHA1HashTest.java
Normal file
146
core/java/test/net/i2p/crypto/SHA1HashTest.java
Normal file
@@ -0,0 +1,146 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
/* @(#)SHA1Test.java 1.10 2004-04-24
|
||||
* This file was freely contributed to the LimeWire project and is covered
|
||||
* by its existing GPL licence, but it may be used individually as a public
|
||||
* domain implementation of a published algorithm (see below for references).
|
||||
* It was also freely contributed to the Bitzi public domain sources.
|
||||
* @author Philippe Verdy
|
||||
*/
|
||||
|
||||
/* Sun may wish to change the following package name, if integrating this
|
||||
* class in the Sun JCE Security Provider for Java 1.5 (code-named Tiger).
|
||||
*/
|
||||
//package com.bitzi.util;
|
||||
|
||||
import java.security.*;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public class SHA1HashTest extends TestCase{
|
||||
|
||||
private final SHA1 hash = new SHA1();
|
||||
|
||||
public void testSHA1() throws Exception{
|
||||
tst(1, 1,"abc","A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D");
|
||||
|
||||
tst(1, 2,"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
"84983E44 1C3BD26e BAAE4AA1 F95129E5 E54670F1");
|
||||
tst(1, 3, 1000000, "a",
|
||||
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F");
|
||||
|
||||
tst(2, 2, new byte[] {/* 8 bits, i.e. 1 byte */
|
||||
(byte)0x5e},
|
||||
"5e6f80a3 4a9798ca fc6a5db9 6cc57ba4 c4db59c2");
|
||||
tst(2, 4, new byte[] {/* 128 bits, i.e. 16 bytes */
|
||||
(byte)0x9a,(byte)0x7d,(byte)0xfd,(byte)0xf1,(byte)0xec,(byte)0xea,(byte)0xd0,(byte)0x6e,
|
||||
(byte)0xd6,(byte)0x46,(byte)0xaa,(byte)0x55,(byte)0xfe,(byte)0x75,(byte)0x71,(byte)0x46},
|
||||
"82abff66 05dbe1c1 7def12a3 94fa22a8 2b544a35");
|
||||
|
||||
tst(3, 2, new byte[] {/* 1304 bits, i.e. 163 bytes */
|
||||
(byte)0xf7,(byte)0x8f,(byte)0x92,(byte)0x14,(byte)0x1b,(byte)0xcd,(byte)0x17,(byte)0x0a,
|
||||
(byte)0xe8,(byte)0x9b,(byte)0x4f,(byte)0xba,(byte)0x15,(byte)0xa1,(byte)0xd5,(byte)0x9f,
|
||||
(byte)0x3f,(byte)0xd8,(byte)0x4d,(byte)0x22,(byte)0x3c,(byte)0x92,(byte)0x51,(byte)0xbd,
|
||||
(byte)0xac,(byte)0xbb,(byte)0xae,(byte)0x61,(byte)0xd0,(byte)0x5e,(byte)0xd1,(byte)0x15,
|
||||
(byte)0xa0,(byte)0x6a,(byte)0x7c,(byte)0xe1,(byte)0x17,(byte)0xb7,(byte)0xbe,(byte)0xea,
|
||||
(byte)0xd2,(byte)0x44,(byte)0x21,(byte)0xde,(byte)0xd9,(byte)0xc3,(byte)0x25,(byte)0x92,
|
||||
(byte)0xbd,(byte)0x57,(byte)0xed,(byte)0xea,(byte)0xe3,(byte)0x9c,(byte)0x39,(byte)0xfa,
|
||||
(byte)0x1f,(byte)0xe8,(byte)0x94,(byte)0x6a,(byte)0x84,(byte)0xd0,(byte)0xcf,(byte)0x1f,
|
||||
(byte)0x7b,(byte)0xee,(byte)0xad,(byte)0x17,(byte)0x13,(byte)0xe2,(byte)0xe0,(byte)0x95,
|
||||
(byte)0x98,(byte)0x97,(byte)0x34,(byte)0x7f,(byte)0x67,(byte)0xc8,(byte)0x0b,(byte)0x04,
|
||||
(byte)0x00,(byte)0xc2,(byte)0x09,(byte)0x81,(byte)0x5d,(byte)0x6b,(byte)0x10,(byte)0xa6,
|
||||
(byte)0x83,(byte)0x83,(byte)0x6f,(byte)0xd5,(byte)0x56,(byte)0x2a,(byte)0x56,(byte)0xca,
|
||||
(byte)0xb1,(byte)0xa2,(byte)0x8e,(byte)0x81,(byte)0xb6,(byte)0x57,(byte)0x66,(byte)0x54,
|
||||
(byte)0x63,(byte)0x1c,(byte)0xf1,(byte)0x65,(byte)0x66,(byte)0xb8,(byte)0x6e,(byte)0x3b,
|
||||
(byte)0x33,(byte)0xa1,(byte)0x08,(byte)0xb0,(byte)0x53,(byte)0x07,(byte)0xc0,(byte)0x0a,
|
||||
(byte)0xff,(byte)0x14,(byte)0xa7,(byte)0x68,(byte)0xed,(byte)0x73,(byte)0x50,(byte)0x60,
|
||||
(byte)0x6a,(byte)0x0f,(byte)0x85,(byte)0xe6,(byte)0xa9,(byte)0x1d,(byte)0x39,(byte)0x6f,
|
||||
(byte)0x5b,(byte)0x5c,(byte)0xbe,(byte)0x57,(byte)0x7f,(byte)0x9b,(byte)0x38,(byte)0x80,
|
||||
(byte)0x7c,(byte)0x7d,(byte)0x52,(byte)0x3d,(byte)0x6d,(byte)0x79,(byte)0x2f,(byte)0x6e,
|
||||
(byte)0xbc,(byte)0x24,(byte)0xa4,(byte)0xec,(byte)0xf2,(byte)0xb3,(byte)0xa4,(byte)0x27,
|
||||
(byte)0xcd,(byte)0xbb,(byte)0xfb},
|
||||
"cb0082c8 f197d260 991ba6a4 60e76e20 2bad27b3");
|
||||
|
||||
{
|
||||
final int RETRIES = 10;
|
||||
final int ITERATIONS = 2000;
|
||||
final int BLOCKSIZE = 65536;
|
||||
byte[] input = new byte[BLOCKSIZE];
|
||||
for (int i = BLOCKSIZE; --i >= 0; )
|
||||
input[i] = (byte)i;
|
||||
|
||||
|
||||
|
||||
for (int retry = 0; retry < RETRIES; retry++) {
|
||||
for (int i = ITERATIONS; --i >= 0; );
|
||||
for (int i = ITERATIONS; --i >= 0; )
|
||||
hash.engineUpdate(input, 0, BLOCKSIZE);
|
||||
}
|
||||
hash.engineReset();
|
||||
|
||||
|
||||
MessageDigest md = MessageDigest.getInstance("SHA");
|
||||
for (int retry = 0; retry < RETRIES; retry++) {
|
||||
for (int i = ITERATIONS; --i >= 0; );
|
||||
for (int i = ITERATIONS; --i >= 0; )
|
||||
md.update(input, 0, BLOCKSIZE);
|
||||
}
|
||||
md.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private final void tst(final int set, final int vector,
|
||||
final String source,
|
||||
final String expect) {
|
||||
byte[] input = new byte[source.length()];
|
||||
for (int i = 0; i < input.length; i++)
|
||||
input[i] = (byte)source.charAt(i);
|
||||
tst(set, vector, input, expect);
|
||||
}
|
||||
|
||||
private final void tst(final int set, final int vector,
|
||||
final byte[] input,
|
||||
final String expect) {
|
||||
|
||||
hash.engineUpdate(input, 0, input.length);
|
||||
tstResult(expect);
|
||||
}
|
||||
|
||||
private final void tst(final int set, final int vector,
|
||||
final int times, final String source,
|
||||
final String expect) {
|
||||
byte[] input = new byte[source.length()];
|
||||
for (int i = 0; i < input.length; i++)
|
||||
input[i] = (byte)source.charAt(i);
|
||||
for (int i = 0; i < times; i++)
|
||||
hash.engineUpdate(input, 0, input.length);
|
||||
tstResult(expect);
|
||||
}
|
||||
|
||||
private final void tstResult(String expect) {
|
||||
final String result = toHex(hash.engineDigest());
|
||||
expect = expect.toUpperCase();
|
||||
assertEquals(expect, result);
|
||||
|
||||
}
|
||||
|
||||
private final String toHex(final byte[] bytes) {
|
||||
StringBuffer buf = new StringBuffer(bytes.length * 2);
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if ((i & 3) == 0 && i != 0)
|
||||
buf.append(' ');
|
||||
buf.append(HEX.charAt((bytes[i] >> 4) & 0xF))
|
||||
.append(HEX.charAt( bytes[i] & 0xF));
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
private static final String HEX = "0123456789ABCDEF";
|
||||
}
|
100
core/java/test/net/i2p/crypto/SHA256Test.java
Normal file
100
core/java/test/net/i2p/crypto/SHA256Test.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package net.i2p.crypto;
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* Written by jrandom in 2003 and released into the public domain
|
||||
* with no warranty of any kind, either expressed or implied.
|
||||
* It probably won't make your computer catch on fire, or eat
|
||||
* your children, but it might. Use at your own risk.
|
||||
*
|
||||
*/
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
|
||||
import org.bouncycastle.crypto.digests.SHA256Digest;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
/**
|
||||
* @author Comwiz
|
||||
*/
|
||||
public class SHA256Test extends TestCase{
|
||||
private I2PAppContext _context;
|
||||
|
||||
protected void setUp() {
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
public void testMultiple(){
|
||||
int size = 1;
|
||||
for(int i = 0; i < 24; i++){
|
||||
byte[] message = new byte[size];
|
||||
size*=2;
|
||||
_context.random().nextBytes(message);
|
||||
|
||||
SHA256Generator.getInstance().calculateHash(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void testCopyConstructor(){
|
||||
SHA256Digest orig = new SHA256Digest();
|
||||
byte[] message = "update this!".getBytes();
|
||||
orig.update(message, 0, message.length);
|
||||
|
||||
SHA256Digest copy = new SHA256Digest(orig);
|
||||
|
||||
byte[] origData = new byte[32];
|
||||
orig.doFinal(origData, 0);
|
||||
byte[] copyData = new byte[32];
|
||||
copy.doFinal(copyData, 0);
|
||||
|
||||
assertTrue(DataHelper.eq(origData, copyData));
|
||||
|
||||
}
|
||||
|
||||
public void testCheckName(){
|
||||
SHA256Digest digest = new SHA256Digest();
|
||||
assertEquals("SHA-256", digest.getAlgorithmName());
|
||||
}
|
||||
|
||||
public void testManualUpdate(){
|
||||
byte[] data = "deathnotronic".getBytes();
|
||||
|
||||
SHA256Digest one = new SHA256Digest();
|
||||
for(int i = 0; i < data.length; i++){
|
||||
one.update(data[i]);
|
||||
}
|
||||
|
||||
SHA256Digest two = new SHA256Digest();
|
||||
two.update(data[0]);
|
||||
two.update(data, 1, data.length-1);
|
||||
|
||||
byte[] oneData = new byte[32];
|
||||
one.doFinal(oneData, 0);
|
||||
byte[] twoData = new byte[32];
|
||||
two.doFinal(twoData, 0);
|
||||
|
||||
assertTrue(DataHelper.eq(oneData, twoData));
|
||||
}
|
||||
|
||||
public void test14Words(){
|
||||
byte message[] = new byte[56];
|
||||
_context.random().nextBytes(message);
|
||||
SHA256Digest orig = new SHA256Digest();
|
||||
orig.update(message, 0, message.length);
|
||||
orig.doFinal(new byte[32], 0);
|
||||
}
|
||||
|
||||
public void testSHA(){
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
byte orig[] = new byte[4096];
|
||||
ctx.random().nextBytes(orig);
|
||||
Hash old = ctx.sha().calculateHash(orig);
|
||||
SHA256Digest d = new SHA256Digest();
|
||||
d.update(orig, 0, orig.length);
|
||||
byte out[] = new byte[Hash.HASH_LENGTH];
|
||||
d.doFinal(out, 0);
|
||||
assertTrue(DataHelper.eq(out, old.getData()));
|
||||
}
|
||||
|
||||
}
|
@@ -13,6 +13,7 @@ import net.i2p.data.PrivateKey;
|
||||
import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.SessionTag;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.DataFormatException;
|
||||
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Clock;
|
||||
@@ -21,72 +22,49 @@ import net.i2p.I2PAppContext;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
*
|
||||
* session key management unit tests:
|
||||
*
|
||||
* Run tagsIncluded useTag rekey
|
||||
* // no sessions
|
||||
* 1 no no no
|
||||
* 2 no no no
|
||||
* // session
|
||||
* 3 yes (2) no no
|
||||
* 4 no yes no
|
||||
* 5 yes (2) yes no
|
||||
* 6 no yes no
|
||||
* 7 no yes no
|
||||
* // rekeying
|
||||
* 8 yes (2) no no
|
||||
* 9 no yes no
|
||||
* 10 yes (2) yes yes
|
||||
* 11 no yes no
|
||||
* 12 no yes no
|
||||
* // long session
|
||||
* 13-1000 20 tags every 10 messages, rekey every 50
|
||||
*/
|
||||
public class SessionEncryptionTest {
|
||||
private final static Log _log = new Log(SessionEncryptionTest.class);
|
||||
public class SessionEncryptionTest extends TestCase{
|
||||
private static I2PAppContext _context = new I2PAppContext();
|
||||
public static void main(String args[]) {
|
||||
SessionEncryptionTest test = new SessionEncryptionTest();
|
||||
try {
|
||||
//test.testNoSessions();
|
||||
//test.testSessions();
|
||||
//test.testRekeying();
|
||||
test.testLongSession();
|
||||
} catch (Throwable t) {
|
||||
_log.error("Error running tests", t);
|
||||
}
|
||||
try { Thread.sleep(60*1000); } catch (InterruptedException ie) {}
|
||||
|
||||
protected void setUp(){
|
||||
_context = new I2PAppContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run tagsIncluded useTag rekey
|
||||
* 1 no no no
|
||||
* 2 no no no
|
||||
*/
|
||||
public void testNoSessions() throws Exception {
|
||||
protected void tearDown() {
|
||||
System.gc();
|
||||
}
|
||||
|
||||
|
||||
public void testNoSessions1() throws Exception{
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
SessionKey curKey = _context.sessionKeyManager().createSession(pubKey);
|
||||
|
||||
byte[] msg1 = "msg 1".getBytes();
|
||||
byte[] msg2 = "msg 2".getBytes();
|
||||
byte[] msg = "msg 1".getBytes();
|
||||
|
||||
byte emsg1[] = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, 64);
|
||||
byte dmsg1[] = _context.elGamalAESEngine().decrypt(emsg1, privKey);
|
||||
if (DataHelper.eq(dmsg1, msg1))
|
||||
_log.info("PASSED: No sessions msg 1");
|
||||
else
|
||||
_log.error("FAILED: No sessions msg 1");
|
||||
byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, 64);
|
||||
byte dmsg[] = _context.elGamalAESEngine().decrypt(emsg, privKey);
|
||||
assertTrue(DataHelper.eq(dmsg, msg));
|
||||
}
|
||||
|
||||
public void testNoSessions2() throws Exception{
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
SessionKey curKey = _context.sessionKeyManager().createSession(pubKey);
|
||||
|
||||
byte emsg2[] = _context.elGamalAESEngine().encrypt(msg2, pubKey, curKey, 64);
|
||||
byte dmsg2[] = _context.elGamalAESEngine().decrypt(emsg2, privKey);
|
||||
if (DataHelper.eq(dmsg2, msg2))
|
||||
_log.info("PASSED: No sessions msg 2");
|
||||
else
|
||||
_log.error("FAILED: No sessions msg 2");
|
||||
byte[] msg = "msg 2".getBytes();
|
||||
|
||||
byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, 64);
|
||||
byte dmsg[] = _context.elGamalAESEngine().decrypt(emsg, privKey);
|
||||
assertTrue(DataHelper.eq(dmsg, msg));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +75,7 @@ public class SessionEncryptionTest {
|
||||
* 4 no yes no
|
||||
* 5 no yes no
|
||||
*/
|
||||
public void testSessions() throws Exception {
|
||||
public void testSessions() throws Exception{
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
@@ -123,96 +101,66 @@ public class SessionEncryptionTest {
|
||||
byte[] msg5 = "msg 5".getBytes();
|
||||
|
||||
byte emsg1[] = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, 64);
|
||||
|
||||
byte dmsg1[] = _context.elGamalAESEngine().decrypt(emsg1, privKey);
|
||||
if (DataHelper.eq(dmsg1, msg1))
|
||||
_log.info("PASSED: Sessions msg 1");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 1");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg1, msg1));
|
||||
|
||||
|
||||
|
||||
_context.sessionKeyManager().tagsDelivered(pubKey, curKey, firstTags);
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
SessionTag curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 2");
|
||||
return;
|
||||
}
|
||||
|
||||
assertNotNull(curTag);
|
||||
|
||||
byte emsg2[] = _context.elGamalAESEngine().encrypt(msg2, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg2[] = _context.elGamalAESEngine().decrypt(emsg2, privKey);
|
||||
if (DataHelper.eq(dmsg2, msg2))
|
||||
_log.info("PASSED: Sessions msg 2");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 2");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg2, msg2));
|
||||
|
||||
|
||||
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 3");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 3");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg3[] = _context.elGamalAESEngine().encrypt(msg3, pubKey, curKey, secondTags, curTag, 64);
|
||||
|
||||
byte dmsg3[] = _context.elGamalAESEngine().decrypt(emsg3, privKey);
|
||||
if (DataHelper.eq(dmsg3, msg3))
|
||||
_log.info("PASSED: Sessions msg 3");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 3");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg3, msg3));
|
||||
|
||||
|
||||
|
||||
_context.sessionKeyManager().tagsDelivered(pubKey, curKey, secondTags);
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 4");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 4");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg4[] = _context.elGamalAESEngine().encrypt(msg4, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg4[] = _context.elGamalAESEngine().decrypt(emsg4, privKey);
|
||||
if (DataHelper.eq(dmsg4, msg4))
|
||||
_log.info("PASSED: Sessions msg 4");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 4");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg4, msg4));
|
||||
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 5");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 5");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg5[] = _context.elGamalAESEngine().encrypt(msg5, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg5[] = _context.elGamalAESEngine().decrypt(emsg5, privKey);
|
||||
if (DataHelper.eq(dmsg5, msg5))
|
||||
_log.info("PASSED: Sessions msg 5");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 5");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg5, msg5));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,7 +171,7 @@ public class SessionEncryptionTest {
|
||||
* 4 no yes no
|
||||
* 5 no yes no
|
||||
*/
|
||||
public void testRekeying() throws Exception {
|
||||
public void testRekeying() throws Exception{
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
@@ -250,119 +198,80 @@ public class SessionEncryptionTest {
|
||||
byte[] msg5 = "msg 5".getBytes();
|
||||
|
||||
byte emsg1[] = _context.elGamalAESEngine().encrypt(msg1, pubKey, curKey, firstTags, 64);
|
||||
|
||||
byte dmsg1[] = _context.elGamalAESEngine().decrypt(emsg1, privKey);
|
||||
if (DataHelper.eq(dmsg1, msg1))
|
||||
_log.info("PASSED: Sessions msg 1");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 1");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg1, msg1));
|
||||
|
||||
|
||||
|
||||
_context.sessionKeyManager().tagsDelivered(pubKey, curKey, firstTags);
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
SessionTag curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 2");
|
||||
return;
|
||||
}
|
||||
|
||||
assertNotNull(curTag);
|
||||
|
||||
byte emsg2[] = _context.elGamalAESEngine().encrypt(msg2, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg2[] = _context.elGamalAESEngine().decrypt(emsg2, privKey);
|
||||
if (DataHelper.eq(dmsg2, msg2))
|
||||
_log.info("PASSED: Sessions msg 2");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 2");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg2, msg2));
|
||||
|
||||
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 3");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 3");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg3[] = _context.elGamalAESEngine().encrypt(msg3, pubKey, curKey, secondTags, curTag, nextKey, 64);
|
||||
|
||||
byte dmsg3[] = _context.elGamalAESEngine().decrypt(emsg3, privKey);
|
||||
if (DataHelper.eq(dmsg3, msg3))
|
||||
_log.info("PASSED: Sessions msg 3");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 3");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg3, msg3));
|
||||
|
||||
|
||||
|
||||
_context.sessionKeyManager().tagsDelivered(pubKey, nextKey, secondTags); // note nextKey not curKey
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 4");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 4");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg4[] = _context.elGamalAESEngine().encrypt(msg4, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg4[] = _context.elGamalAESEngine().decrypt(emsg4, privKey);
|
||||
if (DataHelper.eq(dmsg4, msg4))
|
||||
_log.info("PASSED: Sessions msg 4");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 4");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg4, msg4));
|
||||
|
||||
|
||||
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
curTag = _context.sessionKeyManager().consumeNextAvailableTag(pubKey, curKey);
|
||||
|
||||
if (curTag == null) {
|
||||
_log.error("Not able to consume next tag for message 5");
|
||||
return;
|
||||
}
|
||||
if (curKey == null) {
|
||||
_log.error("Not able to consume next KEY for message 5");
|
||||
return;
|
||||
}
|
||||
assertNotNull(curTag);
|
||||
assertNotNull(curKey);
|
||||
|
||||
byte emsg5[] = _context.elGamalAESEngine().encrypt(msg5, pubKey, curKey, null, curTag, 64);
|
||||
|
||||
byte dmsg5[] = _context.elGamalAESEngine().decrypt(emsg5, privKey);
|
||||
if (DataHelper.eq(dmsg5, msg5))
|
||||
_log.info("PASSED: Sessions msg 5");
|
||||
else {
|
||||
_log.error("FAILED: Sessions msg 5");
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg5, msg5));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 20 tags every 10 messages, rekey every 50
|
||||
*/
|
||||
public void testLongSession() throws Exception {
|
||||
int num = 1000;
|
||||
long start = Clock.getInstance().now();
|
||||
testLongSession(num);
|
||||
long end = Clock.getInstance().now();
|
||||
long time = end - start;
|
||||
float msEach = (float)num / time;
|
||||
_log.error("Test long session duration: " + num + " messages in " + time + "ms (or " + msEach + "ms each)");
|
||||
}
|
||||
|
||||
public void testLongSession(int numMsgs) throws Exception {
|
||||
public void testLongSession() throws Exception{
|
||||
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
|
||||
PublicKey pubKey = (PublicKey)keys[0];
|
||||
PrivateKey privKey = (PrivateKey)keys[1];
|
||||
SessionKey curKey = _context.sessionKeyManager().createSession(pubKey);
|
||||
|
||||
for (int i = 0; i < numMsgs; i++) {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
Set tags = null;
|
||||
SessionKey nextKey = null;
|
||||
curKey = _context.sessionKeyManager().getCurrentKey(pubKey);
|
||||
@@ -371,23 +280,16 @@ public class SessionEncryptionTest {
|
||||
int availTags = _context.sessionKeyManager().getAvailableTags(pubKey, curKey);
|
||||
if ((availTags < 1)) {
|
||||
tags = generateNewTags(50);
|
||||
_log.info("Generating new tags");
|
||||
} else {
|
||||
_log.info("Tags already available: " + availTags + " curTag: " + curTag);
|
||||
}
|
||||
}
|
||||
if (i % 50 == 0)
|
||||
nextKey = KeyGenerator.getInstance().generateSessionKey();
|
||||
|
||||
byte[] msg = ("msg " + i).getBytes();
|
||||
|
||||
byte emsg[] = _context.elGamalAESEngine().encrypt(msg, pubKey, curKey, tags, curTag, nextKey, 64);
|
||||
|
||||
byte dmsg[] = _context.elGamalAESEngine().decrypt(emsg, privKey);
|
||||
if (DataHelper.eq(dmsg, msg))
|
||||
_log.info("PASSED: Long session msg " + i);
|
||||
else {
|
||||
_log.error("FAILED: Long session msg " + i);
|
||||
return;
|
||||
}
|
||||
assertTrue(DataHelper.eq(dmsg, msg));
|
||||
|
||||
if ( (tags != null) && (tags.size() > 0) ) {
|
||||
if (nextKey == null) {
|
||||
|
Reference in New Issue
Block a user