diff --git a/priv_key.go b/priv_key.go index 54fa36a3a..f2d108ee5 100644 --- a/priv_key.go +++ b/priv_key.go @@ -160,9 +160,9 @@ func (privKey PrivKeySecp256k1) Sign(msg []byte) Signature { func (privKey PrivKeySecp256k1) PubKey() PubKey { _, pub__ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), privKey[:]) - pub := [64]byte{} - copy(pub[:], pub__.SerializeUncompressed()[1:]) - return PubKeySecp256k1(pub) + var pub PubKeySecp256k1 + copy(pub[:], pub__.SerializeCompressed()) + return pub } func (privKey PrivKeySecp256k1) Equals(other PrivKey) bool { diff --git a/pub_key.go b/pub_key.go index 9067a0363..45a4db92c 100644 --- a/pub_key.go +++ b/pub_key.go @@ -2,6 +2,7 @@ package crypto import ( "bytes" + "crypto/sha256" secp256k1 "github.com/btcsuite/btcd/btcec" "github.com/tendermint/ed25519" @@ -135,20 +136,20 @@ func (pubKey PubKeyEd25519) Equals(other PubKey) bool { //------------------------------------- -// Implements PubKey -type PubKeySecp256k1 [64]byte +// Implements PubKey. +// 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 { - w, n, err := new(bytes.Buffer), new(int), new(error) - wire.WriteBinary(pubKey[:], w, n, err) - if *err != nil { - PanicCrisis(*err) - } - // append type byte - encodedPubkey := append([]byte{TypeSecp256k1}, w.Bytes()...) - hasher := ripemd160.New() - hasher.Write(encodedPubkey) // does not error - return hasher.Sum(nil) + hasherSHA256 := sha256.New() + hasherSHA256.Write(pubKey[:]) // does not error + sha := hasherSHA256.Sum(nil) + + hasherRIPEMD160 := ripemd160.New() + hasherRIPEMD160.Write(sha) // does not error + return hasherRIPEMD160.Sum(nil) } func (pubKey PubKeySecp256k1) Bytes() []byte { @@ -166,7 +167,7 @@ func (pubKey PubKeySecp256k1) VerifyBytes(msg []byte, sig_ Signature) bool { return false } - pub__, err := secp256k1.ParsePubKey(append([]byte{0x04}, pubKey[:]...), secp256k1.S256()) + pub__, err := secp256k1.ParsePubKey(pubKey[:], secp256k1.S256()) if err != nil { return false } diff --git a/pub_key_test.go b/pub_key_test.go new file mode 100644 index 000000000..0616f5546 --- /dev/null +++ b/pub_key_test.go @@ -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") + } +}