From bc2cf3a382b4f4b3dc8a899d87c8e40388d3ef5b Mon Sep 17 00:00:00 2001 From: Luke Date: Fri, 30 Oct 2020 17:41:42 -0400 Subject: [PATCH] remove more unneeded code --- go.mod | 1 + go.sum | 37 +++++++++++ transaction_test.go | 3 +- verify.go | 149 +++++++++++++++++--------------------------- verify_test.go | 66 -------------------- 5 files changed, 95 insertions(+), 161 deletions(-) diff --git a/go.mod b/go.mod index 4cf676e..e6b384e 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e // indirect github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9 + github.com/btcsuite/btcd v0.21.0-beta github.com/itchyny/base58-go v0.1.0 github.com/libsv/libsv v0.0.11 github.com/piotrnar/gocoin v0.0.0-20201027184336-0c389d7eb2c0 diff --git a/go.sum b/go.sum index 7d50623..e01d415 100644 --- a/go.sum +++ b/go.sum @@ -1,28 +1,65 @@ +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173 h1:2yTIV9u7H0BhRDGXH5xrAwAz7XibWJtX2dNezMeNsUo= github.com/bitcoinsv/bsvd v0.0.0-20190609155523-4c29707f7173/go.mod h1:BZ1UcC9+tmcDEcdVXgpt13hMczwJxWzpAn68wNs7zRA= github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e h1:6f+gRvaPE/4h0g39dqTNPr9/P4mikw0aB+dhiExaWN8= github.com/bitcoinsv/bsvlog v0.0.0-20181216181007-cb81b076bf2e/go.mod h1:WPrWor6cSeuGQZ15qPe+jqFmblJEFrJHYfr5cD7cmyk= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9 h1:hFI8rT84FCA0FFy3cFrkW5Nz4FyNKlIdCvEvvTNySKg= github.com/bitcoinsv/bsvutil v0.0.0-20181216182056-1d77cf353ea9/go.mod h1:p44KuNKUH5BC8uX4ONEODaHUR4+ibC8todEAOGQEJAM= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M= +github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/itchyny/base58-go v0.1.0 h1:zF5spLDo956exUAD17o+7GamZTRkXOZlqJjRciZwd1I= github.com/itchyny/base58-go v0.1.0/go.mod h1:SrMWPE3DFuJJp1M/RUhu4fccp/y9AlB8AL3o3duPToU= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/libsv/libsv v0.0.11 h1:tb2w/RFpsZLEfPNDGl4tlwk3haMSXYXKspta16+nyv4= github.com/libsv/libsv v0.0.11/go.mod h1:jhXD2sLtYUNMWoD9mWmsQN0hoGZUK1wCvindT1Odijo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/piotrnar/gocoin v0.0.0-20201027184336-0c389d7eb2c0 h1:PuqJFsnjEnbgSk7b629KC4jyuWqr5tM09k80ZpyptHY= github.com/piotrnar/gocoin v0.0.0-20201027184336-0c389d7eb2c0/go.mod h1:sW6i99ojgdRHcz53PCjyEeoTEDFh9dfP5iiEIiNfcaM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/transaction_test.go b/transaction_test.go index 0f8a3d4..b0ddae0 100644 --- a/transaction_test.go +++ b/transaction_test.go @@ -307,9 +307,8 @@ func TestCreateTxErrors(t *testing.T) { } // Run tests - for idx, test := range tests { + for _, test := range tests { - fmt.Println("Test", idx) // Private key (from wif) privateKey, err := WifToPrivateKey(test.inputWif) if err != nil && !test.expectedError { diff --git a/verify.go b/verify.go index f6a5534..c023cba 100644 --- a/verify.go +++ b/verify.go @@ -1,14 +1,17 @@ package bitcoin import ( + "bytes" "encoding/base64" "encoding/hex" - "errors" "fmt" + "log" "github.com/bitcoinsv/bsvd/bsvec" + "github.com/bitcoinsv/bsvd/chaincfg" "github.com/bitcoinsv/bsvd/chaincfg/chainhash" - "github.com/piotrnar/gocoin/lib/secp256k1" + "github.com/bitcoinsv/bsvd/wire" + "github.com/bitcoinsv/bsvutil" ) const ( @@ -21,22 +24,47 @@ const ( // // Error will occur if verify fails or verification is not successful (no bool) // Spec: https://docs.moneybutton.com/docs/bsv-message.html -func VerifyMessage(address, signature, data string) error { - if len(address) == 0 { - return errors.New("address is missing") - } else if len(signature) == 0 { - return errors.New("signature is missing") +func VerifyMessage(address, sig, data string) error { + + decodedSig, err := base64.StdEncoding.DecodeString(sig) + if err != nil { + return err + } + + // Validate the signature - this just shows that it was valid at all. + // we will compare it with the key next. + var buf bytes.Buffer + wire.WriteVarString(&buf, 0, hBSV) + // TODO!!! The 0 here controls the variable length integer + if len(data) > 0xFD { + // https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer + log.Println("Long message! Change varint!") + } + wire.WriteVarString(&buf, 0, data) + expectedMessageHash := chainhash.DoubleHashB(buf.Bytes()) + + pk, wasCompressed, err := bsvec.RecoverCompact(bsvec.S256(), decodedSig, expectedMessageHash) + if err != nil { + return err + } + + // Reconstruct the pubkey hash. + var serializedPK []byte + if wasCompressed { + serializedPK = pk.SerializeCompressed() + } else { + serializedPK = pk.SerializeUncompressed() } - addresses, err := sigMessageToAddress(signature, data) + bsvecAddress, err := bsvutil.NewAddressPubKey(serializedPK, &chaincfg.MainNetParams) if err != nil { return err } - for _, testAddress := range addresses { - if address == testAddress { - return nil - } + + // Return nil if addresses match. + if bsvecAddress.EncodeAddress() == address { + return nil } - return fmt.Errorf("address: %s not found in %s", address, addresses) + return fmt.Errorf("address: %s not found vs %s", address, bsvecAddress.EncodeAddress()) } // VerifyMessageDER will take a message string, a public key string and a signature string @@ -78,83 +106,18 @@ func VerifyMessageDER(hash [32]byte, pubKey string, signature string) (verified } // messageHash will compute a hash for the given message & header -func messageHash(message, header string) ([]byte, error) { - headerLength := len(header) - if headerLength >= 0xfd { - return nil, fmt.Errorf("long header is not supported") - } - messageLength := len(message) - if messageLength >= 0xfd { - return nil, fmt.Errorf("long message is not supported") - } - bitcoinMsg := string([]byte{byte(headerLength)}) - bitcoinMsg += header - bitcoinMsg += string([]byte{byte(messageLength)}) - bitcoinMsg += message - return chainhash.DoubleHashB([]byte(bitcoinMsg)), nil -} - -// parseSignature will parse the given signature -func parseSignature(signature string) (sig secp256k1.Signature, recID int, err error) { - // todo: is this 64 or 65? is it always the same? - // panic was occurring: sig.R.SetBytes(sigRaw[1 : 1+32]) - if len(signature) < 64 { - err = fmt.Errorf("signature is less than %d characters", 64) - return - } - var sigRaw []byte - if sigRaw, err = base64.StdEncoding.DecodeString(signature); err != nil { - return - } - r0 := sigRaw[0] - 27 - recID = int(r0 & 3) - if (r0 & 4) == 1 { - err = fmt.Errorf("compressed type is not supported") - return - } - sig.R.SetBytes(sigRaw[1 : 1+32]) - sig.S.SetBytes(sigRaw[1+32 : 1+32+32]) - return -} - -// pubKeyToAddress will convert a pubkey to an address -func pubKeyToAddress(pubkeyXy2 secp256k1.XY, compressed bool, magic []byte) (address string) { - pubkey, _ := bsvec.ParsePubKey(pubkeyXy2.Bytes(compressed), bsvec.S256()) - bsvecAddress, _ := GetAddressFromPubKey(pubkey) - return bsvecAddress.String() -} - -// sigMessageToAddress will convert a signature & message to a list of addresses -func sigMessageToAddress(signature, message string) ([]string, error) { - - // Get message hash - msgHash, err := messageHash(message, hBSV) - if err != nil { - return nil, err - } - - // Parse the signature - var sig secp256k1.Signature - var recID int - sig, recID, err = parseSignature(signature) - if err != nil { - return nil, err - } - - var msg secp256k1.Number - msg.SetBytes(msgHash) - - var pubkeyXy2 secp256k1.XY - var ret bool - ret = secp256k1.RecoverPublicKey(sig.R.Bytes(), sig.S.Bytes(), msgHash, recID, &pubkeyXy2) - if !ret { - return nil, fmt.Errorf("recover pubkey failed") - } - - addresses := make([]string, 2) - for i, compressed := range []bool{true, false} { - addressString := pubKeyToAddress(pubkeyXy2, compressed, []byte{byte(0)}) - addresses[i] = addressString - } - return addresses, nil -} +// func messageHash(message, header string) ([]byte, error) { +// headerLength := len(header) +// if headerLength >= 0xfd { +// return nil, fmt.Errorf("long header is not supported") +// } +// messageLength := len(message) +// // if messageLength >= 0xfd { +// // return nil, fmt.Errorf("long message is not supported") +// // } +// bitcoinMsg := string([]byte{byte(headerLength)}) +// bitcoinMsg += header +// bitcoinMsg += string([]byte{byte(messageLength)}) +// bitcoinMsg += message +// return chainhash.DoubleHashB([]byte(bitcoinMsg)), nil +// } diff --git a/verify_test.go b/verify_test.go index 79f1742..cf9d601 100644 --- a/verify_test.go +++ b/verify_test.go @@ -2,7 +2,6 @@ package bitcoin import ( "crypto/sha256" - "encoding/hex" "fmt" "strconv" "testing" @@ -124,71 +123,6 @@ func BenchmarkVerifyMessage(b *testing.B) { } } -// TestVerifyMessageMessageHash will test the method messageHash() -func TestVerifyMessageMessageHash(t *testing.T) { - - t.Parallel() - - // Testing private methods - var tests = []struct { - inputMessage string - inputHeader string - expectedHash string - expectedError bool - }{ - {"example message", hBSV, "002c483012a3c71d36349682d5ef6495926d4712b5cd2462f1e3c9f57bd4449f", false}, - {"", hBSV, "80e795d4a4caadd7047af389d9f7f220562feb6196032e2131e10563352c4bcc", false}, - {"example message", "", "f91e1e5a01b6aad5ec785946e4233b0613bf6183ffde8da9879949cbf7d7ca57", false}, - {"", "4qdD3HdK7SC4R9wTgfhr4QkNqRCKunbtRFlYPRYY6lGPiTbA9wZplnscnazyK0NMAx3KtvjDwWIX4J8djkSIYZaSNFEmztekNoe8NR0MLydp21U6Ayfm97oHelvTBcI5hQYccY45oI2KKEB1gyS0V6pbxoDtgjbCAGcnQvLB2iFykNcdU7A6Yntx812tKp90KilPADcEoKfkexMddqJ1pMz262MNhpTWmC4QOFMlB3xB5iTy2fxm6DgT3QLkiesk3kwM", "", true}, - {"4qdD3HdK7SC4R9wTgfhr4QkNqRCKunbtRFlYPRYY6lGPiTbA9wZplnscnazyK0NMAx3KtvjDwWIX4J8djkSIYZaSNFEmztekNoe8NR0MLydp21U6Ayfm97oHelvTBcI5hQYccY45oI2KKEB1gyS0V6pbxoDtgjbCAGcnQvLB2iFykNcdU7A6Yntx812tKp90KilPADcEoKfkexMddqJ1pMz262MNhpTWmC4QOFMlB3xB5iTy2fxm6DgT3QLkiesk3kwM", "", "", true}, - } - - // Run tests - for _, test := range tests { - if output, err := messageHash(test.inputMessage, test.inputHeader); err != nil && !test.expectedError { - t.Errorf("%s Failed: [%s] [%s] inputted and error not expected but got: %s", t.Name(), test.inputMessage, test.inputHeader, err.Error()) - } else if err == nil && test.expectedError { - t.Errorf("%s Failed: [%s] [%s] inputted and error was expected", t.Name(), test.inputMessage, test.inputHeader) - } else if test.expectedHash != hex.EncodeToString(output) { - t.Errorf("%s Failed: [%s] [%s] inputted and [%s] expected, but got: %s", t.Name(), test.inputMessage, test.inputHeader, test.expectedHash, hex.EncodeToString(output)) - } - } - -} - -// TestVerifyMessageParseSignature will test the method parseSignature() -func TestVerifyMessageParseSignature(t *testing.T) { - - t.Parallel() - - // Testing private methods - var tests = []struct { - inputSignature string - expectedID int - expectedError bool - }{ - {"0", 0, true}, - {"1234567", 0, true}, - {"Op0u5nr4CPukjekOsOojjxuyEOG1HbIAf8qEteGXjA7tlqFinprrEcvdSlJOkZ8zMb", 0, true}, - {"000000000000000000000000000000000000000000000000000000000000000000", 0, true}, - {"-000-0-000-0---0--00-0-0-000-0--0-000-0-00-0-00---0-0-0--000-00-0-", 0, true}, - {"IBDscOd/Ov4yrd/YXantqajSAnW4fudpfr2KQy5GNo9pZybF12uNaal4KI822UpQLS/UJD+UK2SnNMn6Z3E4na8=", 1, false}, - {"IBDscOd-Ov4yrd-YXantqajSAnW4fudpfr2KQy5GNo9pZybF12uNaal4KI822UpQLS-UJD+UK2SnNMn6Z3E4na8=", 0, true}, - } - - // Run tests - for _, test := range tests { - if _, output, err := parseSignature(test.inputSignature); err != nil && !test.expectedError { - t.Errorf("%s Failed: [%s] inputted and error not expected but got: %s", t.Name(), test.inputSignature, err.Error()) - } else if err == nil && test.expectedError { - t.Errorf("%s Failed: [%s] inputted and error was expected", t.Name(), test.inputSignature) - } else if output != test.expectedID { - t.Errorf("%s Failed: [%s] inputted and [%d] expected, but got: %d", t.Name(), test.inputSignature, test.expectedID, output) - } - } - -} - // TestVerifyMessageSigRecover will test the method recoverSig() // // From: https://github.com/piotrnar/gocoin/blob/master/lib/secp256k1/sig_test.go