Skip to content

Commit

Permalink
vm: fix MODPOW operation
Browse files Browse the repository at this point in the history
Close #3612

Signed-off-by: Ekaterina Pavlova <[email protected]>
  • Loading branch information
AliceInHunterland committed Oct 28, 2024
1 parent b8a65d3 commit 787ee3a
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
4 changes: 2 additions & 2 deletions pkg/compiler/syscall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,9 @@ func TestOpcode(t *testing.T) {
}`
eval(t, src, []stackitem.Item{
stackitem.Make(1),
stackitem.Make(2),
stackitem.Make(-3),
stackitem.Make(1),
stackitem.Make(2),
stackitem.Make(-3),
stackitem.Make(52),
})
})
Expand Down
11 changes: 8 additions & 3 deletions pkg/vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -1036,6 +1036,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
modulus := v.estack.Pop().BigInt()
exponent := v.estack.Pop().BigInt()
base := v.estack.Pop().BigInt()
absModulus := new(big.Int).Abs(modulus)
res := new(big.Int)
switch exponent.Cmp(bigMinusOne) {
case -1:
Expand All @@ -1044,17 +1045,21 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
if base.Cmp(bigZero) <= 0 {
panic("invalid base")
}
if modulus.Cmp(bigTwo) < 0 {
if absModulus.Cmp(bigTwo) < 0 {
panic("invalid modulus")
}
if res.ModInverse(base, modulus) == nil {
if res.ModInverse(base, absModulus) == 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)
res.Exp(base, exponent, absModulus)

if base.Sign() < 0 && exponent.Bit(0) == 1 {
res.Sub(res, absModulus)
}
}

v.estack.PushItem(stackitem.NewBigInteger(res))
Expand Down
6 changes: 4 additions & 2 deletions pkg/vm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,11 @@ func TestMODMUL(t *testing.T) {
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, negative base", getTestFuncForVM(prog, -3, -3, 5, 5))
t.Run("good, negative base", getTestFuncForVM(prog, -1, -1, 3, 3))
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("good, negative base, negative mod", getTestFuncForVM(prog, -3, -3, 5, -5))
t.Run("good, negative base, negative mod", getTestFuncForVM(prog, -2, -5, 5, -3))
t.Run("bad, big negative exponent", getTestFuncForVM(prog, nil, 3, -2, 5))
t.Run("bad, zero modulus", getTestFuncForVM(prog, nil, 3, 4, 0))

Expand Down

0 comments on commit 787ee3a

Please sign in to comment.