From 908fd861904e44da40ceaa3ede33764d1e48f993 Mon Sep 17 00:00:00 2001 From: Youngjoon Lee <5462944+youngjoon-lee@users.noreply.github.com> Date: Thu, 16 May 2024 13:54:09 +0900 Subject: [PATCH] add hue and legend. update readme --- mixnet/v2/sim/README.md | 3 +++ mixnet/v2/sim/docs/msgs-around-interval.png | Bin 0 -> 53503 bytes mixnet/v2/sim/main.py | 11 ++++++++--- mixnet/v2/sim/p2p.py | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 mixnet/v2/sim/docs/msgs-around-interval.png diff --git a/mixnet/v2/sim/README.md b/mixnet/v2/sim/README.md index f8cbadc..e4382f6 100644 --- a/mixnet/v2/sim/README.md +++ b/mixnet/v2/sim/README.md @@ -50,6 +50,9 @@ For more details, please see the [Time and Scheduling](https://simpy.readthedocs ## [Adversary Models](https://www.notion.so/Mixnet-v2-Proof-of-Concept-102d0563e75345a3a6f1c11791fbd746?pvs=4#c5ffa49486ce47ed81d25028bc0d9d40) - [x] Identifying nodes emitting messages around the promised interval. - [ ] With partial visibility + - [ ] Quantifying how much the expected frequent senders are anonymized + - Current output + ![](./docs/msgs-around-interval.png) - [ ] Correlating senders-receivers based on timing - [ ] Active attacks - [ ] Reporting & Visualization diff --git a/mixnet/v2/sim/docs/msgs-around-interval.png b/mixnet/v2/sim/docs/msgs-around-interval.png new file mode 100644 index 0000000000000000000000000000000000000000..f5fc29218510925c372a393b0246877e74c03714 GIT binary patch literal 53503 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 literal 0 HcmV?d00001 diff --git a/mixnet/v2/sim/main.py b/mixnet/v2/sim/main.py index 6a1037f..a5ded12 100644 --- a/mixnet/v2/sim/main.py +++ b/mixnet/v2/sim/main.py @@ -21,12 +21,17 @@ if __name__ == "__main__": print(df.describe()) # Visualize the nodes emitted messages around the promised interval - df = pd.DataFrame([(node.id, cnt) for node, cnt in sim.p2p.nodes_emitted_msg_around_interval.items()], columns=["node", "count"]) + df = pd.DataFrame( + [(node.id, cnt, node.id < len(config.real_message_prob_weights)) + for node, cnt in sim.p2p.senders_around_interval.items()], + columns=["NodeID", "Count", "Expected"] + ) plt.figure(figsize=(10, 6)) - seaborn.barplot(x="node", y="count", data=df) + seaborn.barplot(data=df, x="NodeID", y="Count", hue="Expected", palette={True: "red", False: "blue"}) plt.title("Messages emitted around the promised interval") - plt.xlabel("Node ID") + plt.xlabel("Sender Node ID") plt.ylabel("Msg Count") + plt.legend(title="Expected") plt.show() print("Simulation complete!") \ No newline at end of file diff --git a/mixnet/v2/sim/p2p.py b/mixnet/v2/sim/p2p.py index 733e577..0bd5a8e 100644 --- a/mixnet/v2/sim/p2p.py +++ b/mixnet/v2/sim/p2p.py @@ -14,7 +14,7 @@ class P2p: self.config = config self.nodes = [] self.message_sizes = [] - self.nodes_emitted_msg_around_interval = defaultdict(int) + self.senders_around_interval = defaultdict(int) def add_node(self, nodes): self.nodes.extend(nodes) @@ -26,7 +26,7 @@ class P2p: now_frac, now_int = math.modf(self.env.now) if now_int % self.config.message_interval == 0 and now_frac <= self.config.max_message_prep_time: - self.nodes_emitted_msg_around_interval[sender] += 1 + self.senders_around_interval[sender] += 1 # Yield 0 to ensure that the broadcast is done in the same time step. # Without this, SimPy complains that the broadcast func is not a generator.