core: add Neo.Crypto.CheckSig interop
This commit is contained in:
parent
14ade42101
commit
4e6c1092b8
7 changed files with 87 additions and 0 deletions
|
@ -93,6 +93,7 @@ func TestSyscallExecution(t *testing.T) {
|
|||
"crypto.ECDsaSecp256k1Verify": {interopnames.NeoCryptoVerifyWithECDsaSecp256k1, []string{b, pub, sig}, 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},
|
||||
}
|
||||
ic := &interop.Context{}
|
||||
core.SpawnVM(ic) // set Functions field
|
||||
|
|
|
@ -99,3 +99,17 @@ func getMessageHash(ic *interop.Context, item stackitem.Item) (util.Uint256, err
|
|||
}
|
||||
return hash.Sha256(msg), nil
|
||||
}
|
||||
|
||||
// ECDSASecp256r1CheckSig checks ECDSA signature using Secp256r1 elliptic curve.
|
||||
func ECDSASecp256r1CheckSig(ic *interop.Context) error {
|
||||
hashToCheck := ic.Container.GetSignedHash()
|
||||
keyb := ic.VM.Estack().Pop().Bytes()
|
||||
signature := ic.VM.Estack().Pop().Bytes()
|
||||
pkey, err := keys.NewPublicKeyFromBytes(keyb, elliptic.P256())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res := pkey.Verify(signature, hashToCheck.BytesBE())
|
||||
ic.VM.Estack().PushVal(res)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -279,3 +279,64 @@ func testCurveCHECKMULTISIGBad(t *testing.T, isR1 bool) {
|
|||
require.Error(t, v.Run())
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckSig(t *testing.T) {
|
||||
priv, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
verifyFunc := ECDSASecp256r1CheckSig
|
||||
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))
|
||||
}
|
||||
|
||||
tx := transaction.New(netmode.UnitTestNet, []byte{0, 1, 2}, 1)
|
||||
msg := tx.GetSignedPart()
|
||||
ic.Container = tx
|
||||
|
||||
t.Run("success", func(t *testing.T) {
|
||||
sign := priv.Sign(msg)
|
||||
runCase(t, false, true, sign, priv.PublicKey().Bytes())
|
||||
})
|
||||
|
||||
t.Run("missing argument", func(t *testing.T) {
|
||||
runCase(t, true, false)
|
||||
sign := priv.Sign(msg)
|
||||
runCase(t, true, false, sign)
|
||||
})
|
||||
|
||||
t.Run("invalid signature", func(t *testing.T) {
|
||||
sign := priv.Sign(msg)
|
||||
sign[0] = ^sign[0]
|
||||
runCase(t, false, false, sign, priv.PublicKey().Bytes())
|
||||
})
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ var (
|
|||
ecdsaSecp256k1VerifyID = interopnames.ToID([]byte(interopnames.NeoCryptoVerifyWithECDsaSecp256k1))
|
||||
ecdsaSecp256r1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256r1))
|
||||
ecdsaSecp256k1CheckMultisigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckMultisigWithECDsaSecp256k1))
|
||||
neoCryptoCheckSigID = interopnames.ToID([]byte(interopnames.NeoCryptoCheckSig))
|
||||
)
|
||||
|
||||
var cryptoInterops = []interop.Function{
|
||||
|
@ -17,6 +18,7 @@ var cryptoInterops = []interop.Function{
|
|||
{ID: ecdsaSecp256k1VerifyID, Func: ECDSASecp256k1Verify},
|
||||
{ID: ecdsaSecp256r1CheckMultisigID, Func: ECDSASecp256r1CheckMultisig},
|
||||
{ID: ecdsaSecp256k1CheckMultisigID, Func: ECDSASecp256k1CheckMultisig},
|
||||
{ID: neoCryptoCheckSigID, Func: ECDSASecp256r1CheckSig},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
@ -41,6 +41,7 @@ const (
|
|||
NeoCryptoVerifyWithECDsaSecp256k1 = "Neo.Crypto.VerifyWithECDsaSecp256k1"
|
||||
NeoCryptoCheckMultisigWithECDsaSecp256r1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256r1"
|
||||
NeoCryptoCheckMultisigWithECDsaSecp256k1 = "Neo.Crypto.CheckMultisigWithECDsaSecp256k1"
|
||||
NeoCryptoCheckSig = "Neo.Crypto.CheckSig"
|
||||
)
|
||||
|
||||
var names = []string{
|
||||
|
@ -83,4 +84,5 @@ var names = []string{
|
|||
NeoCryptoVerifyWithECDsaSecp256k1,
|
||||
NeoCryptoCheckMultisigWithECDsaSecp256r1,
|
||||
NeoCryptoCheckMultisigWithECDsaSecp256k1,
|
||||
NeoCryptoCheckSig,
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@ var neoInterops = []interop.Function{
|
|||
Price: fee.ECDSAVerifyPrice, 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},
|
||||
}
|
||||
|
||||
// initIDinInteropsSlice initializes IDs from names in one given
|
||||
|
|
|
@ -31,3 +31,9 @@ func ECDSASecp256r1CheckMultisig(msg []byte, pubs []interop.PublicKey, sigs []in
|
|||
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
|
||||
// (serialized public key). It uses `Neo.Crypto.CheckSig` syscall.
|
||||
func CheckSig(pub interop.PublicKey, sig interop.Signature) bool {
|
||||
return neogointernal.Syscall2("Neo.Crypto.CheckSig", pub, sig).(bool)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue