59 lines
1.5 KiB
Python
Raw Normal View History

from __future__ import annotations
import random
from dataclasses import dataclass
2024-06-26 14:22:16 +09:00
from typing import List
from cryptography.hazmat.primitives.asymmetric.x25519 import (
X25519PrivateKey,
X25519PublicKey,
)
2024-06-26 14:22:16 +09:00
from pysphinx.sphinx import Node as SphinxNode
@dataclass
class MixnetConfig:
2024-06-26 14:22:16 +09:00
node_configs: List[NodeConfig]
membership: MixMembership
@dataclass
2024-06-26 14:22:16 +09:00
class NodeConfig:
private_key: X25519PrivateKey
conn_degree: int # Connection Degree (default: 6)
transmission_rate_per_sec: int # Global Transmission Rate
@dataclass
2024-06-26 14:22:16 +09:00
class MixMembership:
nodes: List[NodePublicInfo]
2024-06-26 14:22:16 +09:00
def generate_route(
self, num_hops: int, last_mix: NodePublicInfo
) -> list[NodePublicInfo]:
"""
Generate a mix route for a Sphinx packet.
The pre-selected mix_destination is used as a last mix node in the route,
so that associated packets can be merged together into a original message.
"""
2024-06-26 14:22:16 +09:00
route = [self.choose() for _ in range(num_hops - 1)]
route.append(last_mix)
return route
2024-06-26 14:22:16 +09:00
def choose(self) -> NodePublicInfo:
"""
2024-06-26 14:22:16 +09:00
Choose a mix node as a mix destination that will reconstruct a message from Sphinx packets.
"""
2024-06-26 14:22:16 +09:00
return random.choice(self.nodes)
@dataclass
2024-06-26 14:22:16 +09:00
class NodePublicInfo:
private_key: X25519PrivateKey
def encryption_public_key(self) -> X25519PublicKey:
2024-06-26 14:22:16 +09:00
return self.private_key.public_key()
2024-06-26 14:22:16 +09:00
def sphinx_node(self) -> SphinxNode:
return SphinxNode(self.private_key, bytes(32))