diff --git a/pkg/compiler/syscall_test.go b/pkg/compiler/syscall_test.go index 68e948256..f14d8629c 100644 --- a/pkg/compiler/syscall_test.go +++ b/pkg/compiler/syscall_test.go @@ -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), + }) + }) } diff --git a/pkg/interop/math/math.go b/pkg/interop/math/math.go index 796a73e57..b77ff0944 100644 --- a/pkg/interop/math/math.go +++ b/pkg/interop/math/math.go @@ -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) +}