Closed void4 closed 3 months ago
It really depends on the situation whether it's more appropriate to use Z3 or the lattice method to crack an LCG. For 10 calls, the lattice method can optimally be on the order of microseconds, although LattiCG is still a bit less optimized than that.
Yes, we know about Z3. Your particular example is not very convincing as it is a problem which can be answered using only basic algebra, which Z3 is good at, while I am not aware of such methods working in the general case. It could be that Z3 is smart enough to use its MILP solver for the general case, in which case its performance should not be bad. One can replace our MILP code with Z3s and probably get something decent.
In general if you want to use some other software besides LattiCG (for example if you need to use a different language), an appropriate replacement is anything which can solve Mixed Integer Linear Programs (MILPs). In the past I have used gurobi for this.
Also, its just no fun!
Your seedfinding explanations made me think of this. Z3 is a quite powerful theorem prover with Python bindings. It can find solutions for many systems and types of constraints, and can work with many datatypes, including floats and bit vectors! Here is an excellent talk about it: https://www.youtube.com/watch?v=56IIrBZy9Rc
Below I implemented a program which tries to find an initial_seed that, after ROUNDS iterations of an LCG, generates sequential values which each satisfy some constraints.
I haven't tested yet how well this works with other sets of constraints/larger numbers or rounds, but for this example it finds a solution even for 10000 LCG iterations within 2 seconds.
pip install z3
Edit: found a video where someone applies it to a different generator: https://www.youtube.com/watch?v=-h_rj2-HP2E