diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/CryptoSuite.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/CryptoSuite.java index b03c84852..fe3a78971 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/CryptoSuite.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/CryptoSuite.java @@ -306,6 +306,28 @@ public boolean verify(final String publicKey, final byte[] message, final byte[] return this.signatureImpl.verify(publicKey, message, signature); } + /** + * recover address from signature + * + * @param msgHash the message hash, must be a digest + * @param signature the signature to be recovered + * @return the public key whitch can verify signature. + */ + public String recoverAddress(final String msgHash, final SignatureResult signature) { + return this.signatureImpl.recoverAddress(msgHash, signature); + } + + /** + * recover address from signature + * + * @param msgHash the byte array type message hash, must be a digest + * @param signature the byte array type signature to be recovered + * @return the public key whitch can verify signature. + */ + public String recoverAddress(final byte[] msgHash, final SignatureResult signature) { + return this.signatureImpl.recoverAddress(msgHash, signature); + } + /** * Create key pair * diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/ECDSASignature.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/ECDSASignature.java index ae32c2d73..9ac61e00d 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/ECDSASignature.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/ECDSASignature.java @@ -17,6 +17,7 @@ import com.webank.wedpr.crypto.NativeInterface; import org.fisco.bcos.sdk.v3.crypto.exceptions.SignatureException; import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.v3.crypto.keypair.ECDSAKeyPair; import org.fisco.bcos.sdk.v3.utils.Hex; import org.fisco.bcos.sdk.v3.utils.Numeric; @@ -88,4 +89,39 @@ public static boolean verifyMessage(String publicKey, String message, String sig } return verifyResult.booleanResult; } + + @Override + public String recoverAddress(final String msgHash, final SignatureResult signature) { + return ecrecoverSignature(msgHash, signature); + } + + @Override + public String recoverAddress(final byte[] msgHash, final SignatureResult signature) { + return recoverAddress(Hex.toHexString(msgHash), signature); + } + + public static String ecrecoverSignature(String msgHash, SignatureResult signature) { + String publicKey = getPubFromSignature(msgHash, signature); + return ECDSAKeyPair.getAddressByPublicKey(publicKey); + } + + @Override + public String recoverPublicKey(final String msgHash, final SignatureResult signature) { + return getPubFromSignature(msgHash, signature); + } + + @Override + public String recoverPublicKey(final byte[] msgHash, final SignatureResult signature) { + return recoverPublicKey(Hex.toHexString(msgHash), signature); + } + + public static String getPubFromSignature(String msgHash, SignatureResult signature) { + CryptoResult verifyResult = + NativeInterface.secp256k1RecoverPublicKey(msgHash, signature.toString()); + if (verifyResult.wedprErrorMessage != null && !verifyResult.wedprErrorMessage.isEmpty()) { + throw new SignatureException( + "Recover public key failed:" + verifyResult.wedprErrorMessage); + } + return verifyResult.getPublicKey(); + } } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/HsmSM2Signature.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/HsmSM2Signature.java index 97069ea86..63925b73a 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/HsmSM2Signature.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/HsmSM2Signature.java @@ -97,4 +97,33 @@ public boolean verifyMessage(String publicKey, String message, String signature) return false; } } + + @Override + public String recoverAddress(final String msgHash, final SignatureResult signature) { + return ecrecoverSignature(msgHash, signature); + } + + @Override + public String recoverAddress(final byte[] msgHash, final SignatureResult signature) { + return recoverAddress(Hex.toHexString(msgHash), signature); + } + + public static String ecrecoverSignature(String msgHash, SignatureResult signature) { + // String publicKey = getPubFromSignature(msgHash, signature); + return ""; + } + + @Override + public String recoverPublicKey(final String msgHash, final SignatureResult signature) { + return getPubFromSignature(msgHash, signature); + } + + @Override + public String recoverPublicKey(final byte[] msgHash, final SignatureResult signature) { + return recoverPublicKey(Hex.toHexString(msgHash), signature); + } + + public static String getPubFromSignature(String msgHash, SignatureResult signature) { + return Hex.toHexString(signature.getPub()); + } } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SM2Signature.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SM2Signature.java index 0cab7d82e..f170878d3 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SM2Signature.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SM2Signature.java @@ -17,6 +17,7 @@ import com.webank.wedpr.crypto.NativeInterface; import org.fisco.bcos.sdk.v3.crypto.exceptions.SignatureException; import org.fisco.bcos.sdk.v3.crypto.keypair.CryptoKeyPair; +import org.fisco.bcos.sdk.v3.crypto.keypair.SM2KeyPair; import org.fisco.bcos.sdk.v3.utils.Hex; import org.fisco.bcos.sdk.v3.utils.Numeric; @@ -74,4 +75,33 @@ public static boolean verifyMessage(String publicKey, String message, String sig } return verifyResult.booleanResult; } + + @Override + public String recoverAddress(final String msgHash, final SignatureResult signature) { + return ecrecoverSignature(msgHash, signature); + } + + @Override + public String recoverAddress(final byte[] msgHash, final SignatureResult signature) { + return recoverAddress(Hex.toHexString(msgHash), signature); + } + + public static String ecrecoverSignature(String msgHash, SignatureResult signature) { + String publicKey = getPubFromSignature(msgHash, signature); + return SM2KeyPair.getAddressByPublicKey(publicKey); + } + + @Override + public String recoverPublicKey(final String msgHash, final SignatureResult signature) { + return getPubFromSignature(msgHash, signature); + } + + @Override + public String recoverPublicKey(final byte[] msgHash, final SignatureResult signature) { + return recoverPublicKey(Hex.toHexString(msgHash), signature); + } + + public static String getPubFromSignature(String msgHash, SignatureResult signature) { + return Hex.toHexString(signature.getPub()); + } } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/Signature.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/Signature.java index 8adf21004..9fa54a907 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/Signature.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/Signature.java @@ -64,4 +64,40 @@ public interface Signature { * @return true/false */ boolean verify(final String publicKey, final byte[] message, final byte[] signature); + + /** + * recover address from signature + * + * @param msgHash the message hash, must be a digest + * @param signature the signature to be recovered + * @return the address who sign the msgHash. + */ + String recoverAddress(final String msgHash, final SignatureResult signature); + + /** + * recover address from signature + * + * @param msgHash the byte array type message hash, must be a digest + * @param signature the byte array type signature to be recovered + * @return the address who sign the msgHash. + */ + String recoverAddress(final byte[] msgHash, final SignatureResult signature); + + /** + * recover public from signature + * + * @param msgHash the message hash, must be a digest + * @param signature the signature to be recovered + * @return the public key which can verify signature. + */ + String recoverPublicKey(final String msgHash, final SignatureResult signature); + + /** + * recover address from signature + * + * @param msgHash the byte array type message hash, must be a digest + * @param signature the byte array type signature to be recovered + * @return the public key which can verify signature. + */ + String recoverPublicKey(final byte[] msgHash, final SignatureResult signature); } diff --git a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SignatureResult.java b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SignatureResult.java index bfae007b3..221ae84ef 100644 --- a/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SignatureResult.java +++ b/src/main/java/org/fisco/bcos/sdk/v3/crypto/signature/SignatureResult.java @@ -60,6 +60,10 @@ public byte[] getS() { return this.s; } + public byte[] getPub() { + return new byte[] {}; + } + public byte[] getSignatureBytes() { return this.signatureBytes; } diff --git a/src/test/java/org/fisco/bcos/sdk/v3/test/crypto/SignatureTest.java b/src/test/java/org/fisco/bcos/sdk/v3/test/crypto/SignatureTest.java index 0edc115c5..c89135575 100644 --- a/src/test/java/org/fisco/bcos/sdk/v3/test/crypto/SignatureTest.java +++ b/src/test/java/org/fisco/bcos/sdk/v3/test/crypto/SignatureTest.java @@ -365,6 +365,8 @@ public void testECDSASignature(CryptoSuite cryptoSuite, CryptoKeyPair keyPair) { Assert.assertEquals(message, Hex.toHexString(messageBytes)); // sign ECDSASignatureResult signatureResult = (ECDSASignatureResult) cryptoSuite.sign(message, keyPair); + //ecrecover + Assert.assertEquals(keyPair.getAddress(), cryptoSuite.recoverAddress(message, signatureResult)); // verify Assert.assertTrue( cryptoSuite.verify( @@ -376,6 +378,7 @@ public void testECDSASignature(CryptoSuite cryptoSuite, CryptoKeyPair keyPair) { // new sign ECDSASignatureResult newSign = new ECDSASignatureResult(signatureResult.getV(), signatureResult.getR(), signatureResult.getS()); + Assert.assertEquals(keyPair.getAddress(), cryptoSuite.recoverAddress(message, newSign)); Assert.assertTrue( cryptoSuite.verify( keyPair.getHexPublicKey(), message, newSign.convertToString())); @@ -418,6 +421,8 @@ public void testSMSignature(CryptoSuite cryptoSuite, CryptoKeyPair keyPair) { Assert.assertEquals(message, Hex.toHexString(messageBytes)); // sign SM2SignatureResult signatureResult = (SM2SignatureResult) cryptoSuite.sign(message, keyPair); + //ecrecover + Assert.assertEquals(keyPair.getAddress(), cryptoSuite.recoverAddress(message, signatureResult)); // verify Assert.assertTrue( cryptoSuite.verify( @@ -429,6 +434,7 @@ public void testSMSignature(CryptoSuite cryptoSuite, CryptoKeyPair keyPair) { // new sign SM2SignatureResult newSign = new SM2SignatureResult(signatureResult.getPub(), signatureResult.getR(), signatureResult.getS()); + Assert.assertEquals(keyPair.getAddress(), cryptoSuite.recoverAddress(message, newSign)); Assert.assertTrue( cryptoSuite.verify( keyPair.getHexPublicKey(), message, newSign.convertToString()));