forked from TrueCloudLab/neoneo-go
Merge pull request #2474 from nspcc-dev/vm/mod-opcodes
vm: add MODMUL and MODPOW opcodes
This commit is contained in:
commit
e87d21d396
33 changed files with 213 additions and 82 deletions
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/engine
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/events
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/iterator
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -3,7 +3,7 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd-nns
|
|||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220506104421-8802dcf05412
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
github.com/nspcc-dev/neo-go v0.98.5-pre.0.20220512113228-bb5cffc4a85e
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
||||
|
|
|
@ -179,10 +179,10 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
|||
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
||||
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
|
||||
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
|
||||
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220506104421-8802dcf05412 h1:poYvGwGXV8GQtci7pMFVzkmldORD25Gb6Qn3t9ZWw2o=
|
||||
github.com/nspcc-dev/neo-go v0.98.3-pre.0.20220506104421-8802dcf05412/go.mod h1:u8Ftsdadsm3DHLO+XGQOM/iaTwPPRtOhZH3sM43xgQI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go v0.98.5-pre.0.20220512113228-bb5cffc4a85e h1:d6a1kyLYiRaPGeNQC3bKCFevo2cgrPIdHT0AhusRL6E=
|
||||
github.com/nspcc-dev/neo-go v0.98.5-pre.0.20220512113228-bb5cffc4a85e/go.mod h1:gcrFLrKkISbhevADP2vwWEqst66Q23j+s9ujVnLoxlk=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/nft-nd
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/oracle
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/runtime
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/storage
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/timer
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
|
@ -2,4 +2,4 @@ module github.com/nspcc-dev/neo-go/examples/token
|
|||
|
||||
go 1.16
|
||||
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
require github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
|
|
2
go.mod
2
go.mod
|
@ -12,7 +12,7 @@ require (
|
|||
github.com/mr-tron/base58 v1.2.0
|
||||
github.com/nspcc-dev/dbft v0.0.0-20220414131237-e497bbf7868e
|
||||
github.com/nspcc-dev/go-ordered-json v0.0.0-20220111165707-25110be27d22
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe
|
||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659
|
||||
github.com/nspcc-dev/rfc6979 v0.2.0
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible
|
||||
|
|
4
go.sum
4
go.sum
|
@ -185,8 +185,8 @@ github.com/nspcc-dev/hrw v1.0.9 h1:17VcAuTtrstmFppBjfRiia4K2wA/ukXZhLFS8Y8rz5Y=
|
|||
github.com/nspcc-dev/hrw v1.0.9/go.mod h1:l/W2vx83vMQo6aStyx2AuZrJ+07lGv2JQGlVkPG06MU=
|
||||
github.com/nspcc-dev/neo-go v0.73.1-pre.0.20200303142215-f5a1b928ce09/go.mod h1:pPYwPZ2ks+uMnlRLUyXOpLieaDQSEaf4NM3zHVbRjmg=
|
||||
github.com/nspcc-dev/neo-go v0.98.0/go.mod h1:E3cc1x6RXSXrJb2nDWXTXjnXk3rIqVN8YdFyWv+FrqM=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb h1:7WtIzIsP+y6yWQVFMAICs5ShY0Q5EHzTWa4503XmHkI=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220506104312-5123b88c36cb/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe h1:R6DsjC+5NOWDpDm7fdLoF+AwTfzKU1ygRetNbY8oyWc=
|
||||
github.com/nspcc-dev/neo-go/pkg/interop v0.0.0-20220512113124-e31f4ca331fe/go.mod h1:QBE0I30F2kOAISNpT5oks82yF4wkkUq3SCfI3Hqgx/Y=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.0-pre.0.20211201134523-3604d96f3fe1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1 h1:SVqc523pZsSaS9vnPS1mm3VV6b6xY0gvdA0uYJ/GWZQ=
|
||||
github.com/nspcc-dev/neofs-api-go/v2 v2.11.1/go.mod h1:oS8dycEh8PPf2Jjp6+8dlwWyEv2Dy77h/XhhcdxYEFs=
|
||||
|
|
|
@ -334,4 +334,44 @@ func TestOpcode(t *testing.T) {
|
|||
stackitem.Make(false),
|
||||
})
|
||||
})
|
||||
t.Run("MODMUL", func(t *testing.T) {
|
||||
src := `package foo
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/math"
|
||||
func Main() []int {
|
||||
r := make([]int, 5)
|
||||
r[0] = math.ModMul(3, 4, 5)
|
||||
r[1] = math.ModMul(-3, 4, 5)
|
||||
r[2] = math.ModMul(3, 4, -5)
|
||||
r[3] = math.ModMul(-3, 4, -5)
|
||||
r[4] = math.ModMul(0, 4, 5)
|
||||
return r
|
||||
}`
|
||||
eval(t, src, []stackitem.Item{
|
||||
stackitem.Make(2),
|
||||
stackitem.Make(3),
|
||||
stackitem.Make(2),
|
||||
stackitem.Make(3),
|
||||
stackitem.Make(0),
|
||||
})
|
||||
})
|
||||
t.Run("MODPOW", func(t *testing.T) {
|
||||
src := `package foo
|
||||
import "github.com/nspcc-dev/neo-go/pkg/interop/math"
|
||||
func Main() []int {
|
||||
r := make([]int, 5)
|
||||
r[0] = math.ModPow(3, 4, 5)
|
||||
r[1] = math.ModPow(-3, 5, 5)
|
||||
r[2] = math.ModPow(3, 4, -5)
|
||||
r[3] = math.ModPow(-3, 5, -5)
|
||||
r[4] = math.ModPow(19, -1, 141)
|
||||
return r
|
||||
}`
|
||||
eval(t, src, []stackitem.Item{
|
||||
stackitem.Make(1),
|
||||
stackitem.Make(2),
|
||||
stackitem.Make(1),
|
||||
stackitem.Make(2),
|
||||
stackitem.Make(52),
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -165,6 +165,8 @@ var coefficients = [256]uint16{
|
|||
opcode.MOD: 1 << 3,
|
||||
opcode.POW: 1 << 6,
|
||||
opcode.SQRT: 1 << 6,
|
||||
opcode.MODMUL: 1 << 5,
|
||||
opcode.MODPOW: 1 << 11,
|
||||
opcode.SHL: 1 << 3,
|
||||
opcode.SHR: 1 << 3,
|
||||
opcode.NOT: 1 << 2,
|
||||
|
|
|
@ -44,3 +44,14 @@ func Min(a, b int) int {
|
|||
func Within(x, a, b int) bool {
|
||||
return neogointernal.Opcode3("WITHIN", x, a, b).(bool)
|
||||
}
|
||||
|
||||
// ModMul returns the result of modulus division on a*b.
|
||||
func ModMul(a, b, mod int) int {
|
||||
return neogointernal.Opcode3("MODMUL", a, b, mod).(int)
|
||||
}
|
||||
|
||||
// ModPow returns the result of modulus division on a^b. If b is -1,
|
||||
// it returns the modular inverse of a.
|
||||
func ModPow(a, b, mod int) int {
|
||||
return neogointernal.Opcode3("MODPOW", a, b, mod).(int)
|
||||
}
|
||||
|
|
|
@ -179,6 +179,8 @@ const (
|
|||
MOD Opcode = 0xA2
|
||||
POW Opcode = 0xA3
|
||||
SQRT Opcode = 0xA4
|
||||
MODMUL Opcode = 0xA5
|
||||
MODPOW Opcode = 0xA6
|
||||
SHL Opcode = 0xA8
|
||||
SHR Opcode = 0xA9
|
||||
NOT Opcode = 0xAA
|
||||
|
|
|
@ -161,6 +161,8 @@ func _() {
|
|||
_ = x[MOD-162]
|
||||
_ = x[POW-163]
|
||||
_ = x[SQRT-164]
|
||||
_ = x[MODMUL-165]
|
||||
_ = x[MODPOW-166]
|
||||
_ = x[SHL-168]
|
||||
_ = x[SHR-169]
|
||||
_ = x[NOT-170]
|
||||
|
@ -202,7 +204,7 @@ func _() {
|
|||
_ = x[CONVERT-219]
|
||||
}
|
||||
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT"
|
||||
const _Opcode_name = "PUSHINT8PUSHINT16PUSHINT32PUSHINT64PUSHINT128PUSHINT256PUSHAPUSHNULLPUSHDATA1PUSHDATA2PUSHDATA4PUSHM1PUSH0PUSH1PUSH2PUSH3PUSH4PUSH5PUSH6PUSH7PUSH8PUSH9PUSH10PUSH11PUSH12PUSH13PUSH14PUSH15PUSH16NOPJMPJMP_LJMPIFJMPIF_LJMPIFNOTJMPIFNOT_LJMPEQJMPEQ_LJMPNEJMPNE_LJMPGTJMPGT_LJMPGEJMPGE_LJMPLTJMPLT_LJMPLEJMPLE_LCALLCALL_LCALLACALLTABORTASSERTTHROWTRYTRY_LENDTRYENDTRY_LENDFINALLYRETSYSCALLDEPTHDROPNIPXDROPCLEARDUPOVERPICKTUCKSWAPROTROLLREVERSE3REVERSE4REVERSENINITSSLOTINITSLOTLDSFLD0LDSFLD1LDSFLD2LDSFLD3LDSFLD4LDSFLD5LDSFLD6LDSFLDSTSFLD0STSFLD1STSFLD2STSFLD3STSFLD4STSFLD5STSFLD6STSFLDLDLOC0LDLOC1LDLOC2LDLOC3LDLOC4LDLOC5LDLOC6LDLOCSTLOC0STLOC1STLOC2STLOC3STLOC4STLOC5STLOC6STLOCLDARG0LDARG1LDARG2LDARG3LDARG4LDARG5LDARG6LDARGSTARG0STARG1STARG2STARG3STARG4STARG5STARG6STARGNEWBUFFERMEMCPYCATSUBSTRLEFTRIGHTINVERTANDORXOREQUALNOTEQUALSIGNABSNEGATEINCDECADDSUBMULDIVMODPOWSQRTMODMULMODPOWSHLSHRNOTBOOLANDBOOLORNZNUMEQUALNUMNOTEQUALLTLEGTGEMINMAXWITHINPACKMAPPACKSTRUCTPACKUNPACKNEWARRAY0NEWARRAYNEWARRAY_TNEWSTRUCT0NEWSTRUCTNEWMAPSIZEHASKEYKEYSVALUESPICKITEMAPPENDSETITEMREVERSEITEMSREMOVECLEARITEMSPOPITEMISNULLISTYPECONVERT"
|
||||
|
||||
var _Opcode_map = map[Opcode]string{
|
||||
0: _Opcode_name[0:8],
|
||||
|
@ -356,45 +358,47 @@ var _Opcode_map = map[Opcode]string{
|
|||
162: _Opcode_name[862:865],
|
||||
163: _Opcode_name[865:868],
|
||||
164: _Opcode_name[868:872],
|
||||
168: _Opcode_name[872:875],
|
||||
169: _Opcode_name[875:878],
|
||||
170: _Opcode_name[878:881],
|
||||
171: _Opcode_name[881:888],
|
||||
172: _Opcode_name[888:894],
|
||||
177: _Opcode_name[894:896],
|
||||
179: _Opcode_name[896:904],
|
||||
180: _Opcode_name[904:915],
|
||||
181: _Opcode_name[915:917],
|
||||
182: _Opcode_name[917:919],
|
||||
183: _Opcode_name[919:921],
|
||||
184: _Opcode_name[921:923],
|
||||
185: _Opcode_name[923:926],
|
||||
186: _Opcode_name[926:929],
|
||||
187: _Opcode_name[929:935],
|
||||
190: _Opcode_name[935:942],
|
||||
191: _Opcode_name[942:952],
|
||||
192: _Opcode_name[952:956],
|
||||
193: _Opcode_name[956:962],
|
||||
194: _Opcode_name[962:971],
|
||||
195: _Opcode_name[971:979],
|
||||
196: _Opcode_name[979:989],
|
||||
197: _Opcode_name[989:999],
|
||||
198: _Opcode_name[999:1008],
|
||||
200: _Opcode_name[1008:1014],
|
||||
202: _Opcode_name[1014:1018],
|
||||
203: _Opcode_name[1018:1024],
|
||||
204: _Opcode_name[1024:1028],
|
||||
205: _Opcode_name[1028:1034],
|
||||
206: _Opcode_name[1034:1042],
|
||||
207: _Opcode_name[1042:1048],
|
||||
208: _Opcode_name[1048:1055],
|
||||
209: _Opcode_name[1055:1067],
|
||||
210: _Opcode_name[1067:1073],
|
||||
211: _Opcode_name[1073:1083],
|
||||
212: _Opcode_name[1083:1090],
|
||||
216: _Opcode_name[1090:1096],
|
||||
217: _Opcode_name[1096:1102],
|
||||
219: _Opcode_name[1102:1109],
|
||||
165: _Opcode_name[872:878],
|
||||
166: _Opcode_name[878:884],
|
||||
168: _Opcode_name[884:887],
|
||||
169: _Opcode_name[887:890],
|
||||
170: _Opcode_name[890:893],
|
||||
171: _Opcode_name[893:900],
|
||||
172: _Opcode_name[900:906],
|
||||
177: _Opcode_name[906:908],
|
||||
179: _Opcode_name[908:916],
|
||||
180: _Opcode_name[916:927],
|
||||
181: _Opcode_name[927:929],
|
||||
182: _Opcode_name[929:931],
|
||||
183: _Opcode_name[931:933],
|
||||
184: _Opcode_name[933:935],
|
||||
185: _Opcode_name[935:938],
|
||||
186: _Opcode_name[938:941],
|
||||
187: _Opcode_name[941:947],
|
||||
190: _Opcode_name[947:954],
|
||||
191: _Opcode_name[954:964],
|
||||
192: _Opcode_name[964:968],
|
||||
193: _Opcode_name[968:974],
|
||||
194: _Opcode_name[974:983],
|
||||
195: _Opcode_name[983:991],
|
||||
196: _Opcode_name[991:1001],
|
||||
197: _Opcode_name[1001:1011],
|
||||
198: _Opcode_name[1011:1020],
|
||||
200: _Opcode_name[1020:1026],
|
||||
202: _Opcode_name[1026:1030],
|
||||
203: _Opcode_name[1030:1036],
|
||||
204: _Opcode_name[1036:1040],
|
||||
205: _Opcode_name[1040:1046],
|
||||
206: _Opcode_name[1046:1054],
|
||||
207: _Opcode_name[1054:1060],
|
||||
208: _Opcode_name[1060:1067],
|
||||
209: _Opcode_name[1067:1079],
|
||||
210: _Opcode_name[1079:1085],
|
||||
211: _Opcode_name[1085:1095],
|
||||
212: _Opcode_name[1095:1102],
|
||||
216: _Opcode_name[1102:1108],
|
||||
217: _Opcode_name[1108:1114],
|
||||
219: _Opcode_name[1114:1121],
|
||||
}
|
||||
|
||||
func (i Opcode) String() string {
|
||||
|
|
|
@ -33,5 +33,5 @@ func TestIsValid(t *testing.T) {
|
|||
require.True(t, IsValid(ADD))
|
||||
require.True(t, IsValid(CONVERT))
|
||||
require.False(t, IsValid(0xff))
|
||||
require.False(t, IsValid(0xa5))
|
||||
require.False(t, IsValid(0xa7))
|
||||
}
|
||||
|
|
2
pkg/vm/testdata/neo-vm
vendored
2
pkg/vm/testdata/neo-vm
vendored
|
@ -1 +1 @@
|
|||
Subproject commit b18e040d2115ed2ea3c9a60ae8722a7865b38927
|
||||
Subproject commit 02f2c68e7ba2694aff88c143631e7acf158d378a
|
45
pkg/vm/vm.go
45
pkg/vm/vm.go
|
@ -89,7 +89,12 @@ type VM struct {
|
|||
invTree *InvocationTree
|
||||
}
|
||||
|
||||
var bigOne = big.NewInt(1)
|
||||
var (
|
||||
bigMinusOne = big.NewInt(-1)
|
||||
bigZero = big.NewInt(0)
|
||||
bigOne = big.NewInt(1)
|
||||
bigTwo = big.NewInt(2)
|
||||
)
|
||||
|
||||
// New returns a new VM object ready to load AVM bytecode scripts.
|
||||
func New() *VM {
|
||||
|
@ -950,6 +955,44 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
|
|||
|
||||
v.estack.PushItem(stackitem.NewBigInteger(new(big.Int).Sqrt(a)))
|
||||
|
||||
case opcode.MODMUL:
|
||||
modulus := v.estack.Pop().BigInt()
|
||||
if modulus.Sign() == 0 {
|
||||
panic("zero modulus")
|
||||
}
|
||||
x2 := v.estack.Pop().BigInt()
|
||||
x1 := v.estack.Pop().BigInt()
|
||||
|
||||
res := new(big.Int).Mul(x1, x2)
|
||||
v.estack.PushItem(stackitem.NewBigInteger(res.Mod(res, modulus)))
|
||||
|
||||
case opcode.MODPOW:
|
||||
modulus := v.estack.Pop().BigInt()
|
||||
exponent := v.estack.Pop().BigInt()
|
||||
base := v.estack.Pop().BigInt()
|
||||
res := new(big.Int)
|
||||
switch exponent.Cmp(bigMinusOne) {
|
||||
case -1:
|
||||
panic("exponent should be >= -1")
|
||||
case 0:
|
||||
if base.Cmp(bigZero) <= 0 {
|
||||
panic("invalid base")
|
||||
}
|
||||
if modulus.Cmp(bigTwo) < 0 {
|
||||
panic("invalid modulus")
|
||||
}
|
||||
if res.ModInverse(base, modulus) == nil {
|
||||
panic("base and modulus are not relatively prime")
|
||||
}
|
||||
case 1:
|
||||
if modulus.Sign() == 0 {
|
||||
panic("zero modulus") // https://docs.microsoft.com/en-us/dotnet/api/system.numerics.biginteger.modpow?view=net-6.0#exceptions
|
||||
}
|
||||
res.Exp(base, exponent, modulus)
|
||||
}
|
||||
|
||||
v.estack.PushItem(stackitem.NewBigInteger(res))
|
||||
|
||||
case opcode.SHL, opcode.SHR:
|
||||
b := toInt(v.estack.Pop().BigInt())
|
||||
if b == 0 {
|
||||
|
|
|
@ -732,6 +732,35 @@ func TestSQRT(t *testing.T) {
|
|||
t.Run("negative value", getTestFuncForVM(prog, nil, -1))
|
||||
}
|
||||
|
||||
func TestMODMUL(t *testing.T) {
|
||||
prog := makeProgram(opcode.MODMUL)
|
||||
t.Run("bad, zero mod", getTestFuncForVM(prog, nil, 1, 2, 0))
|
||||
t.Run("good, positive base", getTestFuncForVM(prog, 2, 3, 4, 5))
|
||||
t.Run("good, zero base", getTestFuncForVM(prog, 0, 0, 4, 5))
|
||||
t.Run("good, negative base", getTestFuncForVM(prog, 3, -3, 4, 5))
|
||||
t.Run("good, positive base, negative mod", getTestFuncForVM(prog, 2, 3, 4, -5))
|
||||
t.Run("good, negative base, negative mod", getTestFuncForVM(prog, 3, -3, 4, -5))
|
||||
}
|
||||
|
||||
func TestMODPOW(t *testing.T) {
|
||||
prog := makeProgram(opcode.MODPOW)
|
||||
t.Run("good, positive base", getTestFuncForVM(prog, 1, 3, 4, 5))
|
||||
t.Run("good, negative base", getTestFuncForVM(prog, 2, -3, 5, 5))
|
||||
t.Run("good, positive base, negative mod", getTestFuncForVM(prog, 1, 3, 4, -5))
|
||||
t.Run("good, negative base, negative mod", getTestFuncForVM(prog, 2, -3, 5, -5))
|
||||
t.Run("bad, big negative exponent", getTestFuncForVM(prog, nil, 3, -2, 5))
|
||||
t.Run("bad, zero modulus", getTestFuncForVM(prog, nil, 3, 4, 0))
|
||||
|
||||
t.Run("inverse compatibility", func(t *testing.T) { // Tests are taken from C# node.
|
||||
t.Run("bad mod", getTestFuncForVM(prog, nil, 1, -1, 0))
|
||||
t.Run("bad mod", getTestFuncForVM(prog, nil, 1, -1, 1))
|
||||
t.Run("bad base", getTestFuncForVM(prog, nil, 0, -1, 0))
|
||||
t.Run("bad base", getTestFuncForVM(prog, nil, 0, -1, 1))
|
||||
t.Run("no inverse exists", getTestFuncForVM(prog, nil, math.MaxUint16, -1, math.MaxUint8))
|
||||
t.Run("good", getTestFuncForVM(prog, 52, 19, -1, 141))
|
||||
})
|
||||
}
|
||||
|
||||
func TestSHR(t *testing.T) {
|
||||
prog := makeProgram(opcode.SHR)
|
||||
t.Run("Good", getTestFuncForVM(prog, 1, 4, 2))
|
||||
|
|
Loading…
Reference in a new issue