secp256k1: use compressed pubkey, bitcoin-style address

This commit is contained in:
Ethan Buchman
2017-03-22 01:18:56 -04:00
parent 3f47cfac5f
commit 3a1313ab7d
3 changed files with 58 additions and 16 deletions

View File

@@ -160,9 +160,9 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature {
func (privKey PrivKeySecp256k1) PubKey() PubKey { func (privKey PrivKeySecp256k1) PubKey() PubKey {
_, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:])
pub := [64]byte{} var pub PubKeySecp256k1
copy(pub[:], pub__.SerializeUncompressed()[1:]) copy(pub[:], pub__.SerializeCompressed())
return PubKeySecp256k1(pub) return pub
} }
func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool {

View File

@@ -2,6 +2,7 @@ package crypto
import ( import (
"bytes" "bytes"
"crypto/sha256"
secp256k1 "github.com/btcsuite/btcd/btcec" secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/tendermint/ed25519" "github.com/tendermint/ed25519"
@@ -135,20 +136,20 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool {
//------------------------------------- //-------------------------------------
// Implements PubKey // Implements PubKey.
type PubKeySecp256k1 [64]byte // Compressed pubkey (just the x-cord),
// prefixed with 0x02 or 0x03, depending on the y-cord.
type PubKeySecp256k1 [33]byte
// Implements Bitcoin style addresses: RIPEMD160(SHA256(pubkey))
func (pubKey PubKeySecp256k1) Address() []byte { func (pubKey PubKeySecp256k1) Address() []byte {
w, n, err := new(bytes.Buffer), new(int), new(error) hasherSHA256 := sha256.New()
wire.WriteBinary(pubKey[:], w, n, err) hasherSHA256.Write(pubKey[:]) // does not error
if *err != nil { sha := hasherSHA256.Sum(nil)
PanicCrisis(*err)
} hasherRIPEMD160 := ripemd160.New()
// append type byte hasherRIPEMD160.Write(sha) // does not error
encodedPubkey := append([]byte{TypeSecp256k1}, w.Bytes()...) return hasherRIPEMD160.Sum(nil)
hasher := ripemd160.New()
hasher.Write(encodedPubkey) // does not error
return hasher.Sum(nil)
} }
func (pubKey PubKeySecp256k1) Bytes() []byte { func (pubKey PubKeySecp256k1) Bytes() []byte {
@@ -166,7 +167,7 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool {
return false return false
} }
pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256())
if err != nil { if err != nil {
return false return false
} }

41
pub_key_test.go Normal file
View File

@@ -0,0 +1,41 @@
package crypto
import (
"encoding/hex"
"testing"
"github.com/btcsuite/btcutil/base58"
"github.com/stretchr/testify/assert"
)
type keyData struct {
priv string
pub string
addr string
}
var secpDataTable = []keyData{
{
priv: "a96e62ed3955e65be32703f12d87b6b5cf26039ecfa948dc5107a495418e5330",
pub: "02950e1cdfcb133d6024109fd489f734eeb4502418e538c28481f22bce276f248c",
addr: "1CKZ9Nx4zgds8tU7nJHotKSDr4a9bYJCa3",
},
}
func TestPubKeySecp256k1Address(t *testing.T) {
for _, d := range secpDataTable {
privB, _ := hex.DecodeString(d.priv)
pubB, _ := hex.DecodeString(d.pub)
addrB, _, _ := base58.CheckDecode(d.addr)
var priv PrivKeySecp256k1
copy(priv[:], privB)
pubT := priv.PubKey().(PubKeySecp256k1)
pub := pubT[:]
addr := priv.PubKey().Address()
assert.Equal(t, pub, pubB, "Expected pub keys to match")
assert.Equal(t, addr, addrB, "Expected addresses to match")
}
}