forked from I2P_Developers/i2p.i2p
EdDSA:
- Add hashCode() and equals() everywhere it was missing, so we can test keys for equality: Curve, EdDSAParameterSpec, EdDSAPrivateKey, and EdDSAPublicKey - Speedup for GroupElement.equals() - Fix public key decode() - Put unknown class name in exceptions - indent fixes Provider: - Add KeyFactory aliases required for cert.verify() - Fix EdDSA signature OID SelfSigned: - Add simple tests after generation using cert.verify() and key equality
This commit is contained in:
@ -153,6 +153,12 @@ public final class SelfSignedGenerator {
|
||||
throw new GeneralSecurityException("cert error", iae);
|
||||
}
|
||||
|
||||
// some simple tests
|
||||
PublicKey cpub = cert.getPublicKey();
|
||||
cert.verify(cpub);
|
||||
if (!cpub.equals(jpub))
|
||||
throw new GeneralSecurityException("pubkey mismatch");
|
||||
|
||||
Object[] rv = { jpub, jpriv, cert };
|
||||
return rv;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.i2p.crypto.eddsa;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.i2p.crypto.eddsa.math.GroupElement;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||
@ -152,8 +153,9 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 0x04 ||
|
||||
d[idx++] != 32)
|
||||
throw new InvalidKeySpecException("unsupported key spec");
|
||||
d[idx++] != 32) {
|
||||
throw new InvalidKeySpecException("unsupported key spec");
|
||||
}
|
||||
byte[] rv = new byte[32];
|
||||
System.arraycopy(d, idx, rv, 0, 32);
|
||||
return rv;
|
||||
@ -185,4 +187,26 @@ public class EdDSAPrivateKey implements EdDSAKey, PrivateKey {
|
||||
public byte[] getAbyte() {
|
||||
return Abyte;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(seed);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof EdDSAPrivateKey))
|
||||
return false;
|
||||
EdDSAPrivateKey pk = (EdDSAPrivateKey) o;
|
||||
return Arrays.equals(seed, pk.getSeed()) &&
|
||||
edDsaSpec.equals(pk.getParams());
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.i2p.crypto.eddsa;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.i2p.crypto.eddsa.math.GroupElement;
|
||||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable;
|
||||
@ -126,9 +127,10 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 1 ||
|
||||
d[idx++] != 0x03 ||
|
||||
d[idx++] != 32 ||
|
||||
d[idx++] != 0)
|
||||
throw new InvalidKeySpecException("unsupported key spec");
|
||||
d[idx++] != 33 ||
|
||||
d[idx++] != 0) {
|
||||
throw new InvalidKeySpecException("unsupported key spec");
|
||||
}
|
||||
byte[] rv = new byte[32];
|
||||
System.arraycopy(d, idx, rv, 0, 32);
|
||||
return rv;
|
||||
@ -152,4 +154,26 @@ public class EdDSAPublicKey implements EdDSAKey, PublicKey {
|
||||
public byte[] getAbyte() {
|
||||
return Abyte;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(Abyte);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof EdDSAPublicKey))
|
||||
return false;
|
||||
EdDSAPublicKey pk = (EdDSAPublicKey) o;
|
||||
return Arrays.equals(Abyte, pk.getAbyte()) &&
|
||||
edDsaSpec.equals(pk.getParams());
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public final class KeyFactory extends KeyFactorySpi {
|
||||
if (keySpec instanceof PKCS8EncodedKeySpec) {
|
||||
return new EdDSAPrivateKey((PKCS8EncodedKeySpec) keySpec);
|
||||
}
|
||||
throw new InvalidKeySpecException("key spec not recognised");
|
||||
throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,7 +45,7 @@ public final class KeyFactory extends KeyFactorySpi {
|
||||
if (keySpec instanceof X509EncodedKeySpec) {
|
||||
return new EdDSAPublicKey((X509EncodedKeySpec) keySpec);
|
||||
}
|
||||
throw new InvalidKeySpecException("key spec not recognised");
|
||||
throw new InvalidKeySpecException("key spec not recognised: " + keySpec.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -69,4 +69,29 @@ public class Curve implements Serializable {
|
||||
ge.precompute(true);
|
||||
return ge;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return f.hashCode() ^
|
||||
d.hashCode() ^
|
||||
I.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof Curve))
|
||||
return false;
|
||||
Curve c = (Curve) o;
|
||||
return f.equals(c.getField()) &&
|
||||
d.equals(c.getD()) &&
|
||||
I.equals(c.getI());
|
||||
}
|
||||
}
|
||||
|
@ -60,4 +60,6 @@ public abstract class FieldElement implements Serializable {
|
||||
public abstract FieldElement invert();
|
||||
|
||||
public abstract FieldElement pow22523();
|
||||
|
||||
// Note: concrete subclasses must implement hashCode() and equals()
|
||||
}
|
||||
|
@ -716,6 +716,8 @@ public class GroupElement implements Serializable {
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (!(obj instanceof GroupElement))
|
||||
return false;
|
||||
GroupElement ge = (GroupElement) obj;
|
||||
|
@ -59,4 +59,29 @@ public class EdDSAParameterSpec implements AlgorithmParameterSpec, Serializable
|
||||
public GroupElement getB() {
|
||||
return B;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return hashAlgo.hashCode() ^
|
||||
curve.hashCode() ^
|
||||
B.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.25
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (!(o instanceof EdDSAParameterSpec))
|
||||
return false;
|
||||
EdDSAParameterSpec s = (EdDSAParameterSpec) o;
|
||||
return hashAlgo.equals(s.getHashAlgorithm()) &&
|
||||
curve.equals(s.getCurve()) &&
|
||||
B.equals(s.getB());
|
||||
}
|
||||
}
|
||||
|
@ -50,19 +50,22 @@ public final class I2PProvider extends Provider {
|
||||
//put("Signature.SHA1withDSA", "net.i2p.crypto.provider.SignatureSpi");
|
||||
|
||||
// EdDSA
|
||||
// OID: 1.3.101.100
|
||||
// Key OID: 1.3.101.100; Sig OID: 1.3.101.101
|
||||
put("KeyFactory.EdDSA", "net.i2p.crypto.eddsa.KeyFactory");
|
||||
put("KeyPairGenerator.EdDSA", "net.i2p.crypto.eddsa.KeyPairGenerator");
|
||||
put("Signature.SHA512withEdDSA", "net.i2p.crypto.eddsa.EdDSAEngine");
|
||||
// Didn't find much documentation on these at all,
|
||||
// see http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/HowToImplAProvider.html
|
||||
// section "Mapping from OID to name"
|
||||
// without these, Certificate.verify() fails
|
||||
put("Alg.Alias.KeyFactory.1.3.101.100", "EdDSA");
|
||||
put("Alg.Alias.KeyFactory.OID.1.3.101.100", "EdDSA");
|
||||
// Without these, keytool fails with:
|
||||
// keytool error: java.security.NoSuchAlgorithmException: unrecognized algorithm name: SHA512withEdDSA
|
||||
put("Alg.Alias.KeyPairGenerator.1.3.101.100", "EdDSA");
|
||||
put("Alg.Alias.KeyPairGenerator.OID.1.3.101.100", "EdDSA");
|
||||
put("Alg.Alias.Signature.1.3.101.100", "SHA512withEdDSA");
|
||||
put("Alg.Alias.Signature.OID.1.3.101.100", "SHA512withEdDSA");
|
||||
put("Alg.Alias.Signature.1.3.101.101", "SHA512withEdDSA");
|
||||
put("Alg.Alias.Signature.OID.1.3.101.101", "SHA512withEdDSA");
|
||||
// TODO Ed25519ph
|
||||
// OID: 1.3.101.101
|
||||
|
||||
@ -75,6 +78,8 @@ public final class I2PProvider extends Provider {
|
||||
put("KeyPairGenerator.DiffieHellman", "net.i2p.crypto.elgamal.KeyPairGenerator");
|
||||
put("KeyPairGenerator.ElGamal", "net.i2p.crypto.elgamal.KeyPairGenerator");
|
||||
put("Signature.SHA256withElGamal", "net.i2p.crypto.elgamal.ElGamalSigEngine");
|
||||
put("Alg.Alias.KeyFactory.1.3.14.7.2.1.1", "ElGamal");
|
||||
put("Alg.Alias.KeyFactory.OID.1.3.14.7.2.1.1", "ElGamal");
|
||||
put("Alg.Alias.KeyPairGenerator.1.3.14.7.2.1.1", "ElGamal");
|
||||
put("Alg.Alias.KeyPairGenerator.OID.1.3.14.7.2.1.1", "ElGamal");
|
||||
put("Alg.Alias.Signature.1.3.14.7.2.1.1", "SHA256withElGamal");
|
||||
|
Reference in New Issue
Block a user