compiler: implement ECDSA signature verification

Add VerifySignature interop for signature verification.
It is converted to VERIFY opcode.
This commit is contained in:
Evgenii Stratonikov 2020-01-22 18:24:58 +03:00
parent 01e16e68ad
commit bd37359393
4 changed files with 63 additions and 0 deletions

View file

@ -14,6 +14,7 @@ var (
builtinFuncs = []string{ builtinFuncs = []string{
"len", "append", "SHA256", "len", "append", "SHA256",
"SHA1", "Hash256", "Hash160", "SHA1", "Hash256", "Hash160",
"VerifySignature",
"FromAddress", "Equals", "FromAddress", "Equals",
} }
) )

View file

@ -666,6 +666,8 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
emitOpcode(c.prog.BinWriter, opcode.HASH256) emitOpcode(c.prog.BinWriter, opcode.HASH256)
case "Hash160": case "Hash160":
emitOpcode(c.prog.BinWriter, opcode.HASH160) emitOpcode(c.prog.BinWriter, opcode.HASH160)
case "VerifySignature":
emitOpcode(c.prog.BinWriter, opcode.VERIFY)
case "Equals": case "Equals":
emitOpcode(c.prog.BinWriter, opcode.EQUAL) emitOpcode(c.prog.BinWriter, opcode.EQUAL)
case "FromAddress": case "FromAddress":

View file

@ -0,0 +1,55 @@
package compiler_test
import (
"fmt"
"testing"
"github.com/CityOfZion/neo-go/pkg/crypto/keys"
"github.com/stretchr/testify/require"
)
func TestVerifyGood(t *testing.T) {
msg := []byte("test message")
pub, sig := signMessage(t, msg)
src := getVerifyProg(pub, sig, msg)
eval(t, src, true)
}
func TestVerifyBad(t *testing.T) {
msg := []byte("test message")
pub, sig := signMessage(t, msg)
sig[0] = ^sig[0]
src := getVerifyProg(pub, sig, msg)
eval(t, src, false)
}
func signMessage(t *testing.T, msg []byte) ([]byte, []byte) {
key, err := keys.NewPrivateKey()
require.NoError(t, err)
sig := key.Sign(msg)
pub := key.PublicKey().Bytes()
return pub, sig
}
func getVerifyProg(pub, sig, msg []byte) string {
pubS := fmt.Sprintf("%#v", pub)
sigS := fmt.Sprintf("%#v", sig)
msgS := fmt.Sprintf("%#v", msg)
return `
package hello
import "github.com/CityOfZion/neo-go/pkg/interop/crypto"
func Main() bool {
pub := ` + pubS + `
sig := ` + sigS + `
msg := ` + msgS + `
return crypto.VerifySignature(msg, sig, pub)
}
`
}

View file

@ -22,3 +22,8 @@ func Hash160(b []byte) []byte {
func Hash256(b []byte) []byte { func Hash256(b []byte) []byte {
return nil return nil
} }
// VerifySignature checks that sig is msg's signature with pub.
func VerifySignature(msg []byte, sig []byte, pub []byte) bool {
return false
}