Добавлен класс TyNetworkManager для управления сетевыми соединениями и класс TyCryptoEngine для шифрования сообщений

This commit is contained in:
lohrrrr 2026-06-03 11:33:35 +00:00
parent f57e525194
commit 4cdedfef83
2 changed files with 84 additions and 5 deletions

78
lib/nwman.py Normal file
View file

@ -0,0 +1,78 @@
import socket
import threading
import sys
class TyNetworkManager:
def __init__(self, on_packet_received):
self.sock = None
self.on_packet_received = on_packet_received
self.is_running = False
def connect(self, host: str, port: int) -> bool:
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, port))
self.is_running = True
threading.Thread(target=self._read_loop, daemon=True).start()
return True
except Exception:
return False
def send_packet(self, packet: bytes) -> bool:
if not self.sock or not self.is_running:
return False
try:
self.sock.sendall(packet)
return True
except Exception:
self.disconnect()
return False
def register_id(self, my_id: int):
header = bytes([0x01, 0x03]) + my_id.to_bytes(3, 'big') + (0).to_bytes(3, 'big')
meta = b'\x00' * 12 + (0).to_bytes(4, 'big')
self.send_packet(header + meta)
def disconnect(self):
self.is_running = False
if self.sock:
try:
self.sock.close()
except Exception:
pass
self.sock = None
def _read_loop(self):
while self.is_running:
try:
header = self._recv_exact(8)
if not header:
break
meta = self._recv_exact(16)
if not meta:
break
iv = meta[0:12]
payload_len = int.from_bytes(meta[12:16], 'big')
payload = b""
if payload_len > 0:
payload = self._recv_exact(payload_len)
if not payload:
break
self.on_packet_received(header, iv, payload)
except Exception:
break
self.disconnect()
def _recv_exact(self, length: int) -> bytes:
data = b""
while len(data) < length:
chunk = self.sock.recv(length - len(data))
if not chunk:
return b""
data += chunk
return data

View file

@ -4,20 +4,22 @@ from cryptography.hazmat.primitives.asymmetric import ed25519, x25519
from cryptography.hazmat.primitives.ciphers.aead import AESGCM from cryptography.hazmat.primitives.ciphers.aead import AESGCM
class TyCryptoEngine: class TyCryptoEngine:
def __init__(self, static_private_bytes=None): def __init__(self, wallet_bytes=None):
if static_private_bytes: if wallet_bytes:
self.id_priv = ed25519.Ed25519PrivateKey.from_private_bytes(static_private_bytes) self.id_priv = ed25519.Ed25519PrivateKey.from_private_bytes(wallet_bytes)
else: else:
self.id_priv = ed25519.Ed25519PrivateKey.generate() self.id_priv = ed25519.Ed25519PrivateKey.generate()
self.id_pub = self.id_priv.public_key() self.id_pub = self.id_priv.public_key()
self.id_pub_bytes = self.id_pub.public_bytes_raw() self.id_pub_bytes = self.id_pub.public_bytes_raw()
# Наш неизменный ID (6 знаков), намертво привязанный к ключу
self.my_id = int(hashlib.sha256(self.id_pub_bytes).hexdigest(), 16) % 1000000 self.my_id = int(hashlib.sha256(self.id_pub_bytes).hexdigest(), 16) % 1000000
self.ek_priv = None self.ek_priv = None
self.aesgcm = None self.aesgcm = None
def get_private_bytes(self) -> bytes: def export_wallet(self) -> bytes:
return self.id_priv.private_bytes_raw() return self.id_priv.private_bytes_raw()
def make_handshake_packet(self, receiver_id: int) -> bytes: def make_handshake_packet(self, receiver_id: int) -> bytes:
@ -80,7 +82,6 @@ class TyCryptoEngine:
@staticmethod @staticmethod
def parse_header(header_bytes: bytes) -> tuple[int, int, int]: def parse_header(header_bytes: bytes) -> tuple[int, int, int]:
version = header_bytes[0]
packet_type = header_bytes[1] packet_type = header_bytes[1]
sender_id = int.from_bytes(header_bytes[2:5], 'big') sender_id = int.from_bytes(header_bytes[2:5], 'big')
receiver_id = int.from_bytes(header_bytes[5:8], 'big') receiver_id = int.from_bytes(header_bytes[5:8], 'big')