Skip to content

Commit 3c55021

Browse files
committed
Better dmap building in scalarmult distinguish.
1 parent a89cc36 commit 3c55021

1 file changed

Lines changed: 83 additions & 77 deletions

File tree

analysis/scalarmults/distinguish.ipynb

Lines changed: 83 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
},
1515
{
1616
"cell_type": "code",
17-
"execution_count": 1,
17+
"execution_count": null,
1818
"id": "bc1528b8-61cd-4219-993f-e3f1ac79e801",
1919
"metadata": {},
2020
"outputs": [],
@@ -24,22 +24,32 @@
2424
"import glob\n",
2525
"import random\n",
2626
"import math\n",
27+
"import sys\n",
2728
"\n",
2829
"from collections import Counter\n",
2930
"\n",
3031
"import numpy as np\n",
3132
"import pandas as pd\n",
33+
"import xarray as xr\n",
3234
"from scipy.stats import binom, entropy\n",
3335
"from scipy.spatial import distance\n",
3436
"from tqdm.auto import tqdm, trange\n",
3537
"from anytree import PreOrderIter, Walker\n",
3638
"from matplotlib import pyplot as plt\n",
39+
"from statsmodels.stats.proportion import proportion_confint\n",
3740
"\n",
3841
"from pyecsca.ec.mult import *\n",
3942
"from pyecsca.misc.utils import TaskExecutor, silent\n",
4043
"from pyecsca.sca.re.tree import Map, Tree\n",
4144
"\n",
42-
"from common import *\n",
45+
"from epare.divisors import divisor_map\n",
46+
"from epare.config import all_configs, Config\n",
47+
"from epare.error_model import all_error_models\n",
48+
"\n",
49+
"if sys.version_info >= (3, 14):\n",
50+
" from compression import zstd\n",
51+
"else:\n",
52+
" from backports import zstd\n",
4353
"\n",
4454
"%matplotlib ipympl"
4555
]
@@ -55,7 +65,7 @@
5565
},
5666
{
5767
"cell_type": "code",
58-
"execution_count": 2,
68+
"execution_count": null,
5969
"id": "119b1e18-eeb0-4b70-bec3-ff277641403f",
6070
"metadata": {},
6171
"outputs": [],
@@ -72,7 +82,7 @@
7282
},
7383
{
7484
"cell_type": "code",
75-
"execution_count": 3,
85+
"execution_count": null,
7686
"id": "ccb00342-3c48-49c9-bedf-2341e5eae3a2",
7787
"metadata": {},
7888
"outputs": [],
@@ -91,68 +101,56 @@
91101
},
92102
{
93103
"cell_type": "code",
94-
"execution_count": 4,
104+
"execution_count": null,
95105
"id": "3dbac9be-d098-479a-8ca2-f531f6668f7c",
96106
"metadata": {},
97-
"outputs": [
98-
{
99-
"data": {
100-
"application/vnd.jupyter.widget-view+json": {
101-
"model_id": "1e5c7654ba8c4e559d1e100a334a3331",
102-
"version_major": 2,
103-
"version_minor": 0
104-
},
105-
"text/plain": [
106-
" 0%| | 0/12480 [00:00<?, ?it/s]"
107-
]
108-
},
109-
"metadata": {},
110-
"output_type": "display_data"
111-
}
112-
],
113-
"source": [
114-
"with open(f\"merged.pickle\", \"rb\") as f:\n",
115-
" distributions_mults = pickle.load(f)\n",
116-
"for probmap in tqdm(distributions_mults.values(), desc=f\"Narrowing probmaps to {divisor_name}.\"):\n",
107+
"outputs": [],
108+
"source": [
109+
"with zstd.open(\"merged.zpickle\", \"rb\") as f:\n",
110+
" config_map = pickle.load(f)\n",
111+
"for probmap in tqdm(config_map.values(), desc=f\"Narrowing probmaps to {divisor_name}.\"):\n",
117112
" probmap.narrow(allfeats)"
118113
]
119114
},
120115
{
121116
"cell_type": "code",
122-
"execution_count": 8,
117+
"execution_count": null,
123118
"id": "38c81e38-a37c-4e58-ac9e-927d14dad458",
124119
"metadata": {},
125120
"outputs": [],
126121
"source": [
127-
"allmults = list(distributions_mults.keys())\n",
128-
"basemults = list(all_mults_with_ctr)\n",
122+
"allmults = list(config_map.keys())\n",
123+
"basemults = list(all_configs)\n",
124+
"\n",
129125
"nbase = len(basemults)\n",
130126
"nmults = len(allmults)\n",
131127
"nallfeats = len(allfeats)"
132128
]
133129
},
134130
{
135131
"cell_type": "code",
136-
"execution_count": 9,
132+
"execution_count": null,
137133
"id": "206b385a-bb98-47e7-9312-94a864794faa",
138134
"metadata": {},
139-
"outputs": [
140-
{
141-
"name": "stdout",
142-
"output_type": "stream",
143-
"text": [
144-
"Have 12480 configurations (scalar multiplier x countermeasure x error model).\n",
145-
"Have 390 base configurations (scalar multiplier x countermeasure).\n",
146-
"Have 3215 base point orders (features).\n"
147-
]
148-
}
149-
],
135+
"outputs": [],
150136
"source": [
151137
"print(f\"Have {nmults} configurations (scalar multiplier x countermeasure x error model).\")\n",
152138
"print(f\"Have {nbase} base configurations (scalar multiplier x countermeasure).\")\n",
153139
"print(f\"Have {nallfeats} base point orders (features).\")"
154140
]
155141
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": null,
145+
"id": "e95a1551-3fec-468a-866d-1efa5721364d",
146+
"metadata": {},
147+
"outputs": [],
148+
"source": [
149+
"probs = xr.DataArray(np.zeros((nmults, nallfeats), dtype=np.float64), dims=(\"cfg\", \"divisor\"), coords={\"cfg\": allmults, \"divisor\": allfeats})\n",
150+
"for mult, probmap in tqdm(config_map.items(), desc=\"Convert probmaps to xarray.\"):\n",
151+
" probs.loc[mult, :] = [probmap[divisor] for divisor in allfeats]"
152+
]
153+
},
156154
{
157155
"cell_type": "markdown",
158156
"id": "437bcd9c-1da5-428a-a979-0835326777f3",
@@ -192,50 +190,56 @@
192190
{
193191
"cell_type": "code",
194192
"execution_count": null,
195-
"id": "0b85fad7-392f-4701-9329-d75d39736bbb",
193+
"id": "bf81fa2e-8746-4af1-963a-8d8340ed22da",
196194
"metadata": {},
197195
"outputs": [],
198196
"source": [
199-
"# Now go over all divisors, cluster based on overlapping CI for given n?\n",
200-
"io_map = {mult:{} for mult in allmults}\n",
201-
"for divisor in tqdm(allfeats):\n",
197+
"def make_groups(column: np.ndarray, nbuild: int, alpha: float, method: str = \"wilson\"):\n",
202198
" prev_ci_low = None\n",
203199
" prev_ci_high = None\n",
204-
" groups = {}\n",
205-
" pvals = {}\n",
206-
" group = 0\n",
207-
" for mult, probmap in sorted(distributions_mults.items(), key=lambda item: -item[1][divisor]):\n",
200+
" groups = []\n",
201+
" ci_low, ci_high = proportion_confint(column * nbuild, nbuild, alpha=alpha, method=method) \n",
202+
" order = np.argsort(column)\n",
203+
" for mult_index in reversed(order.data):\n",
208204
" # We are going from high to low p.\n",
209-
" pval = probmap[divisor]\n",
210-
" pvals[mult] = pval\n",
211-
" ci_low, ci_high = conf_interval(pval, nbuild, alpha)\n",
212-
" ci_low = max(ci_low, 0.0)\n",
213-
" ci_high = min(ci_high, 1.0)\n",
214-
" if (prev_ci_low is None and prev_ci_high is None) or prev_ci_low >= ci_high:\n",
215-
" g = groups.setdefault(f\"arbitrary{group}\", set())\n",
216-
" g.add(mult)\n",
217-
" group += 1\n",
205+
" low = ci_low[mult_index]\n",
206+
" high = ci_high[mult_index]\n",
207+
" if (prev_ci_low is None and prev_ci_high is None) or prev_ci_low >= high:\n",
208+
" g = set()\n",
209+
" groups.append(g)\n",
210+
" #print(low, high, len(groups), prev_ci_low, prev_ci_high)\n",
218211
" else:\n",
219-
" g = groups.setdefault(f\"arbitrary{group}\", set())\n",
220-
" g.add(mult)\n",
221-
" prev_ci_low = ci_low\n",
222-
" prev_ci_high = ci_high\n",
223-
" \n",
224-
" #print(f\"Divisor: {divisor}, num groups: {group}\", end=\"\\n\\t\")\n",
225-
" #for g in groups.values():\n",
212+
" g = groups[-1]\n",
213+
" g.add(mult_index)\n",
214+
" prev_ci_low = low\n",
215+
" prev_ci_high = high\n",
216+
" return groups"
217+
]
218+
},
219+
{
220+
"cell_type": "code",
221+
"execution_count": null,
222+
"id": "0b85fad7-392f-4701-9329-d75d39736bbb",
223+
"metadata": {},
224+
"outputs": [],
225+
"source": [
226+
"# Now go over all divisors, cluster based on overlapping CI for given n?\n",
227+
"cfg_map = pd.DataFrame(list(range(len(allmults))), index=allmults, columns=[\"vals\"])\n",
228+
"codomain = set()\n",
229+
"mapping = np.zeros((nmults, nallfeats), dtype=int)\n",
230+
"for i, divisor in tqdm(enumerate(allfeats), desc=\"Computing groups.\", total=nallfeats):\n",
231+
" groups = make_groups(probs.loc[:, divisor], nbuild, alpha)\n",
232+
" #print(f\"Divisor: {divisor}, num groups: {len(groups)}\")\n",
233+
" #for g in groups:\n",
226234
" # print(len(g), end=\", \")\n",
227235
" #print()\n",
228-
" for group, mults in groups.items():\n",
229-
" mult_pvals = [pvals[mult] for mult in mults]\n",
230-
" group_pval_avg = np.mean(mult_pvals)\n",
231-
" group_pval_var = np.var(mult_pvals)\n",
232-
" group_pval_min = np.min(mult_pvals)\n",
233-
" group_pval_max = np.max(mult_pvals)\n",
234-
" for mult in mults:\n",
235-
" io_map[mult][divisor] = (group, group_pval_avg, group_pval_var, group_pval_min, group_pval_max)\n",
236+
" for group, mult_indices in enumerate(groups):\n",
237+
" codomain.add(group)\n",
238+
" for mult_index in mult_indices:\n",
239+
" mapping[mult_index, i] = group\n",
236240
"\n",
237241
"# then build dmap\n",
238-
"dmap = Map.from_io_maps(set(distributions_mults.keys()), io_map)"
242+
"dmap = Map(mapping=pd.DataFrame(mapping), cfg_map=cfg_map, domain=allfeats, codomain=codomain)"
239243
]
240244
},
241245
{
@@ -285,12 +289,14 @@
285289
"cell_type": "code",
286290
"execution_count": null,
287291
"id": "5735e7d4-149c-4184-96f7-dcfd6017fbad",
288-
"metadata": {},
292+
"metadata": {
293+
"scrolled": true
294+
},
289295
"outputs": [],
290296
"source": [
291297
"# build a tree\n",
292-
"with silent():\n",
293-
" tree = Tree.build(set(allmults), dmap)"
298+
"#with silent():\n",
299+
"tree = Tree.build(set(allmults), dmap)"
294300
]
295301
},
296302
{
@@ -1610,7 +1616,7 @@
16101616
"name": "python",
16111617
"nbconvert_exporter": "python",
16121618
"pygments_lexer": "ipython3",
1613-
"version": "3.13.5"
1619+
"version": "3.12.3"
16141620
}
16151621
},
16161622
"nbformat": 4,

0 commit comments

Comments
 (0)