great renaming (cont.)

This commit is contained in:
jrandom
2004-04-08 04:54:58 +00:00
committed by zzz
parent e40b94c875
commit 2e3fd0abf2
48 changed files with 2864 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
package net.i2p.crypto;
/*
* Copyright (c) 2003, TheCrypto
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the TheCrypto may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import net.i2p.data.SessionKey;
import net.i2p.data.DataHelper;
public class AES256Bench {
public static void main(String args[]) {
char[] cplain = {
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
};
byte[] plain = new byte[cplain.length];
for (int x = 0; x < cplain.length; x++) {
plain[x] = (byte)cplain[x];
}
char[] ckey = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
};
byte[] bkey = new byte[ckey.length];
for (int x = 0; x < ckey.length; x++) {
bkey[x] = (byte)ckey[x];
}
SessionKey key = new SessionKey();
key.setData(bkey);
char[] civ = {
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0xfe, 0xdc, 0xba, 0x98, 0x67, 0x54, 0x32, 0x10
};
byte[] iv = new byte[civ.length];
for (int x = 0; x < iv.length; x++) {
iv[x] = (byte)civ[x];
}
byte[] e = AESEngine.getInstance().encrypt(plain, key, iv);
byte[] d = AESEngine.getInstance().decrypt(e, key, iv);
boolean same = true;
for (int x = 0; x < d.length; x++) {
if (plain[x] != d[x]) {
same = false;
}
}
System.out.println("Standard test D(E(value)) == value? " + same);
plain = "1234567890123456".getBytes();
e = AESEngine.getInstance().encrypt(plain, key, iv);
d = AESEngine.getInstance().decrypt(e, key, iv);
same = DataHelper.eq(plain, d);
System.out.println("Different value test D(E(value)) == value? " + same);
System.out.println();
System.out.println();
long times = 100;
long encrypttime = 0;
long decrypttime = 0;
long maxE = 0;
long minE = 0;
long maxD = 0;
long minD = 0;
byte[] message = new byte[2*1024];
for (int i = 0; i < message.length; i++)
message[i] = (byte)((i%26)+'a');
for (int x = 0; x < times; x++) {
long startencrypt = System.currentTimeMillis();
e = AESEngine.getInstance().encrypt(message, key, iv);
long endencryptstartdecrypt = System.currentTimeMillis();
d = AESEngine.getInstance().decrypt(e, key, iv);
long enddecrypt = System.currentTimeMillis();
System.out.print(".");
encrypttime += endencryptstartdecrypt - startencrypt;
decrypttime += enddecrypt - endencryptstartdecrypt;
if (!DataHelper.eq(d, message)) {
System.out.println("Lengths: source [" + message.length + "] dest [" + d.length + "]");
System.out.println("Data: dest [" + DataHelper.toString(d, d.length) + "]");
throw new RuntimeException("Holy crap, decrypted != source message");
}
if ( (minE == 0) && (minD == 0) ) {
minE = endencryptstartdecrypt - startencrypt;
maxE = endencryptstartdecrypt - startencrypt;
minD = enddecrypt - endencryptstartdecrypt;
maxD = enddecrypt - endencryptstartdecrypt;
} else {
if (minE > endencryptstartdecrypt - startencrypt) minE = endencryptstartdecrypt - startencrypt;
if (maxE < endencryptstartdecrypt - startencrypt) maxE = endencryptstartdecrypt - startencrypt;
if (minD > enddecrypt - endencryptstartdecrypt) minD = enddecrypt - endencryptstartdecrypt;
if (maxD < enddecrypt - endencryptstartdecrypt) maxD = enddecrypt - endencryptstartdecrypt;
}
}
System.out.println();
System.out.println("Data size : " + message.length);
System.out.println("Encryption Time Average : " + (encrypttime/times) + "ms\ttotal: " + encrypttime + "ms\tmin: " + minE + "ms\tmax: " + maxE + "ms\tEncryption Bps: " + (times*message.length*1000)/encrypttime);
System.out.println("Decryption Time Average : " + (decrypttime/times) + "ms\ttotal: " + decrypttime + "ms\tmin: " + minD + "ms\tmax: " + maxD + "ms\tDecryption Bps: " + (times*message.length*1000)/decrypttime);
}
}

View File

@@ -0,0 +1,92 @@
package net.i2p.crypto;
/*
* Copyright (c) 2003, TheCrypto
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the TheCrypto may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
public class DSABench {
public static void main(String args[]) {
int times = 100;
long keygentime = 0;
long signtime = 0;
long verifytime = 0;
long maxKey = 0;
long minKey = 0;
long maxS = 0;
long minS = 0;
long maxV = 0;
long minV = 0;
Object[] keys = KeyGenerator.getInstance().generateSigningKeypair();
byte[] message = new byte[32+32];
for (int i = 0; i < message.length; i++)
message[i] = (byte)((i%26)+'a');
for (int x = 0; x < times; x++) {
long startkeys = System.currentTimeMillis();
keys = KeyGenerator.getInstance().generateSigningKeypair();
SigningPublicKey pubkey = (SigningPublicKey)keys[0];
SigningPrivateKey privkey = (SigningPrivateKey)keys[1];
long endkeys = System.currentTimeMillis();
long startsign = System.currentTimeMillis();
Signature s = DSAEngine.getInstance().sign(message, privkey);
long endsignstartverify = System.currentTimeMillis();
boolean v = DSAEngine.getInstance().verifySignature(s, message, pubkey);
long endverify = System.currentTimeMillis();
System.out.print(".");
keygentime += endkeys - startkeys;
signtime += endsignstartverify - startsign;
verifytime += endverify - endsignstartverify;
if (!v) {
throw new RuntimeException("Holy crap, did not verify");
}
if ( (minKey == 0) && (minS == 0) && (minV == 0) ) {
minKey = endkeys - startkeys;
maxKey = endkeys - startkeys;
minS = endsignstartverify - startsign;
maxS = endsignstartverify - startsign;
minV = endverify - endsignstartverify;
maxV = endverify - endsignstartverify;
} else {
if (minKey > endkeys - startkeys) minKey = endkeys - startkeys;
if (maxKey < endkeys - startkeys) maxKey = endkeys - startkeys;
if (minS > endsignstartverify - startsign) minS = endsignstartverify - startsign;
if (maxS < endsignstartverify - startsign) maxS = endsignstartverify - startsign;
if (minV > endverify - endsignstartverify) minV = endverify - endsignstartverify;
if (maxV < endverify - endsignstartverify) maxV = endverify - endsignstartverify;
}
}
System.out.println();
System.out.println("Key Generation Time Average: " + (keygentime/times) + "\ttotal: " + keygentime + "\tmin: " + minKey + "\tmax: " + maxKey + "\tKeygen/second: " + (keygentime == 0 ? "NaN" : ""+(times*1000)/keygentime));
System.out.println("Signing Time Average : " + (signtime/times) + "\ttotal: " + signtime + "\tmin: " + minS + "\tmax: " + maxS + "\tSigning Bps: " + (times*message.length*1000)/signtime);
System.out.println("Verification Time Average : " + (verifytime/times) + "\ttotal: " + verifytime + "\tmin: " + minV + "\tmax: " + maxV + "\tDecryption Bps: " + (times*message.length*1000)/verifytime);
}
}

View File

@@ -0,0 +1,235 @@
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.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);
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 = SessionKeyManager.getInstance().getCurrentKey(pubKey);
if (key == null)
key = SessionKeyManager.getInstance().createSession(pubKey);
byte[] encrypted = ElGamalAESEngine.encrypt(msg.getBytes(), pubKey, key, 64);
byte[] decrypted = 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 = SessionKeyManager.getInstance().getCurrentKey(pubKey);
if (key == null)
key = SessionKeyManager.getInstance().createSession(pubKey);
long beforeE = Clock.getInstance().now();
byte[] encrypted = ElGamalAESEngine.encrypt(msg, pubKey, key, 1024);
long afterE = Clock.getInstance().now();
byte[] decrypted = 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[] = 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[] = ElGamalAESEngine.decryptAESBlock(encrypted, 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[] = AESEngine.getInstance().encrypt(msg.getBytes(), sessionKey, iv);
byte aesDecr[] = AESEngine.getInstance().decrypt(aesEncr, sessionKey, iv);
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[] = ElGamalEngine.getInstance().encrypt(elgSrc.toByteArray(), pubKey);
byte elgDecr[] = ElGamalEngine.getInstance().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[]) {
ElGamalAESEngineTest tst = new ElGamalAESEngineTest();
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(Log.CRIT);
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
}
}

View File

@@ -0,0 +1,96 @@
package net.i2p.crypto;
/*
* Copyright (c) 2003, TheCrypto
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the TheCrypto may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import net.i2p.data.DataHelper;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
public class ElGamalBench {
public static void main(String args[]) {
int times = 100;
long keygentime = 0;
long encrypttime = 0;
long decrypttime = 0;
long maxKey = 0;
long minKey = 0;
long maxE = 0;
long minE = 0;
long maxD = 0;
long minD = 0;
Object[] keys = KeyGenerator.getInstance().generatePKIKeypair();
byte[] message = new byte[222];
for (int i = 0; i < message.length; i++)
message[i] = (byte)((i%26)+'a');
for (int x = 0; x < times; x++) {
long startkeys = System.currentTimeMillis();
keys = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey pubkey = (PublicKey)keys[0];
PrivateKey privkey = (PrivateKey)keys[1];
long endkeys = System.currentTimeMillis();
long startencrypt = System.currentTimeMillis();
byte[] e = ElGamalEngine.getInstance().encrypt(message, pubkey);
long endencryptstartdecrypt = System.currentTimeMillis();
byte[] d = ElGamalEngine.getInstance().decrypt(e, privkey);
long enddecrypt = System.currentTimeMillis();
System.out.print(".");
keygentime += endkeys - startkeys;
encrypttime += endencryptstartdecrypt - startencrypt;
decrypttime += enddecrypt - endencryptstartdecrypt;
if (!DataHelper.eq(d, message)) {
System.out.println("Lengths: source [" + message.length + "] dest [" + d.length + "]");
byte hash1[] = SHA256Generator.getInstance().calculateHash(message).getData();
byte hash2[] = SHA256Generator.getInstance().calculateHash(d).getData();
System.out.println("Hashes: source [" + DataHelper.toString(hash1, hash1.length) + "] dest [" + DataHelper.toString(hash2, hash2.length) + "]");
throw new RuntimeException("Holy crap, decrypted != source message");
}
if ( (minKey == 0) && (minE == 0) && (minD == 0) ) {
minKey = endkeys - startkeys;
maxKey = endkeys - startkeys;
minE = endencryptstartdecrypt - startencrypt;
maxE = endencryptstartdecrypt - startencrypt;
minD = enddecrypt - endencryptstartdecrypt;
maxD = enddecrypt - endencryptstartdecrypt;
} else {
if (minKey > endkeys - startkeys) minKey = endkeys - startkeys;
if (maxKey < endkeys - startkeys) maxKey = endkeys - startkeys;
if (minE > endencryptstartdecrypt - startencrypt) minE = endencryptstartdecrypt - startencrypt;
if (maxE < endencryptstartdecrypt - startencrypt) maxE = endencryptstartdecrypt - startencrypt;
if (minD > enddecrypt - endencryptstartdecrypt) minD = enddecrypt - endencryptstartdecrypt;
if (maxD < enddecrypt - endencryptstartdecrypt) maxD = enddecrypt - endencryptstartdecrypt;
}
}
System.out.println();
System.out.println("Key Generation Time Average: " + (keygentime/times) + "\ttotal: " + keygentime + "\tmin: " + minKey + "\tmax: " + maxKey + "\tKeygen/second: " + (keygentime == 0 ? "NaN" : ""+(times*1000)/keygentime));
System.out.println("Encryption Time Average : " + (encrypttime/times) + "\ttotal: " + encrypttime + "\tmin: " + minE + "\tmax: " + maxE + "\tEncryption Bps: " + (times*message.length*1000)/encrypttime);
System.out.println("Decryption Time Average : " + (decrypttime/times) + "\ttotal: " + decrypttime + "\tmin: " + minD + "\tmax: " + maxD + "\tDecryption Bps: " + (times*message.length*1000)/decrypttime);
}
}

View File

@@ -0,0 +1,99 @@
package net.i2p.crypto;
/*
* Copyright (c) 2003, TheCrypto
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the TheCrypto may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
import net.i2p.data.Hash;
public class SHA256Bench {
public static void main(String args[]) {
Hash asdfs = SHA256Generator.getInstance().calculateHash("qwerty".getBytes());
int times = 100;
long shorttime = 0;
long medtime = 0;
long longtime = 0;
long minShort = 0;
long maxShort = 0;
long minMed = 0;
long maxMed = 0;
long minLong = 0;
long maxLong = 0;
byte[] smess = new String("abc").getBytes();
StringBuffer buf = new StringBuffer();
for (int x = 0; x < 10*1024; x++) {
buf.append("a");
}
byte[] mmess = buf.toString().getBytes(); // new String("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq").getBytes();
buf = new StringBuffer();
for (int x = 0; x < 1000000; x++) {
buf.append("a");
}
byte[] lmess = buf.toString().getBytes();
// warm up the engines
SHA256Generator.getInstance().calculateHash(smess);
SHA256Generator.getInstance().calculateHash(mmess);
SHA256Generator.getInstance().calculateHash(lmess);
// now do it
for (int x = 0; x < times; x++) {
long startshort = System.currentTimeMillis();
Hash s = SHA256Generator.getInstance().calculateHash(smess);
long endshortstartmed = System.currentTimeMillis();
Hash m = SHA256Generator.getInstance().calculateHash(mmess);
long endmedstartlong = System.currentTimeMillis();
Hash l = SHA256Generator.getInstance().calculateHash(lmess);
long endlong = System.currentTimeMillis();
System.out.print(".");
shorttime += endshortstartmed - startshort;
medtime += endmedstartlong - endshortstartmed;
longtime += endlong - endmedstartlong;
if ((minShort == 0) && (minMed == 0) && (minLong == 0) ) {
minShort = endshortstartmed - startshort;
maxShort = endshortstartmed - startshort;
minMed = endmedstartlong - endshortstartmed;
maxMed = endmedstartlong - endshortstartmed;
minLong = endlong - endmedstartlong;
maxLong = endlong - endmedstartlong;
} else {
if (minShort > endshortstartmed - startshort) minShort = endshortstartmed - startshort;
if (maxShort < endshortstartmed - startshort) maxShort = endshortstartmed - startshort;
if (minMed > endmedstartlong - endshortstartmed) minMed = endmedstartlong - endshortstartmed;
if (maxMed < endmedstartlong - endshortstartmed) maxMed = endmedstartlong - endshortstartmed;
if (minLong > endlong - endmedstartlong) minLong = endlong - endmedstartlong;
if (maxLong < endlong - endmedstartlong) maxLong = endlong - endmedstartlong;
}
}
System.out.println();
System.out.println("Short Message Time Average : " + (shorttime/times) + "\ttotal: " + shorttime + "\tmin: " + minShort + "\tmax: " + maxShort + "\tBps: " + (shorttime == 0 ? "NaN" : ""+(times*smess.length)/shorttime));
System.out.println("Medium Message Time Average : " + (medtime/times) + "\ttotal: " + medtime + "\tmin: " + minMed + "\tmax: " + maxMed + "\tBps: " + (times*mmess.length*1000)/medtime);
System.out.println("Long Message Time Average : " + (longtime/times) + "\ttotal: " + longtime + "\tmin: " + minLong + "\tmax: " + maxLong + "\tBps: " + (times*lmess.length*1000)/longtime);
}
}

View File

@@ -0,0 +1,406 @@
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.PublicKey;
import net.i2p.data.PrivateKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.util.Clock;
import java.util.HashSet;
import java.util.Set;
/**
*
* 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 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) {}
}
/**
* Run tagsIncluded useTag rekey
* 1 no no no
* 2 no no no
*/
public void testNoSessions() throws Exception {
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey pubKey = (PublicKey)keys[0];
PrivateKey privKey = (PrivateKey)keys[1];
SessionKey curKey = SessionKeyManager.getInstance().createSession(pubKey);
byte[] msg1 = "msg 1".getBytes();
byte[] msg2 = "msg 2".getBytes();
byte emsg1[] = ElGamalAESEngine.encrypt(msg1, pubKey, curKey, 64);
byte dmsg1[] = 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 emsg2[] = ElGamalAESEngine.encrypt(msg2, pubKey, curKey, 64);
byte dmsg2[] = ElGamalAESEngine.decrypt(emsg2, privKey);
if (DataHelper.eq(dmsg2, msg2))
_log.info("PASSED: No sessions msg 2");
else
_log.error("FAILED: No sessions msg 2");
}
/**
* Run tagsIncluded useTag rekey
* 1 yes (2) no no
* 2 no yes no
* 3 yes (2) yes no
* 4 no yes no
* 5 no yes no
*/
public void testSessions() throws Exception {
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey pubKey = (PublicKey)keys[0];
PrivateKey privKey = (PrivateKey)keys[1];
SessionKey curKey = SessionKeyManager.getInstance().createSession(pubKey);
SessionTag tag1 = new SessionTag(true);
SessionTag tag2 = new SessionTag(true);
SessionTag tag3 = new SessionTag(true);
SessionTag tag4 = new SessionTag(true);
HashSet firstTags = new HashSet();
firstTags.add(tag1);
firstTags.add(tag2);
HashSet secondTags = new HashSet();
secondTags.add(tag3);
secondTags.add(tag4);
byte[] msg1 = "msg 1".getBytes();
byte[] msg2 = "msg 2".getBytes();
byte[] msg3 = "msg 3".getBytes();
byte[] msg4 = "msg 4".getBytes();
byte[] msg5 = "msg 5".getBytes();
byte emsg1[] = ElGamalAESEngine.encrypt(msg1, pubKey, curKey, firstTags, 64);
byte dmsg1[] = ElGamalAESEngine.decrypt(emsg1, privKey);
if (DataHelper.eq(dmsg1, msg1))
_log.info("PASSED: Sessions msg 1");
else {
_log.error("FAILED: Sessions msg 1");
return;
}
SessionKeyManager.getInstance().tagsDelivered(pubKey, curKey, firstTags);
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
SessionTag curTag = SessionKeyManager.getInstance().consumeNextAvailableTag(pubKey, curKey);
if (curTag == null) {
_log.error("Not able to consume next tag for message 2");
return;
}
byte emsg2[] = ElGamalAESEngine.encrypt(msg2, pubKey, curKey, null, curTag, 64);
byte dmsg2[] = ElGamalAESEngine.decrypt(emsg2, privKey);
if (DataHelper.eq(dmsg2, msg2))
_log.info("PASSED: Sessions msg 2");
else {
_log.error("FAILED: Sessions msg 2");
return;
}
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg3[] = ElGamalAESEngine.encrypt(msg3, pubKey, curKey, secondTags, curTag, 64);
byte dmsg3[] = ElGamalAESEngine.decrypt(emsg3, privKey);
if (DataHelper.eq(dmsg3, msg3))
_log.info("PASSED: Sessions msg 3");
else {
_log.error("FAILED: Sessions msg 3");
return;
}
SessionKeyManager.getInstance().tagsDelivered(pubKey, curKey, secondTags);
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg4[] = ElGamalAESEngine.encrypt(msg4, pubKey, curKey, null, curTag, 64);
byte dmsg4[] = ElGamalAESEngine.decrypt(emsg4, privKey);
if (DataHelper.eq(dmsg4, msg4))
_log.info("PASSED: Sessions msg 4");
else {
_log.error("FAILED: Sessions msg 4");
return;
}
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg5[] = ElGamalAESEngine.encrypt(msg5, pubKey, curKey, null, curTag, 64);
byte dmsg5[] = ElGamalAESEngine.decrypt(emsg5, privKey);
if (DataHelper.eq(dmsg5, msg5))
_log.info("PASSED: Sessions msg 5");
else {
_log.error("FAILED: Sessions msg 5");
return;
}
}
/**
* Run tagsIncluded useTag rekey
* 1 yes (2) no no
* 2 no yes no
* 3 yes (2) yes yes
* 4 no yes no
* 5 no yes no
*/
public void testRekeying() throws Exception {
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey pubKey = (PublicKey)keys[0];
PrivateKey privKey = (PrivateKey)keys[1];
SessionKey curKey = SessionKeyManager.getInstance().createSession(pubKey);
SessionKey nextKey = KeyGenerator.getInstance().generateSessionKey();
SessionTag tag1 = new SessionTag(true);
SessionTag tag2 = new SessionTag(true);
SessionTag tag3 = new SessionTag(true);
SessionTag tag4 = new SessionTag(true);
HashSet firstTags = new HashSet();
firstTags.add(tag1);
firstTags.add(tag2);
HashSet secondTags = new HashSet();
secondTags.add(tag3);
secondTags.add(tag4);
byte[] msg1 = "msg 1".getBytes();
byte[] msg2 = "msg 2".getBytes();
byte[] msg3 = "msg 3".getBytes();
byte[] msg4 = "msg 4".getBytes();
byte[] msg5 = "msg 5".getBytes();
byte emsg1[] = ElGamalAESEngine.encrypt(msg1, pubKey, curKey, firstTags, 64);
byte dmsg1[] = ElGamalAESEngine.decrypt(emsg1, privKey);
if (DataHelper.eq(dmsg1, msg1))
_log.info("PASSED: Sessions msg 1");
else {
_log.error("FAILED: Sessions msg 1");
return;
}
SessionKeyManager.getInstance().tagsDelivered(pubKey, curKey, firstTags);
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
SessionTag curTag = SessionKeyManager.getInstance().consumeNextAvailableTag(pubKey, curKey);
if (curTag == null) {
_log.error("Not able to consume next tag for message 2");
return;
}
byte emsg2[] = ElGamalAESEngine.encrypt(msg2, pubKey, curKey, null, curTag, 64);
byte dmsg2[] = ElGamalAESEngine.decrypt(emsg2, privKey);
if (DataHelper.eq(dmsg2, msg2))
_log.info("PASSED: Sessions msg 2");
else {
_log.error("FAILED: Sessions msg 2");
return;
}
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg3[] = ElGamalAESEngine.encrypt(msg3, pubKey, curKey, secondTags, curTag, nextKey, 64);
byte dmsg3[] = ElGamalAESEngine.decrypt(emsg3, privKey);
if (DataHelper.eq(dmsg3, msg3))
_log.info("PASSED: Sessions msg 3");
else {
_log.error("FAILED: Sessions msg 3");
return;
}
SessionKeyManager.getInstance().tagsDelivered(pubKey, nextKey, secondTags); // note nextKey not curKey
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg4[] = ElGamalAESEngine.encrypt(msg4, pubKey, curKey, null, curTag, 64);
byte dmsg4[] = ElGamalAESEngine.decrypt(emsg4, privKey);
if (DataHelper.eq(dmsg4, msg4))
_log.info("PASSED: Sessions msg 4");
else {
_log.error("FAILED: Sessions msg 4");
return;
}
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
curTag = SessionKeyManager.getInstance().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;
}
byte emsg5[] = ElGamalAESEngine.encrypt(msg5, pubKey, curKey, null, curTag, 64);
byte dmsg5[] = ElGamalAESEngine.decrypt(emsg5, privKey);
if (DataHelper.eq(dmsg5, msg5))
_log.info("PASSED: Sessions msg 5");
else {
_log.error("FAILED: Sessions msg 5");
return;
}
}
/**
* 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 {
Object keys[] = KeyGenerator.getInstance().generatePKIKeypair();
PublicKey pubKey = (PublicKey)keys[0];
PrivateKey privKey = (PrivateKey)keys[1];
SessionKey curKey = SessionKeyManager.getInstance().createSession(pubKey);
for (int i = 0; i < numMsgs; i++) {
Set tags = null;
SessionKey nextKey = null;
curKey = SessionKeyManager.getInstance().getCurrentKey(pubKey);
SessionTag curTag = SessionKeyManager.getInstance().consumeNextAvailableTag(pubKey, curKey);
int availTags = SessionKeyManager.getInstance().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[] = ElGamalAESEngine.encrypt(msg, pubKey, curKey, tags, curTag, nextKey, 64);
byte dmsg[] = 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;
}
if ( (tags != null) && (tags.size() > 0) ) {
if (nextKey == null) {
SessionKeyManager.getInstance().tagsDelivered(pubKey, curKey, tags);
} else {
SessionKeyManager.getInstance().tagsDelivered(pubKey, nextKey, tags);
}
}
}
}
private Set generateNewTags(int numTags) {
Set tags = new HashSet(numTags);
for (int i = 0; i < numTags; i++)
tags.add(new SessionTag(true));
return tags;
}
}