Skip to content

Commit 33211cb

Browse files
authored
Add directional secret derivation and refactor message key
1 parent b3953a2 commit 33211cb

1 file changed

Lines changed: 45 additions & 3 deletions

File tree

src/cyphersyntax/kdf.py

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
55

66

7+
_MAX_SEQUENCE = (1 << 64) - 1
8+
9+
710
def hkdf_expand(secret: bytes, *, length: int, salt: bytes | None, info: bytes) -> bytes:
811
return HKDF(
912
algorithm=hashes.SHA256(),
@@ -28,7 +31,46 @@ def derive_session_root(
2831
)
2932

3033

31-
def derive_message_key(root_key: bytes, sequence: int, suite_name: str) -> tuple[bytes, bytes]:
32-
info = f"CypherSyntax/message/{suite_name}/v1/{sequence}".encode("utf-8")
33-
material = hkdf_expand(root_key, length=44, salt=None, info=info)
34+
def _length_prefixed(value: bytes) -> bytes:
35+
return len(value).to_bytes(4, "big") + value
36+
37+
38+
def derive_directional_secret(
39+
root_key: bytes,
40+
*,
41+
suite_name: str,
42+
sender_public_key: bytes,
43+
recipient_public_key: bytes,
44+
) -> bytes:
45+
suite_bytes = suite_name.encode("utf-8")
46+
info = b"".join(
47+
(
48+
b"CypherSyntax/traffic-secret/v1",
49+
_length_prefixed(suite_bytes),
50+
_length_prefixed(sender_public_key),
51+
_length_prefixed(recipient_public_key),
52+
)
53+
)
54+
return hkdf_expand(root_key, length=32, salt=None, info=info)
55+
56+
57+
def derive_message_key(
58+
root_key: bytes,
59+
sequence: int,
60+
suite_name: str,
61+
*,
62+
sender_public_key: bytes,
63+
recipient_public_key: bytes,
64+
) -> tuple[bytes, bytes]:
65+
if not 0 <= sequence <= _MAX_SEQUENCE:
66+
raise ValueError("message sequence must fit in an unsigned 64-bit integer")
67+
68+
directional_secret = derive_directional_secret(
69+
root_key,
70+
suite_name=suite_name,
71+
sender_public_key=sender_public_key,
72+
recipient_public_key=recipient_public_key,
73+
)
74+
info = b"CypherSyntax/message-key/v1" + sequence.to_bytes(8, "big")
75+
material = hkdf_expand(directional_secret, length=44, salt=None, info=info)
3476
return material[:32], material[32:44]

0 commit comments

Comments
 (0)