diff --git a/pkg/crypto/public_key.go b/pkg/crypto/public_key.go index dbc6f9c78..0ac4c3c01 100644 --- a/pkg/crypto/public_key.go +++ b/pkg/crypto/public_key.go @@ -2,12 +2,14 @@ package crypto import ( "bytes" + "crypto/sha256" "encoding/binary" "encoding/hex" "io" "math/big" "github.com/pkg/errors" + "golang.org/x/crypto/ripemd160" ) // PublicKeys is a list of public keys. @@ -43,7 +45,7 @@ func NewPublicKeyFromString(s string) (*PublicKey, error) { return nil, err } - pubKey := &PublicKey{} + pubKey := new(PublicKey) if err := pubKey.DecodeBinary(bytes.NewReader(b)); err != nil { return nil, err } @@ -140,3 +142,45 @@ func (p *PublicKey) DecodeBinary(r io.Reader) error { func (p *PublicKey) EncodeBinary(w io.Writer) error { return binary.Write(w, binary.LittleEndian, p.Bytes()) } + +func (p *PublicKey) Signature() ([]byte, error) { + b := p.Bytes() + b = append([]byte{0x21}, b...) + b = append(b, 0xAC) + + sha := sha256.New() + sha.Write(b) + hash := sha.Sum(nil) + + ripemd := ripemd160.New() + ripemd.Reset() + ripemd.Write(hash) + hash = ripemd.Sum(nil) + + return hash, nil +} + +func (p *PublicKey) Address() (string, error) { + var ( + err error + b []byte + ) + if b, err = p.Signature(); err != nil { + return "", err + } + + b = append([]byte{0x17}, b...) + + sha := sha256.New() + sha.Write(b) + hash := sha.Sum(nil) + + sha.Reset() + sha.Write(hash) + hash = sha.Sum(nil) + + b = append(b, hash[0:4]...) + + address := Base58Encode(b) + return address, nil +} diff --git a/pkg/wallet/account.go b/pkg/wallet/account.go index 6d8c19e49..5b186fb57 100644 --- a/pkg/wallet/account.go +++ b/pkg/wallet/account.go @@ -103,7 +103,7 @@ func newAccountFromPrivateKey(p *PrivateKey) (*Account, error) { } a := &Account{ - publicKey: pubKey, + publicKey: pubKey.Bytes(), privateKey: p, Address: pubAddr, wif: wif, diff --git a/pkg/wallet/private_key.go b/pkg/wallet/private_key.go index ff05bb8e6..b698b503f 100644 --- a/pkg/wallet/private_key.go +++ b/pkg/wallet/private_key.go @@ -15,7 +15,6 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto" "github.com/anthdm/rfc6979" - "golang.org/x/crypto/ripemd160" ) // PrivateKey represents a NEO private key. @@ -68,8 +67,10 @@ func NewPrivateKeyFromRawBytes(b []byte) (*PrivateKey, error) { } // PublicKey derives the public key from the private key. -func (p *PrivateKey) PublicKey() ([]byte, error) { +func (p *PrivateKey) PublicKey() (*crypto.PublicKey, error) { var ( + err error + pk crypto.PublicKey c = crypto.NewEllipticCurve() q = new(big.Int).SetBytes(p.b) ) @@ -94,7 +95,10 @@ func (p *PrivateKey) PublicKey() ([]byte, error) { } b := append(prefix, padded...) - return b, nil + if err = pk.DecodeBytes(b); err != nil { + return nil, err + } + return &pk, nil } // NewPrivateKeyFromWIF returns a NEO PrivateKey from the given @@ -117,48 +121,20 @@ func (p *PrivateKey) WIF() (string, error) { // Address derives the public NEO address that is coupled with the private key, and // returns it as a string. func (p *PrivateKey) Address() (string, error) { - b, err := p.Signature() + pk, err := p.PublicKey() if err != nil { return "", err } - - b = append([]byte{0x17}, b...) - - sha := sha256.New() - sha.Write(b) - hash := sha.Sum(nil) - - sha.Reset() - sha.Write(hash) - hash = sha.Sum(nil) - - b = append(b, hash[0:4]...) - - address := crypto.Base58Encode(b) - - return address, nil + return pk.Address() } // Signature creates the signature using the private key. func (p *PrivateKey) Signature() ([]byte, error) { - b, err := p.PublicKey() + pk, err := p.PublicKey() if err != nil { return nil, err } - - b = append([]byte{0x21}, b...) - b = append(b, 0xAC) - - sha := sha256.New() - sha.Write(b) - hash := sha.Sum(nil) - - ripemd := ripemd160.New() - ripemd.Reset() - ripemd.Write(hash) - hash = ripemd.Sum(nil) - - return hash, nil + return pk.Signature() } // Sign signs arbitrary length data using the private key. diff --git a/pkg/wallet/wif.go b/pkg/wallet/wif.go index beece2ed2..8147a97fa 100644 --- a/pkg/wallet/wif.go +++ b/pkg/wallet/wif.go @@ -97,13 +97,14 @@ func (wif WIF) GetVerificationScript() ([]byte, error) { checksig = 0xac ) var ( - pubkey, vScript []byte + vScript []byte + pubkey *crypto.PublicKey ) pubkey, err := wif.PrivateKey.PublicKey() if err != nil { return nil, err } - vScript = append([]byte{pushbytes33}, pubkey...) + vScript = append([]byte{pushbytes33}, pubkey.Bytes()...) vScript = append(vScript, checksig) return vScript, nil }