Merge pull request #315 from nspcc-dev/drop-redundant-dev-code-part-1

Drop redundant dev code part 1
This commit is contained in:
Roman Khimov 2019-08-26 13:45:35 +03:00 committed by GitHub
commit 0beb63fd47
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 345 additions and 2181 deletions

View file

@ -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:]
}
}

View file

@ -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
}

View file

@ -1,88 +0,0 @@
package hash
import (
"crypto/sha256"
"io"
"github.com/CityOfZion/neo-go/pkg/wire/util"
"golang.org/x/crypto/ripemd160"
)
// 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
}
// DoubleSha256 performs sha256 twice on the given data
func DoubleSha256(data []byte) (util.Uint256, error) {
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
}
// RipeMD160 performs the RIPEMD160 hash algorithm
// on the given data
func RipeMD160(data []byte) (util.Uint160, error) {
var hash util.Uint160
hasher := ripemd160.New()
hasher.Reset()
_, err := io.WriteString(hasher, string(data))
hash, err = util.Uint160DecodeBytes(hasher.Sum(nil))
if err != nil {
return hash, err
}
return hash, nil
}
// Hash160 performs sha256 and then ripemd160
// on the given data
func Hash160(data []byte) (util.Uint160, error) {
var hash util.Uint160
h1, err := Sha256(data)
h2, err := RipeMD160(h1.Bytes())
hash, err = util.Uint160DecodeBytes(h2.Bytes())
if err != nil {
return hash, err
}
return hash, nil
}
// 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
}

View file

@ -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.

View file

@ -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.

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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!")
}
}

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}
}

View file

@ -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()))),
)
}

View file

@ -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())
}

View file

@ -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()))
}

View file

@ -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)
}
}

View file

@ -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)
}
}

View file

@ -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,

View file

@ -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,
}

View file

@ -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
}

View file

@ -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{})

View file

@ -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.
@ -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)
}
}

View file

@ -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)

View file

@ -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,

View file

@ -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,

View file

@ -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())
}

View file

@ -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++ {

View file

@ -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
}

View file

@ -11,16 +11,17 @@ import (
)
func TestRegisterTX(t *testing.T) {
someuint160, _ := util.Uint160DecodeString("4d3b96ae1bcc5a585e075e3b81920210dec16302")
tx := &Transaction{
Type: RegisterType,
Version: 0,
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(),
Admin: someuint160,
},
}
@ -48,11 +49,11 @@ 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))
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().String())
assert.Equal(t, "c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b", tx.Hash().ReverseString())
buf := new(bytes.Buffer)
assert.Nil(t, tx.EncodeBinary(buf))

View file

@ -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
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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},

View file

@ -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,11 +95,11 @@ 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\"}]",
Amount: util.NewFixed8(100000000),
Amount: util.Fixed8FromInt64(100000000),
Precision: 0,
Owner: &crypto.PublicKey{},
Admin: admin,
@ -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 {
@ -170,7 +168,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.

View file

@ -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())
}

View file

@ -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)
}

View file

@ -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

54
pkg/crypto/hash/hash.go Executable file
View file

@ -0,0 +1,54 @@
package hash
import (
"crypto/sha256"
"github.com/CityOfZion/neo-go/pkg/util"
"golang.org/x/crypto/ripemd160"
)
// Sha256 hashes the incoming byte slice
// using the sha256 algorithm
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 {
var hash util.Uint256
h1 := Sha256(data)
hash = Sha256(h1.Bytes())
return hash
}
// RipeMD160 performs the RIPEMD160 hash algorithm
// on the given data
func RipeMD160(data []byte) util.Uint160 {
var hash util.Uint160
hasher := ripemd160.New()
_, _ = hasher.Write(data)
hash, _ = util.Uint160DecodeBytes(hasher.Sum(nil))
return hash
}
// Hash160 performs sha256 and then ripemd160
// on the given data
func Hash160(data []byte) util.Uint160 {
var hash util.Uint160
h1 := Sha256(data)
h2 := RipeMD160(h1.Bytes())
hash, _ = util.Uint160DecodeBytes(h2.Bytes())
return hash
}
// Checksum returns the checksum for a given piece of data
// using sha256 twice as the hash algorithm
func Checksum(data []byte) []byte {
hash := DoubleSha256(data)
return hash[:4]
}

View file

@ -9,27 +9,20 @@ 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()) // MARK: In the DecodeBytes function, there is a bytes reverse, not sure why?
actual := hex.EncodeToString(data.Bytes())
assert.Equal(t, expected, actual)
}
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())
@ -38,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)
@ -51,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)

View file

@ -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
}

View file

@ -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())
}

View file

@ -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

View file

@ -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),

View file

@ -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
}

View file

@ -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)

View file

@ -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)

View file

@ -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())
}

View file

@ -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)

View file

@ -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
}

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)
}

View file

@ -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}

View file

@ -34,29 +34,34 @@ 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()
}
// 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
}
// 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 {
@ -82,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
}
@ -111,37 +116,37 @@ 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.
func (f Fixed8) Div(i int64) Fixed8 {
return NewFixed8(f.Value() / i)
return f / Fixed8FromInt64(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 +154,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)
}

View file

@ -8,37 +8,69 @@ import (
"github.com/stretchr/testify/assert"
)
func TestNewFixed8(t *testing.T) {
values := []int64{9000, 100000000, 5, 10945}
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).Value())
assert.Equal(t, Fixed8(val*decimals), Fixed8FromInt64(val))
assert.Equal(t, val, Fixed8FromInt64(val).Int64Value())
}
}
func TestFixed8DecodeString(t *testing.T) {
// Fixed8DecodeString works correctly with integers
ivalues := []string{"9000", "100000000", "5", "10945"}
func TestFixed8Add(t *testing.T) {
a := Fixed8FromInt64(1)
b := Fixed8FromInt64(2)
c := a.Add(b)
expected := int64(3)
assert.Equal(t, strconv.FormatInt(expected, 10), c.String())
}
func TestFixed8Sub(t *testing.T) {
a := Fixed8FromInt64(42)
b := Fixed8FromInt64(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), Fixed8FromFloat(val))
assert.Equal(t, val, Fixed8FromFloat(val).FloatValue())
}
}
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)
}
func TestSatoshi(t *testing.T) {
satoshif8 := Satoshi()
assert.Equal(t, "0.00000001", satoshif8.String())
}
func TestFixed8UnmarshalJSON(t *testing.T) {
var testCases = []float64{
123.45,
@ -47,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

View file

@ -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())
}

View file

@ -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())
}

View file

@ -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[:]
@ -63,6 +49,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

View file

@ -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())
}

View file

@ -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,12 +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.
// Uint256DecodeBytes attempts to decode the given string (in BE representation) into an Uint256.
func Uint256DecodeBytes(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))
}
@ -35,11 +34,23 @@ func Uint256DecodeBytes(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[:]
}
// 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 +63,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 +78,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 +89,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

View file

@ -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)
}

View file

@ -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()

View file

@ -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)
}