diff --git a/pkg/vm/builtins/modulo.go b/pkg/vm/builtins/modulo.go index b335f63a9..4b5cc3de5 100644 --- a/pkg/vm/builtins/modulo.go +++ b/pkg/vm/builtins/modulo.go @@ -390,7 +390,24 @@ func (m *ModBuiltin) fillValue(mem *memory.Memory, inputs ModBuiltinInputs, inde } } } else { - value = *new(big.Int).Div(c, a) + x, _, gcd := utils.Igcdex(a, &inputs.p) + // if gcd != 1, the known value is 0, in which case the res must be 0 + if gcd.Cmp(big.NewInt(1)) != 0 { + value = *new(big.Int).Div(&inputs.p, &gcd) + } else { + value = *new(big.Int).Mul(c, &x) + value = *value.Mod(&value, &inputs.p) + tmpK, err := utils.SafeDiv(new(big.Int).Sub(new(big.Int).Mul(a, &value), c), &inputs.p) + if err != nil { + return false, err + } + if tmpK.Cmp(kBound) >= 0 { + return false, fmt.Errorf("%s builtin: ((%d * q) - %d) / %d > %d for any q > 0, such that %d * q = %d (mod %d) ", m.String(), a, c, &inputs.p, kBound, a, c, &inputs.p) + } + if tmpK.Cmp(big.NewInt(0)) < 0 { + value = *value.Add(&value, new(big.Int).Mul(&inputs.p, new(big.Int).Div(new(big.Int).Sub(a, new(big.Int).Sub(&tmpK, big.NewInt(1))), a))) + } + } } if err := m.writeNWordsValue(mem, addresses[1], value); err != nil { return false, err