add payload_size config by removing payload padding in sphinx packet
This commit is contained in:
parent
db86a62ec4
commit
654bc6dc67
|
@ -42,6 +42,8 @@ class SimulationConfig:
|
|||
class MixnetConfig:
|
||||
num_nodes: int
|
||||
num_mix_layers: int
|
||||
# A size of a message payload in bytes (e.g. the size of a block proposal)
|
||||
payload_size: int
|
||||
# An interval of sending a new real/cover message
|
||||
# A probability of actually sending a message depends on the following parameters.
|
||||
message_interval: int
|
||||
|
@ -61,6 +63,7 @@ class MixnetConfig:
|
|||
def validate(self):
|
||||
assert self.num_nodes > 0
|
||||
assert 0 < self.num_mix_layers <= self.num_nodes
|
||||
assert self.payload_size > 0
|
||||
assert self.message_interval > 0
|
||||
assert self.real_message_prob > 0
|
||||
assert len(self.real_message_prob_weights) <= self.num_nodes
|
||||
|
|
|
@ -5,6 +5,8 @@ simulation:
|
|||
mixnet:
|
||||
num_nodes: 100
|
||||
num_mix_layers: 3
|
||||
# A size of a message payload in bytes (e.g. the size of a block proposal)
|
||||
payload_size: 320
|
||||
# An interval of sending a new real/cover message
|
||||
# A probability of actually sending a message depends on the following parameters.
|
||||
message_interval: 1
|
||||
|
|
|
@ -15,7 +15,6 @@ from p2p import P2p
|
|||
|
||||
class Node:
|
||||
INCENTIVE_TX_SIZE = 512
|
||||
PAYLOAD = b"BLOCK"
|
||||
PADDING_SEPARATOR = b'\x01'
|
||||
|
||||
def __init__(self, id: int, env: simpy.Environment, p2p: P2p, config: Config):
|
||||
|
@ -72,7 +71,7 @@ class Node:
|
|||
# Set invalid txs for a cover message,
|
||||
# so that nobody will recognize that as a real message to be forwarded to the next mix.
|
||||
incentive_txs = [Attachment(os.urandom(len(bytes(tx)))) for tx in incentive_txs]
|
||||
return SphinxPacket(public_keys, incentive_txs, self.PAYLOAD)
|
||||
return SphinxPacket(public_keys, incentive_txs, self.build_payload())
|
||||
|
||||
def receive_message(self, msg: SphinxPacket | bytes):
|
||||
"""
|
||||
|
@ -85,15 +84,12 @@ class Node:
|
|||
if self.is_my_incentive_tx(incentive_tx):
|
||||
self.log("Receiving SphinxPacket. It's mine!")
|
||||
if msg.is_all_unwrapped():
|
||||
if msg.payload == self.PAYLOAD:
|
||||
# Pad the final msg to the same size as a SphinxPacket,
|
||||
# assuming that the final msg is going to be sent via secure channels (TLS, Noise, etc.)
|
||||
final_padded_msg = (msg.payload
|
||||
+ self.PADDING_SEPARATOR
|
||||
+ bytes(len(msg) - len(msg.payload) - len(self.PADDING_SEPARATOR)))
|
||||
self.env.process(self.p2p.broadcast(self, final_padded_msg))
|
||||
else:
|
||||
self.log("Dropping a cover message: %s" % msg.payload)
|
||||
# Pad the final msg to the same size as a SphinxPacket,
|
||||
# assuming that the final msg is going to be sent via secure channels (TLS, Noise, etc.)
|
||||
final_padded_msg = (msg.payload
|
||||
+ self.PADDING_SEPARATOR
|
||||
+ bytes(len(msg) - len(msg.payload) - len(self.PADDING_SEPARATOR)))
|
||||
self.env.process(self.p2p.broadcast(self, final_padded_msg))
|
||||
else:
|
||||
# TODO: use Poisson delay or something else, if necessary
|
||||
yield self.env.timeout(random.uniform(0, self.config.mixnet.max_mix_delay))
|
||||
|
@ -104,6 +100,9 @@ class Node:
|
|||
final_msg = msg[:msg.rfind(self.PADDING_SEPARATOR)]
|
||||
self.log("Received final message: %s" % final_msg)
|
||||
|
||||
def build_payload(self) -> bytes:
|
||||
return b"P" + bytes(self.config.mixnet.payload_size - len(b"P"))
|
||||
|
||||
# TODO: This is a dummy logic
|
||||
@classmethod
|
||||
def create_incentive_tx(cls, mix_public_key: X25519PublicKey) -> Attachment:
|
||||
|
|
|
@ -5,43 +5,32 @@ from copy import deepcopy
|
|||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PublicKey, X25519PrivateKey
|
||||
|
||||
|
||||
class SphinxPacket:
|
||||
# TODO: define max path length
|
||||
PADDED_PAYLOAD_SIZE = 321
|
||||
PAYLOAD_TRAIL_PADDING_SEPARATOR = b'\x01'
|
||||
|
||||
def __init__(self, public_keys: list[X25519PublicKey], attachments: list[Attachment], payload: bytes):
|
||||
assert len(public_keys) == len(attachments)
|
||||
if len(payload) > self.PADDED_PAYLOAD_SIZE - len(self.PAYLOAD_TRAIL_PADDING_SEPARATOR):
|
||||
raise ValueError("payload too long", len(payload))
|
||||
payload += (self.PAYLOAD_TRAIL_PADDING_SEPARATOR
|
||||
+ bytes(self.PADDED_PAYLOAD_SIZE - len(payload) - len(self.PAYLOAD_TRAIL_PADDING_SEPARATOR)))
|
||||
|
||||
ephemeral_private_key = X25519PrivateKey.generate()
|
||||
ephemeral_public_key = ephemeral_private_key.public_key()
|
||||
shared_keys = [SharedSecret(ephemeral_private_key, pk) for pk in public_keys]
|
||||
self._header = SphinxHeader(ephemeral_public_key, shared_keys, attachments)
|
||||
self._payload = payload # TODO: encrypt payload
|
||||
self.header = SphinxHeader(ephemeral_public_key, shared_keys, attachments)
|
||||
self.payload = payload # TODO: encrypt payload
|
||||
|
||||
def __bytes__(self):
|
||||
return bytes(self._header) + self._payload
|
||||
return bytes(self.header) + self.payload
|
||||
|
||||
def __len__(self):
|
||||
return len(bytes(self))
|
||||
|
||||
def unwrap(self, private_key: X25519PrivateKey) -> tuple[SphinxPacket, Attachment]:
|
||||
packet = deepcopy(self)
|
||||
attachment = packet._header.unwrap_inplace(private_key)
|
||||
attachment = packet.header.unwrap_inplace(private_key)
|
||||
# TODO: decrypt packet._payload
|
||||
return packet, attachment
|
||||
|
||||
def is_all_unwrapped(self) -> bool:
|
||||
return self._header.is_all_unwrapped()
|
||||
|
||||
@property
|
||||
def payload(self) -> bytes:
|
||||
return self._payload[:self._payload.rfind(self.PAYLOAD_TRAIL_PADDING_SEPARATOR)]
|
||||
return self.header.is_all_unwrapped()
|
||||
|
||||
|
||||
class SphinxHeader:
|
||||
|
|
Loading…
Reference in New Issue