Skip to content
This repository was archived by the owner on Mar 10, 2026. It is now read-only.

Commit 1f234dd

Browse files
committed
fix: recalculate hash chain when our available pads are not enough and we have to generate new pads
1 parent 1662a4d commit 1f234dd

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

logic/message.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,16 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
8282

8383

8484
with user_data_lock:
85-
our_pads = user_data["contacts"][contact_id]["our_pads"]["pads"]
85+
our_pads = user_data["contacts"][contact_id]["our_pads"]["pads"]
86+
87+
rotation_counter = user_data["contacts"][contact_id]["ephemeral_keys"]["rotation_counter"]
88+
rotate_at = user_data["contacts"][contact_id]["ephemeral_keys"]["rotate_at"]
89+
8690

8791
# If we have keys, but no one-time-pads, we send new pads to the contact
8892
if not our_pads:
8993
logger.debug("We have no pads to send message")
9094

91-
with user_data_lock:
92-
93-
rotation_counter = user_data["contacts"][contact_id]["ephemeral_keys"]["rotation_counter"]
94-
rotate_at = user_data["contacts"][contact_id]["ephemeral_keys"]["rotate_at"]
95-
9695

9796
# We rotate keys before generating and sending new batch of pads because
9897
# ephemeral key exchanges always get processed before messages do.
@@ -115,7 +114,6 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
115114

116115
with user_data_lock:
117116
our_pads = user_data["contacts"][contact_id]["our_pads"]["pads"]
118-
119117
user_data["contacts"][contact_id]["ephemeral_keys"]["rotation_counter"] += 1
120118

121119
logger.debug("Incremented rotation_counter by 1. (%d)", rotation_counter)
@@ -126,20 +124,35 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
126124

127125

128126
message_encoded = message.encode("utf-8")
129-
130127
next_hash_chain = sha3_512(our_hash_chain + message_encoded)
131-
132128
message_encoded = next_hash_chain + message_encoded
133129

134130
message_otp_padding_length = max(0, OTP_PADDING_LIMIT - OTP_PADDING_LENGTH - len(message_encoded))
135131

136132
if (len(message_encoded) + OTP_PADDING_LENGTH + message_otp_padding_length) > len(our_pads):
137-
ui_queue.put({"type": "showerror", "title": "Failed to send message", "message": f"Your message size ({len(message_encoded) + OTP_PADDING_LENGTH + message_otp_padding_length}) is larger than our pads size ({len(our_pads)}), please send a shorter message"})
138-
return False
133+
logger.info("Your message size (%d) is larger than our pads size (%s), therefore we are generating new pads for you", len(message_encoded) + OTP_PADDING_LENGTH + message_otp_padding_length, len(our_pads))
134+
135+
if not generate_and_send_pads(user_data, user_data_lock, contact_id, ui_queue):
136+
return False
137+
138+
with user_data_lock:
139+
our_pads = user_data["contacts"][contact_id]["our_pads"]["pads"]
140+
our_hash_chain = user_data["contacts"][contact_id]["our_pads"]["hash_chain"]
141+
142+
user_data["contacts"][contact_id]["ephemeral_keys"]["rotation_counter"] += 1
143+
144+
logger.debug("Incremented rotation_counter by 1. (%d)", rotation_counter)
145+
146+
# We remove old hashchain from message and calculate new next hash in the chain
147+
message_encoded = message_encoded[64:]
148+
next_hash_chain = sha3_512(our_hash_chain + message_encoded)
149+
message_encoded = next_hash_chain + message_encoded
150+
139151

140152
message_otp_pad = our_pads[:len(message_encoded) + OTP_PADDING_LENGTH + message_otp_padding_length]
141153

142154
logger.debug("Our pad size is %d and new size after the message is %d", len(our_pads), len(our_pads) - len(message_otp_pad))
155+
143156
# We one-time-pad encrypt the message with padding
144157
#
145158
# NOTE: The padding only protects short-messages which are easy to infer what is said based purely on message length

0 commit comments

Comments
 (0)