commit c3b2d8ec0f20c7acc12a6bfc3920aa16b80879fb
parent 607a493d7e3066842327338c0dd4f5c45e285477
Author: triesap <tyson@radroots.org>
Date: Tue, 23 Jun 2026 20:33:44 +0000
simplex: accept future official messages with skipped keys
- continue skipped-key lookup when a retained key has a different message number
- let same-chain future messages decrypt through the current receive chain
- keep replay detection for consumed skipped payloads intact
- cover receiving message three before consuming skipped message one
Diffstat:
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/crates/simplex_smp_crypto/src/ratchet.rs b/crates/simplex_smp_crypto/src/ratchet.rs
@@ -507,10 +507,7 @@ impl RadrootsSimplexSmpRatchetState {
continue;
};
if ratchet_header.message_number != skipped.message_number {
- return Err(RadrootsSimplexSmpCryptoError::RatchetMessageRegression {
- received: ratchet_header.message_number,
- current: self.receiving_chain_length,
- });
+ continue;
}
let position = self
.official_skipped_message_keys
@@ -1191,6 +1188,9 @@ mod tests {
let second = sender
.encrypt_official_payload(&shared_secret, b"second", 96)
.unwrap();
+ let third = sender
+ .encrypt_official_payload(&shared_secret, b"third", 96)
+ .unwrap();
assert_eq!(
receiver
@@ -1201,6 +1201,12 @@ mod tests {
assert!(!receiver.is_official_payload_replay(&first).unwrap());
assert_eq!(
receiver
+ .decrypt_official_payload(&shared_secret, &third)
+ .unwrap(),
+ b"third"
+ );
+ assert_eq!(
+ receiver
.decrypt_official_payload(&shared_secret, &first)
.unwrap(),
b"first"