diff --git a/voice.py b/voice.py index c3d4f03..0d58160 100644 --- a/voice.py +++ b/voice.py @@ -70,13 +70,16 @@ KDF_HKDF = 1 def _build_e2ee_options(shared_key: bytes) -> rtc.E2EEOptions: - """Build HKDF E2EE options matching Element Call's key derivation.""" + """Build HKDF E2EE options matching Element Call's key derivation. + + Element Call uses: ratchetWindowSize=10, keyringSize=256, salt="LKFrameEncryptionKey" + """ key_opts = rtc.KeyProviderOptions( shared_key=shared_key, - ratchet_window_size=0, + ratchet_window_size=10, ratchet_salt=b"LKFrameEncryptionKey", - failure_tolerance=-1, - key_ring_size=16, + failure_tolerance=10, + key_ring_size=256, key_derivation_function=KDF_HKDF, ) return rtc.E2EEOptions(key_provider_options=key_opts) @@ -186,13 +189,15 @@ class VoiceSession: break await asyncio.sleep(0.1) - # TEMPORARY: Disable E2EE to test if audio pipeline works if self._e2ee_key: - logger.info("Caller E2EE key available (%d bytes) — but E2EE DISABLED for testing", - len(self._e2ee_key)) + shared_key = self._e2ee_key + logger.info("Using caller E2EE key (%d bytes)", len(shared_key)) if self._publish_key_cb: - self._publish_key_cb(self._e2ee_key) - e2ee_opts = None + self._publish_key_cb(shared_key) + e2ee_opts = _build_e2ee_options(shared_key) + else: + logger.warning("No caller E2EE key — connecting WITHOUT encryption") + e2ee_opts = None room_opts = rtc.RoomOptions(e2ee=e2ee_opts) self.lk_room = rtc.Room()