From 4640394aca558195da057eee508fd9b5d9256468 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 21 Aug 2019 20:14:36 +0300 Subject: [PATCH 01/16] _pkg.dev: drop internal rfc6979 package Reuse anthdm/rfc6979. Closes #285. --- _pkg.dev/crypto/privatekey/privatekey.go | 2 +- _pkg.dev/crypto/rfc6979/LICENSE | 21 -- _pkg.dev/crypto/rfc6979/dsa.go | 45 --- _pkg.dev/crypto/rfc6979/dsa_test.go | 270 -------------- _pkg.dev/crypto/rfc6979/ecdsa.go | 59 --- _pkg.dev/crypto/rfc6979/ecdsa_test.go | 447 ----------------------- _pkg.dev/crypto/rfc6979/example_test.go | 76 ---- _pkg.dev/crypto/rfc6979/rfc6979.go | 119 ------ _pkg.dev/crypto/rfc6979/rfc6979_test.go | 28 -- 9 files changed, 1 insertion(+), 1066 deletions(-) delete mode 100755 _pkg.dev/crypto/rfc6979/LICENSE delete mode 100755 _pkg.dev/crypto/rfc6979/dsa.go delete mode 100755 _pkg.dev/crypto/rfc6979/dsa_test.go delete mode 100755 _pkg.dev/crypto/rfc6979/ecdsa.go delete mode 100755 _pkg.dev/crypto/rfc6979/ecdsa_test.go delete mode 100755 _pkg.dev/crypto/rfc6979/example_test.go delete mode 100755 _pkg.dev/crypto/rfc6979/rfc6979.go delete mode 100755 _pkg.dev/crypto/rfc6979/rfc6979_test.go diff --git a/_pkg.dev/crypto/privatekey/privatekey.go b/_pkg.dev/crypto/privatekey/privatekey.go index fa8af0b1c..f2ac56078 100755 --- a/_pkg.dev/crypto/privatekey/privatekey.go +++ b/_pkg.dev/crypto/privatekey/privatekey.go @@ -15,7 +15,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/crypto/base58" "github.com/CityOfZion/neo-go/pkg/crypto/elliptic" "github.com/CityOfZion/neo-go/pkg/crypto/hash" - "github.com/CityOfZion/neo-go/pkg/crypto/rfc6979" + "github.com/anthdm/rfc6979" ) // PrivateKey represents a NEO private key. diff --git a/_pkg.dev/crypto/rfc6979/LICENSE b/_pkg.dev/crypto/rfc6979/LICENSE deleted file mode 100755 index f9835c241..000000000 --- a/_pkg.dev/crypto/rfc6979/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Coda Hale - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/_pkg.dev/crypto/rfc6979/dsa.go b/_pkg.dev/crypto/rfc6979/dsa.go deleted file mode 100755 index f15b3a73a..000000000 --- a/_pkg.dev/crypto/rfc6979/dsa.go +++ /dev/null @@ -1,45 +0,0 @@ -package rfc6979 - -import ( - "crypto/dsa" - "hash" - "math/big" -) - -// SignDSA signs an arbitrary length hash (which should be the result of hashing -// a larger message) using the private key, priv. It returns the signature as a -// pair of integers. -// -// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated -// to the byte-length of the subgroup. This function does not perform that -// truncation itself. -func SignDSA(priv *dsa.PrivateKey, hash []byte, alg func() hash.Hash) (r, s *big.Int, err error) { - n := priv.Q.BitLen() - if n&7 != 0 { - err = dsa.ErrInvalidPublicKey - return - } - n >>= 3 - - generateSecret(priv.Q, priv.X, alg, hash, func(k *big.Int) bool { - inv := new(big.Int).ModInverse(k, priv.Q) - r = new(big.Int).Exp(priv.G, k, priv.P) - r.Mod(r, priv.Q) - - if r.Sign() == 0 { - return false - } - - z := new(big.Int).SetBytes(hash) - - s = new(big.Int).Mul(priv.X, r) - s.Add(s, z) - s.Mod(s, priv.Q) - s.Mul(s, inv) - s.Mod(s, priv.Q) - - return s.Sign() != 0 - }) - - return -} diff --git a/_pkg.dev/crypto/rfc6979/dsa_test.go b/_pkg.dev/crypto/rfc6979/dsa_test.go deleted file mode 100755 index 6b0f4e829..000000000 --- a/_pkg.dev/crypto/rfc6979/dsa_test.go +++ /dev/null @@ -1,270 +0,0 @@ -package rfc6979_test - -import ( - "crypto/dsa" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "encoding/hex" - "hash" - "math/big" - "testing" - - "github.com/o3labs/neo-utils/neoutils/rfc6979" -) - -type dsaFixture struct { - name string - key *dsaKey - alg func() hash.Hash - message string - r, s string -} - -type dsaKey struct { - key *dsa.PrivateKey - subgroup int -} - -var dsa1024 = &dsaKey{ - key: &dsa.PrivateKey{ - PublicKey: dsa.PublicKey{ - Parameters: dsa.Parameters{ - P: dsaLoadInt("86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED8873ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779"), - Q: dsaLoadInt("996F967F6C8E388D9E28D01E205FBA957A5698B1"), - G: dsaLoadInt("07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA417BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD"), - }, - Y: dsaLoadInt("5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F65392195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E682F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B"), - }, - X: dsaLoadInt("411602CB19A6CCC34494D79D98EF1E7ED5AF25F7"), - }, - subgroup: 160, -} - -var dsa2048 = &dsaKey{ - key: &dsa.PrivateKey{ - PublicKey: dsa.PublicKey{ - Parameters: dsa.Parameters{ - P: dsaLoadInt("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B"), - Q: dsaLoadInt("F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F"), - G: dsaLoadInt("5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7"), - }, - Y: dsaLoadInt("667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD949F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA611728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADECB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D123AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF"), - }, - X: dsaLoadInt("69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC"), - }, - subgroup: 256, -} - -var dsaFixtures = []dsaFixture{ - // DSA, 1024 Bits - // https://tools.ietf.org/html/rfc6979#appendix-A.2.1 - dsaFixture{ - name: "1024/SHA-1 #1", - key: dsa1024, - alg: sha1.New, - message: "sample", - r: "2E1A0C2562B2912CAAF89186FB0F42001585DA55", - s: "29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5", - }, - dsaFixture{ - name: "1024/SHA-224 #1", - key: dsa1024, - alg: sha256.New224, - message: "sample", - r: "4BC3B686AEA70145856814A6F1BB53346F02101E", - s: "410697B92295D994D21EDD2F4ADA85566F6F94C1", - }, - dsaFixture{ - name: "1024/SHA-256 #1", - key: dsa1024, - alg: sha256.New, - message: "sample", - r: "81F2F5850BE5BC123C43F71A3033E9384611C545", - s: "4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89", - }, - dsaFixture{ - name: "1024/SHA-384 #1", - key: dsa1024, - alg: sha512.New384, - message: "sample", - r: "07F2108557EE0E3921BC1774F1CA9B410B4CE65A", - s: "54DF70456C86FAC10FAB47C1949AB83F2C6F7595", - }, - dsaFixture{ - name: "1024/SHA-512 #1", - key: dsa1024, - alg: sha512.New, - message: "sample", - r: "16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B", - s: "02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C", - }, - dsaFixture{ - name: "1024/SHA-1 #2", - key: dsa1024, - alg: sha1.New, - message: "test", - r: "42AB2052FD43E123F0607F115052A67DCD9C5C77", - s: "183916B0230D45B9931491D4C6B0BD2FB4AAF088", - }, - dsaFixture{ - name: "1024/SHA-224 #2", - key: dsa1024, - alg: sha256.New224, - message: "test", - r: "6868E9964E36C1689F6037F91F28D5F2C30610F2", - s: "49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F", - }, - dsaFixture{ - name: "1024/SHA-256 #2", - key: dsa1024, - alg: sha256.New, - message: "test", - r: "22518C127299B0F6FDC9872B282B9E70D0790812", - s: "6837EC18F150D55DE95B5E29BE7AF5D01E4FE160", - }, - dsaFixture{ - name: "1024/SHA-384 #2", - key: dsa1024, - alg: sha512.New384, - message: "test", - r: "854CF929B58D73C3CBFDC421E8D5430CD6DB5E66", - s: "91D0E0F53E22F898D158380676A871A157CDA622", - }, - dsaFixture{ - name: "1024/SHA-512 #2", - key: dsa1024, - alg: sha512.New, - message: "test", - r: "8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0", - s: "7C670C7AD72B6C050C109E1790008097125433E8", - }, - - // DSA, 2048 Bits - // https://tools.ietf.org/html/rfc6979#appendix-A.2.2 - dsaFixture{ - name: "2048/SHA-1 #1", - key: dsa2048, - alg: sha1.New, - message: "sample", - r: "3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A", - s: "D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF", - }, - dsaFixture{ - name: "2048/SHA-224 #1", - key: dsa2048, - alg: sha256.New224, - message: "sample", - r: "DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C", - s: "A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC", - }, - dsaFixture{ - name: "2048/SHA-256 #1", - key: dsa2048, - alg: sha256.New, - message: "sample", - r: "EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809", - s: "7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53", - }, - dsaFixture{ - name: "2048/SHA-384 #1", - key: dsa2048, - alg: sha512.New384, - message: "sample", - r: "B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B", - s: "19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B", - }, - dsaFixture{ - name: "2048/SHA-512 #1", - key: dsa2048, - alg: sha512.New, - message: "sample", - r: "2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E", - s: "D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351", - }, - dsaFixture{ - name: "2048/SHA-1 #2", - key: dsa2048, - alg: sha1.New, - message: "test", - r: "C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0", - s: "414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA", - }, - dsaFixture{ - name: "2048/SHA-224 #2", - key: dsa2048, - alg: sha256.New224, - message: "test", - r: "272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3", - s: "E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806", - }, - dsaFixture{ - name: "2048/SHA-256 #2", - key: dsa2048, - alg: sha256.New, - message: "test", - r: "8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0", - s: "7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E", - }, - dsaFixture{ - name: "2048/SHA-384 #2", - key: dsa2048, - alg: sha512.New384, - message: "test", - r: "239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE", - s: "6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961", - }, - dsaFixture{ - name: "2048/SHA-512 #2", - key: dsa2048, - alg: sha512.New, - message: "test", - r: "89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307", - s: "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1", - }, -} - -func TestDSASignatures(t *testing.T) { - for _, f := range dsaFixtures { - testDsaFixture(&f, t) - } -} - -func testDsaFixture(f *dsaFixture, t *testing.T) { - t.Logf("Testing %s", f.name) - - h := f.alg() - h.Write([]byte(f.message)) - digest := h.Sum(nil) - - g := f.key.subgroup / 8 - if len(digest) > g { - digest = digest[0:g] - } - - r, s, err := rfc6979.SignDSA(f.key.key, digest, f.alg) - if err != nil { - t.Error(err) - return - } - - expectedR := dsaLoadInt(f.r) - expectedS := dsaLoadInt(f.s) - - if r.Cmp(expectedR) != 0 { - t.Errorf("%s: Expected R of %X, got %X", f.name, expectedR, r) - } - - if s.Cmp(expectedS) != 0 { - t.Errorf("%s: Expected S of %X, got %X", f.name, expectedS, s) - } -} - -func dsaLoadInt(s string) *big.Int { - b, err := hex.DecodeString(s) - if err != nil { - panic(err) - } - - return new(big.Int).SetBytes(b) -} diff --git a/_pkg.dev/crypto/rfc6979/ecdsa.go b/_pkg.dev/crypto/rfc6979/ecdsa.go deleted file mode 100755 index 8cf10a79b..000000000 --- a/_pkg.dev/crypto/rfc6979/ecdsa.go +++ /dev/null @@ -1,59 +0,0 @@ -package rfc6979 - -import ( - "hash" - "math/big" - - "github.com/CityOfZion/neo-go/pkg/crypto/elliptic" -) - -// SignECDSA signs an arbitrary length hash (which should be the result of -// hashing a larger message) using the private key, priv. It returns the -// signature as a pair of integers. -// -// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated -// to the byte-length of the subgroup. This function does not perform that -// truncation itself. -func SignECDSA(curve elliptic.Curve, priv []byte, hash []byte, alg func() hash.Hash) (r, s *big.Int, err error) { - c := curve - N := c.N - D := new(big.Int) - D.SetBytes(priv) - generateSecret(N, D, alg, hash, func(k *big.Int) bool { - - inv := new(big.Int).ModInverse(k, N) - - r, _ = curve.ScalarBaseMult(k.Bytes()) - r.Mod(r, N) - - if r.Sign() == 0 { - return false - } - - e := hashToInt(hash, c) - s = new(big.Int).Mul(D, r) - s.Add(s, e) - s.Mul(s, inv) - s.Mod(s, N) - - return s.Sign() != 0 - }) - - return -} - -// copied from crypto/ecdsa -func hashToInt(hash []byte, c elliptic.Curve) *big.Int { - orderBits := c.N.BitLen() - orderBytes := (orderBits + 7) / 8 - if len(hash) > orderBytes { - hash = hash[:orderBytes] - } - - ret := new(big.Int).SetBytes(hash) - excess := len(hash)*8 - orderBits - if excess > 0 { - ret.Rsh(ret, uint(excess)) - } - return ret -} diff --git a/_pkg.dev/crypto/rfc6979/ecdsa_test.go b/_pkg.dev/crypto/rfc6979/ecdsa_test.go deleted file mode 100755 index f6ef52420..000000000 --- a/_pkg.dev/crypto/rfc6979/ecdsa_test.go +++ /dev/null @@ -1,447 +0,0 @@ -package rfc6979_test - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/sha1" - "crypto/sha256" - "crypto/sha512" - "hash" - "math/big" - "testing" - - "github.com/o3labs/neo-utils/neoutils/rfc6979" -) - -type ecdsaFixture struct { - name string - key *ecdsaKey - alg func() hash.Hash - message string - r, s string -} - -type ecdsaKey struct { - key *ecdsa.PrivateKey - subgroup int -} - -var p224 = &ecdsaKey{ - key: &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P224(), - X: ecdsaLoadInt("00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C"), - Y: ecdsaLoadInt("EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A"), - }, - D: ecdsaLoadInt("F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1"), - }, - subgroup: 224, -} - -var p256 = &ecdsaKey{ - key: &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P256(), - X: ecdsaLoadInt("60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"), - Y: ecdsaLoadInt("7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299"), - }, - D: ecdsaLoadInt("C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721"), - }, - subgroup: 256, -} - -var p384 = &ecdsaKey{ - key: &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P384(), - X: ecdsaLoadInt("EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13"), - Y: ecdsaLoadInt("8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720"), - }, - D: ecdsaLoadInt("6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5"), - }, - subgroup: 384, -} - -var p521 = &ecdsaKey{ - key: &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: elliptic.P521(), - X: ecdsaLoadInt("1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4"), - Y: ecdsaLoadInt("0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5"), - }, - D: ecdsaLoadInt("0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538"), - }, - subgroup: 521, -} - -var fixtures = []ecdsaFixture{ - // ECDSA, 224 Bits (Prime Field) - // https://tools.ietf.org/html/rfc6979#appendix-A.2.4 - ecdsaFixture{ - name: "P224/SHA-1 #1", - key: p224, - alg: sha1.New, - message: "sample", - r: "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC", - s: "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69", - }, - ecdsaFixture{ - name: "P224/SHA-224 #1", - key: p224, - alg: sha256.New224, - message: "sample", - r: "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E", - s: "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC", - }, - ecdsaFixture{ - name: "P224/SHA-256 #1", - key: p224, - alg: sha256.New, - message: "sample", - r: "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", - s: "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101", - }, - ecdsaFixture{ - name: "P224/SHA-384 #1", - key: p224, - alg: sha512.New384, - message: "sample", - r: "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953", - s: "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D", - }, - ecdsaFixture{ - name: "P224/SHA-512 #1", - key: p224, - alg: sha512.New, - message: "sample", - r: "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397", - s: "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084", - }, - ecdsaFixture{ - name: "P224/SHA-1 #2", - key: p224, - alg: sha1.New, - message: "test", - r: "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C", - s: "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2", - }, - ecdsaFixture{ - name: "P224/SHA-224 #2", - key: p224, - alg: sha256.New224, - message: "test", - r: "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019", - s: "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4", - }, - ecdsaFixture{ - name: "P224/SHA-256 #2", - key: p224, - alg: sha256.New, - message: "test", - r: "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", - s: "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD", - }, - ecdsaFixture{ - name: "P224/SHA-384 #2", - key: p224, - alg: sha512.New384, - message: "test", - r: "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4", - s: "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB", - }, - ecdsaFixture{ - name: "P224/SHA-512 #2", - key: p224, - alg: sha512.New, - message: "test", - r: "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C", - s: "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF", - }, - // ECDSA, 256 Bits (Prime Field) - // https://tools.ietf.org/html/rfc6979#appendix-A.2.5 - ecdsaFixture{ - name: "P256/SHA-1 #1", - key: p256, - alg: sha1.New, - message: "sample", - r: "61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32", - s: "6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB", - }, - ecdsaFixture{ - name: "P256/SHA-224 #1", - key: p256, - alg: sha256.New224, - message: "sample", - r: "53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F", - s: "B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C", - }, - ecdsaFixture{ - name: "P256/SHA-256 #1", - key: p256, - alg: sha256.New, - message: "sample", - r: "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716", - s: "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8", - }, - ecdsaFixture{ - name: "P256/SHA-384 #1", - key: p256, - alg: sha512.New384, - message: "sample", - r: "0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719", - s: "4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954", - }, - ecdsaFixture{ - name: "P256/SHA-512 #1", - key: p256, - alg: sha512.New, - message: "sample", - r: "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00", - s: "2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE", - }, - ecdsaFixture{ - name: "P256/SHA-1 #2", - key: p256, - alg: sha1.New, - message: "test", - r: "0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89", - s: "01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1", - }, - ecdsaFixture{ - name: "P256/SHA-224 #2", - key: p256, - alg: sha256.New224, - message: "test", - r: "C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692", - s: "C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D", - }, - ecdsaFixture{ - name: "P256/SHA-256 #2", - key: p256, - alg: sha256.New, - message: "test", - r: "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367", - s: "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083", - }, - ecdsaFixture{ - name: "P256/SHA-384 #2", - key: p256, - alg: sha512.New384, - message: "test", - r: "83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6", - s: "8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C", - }, - ecdsaFixture{ - name: "P256/SHA-512 #2", - key: p256, - alg: sha512.New, - message: "test", - r: "461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04", - s: "39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55", - }, - // ECDSA, 384 Bits (Prime Field) - // https://tools.ietf.org/html/rfc6979#appendix-A.2.6 - ecdsaFixture{ - name: "P384/SHA-1 #1", - key: p384, - alg: sha1.New, - message: "sample", - r: "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA37B9BA002899F6FDA3A4A9386790D4EB2", - s: "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF26F49CA031D4857570CCB5CA4424A443", - }, - ecdsaFixture{ - name: "P384/SHA-224 #1", - key: p384, - alg: sha256.New224, - message: "sample", - r: "42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366450F76EE3DE43F5A125333A6BE060122", - s: "9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E4834C082C03D83028EFBF93A3C23940CA8D", - }, - ecdsaFixture{ - name: "P384/SHA-256 #1", - key: p384, - alg: sha256.New, - message: "sample", - r: "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD", - s: "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0", - }, - ecdsaFixture{ - name: "P384/SHA-384 #1", - key: p384, - alg: sha512.New384, - message: "sample", - r: "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46", - s: "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8", - }, - ecdsaFixture{ - name: "P384/SHA-512 #1", - key: p384, - alg: sha512.New, - message: "sample", - r: "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799CFE30F35CC900056D7C99CD7882433709", - s: "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112DC7CC3EF3446DEFCEB01A45C2667FDD5", - }, - ecdsaFixture{ - name: "P384/SHA-1 #2", - key: p384, - alg: sha1.New, - message: "test", - r: "4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678ACD9D29876DAF46638645F7F404B11C7", - s: "D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A2991695BA1C84541327E966FA7B50F7382282", - }, - ecdsaFixture{ - name: "P384/SHA-224 #2", - key: p384, - alg: sha256.New224, - message: "test", - r: "E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E62464A9A817C47FF78B8C11066B24080E72", - s: "07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C6141C53EA5ABEF0D8231077A04540A96B66", - }, - ecdsaFixture{ - name: "P384/SHA-256 #2", - key: p384, - alg: sha256.New, - message: "test", - r: "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559F918EEDAF2293BE5B475CC8F0188636B", - s: "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D51AB373F9845C0514EEFB14024787265", - }, - ecdsaFixture{ - name: "P384/SHA-384 #2", - key: p384, - alg: sha512.New384, - message: "test", - r: "8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB0542A7F0812998DA8F1DD3CA3CF023DB", - s: "DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E06A739F040649A667BF3B828246BAA5A5", - }, - ecdsaFixture{ - name: "P384/SHA-512 #2", - key: p384, - alg: sha512.New, - message: "test", - r: "A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D06FB6495CD21B4B6E340FC236584FB277", - s: "976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B224634A2092CD3792E0159AD9CEE37659C736", - }, - // ECDSA, 521 Bits (Prime Field) - // https://tools.ietf.org/html/rfc6979#appendix-A.2.7 - ecdsaFixture{ - name: "P521/SHA-1 #1", - key: p521, - alg: sha1.New, - message: "sample", - r: "0343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D75D", - s: "0E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5D16", - }, - ecdsaFixture{ - name: "P521/SHA-224 #1", - key: p521, - alg: sha256.New224, - message: "sample", - r: "1776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A30715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2ED2E", - s: "050CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17BA41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B41F", - }, - ecdsaFixture{ - name: "P521/SHA-256 #1", - key: p521, - alg: sha256.New, - message: "sample", - r: "1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7", - s: "04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC", - }, - ecdsaFixture{ - name: "P521/SHA-384 #1", - key: p521, - alg: sha512.New384, - message: "sample", - r: "1EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67451", - s: "1F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65D61", - }, - ecdsaFixture{ - name: "P521/SHA-512 #1", - key: p521, - alg: sha512.New, - message: "sample", - r: "0C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA", - s: "0617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A", - }, - ecdsaFixture{ - name: "P521/SHA-1 #2", - key: p521, - alg: sha1.New, - message: "test", - r: "13BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0367", - s: "1E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC916797FF", - }, - ecdsaFixture{ - name: "P521/SHA-224 #2", - key: p521, - alg: sha256.New224, - message: "test", - r: "1C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE17FB", - s: "177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD519A4", - }, - ecdsaFixture{ - name: "P521/SHA-256 #2", - key: p521, - alg: sha256.New, - message: "test", - r: "00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D8071042EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656AA8", - s: "0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694E86", - }, - ecdsaFixture{ - name: "P521/SHA-384 #2", - key: p521, - alg: sha512.New384, - message: "test", - r: "14BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF6075578C", - s: "133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0ED94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B979", - }, - ecdsaFixture{ - name: "P521/SHA-512 #2", - key: p521, - alg: sha512.New, - message: "test", - r: "13E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47EE6D", - s: "1FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4DCE3", - }, -} - -func TestECDSA(t *testing.T) { - for _, f := range fixtures { - testEcsaFixture(&f, t) - } -} - -func ecdsaLoadInt(s string) (n *big.Int) { - n, _ = new(big.Int).SetString(s, 16) - return -} - -func testEcsaFixture(f *ecdsaFixture, t *testing.T) { - t.Logf("Testing %s", f.name) - - h := f.alg() - h.Write([]byte(f.message)) - digest := h.Sum(nil) - - g := f.key.subgroup / 8 - if len(digest) > g { - digest = digest[0:g] - } - - r, s, err := rfc6979.SignECDSA(f.key.key, digest, f.alg) - if err != nil { - t.Error(err) - return - } - - expectedR := ecdsaLoadInt(f.r) - expectedS := ecdsaLoadInt(f.s) - - if r.Cmp(expectedR) != 0 { - t.Errorf("%s: Expected R of %X, got %X", f.name, expectedR, r) - } - - if s.Cmp(expectedS) != 0 { - t.Errorf("%s: Expected S of %X, got %X", f.name, expectedS, s) - } -} diff --git a/_pkg.dev/crypto/rfc6979/example_test.go b/_pkg.dev/crypto/rfc6979/example_test.go deleted file mode 100755 index b756ea80e..000000000 --- a/_pkg.dev/crypto/rfc6979/example_test.go +++ /dev/null @@ -1,76 +0,0 @@ -package rfc6979 - -import ( - "crypto/dsa" - "crypto/ecdsa" - - "crypto/rand" - "crypto/sha1" - "crypto/sha512" - "fmt" - - "github.com/CityOfZion/neo-go/pkg/crypto/elliptic" -) - -// Generates a 521-bit ECDSA key, uses SHA-512 to sign a message, then verifies -// it. -func ExampleSignECDSA() { - // Generate a key pair. - // You need a high-quality PRNG for this. - curve := elliptic.NewEllipticCurve(elliptic.Secp256r1) - k, err := ecdsa.GenerateKey(curve, rand.Reader) - if err != nil { - fmt.Println(err) - return - } - - // Hash a message. - alg := sha512.New() - _, _ = alg.Write([]byte("I am a potato.")) - hash := alg.Sum(nil) - - // Sign the message. You don't need a PRNG for this. - - r, s, err := SignECDSA(curve, k.D.Bytes(), hash, sha512.New) - if err != nil { - fmt.Println(err) - return - } - - if !ecdsa.Verify(&k.PublicKey, hash, r, s) { - fmt.Println("Invalid signature!") - } -} - -// Generates a 1024-bit DSA key, uses SHA-1 to sign a message, then verifies it. -func ExampleSignDSA() { - // Here I'm generating some DSA params, but you should really pre-generate - // these and re-use them, since this takes a long time and isn't necessary. - k := new(dsa.PrivateKey) - dsa.GenerateParameters(&k.Parameters, rand.Reader, dsa.L1024N160) - - // Generate a key pair. - // You need a high-quality PRNG for this. - err := dsa.GenerateKey(k, rand.Reader) - if err != nil { - fmt.Println(err) - return - } - - // Hash a message. - alg := sha1.New() - _, _ = alg.Write([]byte("I am a potato.")) - hash := alg.Sum(nil) - - // Sign the message. You don't need a PRNG for this. - r, s, err := SignDSA(k, hash, sha1.New) - if err != nil { - fmt.Println(err) - return - } - - if !dsa.Verify(&k.PublicKey, hash, r, s) { - fmt.Println("Invalid signature!") - } - -} diff --git a/_pkg.dev/crypto/rfc6979/rfc6979.go b/_pkg.dev/crypto/rfc6979/rfc6979.go deleted file mode 100755 index cb7b4b0d8..000000000 --- a/_pkg.dev/crypto/rfc6979/rfc6979.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Package rfc6979 is an implementation of RFC 6979's deterministic DSA. - - Such signatures are compatible with standard Digital Signature Algorithm - (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA) digital - signatures and can be processed with unmodified verifiers, which need not be - aware of the procedure described therein. Deterministic signatures retain - the cryptographic security features associated with digital signatures but - can be more easily implemented in various environments, since they do not - need access to a source of high-quality randomness. - -(https://tools.ietf.org/html/rfc6979) - -Provides functions similar to crypto/dsa and crypto/ecdsa. -*/ -package rfc6979 - -import ( - "bytes" - "crypto/hmac" - "hash" - "math/big" -) - -// mac returns an HMAC of the given key and message. -func mac(alg func() hash.Hash, k, m, buf []byte) []byte { - h := hmac.New(alg, k) - h.Write(m) - return h.Sum(buf[:0]) -} - -// https://tools.ietf.org/html/rfc6979#section-2.3.2 -func bits2int(in []byte, qlen int) *big.Int { - vlen := len(in) * 8 - v := new(big.Int).SetBytes(in) - if vlen > qlen { - v = new(big.Int).Rsh(v, uint(vlen-qlen)) - } - return v -} - -// https://tools.ietf.org/html/rfc6979#section-2.3.3 -func int2octets(v *big.Int, rolen int) []byte { - out := v.Bytes() - - // pad with zeros if it's too short - if len(out) < rolen { - out2 := make([]byte, rolen) - copy(out2[rolen-len(out):], out) - return out2 - } - - // drop most significant bytes if it's too long - if len(out) > rolen { - out2 := make([]byte, rolen) - copy(out2, out[len(out)-rolen:]) - return out2 - } - - return out -} - -// https://tools.ietf.org/html/rfc6979#section-2.3.4 -func bits2octets(in []byte, q *big.Int, qlen, rolen int) []byte { - z1 := bits2int(in, qlen) - z2 := new(big.Int).Sub(z1, q) - if z2.Sign() < 0 { - return int2octets(z1, rolen) - } - return int2octets(z2, rolen) -} - -var one = big.NewInt(1) - -// https://tools.ietf.org/html/rfc6979#section-3.2 -func generateSecret(q, x *big.Int, alg func() hash.Hash, hash []byte, test func(*big.Int) bool) { - qlen := q.BitLen() - holen := alg().Size() - rolen := (qlen + 7) >> 3 - bx := append(int2octets(x, rolen), bits2octets(hash, q, qlen, rolen)...) - - // Step B - v := bytes.Repeat([]byte{0x01}, holen) - - // Step C - k := bytes.Repeat([]byte{0x00}, holen) - - // Step D - k = mac(alg, k, append(append(v, 0x00), bx...), k) - - // Step E - v = mac(alg, k, v, v) - - // Step F - k = mac(alg, k, append(append(v, 0x01), bx...), k) - - // Step G - v = mac(alg, k, v, v) - - // Step H - for { - // Step H1 - var t []byte - - // Step H2 - for len(t) < qlen/8 { - v = mac(alg, k, v, v) - t = append(t, v...) - } - - // Step H3 - secret := bits2int(t, qlen) - if secret.Cmp(one) >= 0 && secret.Cmp(q) < 0 && test(secret) { - return - } - k = mac(alg, k, append(v, 0x00), k) - v = mac(alg, k, v, v) - } -} diff --git a/_pkg.dev/crypto/rfc6979/rfc6979_test.go b/_pkg.dev/crypto/rfc6979/rfc6979_test.go deleted file mode 100755 index cc9138653..000000000 --- a/_pkg.dev/crypto/rfc6979/rfc6979_test.go +++ /dev/null @@ -1,28 +0,0 @@ -package rfc6979 - -import ( - "crypto/sha256" - "encoding/hex" - "math/big" - "testing" -) - -// https://tools.ietf.org/html/rfc6979#appendix-A.1 -func TestGenerateSecret(t *testing.T) { - q, _ := new(big.Int).SetString("4000000000000000000020108A2E0CC0D99F8A5EF", 16) - - x, _ := new(big.Int).SetString("09A4D6792295A7F730FC3F2B49CBC0F62E862272F", 16) - - hash, _ := hex.DecodeString("AF2BDBE1AA9B6EC1E2ADE1D694F41FC71A831D0268E9891562113D8A62ADD1BF") - - expected, _ := new(big.Int).SetString("23AF4074C90A02B3FE61D286D5C87F425E6BDD81B", 16) - var actual *big.Int - generateSecret(q, x, sha256.New, hash, func(k *big.Int) bool { - actual = k - return true - }) - - if actual.Cmp(expected) != 0 { - t.Errorf("Expected %x, got %x", expected, actual) - } -} From bc0a4671d4545e183d1f75cb9a9950798a87f291 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Wed, 21 Aug 2019 20:17:41 +0300 Subject: [PATCH 02/16] _pkg.dev: drop crypto/aes, refs #307 Duplicated by pkg/crypto/aes256.go. --- _pkg.dev/crypto/aes/aes256.go | 93 ----------------------------------- 1 file changed, 93 deletions(-) delete mode 100755 _pkg.dev/crypto/aes/aes256.go diff --git a/_pkg.dev/crypto/aes/aes256.go b/_pkg.dev/crypto/aes/aes256.go deleted file mode 100755 index c23c48843..000000000 --- a/_pkg.dev/crypto/aes/aes256.go +++ /dev/null @@ -1,93 +0,0 @@ -package aes - -import ( - "crypto/aes" - "crypto/cipher" -) - -// Encrypt encrypts the key with the given source. -func Encrypt(src, key []byte) ([]byte, error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - ecb := newECBEncrypter(block) - out := make([]byte, len(src)) - ecb.CryptBlocks(out, src) - - return out, nil -} - -// Decrypt decrypts the encrypted source with the given key. -func Decrypt(crypted, key []byte) ([]byte, error) { - block, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - blockMode := newECBDecrypter(block) - out := make([]byte, len(crypted)) - blockMode.CryptBlocks(out, crypted) - return out, nil -} - -type ecb struct { - b cipher.Block - blockSize int -} - -func newECB(b cipher.Block) *ecb { - return &ecb{ - b: b, - blockSize: b.BlockSize(), - } -} - -type ecbEncrypter ecb - -func newECBEncrypter(b cipher.Block) cipher.BlockMode { - return (*ecbEncrypter)(newECB(b)) -} - -func (ecb *ecbEncrypter) BlockSize() int { - return ecb.blockSize -} - -func (ecb *ecbEncrypter) CryptBlocks(dst, src []byte) { - if len(src)%ecb.blockSize != 0 { - panic("crypto/cipher: input not full blocks") - } - if len(dst) < len(src) { - panic("crypto/cipher: output smaller than input") - } - for len(src) > 0 { - ecb.b.Encrypt(dst, src[:ecb.blockSize]) - src = src[ecb.blockSize:] - dst = dst[ecb.blockSize:] - } -} - -type ecbDecrypter ecb - -func newECBDecrypter(b cipher.Block) cipher.BlockMode { - return (*ecbDecrypter)(newECB(b)) -} - -func (ecb ecbDecrypter) BlockSize() int { - return ecb.blockSize -} - -func (ecb *ecbDecrypter) CryptBlocks(dst, src []byte) { - if len(src)%ecb.blockSize != 0 { - panic("crypto/cipher: input not full blocks") - } - if len(dst) < len(src) { - panic("crypto/cipher: output smaller than input") - } - for len(src) > 0 { - ecb.b.Decrypt(dst, src[:ecb.blockSize]) - src = src[ecb.blockSize:] - dst = dst[ecb.blockSize:] - } -} From c1b1b6fca420290fab8be32cbb94c434141cd640 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 22 Aug 2019 15:35:18 +0300 Subject: [PATCH 03/16] uint160: move ReverseString() from _pkg.dev With associated test and drop duplicating Uint160 implementation from _pkg.dev. It doesn't seem to be used in pkg code at the moment, but still it can be useful. Refs #307. --- _pkg.dev/wire/util/uint160.go | 91 ------------------------------ _pkg.dev/wire/util/uint160_test.go | 62 -------------------- pkg/util/uint160.go | 5 ++ pkg/util/uint160_test.go | 11 ++++ 4 files changed, 16 insertions(+), 153 deletions(-) delete mode 100644 _pkg.dev/wire/util/uint160.go delete mode 100644 _pkg.dev/wire/util/uint160_test.go diff --git a/_pkg.dev/wire/util/uint160.go b/_pkg.dev/wire/util/uint160.go deleted file mode 100644 index fa81299bf..000000000 --- a/_pkg.dev/wire/util/uint160.go +++ /dev/null @@ -1,91 +0,0 @@ -package util - -import ( - "crypto/sha256" - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/CityOfZion/neo-go/pkg/wire/util/slice" - "golang.org/x/crypto/ripemd160" -) - -const uint160Size = 20 - -// Uint160 is a 20 byte long unsigned integer. -type Uint160 [uint160Size]uint8 - -// Uint160DecodeString attempts to decode the given string into an Uint160. -func Uint160DecodeString(s string) (u Uint160, err error) { - if len(s) != uint160Size*2 { - return u, fmt.Errorf("expected string size of %d got %d", uint160Size*2, len(s)) - } - b, err := hex.DecodeString(s) - if err != nil { - return u, err - } - return Uint160DecodeBytes(b) -} - -// Uint160DecodeBytes attempts to decode the given bytes into an Uint160. -func Uint160DecodeBytes(b []byte) (u Uint160, err error) { - if len(b) != uint160Size { - return u, fmt.Errorf("expected byte size of %d got %d", uint160Size, len(b)) - } - for i := 0; i < uint160Size; i++ { - u[i] = b[i] - } - return -} - -// Uint160FromScript returns a Uint160 type from a raw script. -func Uint160FromScript(script []byte) (u Uint160, err error) { - sha := sha256.New() - sha.Write(script) - b := sha.Sum(nil) - ripemd := ripemd160.New() - ripemd.Write(b) - b = ripemd.Sum(nil) - return Uint160DecodeBytes(b) -} - -// Bytes returns the byte slice representation of u. -func (u Uint160) Bytes() []byte { - b := make([]byte, uint160Size) - for i := 0; i < uint160Size; i++ { - b[i] = byte(u[i]) - } - return b -} - -// BytesReverse return a reversed byte representation of u. -func (u Uint160) BytesReverse() []byte { - return slice.Reverse(u.Bytes()) -} - -// String implements the stringer interface. -func (u Uint160) String() string { - return hex.EncodeToString(u.Bytes()) -} - -// ReverseString implements the stringer interface. -func (u Uint160) ReverseString() string { - return hex.EncodeToString(u.BytesReverse()) -} - -// Equals returns true if both Uint256 values are the same. -func (u Uint160) Equals(other Uint160) bool { - for i := 0; i < uint160Size; i++ { - if u[i] != other[i] { - return false - } - } - return true -} - -// MarshalJSON implements the json marshaller interface. -func (u Uint160) MarshalJSON() ([]byte, error) { - return json.Marshal( - fmt.Sprintf("0x%s", hex.EncodeToString(slice.Reverse(u.Bytes()))), - ) -} diff --git a/_pkg.dev/wire/util/uint160_test.go b/_pkg.dev/wire/util/uint160_test.go deleted file mode 100644 index f92f736c7..000000000 --- a/_pkg.dev/wire/util/uint160_test.go +++ /dev/null @@ -1,62 +0,0 @@ -package util - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestUInt160DecodeString(t *testing.T) { - hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302" - val, err := Uint160DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUint160DecodeBytes(t *testing.T) { - hexStr := "2d3b96ae1bcc5a585e075e3b81920210dec16302" - b, err := hex.DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - val, err := Uint160DecodeBytes(b) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUInt160Equals(t *testing.T) { - a := "2d3b96ae1bcc5a585e075e3b81920210dec16302" - b := "4d3b96ae1bcc5a585e075e3b81920210dec16302" - - ua, err := Uint160DecodeString(a) - if err != nil { - t.Fatal(err) - } - ub, err := Uint160DecodeString(b) - if err != nil { - t.Fatal(err) - } - if ua.Equals(ub) { - t.Fatalf("%s and %s cannot be equal", ua, ub) - } - if !ua.Equals(ua) { - t.Fatalf("%s and %s must be equal", ua, ua) - } -} - -func TestUInt160String(t *testing.T) { - hexStr := "b28427088a3729b2536d10122960394e8be6721f" - hexRevStr := "1f72e68b4e39602912106d53b229378a082784b2" - - val, err := Uint160DecodeString(hexStr) - assert.Nil(t, err) - - assert.Equal(t, hexStr, val.String()) - assert.Equal(t, hexRevStr, val.ReverseString()) - -} diff --git a/pkg/util/uint160.go b/pkg/util/uint160.go index 9f1341e28..6efb0f546 100644 --- a/pkg/util/uint160.go +++ b/pkg/util/uint160.go @@ -63,6 +63,11 @@ func (u Uint160) String() string { return hex.EncodeToString(u.Bytes()) } +// ReverseString is the same as String, but returnes an inversed representation. +func (u Uint160) ReverseString() string { + return hex.EncodeToString(u.BytesReverse()) +} + // Equals returns true if both Uint256 values are the same. func (u Uint160) Equals(other Uint160) bool { return u == other diff --git a/pkg/util/uint160_test.go b/pkg/util/uint160_test.go index a527974db..0d64a5623 100644 --- a/pkg/util/uint160_test.go +++ b/pkg/util/uint160_test.go @@ -75,3 +75,14 @@ func TestUInt160Equals(t *testing.T) { t.Fatalf("%s and %s must be equal", ua, ua) } } + +func TestUInt160String(t *testing.T) { + hexStr := "b28427088a3729b2536d10122960394e8be6721f" + hexRevStr := "1f72e68b4e39602912106d53b229378a082784b2" + + val, err := Uint160DecodeString(hexStr) + assert.Nil(t, err) + + assert.Equal(t, hexStr, val.String()) + assert.Equal(t, hexRevStr, val.ReverseString()) +} From d5d570f79335f4ed21d1ba9867e2a32a10461507 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 22 Aug 2019 20:33:58 +0300 Subject: [PATCH 04/16] uint256: add Reverse(), change String() to be BE This one makes a little more obvious that we're operating with LE representations mostly. Refs. #307. See #314 also. --- _pkg.dev/wire/util/uint256.go | 77 ------------------------ _pkg.dev/wire/util/uint256_test.go | 50 --------------- pkg/core/block_test.go | 6 +- pkg/core/blockchain_test.go | 2 +- pkg/core/storage/helpers.go | 2 +- pkg/core/transaction/register_test.go | 2 +- pkg/core/transaction/transaction_test.go | 4 +- pkg/core/util_test.go | 6 +- pkg/crypto/merkle_tree_test.go | 4 +- pkg/rpc/neoScanBalanceGetter.go | 2 +- pkg/rpc/rpc.go | 2 +- pkg/rpc/server.go | 8 +-- pkg/rpc/stack_param.go | 2 +- pkg/rpc/stack_param_test.go | 4 +- pkg/util/uint256.go | 27 ++++++--- pkg/util/uint256_test.go | 14 ++--- 16 files changed, 48 insertions(+), 164 deletions(-) delete mode 100644 _pkg.dev/wire/util/uint256.go delete mode 100644 _pkg.dev/wire/util/uint256_test.go diff --git a/_pkg.dev/wire/util/uint256.go b/_pkg.dev/wire/util/uint256.go deleted file mode 100644 index fc3fe86ca..000000000 --- a/_pkg.dev/wire/util/uint256.go +++ /dev/null @@ -1,77 +0,0 @@ -package util - -import ( - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/CityOfZion/neo-go/pkg/wire/util/slice" -) - -const uint256Size = 32 - -// Uint256 is a 32 byte long unsigned integer. -type Uint256 [uint256Size]uint8 - -// Uint256DecodeString attempts to decode the given string into an Uint256. -func Uint256DecodeString(s string) (u Uint256, err error) { - if len(s) != uint256Size*2 { - return u, fmt.Errorf("expected string size of %d got %d", uint256Size*2, len(s)) - } - b, err := hex.DecodeString(s) - if err != nil { - return u, err - } - return Uint256DecodeBytes(b) -} - -// Uint256DecodeBytes attempts to decode the given string into an Uint256. -func Uint256DecodeBytes(b []byte) (u Uint256, err error) { - if len(b) != uint256Size { - return u, fmt.Errorf("expected []byte of size %d got %d", uint256Size, len(b)) - } - for i := 0; i < uint256Size; i++ { - u[i] = b[i] - } - return u, nil -} - -// Bytes returns a byte slice representation of u. -func (u Uint256) Bytes() []byte { - b := make([]byte, uint256Size) - for i := 0; i < uint256Size; i++ { - b[i] = byte(u[i]) - } - return b -} - -// Reverse reverses the Uint256 object -func (u Uint256) Reverse() Uint256 { - res, _ := Uint256DecodeBytes(u.BytesReverse()) - return res -} - -// BytesReverse return a reversed byte representation of u. -func (u Uint256) BytesReverse() []byte { - return slice.Reverse(u.Bytes()) -} - -// Equals returns true if both Uint256 values are the same. -func (u Uint256) Equals(other Uint256) bool { - return u.String() == other.String() -} - -// String implements the stringer interface. -func (u Uint256) String() string { - return hex.EncodeToString(u.Bytes()) -} - -// ReverseString displays a reverse string representation of Uint256. -func (u Uint256) ReverseString() string { - return hex.EncodeToString(slice.Reverse(u.Bytes())) -} - -// MarshalJSON implements the json marshaller interface. -func (u Uint256) MarshalJSON() ([]byte, error) { - return json.Marshal(fmt.Sprintf("0x%s", u.String())) -} diff --git a/_pkg.dev/wire/util/uint256_test.go b/_pkg.dev/wire/util/uint256_test.go deleted file mode 100644 index ae6b8a438..000000000 --- a/_pkg.dev/wire/util/uint256_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package util - -import ( - "encoding/hex" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestUint256DecodeString(t *testing.T) { - hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - val, err := Uint256DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUint256DecodeBytes(t *testing.T) { - hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - b, err := hex.DecodeString(hexStr) - if err != nil { - t.Fatal(err) - } - val, err := Uint256DecodeBytes(b) - if err != nil { - t.Fatal(err) - } - assert.Equal(t, hexStr, val.String()) -} - -func TestUInt256Equals(t *testing.T) { - a := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - b := "e287c5b29a1b66092be6803c59c765308ac20287e1b4977fd399da5fc8f66ab5" - - ua, err := Uint256DecodeString(a) - if err != nil { - t.Fatal(err) - } - ub, err := Uint256DecodeString(b) - if err != nil { - t.Fatal(err) - } - if ua.Equals(ub) { - t.Fatalf("%s and %s cannot be equal", ua, ub) - } - if !ua.Equals(ua) { - t.Fatalf("%s and %s must be equal", ua, ua) - } -} diff --git a/pkg/core/block_test.go b/pkg/core/block_test.go index 9ae7f2a98..a3f660d97 100644 --- a/pkg/core/block_test.go +++ b/pkg/core/block_test.go @@ -30,9 +30,9 @@ func TestDecodeBlock1(t *testing.T) { assert.Equal(t, uint32(data["index"].(float64)), block.Index) assert.Equal(t, uint32(data["version"].(float64)), block.Version) - assert.Equal(t, data["hash"].(string), block.Hash().String()) - assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.String()) - assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.String()) + assert.Equal(t, data["hash"].(string), block.Hash().ReverseString()) + assert.Equal(t, data["previousblockhash"].(string), block.PrevHash.ReverseString()) + assert.Equal(t, data["merkleroot"].(string), block.MerkleRoot.ReverseString()) assert.Equal(t, data["nextconsensus"].(string), crypto.AddressFromUint160(block.NextConsensus)) script := data["script"].(map[string]interface{}) diff --git a/pkg/core/blockchain_test.go b/pkg/core/blockchain_test.go index 7dbe23637..aec494683 100644 --- a/pkg/core/blockchain_test.go +++ b/pkg/core/blockchain_test.go @@ -185,7 +185,7 @@ func getTestBlockchain(t *testing.T) *Blockchain { func getTestTransaction(txID string, t *testing.T) *transaction.Transaction { chain := getTestBlockchain(t) - txHash, err := util.Uint256DecodeString(txID) + txHash, err := util.Uint256DecodeReverseString(txID) require.NoErrorf(t, err, "could not decode string %s to Uint256", txID) tx, _, err := chain.GetTransaction(txHash) diff --git a/pkg/core/storage/helpers.go b/pkg/core/storage/helpers.go index 88dde7a5a..d62f2bcfc 100644 --- a/pkg/core/storage/helpers.go +++ b/pkg/core/storage/helpers.go @@ -38,7 +38,7 @@ func CurrentHeaderHeight(s Store) (i uint32, h util.Uint256, err error) { return } i = binary.LittleEndian.Uint32(b[32:36]) - h, err = util.Uint256DecodeBytes(b[:32]) + h, err = util.Uint256DecodeReverseBytes(b[:32]) return } diff --git a/pkg/core/transaction/register_test.go b/pkg/core/transaction/register_test.go index b9d83e078..00ef0f218 100644 --- a/pkg/core/transaction/register_test.go +++ b/pkg/core/transaction/register_test.go @@ -52,7 +52,7 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) { assert.Equal(t, uint8(0), txData.Precision) assert.Equal(t, &crypto.PublicKey{}, txData.Owner) assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin)) - assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().String()) + assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().ReverseString()) buf := new(bytes.Buffer) assert.Nil(t, tx.EncodeBinary(buf)) diff --git a/pkg/core/transaction/transaction_test.go b/pkg/core/transaction/transaction_test.go index c8761db10..6c1633cae 100644 --- a/pkg/core/transaction/transaction_test.go +++ b/pkg/core/transaction/transaction_test.go @@ -59,7 +59,7 @@ func TestDecodeEncodeClaimTX(t *testing.T) { assert.Equal(t, 1, len(tx.Outputs)) address := crypto.AddressFromUint160(tx.Outputs[0].ScriptHash) assert.Equal(t, "AQJseD8iBmCD4sgfHRhMahmoi9zvopG6yz", address) - assert.Equal(t, "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7", tx.Outputs[0].AssetID.String()) + assert.Equal(t, "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7", tx.Outputs[0].AssetID.ReverseString()) assert.Equal(t, tx.Outputs[0].Amount.String(), "0.06247739") invoc := "40456349cec43053009accdb7781b0799c6b591c812768804ab0a0b56b5eae7a97694227fcd33e70899c075848b2cee8fae733faac6865b484d3f7df8949e2aadb" verif := "2103945fae1ed3c31d778f149192b76734fcc951b400ba3598faa81ff92ebe477eacac" @@ -74,7 +74,7 @@ func TestDecodeEncodeClaimTX(t *testing.T) { assert.Equal(t, rawClaimTX, hex.EncodeToString(buf.Bytes())) hash := "2c6a45547b3898318e400e541628990a07acb00f3b9a15a8e966ae49525304da" - assert.Equal(t, hash, tx.hash.String()) + assert.Equal(t, hash, tx.hash.ReverseString()) } func TestDecodeEncodeInvocationTX(t *testing.T) { diff --git a/pkg/core/util_test.go b/pkg/core/util_test.go index 4d48bb359..ba8233756 100644 --- a/pkg/core/util_test.go +++ b/pkg/core/util_test.go @@ -20,7 +20,7 @@ func TestGenesisBlockMainNet(t *testing.T) { } expect := "d42561e3d30e15be6400b6df2f328e02d2bf6354c41dce433bc57687c82144bf" - assert.Equal(t, expect, block.Hash().String()) + assert.Equal(t, expect, block.Hash().ReverseString()) } func TestGetConsensusAddressMainNet(t *testing.T) { @@ -51,11 +51,11 @@ func TestGetConsensusAddressMainNet(t *testing.T) { func TestUtilityTokenTX(t *testing.T) { expect := "602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7" tx := utilityTokenTX() - assert.Equal(t, expect, tx.Hash().String()) + assert.Equal(t, expect, tx.Hash().ReverseString()) } func TestGoverningTokenTX(t *testing.T) { expect := "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b" tx := governingTokenTX() - assert.Equal(t, expect, tx.Hash().String()) + assert.Equal(t, expect, tx.Hash().ReverseString()) } diff --git a/pkg/crypto/merkle_tree_test.go b/pkg/crypto/merkle_tree_test.go index 4be94f786..413671c80 100644 --- a/pkg/crypto/merkle_tree_test.go +++ b/pkg/crypto/merkle_tree_test.go @@ -17,7 +17,7 @@ func TestComputeMerkleTree(t *testing.T) { hashes := make([]util.Uint256, len(rawHashes)) for i, str := range rawHashes { - hash, _ := util.Uint256DecodeString(str) + hash, _ := util.Uint256DecodeReverseString(str) hashes[i] = hash } @@ -25,5 +25,5 @@ func TestComputeMerkleTree(t *testing.T) { if err != nil { t.Fatal(err) } - assert.Equal(t, "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4", merkle.Root().String()) + assert.Equal(t, "803ff4abe3ea6533bcc0be574efa02f83ae8fdc651c879056b0d9be336c01bf4", merkle.Root().ReverseString()) } diff --git a/pkg/rpc/neoScanBalanceGetter.go b/pkg/rpc/neoScanBalanceGetter.go index 6bd243042..d763d5f24 100644 --- a/pkg/rpc/neoScanBalanceGetter.go +++ b/pkg/rpc/neoScanBalanceGetter.go @@ -57,7 +57,7 @@ func (s NeoScanServer) CalculateInputs(address string, assetIdUint util.Uint256, selected = util.Fixed8(0) us []*Unspent assetUnspent Unspent - assetId = GlobalAssets[assetIdUint.String()] + assetId = GlobalAssets[assetIdUint.ReverseString()] ) if us, err = s.GetBalance(address); err != nil { return nil, util.Fixed8(0), errs.Wrapf(err, "Cannot get balance for address %v", address) diff --git a/pkg/rpc/rpc.go b/pkg/rpc/rpc.go index a4c09aa49..cdf60be7e 100644 --- a/pkg/rpc/rpc.go +++ b/pkg/rpc/rpc.go @@ -139,7 +139,7 @@ func (c *Client) SendToAddress(asset util.Uint256, address string, amount util.F response.ID = resp.ID response.JSONRPC = resp.JSONRPC response.Result = &TxResponse{ - TxID: rawTx.Hash().String(), + TxID: rawTx.Hash().ReverseString(), } return response, nil } diff --git a/pkg/rpc/server.go b/pkg/rpc/server.go index ce7b62fe3..c6a1a2669 100644 --- a/pkg/rpc/server.go +++ b/pkg/rpc/server.go @@ -107,7 +107,7 @@ func (s *Server) methodHandler(w http.ResponseWriter, req *Request, reqParams Pa Methods: switch req.Method { case "getbestblockhash": - results = s.chain.CurrentBlockHash().String() + results = s.chain.CurrentBlockHash().ReverseString() case "getblock": var hash util.Uint256 @@ -120,7 +120,7 @@ Methods: switch param.Type { case "string": - hash, err = util.Uint256DecodeString(param.StringVal) + hash, err = util.Uint256DecodeReverseString(param.StringVal) if err != nil { resultsErr = errInvalidParams break Methods @@ -204,7 +204,7 @@ Methods: break Methods } - paramAssetID, err := util.Uint256DecodeString(param.StringVal) + paramAssetID, err := util.Uint256DecodeReverseString(param.StringVal) if err != nil { resultsErr = errInvalidParams break @@ -253,7 +253,7 @@ func (s *Server) getrawtransaction(reqParams Params) (interface{}, error) { param0, err := reqParams.ValueWithType(0, "string") if err != nil { resultsErr = err - } else if txHash, err := util.Uint256DecodeString(param0.StringVal); err != nil { + } else if txHash, err := util.Uint256DecodeReverseString(param0.StringVal); err != nil { resultsErr = errInvalidParams } else if tx, height, err := s.chain.GetTransaction(txHash); err != nil { err = errors.Wrapf(err, "Invalid transaction hash: %s", txHash) diff --git a/pkg/rpc/stack_param.go b/pkg/rpc/stack_param.go index bea6bf882..ff62b5424 100644 --- a/pkg/rpc/stack_param.go +++ b/pkg/rpc/stack_param.go @@ -214,7 +214,7 @@ func (p StackParam) TryParse(dest interface{}) error { *dest = data return nil case *util.Uint256: - if *dest, err = util.Uint256DecodeBytes(data); err != nil { + if *dest, err = util.Uint256DecodeReverseBytes(data); err != nil { return err } return nil diff --git a/pkg/rpc/stack_param_test.go b/pkg/rpc/stack_param_test.go index e1fd8a60d..6aa602475 100644 --- a/pkg/rpc/stack_param_test.go +++ b/pkg/rpc/stack_param_test.go @@ -90,7 +90,7 @@ func TestStackParam_UnmarshalJSON(t *testing.T) { if err != nil { t.Errorf("error while unmarhsalling: %v", err) } - h256, err := util.Uint256DecodeString("f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d") + h256, err := util.Uint256DecodeReverseString("f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d") if err != nil { t.Errorf("unmarshal error: %v", err) } @@ -149,7 +149,7 @@ func TestStackParam_TryParse(t *testing.T) { Value: data, } ) - expectedUint256, err = util.Uint256DecodeString(hash256) + expectedUint256, err = util.Uint256DecodeReverseString(hash256) if err != nil { t.Fatal(err) } diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 9565cb956..07eb73001 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -13,8 +13,8 @@ const uint256Size = 32 // Uint256 is a 32 byte long unsigned integer. type Uint256 [uint256Size]uint8 -// Uint256DecodeString attempts to decode the given string into an Uint256. -func Uint256DecodeString(s string) (u Uint256, err error) { +// Uint256DecodeReverseString attempts to decode the given string (in LE representation) into an Uint256. +func Uint256DecodeReverseString(s string) (u Uint256, err error) { if len(s) != uint256Size*2 { return u, fmt.Errorf("expected string size of %d got %d", uint256Size*2, len(s)) } @@ -22,11 +22,11 @@ func Uint256DecodeString(s string) (u Uint256, err error) { if err != nil { return u, err } - return Uint256DecodeBytes(b) + return Uint256DecodeReverseBytes(b) } -// Uint256DecodeBytes attempts to decode the given string into an Uint256. -func Uint256DecodeBytes(b []byte) (u Uint256, err error) { +// Uint256DecodeReverseBytes attempts to decode the given string (in LE representation) into an Uint256. +func Uint256DecodeReverseBytes(b []byte) (u Uint256, err error) { b = ArrayReverse(b) if len(b) != uint256Size { return u, fmt.Errorf("expected []byte of size %d got %d", uint256Size, len(b)) @@ -40,6 +40,12 @@ func (u Uint256) Bytes() []byte { return u[:] } +// Reverse reverses the Uint256 object +func (u Uint256) Reverse() Uint256 { + res, _ := Uint256DecodeReverseBytes(u.Bytes()) + return res +} + // BytesReverse return a reversed byte representation of u. func (u Uint256) BytesReverse() []byte { return ArrayReverse(u.Bytes()) @@ -52,7 +58,12 @@ func (u Uint256) Equals(other Uint256) bool { // String implements the stringer interface. func (u Uint256) String() string { - return hex.EncodeToString(ArrayReverse(u.Bytes())) + return hex.EncodeToString(u.Bytes()) +} + +// ReverseString produces string representation of Uint256 with LE byte order. +func (u Uint256) ReverseString() string { + return hex.EncodeToString(u.BytesReverse()) } // UnmarshalJSON implements the json unmarshaller interface. @@ -62,7 +73,7 @@ func (u *Uint256) UnmarshalJSON(data []byte) (err error) { return err } js = strings.TrimPrefix(js, "0x") - *u, err = Uint256DecodeString(js) + *u, err = Uint256DecodeReverseString(js) return err } @@ -73,7 +84,7 @@ func (u Uint256) Size() int { // MarshalJSON implements the json marshaller interface. func (u Uint256) MarshalJSON() ([]byte, error) { - return []byte(`"0x` + u.String() + `"`), nil + return []byte(`"0x` + u.ReverseString() + `"`), nil } // CompareTo compares two Uint256 with each other. Possible output: 1, -1, 0 diff --git a/pkg/util/uint256_test.go b/pkg/util/uint256_test.go index 6e7371945..fcd23e479 100644 --- a/pkg/util/uint256_test.go +++ b/pkg/util/uint256_test.go @@ -9,7 +9,7 @@ import ( func TestUint256UnmarshalJSON(t *testing.T) { str := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - expected, err := Uint256DecodeString(str) + expected, err := Uint256DecodeReverseString(str) if err != nil { t.Fatal(err) } @@ -36,11 +36,11 @@ func TestUint256UnmarshalJSON(t *testing.T) { func TestUint256DecodeString(t *testing.T) { hexStr := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" - val, err := Uint256DecodeString(hexStr) + val, err := Uint256DecodeReverseString(hexStr) if err != nil { t.Fatal(err) } - assert.Equal(t, hexStr, val.String()) + assert.Equal(t, hexStr, val.ReverseString()) } func TestUint256DecodeBytes(t *testing.T) { @@ -49,22 +49,22 @@ func TestUint256DecodeBytes(t *testing.T) { if err != nil { t.Fatal(err) } - val, err := Uint256DecodeBytes(b) + val, err := Uint256DecodeReverseBytes(b) if err != nil { t.Fatal(err) } - assert.Equal(t, hexStr, val.String()) + assert.Equal(t, hexStr, val.ReverseString()) } func TestUInt256Equals(t *testing.T) { a := "f037308fa0ab18155bccfc08485468c112409ea5064595699e98c545f245f32d" b := "e287c5b29a1b66092be6803c59c765308ac20287e1b4977fd399da5fc8f66ab5" - ua, err := Uint256DecodeString(a) + ua, err := Uint256DecodeReverseString(a) if err != nil { t.Fatal(err) } - ub, err := Uint256DecodeString(b) + ub, err := Uint256DecodeReverseString(b) if err != nil { t.Fatal(err) } From c67217159fd4f13263e7f70e7a142fa449c853c3 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 13:15:09 +0300 Subject: [PATCH 05/16] fixed8: remove trailing zeroes from string representation Add some testcases from `dev` branch (with less than zero case added) and remove useless trailing zeroes from the resulting string. --- pkg/rpc/server_test.go | 2 +- pkg/util/fixed8.go | 2 +- pkg/util/fixed8_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/rpc/server_test.go b/pkg/rpc/server_test.go index d0e70efe6..c389142b7 100644 --- a/pkg/rpc/server_test.go +++ b/pkg/rpc/server_test.go @@ -165,7 +165,7 @@ var testRpcCases = []tc{ { rpcCall: `{ "jsonrpc": "2.0", "id": 1, "method": "getaccountstate", "params": ["AK2nJJpJr6o664CWJKi1QRXjqeic2zRp8y"] }`, method: "getaccountstate_1", - expectedResult: `{"jsonrpc":"2.0","result":{"version":0,"script_hash":"0xe9eed8dc39332032dc22e5d6e86332c50327ba23","frozen":false,"votes":[],"balances":[{"asset":"0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7","value":"72099.99960000"},{"asset":"0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b","value":"99989900"}]},"id":1}`, + expectedResult: `{"jsonrpc":"2.0","result":{"version":0,"script_hash":"0xe9eed8dc39332032dc22e5d6e86332c50327ba23","frozen":false,"votes":[],"balances":[{"asset":"0x602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7","value":"72099.9996"},{"asset":"0xc56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b","value":"99989900"}]},"id":1}`, }, // Bad case, invalid address diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index c9e6412e6..1a63a14fa 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -34,7 +34,7 @@ func (f Fixed8) String() string { for i := len(str); i < 8; i++ { buf.WriteRune('0') } - buf.WriteString(str) + buf.WriteString(strings.TrimRight(str, "0")) } return buf.String() } diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index a6b82e577..53546d783 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -19,7 +19,7 @@ func TestNewFixed8(t *testing.T) { func TestFixed8DecodeString(t *testing.T) { // Fixed8DecodeString works correctly with integers - ivalues := []string{"9000", "100000000", "5", "10945"} + ivalues := []string{"9000", "100000000", "5", "10945", "20.45", "0.00000001", "-42"} for _, val := range ivalues { n, err := Fixed8DecodeString(val) assert.Nil(t, err) From a861f537331166245dbbe619bd3c2a9795bf2879 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 13:22:10 +0300 Subject: [PATCH 06/16] fixed8: simplify arithmetic functions I'm not sure they're of any use at all. --- pkg/util/fixed8.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index 1a63a14fa..ad9f13beb 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -116,32 +116,32 @@ func Satoshi() Fixed8 { // Div implements Fixd8 division operator. func (f Fixed8) Div(i int64) Fixed8 { - return NewFixed8(f.Value() / i) + return f / NewFixed8(i) } // Add implements Fixd8 addition operator. func (f Fixed8) Add(g Fixed8) Fixed8 { - return NewFixed8(f.Value() + g.Value()) + return f + g } // Sub implements Fixd8 subtraction operator. func (f Fixed8) Sub(g Fixed8) Fixed8 { - return NewFixed8(f.Value() - g.Value()) + return f - g } // LessThan implements Fixd8 < operator. func (f Fixed8) LessThan(g Fixed8) bool { - return f.Value() < g.Value() + return f < g } // GreaterThan implements Fixd8 < operator. func (f Fixed8) GreaterThan(g Fixed8) bool { - return f.Value() > g.Value() + return f > g } // Equal implements Fixd8 == operator. func (f Fixed8) Equal(g Fixed8) bool { - return f.Value() == g.Value() + return f == g } // CompareTo returns the difference between the f and g. @@ -149,5 +149,5 @@ func (f Fixed8) Equal(g Fixed8) bool { // difference = 0 implies f = g. // difference > 0 implies f > g. func (f Fixed8) CompareTo(g Fixed8) int { - return int(f.Value() - g.Value()) + return int(f - g) } From 20a4ad99b3d92b9946f10ad2784eaa9cff146435 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 13:35:34 +0300 Subject: [PATCH 07/16] fixed8: add some testcases from dev, split Value functions Add FloatValue() and rename Value() to Int64Value() for consistency. --- _pkg.dev/wire/util/fixed8/fixed8.go | 62 ----------------- _pkg.dev/wire/util/fixed8/fixed8_test.go | 85 ------------------------ pkg/util/fixed8.go | 9 ++- pkg/util/fixed8_test.go | 31 ++++++++- 4 files changed, 36 insertions(+), 151 deletions(-) delete mode 100644 _pkg.dev/wire/util/fixed8/fixed8.go delete mode 100644 _pkg.dev/wire/util/fixed8/fixed8_test.go diff --git a/_pkg.dev/wire/util/fixed8/fixed8.go b/_pkg.dev/wire/util/fixed8/fixed8.go deleted file mode 100644 index 9b7f04e4a..000000000 --- a/_pkg.dev/wire/util/fixed8/fixed8.go +++ /dev/null @@ -1,62 +0,0 @@ -package fixed8 - -import ( - "errors" - "fmt" - "strconv" -) - -const ( - decimals = 100000000 -) - -var errInvalidString = errors.New("Fixed8 must satisfy following regex \\d+(\\.\\d{1,8})?") - -// Fixed8 represents a fixed-point number with precision 10^-8. -type Fixed8 int64 - -// String implements the Stringer interface. -func (f Fixed8) String() string { - val := f.Value() - return strconv.FormatFloat(val, 'f', -1, 64) -} - -// Value returns the original value representing the Fixed8. -func (f Fixed8) Value() float64 { - return float64(f) / float64(decimals) -} - -// Add adds two Fixed8 values together -func (f Fixed8) Add(val Fixed8) Fixed8 { - a := int64(f.Value()) - b := int64(val.Value()) - c := a + b - return FromInt(c) -} - -//Sub subtracts two fixed values from each other -func (f Fixed8) Sub(val Fixed8) Fixed8 { - a := int64(f.Value()) - b := int64(val.Value()) - c := a - b - return FromInt(c) -} - -//FromInt returns a Fixed8 objects from an int64 -func FromInt(val int64) Fixed8 { - return Fixed8(val * decimals) -} - -// FromFloat returns a Fixed8 object from a float64 -func FromFloat(val float64) Fixed8 { - return Fixed8(val * decimals) -} - -// FromString returns a Fixed8 object from a string -func FromString(val string) (Fixed8, error) { - res, err := strconv.ParseFloat(val, 64) - if err != nil { - return 0, fmt.Errorf("failed at parsing string %s", val) - } - return FromFloat(res), nil -} diff --git a/_pkg.dev/wire/util/fixed8/fixed8_test.go b/_pkg.dev/wire/util/fixed8/fixed8_test.go deleted file mode 100644 index 8ee5ab37f..000000000 --- a/_pkg.dev/wire/util/fixed8/fixed8_test.go +++ /dev/null @@ -1,85 +0,0 @@ -package fixed8 - -import ( - "strconv" - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestFixed8Value(t *testing.T) { - - input := int64(12) - assert.Equal(t, float64(input), FromInt(input).Value()) - -} -func TestFixed8Add(t *testing.T) { - - a := FromInt(1) - b := FromInt(2) - - c := a.Add(b) - expected := float64(3) - assert.Equal(t, expected, c.Value()) - -} -func TestFixed8AddRecursive(t *testing.T) { - - a := FromInt(1) - sum := int64(1) - - for i := int64(2); i <= 10; i++ { - - sum += i - b := FromInt(i) - c := a.Add(b) - a = c // 1 + 2 + 3 ... + 10 - } - assert.Equal(t, float64(sum), a.Value()) - -} - -func TestFromInt(t *testing.T) { - - inputs := []int64{12, 23, 100, 456789} - - for _, val := range inputs { - assert.Equal(t, Fixed8(val*decimals), FromInt(val)) - assert.Equal(t, float64(val), FromInt(val).Value()) - } - - for _, val := range inputs { - valString := strconv.FormatInt(val, 10) - assert.Equal(t, valString, FromInt(val).String()) - } - -} -func TestFromFloat(t *testing.T) { - inputs := []float64{12.98, 23.87654333, 100.654322, 456789.12345665} - - for _, val := range inputs { - assert.Equal(t, Fixed8(val*decimals), FromFloat(val)) - assert.Equal(t, float64(val), FromFloat(val).Value()) - } -} -func TestFromString(t *testing.T) { - inputs := []string{"9000", "100000000", "5", "10945", "20.45", "0.00000001"} - - for _, val := range inputs { - - n, err := FromString(val) - assert.Nil(t, err) - assert.Equal(t, val, n.String()) - - } - - val := "123456789.12345678" - n, err := FromString(val) - assert.Nil(t, err) - assert.Equal(t, Fixed8(12345678912345678), n) - - val = "901.2341" - n, err = FromString(val) - assert.Nil(t, err) - assert.Equal(t, Fixed8(90123410000), n) -} diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index ad9f13beb..80216edef 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -39,8 +39,13 @@ func (f Fixed8) String() string { return buf.String() } -// Value returns the original value representing the Fixed8. -func (f Fixed8) Value() int64 { +// FloatValue returns the original value representing Fixed8 as float64. +func (f Fixed8) FloatValue() float64 { + return float64(f) / decimals +} + +// Int64Value returns the original value representing Fixed8 as int64. +func (f Fixed8) Int64Value() int64 { return int64(f) / decimals } diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index 53546d783..7bb4aa9d0 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -9,11 +9,38 @@ import ( ) func TestNewFixed8(t *testing.T) { - values := []int64{9000, 100000000, 5, 10945} + values := []int64{9000, 100000000, 5, 10945, -42} for _, val := range values { assert.Equal(t, Fixed8(val*decimals), NewFixed8(val)) - assert.Equal(t, val, NewFixed8(val).Value()) + assert.Equal(t, val, NewFixed8(val).Int64Value()) + } +} + +func TestFixed8Add(t *testing.T) { + a := NewFixed8(1) + b := NewFixed8(2) + + c := a.Add(b) + expected := int64(3) + assert.Equal(t, strconv.FormatInt(expected, 10), c.String()) +} + +func TestFixed8Sub(t *testing.T) { + + a := NewFixed8(42) + b := NewFixed8(34) + + c := a.Sub(b) + assert.Equal(t, int64(8), c.Int64Value()) +} + +func TestFixed8FromFloat(t *testing.T) { + inputs := []float64{12.98, 23.87654333, 100.654322, 456789.12345665, -3.14159265} + + for _, val := range inputs { + assert.Equal(t, Fixed8(val*decimals), NewFixed8FromFloat(val)) + assert.Equal(t, val, NewFixed8FromFloat(val).FloatValue()) } } From b0af8b306d74972702f6948bcabf25bb1c2f8120 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 15:37:01 +0300 Subject: [PATCH 08/16] fixed8: fix Satoshi() and add a test for it --- pkg/util/fixed8.go | 2 +- pkg/util/fixed8_test.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index 80216edef..21317a2aa 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -116,7 +116,7 @@ func (f Fixed8) MarshalJSON() ([]byte, error) { // Satoshi defines the value of a 'Satoshi'. func Satoshi() Fixed8 { - return NewFixed8(1) + return Fixed8(1) } // Div implements Fixd8 division operator. diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index 7bb4aa9d0..352b75250 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -66,6 +66,11 @@ func TestFixed8DecodeString(t *testing.T) { assert.Equal(t, Fixed8(90123410000), n) } +func TestSatoshi(t *testing.T) { + satoshif8 := Satoshi() + assert.Equal(t, "0.00000001", satoshif8.String()) +} + func TestFixed8UnmarshalJSON(t *testing.T) { var testCases = []float64{ 123.45, From 0cde8d962d5b248c27e0e3b5c78a7887d75a2b67 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 15:41:22 +0300 Subject: [PATCH 09/16] fixed8: switch to more uniform function naming --- config/config.go | 10 ++++---- pkg/core/blockchain.go | 6 ++--- pkg/core/transaction/register_test.go | 4 ++-- pkg/core/util.go | 4 ++-- pkg/util/fixed8.go | 16 ++++++------- pkg/util/fixed8_test.go | 34 +++++++++++++-------------- 6 files changed, 37 insertions(+), 37 deletions(-) diff --git a/config/config.go b/config/config.go index de855f88d..67eed94d6 100644 --- a/config/config.go +++ b/config/config.go @@ -127,14 +127,14 @@ func Load(path string, netMode NetMode) (Config, error) { func (s SystemFee) TryGetValue(txType transaction.TXType) util.Fixed8 { switch txType { case transaction.EnrollmentType: - return util.NewFixed8(s.EnrollmentTransaction) + return util.Fixed8FromInt64(s.EnrollmentTransaction) case transaction.IssueType: - return util.NewFixed8(s.IssueTransaction) + return util.Fixed8FromInt64(s.IssueTransaction) case transaction.PublishType: - return util.NewFixed8(s.PublishTransaction) + return util.Fixed8FromInt64(s.PublishTransaction) case transaction.RegisterType: - return util.NewFixed8(s.RegisterTransaction) + return util.Fixed8FromInt64(s.RegisterTransaction) default: - return util.NewFixed8(0) + return util.Fixed8FromInt64(0) } } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index 1cbdda6a7..bd8e6365d 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -635,14 +635,14 @@ func (bc *Blockchain) FeePerByte(t *transaction.Transaction) util.Fixed8 { // NetworkFee returns network fee func (bc *Blockchain) NetworkFee(t *transaction.Transaction) util.Fixed8 { - inputAmount := util.NewFixed8(0) + inputAmount := util.Fixed8FromInt64(0) for _, txOutput := range bc.References(t) { if txOutput.AssetID == utilityTokenTX().Hash() { inputAmount.Add(txOutput.Amount) } } - outputAmount := util.NewFixed8(0) + outputAmount := util.Fixed8FromInt64(0) for _, txOutput := range t.Outputs { if txOutput.AssetID == utilityTokenTX().Hash() { outputAmount.Add(txOutput.Amount) @@ -660,7 +660,7 @@ func (bc *Blockchain) SystemFee(t *transaction.Transaction) util.Fixed8 { // IsLowPriority flags a trnsaction as low priority if the network fee is less than // LowPriorityThreshold func (bc *Blockchain) IsLowPriority(t *transaction.Transaction) bool { - return bc.NetworkFee(t) < util.NewFixed8FromFloat(bc.GetConfig().LowPriorityThreshold) + return bc.NetworkFee(t) < util.Fixed8FromFloat(bc.GetConfig().LowPriorityThreshold) } // GetMemPool returns the memory pool of the blockchain. diff --git a/pkg/core/transaction/register_test.go b/pkg/core/transaction/register_test.go index 00ef0f218..8512f8f7d 100644 --- a/pkg/core/transaction/register_test.go +++ b/pkg/core/transaction/register_test.go @@ -17,7 +17,7 @@ func TestRegisterTX(t *testing.T) { Data: &RegisterTX{ AssetType: UtilityToken, Name: "this is some token I created", - Amount: util.NewFixed8(1000000), + Amount: util.Fixed8FromInt64(1000000), Precision: 8, Owner: &crypto.PublicKey{}, Admin: util.RandomUint160(), @@ -48,7 +48,7 @@ func TestDecodeRegisterTXFromRawString(t *testing.T) { txData := tx.Data.(*RegisterTX) assert.Equal(t, GoverningToken, txData.AssetType) assert.Equal(t, "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", txData.Name) - assert.Equal(t, util.NewFixed8(100000000), txData.Amount) + assert.Equal(t, util.Fixed8FromInt64(100000000), txData.Amount) assert.Equal(t, uint8(0), txData.Precision) assert.Equal(t, &crypto.PublicKey{}, txData.Owner) assert.Equal(t, "Abf2qMs1pzQb8kYk9RuxtUb9jtRKJVuBJt", crypto.AddressFromUint160(txData.Admin)) diff --git a/pkg/core/util.go b/pkg/core/util.go index a5eab4b85..dffbc7b41 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -101,7 +101,7 @@ func governingTokenTX() *transaction.Transaction { registerTX := &transaction.RegisterTX{ AssetType: transaction.GoverningToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", - Amount: util.NewFixed8(100000000), + Amount: util.Fixed8FromInt64(100000000), Precision: 0, Owner: &crypto.PublicKey{}, Admin: admin, @@ -170,7 +170,7 @@ func calculateUtilityAmount() util.Fixed8 { for i := 0; i < len(genAmount); i++ { sum += genAmount[i] } - return util.NewFixed8(int64(sum * decrementInterval)) + return util.Fixed8FromInt64(int64(sum * decrementInterval)) } // headerSliceReverse reverses the given slice of *Header. diff --git a/pkg/util/fixed8.go b/pkg/util/fixed8.go index 21317a2aa..ec7b96d61 100644 --- a/pkg/util/fixed8.go +++ b/pkg/util/fixed8.go @@ -49,19 +49,19 @@ func (f Fixed8) Int64Value() int64 { return int64(f) / decimals } -// NewFixed8 returns a new Fixed8 type multiplied by decimals. -func NewFixed8(val int64) Fixed8 { +// Fixed8FromInt64 returns a new Fixed8 type multiplied by decimals. +func Fixed8FromInt64(val int64) Fixed8 { return Fixed8(decimals * val) } -// NewFixed8FromFloat returns a new Fixed8 type multiplied by decimals. -func NewFixed8FromFloat(val float64) Fixed8 { +// Fixed8FromFloat returns a new Fixed8 type multiplied by decimals. +func Fixed8FromFloat(val float64) Fixed8 { return Fixed8(int64(decimals * val)) } -// Fixed8DecodeString parses s which must be a fixed point number +// Fixed8FromString parses s which must be a fixed point number // with precision up to 10^-8 -func Fixed8DecodeString(s string) (Fixed8, error) { +func Fixed8FromString(s string) (Fixed8, error) { parts := strings.SplitN(s, ".", 2) ip, err := strconv.ParseInt(parts[0], 10, 64) if err != nil { @@ -87,7 +87,7 @@ func Fixed8DecodeString(s string) (Fixed8, error) { func (f *Fixed8) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err == nil { - p, err := Fixed8DecodeString(s) + p, err := Fixed8FromString(s) if err != nil { return err } @@ -121,7 +121,7 @@ func Satoshi() Fixed8 { // Div implements Fixd8 division operator. func (f Fixed8) Div(i int64) Fixed8 { - return f / NewFixed8(i) + return f / Fixed8FromInt64(i) } // Add implements Fixd8 addition operator. diff --git a/pkg/util/fixed8_test.go b/pkg/util/fixed8_test.go index 352b75250..aea003130 100644 --- a/pkg/util/fixed8_test.go +++ b/pkg/util/fixed8_test.go @@ -8,18 +8,18 @@ import ( "github.com/stretchr/testify/assert" ) -func TestNewFixed8(t *testing.T) { +func TestFixed8FromInt64(t *testing.T) { values := []int64{9000, 100000000, 5, 10945, -42} for _, val := range values { - assert.Equal(t, Fixed8(val*decimals), NewFixed8(val)) - assert.Equal(t, val, NewFixed8(val).Int64Value()) + assert.Equal(t, Fixed8(val*decimals), Fixed8FromInt64(val)) + assert.Equal(t, val, Fixed8FromInt64(val).Int64Value()) } } func TestFixed8Add(t *testing.T) { - a := NewFixed8(1) - b := NewFixed8(2) + a := Fixed8FromInt64(1) + b := Fixed8FromInt64(2) c := a.Add(b) expected := int64(3) @@ -28,8 +28,8 @@ func TestFixed8Add(t *testing.T) { func TestFixed8Sub(t *testing.T) { - a := NewFixed8(42) - b := NewFixed8(34) + a := Fixed8FromInt64(42) + b := Fixed8FromInt64(34) c := a.Sub(b) assert.Equal(t, int64(8), c.Int64Value()) @@ -39,29 +39,29 @@ func TestFixed8FromFloat(t *testing.T) { inputs := []float64{12.98, 23.87654333, 100.654322, 456789.12345665, -3.14159265} for _, val := range inputs { - assert.Equal(t, Fixed8(val*decimals), NewFixed8FromFloat(val)) - assert.Equal(t, val, NewFixed8FromFloat(val).FloatValue()) + assert.Equal(t, Fixed8(val*decimals), Fixed8FromFloat(val)) + assert.Equal(t, val, Fixed8FromFloat(val).FloatValue()) } } -func TestFixed8DecodeString(t *testing.T) { - // Fixed8DecodeString works correctly with integers +func TestFixed8FromString(t *testing.T) { + // Fixed8FromString works correctly with integers ivalues := []string{"9000", "100000000", "5", "10945", "20.45", "0.00000001", "-42"} for _, val := range ivalues { - n, err := Fixed8DecodeString(val) + n, err := Fixed8FromString(val) assert.Nil(t, err) assert.Equal(t, val, n.String()) } - // Fixed8DecodeString parses number with maximal precision + // Fixed8FromString parses number with maximal precision val := "123456789.12345678" - n, err := Fixed8DecodeString(val) + n, err := Fixed8FromString(val) assert.Nil(t, err) assert.Equal(t, Fixed8(12345678912345678), n) - // Fixed8DecodeString parses number with non-maximal precision + // Fixed8FromString parses number with non-maximal precision val = "901.2341" - n, err = Fixed8DecodeString(val) + n, err = Fixed8FromString(val) assert.Nil(t, err) assert.Equal(t, Fixed8(90123410000), n) } @@ -79,7 +79,7 @@ func TestFixed8UnmarshalJSON(t *testing.T) { for _, fl := range testCases { str := strconv.FormatFloat(fl, 'g', -1, 64) - expected, _ := Fixed8DecodeString(str) + expected, _ := Fixed8FromString(str) // UnmarshalJSON should decode floats var u1 Fixed8 From 37be2e215c336e4b3ac4e3645136f2432de7990b Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 15:44:49 +0300 Subject: [PATCH 10/16] array: add a test for even num of elements And drop duplicating code from _pkg.dev. --- _pkg.dev/wire/util/slice/slice.go | 15 ------------ _pkg.dev/wire/util/slice/slice_test.go | 33 -------------------------- pkg/util/array_test.go | 11 ++++++++- 3 files changed, 10 insertions(+), 49 deletions(-) delete mode 100644 _pkg.dev/wire/util/slice/slice.go delete mode 100644 _pkg.dev/wire/util/slice/slice_test.go diff --git a/_pkg.dev/wire/util/slice/slice.go b/_pkg.dev/wire/util/slice/slice.go deleted file mode 100644 index fdb93adc3..000000000 --- a/_pkg.dev/wire/util/slice/slice.go +++ /dev/null @@ -1,15 +0,0 @@ -package slice - -// Reverse return a reversed version of the given byte slice. -func Reverse(b []byte) []byte { - // Protect from big.Ints that have 1 len bytes. - if len(b) < 2 { - return b - } - - dest := make([]byte, len(b)) - for i, j := 0, len(b)-1; i < j+1; i, j = i+1, j-1 { - dest[i], dest[j] = b[j], b[i] - } - return dest -} diff --git a/_pkg.dev/wire/util/slice/slice_test.go b/_pkg.dev/wire/util/slice/slice_test.go deleted file mode 100644 index e65c63f65..000000000 --- a/_pkg.dev/wire/util/slice/slice_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package slice - -import ( - "bytes" - "testing" -) - -func TestSliceReverse(t *testing.T) { - arr := []byte{0x01, 0x02, 0x03, 0x04} - have := Reverse(arr) - want := []byte{0x04, 0x03, 0x02, 0x01} - if bytes.Compare(have, want) != 0 { - t.Fatalf("expected %v got %v", want, have) - } -} -func TestSliceReverseOddNumberOfElements(t *testing.T) { - arr := []byte{0x01, 0x02, 0x03, 0x04, 0x05} - have := Reverse(arr) - want := []byte{0x05, 0x04, 0x03, 0x02, 0x01} - if bytes.Compare(have, want) != 0 { - t.Fatalf("expected %v got %v", want, have) - } -} - -// This tests a bug that occured with arrays of size 1 -func TestSliceReverseLen2(t *testing.T) { - arr := []byte{0x01} - have := Reverse(arr) - want := []byte{0x01} - if bytes.Compare(have, want) != 0 { - t.Fatalf("expected %v got %v", want, have) - } -} diff --git a/pkg/util/array_test.go b/pkg/util/array_test.go index f8d78c979..13ab01330 100644 --- a/pkg/util/array_test.go +++ b/pkg/util/array_test.go @@ -5,7 +5,16 @@ import ( "testing" ) -func TestArrayReverse(t *testing.T) { +func TestArrayEvenReverse(t *testing.T) { + arr := []byte{0x01, 0x02, 0x03, 0x04} + have := ArrayReverse(arr) + want := []byte{0x04, 0x03, 0x02, 0x01} + if !bytes.Equal(have, want) { + t.Fatalf("expected %v got %v", want, have) + } +} + +func TestArrayOddReverse(t *testing.T) { arr := []byte{0x01, 0x02, 0x03, 0x04, 0x05} have := ArrayReverse(arr) want := []byte{0x05, 0x04, 0x03, 0x02, 0x01} From 5c5878968b2f46e6df9f802ca5fecb4b1a088ff0 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 17:02:42 +0300 Subject: [PATCH 11/16] hask: import package from _pkg.dev, make it compile --- {_pkg.dev => pkg}/crypto/hash/hash.go | 2 +- {_pkg.dev => pkg}/crypto/hash/hash_test.go | 2 +- pkg/util/uint256.go | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) rename {_pkg.dev => pkg}/crypto/hash/hash.go (97%) rename {_pkg.dev => pkg}/crypto/hash/hash_test.go (91%) diff --git a/_pkg.dev/crypto/hash/hash.go b/pkg/crypto/hash/hash.go similarity index 97% rename from _pkg.dev/crypto/hash/hash.go rename to pkg/crypto/hash/hash.go index be7ab29b9..3b9197484 100755 --- a/_pkg.dev/crypto/hash/hash.go +++ b/pkg/crypto/hash/hash.go @@ -4,7 +4,7 @@ import ( "crypto/sha256" "io" - "github.com/CityOfZion/neo-go/pkg/wire/util" + "github.com/CityOfZion/neo-go/pkg/util" "golang.org/x/crypto/ripemd160" ) diff --git a/_pkg.dev/crypto/hash/hash_test.go b/pkg/crypto/hash/hash_test.go similarity index 91% rename from _pkg.dev/crypto/hash/hash_test.go rename to pkg/crypto/hash/hash_test.go index aa23718f6..b0ca0633f 100755 --- a/_pkg.dev/crypto/hash/hash_test.go +++ b/pkg/crypto/hash/hash_test.go @@ -15,7 +15,7 @@ func TestSha256(t *testing.T) { t.Fatal(err) } expected := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" - actual := hex.EncodeToString(data.Bytes()) // MARK: In the DecodeBytes function, there is a bytes reverse, not sure why? + actual := hex.EncodeToString(data.Bytes()) assert.Equal(t, expected, actual) } diff --git a/pkg/util/uint256.go b/pkg/util/uint256.go index 07eb73001..fbf9a41a1 100644 --- a/pkg/util/uint256.go +++ b/pkg/util/uint256.go @@ -25,9 +25,8 @@ func Uint256DecodeReverseString(s string) (u Uint256, err error) { return Uint256DecodeReverseBytes(b) } -// Uint256DecodeReverseBytes attempts to decode the given string (in LE representation) into an Uint256. -func Uint256DecodeReverseBytes(b []byte) (u Uint256, err error) { - b = ArrayReverse(b) +// Uint256DecodeBytes attempts to decode the given string (in BE representation) into an Uint256. +func Uint256DecodeBytes(b []byte) (u Uint256, err error) { if len(b) != uint256Size { return u, fmt.Errorf("expected []byte of size %d got %d", uint256Size, len(b)) } @@ -35,6 +34,12 @@ func Uint256DecodeReverseBytes(b []byte) (u Uint256, err error) { return u, nil } +// Uint256DecodeReverseBytes attempts to decode the given string (in LE representation) into an Uint256. +func Uint256DecodeReverseBytes(b []byte) (u Uint256, err error) { + b = ArrayReverse(b) + return Uint256DecodeBytes(b) +} + // Bytes returns a byte slice representation of u. func (u Uint256) Bytes() []byte { return u[:] From 80c3c9035a3ac1f463637615d87b90b83ae58931 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 17:08:19 +0300 Subject: [PATCH 12/16] hash: simplify Sha256 implementations Use sha256.Sum256() and drop duplicating Sum() completely. --- pkg/crypto/hash/hash.go | 47 +++++++++--------------------------- pkg/crypto/hash/hash_test.go | 15 +++--------- 2 files changed, 15 insertions(+), 47 deletions(-) diff --git a/pkg/crypto/hash/hash.go b/pkg/crypto/hash/hash.go index 3b9197484..aff161a83 100755 --- a/pkg/crypto/hash/hash.go +++ b/pkg/crypto/hash/hash.go @@ -10,33 +10,18 @@ import ( // Sha256 hashes the incoming byte slice // using the sha256 algorithm -func Sha256(data []byte) (util.Uint256, error) { - var hash util.Uint256 - hasher := sha256.New() - hasher.Reset() - _, err := hasher.Write(data) - - hash, err = util.Uint256DecodeBytes(hasher.Sum(nil)) - if err != nil { - return hash, err - } - return hash, nil +func Sha256(data []byte) util.Uint256 { + hash := sha256.Sum256(data) + return hash } // DoubleSha256 performs sha256 twice on the given data -func DoubleSha256(data []byte) (util.Uint256, error) { +func DoubleSha256(data []byte) util.Uint256 { var hash util.Uint256 - h1, err := Sha256(data) - if err != nil { - return hash, err - } - - hash, err = Sha256(h1.Bytes()) - if err != nil { - return hash, err - } - return hash, nil + h1 := Sha256(data) + hash = Sha256(h1.Bytes()) + return hash } // RipeMD160 performs the RIPEMD160 hash algorithm @@ -58,7 +43,7 @@ func RipeMD160(data []byte) (util.Uint160, error) { // on the given data func Hash160(data []byte) (util.Uint160, error) { var hash util.Uint160 - h1, err := Sha256(data) + h1 := Sha256(data) h2, err := RipeMD160(h1.Bytes()) @@ -72,17 +57,7 @@ func Hash160(data []byte) (util.Uint160, error) { // Checksum returns the checksum for a given piece of data // using sha256 twice as the hash algorithm -func Checksum(data []byte) ([]byte, error) { - hash, err := Sum(data) - if err != nil { - return nil, err - } - return hash[:4], nil -} - -// Sum performs sha256 twice on the given data -// XXX(issue): We should remove this and just do doublesha256 -func Sum(b []byte) (util.Uint256, error) { - hash, err := DoubleSha256((b)) - return hash, err +func Checksum(data []byte) []byte { + hash := DoubleSha256(data) + return hash[:4] } diff --git a/pkg/crypto/hash/hash_test.go b/pkg/crypto/hash/hash_test.go index b0ca0633f..8e5723823 100755 --- a/pkg/crypto/hash/hash_test.go +++ b/pkg/crypto/hash/hash_test.go @@ -9,11 +9,8 @@ import ( func TestSha256(t *testing.T) { input := []byte("hello") - data, err := Sha256(input) + data := Sha256(input) - if err != nil { - t.Fatal(err) - } expected := "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" actual := hex.EncodeToString(data.Bytes()) @@ -22,14 +19,10 @@ func TestSha256(t *testing.T) { func TestHashDoubleSha256(t *testing.T) { input := []byte("hello") - data, err := DoubleSha256(input) + data := DoubleSha256(input) - if err != nil { - t.Fatal(err) - } - - firstSha, _ := Sha256(input) - doubleSha, _ := Sha256(firstSha.Bytes()) + firstSha := Sha256(input) + doubleSha := Sha256(firstSha.Bytes()) expected := hex.EncodeToString(doubleSha.Bytes()) actual := hex.EncodeToString(data.Bytes()) From 3fa6ba9c7b7f69961ffdf3cc042e46101655dac2 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 17:23:11 +0300 Subject: [PATCH 13/16] hash: simplify ripemd160 usage Go's Hash is explicitly specified to never return an error on Write(), and our own decoding functions only check for length which is gonna be right in every case so it makes no sense returning errors from these functions. --- pkg/crypto/hash/hash.go | 27 +++++++++------------------ pkg/crypto/hash/hash_test.go | 10 ++-------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/pkg/crypto/hash/hash.go b/pkg/crypto/hash/hash.go index aff161a83..ba3c6783b 100755 --- a/pkg/crypto/hash/hash.go +++ b/pkg/crypto/hash/hash.go @@ -2,7 +2,6 @@ package hash import ( "crypto/sha256" - "io" "github.com/CityOfZion/neo-go/pkg/util" "golang.org/x/crypto/ripemd160" @@ -26,33 +25,25 @@ func DoubleSha256(data []byte) util.Uint256 { // RipeMD160 performs the RIPEMD160 hash algorithm // on the given data -func RipeMD160(data []byte) (util.Uint160, error) { +func RipeMD160(data []byte) util.Uint160 { var hash util.Uint160 hasher := ripemd160.New() - hasher.Reset() - _, err := io.WriteString(hasher, string(data)) + _, _ = hasher.Write(data) - hash, err = util.Uint160DecodeBytes(hasher.Sum(nil)) - if err != nil { - return hash, err - } - return hash, nil + hash, _ = util.Uint160DecodeBytes(hasher.Sum(nil)) + return hash } // Hash160 performs sha256 and then ripemd160 // on the given data -func Hash160(data []byte) (util.Uint160, error) { +func Hash160(data []byte) util.Uint160 { var hash util.Uint160 + h1 := Sha256(data) + h2 := RipeMD160(h1.Bytes()) + hash, _ = util.Uint160DecodeBytes(h2.Bytes()) - h2, err := RipeMD160(h1.Bytes()) - - hash, err = util.Uint160DecodeBytes(h2.Bytes()) - - if err != nil { - return hash, err - } - return hash, nil + return hash } // Checksum returns the checksum for a given piece of data diff --git a/pkg/crypto/hash/hash_test.go b/pkg/crypto/hash/hash_test.go index 8e5723823..272b744fd 100755 --- a/pkg/crypto/hash/hash_test.go +++ b/pkg/crypto/hash/hash_test.go @@ -31,11 +31,8 @@ func TestHashDoubleSha256(t *testing.T) { func TestHashRipeMD160(t *testing.T) { input := []byte("hello") - data, err := RipeMD160(input) + data := RipeMD160(input) - if err != nil { - t.Fatal(err) - } expected := "108f07b8382412612c048d07d13f814118445acd" actual := hex.EncodeToString(data.Bytes()) assert.Equal(t, expected, actual) @@ -44,11 +41,8 @@ func TestHashRipeMD160(t *testing.T) { func TestHash160(t *testing.T) { input := "02cccafb41b220cab63fd77108d2d1ebcffa32be26da29a04dca4996afce5f75db" publicKeyBytes, _ := hex.DecodeString(input) - data, err := Hash160(publicKeyBytes) + data := Hash160(publicKeyBytes) - if err != nil { - t.Fatal(err) - } expected := "c8e2b685cc70ec96743b55beb9449782f8f775d8" actual := hex.EncodeToString(data.Bytes()) assert.Equal(t, expected, actual) From 2fd782eee89402f10b5746f281077b10765b31c7 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 18:19:07 +0300 Subject: [PATCH 14/16] util: drop RandUint32() I don't see anything useful in it, all the current users of it should just use plain rand.Uint32() not limiting its output in any way. --- pkg/network/helper_test.go | 3 ++- pkg/network/server.go | 7 ++++++- pkg/util/random.go | 16 ---------------- 3 files changed, 8 insertions(+), 18 deletions(-) delete mode 100644 pkg/util/random.go diff --git a/pkg/network/helper_test.go b/pkg/network/helper_test.go index 9bb6803b1..bdf6a9c83 100644 --- a/pkg/network/helper_test.go +++ b/pkg/network/helper_test.go @@ -1,6 +1,7 @@ package network import ( + "math/rand" "testing" "time" @@ -149,7 +150,7 @@ func newTestServer() *Server { chain: testChain{}, transport: localTransport{}, discovery: testDiscovery{}, - id: util.RandUint32(1000000, 9999999), + id: rand.Uint32(), quit: make(chan struct{}), register: make(chan Peer), unregister: make(chan peerDrop), diff --git a/pkg/network/server.go b/pkg/network/server.go index f6e9f4416..d6e260956 100644 --- a/pkg/network/server.go +++ b/pkg/network/server.go @@ -3,6 +3,7 @@ package network import ( "errors" "fmt" + "math/rand" "sync" "time" @@ -61,7 +62,7 @@ func NewServer(config ServerConfig, chain core.Blockchainer) *Server { s := &Server{ ServerConfig: config, chain: chain, - id: util.RandUint32(1000000, 9999999), + id: rand.Uint32(), quit: make(chan struct{}), register: make(chan Peer), unregister: make(chan peerDrop), @@ -349,3 +350,7 @@ func (s *Server) RelayDirectly(p Peer, inv *payload.Inventory) { p.WriteMsg(NewMessage(s.Net, CMDInv, inv)) } + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} diff --git a/pkg/util/random.go b/pkg/util/random.go deleted file mode 100644 index 0ea02d4d9..000000000 --- a/pkg/util/random.go +++ /dev/null @@ -1,16 +0,0 @@ -package util - -import ( - "math/rand" - "time" -) - -// RandUint32 return a random number between min and max. -func RandUint32(min, max int) uint32 { - n := min + rand.Intn(max-min) - return uint32(n) -} - -func init() { - rand.Seed(time.Now().UTC().UnixNano()) -} From ec7e17ffa639031544581803a1188d60f92cca69 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 18:50:45 +0300 Subject: [PATCH 15/16] pkg: make use of the new crypto/hash package Simplifies a lot of code and removes some duplication. Unfortunately I had to move test_util random functions in same commit to avoid cycle dependencies. One of these random functions was also used in core/transaction testing, to simplify things I've just dropped it there and used a static string (which is nice to have for a test anyway). There is still sha256 left in wallet (but it needs to pass Hash structure into the signing function). --- pkg/core/account_state_test.go | 4 +-- pkg/core/asset_state_test.go | 6 ++-- pkg/core/block_base.go | 9 ++---- pkg/core/blockchain.go | 4 +-- pkg/core/header_test.go | 6 ++-- pkg/core/helper_test.go | 6 ++-- pkg/core/random_util_test.go | 40 ++++++++++++++++++++++++ pkg/core/spent_coin_state_test.go | 8 ++--- pkg/core/transaction/register_test.go | 3 +- pkg/core/transaction/transaction.go | 7 ++--- pkg/core/transaction/witness.go | 5 +-- pkg/core/unspent_coint_state_test.go | 7 ++--- pkg/core/util.go | 12 +++---- pkg/crypto/base58.go | 26 ++-------------- pkg/crypto/merkle_tree.go | 11 ++----- pkg/crypto/public_key.go | 25 +++------------ pkg/network/message.go | 14 +++------ pkg/network/payload/getblocks_test.go | 20 ++++++------ pkg/network/payload/inventory_test.go | 6 ++-- pkg/util/test_util.go | 45 --------------------------- pkg/util/uint160.go | 14 --------- pkg/vm/vm.go | 21 +++---------- pkg/wallet/nep2.go | 19 +++-------- 23 files changed, 110 insertions(+), 208 deletions(-) create mode 100644 pkg/core/random_util_test.go delete mode 100644 pkg/util/test_util.go diff --git a/pkg/core/account_state_test.go b/pkg/core/account_state_test.go index 461da4f51..abce2daf9 100644 --- a/pkg/core/account_state_test.go +++ b/pkg/core/account_state_test.go @@ -16,7 +16,7 @@ func TestDecodeEncodeAccountState(t *testing.T) { votes = make([]*crypto.PublicKey, n) ) for i := 0; i < n; i++ { - balances[util.RandomUint256()] = util.Fixed8(int64(util.RandomInt(1, 10000))) + balances[randomUint256()] = util.Fixed8(int64(randomInt(1, 10000))) votes[i] = &crypto.PublicKey{ ECPoint: crypto.RandomECPoint(), } @@ -24,7 +24,7 @@ func TestDecodeEncodeAccountState(t *testing.T) { a := &AccountState{ Version: 0, - ScriptHash: util.RandomUint160(), + ScriptHash: randomUint160(), IsFrozen: true, Votes: votes, Balances: balances, diff --git a/pkg/core/asset_state_test.go b/pkg/core/asset_state_test.go index 802152c9a..37ca5eee4 100644 --- a/pkg/core/asset_state_test.go +++ b/pkg/core/asset_state_test.go @@ -12,7 +12,7 @@ import ( func TestEncodeDecodeAssetState(t *testing.T) { asset := &AssetState{ - ID: util.RandomUint256(), + ID: randomUint256(), AssetType: transaction.Token, Name: "super cool token", Amount: util.Fixed8(1000000), @@ -20,8 +20,8 @@ func TestEncodeDecodeAssetState(t *testing.T) { Precision: 0, FeeMode: feeMode, Owner: &crypto.PublicKey{}, - Admin: util.RandomUint160(), - Issuer: util.RandomUint160(), + Admin: randomUint160(), + Issuer: randomUint160(), Expiration: 10, IsFrozen: false, } diff --git a/pkg/core/block_base.go b/pkg/core/block_base.go index 0fbc0c0c9..608e3e706 100644 --- a/pkg/core/block_base.go +++ b/pkg/core/block_base.go @@ -2,12 +2,12 @@ package core import ( "bytes" - "crypto/sha256" "encoding/binary" "fmt" "io" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" ) @@ -100,12 +100,7 @@ func (b *BlockBase) createHash() error { if err := b.encodeHashableFields(buf); err != nil { return err } - - // Double hash the encoded fields. - var hash util.Uint256 - hash = sha256.Sum256(buf.Bytes()) - hash = sha256.Sum256(hash.Bytes()) - b.hash = hash + b.hash = hash.DoubleSha256(buf.Bytes()) return nil } diff --git a/pkg/core/blockchain.go b/pkg/core/blockchain.go index bd8e6365d..a6c0bd7b1 100644 --- a/pkg/core/blockchain.go +++ b/pkg/core/blockchain.go @@ -906,8 +906,8 @@ func (bc *Blockchain) VerifyWitnesses(t *transaction.Transaction) error { */ } else { - if h, err := witnesses[i].ScriptHash(); err != nil || hashes[i] != h { - return err + if h := witnesses[i].ScriptHash(); hashes[i] != h { + return errors.Errorf("hash mismatch for script #%d", i) } } diff --git a/pkg/core/header_test.go b/pkg/core/header_test.go index f9dff4eb7..ef7dcbec0 100644 --- a/pkg/core/header_test.go +++ b/pkg/core/header_test.go @@ -2,19 +2,19 @@ package core import ( "bytes" - "crypto/sha256" "testing" "time" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" ) func TestHeaderEncodeDecode(t *testing.T) { header := Header{BlockBase: BlockBase{ Version: 0, - PrevHash: sha256.Sum256([]byte("prevhash")), - MerkleRoot: sha256.Sum256([]byte("merkleroot")), + PrevHash: hash.Sha256([]byte("prevhash")), + MerkleRoot: hash.Sha256([]byte("merkleroot")), Timestamp: uint32(time.Now().UTC().Unix()), Index: 3445, ConsensusData: 394949, diff --git a/pkg/core/helper_test.go b/pkg/core/helper_test.go index febbee30d..27317f64a 100644 --- a/pkg/core/helper_test.go +++ b/pkg/core/helper_test.go @@ -2,7 +2,6 @@ package core import ( "bytes" - "crypto/sha256" "encoding/hex" "encoding/json" "fmt" @@ -11,6 +10,7 @@ import ( "time" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" ) @@ -18,8 +18,8 @@ func newBlock(index uint32, txs ...*transaction.Transaction) *Block { b := &Block{ BlockBase: BlockBase{ Version: 0, - PrevHash: sha256.Sum256([]byte("a")), - MerkleRoot: sha256.Sum256([]byte("b")), + PrevHash: hash.Sha256([]byte("a")), + MerkleRoot: hash.Sha256([]byte("b")), Timestamp: uint32(time.Now().UTC().Unix()), Index: index, ConsensusData: 1111, diff --git a/pkg/core/random_util_test.go b/pkg/core/random_util_test.go new file mode 100644 index 000000000..dc2b6150d --- /dev/null +++ b/pkg/core/random_util_test.go @@ -0,0 +1,40 @@ +package core + +import ( + "math/rand" + "time" + + "github.com/CityOfZion/neo-go/pkg/crypto/hash" + "github.com/CityOfZion/neo-go/pkg/util" +) + +// RandomString returns a random string with the n as its length. +func randomString(n int) string { + b := make([]byte, n) + for i := range b { + b[i] = byte(randomInt(65, 90)) + } + + return string(b) +} + +// RandomInt returns a random integer between min and max. +func randomInt(min, max int) int { + return min + rand.Intn(max-min) +} + +// RandomUint256 returns a random Uint256. +func randomUint256() util.Uint256 { + str := randomString(20) + return hash.Sha256([]byte(str)) +} + +// RandomUint160 returns a random Uint160. +func randomUint160() util.Uint160 { + str := randomString(20) + return hash.RipeMD160([]byte(str)) +} + +func init() { + rand.Seed(time.Now().UTC().UnixNano()) +} diff --git a/pkg/core/spent_coin_state_test.go b/pkg/core/spent_coin_state_test.go index 6b61fff6f..8a2b03981 100644 --- a/pkg/core/spent_coin_state_test.go +++ b/pkg/core/spent_coin_state_test.go @@ -11,7 +11,7 @@ import ( func TestEncodeDecodeSpentCoinState(t *testing.T) { spent := &SpentCoinState{ - txHash: util.RandomUint256(), + txHash: randomUint256(), txHeight: 1001, items: map[uint16]uint32{ 1: 3, @@ -35,9 +35,9 @@ func TestCommitSpentCoins(t *testing.T) { ) txx := []util.Uint256{ - util.RandomUint256(), - util.RandomUint256(), - util.RandomUint256(), + randomUint256(), + randomUint256(), + randomUint256(), } for i := 0; i < len(txx); i++ { diff --git a/pkg/core/transaction/register_test.go b/pkg/core/transaction/register_test.go index 8512f8f7d..cbb48570c 100644 --- a/pkg/core/transaction/register_test.go +++ b/pkg/core/transaction/register_test.go @@ -11,6 +11,7 @@ import ( ) func TestRegisterTX(t *testing.T) { + someuint160, _ := util.Uint160DecodeString("4d3b96ae1bcc5a585e075e3b81920210dec16302") tx := &Transaction{ Type: RegisterType, Version: 0, @@ -20,7 +21,7 @@ func TestRegisterTX(t *testing.T) { Amount: util.Fixed8FromInt64(1000000), Precision: 8, Owner: &crypto.PublicKey{}, - Admin: util.RandomUint160(), + Admin: someuint160, }, } diff --git a/pkg/core/transaction/transaction.go b/pkg/core/transaction/transaction.go index 7a045d7f7..d95f73dd9 100644 --- a/pkg/core/transaction/transaction.go +++ b/pkg/core/transaction/transaction.go @@ -2,10 +2,10 @@ package transaction import ( "bytes" - "crypto/sha256" "encoding/binary" "io" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" log "github.com/sirupsen/logrus" ) @@ -240,10 +240,7 @@ func (t *Transaction) createHash() error { return err } - var hash util.Uint256 - hash = sha256.Sum256(buf.Bytes()) - hash = sha256.Sum256(hash.Bytes()) - t.hash = hash + t.hash = hash.DoubleSha256(buf.Bytes()) return nil } diff --git a/pkg/core/transaction/witness.go b/pkg/core/transaction/witness.go index d3e4d1570..cf10d8bb2 100644 --- a/pkg/core/transaction/witness.go +++ b/pkg/core/transaction/witness.go @@ -6,6 +6,7 @@ import ( "encoding/json" "io" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" ) @@ -57,6 +58,6 @@ func (w *Witness) Size() int { } // ScriptHash returns the hash of the VerificationScript. -func (w Witness) ScriptHash() (util.Uint160, error) { - return util.Uint160FromScript(w.VerificationScript) +func (w Witness) ScriptHash() util.Uint160 { + return hash.Hash160(w.VerificationScript) } diff --git a/pkg/core/unspent_coint_state_test.go b/pkg/core/unspent_coint_state_test.go index 223b26ff8..3338f6b8a 100644 --- a/pkg/core/unspent_coint_state_test.go +++ b/pkg/core/unspent_coint_state_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/CityOfZion/neo-go/pkg/core/storage" - "github.com/CityOfZion/neo-go/pkg/util" "github.com/stretchr/testify/assert" ) @@ -33,9 +32,9 @@ func TestCommitUnspentCoins(t *testing.T) { unspentCoins = make(UnspentCoins) ) - txA := util.RandomUint256() - txB := util.RandomUint256() - txC := util.RandomUint256() + txA := randomUint256() + txB := randomUint256() + txC := randomUint256() unspentCoins[txA] = &UnspentCoinState{ states: []CoinState{CoinStateConfirmed}, diff --git a/pkg/core/util.go b/pkg/core/util.go index dffbc7b41..8ee050185 100644 --- a/pkg/core/util.go +++ b/pkg/core/util.go @@ -9,6 +9,7 @@ import ( "github.com/CityOfZion/neo-go/pkg/core/storage" "github.com/CityOfZion/neo-go/pkg/core/transaction" "github.com/CityOfZion/neo-go/pkg/crypto" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/smartcontract" "github.com/CityOfZion/neo-go/pkg/util" "github.com/CityOfZion/neo-go/pkg/vm" @@ -48,10 +49,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { if err != nil { return nil, err } - scriptOut, err := util.Uint160FromScript(rawScript) - if err != nil { - return nil, err - } + scriptOut := hash.Hash160(rawScript) block := &Block{ BlockBase: base, @@ -97,7 +95,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) { } func governingTokenTX() *transaction.Transaction { - admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHT)}) + admin := hash.Hash160([]byte{byte(vm.PUSHT)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.GoverningToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]", @@ -120,7 +118,7 @@ func governingTokenTX() *transaction.Transaction { } func utilityTokenTX() *transaction.Transaction { - admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHF)}) + admin := hash.Hash160([]byte{byte(vm.PUSHF)}) registerTX := &transaction.RegisterTX{ AssetType: transaction.UtilityToken, Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]", @@ -162,7 +160,7 @@ func getNextConsensusAddress(validators []*crypto.PublicKey) (val util.Uint160, if err != nil { return val, err } - return util.Uint160FromScript(raw) + return hash.Hash160(raw), nil } func calculateUtilityAmount() util.Fixed8 { diff --git a/pkg/crypto/base58.go b/pkg/crypto/base58.go index 3f967d965..43fc91884 100644 --- a/pkg/crypto/base58.go +++ b/pkg/crypto/base58.go @@ -2,10 +2,10 @@ package crypto import ( "bytes" - "crypto/sha256" "fmt" "math/big" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/pkg/errors" ) @@ -99,19 +99,7 @@ func Base58CheckDecode(s string) (b []byte, err error) { return nil, errors.New("invalid base-58 check string: missing checksum.") } - sha := sha256.New() - if _, err = sha.Write(b[:len(b)-4]); err != nil { - return nil, err - } - hash := sha.Sum(nil) - - sha.Reset() - if _, err = sha.Write(hash); err != nil { - return nil, err - } - hash = sha.Sum(nil) - - if !bytes.Equal(hash[0:4], b[len(b)-4:]) { + if !bytes.Equal(hash.Checksum(b[:len(b)-4]), b[len(b)-4:]) { return nil, errors.New("invalid base-58 check string: invalid checksum.") } @@ -123,15 +111,7 @@ func Base58CheckDecode(s string) (b []byte, err error) { // Base58checkEncode encodes b into a base-58 check encoded string. func Base58CheckEncode(b []byte) string { - 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]...) + b = append(b, hash.Checksum(b)...) return Base58Encode(b) } diff --git a/pkg/crypto/merkle_tree.go b/pkg/crypto/merkle_tree.go index 1226b9def..a1cf339e8 100644 --- a/pkg/crypto/merkle_tree.go +++ b/pkg/crypto/merkle_tree.go @@ -1,9 +1,9 @@ package crypto import ( - "crypto/sha256" "errors" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" ) @@ -67,7 +67,7 @@ func buildMerkleTree(leaves []*MerkleTreeNode) (*MerkleTreeNode, error) { b1 := parents[i].leftChild.hash.Bytes() b2 := parents[i].rightChild.hash.Bytes() b1 = append(b1, b2...) - parents[i].hash = hash256(b1) + parents[i].hash = hash.DoubleSha256(b1) } return buildMerkleTree(parents) @@ -90,10 +90,3 @@ func (n *MerkleTreeNode) IsLeaf() bool { func (n *MerkleTreeNode) IsRoot() bool { return n.parent == nil } - -func hash256(b []byte) util.Uint256 { - var hash util.Uint256 - hash = sha256.Sum256(b) - hash = sha256.Sum256(hash.Bytes()) - return hash -} diff --git a/pkg/crypto/public_key.go b/pkg/crypto/public_key.go index fd70088ed..4eb2c8b55 100644 --- a/pkg/crypto/public_key.go +++ b/pkg/crypto/public_key.go @@ -3,15 +3,14 @@ package crypto import ( "bytes" "crypto/ecdsa" - "crypto/sha256" "crypto/x509" "encoding/binary" "encoding/hex" "io" "math/big" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/pkg/errors" - "golang.org/x/crypto/ripemd160" ) // PublicKeys is a list of public keys. @@ -172,16 +171,9 @@ func (p *PublicKey) Signature() ([]byte, error) { b = append([]byte{0x21}, b...) b = append(b, 0xAC) - sha := sha256.New() - sha.Write(b) - hash := sha.Sum(nil) + sig := hash.Hash160(b) - ripemd := ripemd160.New() - ripemd.Reset() - ripemd.Write(hash) - hash = ripemd.Sum(nil) - - return hash, nil + return sig.Bytes(), nil } func (p *PublicKey) Address() (string, error) { @@ -195,15 +187,8 @@ func (p *PublicKey) Address() (string, error) { 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]...) + csum := hash.Checksum(b) + b = append(b, csum...) address := Base58Encode(b) return address, nil diff --git a/pkg/network/message.go b/pkg/network/message.go index 54c675eb7..2154c848e 100644 --- a/pkg/network/message.go +++ b/pkg/network/message.go @@ -2,7 +2,6 @@ package network import ( "bytes" - "crypto/sha256" "encoding/binary" "errors" "fmt" @@ -11,6 +10,7 @@ import ( "github.com/CityOfZion/neo-go/config" "github.com/CityOfZion/neo-go/pkg/core" "github.com/CityOfZion/neo-go/pkg/core/transaction" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/network/payload" ) @@ -81,9 +81,9 @@ func NewMessage(magic config.NetMode, cmd CommandType, p payload.Payload) *Messa panic(err) } size = uint32(buf.Len()) - checksum = sumSHA256(sumSHA256(buf.Bytes())) + checksum = hash.Checksum(buf.Bytes()) } else { - checksum = sumSHA256(sumSHA256([]byte{})) + checksum = hash.Checksum([]byte{}) } return &Message{ @@ -269,14 +269,8 @@ func cmdByteArrayToString(cmd [cmdSize]byte) string { return string(buf) } -func sumSHA256(b []byte) []byte { - h := sha256.New() - h.Write(b) - return h.Sum(nil) -} - func compareChecksum(have uint32, b []byte) bool { - sum := sumSHA256(sumSHA256(b))[:4] + sum := hash.Checksum(b) want := binary.LittleEndian.Uint32(sum) return have == want } diff --git a/pkg/network/payload/getblocks_test.go b/pkg/network/payload/getblocks_test.go index 63d292a70..42d68785e 100644 --- a/pkg/network/payload/getblocks_test.go +++ b/pkg/network/payload/getblocks_test.go @@ -2,19 +2,19 @@ package payload import ( "bytes" - "crypto/sha256" "testing" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" "github.com/stretchr/testify/assert" ) func TestGetBlockEncodeDecode(t *testing.T) { start := []util.Uint256{ - sha256.Sum256([]byte("a")), - sha256.Sum256([]byte("b")), - sha256.Sum256([]byte("c")), - sha256.Sum256([]byte("d")), + hash.Sha256([]byte("a")), + hash.Sha256([]byte("b")), + hash.Sha256([]byte("c")), + hash.Sha256([]byte("d")), } p := NewGetBlocks(start, util.Uint256{}) @@ -34,12 +34,12 @@ func TestGetBlockEncodeDecode(t *testing.T) { func TestGetBlockEncodeDecodeWithHashStop(t *testing.T) { var ( start = []util.Uint256{ - sha256.Sum256([]byte("a")), - sha256.Sum256([]byte("b")), - sha256.Sum256([]byte("c")), - sha256.Sum256([]byte("d")), + hash.Sha256([]byte("a")), + hash.Sha256([]byte("b")), + hash.Sha256([]byte("c")), + hash.Sha256([]byte("d")), } - stop = sha256.Sum256([]byte("e")) + stop = hash.Sha256([]byte("e")) ) p := NewGetBlocks(start, stop) buf := new(bytes.Buffer) diff --git a/pkg/network/payload/inventory_test.go b/pkg/network/payload/inventory_test.go index 4cfba1ef5..cab2ab499 100644 --- a/pkg/network/payload/inventory_test.go +++ b/pkg/network/payload/inventory_test.go @@ -2,17 +2,17 @@ package payload import ( "bytes" - "crypto/sha256" "reflect" "testing" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" . "github.com/CityOfZion/neo-go/pkg/util" ) func TestInventoryEncodeDecode(t *testing.T) { hashes := []Uint256{ - sha256.Sum256([]byte("a")), - sha256.Sum256([]byte("b")), + hash.Sha256([]byte("a")), + hash.Sha256([]byte("b")), } inv := NewInventory(BlockType, hashes) diff --git a/pkg/util/test_util.go b/pkg/util/test_util.go deleted file mode 100644 index d4f69992f..000000000 --- a/pkg/util/test_util.go +++ /dev/null @@ -1,45 +0,0 @@ -package util - -import ( - "crypto/sha256" - "math/rand" - "time" - - "golang.org/x/crypto/ripemd160" -) - -// RandomString returns a random string with the n as its length. -func RandomString(n int) string { - b := make([]byte, n) - for i := range b { - b[i] = byte(RandomInt(65, 90)) - } - - return string(b) -} - -// RandomInt returns a random integer between min and max. -func RandomInt(min, max int) int { - return min + rand.Intn(max-min) -} - -// RandomUint256 returns a random Uint256. -func RandomUint256() Uint256 { - str := RandomString(20) - h := sha256.Sum256([]byte(str)) - return Uint256(h) -} - -// RandomUint160 returns a random Uint160. -func RandomUint160() Uint160 { - str := RandomString(20) - ripemd := ripemd160.New() - ripemd.Write([]byte(str)) - h := ripemd.Sum(nil) - v, _ := Uint160DecodeBytes(h) - return v -} - -func init() { - rand.Seed(time.Now().UTC().UnixNano()) -} diff --git a/pkg/util/uint160.go b/pkg/util/uint160.go index 6efb0f546..6da50850e 100644 --- a/pkg/util/uint160.go +++ b/pkg/util/uint160.go @@ -1,13 +1,10 @@ package util import ( - "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "strings" - - "golang.org/x/crypto/ripemd160" ) const uint160Size = 20 @@ -37,17 +34,6 @@ func Uint160DecodeBytes(b []byte) (u Uint160, err error) { return } -// Uint160FromScript returns a Uint160 type from a raw script. -func Uint160FromScript(script []byte) (u Uint160, err error) { - sha := sha256.New() - sha.Write(script) - b := sha.Sum(nil) - ripemd := ripemd160.New() - ripemd.Write(b) - b = ripemd.Sum(nil) - return Uint160DecodeBytes(b) -} - // Bytes returns the byte slice representation of u. func (u Uint160) Bytes() []byte { return u[:] diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index d4493d5fc..19914cce2 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -2,7 +2,6 @@ package vm import ( "crypto/sha1" - "crypto/sha256" "fmt" "io/ioutil" "log" @@ -11,8 +10,8 @@ import ( "text/tabwriter" "reflect" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "github.com/CityOfZion/neo-go/pkg/util" - "golang.org/x/crypto/ripemd160" ) // Mode configures behaviour of the VM. @@ -676,27 +675,15 @@ func (v *VM) execute(ctx *Context, op Instruction) { case SHA256: b := v.estack.Pop().Bytes() - sha := sha256.New() - sha.Write(b) - v.estack.PushVal(sha.Sum(nil)) + v.estack.PushVal(hash.Sha256(b).Bytes()) case HASH160: b := v.estack.Pop().Bytes() - sha := sha256.New() - sha.Write(b) - h := sha.Sum(nil) - ripemd := ripemd160.New() - ripemd.Write(h) - v.estack.PushVal(ripemd.Sum(nil)) + v.estack.PushVal(hash.Hash160(b).Bytes()) case HASH256: b := v.estack.Pop().Bytes() - sha := sha256.New() - sha.Write(b) - h := sha.Sum(nil) - sha.Reset() - sha.Write(h) - v.estack.PushVal(sha.Sum(nil)) + v.estack.PushVal(hash.DoubleSha256(b).Bytes()) case CHECKSIG: // pubkey := v.estack.Pop().Bytes() diff --git a/pkg/wallet/nep2.go b/pkg/wallet/nep2.go index 651567a9c..df43bf38c 100644 --- a/pkg/wallet/nep2.go +++ b/pkg/wallet/nep2.go @@ -2,11 +2,11 @@ package wallet import ( "bytes" - "crypto/sha256" "errors" "fmt" "github.com/CityOfZion/neo-go/pkg/crypto" + "github.com/CityOfZion/neo-go/pkg/crypto/hash" "golang.org/x/crypto/scrypt" "golang.org/x/text/unicode/norm" ) @@ -46,7 +46,7 @@ func NEP2Encrypt(priv *PrivateKey, passphrase string) (s string, err error) { return s, err } - addrHash := hashAddress(address)[0:4] + addrHash := hash.Checksum([]byte(address)) // Normalize the passphrase according to the NFC standard. phraseNorm := norm.NFC.Bytes([]byte(passphrase)) derivedKey, err := scrypt.Key(phraseNorm, addrHash, n, r, p, keyLen) @@ -119,13 +119,13 @@ func NEP2Decrypt(key, passphrase string) (s string, err error) { return privKey.WIF() } -func compareAddressHash(priv *PrivateKey, hash []byte) bool { +func compareAddressHash(priv *PrivateKey, inhash []byte) bool { address, err := priv.Address() if err != nil { return false } - addrHash := hashAddress(address)[0:4] - return bytes.Equal(addrHash, hash) + addrHash := hash.Checksum([]byte(address)) + return bytes.Equal(addrHash, inhash) } func validateNEP2Format(b []byte) error { @@ -154,12 +154,3 @@ func xor(a, b []byte) []byte { } return dst } - -func hashAddress(addr string) []byte { - sha := sha256.New() - sha.Write([]byte(addr)) - hash := sha.Sum(nil) - sha.Reset() - sha.Write(hash) - return sha.Sum(nil) -} From 7165b5ab1ee7b8603c138db0e9ee37c00fdef790 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Fri, 23 Aug 2019 19:12:02 +0300 Subject: [PATCH 16/16] base58: add testing from _pkg.dev And drop implementation in _pkg.dev, as it's redundant. Refs. #307. --- _pkg.dev/crypto/base58/base58.go | 126 ------------------ .../base58 => pkg/crypto}/base58_test.go | 10 +- 2 files changed, 5 insertions(+), 131 deletions(-) delete mode 100755 _pkg.dev/crypto/base58/base58.go rename {_pkg.dev/crypto/base58 => pkg/crypto}/base58_test.go (77%) diff --git a/_pkg.dev/crypto/base58/base58.go b/_pkg.dev/crypto/base58/base58.go deleted file mode 100755 index 5d57dc8c4..000000000 --- a/_pkg.dev/crypto/base58/base58.go +++ /dev/null @@ -1,126 +0,0 @@ -package base58 - -import ( - "bytes" - "fmt" - "math/big" - - "github.com/CityOfZion/neo-go/pkg/crypto/hash" -) - -const prefix rune = '1' - -var decodeMap = map[rune]int64{ - '1': 0, '2': 1, '3': 2, '4': 3, '5': 4, - '6': 5, '7': 6, '8': 7, '9': 8, 'A': 9, - 'B': 10, 'C': 11, 'D': 12, 'E': 13, 'F': 14, - 'G': 15, 'H': 16, 'J': 17, 'K': 18, 'L': 19, - 'M': 20, 'N': 21, 'P': 22, 'Q': 23, 'R': 24, - 'S': 25, 'T': 26, 'U': 27, 'V': 28, 'W': 29, - 'X': 30, 'Y': 31, 'Z': 32, 'a': 33, 'b': 34, - 'c': 35, 'd': 36, 'e': 37, 'f': 38, 'g': 39, - 'h': 40, 'i': 41, 'j': 42, 'k': 43, 'm': 44, - 'n': 45, 'o': 46, 'p': 47, 'q': 48, 'r': 49, - 's': 50, 't': 51, 'u': 52, 'v': 53, 'w': 54, - 'x': 55, 'y': 56, 'z': 57, -} - -// Decode decodes the base58 encoded string. -func Decode(s string) ([]byte, error) { - var ( - startIndex = 0 - zero = 0 - ) - for i, c := range s { - if c == prefix { - zero++ - } else { - startIndex = i - break - } - } - - var ( - n = big.NewInt(0) - div = big.NewInt(58) - ) - for _, c := range s[startIndex:] { - charIndex, ok := decodeMap[c] - if !ok { - return nil, fmt.Errorf( - "invalid character '%c' when decoding this base58 string: '%s'", c, s, - ) - } - n.Add(n.Mul(n, div), big.NewInt(charIndex)) - } - - out := n.Bytes() - buf := make([]byte, (zero + len(out))) - copy(buf[zero:], out[:]) - - return buf, nil -} - -// Encode encodes a byte slice to be a base58 encoded string. -func Encode(bytes []byte) string { - var ( - lookupTable = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" - x = new(big.Int).SetBytes(bytes) - r = new(big.Int) - m = big.NewInt(58) - zero = big.NewInt(0) - encoded string - ) - - for x.Cmp(zero) > 0 { - x.QuoRem(x, m, r) - encoded = string(lookupTable[r.Int64()]) + encoded - } - - return encoded -} - -// CheckDecode decodes the given string. -func CheckDecode(s string) (b []byte, err error) { - b, err = Decode(s) - if err != nil { - return nil, err - } - - for i := 0; i < len(s); i++ { - if s[i] != '1' { - break - } - b = append([]byte{0x00}, b...) - } - - if len(b) < 5 { - return nil, fmt.Errorf("Invalid base-58 check string: missing checksum") - } - - hash, err := hash.DoubleSha256(b[:len(b)-4]) - - if err != nil { - return nil, fmt.Errorf("Could not double sha256 data") - } - - if bytes.Compare(hash[0:4], b[len(b)-4:]) != 0 { - return nil, fmt.Errorf("Invalid base-58 check string: invalid checksum") - } - - // Strip the 4 byte long hash. - b = b[:len(b)-4] - - return b, nil -} - -// CheckEncode encodes b into a base-58 check encoded string. -func CheckEncode(b []byte) (string, error) { - hash, err := hash.DoubleSha256(b) - if err != nil { - return "", fmt.Errorf("Could not double sha256 data") - } - b = append(b, hash[0:4]...) - - return Encode(b), nil -} diff --git a/_pkg.dev/crypto/base58/base58_test.go b/pkg/crypto/base58_test.go similarity index 77% rename from _pkg.dev/crypto/base58/base58_test.go rename to pkg/crypto/base58_test.go index 524f0e55e..7bf48cf70 100755 --- a/_pkg.dev/crypto/base58/base58_test.go +++ b/pkg/crypto/base58_test.go @@ -1,4 +1,4 @@ -package base58 +package crypto import ( "encoding/hex" @@ -7,10 +7,10 @@ import ( "github.com/stretchr/testify/assert" ) -func TestDecode(t *testing.T) { +func TestBase58Decode(t *testing.T) { input := "1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX" - data, err := Decode(input) + data, err := Base58Decode(input) if err != nil { t.Fatal(err) } @@ -19,12 +19,12 @@ func TestDecode(t *testing.T) { actual := hex.EncodeToString(data) assert.Equal(t, expected, actual) } -func TestEncode(t *testing.T) { +func TestBase58Encode(t *testing.T) { input := "0099bc78ba577a95a11f1a344d4d2ae55f2f857b989ea5e5e2" inputBytes, _ := hex.DecodeString(input) - data := Encode(inputBytes) + data := Base58Encode(inputBytes) expected := "F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX" // Removed the 1 as it is not checkEncoding actual := data