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