mirror of
https://github.com/logos-co/nomos-specs.git
synced 2025-02-01 10:06:10 +00:00
58 lines
1.5 KiB
Python
58 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
import random
|
|
from dataclasses import dataclass
|
|
from typing import List
|
|
|
|
from cryptography.hazmat.primitives.asymmetric.x25519 import (
|
|
X25519PrivateKey,
|
|
X25519PublicKey,
|
|
)
|
|
from pysphinx.sphinx import Node as SphinxNode
|
|
|
|
|
|
@dataclass
|
|
class MixnetConfig:
|
|
node_configs: List[NodeConfig]
|
|
membership: MixMembership
|
|
|
|
|
|
@dataclass
|
|
class NodeConfig:
|
|
private_key: X25519PrivateKey
|
|
transmission_rate_per_sec: int # Global Transmission Rate
|
|
|
|
|
|
@dataclass
|
|
class MixMembership:
|
|
nodes: List[NodeInfo]
|
|
|
|
def generate_route(self, num_hops: int, last_mix: NodeInfo) -> list[NodeInfo]:
|
|
"""
|
|
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.
|
|
"""
|
|
route = [self.choose() for _ in range(num_hops - 1)]
|
|
route.append(last_mix)
|
|
return route
|
|
|
|
def choose(self) -> NodeInfo:
|
|
"""
|
|
Choose a mix node as a mix destination that will reconstruct a message from Sphinx packets.
|
|
"""
|
|
return random.choice(self.nodes)
|
|
|
|
|
|
@dataclass
|
|
class NodeInfo:
|
|
private_key: X25519PrivateKey
|
|
|
|
def public_key(self) -> X25519PublicKey:
|
|
return self.private_key.public_key()
|
|
|
|
def sphinx_node(self) -> SphinxNode:
|
|
# TODO: Use a pre-signed incentive tx, instead of NodeAddress
|
|
dummy_node_addr = bytes(32)
|
|
return SphinxNode(self.private_key, dummy_node_addr)
|