-
Notifications
You must be signed in to change notification settings - Fork 26
/
secp256k1.go
93 lines (75 loc) · 2.02 KB
/
secp256k1.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package secp256k1
import (
"math/big"
"github.com/ElrondNetwork/wasm-vm/crypto/hashing"
"github.com/ElrondNetwork/wasm-vm/crypto/signing"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg/chainhash"
)
type MessageHashType uint8
const (
ECDSAPlainMsg MessageHashType = iota
ECDSASha256
ECDSADoubleSha256
ECDSAKeccak256
ECDSARipemd160
)
type secp256k1 struct {
}
func NewSecp256k1() *secp256k1 {
return &secp256k1{}
}
// VerifySecp256k1 checks a secp256k1 signature provided in the DER encoding format.
// The hash type used over the message can also be configured using @param hashType
func (sec *secp256k1) VerifySecp256k1(key, msg, sig []byte, hashType uint8) error {
pubKey, err := btcec.ParsePubKey(key, btcec.S256())
if err != nil {
return err
}
messageHash, err := sec.hashMessage(msg, hashType)
if err != nil {
return err
}
signature, err := btcec.ParseSignature(sig, btcec.S256())
if err != nil {
return err
}
verified := signature.Verify(messageHash, pubKey)
if !verified {
return signing.ErrInvalidSignature
}
return nil
}
// EncodeDERSecp256k1Signature creates a DER encoding of a signature provided with r and s.
// Useful when having the plain params - like in the case of ecrecover
// from ethereum
func (sec *secp256k1) EncodeSecp256k1DERSignature(r, s []byte) []byte {
sig := &btcec.Signature{
R: big.NewInt(0).SetBytes(r),
S: big.NewInt(0).SetBytes(s),
}
return sig.Serialize()
}
func (sec *secp256k1) hashMessage(msg []byte, hashType uint8) ([]byte, error) {
hasher := hashing.NewHasher()
var err error
var hashedMsg []byte
switch MessageHashType(hashType) {
case ECDSASha256:
hashedMsg, err = hasher.Sha256(msg)
case ECDSADoubleSha256:
hashedMsg = chainhash.DoubleHashB(msg)
case ECDSAKeccak256:
hashedMsg, err = hasher.Keccak256(msg)
case ECDSARipemd160:
hashedMsg, err = hasher.Ripemd160(msg)
case ECDSAPlainMsg:
hashedMsg = msg
default:
return nil, signing.ErrHasherNotSupported
}
if err != nil {
return nil, err
}
return hashedMsg, nil
}