diff --git a/voice.py b/voice.py index 696d54d..deb89cb 100644 --- a/voice.py +++ b/voice.py @@ -94,7 +94,7 @@ def _build_e2ee_options() -> rtc.E2EEOptions: shared_key=b"", # empty = per-participant mode ratchet_window_size=10, ratchet_salt=b"LKFrameEncryptionKey", - failure_tolerance=-1, + failure_tolerance=10, key_ring_size=256, key_derivation_function=KDF_HKDF, # Rust FFI applies HKDF; we pass raw base keys ) @@ -145,6 +145,12 @@ class VoiceSession: kp.set_key(p.identity, key, index) logger.info("Live-updated caller raw key[%d] for LK identity %s", index, p.identity) + # Also update shared_key fallback — FFI may use this for incoming decryption. + try: + kp.set_shared_key(key, index) + logger.info("Live-updated shared_key fallback[%d]", index) + except Exception: + pass except Exception as e: logger.warning("Failed to live-update caller key: %s", e) @@ -358,6 +364,18 @@ class VoiceSession: elif not remote_identity: logger.warning("No remote participant found — caller keys not set") + # Fallback: also set shared_key to the most recent caller key. + # In the patched Rust FFI, per-participant decryption may fall back to shared_key + # for incoming audio. This was confirmed working in e3ede3f (Feb 21 19:40 UTC). + if self._caller_key: + try: + max_idx = max(self._caller_all_keys.keys()) if self._caller_all_keys else 0 + kp.set_shared_key(self._caller_key, max_idx) + logger.info("Set shared_key fallback to caller key[%d] (%d bytes)", + max_idx, len(self._caller_key)) + except Exception as e: + logger.warning("Failed to set shared_key fallback: %s", e) + if remote_identity: logger.info("Linking to remote participant: %s", remote_identity)