Util: More elimination of data copies

This commit is contained in:
zzz
2020-11-04 14:27:16 +00:00
parent e242015145
commit 8cc62b5b42
6 changed files with 61 additions and 28 deletions

View File

@ -2069,9 +2069,8 @@ public class BlockfileNamingService extends DummyNamingService {
}
if (baos.size() > 65535)
throw new DataFormatException("Properties too big (65535 max): " + baos.size());
byte propBytes[] = baos.toByteArray();
DataHelper.writeLong(rawStream, 2, propBytes.length);
rawStream.write(propBytes);
DataHelper.writeLong(rawStream, 2, baos.size());
baos.writeTo(rawStream);
} else {
DataHelper.writeLong(rawStream, 2, 0);
}

View File

@ -1,7 +1,6 @@
package net.i2p.client.streaming.impl;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
@ -16,6 +15,7 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Signature;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.Log;
/**
@ -799,7 +799,7 @@ class Packet {
l.warn("Offline signature expired " + toString());
return false;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(6 + _transientSigningPublicKey.length());
ByteArrayStream baos = new ByteArrayStream(6 + _transientSigningPublicKey.length());
try {
DataHelper.writeLong(baos, 4, _transientExpires / 1000);
DataHelper.writeLong(baos, 2, _transientSigningPublicKey.getType().getCode());
@ -809,8 +809,7 @@ class Packet {
} catch (DataFormatException dfe) {
return false;
}
byte[] data = baos.toByteArray();
boolean ok = ctx.dsa().verifySignature(_offlineSignature, data, 0, data.length, spk);
boolean ok = baos.verifySignature(ctx, _offlineSignature, spk);
if (!ok) {
Log l = ctx.logManager().getLog(Packet.class);
if (l.shouldLog(Log.WARN))
@ -915,7 +914,7 @@ class Packet {
else
buf.append(" (no expiration)");
if (_transientSigningPublicKey != null)
buf.append(" TRANSKEY ").append(_transientSigningPublicKey.getType());
buf.append(" TRANSKEY ").append(_transientSigningPublicKey.getType()).append(':').append(_transientSigningPublicKey.toBase64());
else
buf.append(" (no key data)");
if (_offlineSignature != null)

View File

@ -46,6 +46,7 @@ import java.util.zip.CRC32;
import java.util.zip.Deflater;
import net.i2p.I2PAppContext;
import net.i2p.util.ByteArrayStream;
import net.i2p.util.ByteCache;
import net.i2p.util.FileUtil;
import net.i2p.util.OrderedProperties;
@ -283,9 +284,8 @@ public class DataHelper {
}
if (baos.size() > 65535)
throw new DataFormatException("Properties too big (65535 max): " + baos.size());
byte propBytes[] = baos.toByteArray();
writeLong(rawStream, 2, propBytes.length);
rawStream.write(propBytes);
writeLong(rawStream, 2, baos.size());
baos.writeTo(rawStream);
} else {
writeLong(rawStream, 2, 0);
}
@ -318,7 +318,7 @@ public class DataHelper {
p = new OrderedProperties();
p.putAll(props);
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(p.size() * 64);
ByteArrayStream baos = new ByteArrayStream(p.size() * 64);
for (Map.Entry<Object, Object> entry : p.entrySet()) {
String key = (String) entry.getKey();
String val = (String) entry.getValue();
@ -329,11 +329,10 @@ public class DataHelper {
}
if (baos.size() > 65535)
throw new DataFormatException("Properties too big (65535 max): " + baos.size());
byte propBytes[] = baos.toByteArray();
toLong(target, offset, 2, propBytes.length);
toLong(target, offset, 2, baos.size());
offset += 2;
System.arraycopy(propBytes, 0, target, offset, propBytes.length);
offset += propBytes.length;
baos.copyTo(target, offset);
offset += baos.size();
return offset;
} else {
toLong(target, offset, 2, 0);

View File

@ -299,9 +299,7 @@ public class LeaseSet2 extends LeaseSet {
} catch (DataFormatException dfe) {
return null;
}
byte[] data = baos.toByteArray();
I2PAppContext ctx = I2PAppContext.getGlobalContext();
return ctx.dsa().sign(data, priv);
return baos.sign(priv);
}
public boolean verifyOfflineSignature() {
@ -324,8 +322,7 @@ public class LeaseSet2 extends LeaseSet {
} catch (DataFormatException dfe) {
return false;
}
byte[] data = baos.toByteArray();
return ctx.dsa().verifySignature(_offlineSignature, data, 0, data.length, getSigningPublicKey());
return baos.verifySignature(ctx, _offlineSignature, getSigningPublicKey());
}
/**
@ -613,9 +610,8 @@ public class LeaseSet2 extends LeaseSet {
} catch (IOException ioe) {
throw new DataFormatException("Signature failed", ioe);
}
byte data[] = out.toByteArray();
// now sign with the key
_signature = DSAEngine.getInstance().sign(data, key);
_signature = out.sign(key);
if (_signature == null)
throw new DataFormatException("Signature failed with " + key.getType() + " key");
}
@ -659,8 +655,7 @@ public class LeaseSet2 extends LeaseSet {
dfe.printStackTrace();
return false;
}
byte data[] = out.toByteArray();
return DSAEngine.getInstance().verifySignature(_signature, data, spk);
return out.verifySignature(_signature, spk);
}
@Override

View File

@ -289,9 +289,7 @@ public class SessionConfig extends DataStructureImpl {
} catch (DataFormatException dfe) {
return false;
}
byte[] odata = baos.toByteArray();
boolean ok = DSAEngine.getInstance().verifySignature(sig, odata, 0, odata.length,
_destination.getSigningPublicKey());
boolean ok = baos.verifySignature(sig, _destination.getSigningPublicKey());
if (!ok)
return false;
} else {

View File

@ -4,6 +4,12 @@ import java.io.ByteArrayOutputStream;
import java.io.ByteArrayInputStream;
import java.util.Arrays;
import net.i2p.I2PAppContext;
import net.i2p.crypto.DSAEngine;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
/**
* OutputStream to InputStream adapter.
* Zero-copy where possible. Unsynchronized.
@ -52,4 +58,41 @@ public class ByteArrayStream extends ByteArrayOutputStream {
public ByteArrayInputStream asInputStream() {
return new ByteArrayInputStream(buf, 0, count);
}
/**
* Copy all data to the target
*/
public void copyTo(byte[] target, int offset) {
System.arraycopy(buf, 0, target, offset, count);
}
/**
* Verify the written data
*/
public boolean verifySignature(Signature signature, SigningPublicKey verifyingKey) {
return DSAEngine.getInstance().verifySignature(signature, buf, 0, count, verifyingKey);
}
/**
* Verify the written data
*/
public boolean verifySignature(I2PAppContext ctx, Signature signature, SigningPublicKey verifyingKey) {
return ctx.dsa().verifySignature(signature, buf, 0, count, verifyingKey);
}
/**
* Sign the written data
* @return null on error
*/
public Signature sign(SigningPrivateKey signingKey) {
return DSAEngine.getInstance().sign(buf, 0, count, signingKey);
}
/**
* Sign the written data
* @return null on error
*/
public Signature sign(I2PAppContext ctx, SigningPrivateKey signingKey) {
return ctx.dsa().sign(buf, 0, count, signingKey);
}
}