7530 solver runs over 1695 instances in 13 benchmark families · AMD EPYC 7763 64-Core Processor, 15 GB RAM · generated 2026-09-13
Four solvers, each given the encoding it is designed for (Tseitin excepted, which is CNF for all of them). CryptoMiniSat is a CNF-XOR CDCL solver; Xorcle and Xorricane are XNF CDCL solvers (disjunctions of parity constraints); Bosphorus combines algebraic and logical reasoning over ANF.
| Solver | Git SHA | Input | Command line |
|---|---|---|---|
| CryptoMiniSat | 3eb822d0ab |
CNF-XOR / CNF | cryptominisat5 --sls 0 --autodisablegauss 0 --presimp 1 --maxmatrixrows 100000 --maxmatrixcols 100000 --maxnummatrices 1000000 --minmatrixrows 1 |
| CryptoMiniSat, newer build | b79d6193ac |
CNF-XOR / CNF | cryptominisat5 |
| Xorcle | 948b36ce2b |
XNF / CNF | xorcle |
| Xorricane | 05136c7e32 |
XNF | xorricane |
| Bosphorus | 5390b6ea1e |
ANF | bosphorus --solve-xnf --el 0 |
CryptoMiniSat’s defaults are tuned for general CNF, and on these
families they discard almost all of the linear structure before search
begins: --maxnummatrices defaults to 5 where lifted
pebbling builds 11476 simultaneous matrices, and
--maxmatrixrows defaults to 2000 where a single Bivium
matrix is 10809 rows. The command line above lifts those cutoffs, which
is what makes this a measurement of the CNF-XOR path rather than the
plain CNF one.
Lifting them was not enough on its own — the solver had not been run in that regime before, and three changes were required. All are in the pinned revision used here:
| Commit | Change | Needed for |
|---|---|---|
068a3fd79 |
fix crash when
--maxnummatrices exceeds 1000 |
lifted pebbling |
bef479cef |
avoid O(num_matrices) per-literal work in Gauss-Jordan elimination | lifted pebbling |
3970aaf24 |
raise MAX_XOR_RECOVER_SIZE
from 8 to 12 |
Tseitin at k = 9, 10 |
The last one mattered because a Tseitin formula on a k-regular graph has one parity constraint of degree exactly k, and the compile-time ceiling of 8 put k = 9 and k = 10 out of reach at any runtime setting. With it raised, CryptoMiniSat solves 75/75 of that family instead of 60/75.
cms-improved is b79d6193a,
70 commits after the 3970aaf24
used for cms. It runs with no options, as 4b82356e7
made the settings above its defaults. Beyond that, Gauss-Jordan
elimination was made cheaper, much of CaDiCaL’s search was brought
across, and local search was replaced by xnfSAT, which uses the XOR
structure.
We wrote xnf_fuzzer.py, which extends CryptoMiniSat’s
CNF fuzzers, among them Brummayer’s FuzzSAT (Brummayer, Lonsing and
Biere, SAT 2010), to XNF and 2-XNF. Each instance goes to Xorcle (and
Xorricane on 2-XNF) and, as CNF-XOR, to CryptoMiniSat: SAT answers are
checked by substitution, UNSAT ones by CryptoMiniSat’s proof in
cake_xlrup. We also fuzzed UBSan and ASan builds of both
solvers, and tried a few hand-written edge cases. Most of what turned up
is minor: crashes on degenerate inputs, assertions that only fire in
Debug builds, and issues behind non-default options. Two change the
answer, both on unusual input: a variable repeated inside a lineral, and
tab-separated input. CryptoMiniSat gave no wrong answers on the same
instances; its own problems in this regime, listed above, were a crash and a slowdown with many
matrices. Each fix is one patch, whose commit message is the bug
report.
bugs-xorcle/| Patch | Bug | Impact |
|---|---|---|
patch-1.diff |
a repeated variable in a lineral is OR-ed, not XOR-ed | wrong answer, on inputs that repeat a variable |
patch-2.diff |
an empty input clause segfaults instead of giving UNSAT | crash on a degenerate input |
patch-3.diff |
the proof checker rejects the p xnf header |
proof checker script only |
patch-4.diff |
the proof checker has the same OR/XOR parsing bug | proof checker script only |
bugs-xorricane/| Patch | Bug | Impact |
|---|---|---|
patch-1.diff |
util clause deletion writes out of bounds:
segfault |
crash, non-default -delh util only |
patch-2.diff |
avg_util clause deletion (the default) reads
uninitialised memory |
undefined behaviour; no wrong answer seen |
patch-3.diff |
every UNSAT answer calls back() on an empty list |
undefined behaviour; aborts in Debug builds only |
patch-4.diff |
an assertion dereferences a null pointer with
-no-lgj |
Debug builds with -no-lgj only |
patch-5.diff |
Gauss elimination (-il) never reads the first matrix
row |
missed propagations; same answers |
patch-6.diff |
the parser splits on spaces only: wrong answer on tabs, CRLF rejected | wrong answer on tab-separated input |
patch-7.diff |
a late equivalence overwrites an existing one | assertion in Debug builds; release answer correct |
patch-8.diff |
the empty XOR line x 0 overflows the heap |
crash on a degenerate input |
patch-9.diff |
an assertion fails with -rh lbd when a learnt clause
has LBD 0 |
Debug builds only; release answer correct |
| Family | Instances | Timeout (s) | Description |
|---|---|---|---|
| 2xnf-ascon Ascon-128 (2-Xornado suite) |
400 | 180 | 400 satisfiable instances from
key-recovery attacks on round-reduced Ascon-128, rounds 2/3/4, from the
2xnf_sat_solving repository. |
| 2xnf-rand Random 2-XNF (unsat-mixed) |
400 | 180 | 400 random 2-XNF instances, n=21..40, m=3n, from the 2-Xornado paper’s benchmark set. |
| 2xnf-rand_sat Random 2-XNF (satisfiable) |
400 | 180 | 400 random 2-XNF instances guaranteed satisfiable, same parameters as above. |
| ascon Ascon (Xorricane suite, Benchmark 6.5) |
50 | 180 | 50 satisfiable instances from state-recovery attacks on Ascon-128, from the Xorricane-paper release. Distinct from the 2-Xornado Ascon set. |
| bivium Bivium (Xorricane Benchmark 6.6) |
50 | 180 | 50 satisfiable state-recovery instances on the Bivium stream cipher. |
| ctc CTC2 (Xorricane Benchmark 6.7) |
50 | 180 | 50 satisfiable key-recovery instances on the CTC2 block cipher. |
| pebbling_lifted_h_k Pebbling formulas lifted by k-XORs |
40 | 180 | Pebbling formulas on pyramid graphs of height h=60..150, each variable replaced by the XOR of k fresh variables (k=2,4,6,8). Solvable by unit propagation alone in XNF. |
| rand_l2xnf_ld Random linear system with 2-XNF constraints (Benchmark 6.3) |
50 | 180 | n/2 random linear equations plus n random 2-XNF clauses, n=61..110. |
| rand_qp_type_I Multivariate quadratic, Type I (Benchmark 6.4) |
50 | 180 | Random quadratic systems with m=2n, at least one solution, n=11..35. |
| rand_qp_type_IV Multivariate quadratic, Type IV (Benchmark 6.4) |
50 | 180 | Random quadratic systems with n=floor(1.5m), n=11..35. |
| random_kxnf_n Random k-XNFs |
40 | 180 | k=2..5, n=11..20, clause count tuned so roughly half the instances are satisfiable. |
| restricted_kxnf_n Restricted random k-XNFs |
40 | 180 | A random k-XNF restricted by N/2 random affine equations, k=2..5, N=22,24,…,40. |
| tseitin_n_k Tseitin formulas in CNF |
75 | 180 | Unsatisfiable parity formulas on random
k-regular n-vertex graphs, generated with cnfgen. Grid:
(20,k) for k=3..10 and (n,4) for n=10,20,…,1280, five graphs each.
Provably hard for Resolution; the headline family of the Xorcle paper.
Given to every solver as CNF, as in that paper. |
The same formula appears in several formats; each solver reads the one it supports. Conversions were done with these tools:
| Extension | Format | Produced by |
|---|---|---|
.cnf |
plain CNF, XORs blasted | shipped with the benchmark |
.xcnf /
.cnf-xor |
CNF-XOR | shipped, or
xnf_to_xcnf.py |
.2xcnf |
CNF-XOR built from the 2-XNF | xnf_to_xcnf.py |
.xnf |
XNF, + linerals |
shipped |
.2xnf |
2-XNF, at most two linerals per clause | shipped with the benchmark |
.anf |
algebraic normal form | shipped with the benchmark |
The CNF-XOR encodings a benchmark does not ship were generated to
match the one the Xorricane paper uses, and reproduce all 200 shipped
.xcnf files exactly — variable, clause and xor-line counts
all agree.
PAR2 is the SAT-competition penalised average runtime: the mean over attempted instances of the solve time, with unsolved instances charged twice the timeout. Lower is better. The attempted column makes the denominator explicit, since not every solver ran on every family.
CDF of solving time over all families. Bosphorus is excluded here
because it was only run on the Ascon and Xorricane-paper suites.
CryptoMiniSat appears twice: cms is the older build with
the options above, cms-improved
the newer build with none. Where cms was also run on a
CNF-XOR encoding (Type I quadratic systems), this plot uses its plain
CNF run. Every line covers all 1695 instances.
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 1314 | 1695 | 92.57 | 15.02 | 11637 |
| cms | 1196 | 1695 | 121.76 | 22.37 | 6490 |
| xorcle | 919 | 1695 | 173.72 | 16.42 | 9948 |
| xorricane | 583 | 1695 | 282.68 | 20.77 | 1805 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 318 | 400 | 93.50 | 24.79 | 151 |
| cms | 320 | 400 | 99.48 | 34.35 | 91 |
| xorcle | 286 | 400 | 119.18 | 23.18 | 314 |
| bosphorus | 154 | 400 | 254.81 | 86.79 | 526 |
| xorricane | 91 | 400 | 326.99 | 11.15 | 644 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 264 | 400 | 131.51 | 13.81 | 113 |
| cms | 181 | 400 | 207.50 | 22.98 | 70 |
| xorcle | 140 | 400 | 239.91 | 16.90 | 80 |
| xorricane | 100 | 400 | 324.22 | 36.89 | 306 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 332 | 400 | 73.46 | 14.77 | 115 |
| cms | 318 | 400 | 93.54 | 24.83 | 68 |
| xorcle | 172 | 400 | 212.13 | 16.12 | 78 |
| xorricane | 127 | 400 | 296.58 | 31.29 | 300 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms | 75 | 75 | 0.07 | 0.07 | 26 |
| cms-improved | 75 | 75 | 0.08 | 0.08 | 18 |
| xorcle | 75 | 75 | 9.78 | 9.78 | 465 |
| xorricane | 17 | 75 | 327.43 | 11.61 | 877 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 31 | 50 | 147.56 | 17.35 | 134 |
| cms | 28 | 50 | 169.19 | 19.27 | 81 |
| xorcle | 25 | 50 | 189.50 | 19.01 | 317 |
| bosphorus | 18 | 50 | 252.11 | 60.32 | 491 |
| xorricane | 14 | 50 | 302.71 | 1.09 | 666 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 39 | 50 | 93.49 | 18.32 | 91 |
| xorricane | 36 | 50 | 124.12 | 9.05 | 464 |
| cms | 34 | 50 | 131.85 | 24.49 | 249 |
| xorcle | 23 | 50 | 205.73 | 24.63 | 269 |
| bosphorus | 7 | 50 | 324.37 | 105.53 | 1586 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 28 | 50 | 168.01 | 17.16 | 78 |
| cms | 27 | 50 | 175.26 | 17.88 | 79 |
| bosphorus | 26 | 50 | 180.10 | 14.04 | 177 |
| xorcle | 18 | 50 | 233.34 | 8.17 | 809 |
| xorricane | 19 | 50 | 264.45 | 10.65 | 651 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 43 | 50 | 57.82 | 8.63 | 91 |
| bosphorus | 41 | 50 | 74.01 | 11.24 | 69 |
| cms | 40 | 50 | 81.00 | 11.25 | 49 |
| xorricane | 39 | 50 | 107.56 | 19.43 | 351 |
| xorcle | 25 | 50 | 188.42 | 16.85 | 56 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms (.xcnf) | 42 | 50 | 74.12 | 19.66 | 88 |
| cms-improved | 34 | 50 | 122.79 | 11.17 | 63 |
| bosphorus | 31 | 50 | 150.56 | 22.20 | 185 |
| cms (.cnf) | 30 | 50 | 152.39 | 13.98 | 123 |
| xorricane | 31 | 50 | 166.75 | 11.53 | 1014 |
| xorcle | 23 | 50 | 197.30 | 6.31 | 93 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 30 | 50 | 153.60 | 16.00 | 122 |
| cms | 29 | 50 | 160.25 | 15.60 | 148 |
| bosphorus | 24 | 50 | 193.08 | 12.26 | 226 |
| xorcle | 20 | 50 | 223.07 | 17.68 | 134 |
| xorricane | 23 | 50 | 236.14 | 20.30 | 1805 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| xorcle | 40 | 40 | 1.89 | 1.89 | 9948 |
| cms | 40 | 40 | 2.54 | 2.54 | 6490 |
| cms-improved | 40 | 40 | 3.82 | 3.82 | 11637 |
| xorricane | 12 | 40 | 300.48 | 21.61 | 995 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 40 | 40 | 2.34 | 2.34 | 62 |
| xorricane | 40 | 40 | 6.77 | 6.77 | 105 |
| cms | 37 | 40 | 33.49 | 7.02 | 104 |
| xorcle | 36 | 40 | 41.22 | 5.80 | 59 |
| Solver | Solved | Attempted | PAR2 (s) | Avg time solved (s) | Peak RSS (MB) |
|---|---|---|---|---|---|
| cms-improved | 40 | 40 | 2.32 | 2.32 | 57 |
| cms | 37 | 40 | 31.02 | 4.35 | 105 |
| xorcle | 36 | 40 | 40.89 | 5.44 | 67 |
| xorricane | 34 | 40 | 77.44 | 16.99 | 121 |
CryptoMiniSat XOR size limit. With the default
--maxxorsize 7, every Tseitin instance with k ≥ 8 times out
while every k ≤ 7 instance solves in 0.0 s — the parity constraints have
degree exactly k, so at k=8 none are recovered and the solver is left
doing pure resolution. The Xorcle paper points this limit out as
well.
Bivium encoding. On the Xorricane suites
CryptoMiniSat is given the plain .cnf, not the shipped
.xcnf, and this choice favours it: on Bivium it solves
34/50 from the .cnf but only 1/50 from the
.xcnf. The CNF-XOR files are translated from the XNF and
keep its wide linerals, which gives a much denser XOR system than the
one CryptoMiniSat recovers from the CNF itself.
Memory on lifted pebbling. With over ten thousand
matrices or parity constraints per instance, lifted pebbling is the
memory-heavy family: peak RSS is 11.6 GB for cms-improved,
9.9 GB for Xorcle and 6.5 GB for cms, while Xorricane stays
under 1 GB. This limits how many runs can be scheduled in parallel, a
practical cost the solved counts do not show.