-
Notifications
You must be signed in to change notification settings - Fork 123
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cryptol+z3 takes way too long to prove a simple property about bit rotations #573
Comments
Ok, it looks like Another encoding of symbolic rotates that z3 handles much better than lookup tables is to use a barrel-shifter-style construction, where we branch on the bits of the rotation amount:
|
I'm not sure why you say: The smtlib standard does include left- and right-shift operators with symbolic shift amounts, however, but we're not using them either.:
So, SBV does call the variable versions for Regarding the rotate: That is a shame indeed; I wish SMTLib allowed for variable rotations. But looks like z3 supports them, so we can:
I'd go for option 1, since it is probably simpler to do and honestly Pull requests most welcome! |
Oh, my mistake about cryptol/sbv not using the symbolic shift amounts; at some point in the past this was true but I guess not anymore. |
Yes, it used to be that way back in the day when they didn't have symbolic shift amounts. I wonder why they didn't add it to the rotates. I'm working on a patch to implement the first idea above, i.e., do it via |
I've played around with this a bit, but ran into z3 issues; filed here: Z3Prover/z3#2142 Depending on their response, my inclination is to support such symbolic rotate cases only if z3 ends up properly supporting them. I've a feeling they don't really support it, but some variants seem to go through the parser. |
Ah, as I suspected; z3 doesn't really support symbolic rotates. The fact that what you tried passed was a fluke apparently. They just put in a patch to reject it at parse-time now. I'll see if I can get your barrel-shift based idea working. I like it better this way as all solvers (potentially) can benefit from it. |
I've checked in an implementation of "barrel" rotates: LeventErkok/sbv@10e58be Instead of modifying the existing rotate code, I opted to add these as separate functions. The semantics of rotates is already rather complicated, and I think it's worth having the regular version in there in case there's something wrong with the barrel versions. They require bit-vector arguments and also insist that the rotate amount is unsigned. I think that should take care of the Cryptol use case, by generating simpler code. I tried with z3, and it does seem to be performing well with them. Give it a shot and let me know what you find out. (There'll be an SBV release soon, and then I expect a rather lengthy period of inactivity, so it's best to flesh out any issues quickly.) |
I tested this just now... it seems like we are still using SBV in a way that generates tables for the rotates... but Z3 now seems to solve this problem quickly (0.05s with Z3 4.8.7)? I'm not sure what changed. Do we still want to swap over to the barrel-shifter? |
This proof is now done essentially instantly by all the solvers I have access to (except ABC, which crashes shrug), I think we can close this. For posterity, my Z3 at the moment is |
Rotating right by
r
is the inverse of rotating left byr
:It takes a really long time for z3 to figure this out! (Yices and CVC4 are pretty fast, admittedly.)
However, z3 could be fast on this problem! The issue is that the rotations are encoded in smtlib using tables:
Checking this with
z3
takes more than 30 seconds. But checking this equivalent variant takes only a few milliseconds:We should be using the
rotate_left
androtate_right
functions with symbolic rotation amounts instead of generating lookup tables for rotations.The text was updated successfully, but these errors were encountered: