Skip to content

Commit

Permalink
Merge pull request #917 from nspcc-dev/feature/crypto
Browse files Browse the repository at this point in the history
vm: remove crypto-related opcodes
  • Loading branch information
roman-khimov authored Apr 29, 2020
2 parents c1aa96d + 519b31a commit fda943b
Show file tree
Hide file tree
Showing 13 changed files with 90 additions and 110 deletions.
1 change: 0 additions & 1 deletion pkg/compiler/analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ var (
// Go language builtin functions and custom builtin utility functions.
builtinFuncs = []string{
"len", "append", "SHA256",
"SHA1", "Hash256", "Hash160",
"AppCall",
"FromAddress", "Equals",
"panic",
Expand Down
4 changes: 1 addition & 3 deletions pkg/compiler/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1065,9 +1065,7 @@ func (c *codegen) convertBuiltin(expr *ast.CallExpr) {
}
emit.Instruction(c.prog.BinWriter, opcode.CONVERT, []byte{byte(typ)})
case "SHA256":
emit.Opcode(c.prog.BinWriter, opcode.SHA256)
case "SHA1":
emit.Opcode(c.prog.BinWriter, opcode.SHA1)
emit.Syscall(c.prog.BinWriter, "Neo.Crypto.SHA256")
case "AppCall":
numArgs := len(expr.Args) - 1
c.emitReverse(numArgs)
Expand Down
27 changes: 12 additions & 15 deletions pkg/compiler/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ package compiler_test

import (
"testing"

"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/smartcontract/trigger"
"github.com/stretchr/testify/require"
)

func TestSHA256(t *testing.T) {
Expand All @@ -16,20 +21,12 @@ func TestSHA256(t *testing.T) {
return hash
}
`
eval(t, src, []byte{0x2a, 0xa, 0xb7, 0x32, 0xb4, 0xe9, 0xd8, 0x5e, 0xf7, 0xdc, 0x25, 0x30, 0x3b, 0x64, 0xab, 0x52, 0x7c, 0x25, 0xa4, 0xd7, 0x78, 0x15, 0xeb, 0xb5, 0x79, 0xf3, 0x96, 0xec, 0x6c, 0xac, 0xca, 0xd3})
}
v := vmAndCompile(t, src)
ic := &interop.Context{Trigger: trigger.Verification}
v.RegisterInteropGetter(crypto.GetInterop(ic))
require.NoError(t, v.Run())
require.True(t, v.Estack().Len() >= 1)

func TestSHA1(t *testing.T) {
src := `
package foo
import (
"github.com/nspcc-dev/neo-go/pkg/interop/crypto"
)
func Main() []byte {
src := []byte{0x97}
hash := crypto.SHA1(src)
return hash
}
`
eval(t, src, []byte{0xfa, 0x13, 0x8a, 0xe3, 0x56, 0xd3, 0x5c, 0x8d, 0x77, 0x8, 0x3c, 0x40, 0x6a, 0x5b, 0xe7, 0x37, 0x45, 0x64, 0x3a, 0xae})
h := []byte{0x2a, 0xa, 0xb7, 0x32, 0xb4, 0xe9, 0xd8, 0x5e, 0xf7, 0xdc, 0x25, 0x30, 0x3b, 0x64, 0xab, 0x52, 0x7c, 0x25, 0xa4, 0xd7, 0x78, 0x15, 0xeb, 0xb5, 0x79, 0xf3, 0x96, 0xec, 0x6c, 0xac, 0xca, 0xd3}
require.Equal(t, h, v.PopResult())
}
4 changes: 0 additions & 4 deletions pkg/core/gas_price.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ func getPrice(v *vm.VM, op opcode.Opcode, parameter []byte) util.Fixed8 {
case opcode.SYSCALL:
interopID := vm.GetInteropID(parameter)
return getSyscallPrice(v, interopID)
case opcode.SHA1, opcode.SHA256:
return toFixed8(10)
case opcode.HASH160, opcode.HASH256:
return toFixed8(20)
default:
return toFixed8(1)
}
Expand Down
15 changes: 15 additions & 0 deletions pkg/core/interop/crypto/hash.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package crypto

import (
"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
"github.com/nspcc-dev/neo-go/pkg/vm"
)

// Sha256 returns sha256 hash of the data.
func Sha256(ic *interop.Context, v *vm.VM) error {
msg := getMessage(ic, v.Estack().Pop().Item())
h := hash.Sha256(msg).BytesBE()
v.Estack().PushVal(h)
return nil
}
30 changes: 30 additions & 0 deletions pkg/core/interop/crypto/hash_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package crypto

import (
"encoding/hex"
"testing"

"github.com/nspcc-dev/neo-go/pkg/core/interop"
"github.com/nspcc-dev/neo-go/pkg/io"
"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/emit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestSHA256(t *testing.T) {
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
buf := io.NewBufBinWriter()
emit.Bytes(buf.BinWriter, []byte{1, 0})
emit.Syscall(buf.BinWriter, "Neo.Crypto.SHA256")
prog := buf.Bytes()
v := vm.New()
ic := &interop.Context{Trigger: trigger.Verification}
v.RegisterInteropGetter(GetInterop(ic))
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()))
}
7 changes: 7 additions & 0 deletions pkg/core/interop/crypto/interop.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
var (
ecdsaVerifyID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaVerify"))
ecdsaCheckMultisigID = emit.InteropNameToID([]byte("Neo.Crypto.ECDsaCheckMultiSig"))
sha256ID = emit.InteropNameToID([]byte("Neo.Crypto.SHA256"))
)

// GetInterop returns interop getter for crypto-related stuff.
Expand All @@ -27,6 +28,12 @@ func GetInterop(ic *interop.Context) func(uint32) *vm.InteropFuncPrice {
return ECDSACheckMultisig(ic, v)
},
}
case sha256ID:
return &vm.InteropFuncPrice{
Func: func(v *vm.VM) error {
return Sha256(ic, v)
},
}
default:
return nil
}
Expand Down
1 change: 1 addition & 0 deletions pkg/core/interops.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ var neoInterops = []interop.Function{
{Name: "Neo.Contract.Migrate", Func: contractMigrate, Price: 0},
{Name: "Neo.Crypto.ECDsaVerify", Func: crypto.ECDSAVerify, Price: 1},
{Name: "Neo.Crypto.ECDsaCheckMultiSig", Func: crypto.ECDSACheckMultisig, Price: 1},
{Name: "Neo.Crypto.SHA256", Func: crypto.Sha256, Price: 1},
{Name: "Neo.Enumerator.Concat", Func: enumerator.Concat, Price: 1},
{Name: "Neo.Enumerator.Create", Func: enumerator.Create, Price: 1},
{Name: "Neo.Enumerator.Next", Func: enumerator.Next, Price: 1},
Expand Down
5 changes: 0 additions & 5 deletions pkg/interop/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ package crypto
// Package crypto provides function signatures that can be used inside
// smart contracts that are written in the neo-go framework.

// SHA1 computes the sha1 hash of b.
func SHA1(b []byte) []byte {
return nil
}

// SHA256 computes the sha256 hash of b.
func SHA256(b []byte) []byte {
return nil
Expand Down
9 changes: 0 additions & 9 deletions pkg/vm/opcode/opcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,6 @@ const (
MAX Opcode = 0xA4
WITHIN Opcode = 0xA5

// Crypto
SHA1 Opcode = 0xA7
SHA256 Opcode = 0xA8
HASH160 Opcode = 0xA9
HASH256 Opcode = 0xAA
CHECKSIG Opcode = 0xAC
VERIFY Opcode = 0xAD
CHECKMULTISIG Opcode = 0xAE

// Advanced data structures (arrays, structures, maps)
PACK Opcode = 0xC0
UNPACK Opcode = 0xC1
Expand Down
62 changes: 24 additions & 38 deletions pkg/vm/opcode/opcode_string.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 0 additions & 13 deletions pkg/vm/vm.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package vm

import (
"crypto/sha1"
"encoding/binary"
"encoding/json"
"fmt"
Expand All @@ -11,7 +10,6 @@ import (
"text/tabwriter"
"unicode/utf8"

"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/util"
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
Expand Down Expand Up @@ -1314,17 +1312,6 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
panic("wrong collection type")
}

// Cryptographic operations.
case opcode.SHA1:
b := v.estack.Pop().Bytes()
sha := sha1.New()
sha.Write(b)
v.estack.PushVal(sha.Sum(nil))

case opcode.SHA256:
b := v.estack.Pop().Bytes()
v.estack.PushVal(hash.Sha256(b).BytesBE())

case opcode.NOP:
// unlucky ^^

Expand Down
22 changes: 0 additions & 22 deletions pkg/vm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3037,28 +3037,6 @@ func TestDupBool(t *testing.T) {
assert.Equal(t, true, vm.estack.Pop().Bool())
}

func TestSHA1(t *testing.T) {
// 0x0100 hashes to 0e356ba505631fbf715758bed27d503f8b260e3a
res := "0e356ba505631fbf715758bed27d503f8b260e3a"
prog := makeProgram(opcode.PUSHDATA1, 2, 1, 0,
opcode.SHA1)
vm := load(prog)
runVM(t, vm)
assert.Equal(t, 1, vm.estack.Len())
assert.Equal(t, res, hex.EncodeToString(vm.estack.Pop().Bytes()))
}

func TestSHA256(t *testing.T) {
// 0x0100 hashes to 47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254
res := "47dc540c94ceb704a23875c11273e16bb0b8a87aed84de911f2133568115f254"
prog := makeProgram(opcode.PUSHDATA1, 2, 1, 0,
opcode.SHA256)
vm := load(prog)
runVM(t, vm)
assert.Equal(t, 1, vm.estack.Len())
assert.Equal(t, res, hex.EncodeToString(vm.estack.Pop().Bytes()))
}

var opcodesTestCases = map[opcode.Opcode][]struct {
name string
args []interface{}
Expand Down

0 comments on commit fda943b

Please sign in to comment.