nef: change checksum calculation scheme

It's now being calculated for whole file, not just header.
This commit is contained in:
Roman Khimov 2020-11-27 19:33:36 +03:00
parent d93aa745bb
commit e12c52f588
5 changed files with 21 additions and 22 deletions

Binary file not shown.

View file

@ -57,7 +57,7 @@ type rpcTestCase struct {
}
const testContractHash = "743ed26f78e29ecd595535b74a943b1f9ccbc444"
const deploymentTxHash = "f4abbf6a5af7b79819378cce1576dd72663a95961010383d67d8c4e1f00fac02"
const deploymentTxHash = "3f81bc99525ed4b1cbb4a3535feadf73176db646a2879aaf975737348a425edc"
const genesisBlockHash = "a496577895eb8c227bb866dc44f99f21c0cf06417ca8f2a877cc5d761a50dac0"
const verifyContractHash = "a2eb22340979804cb10cc1add0b8822c201f4d8a"

Binary file not shown.

View file

@ -23,10 +23,10 @@ import (
// | Compiler | 32 bytes | Compiler used |
// | Version | 16 bytes | Compiler version (Major, Minor, Build, Version) |
// +------------+-----------+------------------------------------------------------------+
// | Checksum | 4 bytes | First four bytes of double SHA256 hash of the header |
// +------------+-----------+------------------------------------------------------------+
// | Script | Var bytes | Var bytes for the payload |
// +------------+-----------+------------------------------------------------------------+
// | Checksum | 4 bytes | First four bytes of double SHA256 hash of the header |
// +------------+-----------+------------------------------------------------------------+
const (
// Magic is a magic File header constant.
@ -40,8 +40,8 @@ const (
// File represents compiled contract file structure according to the NEF3 standard.
type File struct {
Header Header
Checksum uint32
Script []byte
Checksum uint32
}
// Header represents File header.
@ -73,7 +73,7 @@ func NewFile(script []byte) (File, error) {
return file, err
}
file.Header.Version = v
file.Checksum = file.Header.CalculateChecksum()
file.Checksum = file.CalculateChecksum()
return file, nil
}
@ -171,36 +171,35 @@ func (h *Header) DecodeBinary(r *io.BinReader) {
}
// CalculateChecksum returns first 4 bytes of double-SHA256(Header) converted to uint32.
func (h *Header) CalculateChecksum() uint32 {
buf := io.NewBufBinWriter()
h.EncodeBinary(buf.BinWriter)
if buf.Err != nil {
panic(buf.Err)
func (n *File) CalculateChecksum() uint32 {
bb, err := n.Bytes()
if err != nil {
panic(err)
}
return binary.LittleEndian.Uint32(hash.Checksum(buf.Bytes()))
return binary.LittleEndian.Uint32(hash.Checksum(bb[:len(bb)-4]))
}
// EncodeBinary implements io.Serializable interface.
func (n *File) EncodeBinary(w *io.BinWriter) {
n.Header.EncodeBinary(w)
w.WriteU32LE(n.Checksum)
w.WriteVarBytes(n.Script)
w.WriteU32LE(n.Checksum)
}
// DecodeBinary implements io.Serializable interface.
func (n *File) DecodeBinary(r *io.BinReader) {
n.Header.DecodeBinary(r)
n.Checksum = r.ReadU32LE()
checksum := n.Header.CalculateChecksum()
if checksum != n.Checksum {
r.Err = errors.New("CRC verification fail")
return
}
n.Script = r.ReadVarBytes(MaxScriptLength)
if len(n.Script) == 0 {
r.Err = errors.New("empty script")
return
}
n.Checksum = r.ReadU32LE()
checksum := n.CalculateChecksum()
if checksum != n.Checksum {
r.Err = errors.New("checksum verification failure")
return
}
}
// Bytes returns byte array with serialized NEF File.

View file

@ -36,20 +36,20 @@ func TestEncodeDecodeBinary(t *testing.T) {
t.Run("zero-length script", func(t *testing.T) {
expected.Script = make([]byte, 0)
expected.Checksum = expected.Header.CalculateChecksum()
expected.Checksum = expected.CalculateChecksum()
checkDecodeError(t, expected)
})
t.Run("invalid script length", func(t *testing.T) {
newScript := make([]byte, MaxScriptLength+1)
expected.Script = newScript
expected.Checksum = expected.Header.CalculateChecksum()
expected.Checksum = expected.CalculateChecksum()
checkDecodeError(t, expected)
})
t.Run("positive", func(t *testing.T) {
expected.Script = script
expected.Checksum = expected.Header.CalculateChecksum()
expected.Checksum = expected.CalculateChecksum()
expected.Header.Magic = Magic
testserdes.EncodeDecodeBinary(t, expected, &File{})
})
@ -76,7 +76,7 @@ func TestBytesFromBytes(t *testing.T) {
},
Script: script,
}
expected.Checksum = expected.Header.CalculateChecksum()
expected.Checksum = expected.CalculateChecksum()
bytes, err := expected.Bytes()
require.NoError(t, err)