Skip to content

Commit

Permalink
crypto, *: introduce own Hash/Address implementation
Browse files Browse the repository at this point in the history
A part of #2. Use custom Hash/Address implementation, get rid of
util.Uint256/util.Uint160 NeoGo dependency.

Signed-off-by: Anna Shaleva <[email protected]>
  • Loading branch information
AnnaShaleva committed Feb 13, 2024
1 parent 2d3a276 commit c43e88f
Show file tree
Hide file tree
Showing 17 changed files with 237 additions and 230 deletions.
25 changes: 12 additions & 13 deletions block/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/dbft/merkle"
"github.com/nspcc-dev/neo-go/pkg/util"
)

type (
Expand All @@ -17,9 +16,9 @@ type (
Index uint32
Timestamp uint32
Version uint32
MerkleRoot util.Uint256
PrevHash util.Uint256
NextConsensus util.Uint160
MerkleRoot crypto.Uint256
PrevHash crypto.Uint256
NextConsensus crypto.Uint160
}

// Block is a generic interface for a block used by dbft.
Expand Down Expand Up @@ -58,9 +57,9 @@ type (
base

consensusData uint64
transactions []Transaction[util.Uint256]
transactions []Transaction[crypto.Uint256]
signature []byte
hash *util.Uint256
hash *crypto.Uint256
}
)

Expand All @@ -70,7 +69,7 @@ func (b neoBlock) Version() uint32 {
}

// PrevHash implements Block interface.
func (b *neoBlock) PrevHash() util.Uint256 {
func (b *neoBlock) PrevHash() crypto.Uint256 {
return b.base.PrevHash
}

Expand All @@ -85,12 +84,12 @@ func (b *neoBlock) Index() uint32 {
}

// NextConsensus implements Block interface.
func (b *neoBlock) NextConsensus() util.Uint160 {
func (b *neoBlock) NextConsensus() crypto.Uint160 {
return b.base.NextConsensus
}

// MerkleRoot implements Block interface.
func (b *neoBlock) MerkleRoot() util.Uint256 {
func (b *neoBlock) MerkleRoot() crypto.Uint256 {
return b.base.MerkleRoot
}

Expand All @@ -100,17 +99,17 @@ func (b *neoBlock) ConsensusData() uint64 {
}

// Transactions implements Block interface.
func (b *neoBlock) Transactions() []Transaction[util.Uint256] {
func (b *neoBlock) Transactions() []Transaction[crypto.Uint256] {
return b.transactions
}

// SetTransactions implements Block interface.
func (b *neoBlock) SetTransactions(txx []Transaction[util.Uint256]) {
func (b *neoBlock) SetTransactions(txx []Transaction[crypto.Uint256]) {
b.transactions = txx
}

// NewBlock returns new block.
func NewBlock(timestamp uint64, index uint32, nextConsensus util.Uint160, prevHash util.Uint256, version uint32, nonce uint64, txHashes []util.Uint256) Block[util.Uint256, util.Uint160] {
func NewBlock(timestamp uint64, index uint32, nextConsensus crypto.Uint160, prevHash crypto.Uint256, version uint32, nonce uint64, txHashes []crypto.Uint256) Block[crypto.Uint256, crypto.Uint160] {
block := new(neoBlock)
block.base.Timestamp = uint32(timestamp / 1000000000)
block.base.Index = index
Expand Down Expand Up @@ -165,7 +164,7 @@ func (b *neoBlock) Verify(pub crypto.PublicKey, sign []byte) error {
}

// Hash implements Block interface.
func (b *neoBlock) Hash() (h util.Uint256) {
func (b *neoBlock) Hash() (h crypto.Uint256) {
if b.hash != nil {
return *b.hash
} else if b.transactions == nil {
Expand Down
19 changes: 9 additions & 10 deletions block/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,16 @@ import (
"testing"

"github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestNeoBlock_Setters(t *testing.T) {
b := new(neoBlock)

require.Equal(t, util.Uint256{}, b.Hash())
require.Equal(t, crypto.Uint256{}, b.Hash())

txs := []Transaction[util.Uint256]{testTx(1), testTx(2)}
txs := []Transaction[crypto.Uint256]{testTx(1), testTx(2)}
b.SetTransactions(txs)
assert.Equal(t, txs, b.Transactions())

Expand All @@ -29,14 +28,14 @@ func TestNeoBlock_Setters(t *testing.T) {
b.base.Version = 42
assert.EqualValues(t, 42, b.Version())

b.base.NextConsensus = util.Uint160{1}
assert.Equal(t, util.Uint160{1}, b.NextConsensus())
b.base.NextConsensus = crypto.Uint160{1}
assert.Equal(t, crypto.Uint160{1}, b.NextConsensus())

b.base.PrevHash = util.Uint256{3, 7}
assert.Equal(t, util.Uint256{3, 7}, b.PrevHash())
b.base.PrevHash = crypto.Uint256{3, 7}
assert.Equal(t, crypto.Uint256{3, 7}, b.PrevHash())

b.base.MerkleRoot = util.Uint256{13}
assert.Equal(t, util.Uint256{13}, b.MerkleRoot())
b.base.MerkleRoot = crypto.Uint256{13}
assert.Equal(t, crypto.Uint256{13}, b.MerkleRoot())

b.base.Timestamp = 1234
// 1234s -> 1234000000000ns
Expand Down Expand Up @@ -85,7 +84,7 @@ func (t testKey) Sign([]byte) ([]byte, error) {

type testTx uint64

func (tx testTx) Hash() (h util.Uint256) {
func (tx testTx) Hash() (h crypto.Uint256) {
binary.LittleEndian.PutUint64(h[:], uint64(tx))
return
}
3 changes: 1 addition & 2 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/nspcc-dev/dbft/crypto"
"github.com/nspcc-dev/dbft/payload"
"github.com/nspcc-dev/dbft/timer"
"github.com/nspcc-dev/neo-go/pkg/util"
)

// Context is a main dBFT structure which
Expand Down Expand Up @@ -313,7 +312,7 @@ func (c *Context[H, A]) MakeHeader() block.Block[H, A] {
}

// NewBlockFromContext returns new block filled with given contexet.
func NewBlockFromContext(ctx *Context[util.Uint256, util.Uint160]) block.Block[util.Uint256, util.Uint160] {
func NewBlockFromContext(ctx *Context[crypto.Uint256, crypto.Uint160]) block.Block[crypto.Uint256, crypto.Uint160] {
if ctx.TransactionHashes == nil {
return nil
}
Expand Down
30 changes: 26 additions & 4 deletions crypto/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,47 @@ package crypto

import (
"crypto/sha256"
"encoding/hex"

"github.com/nspcc-dev/neo-go/pkg/util"
"golang.org/x/crypto/ripemd160" //nolint:staticcheck // SA1019: package golang.org/x/crypto/ripemd160 is deprecated
)

const (
Uint256Size = 32
Uint160Size = 20
)

type (
Uint256 [Uint256Size]byte
Uint160 [Uint160Size]byte
)

// String implements fmt.Stringer interface.
func (h Uint256) String() string {
return hex.EncodeToString(h[:])
}

// String implements fmt.Stringer interface.
func (h Uint160) String() string {
return hex.EncodeToString(h[:])
}

// Hash256 returns double sha-256 of data.
func Hash256(data []byte) util.Uint256 {
func Hash256(data []byte) Uint256 {
h1 := sha256.Sum256(data)
h2 := sha256.Sum256(h1[:])

return h2
}

// Hash160 returns ripemd160 from sha256 of data.
func Hash160(data []byte) (h util.Uint160) {
func Hash160(data []byte) Uint160 {
h1 := sha256.Sum256(data)
rp := ripemd160.New()
_, _ = rp.Write(h1[:])

var h Uint160
copy(h[:], rp.Sum(nil))

return
return h
}
9 changes: 4 additions & 5 deletions crypto/hash_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ import (
"encoding/hex"
"testing"

"github.com/nspcc-dev/neo-go/pkg/util"
"github.com/stretchr/testify/require"
)

var hash256tc = []struct {
data []byte
hash util.Uint256
hash Uint256
}{
{[]byte{}, parse256("5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456")},
{[]byte{0, 1, 2, 3}, parse256("f7a355c00c89a08c80636bed35556a210b51786f6803a494f28fc5ba05959fc2")},
}

var hash160tc = []struct {
data []byte
hash util.Uint160
hash Uint160
}{
{[]byte{}, parse160("b472a266d0bd89c13706a4132ccfb16f7c3b9fcb")},
{[]byte{0, 1, 2, 3}, parse160("3c3fa3d4adcaf8f52d5b1843975e122548269937")},
Expand All @@ -36,12 +35,12 @@ func TestHash160(t *testing.T) {
}
}

func parse256(s string) (h util.Uint256) {
func parse256(s string) (h Uint256) {
parseHex(h[:], s)
return
}

func parse160(s string) (h util.Uint160) {
func parse160(s string) (h Uint160) {
parseHex(h[:], s)
return
}
Expand Down
Loading

0 comments on commit c43e88f

Please sign in to comment.