mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-23 13:38:35 +00:00
core: add tests for crypto interops
Also move related test from `core/`.
This commit is contained in:
parent
d5b4553bb3
commit
6e749f4977
3 changed files with 232 additions and 135 deletions
|
@ -2,9 +2,14 @@ package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
|
@ -14,14 +19,116 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCHECKMULTISIG(msg []byte, n int) ([]stackitem.Item, []stackitem.Item, map[string]*keys.PublicKey, error) {
|
func TestECDSASecp256r1Verify(t *testing.T) {
|
||||||
|
testECDSAVerify(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestECDSASecp256k1Verify(t *testing.T) {
|
||||||
|
testECDSAVerify(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testECDSAVerify(t *testing.T, isR1 bool) {
|
||||||
|
var priv *keys.PrivateKey
|
||||||
|
var err error
|
||||||
|
if isR1 {
|
||||||
|
priv, err = keys.NewPrivateKey()
|
||||||
|
} else {
|
||||||
|
priv, err = keys.NewSecp256k1PrivateKey()
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
verifyFunc := ECDSASecp256r1Verify
|
||||||
|
if !isR1 {
|
||||||
|
verifyFunc = ECDSASecp256k1Verify
|
||||||
|
}
|
||||||
|
d := dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false)
|
||||||
|
ic := &interop.Context{DAO: dao.NewCached(d)}
|
||||||
|
runCase := func(t *testing.T, isErr bool, result interface{}, args ...interface{}) {
|
||||||
|
ic.SpawnVM()
|
||||||
|
for i := range args {
|
||||||
|
ic.VM.Estack().PushVal(args[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
func() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = fmt.Errorf("panic: %v", r)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
err = verifyFunc(ic)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if isErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, 1, ic.VM.Estack().Len())
|
||||||
|
require.Equal(t, result, ic.VM.Estack().Pop().Value().(bool))
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := []byte("test message")
|
||||||
|
|
||||||
|
t.Run("success", func(t *testing.T) {
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
runCase(t, false, true, sign, priv.PublicKey().Bytes(), msg)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("signed interop item", func(t *testing.T) {
|
||||||
|
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
||||||
|
msg := tx.GetSignedPart()
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.NewInterop(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("signed script container", func(t *testing.T) {
|
||||||
|
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
||||||
|
msg := tx.GetSignedPart()
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
ic.Container = tx
|
||||||
|
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.Null{})
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("missing arguments", func(t *testing.T) {
|
||||||
|
runCase(t, true, false)
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
runCase(t, true, false, sign)
|
||||||
|
runCase(t, true, false, sign, priv.PublicKey().Bytes())
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid signature", func(t *testing.T) {
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
sign[0] = ^sign[0]
|
||||||
|
runCase(t, false, false, sign, priv.PublicKey().Bytes(), msg)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid public key", func(t *testing.T) {
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
pub := priv.PublicKey().Bytes()
|
||||||
|
pub[0] = 0xFF // invalid prefix
|
||||||
|
runCase(t, true, false, sign, pub, msg)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("invalid message", func(t *testing.T) {
|
||||||
|
sign := priv.Sign(msg)
|
||||||
|
runCase(t, true, false, sign, priv.PublicKey().Bytes(),
|
||||||
|
stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(msg)}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCHECKMULTISIG(isR1 bool, msg []byte, n int) ([]stackitem.Item, []stackitem.Item, map[string]*keys.PublicKey, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
keyMap := make(map[string]*keys.PublicKey)
|
keyMap := make(map[string]*keys.PublicKey)
|
||||||
pkeys := make([]*keys.PrivateKey, n)
|
pkeys := make([]*keys.PrivateKey, n)
|
||||||
pubs := make([]stackitem.Item, n)
|
pubs := make([]stackitem.Item, n)
|
||||||
for i := range pubs {
|
for i := range pubs {
|
||||||
pkeys[i], err = keys.NewPrivateKey()
|
if isR1 {
|
||||||
|
pkeys[i], err = keys.NewPrivateKey()
|
||||||
|
} else {
|
||||||
|
pkeys[i], err = keys.NewSecp256k1PrivateKey()
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -54,18 +161,27 @@ func subSlice(arr []stackitem.Item, indices []int) []stackitem.Item {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM {
|
func initCheckMultisigVMNoArgs(isR1 bool) *vm.VM {
|
||||||
buf := make([]byte, 5)
|
buf := make([]byte, 5)
|
||||||
buf[0] = byte(opcode.SYSCALL)
|
buf[0] = byte(opcode.SYSCALL)
|
||||||
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256r1CheckMultisigID)
|
if isR1 {
|
||||||
|
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256r1CheckMultisigID)
|
||||||
|
} else {
|
||||||
|
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256k1CheckMultisigID)
|
||||||
|
}
|
||||||
|
|
||||||
ic := &interop.Context{Trigger: trigger.Verification}
|
ic := &interop.Context{Trigger: trigger.Verification}
|
||||||
Register(ic)
|
Register(ic)
|
||||||
v := ic.SpawnVM()
|
v := ic.SpawnVM()
|
||||||
v.LoadScript(buf)
|
v.LoadScript(buf)
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
|
func initCHECKMULTISIGVM(t *testing.T, isR1 bool, n int, ik, is []int) *vm.VM {
|
||||||
|
v := initCheckMultisigVMNoArgs(isR1)
|
||||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||||
|
|
||||||
pubs, sigs, _, err := initCHECKMULTISIG(msg, n)
|
pubs, sigs, _, err := initCHECKMULTISIG(isR1, msg, n)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pubs = subSlice(pubs, ik)
|
pubs = subSlice(pubs, ik)
|
||||||
|
@ -78,26 +194,34 @@ func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCHECKMULTISIGGood(t *testing.T, n int, is []int) {
|
func testCHECKMULTISIGGood(t *testing.T, isR1 bool, n int, is []int) {
|
||||||
v := initCHECKMULTISIGVM(t, n, nil, is)
|
v := initCHECKMULTISIGVM(t, isR1, n, nil, is)
|
||||||
|
|
||||||
require.NoError(t, v.Run())
|
require.NoError(t, v.Run())
|
||||||
assert.Equal(t, 1, v.Estack().Len())
|
assert.Equal(t, 1, v.Estack().Len())
|
||||||
assert.True(t, v.Estack().Pop().Bool())
|
assert.True(t, v.Estack().Pop().Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCHECKMULTISIGGood(t *testing.T) {
|
func TestECDSASecp256r1CheckMultisigGood(t *testing.T) {
|
||||||
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{1}) })
|
testCurveCHECKMULTISIGGood(t, true)
|
||||||
t.Run("2_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 2, []int{0, 1}) })
|
|
||||||
t.Run("3_3", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 1, 2}) })
|
|
||||||
t.Run("3_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{0, 2}) })
|
|
||||||
t.Run("4_2", func(t *testing.T) { testCHECKMULTISIGGood(t, 4, []int{0, 2}) })
|
|
||||||
t.Run("10_7", func(t *testing.T) { testCHECKMULTISIGGood(t, 10, []int{2, 3, 4, 5, 6, 8, 9}) })
|
|
||||||
t.Run("12_9", func(t *testing.T) { testCHECKMULTISIGGood(t, 12, []int{0, 1, 4, 5, 6, 7, 8, 9}) })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCHECKMULTISIGBad(t *testing.T, isErr bool, n int, ik, is []int) {
|
func TestECDSASecp256k1CheckMultisigGood(t *testing.T) {
|
||||||
v := initCHECKMULTISIGVM(t, n, ik, is)
|
testCurveCHECKMULTISIGGood(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCurveCHECKMULTISIGGood(t *testing.T, isR1 bool) {
|
||||||
|
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 3, []int{1}) })
|
||||||
|
t.Run("2_2", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 2, []int{0, 1}) })
|
||||||
|
t.Run("3_3", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 3, []int{0, 1, 2}) })
|
||||||
|
t.Run("3_2", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 3, []int{0, 2}) })
|
||||||
|
t.Run("4_2", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 4, []int{0, 2}) })
|
||||||
|
t.Run("10_7", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 10, []int{2, 3, 4, 5, 6, 8, 9}) })
|
||||||
|
t.Run("12_9", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 12, []int{0, 1, 4, 5, 6, 7, 8, 9}) })
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCHECKMULTISIGBad(t *testing.T, isR1 bool, isErr bool, n int, ik, is []int) {
|
||||||
|
v := initCHECKMULTISIGVM(t, isR1, n, ik, is)
|
||||||
|
|
||||||
if isErr {
|
if isErr {
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
|
@ -108,14 +232,49 @@ func testCHECKMULTISIGBad(t *testing.T, isErr bool, n int, ik, is []int) {
|
||||||
assert.False(t, v.Estack().Pop().Bool())
|
assert.False(t, v.Estack().Pop().Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCHECKMULTISIGBad(t *testing.T) {
|
func TestECDSASecp256r1CheckMultisigBad(t *testing.T) {
|
||||||
t.Run("1_1 wrong signature", func(t *testing.T) { testCHECKMULTISIGBad(t, false, 2, []int{0}, []int{1}) })
|
testCurveCHECKMULTISIGBad(t, true)
|
||||||
t.Run("3_2 wrong order", func(t *testing.T) { testCHECKMULTISIGBad(t, false, 3, []int{0, 2}, []int{2, 0}) })
|
}
|
||||||
t.Run("3_2 duplicate sig", func(t *testing.T) { testCHECKMULTISIGBad(t, false, 3, nil, []int{0, 0}) })
|
|
||||||
t.Run("1_2 too many signatures", func(t *testing.T) { testCHECKMULTISIGBad(t, true, 2, []int{0}, []int{0, 1}) })
|
func TestECDSASecp256k1CheckMultisigBad(t *testing.T) {
|
||||||
|
testCurveCHECKMULTISIGBad(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCurveCHECKMULTISIGBad(t *testing.T, isR1 bool) {
|
||||||
|
t.Run("1_1 wrong signature", func(t *testing.T) { testCHECKMULTISIGBad(t, isR1, false, 2, []int{0}, []int{1}) })
|
||||||
|
t.Run("3_2 wrong order", func(t *testing.T) { testCHECKMULTISIGBad(t, isR1, false, 3, []int{0, 2}, []int{2, 0}) })
|
||||||
|
t.Run("3_2 duplicate sig", func(t *testing.T) { testCHECKMULTISIGBad(t, isR1, false, 3, nil, []int{0, 0}) })
|
||||||
|
t.Run("1_2 too many signatures", func(t *testing.T) { testCHECKMULTISIGBad(t, isR1, true, 2, []int{0}, []int{0, 1}) })
|
||||||
t.Run("gas limit exceeded", func(t *testing.T) {
|
t.Run("gas limit exceeded", func(t *testing.T) {
|
||||||
v := initCHECKMULTISIGVM(t, 1, []int{0}, []int{0})
|
v := initCHECKMULTISIGVM(t, isR1, 1, []int{0}, []int{0})
|
||||||
v.GasLimit = ECDSAVerifyPrice - 1
|
v.GasLimit = ECDSAVerifyPrice - 1
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||||
|
pubs, sigs, _, err := initCHECKMULTISIG(isR1, msg, 1)
|
||||||
|
require.NoError(t, err)
|
||||||
|
arr := stackitem.NewArray([]stackitem.Item{stackitem.NewArray(nil)})
|
||||||
|
|
||||||
|
t.Run("invalid message type", func(t *testing.T) {
|
||||||
|
v := initCheckMultisigVMNoArgs(isR1)
|
||||||
|
v.Estack().PushVal(sigs)
|
||||||
|
v.Estack().PushVal(pubs)
|
||||||
|
v.Estack().PushVal(stackitem.NewArray(nil))
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
|
t.Run("invalid public keys", func(t *testing.T) {
|
||||||
|
v := initCheckMultisigVMNoArgs(isR1)
|
||||||
|
v.Estack().PushVal(sigs)
|
||||||
|
v.Estack().PushVal(arr)
|
||||||
|
v.Estack().PushVal(msg)
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
|
t.Run("invalid signatures", func(t *testing.T) {
|
||||||
|
v := initCheckMultisigVMNoArgs(isR1)
|
||||||
|
v.Estack().PushVal(arr)
|
||||||
|
v.Estack().PushVal(pubs)
|
||||||
|
v.Estack().PushVal(msg)
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,42 +5,65 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/interopnames"
|
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type testVerifiable []byte
|
||||||
|
|
||||||
|
var _ crypto.Verifiable = testVerifiable{}
|
||||||
|
|
||||||
|
func (v testVerifiable) GetSignedPart() []byte {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
func (v testVerifiable) GetSignedHash() util.Uint256 {
|
||||||
|
return hash.Sha256(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testHash0100(t *testing.T, result string, interopFunc func(*interop.Context) error) {
|
||||||
|
t.Run("good", func(t *testing.T) {
|
||||||
|
bs := []byte{1, 0}
|
||||||
|
|
||||||
|
checkGood := func(t *testing.T, ic *interop.Context) {
|
||||||
|
require.NoError(t, interopFunc(ic))
|
||||||
|
require.Equal(t, 1, ic.VM.Estack().Len())
|
||||||
|
require.Equal(t, result, hex.EncodeToString(ic.VM.Estack().Pop().Bytes()))
|
||||||
|
}
|
||||||
|
t.Run("raw bytes", func(t *testing.T) {
|
||||||
|
ic := &interop.Context{VM: vm.New()}
|
||||||
|
ic.VM.Estack().PushVal(bs)
|
||||||
|
checkGood(t, ic)
|
||||||
|
})
|
||||||
|
t.Run("interop", func(t *testing.T) {
|
||||||
|
ic := &interop.Context{VM: vm.New()}
|
||||||
|
ic.VM.Estack().PushVal(stackitem.NewInterop(testVerifiable(bs)))
|
||||||
|
checkGood(t, ic)
|
||||||
|
})
|
||||||
|
t.Run("container", func(t *testing.T) {
|
||||||
|
ic := &interop.Context{VM: vm.New(), Container: testVerifiable(bs)}
|
||||||
|
ic.VM.Estack().PushVal(stackitem.Null{})
|
||||||
|
checkGood(t, ic)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
t.Run("bad message", func(t *testing.T) {
|
||||||
|
ic := &interop.Context{VM: vm.New()}
|
||||||
|
ic.VM.Estack().PushVal(stackitem.NewArray(nil))
|
||||||
|
require.Error(t, interopFunc(ic))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestSHA256(t *testing.T) {
|
func TestSHA256(t *testing.T) {
|
||||||
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
|
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
|
||||||
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
|
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
|
||||||
buf := io.NewBufBinWriter()
|
testHash0100(t, res, Sha256)
|
||||||
emit.Bytes(buf.BinWriter, []byte{1, 0})
|
|
||||||
emit.Syscall(buf.BinWriter, interopnames.NeoCryptoSHA256)
|
|
||||||
prog := buf.Bytes()
|
|
||||||
ic := &interop.Context{Trigger: trigger.Verification}
|
|
||||||
Register(ic)
|
|
||||||
v := ic.SpawnVM()
|
|
||||||
v.Load(prog)
|
|
||||||
require.NoError(t, v.Run())
|
|
||||||
assert.Equal(t, 1, v.Estack().Len())
|
|
||||||
assert.Equal(t, res, hex.EncodeToString(v.Estack().Pop().Bytes()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRIPEMD160(t *testing.T) {
|
func TestRIPEMD160(t *testing.T) {
|
||||||
// 0x0100 hashes to 213492c0c6fc5d61497cf17249dd31cd9964b8a3
|
// 0x0100 hashes to 213492c0c6fc5d61497cf17249dd31cd9964b8a3
|
||||||
res := "213492c0c6fc5d61497cf17249dd31cd9964b8a3"
|
res := "213492c0c6fc5d61497cf17249dd31cd9964b8a3"
|
||||||
buf := io.NewBufBinWriter()
|
testHash0100(t, res, RipeMD160)
|
||||||
emit.Bytes(buf.BinWriter, []byte{1, 0})
|
|
||||||
emit.Syscall(buf.BinWriter, interopnames.NeoCryptoRIPEMD160)
|
|
||||||
prog := buf.Bytes()
|
|
||||||
ic := &interop.Context{Trigger: trigger.Verification}
|
|
||||||
Register(ic)
|
|
||||||
v := ic.SpawnVM()
|
|
||||||
v.Load(prog)
|
|
||||||
require.NoError(t, v.Run())
|
|
||||||
assert.Equal(t, 1, v.Estack().Len())
|
|
||||||
assert.Equal(t, res, hex.EncodeToString(v.Estack().Pop().Bytes()))
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,18 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
"github.com/nspcc-dev/neo-go/pkg/core/dao"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/crypto"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/enumerator"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
|
"github.com/nspcc-dev/neo-go/pkg/core/interop/iterator"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
"github.com/nspcc-dev/neo-go/pkg/core/state"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
"github.com/nspcc-dev/neo-go/pkg/core/storage"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -129,88 +126,6 @@ func TestStorageFind(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestECDSAVerify(t *testing.T) {
|
|
||||||
priv, err := keys.NewPrivateKey()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
chain := newTestChain(t)
|
|
||||||
defer chain.Close()
|
|
||||||
|
|
||||||
ic := chain.newInteropContext(trigger.Application, dao.NewSimple(storage.NewMemoryStore(), netmode.UnitTestNet, false), nil, nil)
|
|
||||||
runCase := func(t *testing.T, isErr bool, result interface{}, args ...interface{}) {
|
|
||||||
ic.SpawnVM()
|
|
||||||
for i := range args {
|
|
||||||
ic.VM.Estack().PushVal(args[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
func() {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
err = fmt.Errorf("panic: %v", r)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
err = crypto.ECDSASecp256r1Verify(ic)
|
|
||||||
}()
|
|
||||||
|
|
||||||
if isErr {
|
|
||||||
require.Error(t, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
require.NoError(t, err)
|
|
||||||
require.Equal(t, 1, ic.VM.Estack().Len())
|
|
||||||
require.Equal(t, result, ic.VM.Estack().Pop().Value().(bool))
|
|
||||||
}
|
|
||||||
|
|
||||||
msg := []byte("test message")
|
|
||||||
|
|
||||||
t.Run("success", func(t *testing.T) {
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
runCase(t, false, true, sign, priv.PublicKey().Bytes(), msg)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("signed interop item", func(t *testing.T) {
|
|
||||||
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
|
||||||
msg := tx.GetSignedPart()
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.NewInterop(tx))
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("signed script container", func(t *testing.T) {
|
|
||||||
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
|
||||||
msg := tx.GetSignedPart()
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
ic.Container = tx
|
|
||||||
runCase(t, false, true, sign, priv.PublicKey().Bytes(), stackitem.Null{})
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("missing arguments", func(t *testing.T) {
|
|
||||||
runCase(t, true, false)
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
runCase(t, true, false, sign)
|
|
||||||
runCase(t, true, false, sign, priv.PublicKey().Bytes())
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("invalid signature", func(t *testing.T) {
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
sign[0] = ^sign[0]
|
|
||||||
runCase(t, false, false, sign, priv.PublicKey().Bytes(), msg)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("invalid public key", func(t *testing.T) {
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
pub := priv.PublicKey().Bytes()
|
|
||||||
pub[0] = 0xFF // invalid prefix
|
|
||||||
runCase(t, true, false, sign, pub, msg)
|
|
||||||
})
|
|
||||||
|
|
||||||
t.Run("invalid message", func(t *testing.T) {
|
|
||||||
sign := priv.Sign(msg)
|
|
||||||
runCase(t, true, false, sign, priv.PublicKey().Bytes(),
|
|
||||||
stackitem.NewArray([]stackitem.Item{stackitem.NewByteArray(msg)}))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper functions to create VM, InteropContext, TX, Account, Contract.
|
// Helper functions to create VM, InteropContext, TX, Account, Contract.
|
||||||
|
|
||||||
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
|
func createVM(t *testing.T) (*vm.VM, *interop.Context, *Blockchain) {
|
||||||
|
|
Loading…
Reference in a new issue