diff --git a/core/java/src/net/i2p/crypto/Blinding.java b/core/java/src/net/i2p/crypto/Blinding.java index d9a423cbf95e3e334cc21ec6658345b88e8d7bb0..6ef788d324acdb8f94f1bb8f34381bdedb0cb9fc 100644 --- a/core/java/src/net/i2p/crypto/Blinding.java +++ b/core/java/src/net/i2p/crypto/Blinding.java @@ -39,16 +39,18 @@ public final class Blinding { private Blinding() {} /** - * Only for SigType EdDSA_SHA512_Ed25519. + * Only for SigTypes EdDSA_SHA512_Ed25519 and RedDSA_SHA512_Ed25519. * - * @param key must be SigType EdDSA_SHA512_Ed25519 + * @param key must be SigType EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @param alpha must be SigType RedDSA_SHA512_Ed25519 * @return SigType RedDSA_SHA512_Ed25519 * @throws UnsupportedOperationException unless supported SigTypes * @throws IllegalArgumentException on bad inputs */ public static SigningPublicKey blind(SigningPublicKey key, SigningPrivateKey alpha) { - if (key.getType() != TYPE || alpha.getType() != TYPER) + SigType type = key.getType(); + if ((type != TYPE && type != TYPER) || + alpha.getType() != TYPER) throw new UnsupportedOperationException(); try { EdDSAPublicKey jk = SigUtil.toJavaEdDSAKey(key); @@ -61,16 +63,18 @@ public final class Blinding { } /** - * Only for SigType EdDSA_SHA512_Ed25519. + * Only for SigTypes EdDSA_SHA512_Ed25519 and RedDSA_SHA512_Ed25519. * - * @param key must be SigType EdDSA_SHA512_Ed25519 + * @param key must be SigType EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @param alpha must be SigType RedDSA_SHA512_Ed25519 * @return SigType RedDSA_SHA512_Ed25519 * @throws UnsupportedOperationException unless supported SigTypes * @throws IllegalArgumentException on bad inputs */ public static SigningPrivateKey blind(SigningPrivateKey key, SigningPrivateKey alpha) { - if (key.getType() != TYPE || alpha.getType() != TYPER) + SigType type = key.getType(); + if ((type != TYPE && type != TYPER) || + alpha.getType() != TYPER) throw new UnsupportedOperationException(); try { EdDSAPrivateKey jk = SigUtil.toJavaEdDSAKey(key); @@ -122,9 +126,9 @@ public final class Blinding { /** * Generate alpha for the given time. - * Only for SigType EdDSA_SHA512_Ed25519. + * Only for SigType EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519. * - * @param dest spk must be SigType EdDSA_SHA512_Ed25519 + * @param dest spk must be SigType EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @param secret may be null or zero-length * @param now for what time? * @return SigType RedDSA_SHA512_Ed25519 diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java index 21b839a6e2515bd4bd4287084f3d26fa0262773d..d7f1b6135a456c5b0df9e76ac5c951beb7e188db 100644 --- a/core/java/src/net/i2p/crypto/KeyGenerator.java +++ b/core/java/src/net/i2p/crypto/KeyGenerator.java @@ -35,6 +35,7 @@ import com.southernstorm.noise.crypto.x25519.Curve25519; import net.i2p.I2PAppContext; import net.i2p.crypto.eddsa.EdDSAPrivateKey; import net.i2p.crypto.eddsa.EdDSAPublicKey; +import net.i2p.crypto.eddsa.RedKeyPairGenerator; import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; import net.i2p.crypto.provider.I2PProvider; import net.i2p.data.Hash; @@ -289,7 +290,11 @@ public final class KeyGenerator { return generateSigningKeys(); java.security.KeyPair kp; if (type.getBaseAlgorithm() == SigAlgo.EdDSA) { - net.i2p.crypto.eddsa.KeyPairGenerator kpg = new net.i2p.crypto.eddsa.KeyPairGenerator(); + net.i2p.crypto.eddsa.KeyPairGenerator kpg; + if (type == SigType.RedDSA_SHA512_Ed25519) + kpg = new RedKeyPairGenerator(); + else + kpg = new net.i2p.crypto.eddsa.KeyPairGenerator(); kpg.initialize(type.getParams(), _context.random()); kp = kpg.generateKeyPair(); } else { diff --git a/core/java/src/net/i2p/crypto/SU3File.java b/core/java/src/net/i2p/crypto/SU3File.java index 65b2ee542d056bea797c330e2e98f003f270b29b..70da7e9c4365c136f6a8a5c5691d437cbd3be562 100644 --- a/core/java/src/net/i2p/crypto/SU3File.java +++ b/core/java/src/net/i2p/crypto/SU3File.java @@ -673,7 +673,8 @@ public class SU3File { for (SigType t : EnumSet.allOf(SigType.class)) { if (!t.isAvailable()) continue; - if (t == SigType.EdDSA_SHA512_Ed25519) + if (t == SigType.EdDSA_SHA512_Ed25519 || + t == SigType.RedDSA_SHA512_Ed25519) continue; // not supported by keytool, and does double hashing right now buf.append(" ").append(t).append("\t(code: ").append(t.getCode()).append(')'); if (t.getCode() == DEFAULT_SIG_CODE) diff --git a/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java b/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java index 8703c2945d3ded88c5f19ae066ec2e17c71d851a..36d88e193253e3fa9f73219ffc389f4a2e108f78 100644 --- a/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java +++ b/core/java/src/net/i2p/crypto/eddsa/EdDSAPrivateKey.java @@ -71,7 +71,7 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey { } /** - * Returns the public key in its canonical encoding. + * Returns the private key in its canonical encoding. *<p> * This implements the following specs: *<ul><li> diff --git a/core/java/src/net/i2p/crypto/eddsa/KeyPairGenerator.java b/core/java/src/net/i2p/crypto/eddsa/KeyPairGenerator.java index f42f272d06ef51ba3bf1b26f9723db42a822190a..3480355cf34cc46704c51a026cf068ca7c7bab60 100644 --- a/core/java/src/net/i2p/crypto/eddsa/KeyPairGenerator.java +++ b/core/java/src/net/i2p/crypto/eddsa/KeyPairGenerator.java @@ -21,11 +21,11 @@ import net.i2p.util.RandomSource; * * @since 0.9.15 */ -public final class KeyPairGenerator extends KeyPairGeneratorSpi { - private static final int DEFAULT_KEYSIZE = 256; - private EdDSAParameterSpec edParams; - private SecureRandom random; - private boolean initialized; +public class KeyPairGenerator extends KeyPairGeneratorSpi { + protected static final int DEFAULT_KEYSIZE = 256; + protected EdDSAParameterSpec edParams; + protected SecureRandom random; + protected boolean initialized; private static final Hashtable<Integer, AlgorithmParameterSpec> edParameters; diff --git a/core/java/src/net/i2p/crypto/eddsa/RedKeyPairGenerator.java b/core/java/src/net/i2p/crypto/eddsa/RedKeyPairGenerator.java new file mode 100644 index 0000000000000000000000000000000000000000..de0e532af5570f393efa7a5ecc0b6c9f2b4a7fb7 --- /dev/null +++ b/core/java/src/net/i2p/crypto/eddsa/RedKeyPairGenerator.java @@ -0,0 +1,31 @@ +package net.i2p.crypto.eddsa; + +import java.security.KeyPair; + +import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; +import net.i2p.crypto.eddsa.spec.EdDSAPublicKeySpec; +import net.i2p.util.RandomSource; + +/** + * Default keysize is 256 (Ed25519) + * + * @since 0.9.39 + */ +public final class RedKeyPairGenerator extends KeyPairGenerator { + + @Override + public KeyPair generateKeyPair() { + if (!initialized) + initialize(DEFAULT_KEYSIZE, RandomSource.getInstance()); + + // 64 bytes + byte[] seed = new byte[edParams.getCurve().getField().getb()/4]; + random.nextBytes(seed); + byte[] b = EdDSABlinding.reduce(seed); + + EdDSAPrivateKeySpec privKey = new EdDSAPrivateKeySpec(b, null, edParams); + EdDSAPublicKeySpec pubKey = new EdDSAPublicKeySpec(privKey.getA(), edParams); + + return new KeyPair(new EdDSAPublicKey(pubKey), new EdDSAPrivateKey(privKey)); + } +} diff --git a/core/java/src/net/i2p/data/EncryptedLeaseSet.java b/core/java/src/net/i2p/data/EncryptedLeaseSet.java index f83f9c85b798736b23fd3308c62063f43cdb6eb2..0d70b9010ed9f6df3497284bd208617c56c0f298 100644 --- a/core/java/src/net/i2p/data/EncryptedLeaseSet.java +++ b/core/java/src/net/i2p/data/EncryptedLeaseSet.java @@ -82,7 +82,7 @@ public class EncryptedLeaseSet extends LeaseSet2 { /** * Overridden to set the blinded key * - * @param dest non-null, must be EdDSA_SHA512_Ed25519 + * @param dest non-null, must be EdDSA_SHA512_Ed25519 or RedDSA_SHA512_Ed25519 * @throws IllegalStateException if already signed * @throws IllegalArgumentException if not EdDSA */ @@ -90,7 +90,9 @@ public class EncryptedLeaseSet extends LeaseSet2 { public void setDestination(Destination dest) { super.setDestination(dest); SigningPublicKey spk = dest.getSigningPublicKey(); - if (spk.getType() != SigType.EdDSA_SHA512_Ed25519) + SigType type = spk.getType(); + if (type != SigType.EdDSA_SHA512_Ed25519 && + type != SigType.RedDSA_SHA512_Ed25519) throw new IllegalArgumentException(); SigningPublicKey bpk = blind(); if (_signingKey == null)