@@ -5,8 +5,6 @@ import static com.jd.blockchain.crypto.CryptoBytes.ALGORYTHM_CODE_SIZE; | |||
import static com.jd.blockchain.crypto.CryptoKeyType.PRIVATE; | |||
import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; | |||
import java.security.KeyPair; | |||
import com.jd.blockchain.crypto.CryptoAlgorithm; | |||
import com.jd.blockchain.crypto.CryptoException; | |||
import com.jd.blockchain.crypto.PrivKey; | |||
@@ -14,14 +12,11 @@ import com.jd.blockchain.crypto.PubKey; | |||
import com.jd.blockchain.crypto.asymmetric.CryptoKeyPair; | |||
import com.jd.blockchain.crypto.asymmetric.SignatureDigest; | |||
import com.jd.blockchain.crypto.asymmetric.SignatureFunction; | |||
import com.jd.blockchain.utils.security.Ed25519Utils; | |||
import com.jd.blockchain.crypto.utils.classic.ED25519Utils; | |||
import net.i2p.crypto.eddsa.EdDSAPrivateKey; | |||
import net.i2p.crypto.eddsa.EdDSAPublicKey; | |||
import net.i2p.crypto.eddsa.KeyPairGenerator; | |||
import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable; | |||
import net.i2p.crypto.eddsa.spec.EdDSAParameterSpec; | |||
import net.i2p.crypto.eddsa.spec.EdDSAPrivateKeySpec; | |||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; | |||
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; | |||
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; | |||
public class ED25519SignatureFunction implements SignatureFunction { | |||
@@ -54,7 +49,9 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
} | |||
// 调用ED25519签名算法计算签名结果 | |||
return new SignatureDigest(ED25519, Ed25519Utils.sign_512(data, rawPrivKeyBytes)); | |||
// return new SignatureDigest(ED25519, Ed25519Utils.sign_512(data, rawPrivKeyBytes)); | |||
return new SignatureDigest(ED25519, ED25519Utils.sign(data, rawPrivKeyBytes)); | |||
} | |||
@Override | |||
@@ -79,15 +76,17 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
} | |||
// 调用ED25519验签算法验证签名结果 | |||
return Ed25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
// return Ed25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
return ED25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||
} | |||
@Override | |||
public PubKey retrievePubKey(PrivKey privKey) { | |||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | |||
EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512); | |||
EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(rawPrivKeyBytes, spec); | |||
byte[] rawPubKeyBytes = privateKeySpec.getA().toByteArray(); | |||
byte[] rawPubKeyBytes = ED25519Utils.retrievePublicKey(rawPrivKeyBytes); | |||
// EdDSAParameterSpec spec = EdDSANamedCurveTable.getByName(EdDSANamedCurveTable.CURVE_ED25519_SHA512); | |||
// EdDSAPrivateKeySpec privateKeySpec = new EdDSAPrivateKeySpec(rawPrivKeyBytes, spec); | |||
// byte[] rawPubKeyBytes = privateKeySpec.getA().toByteArray(); | |||
return new PubKey(ED25519, rawPubKeyBytes); | |||
} | |||
// | |||
@@ -157,11 +156,18 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||
@Override | |||
public CryptoKeyPair generateKeyPair() { | |||
// 调用ED25519算法的密钥生成算法生成公私钥对priKey和pubKey,返回密钥对 | |||
KeyPairGenerator keyPairGenerator = new KeyPairGenerator(); | |||
KeyPair keyPair = keyPairGenerator.generateKeyPair(); | |||
EdDSAPrivateKey privKey = (EdDSAPrivateKey) keyPair.getPrivate(); | |||
EdDSAPublicKey pubKey = (EdDSAPublicKey) keyPair.getPublic(); | |||
return new CryptoKeyPair(new PubKey(ED25519, pubKey.getAbyte()), new PrivKey(ED25519, privKey.getSeed())); | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
Ed25519PublicKeyParameters pubKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
// KeyPairGenerator keyPairGenerator = new KeyPairGenerator(); | |||
// KeyPair keyPair = keyPairGenerator.generateKeyPair(); | |||
// EdDSAPrivateKey privKey = (EdDSAPrivateKey) keyPair.getPrivate(); | |||
// EdDSAPublicKey pubKey = (EdDSAPublicKey) keyPair.getPublic(); | |||
// return new CryptoKeyPair(new PubKey(ED25519, pubKey.getAbyte()), new PrivKey(ED25519, privKey.getSeed())); | |||
return new CryptoKeyPair(new PubKey(ED25519, pubKeyBytes), new PrivKey(ED25519, privKeyBytes)); | |||
} | |||
} |
@@ -1,5 +1,15 @@ | |||
package com.jd.blockchain.crypto.utils.classic; | |||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; | |||
import org.bouncycastle.crypto.CipherParameters; | |||
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator; | |||
import org.bouncycastle.crypto.params.Ed25519KeyGenerationParameters; | |||
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; | |||
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; | |||
import org.bouncycastle.crypto.signers.Ed25519Signer; | |||
import java.security.SecureRandom; | |||
/** | |||
* @author zhanglin33 | |||
* @title: ED25519Utils | |||
@@ -7,4 +17,75 @@ package com.jd.blockchain.crypto.utils.classic; | |||
* @date 2019-04-04, 20:01 | |||
*/ | |||
public class ED25519Utils { | |||
//-----------------Key Pair Generation Algorithm----------------- | |||
/** | |||
* key generation | |||
* | |||
* @return key pair | |||
*/ | |||
public static AsymmetricCipherKeyPair generateKeyPair(){ | |||
SecureRandom random = new SecureRandom(); | |||
return generateKeyPair(random); | |||
} | |||
public static AsymmetricCipherKeyPair generateKeyPair(SecureRandom random){ | |||
Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator(); | |||
keyPairGenerator.init(new Ed25519KeyGenerationParameters(random)); | |||
return keyPairGenerator.generateKeyPair(); | |||
} | |||
/** | |||
* public retrieval | |||
* | |||
* @param privateKey private key | |||
* @return publicKey | |||
*/ | |||
public static byte[] retrievePublicKey(byte[] privateKey){ | |||
Ed25519PrivateKeyParameters privKeyParams = new Ed25519PrivateKeyParameters(privateKey,0); | |||
return privKeyParams.generatePublicKey().getEncoded(); | |||
} | |||
//-----------------Digital Signature Algorithm----------------- | |||
/** | |||
* signature generation | |||
* | |||
* @param data data to be signed | |||
* @param privateKey private key | |||
* @return signature | |||
*/ | |||
public static byte[] sign(byte[] data, byte[] privateKey){ | |||
Ed25519PrivateKeyParameters privKeyParams = new Ed25519PrivateKeyParameters(privateKey,0); | |||
return sign(data,privKeyParams); | |||
} | |||
public static byte[] sign(byte[] data, CipherParameters params){ | |||
Ed25519Signer signer = new Ed25519Signer(); | |||
signer.init(true, params); | |||
signer.update(data,0,data.length); | |||
return signer.generateSignature(); | |||
} | |||
/** | |||
* verification | |||
* | |||
* @param data data to be signed | |||
* @param publicKey public key | |||
* @param signature signature to be verified | |||
* @return true or false | |||
*/ | |||
public static boolean verify(byte[] data, byte[] publicKey, byte[] signature){ | |||
Ed25519PublicKeyParameters pubKeyParams = new Ed25519PublicKeyParameters(publicKey,0); | |||
return verify(data,pubKeyParams,signature); | |||
} | |||
public static boolean verify(byte[] data, CipherParameters params, byte[] signature){ | |||
Ed25519Signer verifier = new Ed25519Signer(); | |||
verifier.init(false, params); | |||
verifier.update(data,0,data.length); | |||
return verifier.verifySignature(signature); | |||
} | |||
} |
@@ -0,0 +1,111 @@ | |||
package test.com.jd.blockchain.crypto.utils.classic; | |||
import com.jd.blockchain.crypto.utils.classic.ED25519Utils; | |||
import com.jd.blockchain.utils.security.Ed25519Utils; | |||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; | |||
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters; | |||
import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; | |||
import org.junit.Test; | |||
import java.util.Random; | |||
import static org.junit.Assert.*; | |||
/** | |||
* @author zhanglin33 | |||
* @title: ED25519UtilsTest | |||
* @description: Tests for methods in ED25519Utils | |||
* @date 2019-04-08, 16:32 | |||
*/ | |||
public class ED25519UtilsTest { | |||
@Test | |||
public void generateKeyPairTest(){ | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
Ed25519PublicKeyParameters pubKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
assertEquals(32,privKeyBytes.length); | |||
assertEquals(32,pubKeyBytes.length); | |||
} | |||
@Test | |||
public void retrievePublicKeyTest(){ | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
Ed25519PublicKeyParameters pubKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
byte[] retrievedPubKeyBytes = ED25519Utils.retrievePublicKey(privKeyBytes); | |||
assertArrayEquals(pubKeyBytes,retrievedPubKeyBytes); | |||
} | |||
@Test | |||
public void signTest(){ | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
Random random = new Random(); | |||
byte[] data = new byte[1024]; | |||
random.nextBytes(data); | |||
byte[] signatureDigestFromBytes = ED25519Utils.sign(data,privKeyBytes); | |||
byte[] signatureDigestFromParams = ED25519Utils.sign(data,privKeyBytes); | |||
assertArrayEquals(signatureDigestFromBytes,signatureDigestFromParams); | |||
assertEquals(64,signatureDigestFromBytes.length); | |||
} | |||
@Test | |||
public void verifyTest(){ | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
Ed25519PublicKeyParameters pubKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
Random random = new Random(); | |||
byte[] data = new byte[1024]; | |||
random.nextBytes(data); | |||
byte[] signatureDigest = ED25519Utils.sign(data,privKeyParams); | |||
assertTrue(ED25519Utils.verify(data,pubKeyParams,signatureDigest)); | |||
assertTrue(ED25519Utils.verify(data,pubKeyBytes,signatureDigest)); | |||
} | |||
@Test | |||
public void consistencyTest(){ | |||
AsymmetricCipherKeyPair keyPair = ED25519Utils.generateKeyPair(); | |||
Ed25519PrivateKeyParameters privKeyParams = (Ed25519PrivateKeyParameters) keyPair.getPrivate(); | |||
Ed25519PublicKeyParameters pubKeyParams = (Ed25519PublicKeyParameters) keyPair.getPublic(); | |||
byte[] pubKeyBytes = pubKeyParams.getEncoded(); | |||
byte[] privKeyBytes = privKeyParams.getEncoded(); | |||
Random random = new Random(); | |||
byte[] data = new byte[1024]; | |||
random.nextBytes(data); | |||
byte[] signatureDigest = ED25519Utils.sign(data,privKeyParams); | |||
byte[] signatureDigestFromOlderVersion = Ed25519Utils.sign_512(data,privKeyBytes); | |||
assertArrayEquals(signatureDigest,signatureDigestFromOlderVersion); | |||
assertTrue(Ed25519Utils.verify(data,pubKeyBytes,signatureDigest)); | |||
} | |||
} |
@@ -68,8 +68,13 @@ public class SM2Utils { | |||
return keyPairGenerator.generateKeyPair(); | |||
} | |||
public static byte[] retrievePublicKey(byte[] privateKey) | |||
{ | |||
/** | |||
* public retrieval | |||
* | |||
* @param privateKey private key | |||
* @return publicKey | |||
*/ | |||
public static byte[] retrievePublicKey(byte[] privateKey) { | |||
ECMultiplier createBasePointMultiplier = new FixedPointCombMultiplier(); | |||
ECPoint publicKeyPoint = createBasePointMultiplier.multiply(DOMAIN_PARAMS.getG(), new BigInteger(1,privateKey)).normalize(); | |||
return publicKeyPoint.getEncoded(false); | |||
@@ -103,12 +108,12 @@ public class SM2Utils { | |||
return sign(data,param); | |||
} | |||
public static byte[] sign(byte[] data, CipherParameters param){ | |||
public static byte[] sign(byte[] data, CipherParameters params){ | |||
SM2Signer signer = new SM2Signer(); | |||
// To get Z_A and prepare parameters | |||
signer.init(true,param); | |||
signer.init(true,params); | |||
// To fill the whole message to be signed | |||
signer.update(data,0,data.length); | |||
// To get and return the signature result; | |||
@@ -137,6 +142,7 @@ public class SM2Utils { | |||
* | |||
* @param data data to be signed | |||
* @param publicKey public key | |||
* @param signature signature to be verified | |||
* @return true or false | |||
*/ | |||
public static boolean verify(byte[] data, byte[] publicKey, byte[] signature){ | |||