1

I'm trying to find a key that fulfills these conditions:

  • Key length is 19 characters
  • Characters in the ASCII range are from 0x30 to 0x5F
  • Key[1] same as key[2]
  • Summary of all characters is 1418 (decimal)
  • Summary of sum_mul_pi function is 39944 (decimal)
  • ... redacted for simplicity

My problem is with float operations in Z3. I cannot write correct expressions in Z3 because z3 returns nothing.

If I remove the sum_mul_pi function (float operations), I get a lot of results and I process those results using non-z3 (python only) code to filter out those that don't match this condition, I see some results.

Why those results are not written by z3 with the sum_mul_pi function?

Thanks!

#
# this is a simplified model, there are more constraints
#

from z3 import *
set_param("parallel.enable", True)

def sum_mul_pi(values):
    val = BitVecVal(0, 64)
    for i in range(0, len(values)):
        val1 = FPVal(float(i) * float(3.141592), Float(64))
        val2 = fpMul(RTZ(), fpBVToFP(values[i], Float64()), val1)
        val += fptoUBV(RTZ(), val2, BitVecSort(64))
    return val

key = [BitVec("i%d" % i, 64) for i in range(19)]

s = Solver()

for x in range(19):
    s.add(key[x] >= ord("0"))
    s.add(key[x] <= ord("_"))

s.add(key[1] == key[2])
s.add(Sum(key) == 1418)
s.add(sum_mul_pi(key) == 39944)

while s.check() == sat:
    m = s.model()
    ss = "".join([chr(m[x].as_long()) for x in key])
    print(ss)
    s.add(Or([ f() != m[f] for f in m.decls() if f.arity() == 0])) 

sum_mul_pi is really not complicated, python only version looks like this:

def sum_mul_pi(values):
    val = 0
    for i in range(0, len(values)):
        val1 = float(i) * float(3.141592)
        val2 = float(ord(values[i])) * val1
        val += int(val2)
    return val
JohanC
  • 71,591
  • 8
  • 33
  • 66
fritz
  • 111
  • 1
  • 11
  • What does "returns nothing" mean? Is the problem unsatisfiable? – Christoph Wintersteiger Sep 28 '21 at 13:01
  • Thanks for responding! It means that the z3 app just ends without printing anything. If I remove this constraint (s.add(sum_mul_pi(key) == 39944)), I get a bunch of results and some of them match this condition when processed without z3 as you can see in second code paste. The question really is how to write z3 expression that matches the second code paste (python - sum_mul_pi). – fritz Sep 28 '21 at 13:07
  • What does `s.check()` return? – Christoph Wintersteiger Sep 28 '21 at 13:07
  • 1
    Your program has a couple of typos to start with. `Float(64)` should be `Float64()`, and `fpToUBV` not `fptoUBV`. But the main issue here is that you're using way too large values, and z3 is just getting bogged down. See if you can cast the problem without using floats. Since you're multiplying by `3.141592` and casting back, maybe you can multiply by `3141592` (i.e., scale by 100000`) and then check for the appropriate sum value. If you keep this to just bit-vectors or integers only, you might have better luck. – alias Sep 28 '21 at 15:12
  • @ChristophWintersteiger s.check() returns "unsat". – fritz Sep 28 '21 at 19:05
  • @alias thanks for responding! Sorry about the typos, there are just here on post :-( Regarding large values, there are more constraints, but they are simple because they are integers, except they have large values and that's the reason why I'm using 64 bit values. Actually, full solution that I'm working on is here - https://pastebin.com/etRm3sQ8. Everything seems to work fine except the float case, that's v21 method (here in SO post is sum_mul_pi). I'll see if I can try with scale by 100000. – fritz Sep 28 '21 at 19:27
  • Scaling by 1000000 just keeps my CPU cores busy with used approx 100 GB RAM and no result for 24 hours :-( – fritz Sep 29 '21 at 20:08

0 Answers0