core: remove Neo.Crypto.CheckMultisigWithECDsaSecp256k1
Koblitz RIP.
This commit is contained in:
parent
cdaca7be3e
commit
7126637f73
7 changed files with 32 additions and 73 deletions
|
@ -90,7 +90,6 @@ func TestSyscallExecution(t *testing.T) {
|
||||||
"storage.Put": {interopnames.SystemStoragePut, []string{sctx, b, b}, true},
|
"storage.Put": {interopnames.SystemStoragePut, []string{sctx, b, b}, true},
|
||||||
"storage.ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, []string{sctx}, false},
|
"storage.ConvertContextToReadOnly": {interopnames.SystemStorageAsReadOnly, []string{sctx}, false},
|
||||||
"crypto.ECDSASecp256r1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, []string{b, pubs, sigs}, false},
|
"crypto.ECDSASecp256r1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, []string{b, pubs, sigs}, false},
|
||||||
"crypto.ECDSASecp256k1CheckMultisig": {interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, []string{b, pubs, sigs}, false},
|
|
||||||
"crypto.CheckSig": {interopnames.NeoCryptoCheckSig, []string{pub, sig}, false},
|
"crypto.CheckSig": {interopnames.NeoCryptoCheckSig, []string{pub, sig}, false},
|
||||||
}
|
}
|
||||||
ic := &interop.Context{}
|
ic := &interop.Context{}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/btcec"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
"github.com/nspcc-dev/neo-go/pkg/core/fee"
|
||||||
"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/crypto"
|
"github.com/nspcc-dev/neo-go/pkg/crypto"
|
||||||
|
@ -19,18 +18,6 @@ import (
|
||||||
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using
|
// ECDSASecp256r1CheckMultisig checks multiple ECDSA signatures at once using
|
||||||
// Secp256r1 elliptic curve.
|
// Secp256r1 elliptic curve.
|
||||||
func ECDSASecp256r1CheckMultisig(ic *interop.Context) error {
|
func ECDSASecp256r1CheckMultisig(ic *interop.Context) error {
|
||||||
return ecdsaCheckMultisig(ic, elliptic.P256())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once using
|
|
||||||
// Secp256k1 elliptic curve.
|
|
||||||
func ECDSASecp256k1CheckMultisig(ic *interop.Context) error {
|
|
||||||
return ecdsaCheckMultisig(ic, btcec.S256())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ecdsaCheckMultisig is internal representation of ECDSASecp256r1CheckMultisig and
|
|
||||||
// ECDSASecp256k1CheckMultisig
|
|
||||||
func ecdsaCheckMultisig(ic *interop.Context, curve elliptic.Curve) error {
|
|
||||||
hashToCheck, err := getMessageHash(ic, ic.VM.Estack().Pop().Item())
|
hashToCheck, err := getMessageHash(ic, ic.VM.Estack().Pop().Item())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -51,7 +38,7 @@ func ecdsaCheckMultisig(ic *interop.Context, curve elliptic.Curve) error {
|
||||||
if len(pkeys) < len(sigs) {
|
if len(pkeys) < len(sigs) {
|
||||||
return errors.New("more signatures than there are keys")
|
return errors.New("more signatures than there are keys")
|
||||||
}
|
}
|
||||||
sigok := vm.CheckMultisigPar(ic.VM, curve, hashToCheck.BytesBE(), pkeys, sigs)
|
sigok := vm.CheckMultisigPar(ic.VM, elliptic.P256(), hashToCheck.BytesBE(), pkeys, sigs)
|
||||||
ic.VM.Estack().PushVal(sigok)
|
ic.VM.Estack().PushVal(sigok)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,18 +20,14 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initCHECKMULTISIG(isR1 bool, msg []byte, n int) ([]stackitem.Item, []stackitem.Item, map[string]*keys.PublicKey, error) {
|
func initCHECKMULTISIG(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 {
|
||||||
if isR1 {
|
|
||||||
pkeys[i], err = keys.NewPrivateKey()
|
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
|
||||||
}
|
}
|
||||||
|
@ -64,14 +60,10 @@ func subSlice(arr []stackitem.Item, indices []int) []stackitem.Item {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func initCheckMultisigVMNoArgs(isR1 bool) *vm.VM {
|
func initCheckMultisigVMNoArgs() *vm.VM {
|
||||||
buf := make([]byte, 5)
|
buf := make([]byte, 5)
|
||||||
buf[0] = byte(opcode.SYSCALL)
|
buf[0] = byte(opcode.SYSCALL)
|
||||||
if isR1 {
|
|
||||||
binary.LittleEndian.PutUint32(buf[1:], ecdsaSecp256r1CheckMultisigID)
|
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)
|
||||||
|
@ -80,11 +72,11 @@ func initCheckMultisigVMNoArgs(isR1 bool) *vm.VM {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func initCHECKMULTISIGVM(t *testing.T, isR1 bool, n int, ik, is []int) *vm.VM {
|
func initCHECKMULTISIGVM(t *testing.T, n int, ik, is []int) *vm.VM {
|
||||||
v := initCheckMultisigVMNoArgs(isR1)
|
v := initCheckMultisigVMNoArgs()
|
||||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||||
|
|
||||||
pubs, sigs, _, err := initCHECKMULTISIG(isR1, msg, n)
|
pubs, sigs, _, err := initCHECKMULTISIG(msg, n)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
pubs = subSlice(pubs, ik)
|
pubs = subSlice(pubs, ik)
|
||||||
|
@ -97,8 +89,8 @@ func initCHECKMULTISIGVM(t *testing.T, isR1 bool, n int, ik, is []int) *vm.VM {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func testCHECKMULTISIGGood(t *testing.T, isR1 bool, n int, is []int) {
|
func testCHECKMULTISIGGood(t *testing.T, n int, is []int) {
|
||||||
v := initCHECKMULTISIGVM(t, isR1, n, nil, is)
|
v := initCHECKMULTISIGVM(t, 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())
|
||||||
|
@ -106,25 +98,21 @@ func testCHECKMULTISIGGood(t *testing.T, isR1 bool, n int, is []int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestECDSASecp256r1CheckMultisigGood(t *testing.T) {
|
func TestECDSASecp256r1CheckMultisigGood(t *testing.T) {
|
||||||
testCurveCHECKMULTISIGGood(t, true)
|
testCurveCHECKMULTISIGGood(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestECDSASecp256k1CheckMultisigGood(t *testing.T) {
|
func testCurveCHECKMULTISIGGood(t *testing.T) {
|
||||||
testCurveCHECKMULTISIGGood(t, false)
|
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, 3, []int{1}) })
|
||||||
|
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 testCurveCHECKMULTISIGGood(t *testing.T, isR1 bool) {
|
func testCHECKMULTISIGBad(t *testing.T, isErr bool, n int, ik, is []int) {
|
||||||
t.Run("3_1", func(t *testing.T) { testCHECKMULTISIGGood(t, isR1, 3, []int{1}) })
|
v := initCHECKMULTISIGVM(t, n, ik, is)
|
||||||
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())
|
||||||
|
@ -136,45 +124,41 @@ func testCHECKMULTISIGBad(t *testing.T, isR1 bool, isErr bool, n int, ik, is []i
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestECDSASecp256r1CheckMultisigBad(t *testing.T) {
|
func TestECDSASecp256r1CheckMultisigBad(t *testing.T) {
|
||||||
testCurveCHECKMULTISIGBad(t, true)
|
testCurveCHECKMULTISIGBad(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestECDSASecp256k1CheckMultisigBad(t *testing.T) {
|
func testCurveCHECKMULTISIGBad(t *testing.T) {
|
||||||
testCurveCHECKMULTISIGBad(t, false)
|
t.Run("1_1 wrong signature", func(t *testing.T) { testCHECKMULTISIGBad(t, false, 2, []int{0}, []int{1}) })
|
||||||
}
|
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}) })
|
||||||
func testCurveCHECKMULTISIGBad(t *testing.T, isR1 bool) {
|
t.Run("1_2 too many signatures", func(t *testing.T) { testCHECKMULTISIGBad(t, true, 2, []int{0}, []int{0, 1}) })
|
||||||
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, isR1, 1, []int{0}, []int{0})
|
v := initCHECKMULTISIGVM(t, 1, []int{0}, []int{0})
|
||||||
v.GasLimit = fee.ECDSAVerifyPrice - 1
|
v.GasLimit = fee.ECDSAVerifyPrice - 1
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
})
|
})
|
||||||
|
|
||||||
msg := []byte("NEO - An Open Network For Smart Economy")
|
msg := []byte("NEO - An Open Network For Smart Economy")
|
||||||
pubs, sigs, _, err := initCHECKMULTISIG(isR1, msg, 1)
|
pubs, sigs, _, err := initCHECKMULTISIG(msg, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
arr := stackitem.NewArray([]stackitem.Item{stackitem.NewArray(nil)})
|
arr := stackitem.NewArray([]stackitem.Item{stackitem.NewArray(nil)})
|
||||||
|
|
||||||
t.Run("invalid message type", func(t *testing.T) {
|
t.Run("invalid message type", func(t *testing.T) {
|
||||||
v := initCheckMultisigVMNoArgs(isR1)
|
v := initCheckMultisigVMNoArgs()
|
||||||
v.Estack().PushVal(sigs)
|
v.Estack().PushVal(sigs)
|
||||||
v.Estack().PushVal(pubs)
|
v.Estack().PushVal(pubs)
|
||||||
v.Estack().PushVal(stackitem.NewArray(nil))
|
v.Estack().PushVal(stackitem.NewArray(nil))
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
})
|
})
|
||||||
t.Run("invalid public keys", func(t *testing.T) {
|
t.Run("invalid public keys", func(t *testing.T) {
|
||||||
v := initCheckMultisigVMNoArgs(isR1)
|
v := initCheckMultisigVMNoArgs()
|
||||||
v.Estack().PushVal(sigs)
|
v.Estack().PushVal(sigs)
|
||||||
v.Estack().PushVal(arr)
|
v.Estack().PushVal(arr)
|
||||||
v.Estack().PushVal(msg)
|
v.Estack().PushVal(msg)
|
||||||
require.Error(t, v.Run())
|
require.Error(t, v.Run())
|
||||||
})
|
})
|
||||||
t.Run("invalid signatures", func(t *testing.T) {
|
t.Run("invalid signatures", func(t *testing.T) {
|
||||||
v := initCheckMultisigVMNoArgs(isR1)
|
v := initCheckMultisigVMNoArgs()
|
||||||
v.Estack().PushVal(arr)
|
v.Estack().PushVal(arr)
|
||||||
v.Estack().PushVal(pubs)
|
v.Estack().PushVal(pubs)
|
||||||
v.Estack().PushVal(msg)
|
v.Estack().PushVal(msg)
|
||||||
|
|
|
@ -7,13 +7,11 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
|
ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
|
||||||
ecdsaSecp256k1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1))
|
|
||||||
neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig))
|
neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig))
|
||||||
)
|
)
|
||||||
|
|
||||||
var cryptoInterops = []interop.Function{
|
var cryptoInterops = []interop.Function{
|
||||||
{ID: ecdsaSecp256r1CheckMultisigID, Func: ECDSASecp256r1CheckMultisig},
|
{ID: ecdsaSecp256r1CheckMultisigID, Func: ECDSASecp256r1CheckMultisig},
|
||||||
{ID: ecdsaSecp256k1CheckMultisigID, Func: ECDSASecp256k1CheckMultisig},
|
|
||||||
{ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig},
|
{ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,6 @@ const (
|
||||||
SystemStoragePut = "System.Storage.Put"
|
SystemStoragePut = "System.Storage.Put"
|
||||||
SystemStorageAsReadOnly = "System.Storage.AsReadOnly"
|
SystemStorageAsReadOnly = "System.Storage.AsReadOnly"
|
||||||
NeoCryptoCheckMultisigWithECDsaSecp256r1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256r1"
|
NeoCryptoCheckMultisigWithECDsaSecp256r1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256r1"
|
||||||
NeoCryptoCheckMultisigWithECDsaSecp256k1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256k1"
|
|
||||||
NeoCryptoCheckSig = "Neo.Crypto.CheckSig"
|
NeoCryptoCheckSig = "Neo.Crypto.CheckSig"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -79,6 +78,5 @@ var names = []string{
|
||||||
SystemStoragePut,
|
SystemStoragePut,
|
||||||
SystemStorageAsReadOnly,
|
SystemStorageAsReadOnly,
|
||||||
NeoCryptoCheckMultisigWithECDsaSecp256r1,
|
NeoCryptoCheckMultisigWithECDsaSecp256r1,
|
||||||
NeoCryptoCheckMultisigWithECDsaSecp256k1,
|
|
||||||
NeoCryptoCheckSig,
|
NeoCryptoCheckSig,
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,6 @@ var systemInterops = []interop.Function{
|
||||||
|
|
||||||
var neoInterops = []interop.Function{
|
var neoInterops = []interop.Function{
|
||||||
{Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3},
|
{Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1, Func: crypto.ECDSASecp256r1CheckMultisig, Price: 0, ParamCount: 3},
|
||||||
{Name: interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1, Func: crypto.ECDSASecp256k1CheckMultisig, Price: 0, ParamCount: 3},
|
|
||||||
{Name: interopnames.NeoCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
|
{Name: interopnames.NeoCryptoCheckSig, Func: crypto.ECDSASecp256r1CheckSig, Price: fee.ECDSAVerifyPrice, ParamCount: 2},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,12 +14,6 @@ func ECDSASecp256r1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []in
|
||||||
return neogointernal.Syscall3("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", msg, pubs, sigs).(bool)
|
return neogointernal.Syscall3("Neo.Crypto.CheckMultisigWithECDsaSecp256r1", msg, pubs, sigs).(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ECDSASecp256k1CheckMultisig checks multiple ECDSA signatures at once. It uses
|
|
||||||
// `Neo.Crypto.CheckMultisigWithECDsaSecp256k1` syscall.
|
|
||||||
func ECDSASecp256k1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []interop.Signature) bool {
|
|
||||||
return neogointernal.Syscall3("Neo.Crypto.CheckMultisigWithECDsaSecp256k1", msg, pubs, sigs).(bool)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CheckSig checks that sig is correct script-container's signature for a given pub
|
// CheckSig checks that sig is correct script-container's signature for a given pub
|
||||||
// (serialized public key). It uses `Neo.Crypto.CheckSig` syscall.
|
// (serialized public key). It uses `Neo.Crypto.CheckSig` syscall.
|
||||||
func CheckSig(pub interop.PublicKey, sig interop.Signature) bool {
|
func CheckSig(pub interop.PublicKey, sig interop.Signature) bool {
|
||||||
|
|
Loading…
Reference in a new issue