forked from I2P_Developers/i2p.i2p
Crypto: Define ElG length constants
This commit is contained in:
@ -58,6 +58,9 @@ public final class ElGamalEngine {
|
|||||||
private final YKGenerator _ykgen;
|
private final YKGenerator _ykgen;
|
||||||
|
|
||||||
private static final BigInteger ELGPM1 = CryptoConstants.elgp.subtract(BigInteger.ONE);
|
private static final BigInteger ELGPM1 = CryptoConstants.elgp.subtract(BigInteger.ONE);
|
||||||
|
private static final int ELG_CLEARTEXT_LENGTH = 222;
|
||||||
|
private static final int ELG_ENCRYPTED_LENGTH = 514;
|
||||||
|
private static final int ELG_HALF_LENGTH = ELG_ENCRYPTED_LENGTH / 2;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,8 +116,8 @@ public final class ElGamalEngine {
|
|||||||
* the cleartext to 222 bytes with random data.
|
* the cleartext to 222 bytes with random data.
|
||||||
*/
|
*/
|
||||||
public byte[] encrypt(byte data[], PublicKey publicKey) {
|
public byte[] encrypt(byte data[], PublicKey publicKey) {
|
||||||
if ((data == null) || (data.length >= 223))
|
if ((data == null) || (data.length > ELG_CLEARTEXT_LENGTH))
|
||||||
throw new IllegalArgumentException("Data to encrypt must be < 223 bytes at the moment");
|
throw new IllegalArgumentException("Data to encrypt must be <= 222 bytes");
|
||||||
if (publicKey == null) throw new IllegalArgumentException("Null public key specified");
|
if (publicKey == null) throw new IllegalArgumentException("Null public key specified");
|
||||||
|
|
||||||
long start = _context.clock().now();
|
long start = _context.clock().now();
|
||||||
@ -149,11 +152,11 @@ public final class ElGamalEngine {
|
|||||||
|
|
||||||
byte[] ybytes = y.toByteArray();
|
byte[] ybytes = y.toByteArray();
|
||||||
byte[] dbytes = d.toByteArray();
|
byte[] dbytes = d.toByteArray();
|
||||||
byte[] out = new byte[514];
|
byte[] out = new byte[ELG_ENCRYPTED_LENGTH];
|
||||||
System.arraycopy(ybytes, 0, out, (ybytes.length < 257 ? 257 - ybytes.length : 0),
|
System.arraycopy(ybytes, 0, out, (ybytes.length < ELG_HALF_LENGTH ? ELG_HALF_LENGTH - ybytes.length : 0),
|
||||||
(ybytes.length > 257 ? 257 : ybytes.length));
|
(ybytes.length > ELG_HALF_LENGTH ? ELG_HALF_LENGTH : ybytes.length));
|
||||||
System.arraycopy(dbytes, 0, out, (dbytes.length < 257 ? 514 - dbytes.length : 257),
|
System.arraycopy(dbytes, 0, out, (dbytes.length < ELG_HALF_LENGTH ? ELG_ENCRYPTED_LENGTH - dbytes.length : ELG_HALF_LENGTH),
|
||||||
(dbytes.length > 257 ? 257 : dbytes.length));
|
(dbytes.length > ELG_HALF_LENGTH ? ELG_HALF_LENGTH : dbytes.length));
|
||||||
/*
|
/*
|
||||||
StringBuilder buf = new StringBuilder(1024);
|
StringBuilder buf = new StringBuilder(1024);
|
||||||
buf.append("Timing\n");
|
buf.append("Timing\n");
|
||||||
@ -190,18 +193,18 @@ public final class ElGamalEngine {
|
|||||||
* @return unencrypted data or null on failure
|
* @return unencrypted data or null on failure
|
||||||
*/
|
*/
|
||||||
public byte[] decrypt(byte encrypted[], PrivateKey privateKey) {
|
public byte[] decrypt(byte encrypted[], PrivateKey privateKey) {
|
||||||
if ((encrypted == null) || (encrypted.length != 514))
|
if ((encrypted == null) || (encrypted.length != ELG_ENCRYPTED_LENGTH))
|
||||||
throw new IllegalArgumentException("Data to decrypt must be exactly 514 bytes");
|
throw new IllegalArgumentException("Data to decrypt must be exactly ELG_ENCRYPTED_LENGTH bytes");
|
||||||
long start = _context.clock().now();
|
long start = _context.clock().now();
|
||||||
|
|
||||||
BigInteger a = new NativeBigInteger(1, privateKey.getData());
|
BigInteger a = new NativeBigInteger(1, privateKey.getData());
|
||||||
BigInteger y1p = ELGPM1.subtract(a);
|
BigInteger y1p = ELGPM1.subtract(a);
|
||||||
// we use this buf first for Y, then for D, then for the hash
|
// we use this buf first for Y, then for D, then for the hash
|
||||||
byte[] buf = SimpleByteCache.acquire(257);
|
byte[] buf = SimpleByteCache.acquire(ELG_HALF_LENGTH);
|
||||||
System.arraycopy(encrypted, 0, buf, 0, 257);
|
System.arraycopy(encrypted, 0, buf, 0, ELG_HALF_LENGTH);
|
||||||
NativeBigInteger y = new NativeBigInteger(1, buf);
|
NativeBigInteger y = new NativeBigInteger(1, buf);
|
||||||
BigInteger ya = y.modPowCT(y1p, CryptoConstants.elgp);
|
BigInteger ya = y.modPowCT(y1p, CryptoConstants.elgp);
|
||||||
System.arraycopy(encrypted, 257, buf, 0, 257);
|
System.arraycopy(encrypted, ELG_HALF_LENGTH, buf, 0, ELG_HALF_LENGTH);
|
||||||
BigInteger d = new NativeBigInteger(1, buf);
|
BigInteger d = new NativeBigInteger(1, buf);
|
||||||
BigInteger m = ya.multiply(d);
|
BigInteger m = ya.multiply(d);
|
||||||
m = m.mod(CryptoConstants.elgp);
|
m = m.mod(CryptoConstants.elgp);
|
||||||
|
@ -42,6 +42,8 @@ public final class ElGamalAESEngine {
|
|||||||
private final I2PAppContext _context;
|
private final I2PAppContext _context;
|
||||||
/** enforced since release 0.6 */
|
/** enforced since release 0.6 */
|
||||||
public static final int MAX_TAGS_RECEIVED = 200;
|
public static final int MAX_TAGS_RECEIVED = 200;
|
||||||
|
private static final int ELG_CLEARTEXT_LENGTH = 222;
|
||||||
|
private static final int ELG_ENCRYPTED_LENGTH = 514;
|
||||||
|
|
||||||
public ElGamalAESEngine(I2PAppContext ctx) {
|
public ElGamalAESEngine(I2PAppContext ctx) {
|
||||||
_context = ctx;
|
_context = ctx;
|
||||||
@ -178,15 +180,15 @@ public final class ElGamalAESEngine {
|
|||||||
if (data == null) {
|
if (data == null) {
|
||||||
//if (_log.shouldLog(Log.WARN)) _log.warn("Data is null, unable to decrypt new session");
|
//if (_log.shouldLog(Log.WARN)) _log.warn("Data is null, unable to decrypt new session");
|
||||||
return null;
|
return null;
|
||||||
} else if (data.length < 514) {
|
} else if (data.length < ELG_ENCRYPTED_LENGTH) {
|
||||||
//if (_log.shouldLog(Log.WARN)) _log.warn("Data length is too small (" + data.length + ")");
|
//if (_log.shouldLog(Log.WARN)) _log.warn("Data length is too small (" + data.length + ")");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
byte elgEncr[] = new byte[514];
|
byte elgEncr[] = new byte[ELG_ENCRYPTED_LENGTH];
|
||||||
if (data.length > 514) {
|
if (data.length > ELG_ENCRYPTED_LENGTH) {
|
||||||
System.arraycopy(data, 0, elgEncr, 0, 514);
|
System.arraycopy(data, 0, elgEncr, 0, ELG_ENCRYPTED_LENGTH);
|
||||||
} else {
|
} else {
|
||||||
System.arraycopy(data, 0, elgEncr, 514 - data.length, data.length);
|
System.arraycopy(data, 0, elgEncr, ELG_ENCRYPTED_LENGTH - data.length, data.length);
|
||||||
}
|
}
|
||||||
byte elgDecr[] = _context.elGamalEngine().decrypt(elgEncr, targetPrivateKey);
|
byte elgDecr[] = _context.elGamalEngine().decrypt(elgEncr, targetPrivateKey);
|
||||||
if (elgDecr == null) {
|
if (elgDecr == null) {
|
||||||
@ -217,7 +219,8 @@ public final class ElGamalAESEngine {
|
|||||||
// feed the extra bytes into the PRNG
|
// feed the extra bytes into the PRNG
|
||||||
_context.random().harvester().feedEntropy("ElG/AES", elgDecr, offset, elgDecr.length - offset);
|
_context.random().harvester().feedEntropy("ElG/AES", elgDecr, offset, elgDecr.length - offset);
|
||||||
|
|
||||||
byte aesDecr[] = decryptAESBlock(data, 514, data.length-514, usedKey, iv, null, foundTags, foundKey);
|
byte aesDecr[] = decryptAESBlock(data, ELG_ENCRYPTED_LENGTH, data.length - ELG_ENCRYPTED_LENGTH,
|
||||||
|
usedKey, iv, null, foundTags, foundKey);
|
||||||
SimpleByteCache.release(iv);
|
SimpleByteCache.release(iv);
|
||||||
|
|
||||||
//if (_log.shouldLog(Log.DEBUG))
|
//if (_log.shouldLog(Log.DEBUG))
|
||||||
@ -508,10 +511,10 @@ public final class ElGamalAESEngine {
|
|||||||
private byte[] encryptNewSession(byte data[], PublicKey target, SessionKey key, Set<SessionTag> tagsForDelivery,
|
private byte[] encryptNewSession(byte data[], PublicKey target, SessionKey key, Set<SessionTag> tagsForDelivery,
|
||||||
SessionKey newKey, long paddedSize) {
|
SessionKey newKey, long paddedSize) {
|
||||||
//_log.debug("Encrypting to a NEW session");
|
//_log.debug("Encrypting to a NEW session");
|
||||||
byte elgSrcData[] = new byte[SessionKey.KEYSIZE_BYTES+32+158];
|
byte elgSrcData[] = new byte[ELG_CLEARTEXT_LENGTH];
|
||||||
System.arraycopy(key.getData(), 0, elgSrcData, 0, SessionKey.KEYSIZE_BYTES);
|
System.arraycopy(key.getData(), 0, elgSrcData, 0, SessionKey.KEYSIZE_BYTES);
|
||||||
// get both the preIV and the padding at once, then copy to the preIV array
|
// get both the preIV and the padding at once, then copy to the preIV array
|
||||||
_context.random().nextBytes(elgSrcData, SessionKey.KEYSIZE_BYTES, 32 + 158);
|
_context.random().nextBytes(elgSrcData, SessionKey.KEYSIZE_BYTES, ELG_CLEARTEXT_LENGTH - SessionKey.KEYSIZE_BYTES);
|
||||||
byte preIV[] = SimpleByteCache.acquire(32);
|
byte preIV[] = SimpleByteCache.acquire(32);
|
||||||
System.arraycopy(elgSrcData, SessionKey.KEYSIZE_BYTES, preIV, 0, 32);
|
System.arraycopy(elgSrcData, SessionKey.KEYSIZE_BYTES, preIV, 0, 32);
|
||||||
|
|
||||||
@ -523,9 +526,9 @@ public final class ElGamalAESEngine {
|
|||||||
long after = _context.clock().now();
|
long after = _context.clock().now();
|
||||||
_log.info("elgEngine.encrypt of the session key took " + (after - before) + "ms");
|
_log.info("elgEngine.encrypt of the session key took " + (after - before) + "ms");
|
||||||
}
|
}
|
||||||
if (elgEncr.length < 514) {
|
if (elgEncr.length < ELG_ENCRYPTED_LENGTH) {
|
||||||
// ??? ElGamalEngine.encrypt() always returns 514 bytes
|
// ??? ElGamalEngine.encrypt() always returns 514 bytes
|
||||||
byte elg[] = new byte[514];
|
byte elg[] = new byte[ELG_ENCRYPTED_LENGTH];
|
||||||
int diff = elg.length - elgEncr.length;
|
int diff = elg.length - elgEncr.length;
|
||||||
//if (_log.shouldLog(Log.DEBUG)) _log.debug("Difference in size: " + diff);
|
//if (_log.shouldLog(Log.DEBUG)) _log.debug("Difference in size: " + diff);
|
||||||
System.arraycopy(elgEncr, 0, elg, diff, elgEncr.length);
|
System.arraycopy(elgEncr, 0, elg, diff, elgEncr.length);
|
||||||
|
Reference in New Issue
Block a user