3

I have the following linear equations.

m = 2 ** 31 - 1

(207560540 ∗ a + b) modulo m = 956631177
(956631177 ∗ a + b) modulo m = 2037688522

What is the most efficient way to solve these equations?

I used Z3 however it did not find any solution. My code for Z3 to solve the above equations is:

#! /usr/bin/python

from z3 import *

a = Int('a')
b = Int('b')

s = Solver()

s.add((a * 207560540 + b) % 2147483647 == 956631177)
s.add((a * 956631177 + b) % 2147483647 == 2037688522)

print s.check()
print s.model()

I know that the solution is: a = 16807, b = 78125, however, how can I make Z3 solve it?

The other method I tried is by setting a and b to BitVec() instead of Integers as shown below:

a = BitVec('a', 32)
b = BitVec('b', 32)

This gives me an incorrect solution as shown below:

[b = 3637638538, a = 4177905984]

Is there way to solve it with Z3?

Thanks.

Neon Flash
  • 3,113
  • 12
  • 58
  • 96

1 Answers1

1

An aside on bit-vectors: When you use bit-vectors, then all operations are done modulo 2^N where N is the bit-vector size. So, z3 isn't giving you an incorrect solution: If you do the math modulo 2^32, you'll find that the model it finds is indeed correct.

It appears your problem does indeed need unbounded integers, and it is not really linear due to modulus 2^31-1. (Linear means multiplication by a constant; modulus by a constant takes you to a different realm.) And modulus is just not easy to reason with; I don't think z3 is the right tool for this sort of problem, nor any other SMT solver. Tools like mathematica, wolfram-alpha etc. probably are better choices in this case; for instance, see: wolfram-alpha solution

alias
  • 28,120
  • 2
  • 23
  • 40