diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java index 196074546..5d0ecbfd6 100644 --- a/core/java/src/net/i2p/crypto/KeyGenerator.java +++ b/core/java/src/net/i2p/crypto/KeyGenerator.java @@ -76,6 +76,20 @@ public class KeyGenerator { return keys; } + /** Convert a PrivateKey to its corresponding PublicKey + * @param a PrivateKey object + * @return the corresponding PublicKey object + * @author aum + */ + public static PublicKey getPublicKey(PrivateKey priv) { + BigInteger a = new NativeBigInteger(priv.toByteArray()); + BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp); + PublicKey pub = new PublicKey(); + byte [] pubBytes = aalpha.toByteArray(); + pub.setData(padBuffer(pubBytes, PublicKey.KEYSIZE_BYTES)); + return pub; + } + /** Generate a pair of DSA keys, where index 0 is a SigningPublicKey, and * index 1 is a SigningPrivateKey * @return pair of keys @@ -100,6 +114,20 @@ public class KeyGenerator { return keys; } + /** Convert a SigningPrivateKey to a SigningPublicKey + * @param a SigningPrivateKey object + * @return a SigningPublicKey object + * @author aum + */ + public static SigningPublicKey getSigningPublicKey(SigningPrivateKey priv) { + BigInteger x = new NativeBigInteger(priv.toByteArray()); + BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap); + SigningPublicKey pub = new SigningPublicKey(); + byte [] pubBytes = padBuffer(y.toByteArray(), SigningPublicKey.KEYSIZE_BYTES); + pub.setData(pubBytes); + return pub; + } + /** * Pad the buffer w/ leading 0s or trim off leading bits so the result is the * given length. diff --git a/core/java/src/net/i2p/data/PrivateKey.java b/core/java/src/net/i2p/data/PrivateKey.java index 146279500..146dc76b9 100644 --- a/core/java/src/net/i2p/data/PrivateKey.java +++ b/core/java/src/net/i2p/data/PrivateKey.java @@ -14,6 +14,7 @@ import java.io.InputStream; import java.io.OutputStream; import net.i2p.util.Log; +import net.i2p.crypto.KeyGenerator; /** * Defines the PrivateKey as defined by the I2P data structure spec. @@ -77,4 +78,14 @@ public class PrivateKey extends DataStructureImpl { buf.append("]"); return buf.toString(); } + + /** derives a new PublicKey object derived from the secret contents + * of this PrivateKey + * @return a PublicKey object + * @author aum + */ + public PublicKey toPublic() { + return KeyGenerator.getPublicKey(this); + } + } \ No newline at end of file diff --git a/core/java/src/net/i2p/data/PublicKey.java b/core/java/src/net/i2p/data/PublicKey.java index d182d9933..86d31177e 100644 --- a/core/java/src/net/i2p/data/PublicKey.java +++ b/core/java/src/net/i2p/data/PublicKey.java @@ -76,4 +76,5 @@ public class PublicKey extends DataStructureImpl { buf.append("]"); return buf.toString(); } + } \ No newline at end of file diff --git a/core/java/src/net/i2p/data/SigningPrivateKey.java b/core/java/src/net/i2p/data/SigningPrivateKey.java index ccd7f946f..587546db8 100644 --- a/core/java/src/net/i2p/data/SigningPrivateKey.java +++ b/core/java/src/net/i2p/data/SigningPrivateKey.java @@ -14,6 +14,7 @@ import java.io.InputStream; import java.io.OutputStream; import net.i2p.util.Log; +import net.i2p.crypto.KeyGenerator; /** * Defines the SigningPrivateKey as defined by the I2P data structure spec. @@ -76,4 +77,12 @@ public class SigningPrivateKey extends DataStructureImpl { buf.append("]"); return buf.toString(); } + + /** converts this signing private key to its public equivalent + * @return a SigningPublicKey object derived from this private key + * @author aum + */ + public SigningPublicKey toPublic() { + return KeyGenerator.getSigningPublicKey(this); + } } \ No newline at end of file