Skip to content

Commit 66a5ab5

Browse files
bitcoin sig: add public key into signature (#670)
* bitcoin sig: add public key into signature
1 parent adad659 commit 66a5ab5

File tree

8 files changed

+881
-87
lines changed

8 files changed

+881
-87
lines changed

cmd/transaction/generator.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,25 @@ func GenerateBasicTransaction(
250250
senderAccountAddress = crypto.NewEd25519Signature().GetAddressFromSeed(senderSeed)
251251
case model.SignatureType_BitcoinSignature:
252252
var (
253-
bitcoinSig = crypto.NewBitcoinSignature(crypto.DefaultBitcoinNetworkParams(), crypto.DefaultBitcoinCurve())
254-
pubKey = bitcoinSig.GetPublicKeyFromSeed(senderSeed, crypto.DefaultBitcoinPublicKeyFormat())
255-
err error
253+
bitcoinSig = crypto.NewBitcoinSignature(crypto.DefaultBitcoinNetworkParams(), crypto.DefaultBitcoinCurve())
254+
pubKey, err = bitcoinSig.GetPublicKeyFromSeed(
255+
senderSeed,
256+
crypto.DefaultBitcoinPublicKeyFormat(),
257+
crypto.DefaultBitcoinPrivateKeyLength(),
258+
)
256259
)
257-
senderAccountAddress, err = bitcoinSig.GetAddressPublicKey(pubKey)
258260
if err != nil {
259-
fmt.Println("GenerateBasicTransaction-BitcoinSignature-Failed GetPublicKey")
261+
panic(fmt.Sprintln(
262+
"GenerateBasicTransaction-BitcoinSignature-Failed GetPublicKey",
263+
err.Error(),
264+
))
265+
}
266+
senderAccountAddress, err = bitcoinSig.GetAddressFromPublicKey(pubKey)
267+
if err != nil {
268+
panic(fmt.Sprintln(
269+
"GenerateBasicTransaction-BitcoinSignature-Failed GetPublicKey",
270+
err.Error(),
271+
))
260272
}
261273
default:
262274
panic("GenerateBasicTransaction-Invalid Signature Type")

common/crypto/bitcoinSignature.go

Lines changed: 76 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package crypto
22

33
import (
4+
"hash"
5+
46
"github.com/btcsuite/btcd/btcec"
57
"github.com/btcsuite/btcd/chaincfg"
68
"github.com/btcsuite/btcutil"
9+
"github.com/zoobc/zoobc-core/common/blocker"
10+
"github.com/zoobc/zoobc-core/common/model"
711
"golang.org/x/crypto/sha3"
812
)
913

@@ -30,9 +34,14 @@ func DefaultBitcoinCurve() *btcec.KoblitzCurve {
3034
}
3135

3236
// DefaultBitcoinPublicKeyFormat return recommended public key format
33-
func DefaultBitcoinPublicKeyFormat() btcutil.PubKeyFormat {
37+
func DefaultBitcoinPublicKeyFormat() model.BitcoinPublicKeyFormat {
3438
// https://bitcoin.org/en/glossary/compressed-public-key
35-
return btcutil.PKFCompressed
39+
return model.BitcoinPublicKeyFormat_PublicKeyFormatCompressed
40+
}
41+
42+
// DefaultBitcoinPrivateKeyLength to
43+
func DefaultBitcoinPrivateKeyLength() model.PrivateKeyBytesLength {
44+
return model.PrivateKeyBytesLength_PrivateKey256Bits
3645
}
3746

3847
// NewBitcoinSignature is new instance of bitcoin signature
@@ -47,7 +56,7 @@ func NewBitcoinSignature(netParams *chaincfg.Params, curve *btcec.KoblitzCurve)
4756
func (*BitcoinSignature) Sign(privateKey *btcec.PrivateKey, payload []byte) ([]byte, error) {
4857
var sig, err = privateKey.Sign(payload)
4958
if err != nil {
50-
return nil, err
59+
return nil, blocker.NewBlocker(blocker.AuthErr, err.Error())
5160
}
5261
return sig.Serialize(), nil
5362
}
@@ -67,70 +76,101 @@ func (b *BitcoinSignature) GetNetworkParams() *chaincfg.Params {
6776
}
6877

6978
// GetPrivateKeyFromSeed to get private key form seed
70-
func (b *BitcoinSignature) GetPrivateKeyFromSeed(seed string) *btcec.PrivateKey {
79+
func (b *BitcoinSignature) GetPrivateKeyFromSeed(
80+
seed string,
81+
privkeyLength model.PrivateKeyBytesLength,
82+
) (*btcec.PrivateKey, error) {
7183
var (
7284
// Convert seed (secret phrase) to byte array
7385
seedBuffer = []byte(seed)
74-
// Compute SHA3-256 hash of seed (secret phrase)
75-
seedHash = sha3.Sum256(seedBuffer)
76-
privateKey, _ = btcec.PrivKeyFromBytes(b.Curve, seedHash[:])
86+
hasher hash.Hash
87+
privateKey *btcec.PrivateKey
7788
)
78-
return privateKey
89+
switch privkeyLength {
90+
case model.PrivateKeyBytesLength_PrivateKey256Bits:
91+
hasher = sha3.New256()
92+
case model.PrivateKeyBytesLength_PrivateKey384Bits:
93+
hasher = sha3.New384()
94+
case model.PrivateKeyBytesLength_PrivateKey512Bits:
95+
hasher = sha3.New512()
96+
default:
97+
return nil, blocker.NewBlocker(blocker.AppErr, "invalidPrivateKeyLength")
98+
}
99+
hasher.Write(seedBuffer)
100+
privateKey, _ = btcec.PrivKeyFromBytes(b.Curve, hasher.Sum(nil))
101+
return privateKey, nil
79102
}
80103

81104
// GetPublicKeyFromSeed Get the raw public key corresponding to a seed (secret phrase)
105+
func (b *BitcoinSignature) GetPublicKeyFromSeed(
106+
seed string,
107+
format model.BitcoinPublicKeyFormat,
108+
privkeyLength model.PrivateKeyBytesLength,
109+
) ([]byte, error) {
110+
var privateKey, err = b.GetPrivateKeyFromSeed(seed, privkeyLength)
111+
if err != nil {
112+
return nil, err
113+
}
114+
publicKey, err := b.GetPublicKeyFromPrivateKey(privateKey, format)
115+
if err != nil {
116+
return nil, err
117+
}
118+
return publicKey, nil
119+
}
120+
121+
// GetPublicKeyFromPrivateKey get raw public key from private key
82122
// public key format : https://bitcoin.org/en/wallets-guide#public-key-formats
83-
func (b *BitcoinSignature) GetPublicKeyFromSeed(seed string, format btcutil.PubKeyFormat) []byte {
84-
var privateKey = b.GetPrivateKeyFromSeed(seed)
123+
func (*BitcoinSignature) GetPublicKeyFromPrivateKey(
124+
privateKey *btcec.PrivateKey,
125+
format model.BitcoinPublicKeyFormat,
126+
) ([]byte, error) {
85127
switch format {
86-
case btcutil.PKFUncompressed:
87-
return privateKey.PubKey().SerializeUncompressed()
88-
case btcutil.PKFCompressed:
89-
return privateKey.PubKey().SerializeCompressed()
90-
case btcutil.PKFHybrid:
91-
return privateKey.PubKey().SerializeHybrid()
128+
case model.BitcoinPublicKeyFormat_PublicKeyFormatUncompressed:
129+
return privateKey.PubKey().SerializeUncompressed(), nil
130+
case model.BitcoinPublicKeyFormat_PublicKeyFormatCompressed:
131+
return privateKey.PubKey().SerializeCompressed(), nil
92132
default:
93-
return nil
133+
return nil, blocker.NewBlocker(blocker.AppErr, "invalidPublicKeyFormat")
94134
}
95135
}
96136

97-
// GetAddressPublicKey to get address public key from seed
98-
// NOTE: Currently the address is the hex-encoded from serialized public key (pay-to-pubkey)
99-
func (b *BitcoinSignature) GetAddressPublicKey(publicKey []byte) (string, error) {
137+
// GetPublicKeyFromBytes to get public key from raw bytes public key
138+
func (b *BitcoinSignature) GetPublicKeyFromBytes(pubkey []byte) (*btcec.PublicKey, error) {
139+
return btcec.ParsePubKey(pubkey, b.Curve)
140+
}
141+
142+
// GetPublicKeyString will return hex string from bytes public key
143+
func (b *BitcoinSignature) GetPublicKeyString(publicKey []byte) (string, error) {
100144
var address, err = btcutil.NewAddressPubKey(publicKey, b.GetNetworkParams())
101145
if err != nil {
102-
return "", err
146+
return "", blocker.NewBlocker(blocker.ParserErr, err.Error())
103147
}
104148
return address.String(), nil
105149
}
106150

107-
// GetBytesAddressPublicKey Get raw bytes of address
108-
func (b *BitcoinSignature) GetBytesAddressPublicKey(address string) ([]byte, error) {
109-
var decodedAddress, err = btcutil.DecodeAddress(address, b.GetNetworkParams())
151+
// GetAddressFromPublicKey to get address public key from seed
152+
func (b *BitcoinSignature) GetAddressFromPublicKey(publicKey []byte) (string, error) {
153+
var address, err = btcutil.NewAddressPubKey(publicKey, b.GetNetworkParams())
110154
if err != nil {
111-
return nil, err
155+
return "", blocker.NewBlocker(blocker.ParserErr, err.Error())
112156
}
113-
return decodedAddress.ScriptAddress(), nil
157+
return address.EncodeAddress(), nil
114158
}
115159

116-
// GetPublicKeyFromAddress to get public key from address
117-
func (b *BitcoinSignature) GetPublicKeyFromAddress(address string) (*btcec.PublicKey, error) {
118-
rowBytesAddress, err := b.GetBytesAddressPublicKey(address)
119-
if err != nil {
120-
return nil, err
121-
}
122-
publicKey, err := btcec.ParsePubKey(rowBytesAddress, b.Curve)
160+
// GetAddressBytes Get raw bytes of address
161+
func (b *BitcoinSignature) GetAddressBytes(address string) ([]byte, error) {
162+
var decodedAddress, err = btcutil.DecodeAddress(address, b.GetNetworkParams())
123163
if err != nil {
124-
return nil, err
164+
return nil, blocker.NewBlocker(blocker.ParserErr, err.Error())
125165
}
126-
return publicKey, nil
166+
return decodedAddress.ScriptAddress(), nil
127167
}
128168

129169
// GetSignatureFromBytes to get signature type from signature raw bytes
130170
func (b *BitcoinSignature) GetSignatureFromBytes(signatureBytes []byte) (*btcec.Signature, error) {
131171
var signature, err = btcec.ParseSignature(signatureBytes, b.Curve)
132172
if err != nil {
133-
return nil, err
173+
return nil, blocker.NewBlocker(blocker.ParserErr, err.Error())
134174
}
135175
return signature, nil
136176
}

0 commit comments

Comments
 (0)