2929)
3030from core .constants import (
3131 MSG_TYPE ,
32- MESSAGE_HASH_CHAIN_LEN ,
3332 OTP_MAX_BUCKET ,
3433 OTP_PAD_SIZE ,
3534 ML_KEM_1024_NAME ,
@@ -78,12 +77,10 @@ def generate_and_send_pads(user_data, user_data_lock, contact_id: str, ui_queue)
7877
7978 otp_batch_signature = create_signature (ML_DSA_87_NAME , kyber_ciphertext_blob + mceliece_ciphertext_blob , our_lt_private_key )
8079
81- hash_chain_seed = sha3_512 (secrets .token_bytes (MESSAGE_HASH_CHAIN_LEN ))
82-
8380 our_new_strand_nonce = sha3_512 (secrets .token_bytes (XCHACHA20POLY1305_NONCE_LEN ))[:XCHACHA20POLY1305_NONCE_LEN ]
8481 _ , ciphertext_blob = encrypt_xchacha20poly1305 (
8582 our_strand_key ,
86- MSG_TYPE + b"\x00 " + our_new_strand_nonce + hash_chain_seed + otp_batch_signature + kyber_ciphertext_blob + mceliece_ciphertext_blob + xchacha_shared_secrets ,
83+ MSG_TYPE + b"\x00 " + our_new_strand_nonce + otp_batch_signature + kyber_ciphertext_blob + mceliece_ciphertext_blob + xchacha_shared_secrets ,
8784 nonce = our_next_strand_nonce
8885 )
8986
@@ -109,9 +106,8 @@ def generate_and_send_pads(user_data, user_data_lock, contact_id: str, ui_queue)
109106 with user_data_lock :
110107 user_data ["contacts" ][contact_id ]["our_next_strand_nonce" ] = our_new_strand_nonce
111108 user_data ["contacts" ][contact_id ]["our_strand_key" ] = our_strand_key
112- user_data ["contacts" ][contact_id ]["our_pads" ][ "pads" ] = pads [32 :]
109+ user_data ["contacts" ][contact_id ]["our_pads" ] = pads [32 :]
113110
114- user_data ["contacts" ][contact_id ]["our_pads" ]["hash_chain" ] = hash_chain_seed
115111
116112 save_account_data (user_data , user_data_lock )
117113
@@ -137,7 +133,7 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
137133 contact_kyber_public_key = user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["contact_public_keys" ][ML_KEM_1024_NAME ]
138134 contact_mceliece_public_key = user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["contact_public_keys" ][CLASSIC_MCELIECE_8_F_NAME ]
139135
140- our_pads = user_data ["contacts" ][contact_id ]["our_pads" ][ "pads" ]
136+ our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]
141137
142138
143139
@@ -162,10 +158,7 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
162158
163159
164160 with user_data_lock :
165- our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ]
166-
167- with user_data_lock :
168- our_hash_chain = user_data ["contacts" ][contact_id ]["our_pads" ]["hash_chain" ]
161+ our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]
169162
170163
171164
@@ -182,29 +175,26 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
182175 logger .debug ("Our old pad size is %d and new size after the message is %d" , len (our_pads ), len (new_pads ))
183176 break
184177 except ValueError as e :
185- logger .debug ("Failed to encrypt message to contact (%s) with error: %s" , contact_id , str (e ))
178+ logger .debug ("Couldnt encrypt message to contact (%s) with error: %s" , contact_id , str (e ))
186179 logger .info ("Your message size (%d) when padded, is larger than our pads size (%s), therefore we are generating new pads for you" , len (message ), len (our_pads ))
187180
188181 if not generate_and_send_pads (user_data , user_data_lock , contact_id , ui_queue ):
189182 return False
190183
191184 with user_data_lock :
192- our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ]
193- our_hash_chain = user_data ["contacts" ][contact_id ]["our_pads" ]["hash_chain" ]
185+ our_pads = user_data ["contacts" ][contact_id ]["our_pads" ]
194186
195187
196188
197189 # Unlike in other functions, we truncate pads here and compute the next hash chain regardless of request being successful or not
198190 # because a malicious server could make our requests fail to force us to re-use the same pad for our next message
199191 # which would break all of our security
200192
201- next_hash_chain = sha3_512 (our_hash_chain + message_encrypted )
202193
203194 our_new_strand_nonce = sha3_512 (secrets .token_bytes (XCHACHA20POLY1305_NONCE_LEN ))[:XCHACHA20POLY1305_NONCE_LEN ]
204195
205196 with user_data_lock :
206- user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ] = user_data ["contacts" ][contact_id ]["our_pads" ]["pads" ][len (message_encrypted ):]
207- user_data ["contacts" ][contact_id ]["our_pads" ]["hash_chain" ] = next_hash_chain
197+ user_data ["contacts" ][contact_id ]["our_pads" ] = user_data ["contacts" ][contact_id ]["our_pads" ][len (message_encrypted ):]
208198
209199 our_strand_key = user_data ["contacts" ][contact_id ]["our_strand_key" ]
210200
@@ -215,7 +205,7 @@ def send_message_processor(user_data, user_data_lock, contact_id: str, message:
215205
216206 _ , ciphertext_blob = encrypt_xchacha20poly1305 (
217207 our_strand_key ,
218- MSG_TYPE + b"\x01 " + our_new_strand_nonce + next_hash_chain + message_encrypted ,
208+ MSG_TYPE + b"\x01 " + our_new_strand_nonce + message_encrypted ,
219209 nonce = our_next_strand_nonce
220210 )
221211
@@ -273,16 +263,14 @@ def messages_data_handler(user_data: dict, user_data_lock, user_data_copied: dic
273263
274264 # /32 because KEM shared_secret is 32 bytes, /64 because sha3_512 output is 64 bytes
275265
276- if len (msgs_plaintext ) != ( (ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 )) + (64 * (OTP_PAD_SIZE // 64 )) + ML_DSA_87_SIGN_LEN + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 :
266+ if len (msgs_plaintext ) != ( (ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 )) + (64 * (OTP_PAD_SIZE // 64 )) + ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 :
277267 logger .error ("Contact (%s) gave us a otp batch message request with malformed strand plaintext length (%d)" , contact_id , len (msgs_plaintext ))
278268 return
279269
280- otp_hashchain_signature = msgs_plaintext [1 + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN : MESSAGE_HASH_CHAIN_LEN + ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 ]
281- otp_hashchain_ciphertext = msgs_plaintext [ML_DSA_87_SIGN_LEN + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 : ML_DSA_87_SIGN_LEN + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 + ((ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 ))]
270+ otp_hashchain_signature = msgs_plaintext [1 + XCHACHA20POLY1305_NONCE_LEN : ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 ]
271+ otp_hashchain_ciphertext = msgs_plaintext [ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 : ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 + ((ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 ))]
282272
283- xchacha_pads = msgs_plaintext [ML_DSA_87_SIGN_LEN + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 + ((ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 )):]
284-
285- contact_hash_chain = msgs_plaintext [1 + XCHACHA20POLY1305_NONCE_LEN : MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 ]
273+ xchacha_pads = msgs_plaintext [ML_DSA_87_SIGN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 + ((ML_KEM_1024_CT_LEN + CLASSIC_MCELIECE_8_F_CT_LEN ) * (OTP_PAD_SIZE // 32 )):]
286274
287275 try :
288276 valid_signature = verify_signature (ML_DSA_87_NAME , otp_hashchain_ciphertext , otp_hashchain_signature , contact_public_key )
@@ -316,10 +304,9 @@ def messages_data_handler(user_data: dict, user_data_lock, user_data_copied: dic
316304
317305
318306 with user_data_lock :
319- user_data ["contacts" ][contact_id ]["contact_pads" ]["pads" ] = contact_pads
320- user_data ["contacts" ][contact_id ]["contact_pads" ]["hash_chain" ] = contact_hash_chain
307+ user_data ["contacts" ][contact_id ]["contact_pads" ] = contact_pads
321308
322- user_data ["contacts" ][contact_id ]["contact_strand_key" ] = contact_strand_key
309+ user_data ["contacts" ][contact_id ]["contact_strand_key" ] = contact_strand_key
323310
324311 user_data ["contacts" ][contact_id ]["ephemeral_keys" ]["our_keys" ][CLASSIC_MCELIECE_8_F_NAME ]["rotation_counter" ] += 1
325312
@@ -344,25 +331,16 @@ def messages_data_handler(user_data: dict, user_data_lock, user_data_copied: dic
344331 elif msgs_plaintext [0 ] == 1 :
345332 logger .debug ("Received a new message from contact (%s)." , contact_id )
346333
347- if len (msgs_plaintext ) < OTP_MAX_BUCKET + MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 :
334+ if len (msgs_plaintext ) < OTP_MAX_BUCKET + XCHACHA20POLY1305_NONCE_LEN + 1 :
348335 logger .error ("Contact (%s) gave us a message request with malformed strand plaintext length (%d)" , contact_id , len (msgs_plaintext ))
349336 return
350337
351338
352- hash_chain = msgs_plaintext [1 + XCHACHA20POLY1305_NONCE_LEN : MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 ]
353- message_encrypted = msgs_plaintext [MESSAGE_HASH_CHAIN_LEN + XCHACHA20POLY1305_NONCE_LEN + 1 :]
339+ message_encrypted = msgs_plaintext [XCHACHA20POLY1305_NONCE_LEN + 1 :]
354340
355341
356342 with user_data_lock :
357- contact_pads = user_data ["contacts" ][contact_id ]["contact_pads" ]["pads" ]
358- contact_hash_chain = user_data ["contacts" ][contact_id ]["contact_pads" ]["hash_chain" ]
359-
360-
361- next_hash_chain = sha3_512 (contact_hash_chain + message_encrypted )
362-
363- if next_hash_chain != hash_chain :
364- logger .error ("Message hash chain did not match, this could be a possible replay attack, or a failed tampering attempt. Skipping this message..." )
365- return
343+ contact_pads = user_data ["contacts" ][contact_id ]["contact_pads" ]
366344
367345
368346 if (not contact_pads ) or (len (message_encrypted ) > len (contact_pads )):
@@ -376,10 +354,9 @@ def messages_data_handler(user_data: dict, user_data_lock, user_data_copied: dic
376354 contact_pads = contact_pads [len (message_encrypted ):]
377355
378356
379- # and save the new pads and the hash chain
357+ # save the new pads
380358 with user_data_lock :
381- user_data ["contacts" ][contact_id ]["contact_pads" ]["pads" ] = contact_pads
382- user_data ["contacts" ][contact_id ]["contact_pads" ]["hash_chain" ] = next_hash_chain
359+ user_data ["contacts" ][contact_id ]["contact_pads" ] = contact_pads
383360
384361 save_account_data (user_data , user_data_lock )
385362
0 commit comments