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

MetricMeaning
duration_secondsElapsed file-transfer time.
throughput_bpsTransfer throughput in bits per second.
packet_countTotal number of DNS packets captured.
entropyMeasured 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 dd, allowing for the encryption envelope, is

∣S∣Base32≈⌊58(252−d)⌋−32. |S|_{\mathrm{Base32}}\approx \left\lfloor\frac{5}{8}(252-d)\right\rfloor-32.

For bench.local, d=11d=11, giving an estimate of approximately 118 bytes. The benchmark used a 115-byte chunk size, including its transfer metadata.

Base32: mean results across five 1 MiB transfers.
Key exchangeDuration (s)Throughput (bps)DNS packetsEntropy (bits/char)
none134.5306235721186≈ 4.9489
x25519134.0456258021178≈ 4.9492
p256134.7356226421177≈ 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 log⁡226\log_2 26 rather than Base32’s 5 bits per character. Its initial capacity estimate is

∣S∣regex≈⌊log⁡2268(252−d)⌋−32. |S|_{\mathrm{regex}}\approx \left\lfloor\frac{\log_2 26}{8}(252-d)\right\rfloor-32.

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.

Regex / FTE: mean results across five 1 MiB transfers.
Key exchangeDuration (s)Throughput (bps)DNS packetsEntropy (bits/char)
none185.9564511128342≈ 4.6739
x25519188.6014448228337≈ 4.6739
p256186.9044488128330≈ 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.

Weighted / Huffman: mean results across five 1 MiB transfers.
Key exchangeDuration (s)Throughput (bps)DNS packetsEntropy (bits/char)
none207.0444051632767≈ 4.1798
x25519207.1884048832764≈ 4.1806
p256206.8394055632768≈ 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:

EncodingDuration (s)Throughput (bps)DNS packetsEntropy (bits/char)
Base32134.53062,35721,186≈ 4.9489
Regex/FTE185.95645,11128,342≈ 4.6739
Weighted/Huffman207.04440,51632,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

Wireshark capture of DNS packets generated by a regex-encoded file transfer with X25519 key exchange

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

Wireshark capture of DNS packets generated by a weighted-encoded file transfer with X25519 key exchange

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