This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 346
/
signature.go
67 lines (54 loc) · 1.64 KB
/
signature.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
package crypto
import (
"fmt"
"github.com/btcsuite/btcd/btcec"
hex "github.com/tmthrgd/go-hex"
"golang.org/x/crypto/ed25519"
)
func SignatureFromBytes(bs []byte, curveType CurveType) (*Signature, error) {
switch curveType {
case CurveTypeEd25519:
if len(bs) != ed25519.SignatureSize {
return nil, fmt.Errorf("bytes passed have length %v by ed25519 signatures have %v bytes",
len(bs), ed25519.SignatureSize)
}
case CurveTypeSecp256k1:
// TODO: validate?
}
return &Signature{CurveType: curveType, Signature: bs}, nil
}
func (sig *Signature) RawBytes() []byte {
return sig.Signature
}
func (sig *Signature) String() string {
return hex.EncodeUpperToString(sig.Signature)
}
func CompressedSignatureFromParams(v uint64, r, s []byte) []byte {
bitlen := (btcec.S256().BitSize + 7) / 8
sig := make([]byte, 1+bitlen*2)
sig[0] = byte(v)
copy(sig[1:bitlen+1], r)
copy(sig[bitlen+1:], s)
return sig
}
func UncompressedSignatureFromParams(r, s []byte) []byte {
// <0x30> <length of whole message>
// <0x02> <length of R> <R>
// <0x2> <length of S> <S>
rr := append([]byte{0x02, byte(len(r))}, r...)
ss := append([]byte{0x2, byte(len(s))}, s...)
rrss := append(rr, ss...)
return append([]byte{0x30, byte(len(rrss))}, rrss...)
}
// PublicKeyFromSignature verifies an ethereum compact signature and returns the public key if valid
func PublicKeyFromSignature(sig, hash []byte) (*PublicKey, error) {
pub, _, err := btcec.RecoverCompact(btcec.S256(), sig, hash)
if err != nil {
return nil, err
}
publicKey, err := PublicKeyFromBytes(pub.SerializeCompressed(), CurveTypeSecp256k1)
if err != nil {
return nil, err
}
return &publicKey, nil
}