Evaluation
Benchmarking setup
The evaluation used an isolated Docker environment. A tool-server container ran the DNS receiver, while an orchestrator container executed client transfers and captured DNS traffic. A bridge network, bench_net, connected the containers, and a volume, bench_results_vol, retained benchmark artifacts.
A 1 MiB file was transferred using the domain bench.local. Each configuration was run five times, and the results report the mean values. Every encoding used a 10 ms delay between queries.
Three representations were compared: a Base32 baseline, regex-based FTE, and weighted Huffman. Each was evaluated with no key exchange, X25519, and P-256. The none mode uses a fixed development key, so the comparison concerns handshake overhead rather than an unencrypted transfer.
Metrics
| Metric | Meaning |
|---|---|
duration_seconds | Elapsed file-transfer time. |
throughput_bps | Transfer throughput in bits per second. |
packet_count | Total number of DNS packets captured. |
entropy | Measured Shannon entropy of domain names, in bits per character. |
DNS packet counts include the captured traffic; they should not be interpreted as counts of file chunks alone. Entropy values are approximate.
Base32 encoding
The benchmark baseline encodes encrypted output in Base32 and separates the labels at the 63-byte limit. Base32 carries 5 bits per output character and prioritizes capacity rather than shaping the character distribution.
The estimated chunk capacity for a suffix of length , allowing for the encryption envelope, is
For bench.local, , giving an estimate of approximately 118 bytes. The benchmark used a 115-byte chunk size, including its transfer metadata.
| Key exchange | Duration (s) | Throughput (bps) | DNS packets | Entropy (bits/char) |
|---|---|---|---|---|
none | 134.530 | 62357 | 21186 | ≈ 4.9489 |
x25519 | 134.045 | 62580 | 21178 | ≈ 4.9492 |
p256 | 134.735 | 62264 | 21177 | ≈ 4.9492 |
Base32 produced the best transfer performance: approximately 62,000 bps, about 134 seconds per transfer, and just over 21,000 DNS packets. Its measured entropy was close to the theoretical 5 bits per character.
Regex-based FTE
The regex configuration uses the theoretical lowercase-letter capacity rather than Base32’s 5 bits per character. Its initial capacity estimate is
For the benchmark domain this gives approximately 109 bytes. The FTE implementation has additional header overhead, so a conservative 90-byte chunk size was selected.
| Key exchange | Duration (s) | Throughput (bps) | DNS packets | Entropy (bits/char) |
|---|---|---|---|---|
none | 185.956 | 45111 | 28342 | ≈ 4.6739 |
x25519 | 188.601 | 44482 | 28337 | ≈ 4.6739 |
p256 | 186.904 | 44881 | 28330 | ≈ 4.6740 |
Regex/FTE achieved approximately 44,000–45,000 bps, with durations of about 186–189 seconds and roughly 28,300 DNS packets. Its measured entropy remained near 4.674 bits per character, below Base32 but close to the uniform lowercase-letter capacity.
Weighted Huffman encoding
Weighted output length depends on the codewords encountered by the encrypted bitstream. A capacity calculation based on expected codeword length does not guarantee that each resulting name fits.
The chunk size was selected empirically by generating encoded subdomains and checking the full-name length. With bench.local, an 80-byte chunk size produced zero failures in 20,000 trials. This supports the chosen benchmark configuration without establishing a universal worst-case bound.
| Key exchange | Duration (s) | Throughput (bps) | DNS packets | Entropy (bits/char) |
|---|---|---|---|---|
none | 207.044 | 40516 | 32767 | ≈ 4.1798 |
x25519 | 207.188 | 40488 | 32764 | ≈ 4.1806 |
p256 | 206.839 | 40556 | 32768 | ≈ 4.1797 |
Weighted encoding lowered measured entropy to approximately 4.180 bits per character. Its throughput was approximately 40,500 bps, transfers took about 207 seconds, and the captured traffic contained roughly 32,800 DNS packets.
Comparison
The no-key-exchange configurations provide a compact comparison of the three encodings:
| Encoding | Duration (s) | Throughput (bps) | DNS packets | Entropy (bits/char) |
|---|---|---|---|---|
| Base32 | 134.530 | 62,357 | 21,186 | ≈ 4.9489 |
| Regex/FTE | 185.956 | 45,111 | 28,342 | ≈ 4.6739 |
| Weighted/Huffman | 207.044 | 40,516 | 32,767 | ≈ 4.1798 |
Base32’s higher payload capacity produces fewer queries and better throughput. Regex/FTE gives up some capacity by using a smaller alphabet and the FTE representation. Weighted encoding goes further by making its character distribution non-uniform, sacrificing capacity for lower measured entropy.
The configurations use different chunk sizes: 115, 90, and 80 bytes. The comparison describes the complete chosen configurations, rather than an experiment at identical per-packet file-payload capacity.
Key-exchange overhead
Performance differences between none, x25519, and p256 were small within each encoding. This is consistent with the handshake affecting only the initial messages, while the rest of the transfer requires thousands of DNS packets. Entropy also remained stable within each representation across key-exchange modes.
Interpretation
The choice of encoding has the clearest effect on the measured performance. More characters per encrypted bit lead to less file payload per query, a higher packet count, and longer transfers.
The weighted method successfully changes a payload characteristic used in detection, but the measurements are not detector success or failure rates. The evaluation measures transfer behaviour and hostname entropy, not whether a real IDS accepts or blocks the traffic.
Packet captures

DNS packets from a regex-encoded file transfer with X25519 key exchange.

DNS packets from a weighted-encoded file transfer with X25519 key exchange.