Final revision: audit fixes, cross-scheme comparisons, known-plaintext stage
- exclude the all-ones Walsh-Hadamard row and test every key family against the all-ones guess - pass the model dimension to the noise scaling so the key-length sweep runs at a fixed per-dimension SNR - known-plaintext attack with nested accumulation and common random numbers, averaged over 40 collections - key sensitivity and brute-force search extended to the permutation key and the index cipher - make_tables regenerates all three result tables from the CSVs
This commit is contained in:
+40
-16
@@ -1,9 +1,11 @@
|
||||
"""Generate the LaTeX rows of the two result tables from the CSVs, so
|
||||
"""Generate the LaTeX rows of the three result tables from the CSVs, so
|
||||
that every table in the paper is reproducible from data/ (TIFS mandate).
|
||||
Prints the tabular body; paste into main.tex without edits.
|
||||
Prints the tabular bodies; paste into main.tex without edits.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import csv
|
||||
import json
|
||||
import math
|
||||
from pathlib import Path
|
||||
|
||||
DATA = Path(__file__).resolve().parents[1] / "data"
|
||||
@@ -17,39 +19,61 @@ NAME = {
|
||||
"random": "Random",
|
||||
"hadamard": "Walsh-Hadamard",
|
||||
"learned": "Learned",
|
||||
"learned_reg": r"Regularized~\eqref{eq:regloss}",
|
||||
}
|
||||
RECEIVER = {
|
||||
"legit": "Legitimate", "oma": "OMA",
|
||||
"insider": "Insider", "eve": "Outsider eavesdropper",
|
||||
}
|
||||
|
||||
|
||||
def f3(x: str) -> str:
|
||||
"""Three decimals, or an em-dash for a value that does not apply."""
|
||||
try:
|
||||
return f"{float(x):.3f}"
|
||||
except ValueError:
|
||||
v = float(x)
|
||||
except (TypeError, ValueError):
|
||||
return "--"
|
||||
return "--" if math.isnan(v) else f"{v:.3f}"
|
||||
|
||||
|
||||
def cell(x: str, bold: bool) -> str:
|
||||
s = f3(x)
|
||||
if s == "--":
|
||||
return "--"
|
||||
return rf"$\mathbf{{{s}}}$" if bold else f"${s}$"
|
||||
|
||||
|
||||
def compare_table():
|
||||
print("% Table: scheme comparison (from sec_compare.csv)")
|
||||
rows = list(csv.DictReader(open(DATA / "sec_compare.csv")))
|
||||
order = ["public_mask", "perm_key", "index_cipher", "oma_plain", "proposed"]
|
||||
rows = sorted(rows, key=lambda r: order.index(r["scheme"]))
|
||||
rows.sort(key=lambda r: order.index(r["scheme"]))
|
||||
for r in rows:
|
||||
cells = [f3(r["legit_ser"]), f3(r["eve_out"]), f3(r["eve_in"]),
|
||||
f3(r["jam0_ser"])]
|
||||
if r["scheme"] == "proposed":
|
||||
cells = [rf"$\mathbf{{{c}}}$" for c in cells]
|
||||
else:
|
||||
cells = [f"${c}$" if c != "--" else "--" for c in cells]
|
||||
b = r["scheme"] == "proposed"
|
||||
cells = [cell(r[k], b) for k in
|
||||
("legit_ser", "eve_out", "eve_in", "jam0_ser")]
|
||||
print(f"{NAME[r['scheme']]} & " + " & ".join(cells) + r" \\")
|
||||
|
||||
|
||||
def maskfam_table():
|
||||
print("% Table: key families (from sec_maskfam.csv)")
|
||||
for r in csv.DictReader(open(DATA / "sec_maskfam.csv")):
|
||||
print(f"{NAME[r['family']]} & ${f3(r['legit_ser'])}$ & "
|
||||
f"${f3(r['eve_ser'])}$ & ${f3(r['mask_xcorr'])}$" + r" \\")
|
||||
cells = [cell(r[k], False) for k in
|
||||
("legit_ser", "eve_ser", "eve_ones_ser", "mask_xcorr")]
|
||||
print(f"{NAME[r['family']]} & " + " & ".join(cells) + r" \\")
|
||||
|
||||
|
||||
def real_table():
|
||||
print("% Table: headline recovery (from real_sec_stats.json)")
|
||||
st = json.loads((DATA / "real_sec_stats.json").read_text())
|
||||
rec = st["recovery"]
|
||||
snrs = sorted(rec, key=float)
|
||||
for key in ("legit", "oma", "insider", "eve"):
|
||||
cells = " & ".join(f"${rec[s][key]:.3f}$" for s in snrs)
|
||||
print(f"{RECEIVER[key]} & {cells}" + r" \\")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
compare_table()
|
||||
print()
|
||||
maskfam_table()
|
||||
compare_table(); print()
|
||||
maskfam_table(); print()
|
||||
real_table()
|
||||
|
||||
Reference in New Issue
Block a user