Skip to content

Commit

Permalink
Replace Double-SHA256 with blake2b and implement domain seperation (#…
Browse files Browse the repository at this point in the history
…1245)

* Replace default hasher (Double-SHA256) with domain seperated blake2b

* Replace all hashes with domain seperated blake2b

* Update the genesis blocks

* Replace OP_HASH256 with OP_BLAKE2B

* Fix the merkle tree by appending zeros instead of duplicating the hash when there is 1 branch left

* Update tests

* Add a payloadHash function

* Update gitignore to ignore binaries

* Fix a bug in the blake2b opcode
  • Loading branch information
elichai authored Dec 21, 2020
1 parent 9f8f0fd commit 45edacf
Show file tree
Hide file tree
Showing 25 changed files with 270 additions and 199 deletions.
18 changes: 16 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ kaspad.db
*.o
*.a
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Real binaries, build with `go build .`
kaspad
cmd/gencerts/gencerts
cmd/kaspactl/kaspactl
cmd/kasminer/kaspaminer
*.exe
*.exe~

# Output of the go coverage tool
*.out

# Folders
_obj
Expand All @@ -31,8 +46,7 @@ _cgo_export.*

_testmain.go

*.exe


# IDE
.idea
.vscode
Expand Down
5 changes: 2 additions & 3 deletions app/appmessage/p2p_msgtx.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ package appmessage

import (
"encoding/binary"
"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"
"strconv"

"github.com/kaspanet/kaspad/domain/consensus/utils/constants"

"github.com/kaspanet/kaspad/domain/consensus/utils/consensushashing"

"github.com/kaspanet/kaspad/domain/consensus/utils/hashes"

"github.com/kaspanet/kaspad/domain/consensus/utils/subnetworks"

"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
Expand Down Expand Up @@ -285,7 +284,7 @@ func newMsgTx(version int32, txIn []*TxIn, txOut []*TxOut, subnetworkID *externa

var payloadHash externalapi.DomainHash
if *subnetworkID != subnetworks.SubnetworkIDNative {
payloadHash = *hashes.HashData(payload)
payloadHash = *hashes.PayloadHash(payload)
}

return &MsgTx{
Expand Down
20 changes: 12 additions & 8 deletions app/appmessage/p2p_msgtx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,11 +131,15 @@ func TestTx(t *testing.T) {

// TestTxHash tests the ability to generate the hash of a transaction accurately.
func TestTxHashAndID(t *testing.T) {
txID1Str := "a3d29c39bfb578235e4813cc8138a9ba10def63acad193a7a880159624840d7f"
txHash1Str := "c2ac1e792c5c49260103ad9f86caf749d431958b7c7e5e5129346ceab8b709cf"
txID1Str := "47ce12a5ee5727cf97c0481eebedad0d80646b743305b0921a2403f1836f8b37"
wantTxID1, err := transactionid.FromString(txID1Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
t.Fatalf("NewTxIDFromStr: %v", err)
}
wantTxHash1, err := transactionid.FromString(txHash1Str)
if err != nil {
t.Fatalf("NewTxIDFromStr: %v", err)
}

// A coinbase transaction
Expand Down Expand Up @@ -167,7 +171,7 @@ func TestTxHashAndID(t *testing.T) {

// Ensure the hash produced is expected.
tx1Hash := tx1.TxHash()
if *tx1Hash != (externalapi.DomainHash)(*wantTxID1) {
if *tx1Hash != (externalapi.DomainHash)(*wantTxHash1) {
t.Errorf("TxHash: wrong hash - got %v, want %v",
spew.Sprint(tx1Hash), spew.Sprint(wantTxID1))
}
Expand All @@ -179,14 +183,14 @@ func TestTxHashAndID(t *testing.T) {
spew.Sprint(tx1ID), spew.Sprint(wantTxID1))
}

hash2Str := "c84f3009b337aaa3adeb2ffd41010d5f62dd773ca25b39c908a77da91f87b729"
hash2Str := "6b769655a1420022e4690a4f7bb9b1c381185ebbefe3070351f06fb573a0600c"
wantHash2, err := hashes.FromString(hash2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
return
}

id2Str := "7c919f676109743a1271a88beeb43849a6f9cc653f6082e59a7266f3df4802b9"
id2Str := "af916032e271adaaa21f02bee4b44db2cca4dad9149dcaebc188009c7313ec68"
wantID2, err := transactionid.FromString(id2Str)
if err != nil {
t.Errorf("NewTxIDFromStr: %v", err)
Expand Down Expand Up @@ -249,7 +253,7 @@ func TestTxHashAndID(t *testing.T) {

tx2.TxIn[0].SignatureScript = []byte{}
newTx2Hash := tx2.TxHash()
if *tx2ID != (externalapi.DomainTransactionID)(*newTx2Hash) {
t.Errorf("tx2ID and newTx2Hash should be the same for transaction with an empty signature")
if *tx2ID == (externalapi.DomainTransactionID)(*newTx2Hash) {
t.Errorf("tx2ID and newTx2Hash should not be the same even for transaction with an empty signature")
}
}
1 change: 0 additions & 1 deletion domain/consensus/consensus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (

func TestConsensus_GetBlockInfo(t *testing.T) {
testutils.ForAllNets(t, true, func(t *testing.T, params *dagconfig.Params) {

factory := NewFactory()
consensus, teardown, err := factory.NewTestConsensus(params, "TestConsensus_GetBlockInfo")
if err != nil {
Expand Down
18 changes: 6 additions & 12 deletions domain/consensus/model/pow/pow.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,17 @@ func calcPowValue(header *externalapi.DomainBlockHeader) *big.Int {
header.TimeInMilliseconds, header.Nonce = timestamp, nonce

// PRE_POW_HASH || TIME || 32 zero byte padding || NONCE
writer := hashes.NewHashWriter()
_, err := writer.Write(prePowHash[:])
writer := hashes.NewPoWHashWriter()
writer.InfallibleWrite(prePowHash[:])
err := serialization.WriteElement(writer, timestamp)
if err != nil {
panic(errors.Wrap(err, "this should never happen. SHA256's digest should never return an error"))
}
err = serialization.WriteElement(writer, timestamp)
if err != nil {
panic(errors.Wrap(err, "this should never happen. SHA256's digest should never return an error"))
panic(errors.Wrap(err, "this should never happen. Hash digest should never return an error"))
}
zeroes := [32]byte{}
_, err = writer.Write(zeroes[:])
if err != nil {
panic(errors.Wrap(err, "this should never happen. SHA256's digest should never return an error"))
}
writer.InfallibleWrite(zeroes[:])
err = serialization.WriteElement(writer, nonce)
if err != nil {
panic(errors.Wrap(err, "this should never happen. SHA256's digest should never return an error"))
panic(errors.Wrap(err, "this should never happen. Hash digest should never return an error"))
}
return hashes.ToBig(writer.Finalize())
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,10 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
},
},
HashMerkleRoot: externalapi.DomainHash{
0xa2, 0x60, 0x5a, 0x45, 0xfe, 0x01, 0x41, 0xc9,
0xc2, 0x8d, 0xe2, 0xc3, 0x2d, 0x00, 0xa4, 0x29,
0xd4, 0x01, 0x57, 0x2d, 0x2f, 0xcd, 0x49, 0xd4,
0xff, 0x6f, 0xab, 0xd2, 0xd1, 0x96, 0x38, 0xb9,
0xf8, 0x55, 0x7b, 0xd0, 0xda, 0xf2, 0x06, 0x8b,
0x3b, 0xb1, 0x93, 0x5a, 0x2c, 0x52, 0x43, 0xf0,
0x02, 0xf2, 0xb1, 0x40, 0x81, 0x2c, 0x0c, 0x15,
0x8d, 0x04, 0x3d, 0xe2, 0x23, 0x54, 0x98, 0x88,
},
AcceptedIDMerkleRoot: externalapi.DomainHash{
0x80, 0xf7, 0x00, 0xe3, 0x16, 0x3d, 0x04, 0x95,
Expand Down Expand Up @@ -186,10 +186,10 @@ var unOrderedParentsBlock = externalapi.DomainBlock{
SubnetworkID: subnetworks.SubnetworkIDCoinbase,
Payload: []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
PayloadHash: externalapi.DomainHash{
0x95, 0x7b, 0xde, 0x03, 0xa6, 0x26, 0x1f, 0xf0,
0x95, 0x5d, 0x2c, 0x92, 0x07, 0x4b, 0x5c, 0xdc,
0xd5, 0xbb, 0x9f, 0x7d, 0x8f, 0xeb, 0x61, 0x16,
0xe3, 0xe5, 0x77, 0x16, 0x5e, 0x98, 0x82, 0xa7,
0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
},
},
{
Expand Down Expand Up @@ -410,10 +410,10 @@ var exampleValidBlock = externalapi.DomainBlock{
},
},
HashMerkleRoot: externalapi.DomainHash{
0xce, 0xea, 0x78, 0x53, 0x7e, 0x89, 0x67, 0xaf,
0xdc, 0x4a, 0xd1, 0x67, 0xb0, 0xc4, 0xfc, 0x6e,
0xe5, 0x4b, 0x87, 0xb0, 0x55, 0x8f, 0xf4, 0x6b,
0x05, 0x4d, 0x43, 0x0a, 0xb6, 0xbb, 0xe8, 0xdf,
0x33, 0x70, 0xa7, 0x40, 0x9f, 0x2d, 0x87, 0xe1,
0x26, 0xaf, 0x0f, 0x5c, 0x7e, 0xc3, 0x84, 0x5e,
0x4f, 0x68, 0x42, 0x0a, 0xbf, 0x90, 0xcd, 0xef,
0x94, 0x9b, 0xe1, 0x9a, 0xf7, 0xdd, 0xb0, 0xb5,
},
AcceptedIDMerkleRoot: externalapi.DomainHash{
0x8a, 0xb7, 0xd6, 0x73, 0x1b, 0xe6, 0xc5, 0xd3,
Expand Down Expand Up @@ -458,10 +458,10 @@ var exampleValidBlock = externalapi.DomainBlock{
SubnetworkID: subnetworks.SubnetworkIDCoinbase,
Payload: []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
PayloadHash: externalapi.DomainHash{
0x95, 0x7b, 0xde, 0x03, 0xa6, 0x26, 0x1f, 0xf0,
0x95, 0x5d, 0x2c, 0x92, 0x07, 0x4b, 0x5c, 0xdc,
0xd5, 0xbb, 0x9f, 0x7d, 0x8f, 0xeb, 0x61, 0x16,
0xe3, 0xe5, 0x77, 0x16, 0x5e, 0x98, 0x82, 0xa7,
0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
},
},
{
Expand Down Expand Up @@ -765,10 +765,10 @@ var blockWithWrongTxOrder = externalapi.DomainBlock{
SubnetworkID: subnetworks.SubnetworkIDCoinbase,
Payload: []byte{9, 0, 0, 0, 0, 0, 0, 0, 0},
PayloadHash: externalapi.DomainHash{
0x95, 0x7b, 0xde, 0x03, 0xa6, 0x26, 0x1f, 0xf0,
0x95, 0x5d, 0x2c, 0x92, 0x07, 0x4b, 0x5c, 0xdc,
0xd5, 0xbb, 0x9f, 0x7d, 0x8f, 0xeb, 0x61, 0x16,
0xe3, 0xe5, 0x77, 0x16, 0x5e, 0x98, 0x82, 0xa7,
0x31, 0x3d, 0xd5, 0x20, 0x4c, 0xc9, 0x89, 0x20,
0x46, 0x22, 0x59, 0xe0, 0x0d, 0x33, 0x27, 0xe6,
0x04, 0x20, 0x5f, 0x4e, 0xd5, 0xf4, 0xf9, 0x2f,
0x1a, 0xf0, 0x13, 0x0b, 0xe3, 0x92, 0xd8, 0xff,
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func (c *coinbaseManager) ExpectedCoinbaseTransaction(blockHash *externalapi.Dom
return nil, err
}

payloadHash := hashes.HashData(payload)
payloadHash := hashes.PayloadHash(payload)

return &externalapi.DomainTransaction{
Version: constants.TransactionVersion,
Expand Down
Loading

0 comments on commit 45edacf

Please sign in to comment.