aboutsummaryrefslogtreecommitdiffhomepage
path: root/notebooks
diff options
context:
space:
mode:
authorAdam Janovsky2023-06-14 14:58:14 +0200
committerAdam Janovsky2023-06-14 14:58:14 +0200
commit6789da266bbaf8aca3c530308eb2e7f4b9e2bf70 (patch)
tree0eab060877062656331b3b547ad124849a62c8ea /notebooks
parent617fa6c71324624f5b4ba9a8693740bb173871bb (diff)
downloadsec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.tar.gz
sec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.tar.zst
sec-certs-6789da266bbaf8aca3c530308eb2e7f4b9e2bf70.zip
add more plots to reference notebook
Diffstat (limited to 'notebooks')
-rw-r--r--notebooks/cc/references.ipynb156
1 files changed, 155 insertions, 1 deletions
diff --git a/notebooks/cc/references.ipynb b/notebooks/cc/references.ipynb
index 15b2a1f4..1a934b38 100644
--- a/notebooks/cc/references.ipynb
+++ b/notebooks/cc/references.ipynb
@@ -28,6 +28,7 @@
},
"outputs": [],
"source": [
+ "from __future__ import annotations\n",
"import networkx as nx\n",
"import networkx.algorithms.community as nx_comm\n",
"import matplotlib\n",
@@ -38,6 +39,7 @@
"import seaborn as sns\n",
"import numpy as np\n",
"import sys\n",
+ "from tqdm import tqdm\n",
"from pathlib import Path\n",
"\n",
"\n",
@@ -46,7 +48,7 @@
"\n",
"%matplotlib inline\n",
"\n",
- "matplotlib.use(\"pgf\")\n",
+ "# matplotlib.use(\"pgf\")\n",
"sns.set_theme(style='white')\n",
"plt.rcParams[\"axes.linewidth\"] = 0.5\n",
"plt.rcParams[\"legend.fontsize\"] = 6.5\n",
@@ -152,6 +154,158 @@
]
},
{
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def len_if_exists(x) -> int:\n",
+ " return len(x) if pd.notnull(x) else 0\n",
+ "\n",
+ "df_id_rich[\"n_references\"] = df_id_rich.directly_referencing.map(len_if_exists)\n",
+ "df_id_rich[\"n_trans_references\"] = df_id_rich.indirectly_referencing.map(len_if_exists)\n",
+ "df_id_rich[\"n_referenced_by\"] = df_id_rich.directly_referenced_by.map(len_if_exists)\n",
+ "df_id_rich[\"n_trans_referenced_by\"] = df_id_rich.indirectly_referenced_by.map(len_if_exists)\n",
+ "\n",
+ "n_ref_smartcards = df_id_rich.loc[(df_id_rich.directly_referencing.notnull()) & (df_id_rich.category == \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")].shape[0]\n",
+ "n_ref_others = df_id_rich.loc[(df_id_rich.directly_referencing.notnull()) & (df_id_rich.category != \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")].shape[0]\n",
+ "print(f\"Number of smartcard certificates that reference some other certificate: {n_ref_smartcards}\")\n",
+ "print(f\"Number of non-smartcard certificates that reference some other certificate: {n_ref_others}\")"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Distribution of references and certificate reach"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "df_melted = df_id_rich[[\"n_references\", \"n_trans_references\", \"n_referenced_by\", \"n_trans_referenced_by\"]].melt()\n",
+ "df_melted[\"incoming\"] = df_melted.variable.map(lambda x: False if x.endswith(\"by\") else True)\n",
+ "sns.catplot(data=df_melted, kind=\"violin\", x=\"variable\", y=\"value\", col=\"incoming\", sharex=False, sharey=False)\n",
+ "plt.savefig(RESULTS_DIR / \"violin_n_references.pdf\", bbox_inches=\"tight\")\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Evolution of certificate reach for top-10 certificates"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "top_10 = df_id_rich.n_trans_referenced_by.sort_values(ascending=False).head(10)\n",
+ "top_10_cert_ids = df_id_rich.loc[top_10.index].cert_id\n",
+ "top_10"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# TODO: Check if the computation can be vectorized through some time-series or other thing...\n",
+ "def find_reach_over_time(df: pd.DataFrame, cert_id: str, date_range: pd.DatetimeIndex) -> pd.Series:\n",
+ " df_copy = df.copy()\n",
+ " df_copy[\"is_referenced_by\"] = df_copy.indirectly_referencing.map(lambda x: False if pd.isnull(x) else cert_id in x)\n",
+ " df_subset = df_copy.loc[df_copy.is_referenced_by]\n",
+ " dct = {}\n",
+ " for date in date_range:\n",
+ " dct[date] = df_subset.loc[(date >= df_subset.not_valid_before) & (date < df_subset.not_valid_after)].shape[0]\n",
+ " return pd.Series(dct, name=cert_id)\n",
+ "\n",
+ "certs_with_top_reach = top_10_cert_ids.tolist()\n",
+ "date_range = pd.date_range(df_id_rich.not_valid_before.min(), df_id_rich.not_valid_before.max())\n",
+ "data = [find_reach_over_time(df_id_rich, x, date_range) for x in tqdm(certs_with_top_reach)]\n",
+ "df_reach_evolution = pd.concat(data, axis=1)\n",
+ "\n",
+ "df_reach_evolution.index.name = \"date\"\n",
+ "df_reach_evolution = df_reach_evolution.reset_index()\n",
+ "\n",
+ "\n",
+ "df_reach_evolution_melted = df_reach_evolution.melt(id_vars=\"date\", var_name=\"certificate\", value_name=\"reach\")\n",
+ "\n",
+ "g = sns.lineplot(data=df_reach_evolution_melted, x=\"date\", y=\"reach\", hue=\"certificate\")\n",
+ "g.set(title=\"Certificate reach over time\", xlabel=\"Time\", ylabel=\"Certificate reach\")\n",
+ "plt.savefig(RESULTS_DIR / \"lineplot_top_certificate_reach.pdf\", bbox_inches=\"tight\")\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "attachments": {},
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Average number of references & certificate reach over time"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def compute_avg_references(df: pd.DataFrame, smartcards: bool, variable: str) -> pd.DataFrame:\n",
+ " \"\"\"\n",
+ " Computes a series where index is date and value is average 'variable' value for certificates that were valid at that time,\n",
+ " coming from either smardcards or other categories. E.g., variable can be `directly_referencing`.\n",
+ " \"\"\"\n",
+ " df_copy = df.copy()\n",
+ " df_copy[\"target_variable\"] = df[variable].map(lambda x: len(x) if pd.notnull(x) else 0)\n",
+ "\n",
+ " date_range = pd.date_range(df_copy.not_valid_before.min(), df_copy.not_valid_before.max())\n",
+ " dct = {}\n",
+ " for date in date_range:\n",
+ " if smartcards:\n",
+ " dct[date] = df_copy.loc[(date >= df_copy.not_valid_before) & (date < df_copy.not_valid_after) & (df_copy.category == \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")][\"target_variable\"].mean()\n",
+ " else:\n",
+ " dct[date] = df_copy.loc[(date >= df_copy.not_valid_before) & (date < df_copy.not_valid_after) & (df_copy.category != \"ICs, Smart Cards and Smart Card-Related Devices and Systems\")][\"target_variable\"].mean()\n",
+ " series_name = variable + \" smartcards\" if smartcards else variable + \" other categories\"\n",
+ " return pd.Series(dct, name=series_name) \n",
+ "\n",
+ "refs_smartcards = compute_avg_references(df_id_rich, True, \"directly_referencing\")\n",
+ "trans_refs_smartcards = compute_avg_references(df_id_rich, True, \"indirectly_referencing\")\n",
+ "refs_others = compute_avg_references(df_id_rich, False, \"directly_referencing\")\n",
+ "trans_refs_others = compute_avg_references(df_id_rich, False, \"indirectly_referencing\")\n",
+ "df_avg_num_refs = pd.concat([refs_smartcards, refs_others, trans_refs_smartcards, trans_refs_others], axis=1)\n",
+ "df_avg_num_refs.index.name = \"date\"\n",
+ "df_avg_num_refs = df_avg_num_refs.reset_index()\n",
+ "df_avg_num_refs_melted = df_avg_num_refs.melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"n_references\")\n",
+ "\n",
+ "reach_smartcards = compute_avg_references(df_id_rich, True, \"indirectly_referenced_by\")\n",
+ "reach_others = compute_avg_references(df_id_rich, False, \"indirectly_referenced_by\")\n",
+ "df_avg_reach = pd.concat([reach_smartcards, reach_others], axis=1)\n",
+ "df_avg_reach.index.name = \"date\"\n",
+ "df_avg_reach = df_avg_reach.reset_index()\n",
+ "df_avg_reach_melted = df_avg_reach.melt(id_vars=[\"date\"], var_name=\"category\", value_name=\"certificate reach\")\n",
+ "\n",
+ "g = sns.lineplot(data=df_avg_num_refs_melted, x=\"date\", y=\"n_references\", hue=\"category\")\n",
+ "g.set(title=\"Average number of references in certificates\", xlabel=\"Time\", ylabel=\"Number of references\")\n",
+ "plt.savefig(RESULTS_DIR / \"lineplot_avg_n_references.pdf\", bbox_inches=\"tight\")\n",
+ "plt.show()\n",
+ "\n",
+ "g = sns.lineplot(data=df_avg_reach_melted, x=\"date\", y=\"certificate reach\", hue=\"category\")\n",
+ "g.set(title=\"Average reach of a certificate in time\", xlabel=\"Time\", ylabel=\"Reach\")\n",
+ "plt.savefig(RESULTS_DIR / \"lineplot_avg_reach.pdf\", bbox_inches=\"tight\")\n",
+ "plt.show()"
+ ]
+ },
+ {
"attachments": {},
"cell_type": "markdown",
"metadata": {},