Search code examples
pythonbit-manipulationz3z3pysat-solvers

Why Z3 falling at this?


i'm trying to solve this using z3-solver
but the proplem is that it gives me wrong values
i tried to replace the >> with LShR the values changes but non of them is corrent
however i know the value of w should be 0x41414141 in hex
i also tried to set w to 0x41414141 and it said that it's unsat

from z3 import *
def F(w):
    return ((w * 31337) ^ (w * 1337 >> 16)) % 2**32

s = Solver()
w = BitVec("w",32)
s.add ( F(w) == F(0x41414141))

while s.check() == sat:
     print s.model()
     s.add(Or(w != s.model()[w]))

Solution

  • Python uses arbitrary-size integers, whereas z3 clamps all intermediate results to 32 bits, so F gives different results for Python and z3. You'd need something like

    def F1(w):
        return ((w * 31337) ^ (((w * 1337) & 0xffffffff) >> 16)) % 2**32
    def F1Z(w):
        return ((w * 31337) ^ LShR(((w * 1337) & 0xffffffff), 16)) % 2**32
    
    s.add ( F1Z(w) == F1(0x41414141))