nomos-specs/mixnet/config.py

67 lines
1.9 KiB
Python
Raw Normal View History

from __future__ import annotations
2024-07-05 17:01:11 +09:00
import hashlib
import random
2024-07-05 17:01:11 +09:00
from dataclasses import dataclass, field
2024-06-26 15:55:00 +09:00
from typing import List
from cryptography.hazmat.primitives.asymmetric.x25519 import (
X25519PrivateKey,
X25519PublicKey,
)
2024-06-26 15:55:00 +09:00
from pysphinx.sphinx import Node as SphinxNode
@dataclass
2024-06-27 17:32:22 +09:00
class GlobalConfig:
2024-06-26 15:55:00 +09:00
membership: MixMembership
2024-07-03 23:29:26 +09:00
transmission_rate_per_sec: float # Global Transmission Rate
2024-06-27 17:32:22 +09:00
# TODO: use this to make the size of Sphinx packet constant
max_mix_path_length: int
@dataclass
2024-06-26 15:55:00 +09:00
class NodeConfig:
private_key: X25519PrivateKey
2024-07-03 11:41:29 +09:00
# The target number of peers a node should maintain in its p2p network
2024-06-28 12:26:44 +09:00
peering_degree: int
2024-06-27 17:32:22 +09:00
mix_path_length: int # TODO: use this when creating Sphinx packets
2024-07-05 17:01:11 +09:00
def id(self, short=False) -> str:
id = (
hashlib.sha256(self.private_key.public_key().public_bytes_raw())
.digest()
.hex()
)
return id[:8] if short else id
@dataclass
2024-06-26 15:55:00 +09:00
class MixMembership:
nodes: List[NodeInfo]
2024-07-05 17:01:11 +09:00
rng: random.Random = field(default_factory=random.Random)
2024-06-26 15:55:00 +09:00
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.
"""
2024-06-28 17:37:02 +09:00
return [*(self.choose() for _ in range(num_hops - 1)), last_mix]
2024-06-26 15:55:00 +09:00
def choose(self) -> NodeInfo:
"""
2024-06-26 15:55:00 +09:00
Choose a mix node as a mix destination that will reconstruct a message from Sphinx packets.
"""
2024-07-05 17:01:11 +09:00
return self.rng.choice(self.nodes)
@dataclass
2024-06-26 15:55:00 +09:00
class NodeInfo:
public_key: X25519PublicKey
2024-06-26 15:55:00 +09:00
def sphinx_node(self) -> SphinxNode:
# TODO: Use a pre-signed incentive tx, instead of NodeAddress
dummy_node_addr = bytes(32)
return SphinxNode(self.public_key, dummy_node_addr)