@@ -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.PRIVATE; | ||||
import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; | import static com.jd.blockchain.crypto.CryptoKeyType.PUBLIC; | ||||
import java.security.KeyPair; | |||||
import com.jd.blockchain.crypto.CryptoAlgorithm; | import com.jd.blockchain.crypto.CryptoAlgorithm; | ||||
import com.jd.blockchain.crypto.CryptoException; | import com.jd.blockchain.crypto.CryptoException; | ||||
import com.jd.blockchain.crypto.PrivKey; | 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.CryptoKeyPair; | ||||
import com.jd.blockchain.crypto.asymmetric.SignatureDigest; | import com.jd.blockchain.crypto.asymmetric.SignatureDigest; | ||||
import com.jd.blockchain.crypto.asymmetric.SignatureFunction; | 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 { | public class ED25519SignatureFunction implements SignatureFunction { | ||||
@@ -54,7 +49,9 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||||
} | } | ||||
// 调用ED25519签名算法计算签名结果 | // 调用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 | @Override | ||||
@@ -79,15 +76,17 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||||
} | } | ||||
// 调用ED25519验签算法验证签名结果 | // 调用ED25519验签算法验证签名结果 | ||||
return Ed25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||||
// return Ed25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||||
return ED25519Utils.verify(data, rawPubKeyBytes, rawDigestBytes); | |||||
} | } | ||||
@Override | @Override | ||||
public PubKey retrievePubKey(PrivKey privKey) { | public PubKey retrievePubKey(PrivKey privKey) { | ||||
byte[] rawPrivKeyBytes = privKey.getRawKeyBytes(); | 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); | return new PubKey(ED25519, rawPubKeyBytes); | ||||
} | } | ||||
// | // | ||||
@@ -157,11 +156,18 @@ public class ED25519SignatureFunction implements SignatureFunction { | |||||
@Override | @Override | ||||
public CryptoKeyPair generateKeyPair() { | public CryptoKeyPair generateKeyPair() { | ||||
// 调用ED25519算法的密钥生成算法生成公私钥对priKey和pubKey,返回密钥对 | // 调用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; | 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 | * @author zhanglin33 | ||||
* @title: ED25519Utils | * @title: ED25519Utils | ||||
@@ -7,4 +17,75 @@ package com.jd.blockchain.crypto.utils.classic; | |||||
* @date 2019-04-04, 20:01 | * @date 2019-04-04, 20:01 | ||||
*/ | */ | ||||
public class ED25519Utils { | 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(); | 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(); | ECMultiplier createBasePointMultiplier = new FixedPointCombMultiplier(); | ||||
ECPoint publicKeyPoint = createBasePointMultiplier.multiply(DOMAIN_PARAMS.getG(), new BigInteger(1,privateKey)).normalize(); | ECPoint publicKeyPoint = createBasePointMultiplier.multiply(DOMAIN_PARAMS.getG(), new BigInteger(1,privateKey)).normalize(); | ||||
return publicKeyPoint.getEncoded(false); | return publicKeyPoint.getEncoded(false); | ||||
@@ -103,12 +108,12 @@ public class SM2Utils { | |||||
return sign(data,param); | return sign(data,param); | ||||
} | } | ||||
public static byte[] sign(byte[] data, CipherParameters param){ | |||||
public static byte[] sign(byte[] data, CipherParameters params){ | |||||
SM2Signer signer = new SM2Signer(); | SM2Signer signer = new SM2Signer(); | ||||
// To get Z_A and prepare parameters | // To get Z_A and prepare parameters | ||||
signer.init(true,param); | |||||
signer.init(true,params); | |||||
// To fill the whole message to be signed | // To fill the whole message to be signed | ||||
signer.update(data,0,data.length); | signer.update(data,0,data.length); | ||||
// To get and return the signature result; | // To get and return the signature result; | ||||
@@ -137,6 +142,7 @@ public class SM2Utils { | |||||
* | * | ||||
* @param data data to be signed | * @param data data to be signed | ||||
* @param publicKey public key | * @param publicKey public key | ||||
* @param signature signature to be verified | |||||
* @return true or false | * @return true or false | ||||
*/ | */ | ||||
public static boolean verify(byte[] data, byte[] publicKey, byte[] signature){ | public static boolean verify(byte[] data, byte[] publicKey, byte[] signature){ | ||||