Skip to content

Commit 2db3d34

Browse files
committed
progress SAE IDs
1 parent 51a7a98 commit 2db3d34

7 files changed

Lines changed: 103 additions & 23 deletions

File tree

client/__main__.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ async def get_etsi_get_key(slave_sae_id: str, size: int | None = None):
7777
"""
7878
ETSI QKD 014 API: Get Key.
7979
"""
80-
return await _CLIENT.etsi_get_key(slave_sae_id, size=size)
80+
master_sae_id = _CLIENT.name # Currently, SAE names are the same as client names.
81+
return await _CLIENT.etsi_get_key(master_sae_id, slave_sae_id, size)
8182

8283

8384
@_APP.get(f"/client/{_CLIENT.name}/etsi/api/v1/keys/{{master_sae_id}}/dec_keys")
@@ -87,7 +88,8 @@ async def get_eti_get_key_with_key_ids(master_sae_id: str, key_ID: str):
8788
"""
8889
# ETSI QKD 014 says that ID in key_ID has to be upper case, which lint doesn't like.
8990
# pylint: disable=invalid-name
90-
return await _CLIENT.etsi_get_key_with_key_ids(master_sae_id, key_ID)
91+
slave_sae_id = _CLIENT.name # Currently, SAE names are the same as client names.
92+
return await _CLIENT.etsi_get_key_with_key_ids(master_sae_id, slave_sae_id, key_ID)
9193

9294

9395
@_APP.get(f"/client/{_CLIENT.name}/mgmt/v1/status")

client/client.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,12 @@ async def etsi_status(self, slave_sae_id: str):
7070
"max_sae_id_count": 0,
7171
}
7272

73-
async def etsi_get_key(self, _slave_sae_id: str, size: int | None = None):
73+
async def etsi_get_key(
74+
self,
75+
master_sae_id: str,
76+
slave_sae_id: str,
77+
size: int | None = None,
78+
):
7479
"""
7580
ETSI QKD 014 V1.1.1 Get key API.
7681
"""
@@ -89,25 +94,25 @@ async def etsi_get_key(self, _slave_sae_id: str, size: int | None = None):
8994
)
9095
size_in_bytes = size // 8
9196
key = UserKey.create_random_key(size_in_bytes)
92-
await self.scatter_key_amongst_peer_hubs(key)
97+
await self.scatter_key_amongst_peer_hubs(master_sae_id, slave_sae_id, key)
9398
return {
9499
"keys": {
95100
"key_ID": key.key_id,
96101
"key": utils.bytes_to_str(key.value),
97102
}
98103
}
99104

100-
async def etsi_get_key_with_key_ids(self, _master_sae_id: str, key_id: str):
105+
async def etsi_get_key_with_key_ids(
106+
self, master_sae_id: str, slave_sae_id: str, key_id: str
107+
):
101108
"""
102109
ETSI QKD 014 V1.1.1 Get key with key IDs API.
103110
"""
104-
# TODO: Pass the master SAE ID and the slave SAE ID along with the relayed shares
105-
# and check that they match here.
106111
try:
107112
key_id = UUID(key_id)
108113
except ValueError as exc:
109114
raise exceptions.InvalidKeyIDError(key_id) from exc
110-
key = await self.gather_key_from_peer_hubs(key_id)
115+
key = await self.gather_key_from_peer_hubs(master_sae_id, slave_sae_id, key_id)
111116
return {
112117
"keys": [
113118
{
@@ -124,15 +129,22 @@ def start_all_peer_hubs(self) -> None:
124129
for peer_hub in self._peer_hubs:
125130
peer_hub.start_register_task()
126131

127-
async def scatter_key_amongst_peer_hubs(self, key: UserKey) -> None:
132+
async def scatter_key_amongst_peer_hubs(
133+
self,
134+
master_sae_id: str,
135+
slave_sae_id: str,
136+
key: UserKey,
137+
) -> None:
128138
"""
129139
Split the key into key shares, and send each key share to a peer hub.
130140
"""
131141
nr_shares = len(self._peer_hubs)
132-
shares = key.split_into_shares(nr_shares, _MIN_NR_SHARES)
142+
shares = key.split_into_shares(
143+
master_sae_id, slave_sae_id, nr_shares, _MIN_NR_SHARES
144+
)
133145
assert len(shares) == nr_shares
134146
coroutines = [
135-
peer_hub.post_share(share)
147+
peer_hub.post_share(master_sae_id, slave_sae_id, share)
136148
for peer_hub, share in zip(self._peer_hubs, shares)
137149
]
138150
results = await asyncio.gather(*coroutines, return_exceptions=True)
@@ -152,13 +164,21 @@ async def scatter_key_amongst_peer_hubs(self, key: UserKey) -> None:
152164
key.key_id, nr_shares_successfully_scattered, _MIN_NR_SHARES, causes
153165
)
154166

155-
async def gather_key_from_peer_hubs(self, key_id: UUID) -> UserKey:
167+
async def gather_key_from_peer_hubs(
168+
self,
169+
master_sae_id: str,
170+
slave_sae_id: str,
171+
key_id: UUID,
172+
) -> UserKey:
156173
"""
157174
Gather key shares from the peer hubs, and reconstruct the key out of (a subset of)
158175
the key shares.
159176
"""
160177
nr_shares_attempted_to_gather = len(self._peer_hubs)
161-
coroutines = [peer_hub.get_share(key_id) for peer_hub in self._peer_hubs]
178+
coroutines = [
179+
peer_hub.get_share(master_sae_id, slave_sae_id, key_id)
180+
for peer_hub in self._peer_hubs
181+
]
162182
results = await asyncio.gather(*coroutines, return_exceptions=True)
163183
shares = [result for result in results if not isinstance(result, Exception)]
164184
nr_shares_successfully_gathered = len(shares)

client/peer_hub.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,15 +212,19 @@ async def attempt_request_psrd(self, pool: Pool) -> bool:
212212
pool.add_block(block)
213213
return True
214214

215-
async def post_share(self, share: Share) -> None:
215+
async def post_share(
216+
self, master_sae_id: str, slave_sae_id: str, share: Share
217+
) -> None:
216218
"""
217219
Post a key share to the peer hub.
218220
"""
219221
try:
220222
url = f"{self._base_url}/dske/api/v1/key-share"
221223
encryption_key = EncryptionKey.from_pool(self._local_pool, share.size)
222224
request = APIPostShareRequest(
223-
client_name=self._client.name,
225+
master_client_name=self._client.name,
226+
master_sae_id=master_sae_id,
227+
slave_sae_id=slave_sae_id,
224228
user_key_id=str(share.user_key_id),
225229
share_index=share.share_index,
226230
encryption_key_allocation=encryption_key.allocation.to_api(),
@@ -236,14 +240,18 @@ async def post_share(self, share: Share) -> None:
236240
self.delete_fully_used_blocks()
237241
self.start_request_psrd_task_if_needed()
238242

239-
async def get_share(self, key_id: UUID) -> Share:
243+
async def get_share(
244+
self, master_sae_id: str, slave_sae_id: str, key_id: UUID
245+
) -> Share:
240246
"""
241247
Get a key share from the peer hub.
242248
"""
243249
try:
244250
url = f"{self._base_url}/dske/api/v1/key-share"
245251
params = {
246252
"client_name": self._client.name,
253+
"master_sae_id": master_sae_id,
254+
"slave_sae_id": slave_sae_id,
247255
"key_id": str(key_id),
248256
}
249257
response = await self._http_client.get(
@@ -259,7 +267,9 @@ async def get_share(self, key_id: UUID) -> Share:
259267
encrypted_share_value = str_to_bytes(response.encrypted_share_value)
260268
share_value = encryption_key.decrypt(encrypted_share_value)
261269
share = Share(
262-
user_key_id=response,
270+
master_sae_id=master_sae_id,
271+
slave_sae_id=slave_sae_id,
272+
user_key_id=response.key_id,
263273
share_index=response.share_index,
264274
value=share_value,
265275
)

common/share.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,40 @@ class Share:
1212
can be reconstructed from a subset (`min_nr_shares`) of these shares.
1313
"""
1414

15-
def __init__(self, user_key_id: UUID, share_index: int, value: bytes | None = None):
15+
_master_sae_id: str
16+
_slave_sae_id: str
17+
_user_key_id: UUID
18+
_share_index: int
19+
_value: bytes # TODO: Rename to data
20+
21+
def __init__(
22+
self,
23+
master_sae_id: str,
24+
slave_sae_id: str,
25+
user_key_id: UUID,
26+
share_index: int,
27+
value: bytes | None = None,
28+
):
29+
self._master_sae_id = master_sae_id
30+
self._slave_sae_id = slave_sae_id
1631
self._user_key_id = user_key_id
1732
self._share_index = share_index
1833
self._value = value
1934

35+
@property
36+
def master_sae_id(self) -> str:
37+
"""
38+
Get the master SAE ID.
39+
"""
40+
return self._master_sae_id
41+
42+
@property
43+
def slave_sae_id(self) -> str:
44+
"""
45+
Get the slave SAE ID.
46+
"""
47+
return self._slave_sae_id
48+
2049
@property
2150
def user_key_id(self) -> UUID:
2251
"""
@@ -63,6 +92,8 @@ def to_mgmt(self):
6392
Get the management status.
6493
"""
6594
return {
95+
"master_sae_id": self._master_sae_id,
96+
"slave_sae_id": self._slave_sae_id,
6697
"key_id": str(self._user_key_id),
6798
"share_index": self._share_index,
6899
"value": bytes_to_str(self._value, truncate=True),

common/share_api.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,28 @@ class APIPostShareRequest(pydantic.BaseModel):
1111
Model for the POST share request in the API.
1212
"""
1313

14-
client_name: str
14+
master_client_name: str
15+
master_sae_id: str
16+
slave_sae_id: str
1517
user_key_id: str
1618
share_index: int
1719
encryption_key_allocation: APIAllocation
1820
encrypted_share_value: str # Base64 encoded
1921

2022
def __init__(
2123
self,
22-
client_name: str,
24+
master_client_name: str,
25+
master_sae_id: str,
26+
slave_sae_id: str,
2327
user_key_id: str,
2428
share_index: int,
2529
encryption_key_allocation: APIAllocation,
2630
encrypted_share_value: str, # Base64 encoded
2731
):
2832
super().__init__(
29-
client_name=client_name,
33+
master_client_name=master_client_name,
34+
master_sae_id=master_sae_id,
35+
slave_sae_id=slave_sae_id,
3036
user_key_id=user_key_id,
3137
share_index=share_index,
3238
encryption_key_allocation=encryption_key_allocation,

common/user_key.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ def create_random_key(cls, size_in_bytes) -> "UserKey":
5656

5757
def split_into_shares(
5858
self,
59+
master_sae_id: str,
60+
slave_sae_id: str,
5961
nr_shares: int,
6062
min_nr_shares: int,
6163
) -> list[Share]:
@@ -74,6 +76,12 @@ def split_into_shares(
7476
raise ShamirSplitError(self._key_id, str(exc)) from exc
7577
shares = []
7678
for share_index, share_value in share_indexes_and_values:
77-
share = Share(self._key_id, share_index, value=share_value)
79+
share = Share(
80+
master_sae_id,
81+
slave_sae_id,
82+
self._key_id,
83+
share_index,
84+
value=share_value,
85+
)
7886
shares.append(share)
7987
return shares

hub/hub.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ async def store_share_received_from_client(
9393
"""
9494
Store a key share posted by a client.
9595
"""
96-
client_name = api_post_share_request.client_name
96+
client_name = api_post_share_request.master_client_name
9797
if client_name not in self._peer_clients:
9898
raise exceptions.ClientNotRegisteredError(client_name)
9999
peer_client = self._peer_clients[client_name]
@@ -106,7 +106,10 @@ async def store_share_received_from_client(
106106
api_post_share_request.encrypted_share_value
107107
)
108108
share_value = encryption_key.decrypt(encrypted_share_value)
109+
# TODO: Check that master and slave client names match registered client
109110
share = Share(
111+
master_sae_id=api_post_share_request.master_sae_id,
112+
slave_sae_id=api_post_share_request.slave_sae_id,
110113
user_key_id=UUID(api_post_share_request.user_key_id),
111114
share_index=api_post_share_request.share_index,
112115
value=share_value,

0 commit comments

Comments
 (0)