Side-Channel Discovery (Section 5.2)

October 12, 2025 · View on GitHub

This directory contains the artifacts for the fuzzing campaigns, clustering, categorization, and further analysis in Section 5.2.

Since the large fuzzing campaign is non-trivial to reproduce we provide the results. The results can be extracted from file fuzzing_campaign_results_expanded.zip hosted alongside the artifact. Download the file and extract the results. This command creates a new directory so is safe run without a new directory:

unzip fuzzing_campaign_results_expanded.zip

This will create a new directory fuzzing_campaign_results_expanded with per-device metadata and reproducers.

Clustering (Section 5.2)

Clustering can be run like:

python cluster.py fuzzing_campaign_results_expanded

Note

If the results are not pre-expandend, i.e., they come directly from the fuzzer, you need to expand them first with expand-repro <directory-of-results>.

Expected output:

Processing 13116 files
New class: /home/fabian/repos/cispa/2025_arm_architectural_sc/artifact/framework_evaluation/side_channel_discovery/classes/class_11_11-reg_mem/Oryon
Progress: 0%
New class: /home/fabian/repos/cispa/2025_arm_architectural_sc/artifact/framework_evaluation/side_channel_discovery/classes/class_4_4-si_pc_si_addr/Oryon
New class: /home/fabian/repos/cispa/2025_arm_architectural_sc/artifact/framework_evaluation/side_channel_discovery/classes/class_4_4-reg_mem/Oryon
New class: /home/fabian/repos/cispa/2025_arm_architectural_sc/artifact/framework_evaluation/side_channel_discovery/classes/class_0_0-reg_mem/Oryon
New class: /home/fabian/repos/cispa/2025_arm_architectural_sc/artifact/framework_evaluation/side_channel_discovery/classes/class_0_0-mem/Oryon
...
Total classes: 32

This takes 20-40 minutes.

This creates a folder classes, one directory for each class, listing the reproducers per microarchitecture. You can use this command to preview one reproducer per class and microarchitecture:

for dir in classes/*/*/; do find "$dir" -maxdepth 1 -type f | head -n 1; done | xargs bat --style=header --line-range :80

Categorization (Section 5.2)

Those need to be categorized by the categorization stage:

python categorize.py --status --list-files fuzzing_campaign_results_expanded

Expected output:

Categorizing 13116 files
0%
1%
...
99%
100%

The categorization stage takes 10-20 minutes to finish, but notifies about progress. This creates a file categorized.json, which lists the best primitive for each unique side channel.

Overview (Table 1)

These categorized.json files can finally be used to create a table similar to Table 1:

make pdf JSON=categorized.json

The table is rendered via Latex to out/result_table.pdf.

We also provide the final "global" categorization list which is used to generate Table 1 in the paper as global_categorized.json. This list includes primitives from prior runs and is the global ground truth of discovered side channels.

Side-Channel Complexity (Section 5.2)

python calc_avg_len_and_regs.py --status fuzzing_campaign_results_expanded

The script takes 10-20 minutes to finish, but notifies about progress. Expected output:

Processing 13116 files
0%
...
100%
seq_lens: mean = 2.3091643793839585, stderr = 0.007428902020704587
seq_lens_with_nop: mean = 2.786062824031717, stderr = 0.011010489547143135
registers: mean = 1.0196706312900274, stderr = 0.0013658937191587484

Time to Discovery (Table 2)

python time_to_discovery.py categorized.json --merge

Expected output:

Primitive Type: lx_sx
| Microarch   |   Min |    Avg |   ± stderr |   reproducers |
|-------------|-------|--------|------------|---------------|
| Merged      |     3 | 3820.9 |    1519.93 |          2160 |

Primitive Type: pointer_chase
| Microarch   |   Min |   Avg |   ± stderr |   reproducers |
|-------------|-------|-------|------------|---------------|
| Merged      |     7 |  93.5 |       86.5 |           135 |

Primitive Type: split_store
| Microarch   |   Min |   Avg |   ± stderr |   reproducers |
|-------------|-------|-------|------------|---------------|
| Merged      |     1 |  1.75 |       0.25 |          3997 |

Primitive Type: store_ret
| Microarch   |   Min |     Avg |   ± stderr |   reproducers |
|-------------|-------|---------|------------|---------------|
| Merged      |     1 | 526.444 |    194.109 |          4059 |

Primitive Type: translation_race
| Microarch   |   Min |   Avg |   ± stderr |   reproducers |
|-------------|-------|-------|------------|---------------|
| Merged      |     1 |     2 |   0.408248 |          1637 |

Side-channel Coverage over Time (Figure 2)

python plot_coverage_over_time.py --merge categorized.json --export coverage_over_time.svg --format svg

Expected output (+ coverage_over_time.svg):

coverage is reached at time: 4502
Plot exported to coverage_over_time.svg as svg