I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit ee57bd73 authored by zzz's avatar zzz
Browse files

Data: Add encryption types for PublicKey, PrivateKey

parent 4c970fa0
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,7 @@ package net.i2p.data;
import java.util.Arrays;
import net.i2p.crypto.EncType;
import net.i2p.crypto.KeyGenerator;
/**
......@@ -18,20 +19,42 @@ import net.i2p.crypto.KeyGenerator;
* A private key is 256byte Integer. The private key represents only the
* exponent, not the primes, which are constant and defined in the crypto spec.
*
* Note that we use short exponents, so all but the last 28.25 bytes are zero.
* See http://www.i2p2.i2p/how_cryptography for details.
* As of release 0.9.38, keys of arbitrary length and type are supported.
* See EncType.
*
* @author jrandom
*/
public class PrivateKey extends SimpleDataStructure {
public final static int KEYSIZE_BYTES = 256;
private static final EncType DEF_TYPE = EncType.ELGAMAL_2048;
public final static int KEYSIZE_BYTES = DEF_TYPE.getPrivkeyLen();
private final EncType _type;
public PrivateKey() {
this(DEF_TYPE);
}
/**
* @param type non-null
* @since 0.9.38
*/
public PrivateKey(EncType type) {
super();
_type = type;
}
public PrivateKey(byte data[]) {
this(DEF_TYPE, data);
}
/**
* @param type non-null
* @param data must be non-null
* @since 0.9.38
*/
public PrivateKey(EncType type, byte data[]) {
super(data);
_type = type;
}
/** constructs from base64
......@@ -39,12 +62,20 @@ public class PrivateKey extends SimpleDataStructure {
* on a prior instance of PrivateKey
*/
public PrivateKey(String base64Data) throws DataFormatException {
super();
this(DEF_TYPE);
fromBase64(base64Data);
}
public int length() {
return KEYSIZE_BYTES;
return _type.getPrivkeyLen();
}
/**
* @return non-null
* @since 0.9.38
*/
public EncType getType() {
return _type;
}
/** derives a new PublicKey object derived from the secret contents
......@@ -56,6 +87,23 @@ public class PrivateKey extends SimpleDataStructure {
return KeyGenerator.getPublicKey(this);
}
/**
* @since 0.9.38
*/
@Override
public String toString() {
StringBuilder buf = new StringBuilder(64);
buf.append("[PrivateKey ").append(_type).append(": ");
int length = length();
if (_data == null) {
buf.append("null");
} else {
buf.append("size: ").append(length);
}
buf.append(']');
return buf.toString();
}
/**
* We assume the data has enough randomness in it, so use the last 4 bytes for speed.
* Overridden since we use short exponents, so the first 227 bytes are all zero.
......@@ -64,6 +112,8 @@ public class PrivateKey extends SimpleDataStructure {
public int hashCode() {
if (_data == null)
return 0;
if (_type != DEF_TYPE)
return DataHelper.hashCode(_data);
int rv = _data[KEYSIZE_BYTES - 4];
for (int i = 1; i < 4; i++)
rv ^= (_data[i + (KEYSIZE_BYTES - 4)] << (i*8));
......@@ -74,6 +124,7 @@ public class PrivateKey extends SimpleDataStructure {
public boolean equals(Object obj) {
if (obj == this) return true;
if ((obj == null) || !(obj instanceof PrivateKey)) return false;
return Arrays.equals(_data, ((PrivateKey) obj)._data);
PrivateKey p = (PrivateKey) obj;
return _type == p._type && Arrays.equals(_data, p._data);
}
}
......@@ -12,19 +12,27 @@ package net.i2p.data;
import java.io.InputStream;
import java.io.IOException;
import net.i2p.crypto.EncType;
/**
* Defines the PublicKey as defined by the I2P data structure spec.
* A public key is 256byte Integer. The public key represents only the
* exponent, not the primes, which are constant and defined in the crypto spec.
*
* As of release 0.9.38, keys of arbitrary length and type are supported.
* See EncType.
*
* @author jrandom
*/
public class PublicKey extends SimpleDataStructure {
public final static int KEYSIZE_BYTES = 256;
private static final EncType DEF_TYPE = EncType.ELGAMAL_2048;
public final static int KEYSIZE_BYTES = DEF_TYPE.getPubkeyLen();
private static final int CACHE_SIZE = 1024;
private static final SDSCache<PublicKey> _cache = new SDSCache<PublicKey>(PublicKey.class, KEYSIZE_BYTES, CACHE_SIZE);
private final EncType _type;
/**
* Pull from cache or return new.
* Deprecated - used only by deprecated Destination.readBytes(data, off)
......@@ -45,12 +53,31 @@ public class PublicKey extends SimpleDataStructure {
}
public PublicKey() {
this(DEF_TYPE);
}
/**
* @param type if null, type is unknown
* @since 0.9.38
*/
public PublicKey(EncType type) {
super();
_type = type;
}
/** @param data must be non-null */
public PublicKey(byte data[]) {
this(DEF_TYPE, data);
}
/**
* @param type if null, type is unknown
* @param data must be non-null
* @since 0.9.38
*/
public PublicKey(EncType type, byte data[]) {
super();
_type = type;
if (data == null)
throw new IllegalArgumentException("Data must be specified");
_data = data;
......@@ -61,18 +88,46 @@ public class PublicKey extends SimpleDataStructure {
* on a prior instance of PublicKey
*/
public PublicKey(String base64Data) throws DataFormatException {
super();
this(DEF_TYPE);
fromBase64(base64Data);
}
public int length() {
if (_type != null)
return _type.getPubkeyLen();
if (_data != null)
return _data.length;
return KEYSIZE_BYTES;
}
/**
* @return null if unknown
* @since 0.9.38
*/
public EncType getType() {
return _type;
}
/**
* @since 0.9.17
*/
public static void clearCache() {
_cache.clear();
}
/**
* @since 0.9.38
*/
@Override
public String toString() {
StringBuilder buf = new StringBuilder(64);
buf.append("[PublicKey ").append((_type != null) ? _type.toString() : "unknown type").append(' ');
if (_data == null) {
buf.append("null");
} else {
buf.append("size: ").append(length());
}
buf.append(']');
return buf.toString();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment