aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/secp256k1/secp256.go
diff options
context:
space:
mode:
authorYondon Fu <yondon.fu@gmail.com>2017-12-19 06:17:41 +0800
committerYondon Fu <yondon.fu@gmail.com>2017-12-19 06:17:41 +0800
commit3857cdc267e3192697f561df0a0f827f65dfb6b5 (patch)
tree401c52c4972a68229ea283a394a0b0a5f3cfdc8e /crypto/secp256k1/secp256.go
parenta5330fe0c569b75cb8a524f60f7e8dc06498262b (diff)
parentfe070ab5c32702033489f1b9d1655ea1b894c29e (diff)
downloaddexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar.gz
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar.bz2
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar.lz
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar.xz
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.tar.zst
dexon-3857cdc267e3192697f561df0a0f827f65dfb6b5.zip
Merge branch 'master' into abi-offset-fixed-arrays
Diffstat (limited to 'crypto/secp256k1/secp256.go')
-rw-r--r--crypto/secp256k1/secp256.go51
1 files changed, 50 insertions, 1 deletions
diff --git a/crypto/secp256k1/secp256.go b/crypto/secp256k1/secp256.go
index 0ffa04fe0..eefbb99ee 100644
--- a/crypto/secp256k1/secp256.go
+++ b/crypto/secp256k1/secp256.go
@@ -38,6 +38,7 @@ import "C"
import (
"errors"
+ "math/big"
"unsafe"
)
@@ -55,6 +56,7 @@ var (
ErrInvalidSignatureLen = errors.New("invalid signature length")
ErrInvalidRecoveryID = errors.New("invalid signature recovery id")
ErrInvalidKey = errors.New("invalid private key")
+ ErrInvalidPubkey = errors.New("invalid public key")
ErrSignFailed = errors.New("signing failed")
ErrRecoverFailed = errors.New("recovery failed")
)
@@ -113,12 +115,59 @@ func RecoverPubkey(msg []byte, sig []byte) ([]byte, error) {
sigdata = (*C.uchar)(unsafe.Pointer(&sig[0]))
msgdata = (*C.uchar)(unsafe.Pointer(&msg[0]))
)
- if C.secp256k1_ecdsa_recover_pubkey(context, (*C.uchar)(unsafe.Pointer(&pubkey[0])), sigdata, msgdata) == 0 {
+ if C.secp256k1_ext_ecdsa_recover(context, (*C.uchar)(unsafe.Pointer(&pubkey[0])), sigdata, msgdata) == 0 {
return nil, ErrRecoverFailed
}
return pubkey, nil
}
+// VerifySignature checks that the given pubkey created signature over message.
+// The signature should be in [R || S] format.
+func VerifySignature(pubkey, msg, signature []byte) bool {
+ if len(msg) != 32 || len(signature) != 64 || len(pubkey) == 0 {
+ return false
+ }
+ sigdata := (*C.uchar)(unsafe.Pointer(&signature[0]))
+ msgdata := (*C.uchar)(unsafe.Pointer(&msg[0]))
+ keydata := (*C.uchar)(unsafe.Pointer(&pubkey[0]))
+ return C.secp256k1_ext_ecdsa_verify(context, sigdata, msgdata, keydata, C.size_t(len(pubkey))) != 0
+}
+
+// DecompressPubkey parses a public key in the 33-byte compressed format.
+// It returns non-nil coordinates if the public key is valid.
+func DecompressPubkey(pubkey []byte) (x, y *big.Int) {
+ if len(pubkey) != 33 {
+ return nil, nil
+ }
+ var (
+ pubkeydata = (*C.uchar)(unsafe.Pointer(&pubkey[0]))
+ pubkeylen = C.size_t(len(pubkey))
+ out = make([]byte, 65)
+ outdata = (*C.uchar)(unsafe.Pointer(&out[0]))
+ outlen = C.size_t(len(out))
+ )
+ if C.secp256k1_ext_reencode_pubkey(context, outdata, outlen, pubkeydata, pubkeylen) == 0 {
+ return nil, nil
+ }
+ return new(big.Int).SetBytes(out[1:33]), new(big.Int).SetBytes(out[33:])
+}
+
+// CompressPubkey encodes a public key to 33-byte compressed format.
+func CompressPubkey(x, y *big.Int) []byte {
+ var (
+ pubkey = S256().Marshal(x, y)
+ pubkeydata = (*C.uchar)(unsafe.Pointer(&pubkey[0]))
+ pubkeylen = C.size_t(len(pubkey))
+ out = make([]byte, 33)
+ outdata = (*C.uchar)(unsafe.Pointer(&out[0]))
+ outlen = C.size_t(len(out))
+ )
+ if C.secp256k1_ext_reencode_pubkey(context, outdata, outlen, pubkeydata, pubkeylen) == 0 {
+ panic("libsecp256k1 error")
+ }
+ return out
+}
+
func checkSignature(sig []byte) error {
if len(sig) != 65 {
return ErrInvalidSignatureLen