0b1-protocol 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 0b1_protocol-0.1.0.dist-info/METADATA +246 -0
- 0b1_protocol-0.1.0.dist-info/RECORD +11 -0
- 0b1_protocol-0.1.0.dist-info/WHEEL +4 -0
- 0b1_protocol-0.1.0.dist-info/entry_points.txt +2 -0
- ob1/__init__.py +67 -0
- ob1/agent.py +436 -0
- ob1/cli.py +477 -0
- ob1/client.py +368 -0
- ob1/crypto.py +206 -0
- ob1/keystore.py +130 -0
- ob1/protocol.py +79 -0
ob1/protocol.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""0b1 Protocol Constants and Validators."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
# Protocol constants
|
|
6
|
+
MAGIC_HEADER: bytes = b'\x0b\x01'
|
|
7
|
+
MAGIC_HEADER_HEX: str = "0b01"
|
|
8
|
+
API_BASE_URL: str = "https://0b1.xyz/api"
|
|
9
|
+
DEFAULT_KEY_PATH: Path = Path.home() / ".ob1" / "key.json"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ProtocolError(Exception):
|
|
13
|
+
"""Raised when message violates 0b1 protocol."""
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def validate_blob(blob_hex: str) -> bool:
|
|
18
|
+
"""
|
|
19
|
+
Validate that encrypted blob starts with 0b01 header.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
blob_hex: Hex-encoded encrypted message (e.g., "0b01a7f8...")
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
True if valid
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ProtocolError: If header missing or invalid format
|
|
29
|
+
"""
|
|
30
|
+
if not blob_hex:
|
|
31
|
+
raise ProtocolError("Empty blob")
|
|
32
|
+
|
|
33
|
+
# Normalize: remove 0x prefix if present
|
|
34
|
+
clean = blob_hex.lower()
|
|
35
|
+
if clean.startswith("0x"):
|
|
36
|
+
clean = clean[2:]
|
|
37
|
+
|
|
38
|
+
if not clean.startswith(MAGIC_HEADER_HEX):
|
|
39
|
+
raise ProtocolError(f"Invalid header: expected '{MAGIC_HEADER_HEX}', got '{clean[:4]}'")
|
|
40
|
+
|
|
41
|
+
if len(clean) < 8: # Header + at least some data
|
|
42
|
+
raise ProtocolError("Blob too short")
|
|
43
|
+
|
|
44
|
+
return True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def prepend_header(data: bytes) -> bytes:
|
|
48
|
+
"""
|
|
49
|
+
Prepend MAGIC_HEADER to raw encrypted bytes.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
data: Raw ECIES ciphertext bytes
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
bytes: MAGIC_HEADER + data
|
|
56
|
+
"""
|
|
57
|
+
return MAGIC_HEADER + data
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def strip_header(data: bytes) -> bytes:
|
|
61
|
+
"""
|
|
62
|
+
Remove and validate MAGIC_HEADER from message.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
data: Full message with header
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
bytes: Ciphertext without header
|
|
69
|
+
|
|
70
|
+
Raises:
|
|
71
|
+
ProtocolError: If header invalid
|
|
72
|
+
"""
|
|
73
|
+
if len(data) < 2:
|
|
74
|
+
raise ProtocolError("Data too short for header")
|
|
75
|
+
|
|
76
|
+
if data[:2] != MAGIC_HEADER:
|
|
77
|
+
raise ProtocolError(f"Invalid header bytes: {data[:2].hex()}")
|
|
78
|
+
|
|
79
|
+
return data[2:]
|