pkg: make use of the new crypto/hash package

Simplifies a lot of code and removes some duplication. Unfortunately I had to
move test_util random functions in same commit to avoid cycle
dependencies. One of these random functions was also used in core/transaction
testing, to simplify things I've just dropped it there and used a static
string (which is nice to have for a test anyway).

There is still sha256 left in wallet (but it needs to pass Hash structure into
the signing function).
This commit is contained in:
Roman Khimov 2019-08-23 18:50:45 +03:00
parent 2fd782eee8
commit ec7e17ffa6
23 changed files with 110 additions and 208 deletions

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

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

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

@ -11,6 +11,7 @@ import (
)
func TestRegisterTX(t *testing.T) {
someuint160, _ := util.Uint160DecodeString("4d3b96ae1bcc5a585e075e3b81920210dec16302")
tx := &Transaction{
Type: RegisterType,
Version: 0,
@ -20,7 +21,7 @@ func TestRegisterTX(t *testing.T) {
Amount: util.Fixed8FromInt64(1000000),
Precision: 8,
Owner: &crypto.PublicKey{},
Admin: util.RandomUint160(),
Admin: someuint160,
},
}

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

@ -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,7 +95,7 @@ func createGenesisBlock(cfg config.ProtocolConfiguration) (*Block, error) {
}
func governingTokenTX() *transaction.Transaction {
admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHT)})
admin := hash.Hash160([]byte{byte(vm.PUSHT)})
registerTX := &transaction.RegisterTX{
AssetType: transaction.GoverningToken,
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁股\"},{\"lang\":\"en\",\"name\":\"AntShare\"}]",
@ -120,7 +118,7 @@ func governingTokenTX() *transaction.Transaction {
}
func utilityTokenTX() *transaction.Transaction {
admin, _ := util.Uint160FromScript([]byte{byte(vm.PUSHF)})
admin := hash.Hash160([]byte{byte(vm.PUSHF)})
registerTX := &transaction.RegisterTX{
AssetType: transaction.UtilityToken,
Name: "[{\"lang\":\"zh-CN\",\"name\":\"小蚁币\"},{\"lang\":\"en\",\"name\":\"AntCoin\"}]",
@ -162,7 +160,7 @@ func getNextConsensusAddress(validators []*crypto.PublicKey) (val util.Uint160,
if err != nil {
return val, err
}
return util.Uint160FromScript(raw)
return hash.Hash160(raw), nil
}
func calculateUtilityAmount() util.Fixed8 {

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

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

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

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

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