MTLsim
A simulator for MTL mode in DNSSEC.
Installation
Option 1: Nix Flake (recommended)
Install Nix from the NixOS website and run:
nix shell github:malmeloo/mtlsim
This will build the simulator and drop you in a shell where the mtlsim command is available.
Option 2: Python / UV
Install UV, clone the repository and run the simulator with:
uv run mtlsim
Only Python 3.13+ is officially supported.
Usage
The simulator workflow looks like this:
- Ingest zone and query events, convert into JSONL format;
- Run the simulation with the ingested data;
- Analyze the results.
Ingest zone events
mtlsim comes with a set of CLI commands to ingest and generate zone and query data from various sources. To view all commands, run mtlsim --help.
Zone input data is expected to be in JSONL format:
{"timestamp":"2026-07-20T05:00:00","removed":[],"added":[["example", "DS"], ["example", "NSEC3"]]}
{"timestamp":"2026-07-20T06:00:00","removed":[["example", "DS"]],"added":[["example", "NSEC3"]]}
"added" and "removed" are lists of tuples indicating RRSIG records, where each tuple contains a domain name and a record type. "added" contains RRSIGs that were added or updated, while "removed" contains RRSIGs that were removed.
Ingest query events
Query / resolver input data is also expected to be in JSONL format:
{"timestamp":"2026-07-20T05:00:00","type": "given", "query_name": "example", "query_type": "DS"}
{"timestamp":"2026-07-20T05:00:01","type": "given", "query_name": "example", "query_type": "DS"}
Several fields are available for query events:
- given: the event contains the query name and type
- random: the event contains a record type, and the query name is randomly generated from the zone
- random_seeded: same as random, but the random generator is seeded for reproducibility
type: Literal["given", "random", "random_seeded"] = "given"
query_name: str | None
query_type: str | None
seed: str | None
Simulation
Example command to run a simulation:
mtlsim simulate --zone-input inputs/nl/zone.jsonl --query-input inputs/nl/resolver_1.jsonl --strategy single_inf --tag nl-singleinf-1
Results will be written to logs/<tag>-<timestamp>.jsonl. The tag is used to identify the simulation run, and the timestamp is automatically generated.
Example output log:
{"timestamp":"2026-03-11T14:00:00","type":"new_ladder","sid":"648628cc-09db-4602-9583-fb3cb47b5b40"}
{"timestamp":"2026-03-11T14:00:00","type":"ladder_add","sid":"648628cc-09db-4602-9583-fb3cb47b5b40","count":9683849}
{"timestamp":"2026-03-11T14:04:00.420860","type":"query","sig_type":"full"}
{"timestamp":"2026-03-11T14:07:54.039826","type":"query","sig_type":"condensed"}
Analyzing results
Analysis can be done with the mtlsim analyze command. For example, to analyze all results from the logs directory, run:
mtlsim analyze logs/*.jsonl
Analysis results will be written to output/<tag>.json. If multiple files with the same tag but different timestamps are provided, analysis will only be done on the latest file.
Example output:
{
"run_name": "single_inf_0.01",
"timestamp": "2026-06-12T13:30:20",
"time_between_fullsig": [
63653.10127186775,
87375.85578608513,
69382.63759803772,
4492.899500846863
// (elapsed time in seconds between full signature checks)
],
"queries_between_fullsig": [
622,
870,
687,
38
// (number of queries between full signature checks)
],
"ladder_sizes": {
"f0493d15-1666-41a7-a118-1b9bbb2d37fd": [
["2026-03-11T14:00:00", 0],
["2026-03-11T14:00:00", 9683849],
["2026-03-11T14:30:00", 9684793],
["2026-03-11T15:00:00", 9685610]
// ... [timestamp, integer] pairs
]
// potentially additional ladder UUIDs
}
}
Metadata
Release files for mtlsim 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mtlsim-0.1.0.tar.gz | 30.6 kB | Without provenance | Details for mtlsim-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mtlsim-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for mtlsim-0.1.0-py3-none-any.whl |
Total release size: 67.5 kB
Release files / mtlsim-0.1.0.tar.gz
| Download URL | mtlsim-0.1.0.tar.gz |
|---|---|
| Size | 30.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ff950aa1282c428116dceb3a332260528450572e17b50e8e5af7b9e0d3c27308
|
|
BLAKE2b-256 checksum How to use checksums |
3bac5b4165b00a2a39362dc1e93d7c55f0d4181616416bdbfa72318622403f2a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mtlsim-0.1.0-py3-none-any.whl
| Download URL | mtlsim-0.1.0-py3-none-any.whl |
|---|---|
| Size | 37.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
62a33af4d29e4a8ceacfe69f009189eef9cd3e6331c688922ae02af2ff7ab90b
|
|
BLAKE2b-256 checksum How to use checksums |
119c27904c023375ff331eb651dfe711d82d3e2c5f0ff56a0e5b8ee800bd772e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"NixOS","version":"26.05","id":"yarara","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mtlsim 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.