2024-02-05 06:47:36 +00:00
|
|
|
from typing import List
|
2024-02-05 08:04:02 +00:00
|
|
|
from unittest import TestCase
|
2024-01-15 06:17:35 +00:00
|
|
|
|
|
|
|
from pysphinx.sphinx import ProcessedFinalHopPacket, SphinxPacket
|
|
|
|
|
2024-02-05 08:04:02 +00:00
|
|
|
from mixnet.config import MixNodeInfo
|
2024-01-15 06:17:35 +00:00
|
|
|
from mixnet.packet import (
|
|
|
|
Fragment,
|
|
|
|
MessageFlag,
|
|
|
|
MessageReconstructor,
|
|
|
|
PacketBuilder,
|
|
|
|
)
|
2024-02-08 06:39:50 +00:00
|
|
|
from mixnet.test_utils import init_mixnet_config
|
2024-01-15 06:17:35 +00:00
|
|
|
from mixnet.utils import random_bytes
|
|
|
|
|
|
|
|
|
2024-02-05 08:04:02 +00:00
|
|
|
class TestPacket(TestCase):
|
2024-01-15 06:17:35 +00:00
|
|
|
def test_real_packet(self):
|
2024-02-08 06:39:50 +00:00
|
|
|
topology = init_mixnet_config().mixclient_config.topology
|
2024-01-15 06:17:35 +00:00
|
|
|
msg = random_bytes(3500)
|
2024-02-05 08:04:02 +00:00
|
|
|
packets_and_routes = PacketBuilder.build_real_packets(msg, topology)
|
|
|
|
self.assertEqual(4, len(packets_and_routes))
|
2024-01-15 06:17:35 +00:00
|
|
|
|
|
|
|
reconstructor = MessageReconstructor()
|
|
|
|
self.assertIsNone(
|
2024-02-05 08:04:02 +00:00
|
|
|
reconstructor.add(
|
|
|
|
self.process_packet(packets_and_routes[1][0], packets_and_routes[1][1])
|
|
|
|
),
|
2024-01-15 06:17:35 +00:00
|
|
|
)
|
|
|
|
self.assertIsNone(
|
2024-02-05 08:04:02 +00:00
|
|
|
reconstructor.add(
|
|
|
|
self.process_packet(packets_and_routes[3][0], packets_and_routes[3][1])
|
|
|
|
),
|
2024-01-15 06:17:35 +00:00
|
|
|
)
|
|
|
|
self.assertIsNone(
|
2024-02-05 08:04:02 +00:00
|
|
|
reconstructor.add(
|
|
|
|
self.process_packet(packets_and_routes[2][0], packets_and_routes[2][1])
|
|
|
|
),
|
|
|
|
)
|
|
|
|
msg_with_flag = reconstructor.add(
|
|
|
|
self.process_packet(packets_and_routes[0][0], packets_and_routes[0][1])
|
2024-01-15 06:17:35 +00:00
|
|
|
)
|
|
|
|
assert msg_with_flag is not None
|
|
|
|
self.assertEqual(
|
|
|
|
PacketBuilder.parse_msg_and_flag(msg_with_flag),
|
|
|
|
(MessageFlag.MESSAGE_FLAG_REAL, msg),
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_cover_packet(self):
|
2024-02-08 06:39:50 +00:00
|
|
|
topology = init_mixnet_config().mixclient_config.topology
|
2024-01-15 06:17:35 +00:00
|
|
|
msg = b"cover"
|
2024-02-05 08:04:02 +00:00
|
|
|
packets_and_routes = PacketBuilder.build_drop_cover_packets(msg, topology)
|
|
|
|
self.assertEqual(1, len(packets_and_routes))
|
2024-01-15 06:17:35 +00:00
|
|
|
|
|
|
|
reconstructor = MessageReconstructor()
|
2024-02-05 08:04:02 +00:00
|
|
|
msg_with_flag = reconstructor.add(
|
|
|
|
self.process_packet(packets_and_routes[0][0], packets_and_routes[0][1])
|
|
|
|
)
|
2024-01-15 06:17:35 +00:00
|
|
|
assert msg_with_flag is not None
|
|
|
|
self.assertEqual(
|
|
|
|
PacketBuilder.parse_msg_and_flag(msg_with_flag),
|
|
|
|
(MessageFlag.MESSAGE_FLAG_DROP_COVER, msg),
|
|
|
|
)
|
|
|
|
|
|
|
|
@staticmethod
|
2024-02-05 08:04:02 +00:00
|
|
|
def process_packet(packet: SphinxPacket, route: List[MixNodeInfo]) -> Fragment:
|
2024-01-15 06:17:35 +00:00
|
|
|
processed = packet.process(route[0].encryption_private_key)
|
|
|
|
if isinstance(processed, ProcessedFinalHopPacket):
|
|
|
|
return Fragment.from_bytes(processed.payload.recover_plain_playload())
|
|
|
|
else:
|
|
|
|
processed = processed
|
|
|
|
for node in route[1:]:
|
|
|
|
p = processed.next_packet.process(node.encryption_private_key)
|
|
|
|
if isinstance(p, ProcessedFinalHopPacket):
|
|
|
|
return Fragment.from_bytes(p.payload.recover_plain_playload())
|
|
|
|
else:
|
|
|
|
processed = p
|
|
|
|
assert False
|