Skip to content

Commit f5a4b07

Browse files
committed
fix: update shared constants to reflect new NIST sizes
1 parent 443b57f commit f5a4b07

File tree

4 files changed

+35
-22
lines changed

4 files changed

+35
-22
lines changed

core/constants.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
SMP_NONCE_LENGTH = 64
2020
SMP_PROOF_LENGTH = 64
2121
SMP_ANSWER_OUTPUT_LEN = 64
22-
SMP_QUESTION_MAX_LEN = 500
22+
SMP_QUESTION_MAX_LEN = 512
23+
24+
KEYS_HASH_CHAIN_LEN = 64
25+
MESSAGE_HASH_CHAIN_LEN = 64
26+
2327

2428
# NIST-specified key sizes (bytes) and metadata
2529
ML_KEM_1024_NAME = "ML-KEM-1024"
@@ -29,18 +33,17 @@
2933

3034

3135
ML_DSA_87_NAME = "ML-DSA-87"
32-
ML_DSA_87_SK_LEN = 4864
36+
ML_DSA_87_SK_LEN = 4896
3337
ML_DSA_87_PK_LEN = 2592
34-
ML_DSA_87_SIGN_LEN = 4595
35-
38+
ML_DSA_87_SIGN_LEN = 4627
3639

37-
CLASSIC_MCELIECE_8_F_NAME = "Classic-McEliece-8192128f"
38-
CLASSIC_MCELIECE_8_F_SK_LEN = 14120
39-
CLASSIC_MCELIECE_8_F_PK_LEN = 1357824
40-
CLASSIC_MCELIECE_8_F_CT_LEN = 208
4140

41+
CLASSIC_MCELIECE_8_F_NAME = "Classic-McEliece-8192128f"
42+
CLASSIC_MCELIECE_8_F_SK_LEN = 14120
43+
CLASSIC_MCELIECE_8_F_PK_LEN = 1357824
44+
CLASSIC_MCELIECE_8_F_CT_LEN = 208
4245

43-
CLASSIC_MCELIECE_8_F_ROTATE_AT = 3 # Default OTP batches needed to be sent for a key rotation to occur
46+
CLASSIC_MCELIECE_8_F_ROTATE_AT = 3 # Default OTP batches needed to be sent for a key rotation to occur
4447

4548

4649

core/requests.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
from urllib import request
1+
from urllib import request, error
2+
import urllib
23
import json
4+
import logging
5+
6+
logger = logging.getLogger(__name__)
37

48
_ORIGINAL_SOCKET = None
59

@@ -66,10 +70,15 @@ def http_request(url: str, method: str, auth_token: str = None, payload: dict =
6670
req.add_header("Authorization", "Bearer " + auth_token)
6771

6872
# NOTE: urllib raises a HTTPError for status code >= 400
69-
if longpoll == -1:
70-
with request.urlopen(req) as response:
71-
return json.loads(response.read().decode())
72-
else:
73-
with request.urlopen(req, timeout=longpoll) as response:
74-
return json.loads(response.read().decode())
7573

74+
try:
75+
if longpoll == -1:
76+
with request.urlopen(req) as response:
77+
return json.loads(response.read().decode())
78+
else:
79+
with request.urlopen(req, timeout=longpoll) as response:
80+
return json.loads(response.read().decode())
81+
except urllib.error.HTTPError as e:
82+
body = e.read().decode()
83+
logger.error("We received error from server: %s", body)
84+
raise Exception(body)

logic/pfs.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
ML_KEM_1024_NAME,
1212
ML_DSA_87_NAME,
1313
CLASSIC_MCELIECE_8_F_NAME,
14-
CLASSIC_MCELIECE_8_F_ROTATE_AT
14+
CLASSIC_MCELIECE_8_F_ROTATE_AT,
15+
KEYS_HASH_CHAIN_LEN
1516
)
1617
from core.trad_crypto import sha3_512
1718
from base64 import b64encode, b64decode
@@ -39,7 +40,7 @@ def send_new_ephemeral_keys(user_data, user_data_lock, contact_id, ui_queue) ->
3940
if not user_data_copied["contacts"][contact_id]["lt_sign_keys"]["our_hash_chain"]:
4041
with user_data_lock:
4142
# Set up the hash chain's initial seed
42-
user_data["contacts"][contact_id]["lt_sign_keys"]["our_hash_chain"] = secrets.token_bytes(64)
43+
user_data["contacts"][contact_id]["lt_sign_keys"]["our_hash_chain"] = secrets.token_bytes(KEYS_HASH_CHAIN_LEN)
4344

4445
our_hash_chain = user_data["contacts"][contact_id]["lt_sign_keys"]["our_hash_chain"]
4546
else:
@@ -157,7 +158,7 @@ def pfs_data_handler(user_data, user_data_lock, user_data_copied, ui_queue, mess
157158
logger.error("contact (%s) sent message of unknown pfs_type (%s)", contact_id, message["pfs_type"])
158159
return
159160

160-
contact_hash_chain = contact_publickeys_hashchain[:64]
161+
contact_hash_chain = contact_publickeys_hashchain[:KEYS_HASH_CHAIN_LEN]
161162

162163
# If we do not have a hashchain for the contact, we don't need to compute the chain, just save.
163164
if not user_data_copied["contacts"][contact_id]["lt_sign_keys"]["contact_hash_chain"]:
@@ -172,11 +173,11 @@ def pfs_data_handler(user_data, user_data_lock, user_data_copied, ui_queue, mess
172173
logger.error("Contact hash chain does not match our computed hash chain, we are skipping this PFS message...")
173174
return
174175

175-
contact_kyber_public_key = contact_publickeys_hashchain[64: ALGOS_BUFFER_LIMITS[ML_KEM_1024_NAME]["PK_LEN"] + 64]
176+
contact_kyber_public_key = contact_publickeys_hashchain[KEYS_HASH_CHAIN_LEN: ALGOS_BUFFER_LIMITS[ML_KEM_1024_NAME]["PK_LEN"] + KEYS_HASH_CHAIN_LEN]
176177
if message["pfs_type"] == "full":
177178
logger.info("contact (%s) has rotated their Kyber and McEliece keys", contact_id)
178179

179-
contact_mceliece_public_key = contact_publickeys_hashchain[ALGOS_BUFFER_LIMITS[ML_KEM_1024_NAME]["PK_LEN"] + 64:]
180+
contact_mceliece_public_key = contact_publickeys_hashchain[ALGOS_BUFFER_LIMITS[ML_KEM_1024_NAME]["PK_LEN"] + KEYS_HASH_CHAIN_LEN:]
180181
with user_data_lock:
181182
user_data["contacts"][contact_id]["ephemeral_keys"]["contact_public_keys"][CLASSIC_MCELIECE_8_F_NAME] = contact_mceliece_public_key
182183

logic/smp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ def smp_step_4(user_data, user_data_lock, contact_id, message, ui_queue) -> None
245245

246246
# Derieve a high-entropy secret key from the low-entropy answer
247247
argon2id_salt = sha3_512(our_nonce + contact_nonce)
248-
answer_secret, _ = derive_key_argon2id(answer.encode(), salt=argon2id_salt, output_length=64)
248+
answer_secret, _ = derive_key_argon2id(answer.encode(), salt=argon2id_salt, output_length=SMP_ANSWER_OUTPUT_LEN)
249249

250250
# Compute the proof
251251
our_message = our_nonce + contact_nonce + our_key_fingerprint

0 commit comments

Comments
 (0)