https://github.com/hadipourh/autoguess
An easy-to-use, general and open-source tool to solve the guess-and-determine problem
https://github.com/hadipourh/autoguess
blockcipher constraint-programming cryptanalysis cryptography groebner-basis guess-and-determine key-bridging milp minizinc or-tools pysat pysmt python3 sagemath sat sat-solver-application smt stream-ciphers
Last synced: 3 months ago
JSON representation
An easy-to-use, general and open-source tool to solve the guess-and-determine problem
- Host: GitHub
- URL: https://github.com/hadipourh/autoguess
- Owner: hadipourh
- License: gpl-3.0
- Created: 2021-11-21T13:25:34.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2026-02-24T16:01:33.000Z (3 months ago)
- Last Synced: 2026-02-24T16:32:09.824Z (3 months ago)
- Topics: blockcipher, constraint-programming, cryptanalysis, cryptography, groebner-basis, guess-and-determine, key-bridging, milp, minizinc, or-tools, pysat, pysmt, python3, sagemath, sat, sat-solver-application, smt, stream-ciphers
- Language: Python
- Homepage: https://hadipourh.github.io/autoguess
- Size: 24.6 MB
- Stars: 29
- Watchers: 1
- Forks: 5
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Autoguess
[](./LICENSE.txt)
[](https://pypi.org/project/autoguess/)
[](https://doi.org/10.5281/zenodo.16932672)
[](https://www.python.org/)
[](https://www.docker.com/)
[](https://github.com/pysathq/pysat)
[](https://www.minizinc.org/)
[](https://developers.google.com/optimization)
[](https://www.gurobi.com/)
[](https://www.sagemath.org/)
[](https://github.com/hadipourh/autoguess/stargazers)
[](https://github.com/hadipourh/autoguess/network)
**Autoguess** is a generic and easy-to-use tool designed to assist in solving the guess-and-determine problem. It is commonly applied in areas such as identifying guess-and-determine attacks and key bridging in cryptographic systems. The tool supports multiple solving approaches, including:
- **Constraint Programming (CP)** via MiniZinc
- **Mixed-Integer Linear Programming (MILP)** via Gurobi
- **Boolean Satisfiability (SAT)** via PySAT
- **Satisfiability Modulo Theories (SMT)** via pySMT
- **Algebraic methods** via SageMath and Groebner basis computation
The tool is particularly useful for cryptanalysis of symmetric-key primitives, helping researchers discover minimal guess bases for various cryptographic primitives and protocols.
---
## Overall Structure
The following shape represents the overall structure of Autoguess. As it can be seen, Autoguess relies on [Minizinc](https://www.minizinc.org/), [PySAT](https://github.com/pysathq/pysat), [pySMT](https://github.com/pysmt/pysmt), [Gurobi](https://www.gurobi.com/) and [SageMath](https://www.sagemath.org/). Providing a Python interface, Autoguess translates the guess-and-determine problem to a SAT, SMT, MILP or Groebner basis computation problem and then calls an appropriate solver to solve it. It also provides a lightweight **knowledge-propagation** mode that iteratively deduces variables from an initial known set without invoking any external solver. Additionally, it utilizes [Graphviz](https://pypi.org/project/graphviz/) to visualize the discovered determination flow.

---
- [Autoguess](#autoguess)
- [Overall Structure](#overall-structure)
- [Installation](#installation)
- [Prerequisites](#prerequisites)
- [Installation Methods](#installation-methods)
- [Method 1: pip install (Recommended)](#method-1-pip-install-recommended)
- [Method 2: Build Docker Image Locally](#method-2-build-docker-image-locally)
- [For ARM64 (Apple Silicon)](#for-arm64-apple-silicon)
- [For x86\_64 (Most Linux Systems)](#for-x86_64-most-linux-systems)
- [Method 3: Use Pre-built Docker Image](#method-3-use-pre-built-docker-image)
- [Method 4: Native Installation (Debian-based and macOS)](#method-4-native-installation-debian-based-and-macos)
- [Quick Start](#quick-start)
- [Format of Input File](#format-of-input-file)
- [Usage](#usage)
- [Command Line Interface](#command-line-interface)
- [Example 1](#example-1)
- [Example 2](#example-2)
- [Example 3](#example-3)
- [Example 4](#example-4)
- [Example 5](#example-5)
- [Example 6](#example-6)
- [Troubleshooting](#troubleshooting)
- [Common Issues](#common-issues)
- [Docker Issues](#docker-issues)
- [Missing Dependencies](#missing-dependencies)
- [Input File Issues](#input-file-issues)
- [Performance Tips](#performance-tips)
- [Getting Help](#getting-help)
- [Applications](#applications)
- [GD Attack on 1 Round of AES with 1 Known Plaintext/Ciphertext Pair](#gd-attack-on-1-round-of-aes-with-1-known-plaintextciphertext-pair)
- [GD Attack on 2 Rounds of AES with 1 Known Plaintext/Ciphertext Pair](#gd-attack-on-2-rounds-of-aes-with-1-known-plaintextciphertext-pair)
- [GD Attack on 3 Rounds of AES with 1 Known Plaintext/Ciphertext Pair](#gd-attack-on-3-rounds-of-aes-with-1-known-plaintextciphertext-pair)
- [GD Attack on 14 Rounds of Khudra with 1 Known Plaintext/Ciphertext Pair](#gd-attack-on-14-rounds-of-khudra-with-1-known-plaintextciphertext-pair)
- [GD Attack on 11 Rounds of SKINNY-n-n with 1 Known Plaintext/Ciphertext Pair](#gd-attack-on-11-rounds-of-skinny-n-n-with-1-known-plaintextciphertext-pair)
- [GD Attack on Enocoro128-v2](#gd-attack-on-enocoro128-v2)
- [GD Attack on KCipher2](#gd-attack-on-kcipher2)
- [GD Attack on SNOW1](#gd-attack-on-snow1)
- [GD Attack on SNOW2](#gd-attack-on-snow2)
- [GD Attack on SNOW3](#gd-attack-on-snow3)
- [GD Attack on ZUC](#gd-attack-on-zuc)
- [GD Attack on Bivium-A](#gd-attack-on-bivium-a)
- [Key-bridging in Linear Attack on PRESENT](#key-bridging-in-linear-attack-on-present)
- [Key-bridging in Integral Attack on LBlock](#key-bridging-in-integral-attack-on-lblock)
- [Key Bridging in Impossible Differential Attack on LBlock](#key-bridging-in-impossible-differential-attack-on-lblock)
- [Key Bridging in Zero Correlation Attack on SKINNY-64-128](#key-bridging-in-zero-correlation-attack-on-skinny-64-128)
- [Key Bridging in Zero Correlation Attack on SKINNY-64-192](#key-bridging-in-zero-correlation-attack-on-skinny-64-192)
- [Key Bridging in DS-MITM Attack on SKINNY-128-384](#key-bridging-in-ds-mitm-attack-on-skinny-128-384)
- [Key Bridging in Impossible Differential Attack on T-TWINE-80](#key-bridging-in-impossible-differential-attack-on-t-twine-80)
- [Key Bridging in Impossible Differential Attack on T-TWINE-128](#key-bridging-in-impossible-differential-attack-on-t-twine-128)
- [The Paper](#the-paper)
- [Citation](#citation)
- [License](#license)
## Installation
### Prerequisites
Before installing Autoguess, ensure you have the following:
- **Python 3.8+**: Autoguess requires Python 3.8 or higher (Python 3.11+ needed for Groebner basis support)
- **Docker** (alternative): For a self-contained installation
- **Git**: For cloning the repository and dependencies
### Installation Methods
Autoguess can be installed via `pip` (recommended), Docker, or native installer scripts.
#### Method 1: pip install (Recommended)
The simplest way to install Autoguess is via pip:
```bash
# Core installation (SAT solver and visualization)
pip install autoguess
# With SMT solver support (z3, cvc5 -- requires a C++20 compiler for z3)
pip install "autoguess[smt]"
# With CP solver support (also install the MiniZinc binary)
pip install "autoguess[cp]"
autoguess --install-minizinc
# With Groebner basis support (via passagemath, pip-installable SageMath; requires Python >= 3.11)
pip install "autoguess[groebner]"
# With Gurobi MILP support (requires Gurobi license)
pip install "autoguess[gurobi]"
# Everything (SMT + CP + Groebner + Gurobi)
pip install "autoguess[all]"
```
The following table summarizes the available extras:
| Extra | Solvers included | Notes |
|-------|-----------------|-------|
| *(core)* | SAT (PySAT) | Always installed |
| `[smt]` | z3, cvc5 | z3-solver builds from source (needs C++20 compiler, e.g. GCC 11+). For boolector, install `pyboolector` manually (PyPI builds are broken). |
| `[cp]` | MiniZinc CP | Also run `autoguess --install-minizinc` to download the MiniZinc binary |
| `[groebner]` | Groebner basis (passagemath) | Requires Python >= 3.11 and native build tools. Falls back to system SageMath if passagemath is not installed. |
| `[gurobi]` | Gurobi MILP | Requires a Gurobi license |
| `[all]` | All of the above | |
**System dependencies** (not installed by pip):
- **Python development headers** (required for `[groebner]` / `[all]`): `sudo apt install python3-dev` (Debian/Ubuntu) / `sudo dnf install python3-devel` (Fedora) — needed to build native extensions like `cysignals`
- **MiniZinc binary**: Run `autoguess --install-minizinc` to auto-download, or install via your package manager (`brew install minizinc` / `snap install minizinc --classic`)
- **Graphviz binary** (optional, for visualization rendering): `brew install graphviz` / `apt install graphviz`
#### Method 2: Build Docker Image Locally
The easiest way is using the provided [Dockerfile](docker/DockerfileDebian) to get Autoguess and all of its dependencies at once. To do so, regardless of what OS you use:
1. **Install Docker**: Follow the [Docker installation guide](https://docs.docker.com/get-docker/) for your platform
2. **Clone this repository**:
```sh
git clone https://github.com/hadipourh/autoguess.git
cd autoguess
```
3. **Build the Docker image**: Navigate to the directory where you cloned the repository and build a local image of Autoguess:
```sh
docker build --platform linux/amd64 -t autoguess -f docker/DockerfileDebian .
```
4. **Run Autoguess**: Once built, you can run Autoguess using the following commands:
##### For ARM64 (Apple Silicon)
```sh
docker run --platform linux/amd64 -it --rm autoguess
```
##### For x86_64 (Most Linux Systems)
```sh
docker run -it --rm autoguess
```
The provided image is self-contained and includes MiniZinc, PySAT, pySMT, and SageMath. While Autoguess also offers a direct Python interface to [Gurobi](https://www.gurobi.com/), Gurobi itself and its license are not included in the image. If you wish to use the MILP-based method to solve the guess-and-determine problem, you will need to install Gurobi separately. For Linux and macOS, you can use the installer available in [this repository](https://github.com/hadipourh/grabgurobi).
One can also build an image of Autoguess with the [DockerfileArch](docker/DockerfileArch) which is based on the [Arch Linux](https://archlinux.org/) distribution. To do so, you can use the following command:
```sh
docker build -f docker/DockerfileArch -t autoguess_arch .
```
Then, you can run Autoguess by the following command:
```sh
docker run --rm -it autoguess_arch
```
#### Method 3: Use Pre-built Docker Image
If you have already installed [Docker](https://www.docker.com/) and prefer to use a pre-built image instead of building locally, you can download a prebuilt image of Autoguess from [Docker Hub](https://hub.docker.com/):
**For Debian-based image:**
```sh
docker pull hoseinhadipour/autoguess
```
Then run Autoguess:
```sh
docker run --rm -it hoseinhadipour/autoguess
```
**For Arch Linux-based image:**
```sh
docker pull hoseinhadipour/autoguess_arch
```
Then run Autoguess:
```sh
docker run --rm -it hoseinhadipour/autoguess_arch
```
#### Method 4: Native Installation (Debian-based and macOS)
For Debian-based Linux operating systems, you can install Autoguess natively using the provided installer script:
```bash
git clone https://github.com/hadipourh/autoguess.git
cd autoguess
bash installer.sh
```
For macOS users, you can also use the installer script, but you will need to install [Homebrew](https://brew.sh/) first. After installing Homebrew, you can use the provided installer script:
```bash
chmod +x installer_macos.sh
./installer_macos.sh
```
**Note**: This method requires manually installing all dependencies. Review the [requirements.txt](requirements.txt) file for the complete list of Python dependencies.
---
## Quick Start
Once you have Autoguess installed, you can quickly test it with one of the provided examples:
```bash
# If installed via pip
autoguess --inputfile ciphers/Example1/relationfile.txt --solver cp --maxsteps 5
# Using Docker (pre-built)
1- docker run --rm -it hoseinhadipour/autoguess
2- python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver cp --maxsteps 5
# Or if you built Docker locally
1- docker run --rm -it autoguess
2- python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver cp --maxsteps 5
# Or if installed natively via scripts
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver cp --maxsteps 5
```
This should output something like:
```text
Number of guesses: 2
Number of known variables in the final state: 7 out of 7
The following 2 variable(s) are guessed:
v, u
```
---
## Format of Input File
The input file can be a plain text separated into the following parts:
- Algebraic relations. This section begins with `algebraic relations` and includes the algebraic relations (currently the algebraic relations over GF(2) are merely supported).
- Connection relations. This section begins with `connection relations` and includes the connections relations consisting of symmetric or implication relations.
- Known variables. This section begins with `known` key word under which all known variables are specified.
- Target variables. This section begins with `target` key word under which all target variables are specified.
- The input file must be ended with a line including the `end` key word.
- The lines starting with `#` character are interpreted as comments.
The following example, represents the overall structure of an input file.
```text
# Sample input file
algebraic relations
X1*X4 + X2*X5 + X1 + X3 + X4
X2*X3 + X1*X6 + X3*X4 + X1
X1*X4 + X1*X5 + X3 + X4 + X6
X5*X6 + X4*X3 + X2
connection relations
X3, X5, X2
X1, X2, X4, X6 => X5
known
X2
target
X1
X3
X4
X5
X6
end
```
You can find many other input files inside the [ciphers](ciphers) folder. Moreover, Autoguess supports system of relations including variables with different weights when the SAT or MILP solvers are used. [Example5](#example-5) and [ZUC](#gd-attack-on-zuc) are two example where the system of relations includes variables with different weights.
---
## Usage
### Command Line Interface
You can access a brief help for Autoguess by running:
```bash
python3 autoguess.py -h
```
```text
usage: autoguess.py [-h] [-i INPUTFILE] [-o OUTPUTFILE] [-mg MAXGUESS] [-ms MAXSTEPS] [-s {cp,milp,sat,smt,groebner,propagate}] [-milpd {min,max}]
[-cps {mip,float,api,osicbc,coinbc,cbc,org.minizinc.mip.coin-bc,coin-bc,org.minizinc.mip.cplex,cplex,org.minizinc.mip.gurobi,gurobi,highs,org.minizinc.mip.highs,cp-sat,cp,lcg,int,org.minizinc.mip.scip,scip,org.minizinc.mip.xpress,xpress}]
[-sats {cadical103,cadical153,cadical195,cryptosat,gluecard3,gluecard4,glucose3,glucose4,glucose42,lingeling,maplechrono,maplecm,maplesat,mergesat3,minicard,minisat22,minisatgh}]
[-smts {btor,cvc5,z3}] [-cpopt {0,1}] [-tl TIMELIMIT] [-tk TIKZ] [-prep PREPROCESS] [-D D] [-tord TERM_ORDERING] [-oln OVERLAPPING_NUMBER] [-cnf2anf {simple,blockwise}]
[-dgl {dot,circo,twopi,fdp,neato,nop,nop1,nop2,osage,patchwork,sfdp}] [-log {0,1}] [--nograph] [--findmin] [--install-minizinc] [-kn KNOWN] [-V]
This tool automates the Guess-and-Determine and Key-Bridging techniques using a variety of CP, MILP, SMT and SAT solvers, as well as the algebraic method based on Groebner basis
options:
-h, --help show this help message and exit
-i, --inputfile INPUTFILE
Use an input file in plain text format
-o, --outputfile OUTPUTFILE
Use an output file to write the output into it
-mg, --maxguess MAXGUESS
An upper bound for the number of guessed variables
-ms, --maxsteps MAXSTEPS
An integer number specifying the depth of search
-s, --solver {cp,milp,sat,smt,groebner,propagate}
Solver choice
-milpd, --milpdirection {min,max}
MILP direction
-cps, --cpsolver {mip,float,api,osicbc,coinbc,cbc,org.minizinc.mip.coin-bc,coin-bc,org.minizinc.mip.cplex,cplex,org.minizinc.mip.gurobi,gurobi,highs,org.minizinc.mip.highs,cp-sat,cp,lcg,int,org.minizinc.mip.scip,scip,org.minizinc.mip.xpress,xpress}
CP solver choice
-sats, --satsolver {cadical103,cadical153,cadical195,cryptosat,gluecard3,gluecard4,glucose3,glucose4,glucose42,lingeling,maplechrono,maplecm,maplesat,mergesat3,minicard,minisat22,minisatgh}
SAT solver choice
-smts, --smtsolver {btor,cvc5,z3}
SMT solver choice
-cpopt, --cpoptimization {0,1}
CP optimization
-tl, --timelimit TIMELIMIT
Time limit for the search in seconds
-tk, --tikz TIKZ Generate the tikz code of the determination flow graph
-prep, --preprocess PREPROCESS
Enable the preprocessing phase
-D, --D D Degree of Macaulay matrix generated in preprocessing phase
-tord, --term_ordering TERM_ORDERING
Term ordering such as 'degrevlex' or 'deglex'
-oln, --overlapping_number OVERLAPPING_NUMBER
Overlapping number in block-wise CNF to ANF conversion
-cnf2anf, --cnf_to_anf_conversion {simple,blockwise}
CNF to ANF conversion method
-dgl, --dglayout {dot,circo,twopi,fdp,neato,nop,nop1,nop2,osage,patchwork,sfdp}
Layout of determination flow graph
-log, --log {0,1} Store intermediate generated files and results
--nograph Skip generating the determination flow graph (faster)
--findmin Iteratively decrease max_guess to find the minimum number of guesses (SAT/SMT only)
--install-minizinc Download and install MiniZinc binary to ~/.autoguess/minizinc/
-kn, --known KNOWN Comma-separated list of initially known variables (for 'propagate' solver)
-V, --version show program's version number and exit
```
Here we also provide some examples to show how our tool can easily be used to find a minimal guess basis.
### Example 1
In this example, given a system of symmetric relations we use Autoguess to find a minimal guess basis. The input file of this example is located in [Example1](./ciphers/Example1/relationfile.txt) which includes the following content:
```text
connection relations
x, s, v
x, u, s, y, z
v, u, s
z, s, v, t
u, t, x
end
```
***CP***
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver cp --maxsteps 5 --dglayout circo
```
Terminal output:
```text
Number of guessed variables is set to be at most 7
============================================================
CP SOLVER — Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
============================================================
Variables: 7 | Relations: 5
Max guess: 7 | Max steps: 5
Solver: cp-sat
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
CP model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.29 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (2):
v
u
============================================================
```
Autoguess also generates the following graph visualizing the determination flow:

***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver groebner
```
Terminal output:
```text
============================================================
GRÖBNER BASIS SOLVER — Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
============================================================
Variables: 7 | Relations: 5
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 7 variables ...
Ring constructed in 0.00 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.00 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
ANF representation generated in 0.00 seconds
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
------------------------------------------------------------
Guessed variable(s) (2):
u
y
============================================================
```
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver sat --maxguess 2 --maxsteps 5
```
Terminal output:
```text
============================================================
SAT SOLVER — Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
============================================================
Variables: 7 | Relations: 5
Max guess: 2 | Max steps: 5
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (2):
x
s
============================================================
```
Now, we try to find the minimum number of guesses by using the `--findmin` switch. This will reduce the optimization problem (COP) into a sequence of decision problems (CSP) and solve them using SAT solvers. So, it may take more time to find the minimum number of guesses compared to finding some bounds on the number of guesses using SAT solvers.
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver sat --findmin
```
Terminal output:
```text
FIND-MIN MODE: searching for minimum guesses (starting from 7)
============================================================
max_guess = 7: SAT — a guess basis of size 7 exists (0.00s)
max_guess = 6: SAT — a guess basis of size 6 exists (0.00s)
max_guess = 5: SAT — a guess basis of size 5 exists (0.00s)
max_guess = 4: SAT — a guess basis of size 4 exists (0.00s)
max_guess = 3: SAT — a guess basis of size 2 exists (0.00s)
max_guess = 2: SAT — a guess basis of size 2 exists (0.00s)
max_guess = 1: UNSAT (0.00s)
############################################################
FIND-MIN RESULT: minimum number of guesses = 2
Total findmin time: 0.00s
############################################################
Re-solving with max_guess = 2 for detailed output ...
(Note: the timings below are for this single verification
solve only, not for the entire findmin search.)
============================================================
SAT SOLVER — Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
============================================================
Variables: 7 | Relations: 5
Max guess: 2 | Max steps: 7
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 7 / 7
Max steps used: 7
------------------------------------------------------------
Guessed variable(s) (2):
x, s
============================================================
Total findmin search time: 0.00s
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver smt --maxguess 2 --maxsteps 5
```
Terminal output:
```text
============================================================
SMT SOLVER — Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
============================================================
Variables: 7 | Relations: 5
Max guess: 2 | Max steps: 5
Solver: z3
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 0.01 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (2):
x
v
============================================================
```
***MILP***
```sh
python3 autoguess.py --inputfile ciphers/Example1/relationfile.txt --solver milp --maxsteps 5
```
Terminal output:
```text
Generating the MILP model ...
MILP model was generated after 0.00 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg50_ms5_min_5d734ea45aa1173beb95c81f6cbc98.lp
Reading time = 0.00 seconds
: 287 rows, 167 columns, 1084 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 287 rows, 167 columns and 1084 nonzeros (Min)
Model fingerprint: 0x0de8c583
Model has 7 linear objective coefficients
Variable types: 0 continuous, 167 integer (167 binary)
Coefficient statistics:
Matrix range [1e+00, 5e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 5e+01]
Found heuristic solution: objective 7.0000000
Presolve removed 90 rows and 67 columns
Presolve time: 0.01s
Presolved: 197 rows, 100 columns, 802 nonzeros
Variable types: 0 continuous, 100 integer (100 binary)
Root relaxation: objective 2.516199e-02, 119 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 0.02516 0 75 7.00000 0.02516 100% - 0s
H 0 0 2.0000000 0.02516 98.7% - 0s
0 0 1.00000 0 55 2.00000 1.00000 50.0% - 0s
Cutting planes:
Gomory: 2
Cover: 6
Clique: 6
MIR: 2
RLT: 12
BQP: 6
Explored 1 nodes (245 simplex iterations) in 0.02 seconds (0.02 work units)
Thread count was 10 (of 10 available processors)
Solution count 2: 2 7
Optimal solution found (tolerance 1.00e-04)
Best objective 2.000000000000e+00, best bound 2.000000000000e+00, gap 0.0000%
Solving process was finished after 0.02 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (2):
x
v
============================================================
```
***Propagate***
The `propagate` solver does not search for a minimal guess basis. Instead, given a set of initially known variables (via `-kn`), it iteratively deduces new variables using the relations until no further progress can be made. This is useful for quickly checking how far a particular guess set can reach.
```sh
autoguess --inputfile ciphers/Example1/relationfile.txt --solver propagate --known "u,v"
```
Terminal output:
```text
============================================================
Knowledge propagation started - 2026-02-23 22:29:19.842286
Problem: Taken from https://doi.org/10.1007/978-3-642-00862-7_11: Speeding up Collision Search for Byte-Oriented Hash Functions
Total variables: 7
Total relations: 5 (symmetric: 5, implication: 0)
Initially known variables: 2
u, v
============================================================
Iteration 1: learned 1 new variable(s)
s <-- [v, u, s]
Iteration 2: learned 1 new variable(s)
x <-- [x, s, v]
Iteration 3: learned 1 new variable(s)
t <-- [u, t, x]
Iteration 4: learned 1 new variable(s)
z <-- [z, s, v, t]
Iteration 5: learned 1 new variable(s)
y <-- [x, u, s, y, z]
============================================================
PROPAGATION SUMMARY
============================================================
Total iterations: 5
Initially known: 2
Newly learned: 5
Total known after prop.: 7 / 7
Unreachable variables: 0
Target variables covered: 7 / 7
Elapsed time: 0.0001 seconds
============================================================
```
### Example 2
In this example we specify a subset of variables as the target and known variables. Note that, if you don't specify any target variable, Autoguess considers all variables as the target variables. You can find the input file of this example in [Example2](./ciphers/Example2) which includes the following contents:
```text
connection relations
u, v, x, y, z
u, w, y, z
w, x, y, z
u, w, z
u, w => t
t, z, v
target
u
v
x
known
w
end
```
***CP***
```sh
python3 autoguess.py --inputfile ciphers/Example2/example2.txt --solver cp --maxsteps 5 --dglayout circo
```
Terminal output:
```text
Number of guessed variables is set to be at most 7
============================================================
CP SOLVER — Example of our paper
============================================================
Variables: 7 | Relations: 6
Max guess: 7 | Max steps: 5
Solver: cp-sat
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
CP model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.27 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
u
============================================================
```

***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/Example2/example2.txt --solver groebner
```
Terminal output:
```text
============================================================
GRÖBNER BASIS SOLVER — Example of our paper
============================================================
Variables: 7 | Relations: 6
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 7 variables ...
Ring constructed in 0.00 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.00 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
ANF representation generated in 0.00 seconds
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
------------------------------------------------------------
Guessed variable(s) (1):
x
============================================================
```
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example2/example2.txt --solver sat --maxguess 1 --maxsteps 5
```
Terminal output:
```text
============================================================
SAT SOLVER — Example of our paper
============================================================
Variables: 7 | Relations: 6
Max guess: 1 | Max steps: 5
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
u
============================================================
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/Example2/example2.txt --solver smt --maxguess 1 --maxsteps 5
```
Terminal output:
```text
============================================================
SMT SOLVER — Example of our paper
============================================================
Variables: 7 | Relations: 6
Max guess: 1 | Max steps: 5
Solver: z3
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 0.01 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
z
============================================================
```
***MILP***
```sh
python3 autoguess.py --inputfile ciphers/Example2/example2.txt --solver milp --maxsteps 5
```
Terminal output:
```text
Generating the MILP model ...
MILP model was generated after 0.00 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg50_ms5_min_493b0329677a8e4da2a20c8408b175.lp
Reading time = 0.00 seconds
: 308 rows, 177 columns, 1200 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 308 rows, 177 columns and 1200 nonzeros (Min)
Model fingerprint: 0xbd74212b
Model has 6 linear objective coefficients
Variable types: 0 continuous, 177 integer (177 binary)
Coefficient statistics:
Matrix range [1e+00, 6e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 5e+01]
Found heuristic solution: objective 6.0000000
Presolve removed 215 rows and 130 columns
Presolve time: 0.00s
Presolved: 93 rows, 47 columns, 352 nonzeros
Variable types: 0 continuous, 47 integer (47 binary)
Root relaxation: objective 1.269841e-01, 39 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 0.12698 0 30 6.00000 0.12698 97.9% - 0s
H 0 0 3.0000000 0.12698 95.8% - 0s
H 0 0 1.0000000 0.12698 87.3% - 0s
0 0 0.12698 0 30 1.00000 0.12698 87.3% - 0s
Explored 1 nodes (41 simplex iterations) in 0.01 seconds (0.01 work units)
Thread count was 10 (of 10 available processors)
Solution count 3: 1 3 6
Optimal solution found (tolerance 1.00e-04)
Best objective 1.000000000000e+00, best bound 1.000000000000e+00, gap 0.0000%
Solving process was finished after 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 7 / 7
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
z
============================================================
```
### Example 3
In this example, we show the application of Autoguess to discover the possible early abortion techniques. The input file of this example is located in [Example3](./ciphers/Example3/relationfile.txt) which includes the following contents:
```text
# Example to describe the early abortion technique
# (x0 <<< 3) + S(x1) + x2 = 0
# S(x0) + S(x2) + (x5 <<< 2) = 0
# L(x1 + x2) + x5 = 0
# x2 + L(x3) = 0
# S(x3 * S(x1 * x4)) + L(x0) + x6 = 0
# (S(x4) xor L(x6)) + x3 = 0
connection relations
x0, x1, x2
x0, x2, x5
x1, x2, x5
x2, x3
x3, x1, x4 => t
t, x0, x6
x4, x6, x3
#known
#x0
#x4
#x5
end
```
We emphasize that the lines starting with `#` are considered as comments.
***CP***
```sh
python3 autoguess.py --inputfile ciphers/Example3/relationfile.txt --solver cp --maxguess 5
```
Terminal output:
```text
============================================================
CP SOLVER — Example to describe the early abortion technique
============================================================
Variables: 8 | Relations: 7
Max guess: 5 | Max steps: 5
Solver: cp-sat
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
CP model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.20 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (3):
x1
x5
t
============================================================
```
The following graph represents the determination flow in the discovered GD attack.

The full content of the output file generated by Autoguess is as follows which includes many useful information guiding the user to find possible early abortion techniques:
```text
Number of relations: 7
Number of variables: 8
Number of target variables: 8
Number of known variables: 0
Number of guessed variables: 3
Number of state copies (max_steps): 5
An upper bound for the number of guessed variables given by user (max_guess): 5
8 out of 8 state variables are known after 5 state copies
############################################################
The following 3 variable(s) are guessed:
x1, x5, t
############################################################
The following 0 variable(s) are initially known:
############################################################
Target variables:
x0, x1, x2, x5, x3, x4, t, x6
############################################################
Determination flow:
State 0:
x1, x5 in symmetric relation [x1, x2, x5] are known: x1, x5 ===> x2
############################################################
State 1:
x1, x2 in symmetric relation [x0, x1, x2] are known: x1, x2 ===> x0
x2, x5 in symmetric relation [x0, x2, x5] are known: x2, x5 ===> x0
x2 in symmetric relation [x2, x3] are known: x2 ===> x3
############################################################
State 2:
t, x0 in symmetric relation [t, x0, x6] are known: t, x0 ===> x6
############################################################
State 3:
x6, x3 in symmetric relation [x4, x6, x3] are known: x6, x3 ===> x4
############################################################
The following variables are known in final state:
x0, x1, x2, x5, x3, x4, t, x6
############################################################
The following relations have not been used in determination (they might be used to check the correctness of guesses):
x3, x1, x4 => t
############################################################
The following variables can be deduced from multiple paths:
x0 can be deduced from:
x0, x1, x2
x0, x2, x5
```
The first lines give a brief description of the input. The main body, describes how the remaining variables can be deduced from the guessed variables. As you can see, three steps (state copies) are sufficient to determine all of the variables. According to the last two lines of the output files, `x0` can be deduced from two different equations, i.e., `(x0 <<< 3) + S(x1) + x2 = 0` and `S(x0) + S(x2) + (x5 <<< 2) = 0`. By the way, according to the determination flow, `x0` is determined before guessing `t`. Hence, a portion of wrong values for the two guessed variables, namely, `x1, x5` can be detected and excluded from the search space before guessing `x0` which results in a GD attack with less time complexity by a factor of `2^|x0|`.
***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/Example3/relationfile.txt --solver groebner
```
Terminal output:
```text
============================================================
GRÖBNER BASIS SOLVER — Example to describe the early abortion technique
============================================================
Variables: 8 | Relations: 7
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 8 variables ...
Ring constructed in 0.00 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.00 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
ANF representation generated in 0.00 seconds
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
------------------------------------------------------------
Guessed variable(s) (3):
x0
x1
x2
============================================================
```
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example3/relationfile.txt --solver sat --maxguess 3 --maxsteps 3
```
Terminal output:
```text
============================================================
SAT SOLVER — Example to describe the early abortion technique
============================================================
Variables: 8 | Relations: 7
Max guess: 3 | Max steps: 3
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 3
------------------------------------------------------------
Guessed variable(s) (3):
x3
x4
t
============================================================
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/Example3/relationfile.txt --solver smt --smtsolver z3 --maxguess 3 --maxsteps 3
```
Terminal output:
```text
============================================================
SMT SOLVER — Example to describe the early abortion technique
============================================================
Variables: 8 | Relations: 7
Max guess: 3 | Max steps: 3
Solver: z3
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 0.01 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 3
------------------------------------------------------------
Guessed variable(s) (3):
x1
x2
x4
============================================================
```
***MILP***
```sh
python3 autoguess.py --inputfile ciphers/Example3/relationfile.txt --solver milp --maxsteps 3
```
Terminal output:
```text
Generating the MILP model ...
MILP model was generated after 0.00 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg50_ms3_min_c74688273c88de841250efd06ea0d9.lp
Reading time = 0.00 seconds
: 176 rows, 110 columns, 574 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 176 rows, 110 columns and 574 nonzeros (Min)
Model fingerprint: 0x7dfef622
Model has 8 linear objective coefficients
Variable types: 0 continuous, 110 integer (110 binary)
Coefficient statistics:
Matrix range [1e+00, 5e+00]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 5e+01]
Found heuristic solution: objective 8.0000000
Presolve removed 94 rows and 66 columns
Presolve time: 0.00s
Presolved: 82 rows, 44 columns, 286 nonzeros
Variable types: 0 continuous, 44 integer (44 binary)
Root relaxation: objective 4.130435e-01, 49 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 0.41304 0 29 8.00000 0.41304 94.8% - 0s
H 0 0 3.0000000 0.41304 86.2% - 0s
0 0 1.14286 0 28 3.00000 1.14286 61.9% - 0s
0 0 2.00000 0 31 3.00000 2.00000 33.3% - 0s
Cutting planes:
Gomory: 4
Cover: 19
Clique: 6
MIR: 1
Zero half: 3
RLT: 14
Relax-and-lift: 5
Explored 1 nodes (110 simplex iterations) in 0.02 seconds (0.01 work units)
Thread count was 10 (of 10 available processors)
Solution count 2: 3 8
Optimal solution found (tolerance 1.00e-04)
Best objective 3.000000000000e+00, best bound 3.000000000000e+00, gap 0.0000%
Solving process was finished after 0.02 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 3
------------------------------------------------------------
Guessed variable(s) (3):
x0
x5
t
============================================================
```
### Example 4
In this example, we aim to show the advantage of preprocessing phase when some algebraic relations are included in the input file. The input file of this example which is located in [Example4](./ciphers/Example4/algebraic_relations.txt) includes the following quadratic equations over `GF(2)`:
```text
algebraic relations
X1*X3 + X2*X4 + X1 + X3 + X4
X2*X3 + X1*X4 + X3*X4 + X1 + X2 + X4
X2*X4 + X3*X4 + X1 + X3 + 1
X1*X2 + X1*X3 + X2*X3 + X3 + X4 + 1
X1*X2 + X2*X3 + X1*X4 + X3
X1*X3 + X1*X4 + X3*X4 + X1 + X2 + X3 + X4
X1*X2 + X2*X4 + X1 + 1
end
```
***CP***
The preprocessor of Autoguess is enabled by default and to disable it you can use `--preprocess 0` in front of your command when you call Autoguess. To adjust the degree of preprocessing phase you can use this switch `--D `. For example in the following command, we apply the preprocessing phase of Autoguess with degree of 2.
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver cp --maxsteps 10 --preprocess 1 --D 2 --dglayout circo
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 7 by 11 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:44:51.835018
#Dependent variables: 7
#Free variables: 3
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_676e0e7043290f519ee6de0bac1b84.txt - 2026-02-23 22:44:51.835115
Result was written into temp/macaulay_basis_676e0e7043290f519ee6de0bac1b84.txt after 0.00 seconds
Preprocessing finished in 1.4718 seconds
Number of guessed variables is set to be at most 10
============================================================
CP SOLVER — gdproblem
============================================================
Variables: 10 | Relations: 19
Max guess: 10 | Max steps: 10
Solver: cp-sat
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
CP model generated in 0.01 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.26 seconds
============================================================
RESULTS
============================================================
Number of guesses: 2
Known in final state: 10 / 10
Max steps used: 10
------------------------------------------------------------
Guessed variable(s) (2):
X2
X4
============================================================
```

Next, we call Autoguess with preprocessing of degree 3 to get a better result.
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver cp --maxsteps 10 --preprocess 1 --D 3 --dglayout circo
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 35 by 15 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:46:12.429585
#Dependent variables: 13
#Free variables: 1
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_88e597205e4bd22daf4ee4c083f4dc.txt - 2026-02-23 22:46:12.429697
Result was written into temp/macaulay_basis_88e597205e4bd22daf4ee4c083f4dc.txt after 0.00 seconds
Preprocessing finished in 1.5163 seconds
Number of guessed variables is set to be at most 14
============================================================
CP SOLVER — gdproblem
============================================================
Variables: 14 | Relations: 24
Max guess: 14 | Max steps: 10
Solver: cp-sat
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
CP model generated in 0.01 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.30 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 14 / 14
Max steps used: 10
------------------------------------------------------------
Guessed variable(s) (1):
X2
============================================================
```

The [Tikz](https://en.wikibooks.org/wiki/LaTeX/PGF/TikZ) code of the determination graph can also be generated by putting `--tikz 1` in front of your command when you call Autoguess.
***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver groebner --preprocess 1 --D 3
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 35 by 15 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:47:05.293590
#Dependent variables: 13
#Free variables: 1
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_7f40767192abe937548909a93544f6.txt - 2026-02-23 22:47:05.293753
Result was written into temp/macaulay_basis_7f40767192abe937548909a93544f6.txt after 0.00 seconds
Preprocessing finished in 0.0808 seconds
============================================================
GRÖBNER BASIS SOLVER — gdproblem
============================================================
Variables: 14 | Relations: 24
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 14 variables ...
Ring constructed in 0.00 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.00 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
ANF representation generated in 0.00 seconds
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
------------------------------------------------------------
Guessed variable(s) (1):
X3
============================================================
```
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver sat --maxguess 1 --maxsteps 5 --preprocess 1 --D 3
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 35 by 15 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:47:55.291771
#Dependent variables: 13
#Free variables: 1
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_c918ac2c862f0bfbd05f830067a239.txt - 2026-02-23 22:47:55.291903
Result was written into temp/macaulay_basis_c918ac2c862f0bfbd05f830067a239.txt after 0.00 seconds
Preprocessing finished in 1.5456 seconds
============================================================
SAT SOLVER — gdproblem
============================================================
Variables: 14 | Relations: 24
Max guess: 1 | Max steps: 5
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 14 / 14
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
X2
============================================================
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver smt --maxguess 1 --maxsteps 5 --preprocess 1 --D 3
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 35 by 15 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:48:10.731367
#Dependent variables: 13
#Free variables: 1
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_41304864ec176a77963f8daabe4832.txt - 2026-02-23 22:48:10.731486
Result was written into temp/macaulay_basis_41304864ec176a77963f8daabe4832.txt after 0.00 seconds
Preprocessing finished in 1.6922 seconds
============================================================
SMT SOLVER — gdproblem
============================================================
Variables: 14 | Relations: 24
Max guess: 1 | Max steps: 5
Solver: z3
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 0.03 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 14 / 14
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
VULX1x3 (represents: X2 * X4)
============================================================
```
***MILP***
```sh
python3 autoguess.py --inputfile ciphers/Example4/algebraic_relations.txt --solver milp --maxsteps 5 --preprocess 1 --D 3
```
Terminal output:
```text
------------------------------------------------------------
PREPROCESSING (Macaulay matrix)
------------------------------------------------------------
Number of algebraic equations: 7
Number of algebraic variables: 4
Number of algebraic monomials: 11
Spectrum of degrees: [2]
Macaulay matrix was generated in full matrixspace of 35 by 15 sparse matrices over finite field of size 2
Gaussian elimination was started - 2026-02-23 22:48:29.854185
#Dependent variables: 13
#Free variables: 1
Gaussian elimination was finished after 0.00 seconds
Writing the results into the temp/macaulay_basis_170a23f2bde01f3bbf6fb967d3c415.txt - 2026-02-23 22:48:29.854295
Result was written into temp/macaulay_basis_170a23f2bde01f3bbf6fb967d3c415.txt after 0.00 seconds
Preprocessing finished in 1.6932 seconds
Generating the MILP model ...
MILP model was generated after 0.00 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg50_ms5_min_11d3a43ee22ec0813703f97835cb8d.lp
Reading time = 0.00 seconds
: 728 rows, 444 columns, 3268 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 728 rows, 444 columns and 3268 nonzeros (Min)
Model fingerprint: 0xc1841a82
Model has 8 linear objective coefficients
Variable types: 0 continuous, 444 integer (444 binary)
Coefficient statistics:
Matrix range [1e+00, 1e+01]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 5e+01]
Found heuristic solution: objective 8.0000000
Presolve removed 687 rows and 417 columns
Presolve time: 0.01s
Presolved: 41 rows, 27 columns, 208 nonzeros
Variable types: 0 continuous, 27 integer (27 binary)
Found heuristic solution: objective 7.0000000
Root relaxation: objective 1.000000e+00, 1 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
* 0 0 0 1.0000000 1.00000 0.00% - 0s
Explored 1 nodes (1 simplex iterations) in 0.01 seconds (0.01 work units)
Thread count was 10 (of 10 available processors)
Solution count 3: 1 7 8
Optimal solution found (tolerance 1.00e-04)
Best objective 1.000000000000e+00, best bound 1.000000000000e+00, gap 0.0000%
Solving process was finished after 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 1
Known in final state: 14 / 14
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (1):
AADO0x2x3 (represents: X1 * X3 * X4)
============================================================
```
### Example 5
In this example, we show how to build an input file consisting of variables with different weights. The input file of this example is located in [Example5](./ciphers/Example5/example5.txt) which includes the following contents:
```text
connection relations
x0, x1, x2
x0, x2, x5
x1, x2, x5
x2, x3
x3, x1, x4 => t
t, x0, x6
x4, x6, x3
weights
x0 1
x1 2
x2 1
x3 3
x4 1
x5 2
x6 3
t 2
end
```
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example5/example5.txt --solver sat --maxguess 3 --maxsteps 5 --dglayout circo
```
Terminal output:
```text
============================================================
SAT SOLVER — gdproblem
============================================================
Variables: 8 | Relations: 7
Max guess: 3 | Max steps: 5
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.00 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.00 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 5
------------------------------------------------------------
Guessed variable(s) (3):
x0
x2
x4
============================================================
```
As it can be seen, the variables with minimum weights have been chosen as the guess basis.

***MILP***
```sh
python3 autoguess.py --inputfile ciphers/Example5/example5.txt --solver milp --maxsteps 3
```
Terminal output:
```text
Generating the MILP model ...
MILP model was generated after 0.00 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg50_ms3_min_9b386bd93e4ea29a7a452cd33c9180.lp
Reading time = 0.00 seconds
: 176 rows, 110 columns, 574 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 176 rows, 110 columns and 574 nonzeros (Min)
Model fingerprint: 0xaa75b0d7
Model has 8 linear objective coefficients
Variable types: 0 continuous, 110 integer (110 binary)
Coefficient statistics:
Matrix range [1e+00, 5e+00]
Objective range [1e+00, 3e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 5e+01]
Found heuristic solution: objective 15.0000000
Presolve removed 94 rows and 66 columns
Presolve time: 0.00s
Presolved: 82 rows, 44 columns, 286 nonzeros
Variable types: 0 continuous, 44 integer (44 binary)
Root relaxation: objective 4.503817e-01, 49 iterations, 0.00 seconds (0.00 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 0.45038 0 30 15.00000 0.45038 97.0% - 0s
H 0 0 6.0000000 0.45038 92.5% - 0s
H 0 0 4.0000000 0.45038 88.7% - 0s
H 0 0 3.0000000 0.45038 85.0% - 0s
Cutting planes:
Gomory: 1
Cover: 4
Clique: 4
MIR: 2
Flow cover: 2
Zero half: 2
RLT: 11
Relax-and-lift: 2
Explored 1 nodes (53 simplex iterations) in 0.01 seconds (0.00 work units)
Thread count was 10 (of 10 available processors)
Solution count 4: 3 4 6 15
Optimal solution found (tolerance 1.00e-04)
Best objective 3.000000000000e+00, best bound 3.000000000000e+00, gap 0.0000%
Solving process was finished after 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 3
Known in final state: 8 / 8
Max steps used: 3
------------------------------------------------------------
Guessed variable(s) (3):
x0
x2
x4
============================================================
```
### Example 6
In this example, we try to analyze a toy stream cipher which its keystream generation phase works based on the following state machine:
```text
for i = 0 ... N:
x_0_i+1 <--- f0(x_6_i, x_7_i <<< 16)
x_1_i+1 <--- f1(x_7_i, x_0_i <<< 8)
x_2_i+1 <--- f2(x_0_i, x_1_i <<< 16)
x_3_i+1 <--- f3(x_1_i, x_2_i <<< 8)
x_4_i+1 <--- f4(x_2_i, x_3_i <<< 16)
x_5_i+1 <--- f5(x_3_i, x_4_i <<< 8)
x_6_i+1 <--- f6(x_4_i, x_5_i <<< 16)
x_7_i+1 <--- f7(x_5_i, x_6_i <<< 8)
z_i+1 <--- g(x_7_i, x_2_i)
```
where `f0, ..., f7`, and `g` are some functions. The following shape represnts how the state machine of this toy stream cipher works.

Assuming that the output words, i.e., `z_i` for `i = 1, 2, ...` are known, we aim to find the minimum number of guessed variables to retrieve the initial state, namely, `x_0_0, x_1_0, ..., x_7_0`.
***SAT***
```sh
python3 autoguess.py --inputfile ciphers/Example6/relationfile_rabit_9clk_mg6_ms22.txt --solver sat --maxguess 6 --maxsteps 12 --tikz 1
```
Terminal output:
```text
============================================================
SAT SOLVER — rabit 9 clock cycles
============================================================
Variables: 88 | Relations: 80
Max guess: 6 | Max steps: 12
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.05 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.81 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
Known in final state: 88 / 88
Max steps used: 12
------------------------------------------------------------
Guessed variable(s) (6):
x_5_1
x_4_0
x_6_1
x_0_2
x_1_2
x_0_3
============================================================
Generating the tikz code ...
```

***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/Example6/relationfile_rabit_9clk_mg6_ms22.txt --solver groebner
```
Terminal output:
```text
============================================================
GRÖBNER BASIS SOLVER — rabit 9 clock cycles
============================================================
Variables: 88 | Relations: 80
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 88 variables ...
Ring constructed in 0.00 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.00 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
ANF representation generated in 0.00 seconds
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 0.86 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
------------------------------------------------------------
Guessed variable(s) (6):
x_0_3
x_4_4
x_6_6
x_3_7
x_2_8
x_3_8
============================================================
```
---
## Troubleshooting
### Common Issues
#### Docker Issues
- **Permission denied**: On Linux, you may need to run Docker commands with `sudo` or add your user to the docker group
- **Platform issues on ARM64**: Always use `--platform linux/amd64` flag for Apple Silicon Macs
- **Out of memory**: For large problems, increase Docker memory limits in Docker Desktop settings
#### Missing Dependencies
- **ModuleNotFoundError**: If running natively, ensure all dependencies are installed.
- **Solver not found**: Some solvers require separate installation (e.g., Gurobi requires a license)
- **MiniZinc not found**: Install MiniZinc following the instructions in Method 3
#### Input File Issues
- **File format**: Ensure your input file follows the correct format as described in the [Format of Input File](#format-of-input-file) section
- **Path issues**: Use absolute paths or ensure files are in the correct relative location
- **Syntax errors**: Check that your algebraic and connection relations are properly formatted
### Performance Tips
- **Large problems**: Use the `--timelimit` parameter to set reasonable time bounds
- **Solver selection**: Different solvers perform better on different types of problems. So try different solvers if you encounter performance issues.
- **Guess bounds**: If you are looking for some bounds on the number of guesses, use `--maxguess ` to limit the number of guesses and use SAT solvers.
- **Preprocessing**: If the input relations include algebraic relations, use preprocessing phase with `--preprocess 1` and `--D ` to derive new relations (using Macaulay matrix) and set the solver to one of the many available solvers, e.g., `--solver sat` or `--solver cp`, or `--solver groebner`.
- **Minimization problem**: If you want to find the minimum number of guesses, use `--solver cp` or `--solver milp` to solve the problem as a constraint optimization problem or a mixed-integer linear programming problem, respectively. However, the optimization problem (COP) may take longer to solve compared to finding a bound on the number of guesses using SAT solvers (that is a CSP or SAT problem). You may want to reduce the optimization problem (COP) into a sequence of decision problems (CSP) by using `--maxsteps ` to limit the number of steps in the search space.
- **Maximization problem**: Since the first version of Autoguess, it is possible to find the maximum number of determined variables in the final state given a set of variables/relations in which a subset of variables are already known (or guessed). This feature is avaialble when using the MILP solvers. To determine the direction of optimization, you can use the `--milpd ` switch to set the direction of optimization to `max` or `min`. The default value is `min` to find minimal guess basis.
### Getting Help
If you encounter issues:
1. Check the [GitHub Issues](https://github.com/hadipourh/autoguess/issues) page
2. Refer to the comprehensive examples in this README
3. Contact the author at hsn.hadipour@gmail.com
---
## Applications
The following sections include some of the applications of our tool running on a laptop with the following configuration:
```text
OS: macOS 15.7.4 (arm64)
CPU: Apple M4
RAM: 24 GB
```
### GD Attack on 1 Round of AES with 1 Known Plaintext/Ciphertext Pair

***SAT***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_1r_mg6_ms14.txt --solver sat --maxguess 6 --maxsteps 14
```
Terminal outputs:
```text
============================================================
SAT SOLVER — aes1kp 1 Rounds
============================================================
Variables: 96 | Relations: 1168
Max guess: 6 | Max steps: 14
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.08 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
Known in final state: 96 / 96
Max steps used: 14
------------------------------------------------------------
Guessed variable(s) (6):
X_0_0_2, K_0_1_2, X_0_2_0, X_0_3_0, W_0_1_1, K_1_3_1
============================================================
```
As you can see Autoguess finds a GD attack on 1 round of AES in less than a second. Autoguess uses [CaDiCaL](http://fmv.jku.at/cadical153/) as the SAT solver by default. However, user can simply choose another SAT solver among `cadical153,glucose3,glucose4,lingeling,maplechrono,maplecm,maplesat,minicard,minisat22,minisat-gh` by this switch : `--satsolver SAT_SOLVER_NAME`.
Now, we try to find the minimum number of guesses by using the `--findmin` switch. This will reduce the optimization problem (COP) into a sequence of decision problems (CSP) and solve them using SAT solvers. So, it may take more time to find the minimum number of guesses compared to finding some bounds on the number of guesses using SAT solvers.
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_1r_mg6_ms14.txt --solver sat --maxsteps 14 --findmin
```
Terminal outputs:
```text
============================================================
FIND-MIN MODE: searching for minimum guesses (starting from 96)
============================================================
max_guess = 96: SAT — a guess basis of size 64 exists (0.00s)
max_guess = 64: SAT — a guess basis of size 64 exists (0.00s)
max_guess = 63: SAT — a guess basis of size 63 exists (0.00s)
max_guess = 62: SAT — a guess basis of size 62 exists (0.00s)
max_guess = 61: SAT — a guess basis of size 61 exists (0.00s)
max_guess = 60: SAT — a guess basis of size 60 exists (0.00s)
max_guess = 59: SAT — a guess basis of size 59 exists (0.00s)
max_guess = 58: SAT — a guess basis of size 58 exists (0.00s)
max_guess = 57: SAT — a guess basis of size 57 exists (0.00s)
max_guess = 56: SAT — a guess basis of size 56 exists (0.00s)
max_guess = 55: SAT — a guess basis of size 55 exists (0.00s)
max_guess = 54: SAT — a guess basis of size 54 exists (0.00s)
max_guess = 53: SAT — a guess basis of size 53 exists (0.00s)
max_guess = 52: SAT — a guess basis of size 52 exists (0.00s)
max_guess = 51: SAT — a guess basis of size 51 exists (0.00s)
max_guess = 50: SAT — a guess basis of size 50 exists (0.00s)
max_guess = 49: SAT — a guess basis of size 49 exists (0.00s)
max_guess = 48: SAT — a guess basis of size 48 exists (0.00s)
max_guess = 47: SAT — a guess basis of size 47 exists (0.00s)
max_guess = 46: SAT — a guess basis of size 46 exists (0.00s)
max_guess = 45: SAT — a guess basis of size 45 exists (0.00s)
max_guess = 44: SAT — a guess basis of size 44 exists (0.00s)
max_guess = 43: SAT — a guess basis of size 43 exists (0.00s)
max_guess = 42: SAT — a guess basis of size 42 exists (0.00s)
max_guess = 41: SAT — a guess basis of size 41 exists (0.00s)
max_guess = 40: SAT — a guess basis of size 40 exists (0.00s)
max_guess = 39: SAT — a guess basis of size 39 exists (0.00s)
max_guess = 38: SAT — a guess basis of size 38 exists (0.00s)
max_guess = 37: SAT — a guess basis of size 37 exists (0.00s)
max_guess = 36: SAT — a guess basis of size 36 exists (0.00s)
max_guess = 35: SAT — a guess basis of size 35 exists (0.00s)
max_guess = 34: SAT — a guess basis of size 34 exists (0.00s)
max_guess = 33: SAT — a guess basis of size 33 exists (0.00s)
max_guess = 32: SAT — a guess basis of size 32 exists (0.00s)
max_guess = 31: SAT — a guess basis of size 31 exists (0.00s)
max_guess = 30: SAT — a guess basis of size 30 exists (0.00s)
max_guess = 29: SAT — a guess basis of size 29 exists (0.00s)
max_guess = 28: SAT — a guess basis of size 28 exists (0.00s)
max_guess = 27: SAT — a guess basis of size 27 exists (0.00s)
max_guess = 26: SAT — a guess basis of size 26 exists (0.00s)
max_guess = 25: SAT — a guess basis of size 25 exists (0.00s)
max_guess = 24: SAT — a guess basis of size 24 exists (0.00s)
max_guess = 23: SAT — a guess basis of size 23 exists (0.00s)
max_guess = 22: SAT — a guess basis of size 22 exists (0.00s)
max_guess = 21: SAT — a guess basis of size 21 exists (0.00s)
max_guess = 20: SAT — a guess basis of size 20 exists (0.00s)
max_guess = 19: SAT — a guess basis of size 19 exists (0.00s)
max_guess = 18: SAT — a guess basis of size 18 exists (0.00s)
max_guess = 17: SAT — a guess basis of size 17 exists (0.00s)
max_guess = 16: SAT — a guess basis of size 16 exists (0.00s)
max_guess = 15: SAT — a guess basis of size 15 exists (0.00s)
max_guess = 14: SAT — a guess basis of size 14 exists (0.00s)
max_guess = 13: SAT — a guess basis of size 13 exists (0.00s)
max_guess = 12: SAT — a guess basis of size 12 exists (0.00s)
max_guess = 11: SAT — a guess basis of size 9 exists (0.00s)
max_guess = 9: SAT — a guess basis of size 9 exists (0.01s)
max_guess = 8: SAT — a guess basis of size 8 exists (0.00s)
max_guess = 7: SAT — a guess basis of size 7 exists (0.02s)
max_guess = 6: SAT — a guess basis of size 6 exists (0.02s)
max_guess = 5: UNSAT (52.46s)
############################################################
FIND-MIN RESULT: minimum number of guesses = 6
Total findmin time: 52.67s
############################################################
Re-solving with max_guess = 6 for detailed output ...
(Note: the timings below are for this single verification
solve only, not for the entire findmin search.)
============================================================
SAT SOLVER — aes1kp 1 Rounds
============================================================
Variables: 96 | Relations: 1168
Max guess: 6 | Max steps: 14
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.09 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.01 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
Known in final state: 96 / 96
Max steps used: 14
------------------------------------------------------------
Guessed variable(s) (6):
X_0_0_2, K_0_1_2, X_0_2_0, X_0_3_0, W_0_1_1, K_1_3_1
============================================================
Total findmin search time: 52.67s
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_1r_mg6_ms14.txt --solver smt --smtsolver z3 --maxguess 6 --maxsteps 14
```
Terminal output:
```text
============================================================
SMT SOLVER — aes1kp 1 Rounds
============================================================
Variables: 96 | Relations: 1168
Max guess: 6 | Max steps: 14
Solver: btor
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 0.46 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 1.10 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
Known in final state: 96 / 96
Max steps used: 14
------------------------------------------------------------
Guessed variable(s) (6):
X_0_0_0, X_0_0_1, K_0_1_3, K_0_3_1, W_0_1_0, K_1_2_0
============================================================
```
In the above command we have used [Boolector](https://github.com/boolector/boolector) as the SMT solver.
Note that Boolector project has been officially archived in 2024 and is no longer maintained.
***MILP***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_1r_mg6_ms14.txt --solver milp --maxguess 10 --maxsteps 14
```
Terminal outputs:
```text
Generating the MILP model ...
MILP model was generated after 0.02 seconds
Set parameter Username
Set parameter LicenseID to value 2782105
Academic license - for non-commercial use only - expires 2027-02-23
Read LP format model from file temp/milp_mg10_ms14_min_a0f9cf732211135c51793acd11593b.lp
Reading time = 0.04 seconds
: 39458 rows, 20480 columns, 212544 nonzeros
Set parameter MIPFocus to value 0
Set parameter Threads to value 0
Set parameter OutputFlag to value 1
Gurobi Optimizer version 13.0.1 build v13.0.1rc0 (mac64[arm] - Darwin 24.6.0 24G517)
CPU model: Apple M4
Thread count: 10 physical cores, 10 logical processors, using up to 10 threads
Optimize a model with 39458 rows, 20480 columns and 212544 nonzeros (Min)
Model fingerprint: 0x853798bd
Model has 64 linear objective coefficients
Variable types: 0 continuous, 20480 integer (20480 binary)
Coefficient statistics:
Matrix range [1e+00, 4e+01]
Objective range [1e+00, 1e+00]
Bounds range [1e+00, 1e+00]
RHS range [1e+00, 1e+02]
Presolve removed 5093 rows and 3298 columns
Presolve time: 0.48s
Presolved: 34365 rows, 17182 columns, 197325 nonzeros
Variable types: 0 continuous, 17182 integer (17182 binary)
Found heuristic solution: objective 7.0000000
Deterministic concurrent LP optimizer: primal and dual simplex
Showing primal log only...
Concurrent spin time: 0.19s (can be avoided by choosing Method=3)
Solved with primal simplex
Root relaxation: objective 4.241545e-09, 7530 iterations, 1.39 seconds (5.72 work units)
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 0.00000 0 1315 7.00000 0.00000 100% - 2s
H 0 0 6.0000000 0.00000 100% - 11s
0 0 0.00000 0 1619 6.00000 0.00000 100% - 11s
0 0 0.00000 0 1700 6.00000 0.00000 100% - 13s
0 0 0.00000 0 2213 6.00000 0.00000 100% - 19s
0 0 0.00000 0 2213 6.00000 0.00000 100% - 19s
0 0 0.00000 0 2195 6.00000 0.00000 100% - 22s
....
3956 1865 1.73377 34 445 6.00000 1.00000 83.3% 2261 579s
^C (manually interrupted)
Interrupt request received
4037 1849 1.00455 28 931 6.00000 1.00000 83.3% 2301 581s
Explored 4050 nodes (9379254 simplex iterations) in 581.44 seconds (2720.99 work units)
Thread count was 10 (of 10 available processors)
Solution count 2: 6 7
Solve interrupted
Best objective 6.000000000000e+00, best bound 1.000000000000e+00, gap 83.3333%
Solving process was finished after 581.45 seconds
============================================================
RESULTS
============================================================
Number of guesses: 6
Known in final state: 96 / 96
Max steps used: 14
------------------------------------------------------------
Guessed variable(s) (6):
K_0_0_2, K_0_0_3, K_0_1_3, K_0_2_0, W_0_0_2, W_0_3_3
============================================================
```
***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_1r_mg6_ms14.txt --solver groebner --log 1
```
Terminal outputs:
```text
============================================================
GRÖBNER BASIS SOLVER — aes1kp 1 Rounds
============================================================
Variables: 96 | Relations: 1168
Term ordering: degrevlex | Overlapping: 2
CNF→ANF method: simple
------------------------------------------------------------
POLYNOMIAL RING CONSTRUCTION
------------------------------------------------------------
Generating Boolean Polynomial Ring in 96 variables ...
Ring constructed in 0.01 seconds
------------------------------------------------------------
HORN-SAT GENERATION
------------------------------------------------------------
Horn-SAT problem generated in 0.02 seconds
------------------------------------------------------------
CNF → ANF CONVERSION (simple)
------------------------------------------------------------
Results were written into the temp/anf_94efe633bf5f01b2c4d3ab440c347a.anf
ANF representation generated in 0.01 seconds
Main ideal stored at: temp/main_ideal_94efe633bf5f01b2c4d3ab440c347a
------------------------------------------------------------
GRÖBNER BASIS COMPUTATION
------------------------------------------------------------
Gröbner basis computed in 1.07 seconds
All guess bases were written into temp/guess_basis_94efe633bf5f01b2c4d3ab440c347a.txt
============================================================
RESULTS
============================================================
Number of guesses: 6
------------------------------------------------------------
Guessed variable(s) (6):
K_0_0_0
K_0_0_1
K_0_0_2
K_0_0_3
K_0_1_3
K_0_2_3
============================================================
```
If we use the Groebner basis, Autoguess generates multiple minimal guess bases at once and stores them inside the [temp](temp) folder. For example, in the above example, in addition to `[K_1_3_3, K_1_3_2, K_1_3_1, K_1_3_0, K_1_2_0, K_1_1_0]` Autoguess discovered many other minimal guess bases some of which are represented below:
```text
K_1_2_2, K_1_2_1, K_1_1_3, K_1_1_2, K_1_0_0, X_0_1_1
K_1_2_2, K_1_2_1, K_1_1_3, K_1_1_2, K_1_0_0, X_0_3_3
K_1_2_2, K_1_2_1, K_1_1_3, K_1_1_2, K_1_1_0, K_1_0_0
K_1_2_2, K_1_2_1, K_1_2_0, K_1_1_3, K_1_1_2, K_1_0_0
K_1_3_0, K_1_0_3, K_1_0_2, X_0_2_3, X_0_1_2, X_0_0_1
K_1_3_0, K_1_0_3, K_1_0_2, K_1_0_1, X_0_2_3, X_0_1_2
K_1_3_0, K_1_0_3, K_1_0_2, K_1_0_1, K_1_0_0, X_0_1_2
K_1_3_0, K_1_0_3, K_1_0_2, K_1_0_1, K_1_0_0, X_0_2_3
K_1_3_0, K_1_1_1, K_1_0_3, K_1_0_2, X_0_2_3, X_0_0_1
K_1_3_0, K_1_1_1, K_1_0_3, K_1_0_2, K_1_0_1, X_0_2_3
K_1_3_0, K_1_1_1, K_1_0_3, K_1_0_2, K_1_0_1, K_1_0_0
K_1_3_0, K_1_1_2, K_1_1_1, K_1_0_3, K_1_0_2, X_0_0_1
K_1_3_0, K_1_1_2, K_1_1_1, K_1_0_3, K_1_0_2, X_0_2_3
K_1_3_0, K_1_1_2, K_1_1_1, K_1_0_3, K_1_0_2, K_1_0_1
K_1_3_0, K_1_2_0, K_1_1_1, K_1_1_0, K_1_0_1, X_0_2_3
K_1_3_0, K_1_2_0, K_1_1_1, K_1_1_0, K_1_0_1, X_0_3_0
K_1_3_0, K_1_2_0, K_1_1_1, K_1_1_0, K_1_0_2, K_1_0_1
K_1_3_0, K_1_2_0, K_1_1_3, K_1_1_2, K_1_0_0, X_0_0_2
K_1_3_0, K_1_2_0, K_1_1_3, K_1_1_2, K_1_0_1, K_1_0_0
...
...
```
---
### GD Attack on 2 Rounds of AES with 1 Known Plaintext/Ciphertext Pair

***SAT***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_2r_mg10_ms20.txt --solver sat --maxguess 10 --maxsteps 22
```
Terminal output:
```text
============================================================
SAT SOLVER — aes1kp 2 Rounds
============================================================
Variables: 144 | Relations: 2332
Max guess: 10 | Max steps: 22
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.24 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 7.08 seconds
============================================================
RESULTS
============================================================
Number of guesses: 10
Known in final state: 144 / 144
Max steps used: 22
------------------------------------------------------------
Guessed variable(s) (10):
K_0_1_0, K_0_3_2, W_0_0_2, K_1_1_3, X_1_2_0, W_0_2_3, K_1_3_3, X_1_3_3, W_1_2_2, W_1_3_2
============================================================
```
***SMT***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_2r_mg10_ms20.txt --solver smt --smtsolver z3 --maxguess 10 --maxsteps 20
```
Terminal output:
```text
============================================================
SMT SOLVER — aes1kp 2 Rounds
============================================================
Variables: 144 | Relations: 2332
Max guess: 10 | Max steps: 20
Solver: z3
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SMT model generated in 2.24 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 37.80 seconds
============================================================
RESULTS
============================================================
Number of guesses: 10
Known in final state: 144 / 144
Max steps used: 20
------------------------------------------------------------
Guessed variable(s) (10):
K_0_2_1, X_1_0_2, X_1_1_0, W_0_1_3, X_1_2_0, K_1_3_3, X_1_3_3, W_1_0_2, W_1_0_3, W_1_3_2
============================================================
```
***Groebner***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_2r_mg10_ms20.txt --solver groebner --overlapping_number 100
```
Terminal output:
```text
(This output is from the old version of Autoguess running on a different machine: OS: Linux 5.4.0-84-generic - Ubuntu, CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz, RAM: 16 GB)
Generating the Boolean Polynomial Ring in 144 variables
Generation of the Boolean polynomial ring was finished after 0.03 seconds
CNF to ANF conversion using the block-wise method was started - 2021-04-03 12:22:23.463899
Results were written into the temp/anf_b55c6bf2574c3b718107cafd93e211.anf
Algebraic representation in ANF form was generated after 220.32 seconds
Computing the Groebner basis was started - 2021-04-03 12:26:03.802563
Computing the Groebner basis was finished after 36356.55 seconds
Number of guesses: 10
The following 10 variable(s) are guessed:
K_2_3_3, K_2_3_2, K_2_3_0, K_2_2_3, K_2_2_2, K_2_2_1, K_2_1_3, K_2_1_2, K_2_0_3, K_2_0_2
```
---
### GD Attack on 3 Rounds of AES with 1 Known Plaintext/Ciphertext Pair

***SAT***
```sh
python3 autoguess.py --inputfile ciphers/AES/relationfile_aes1kp_3r_mg15_ms22.txt --solver sat --maxguess 15 --maxsteps 22
```
Terminal output:
```text
============================================================
SAT SOLVER — aes1kp 3 Rounds
============================================================
Variables: 192 | Relations: 3472
Max guess: 15 | Max steps: 22
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.44 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 37.86 seconds
============================================================
RESULTS
============================================================
Number of guesses: 15
Known in final state: 192 / 192
Max steps used: 22
------------------------------------------------------------
Guessed variable(s) (15):
X_0_2_2, W_0_3_0, K_2_0_0, X_2_0_0, K_2_1_0, K_2_1_2, K_2_2_0, K_2_2_1, X_2_3_1, X_2_3_2, K_3_1_0, W_2_1_2, W_2_1_3, W_2_2_3, W_2_3_3
============================================================
```
---
### GD Attack on 14 Rounds of Khudra with 1 Known Plaintext/Ciphertext Pair

***SAT***
Solving with [Lingeling](https://github.com/arminbiere/lingeling).
```sh
python3 autoguess.py --inputfile ciphers/Khudra/relationfile_khudra_alternative_14r_mg4_ms16.txt --solver sat --satsolver lingeling --maxguess 4 --maxsteps 16
```
Terminal output:
```text
============================================================
SAT SOLVER — khudra_alternative 14 Rounds
============================================================
Variables: 70 | Relations: 61
Max guess: 4 | Max steps: 16
Solver: lingeling
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.04 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.65 seconds
============================================================
RESULTS
============================================================
Number of guesses: 4
Known in final state: 70 / 70
Max steps used: 16
------------------------------------------------------------
Guessed variable(s) (4):
x_3_3
x_12_1
x_13_2
x_14_3
============================================================
```
Solving with [CaDiCaL](https://github.com/arminbiere/cadical153).
```sh
python3 autoguess.py --inputfile ciphers/Khudra/relationfile_khudra_alternative_14r_mg4_ms16.txt --solver sat --satsolver cadical153 --maxguess 4 --maxsteps 16
```
Terminal output:
```text
============================================================
SAT SOLVER — khudra_alternative 14 Rounds
============================================================
Variables: 70 | Relations: 61
Max guess: 4 | Max steps: 16
Solver: cadical153
------------------------------------------------------------
MODEL GENERATION
------------------------------------------------------------
SAT model generated in 0.03 seconds
------------------------------------------------------------
SOLVING
------------------------------------------------------------
Solving finished in 0.61 seconds
============================================================
RESULTS
============================================================
Number of guesses: 4
Known in final state: 70 / 70
Max steps used: 16
------------------------------------------------------------
Guessed variable(s) (4):
x_2_0
x_12_1
x_13_2
x_14_3
============================================================
```
***SMT***
Solving via [cvc5](https://cvc5.github.io):
```sh
python3 autoguess.py --inputfile ciphers/Khudra/relationfile_khudra_alternative_14r_mg4_ms16.txt --solver smt --smtsolver cvc5 --maxguess 4 --maxsteps 16
```
Terminal output:
```text
===============================================