feat: replace python-olm with fresholm for Matrix E2EE - #14139
feat: replace python-olm with fresholm for Matrix E2EE#14139cortexuvula wants to merge 1 commit into
Conversation
On macOS, `mautrix[encryption]` pulls in python-olm 3.2.16, which
bundles libolm source containing a C++ const-pointer bug in
`libolm/include/olm/list.hh`:
T * const other_pos = other._data;
// ...
++other_pos; // error: cannot assign to const-qualified variable
Apple clang (Xcode 15+) rejects this as a hard compile error even
without -Werror, so `platform.matrix` lazy-install always fails on
macOS with:
error: subprocess-exited-with-error
× Getting requirements to build wheel did not run successfully.
Fix: when `ensure("platform.matrix")` runs on darwin, pre-install
python-olm from a patched copy of the sdist (one-line removal of the
spurious `const` qualifier) before the main pip install runs.
mautrix[encryption] then finds python-olm already satisfied and skips
the broken bundled-source build.
The patch is idempotent — if the target line is absent (upstream fixed
it), we log a warning and proceed without patching.
Relates to: NousResearch#27795 (adds libolm-dev for Docker, same root cause)
Relates to: NousResearch#14139 (replaces python-olm with fresholm long-term)
|
@cortexuvula Hmm... intriguing alternative for matrix dependencies snafu! Is this just the lazy-install-completion-check failing due to the switch of python-olm with fresholm or what? |
|
Hey @tdussmann — good catch. The issue is that the PR updated the dependencies (pyproject.toml) and added the import hook (line 37), but did NOT update two downstream things:
Can you confirm:
The error message showing the old hint ( That said, the PR is incomplete — I should also update |
>>> from mautrix.crypto import OlmMachine
Traceback (most recent call last):
File "<python-input-0>", line 1, in <module>
from mautrix.crypto import OlmMachine
File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/__init__.py", line 1, in <module>
from .account import OlmAccount
File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/account.py", line 9, in <module>
import olm
ModuleNotFoundError: No module named 'olm'
>>> import fresholm.import_hook
>>> from mautrix.crypto import OlmMachine
Traceback (most recent call last):
File "<python-input-2>", line 1, in <module>
from mautrix.crypto import OlmMachine
File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/__init__.py", line 1, in <module>
from .account import OlmAccount
File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/account.py", line 23, in <module>
from .signature import sign_olm
File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/signature.py", line 11, in <module>
import unpaddedbase64
ModuleNotFoundError: No module named 'unpaddedbase64'I think I got it: the problem stems from not requesting the mautrix[encryption] extra dependencies, which makes mautrix fail to init despite the import_hook of fresholm redirecting all python-olm imports. See: https://github.com/mautrix/python/blob/master/setup.py#L5 |
|
You nailed it @tdussmann.
Pushed a fix (712dbfa80) to the PR branch:
So the complete install for Docker users avoiding python-olm: pip install 'mautrix>=0.20' fresholm unpaddedbase64 pycryptodome base58 asyncpg aiosqliteOr for users who just want the pip install 'mautrix[encryption]' asyncpg aiosqlite |
Replace python-olm (deprecated libolm C bindings) with fresholm
(Rust/vodozemac-backed) for Matrix end-to-end encryption.
Changes:
- pyproject.toml: Replace mautrix[encryption] with explicit deps
(mautrix>=0.20, fresholm, unpaddedbase64, pycryptodome, base58)
- gateway/platforms/matrix.py:
- Add fresholm import hook before mautrix imports
- Update _E2EE_INSTALL_HINT to list all required packages
- Update _check_e2ee_deps() to verify unpaddedbase64/pycryptodome/base58
and fall back to explicit fresholm import hook activation
Why: python-olm requires libolm C headers + CFFI compilation which breaks
on macOS/Windows. fresholm ships pre-built wheels on PyPI.
Refs: #14139
712dbfa to
bcac6b7
Compare
|
Updated the PR with a clean rebase on latest main. All three issues addressed:
PR is mergeable but I don't have permissions to merge on NousResearch. @NousResearch can you merge when CI is green? 🙏 |
|
@cortexuvula I've just tried it out now, removing the installation of libolm-dev package beforehand, however I don't think the import_hook would work without making more changes to the way mautrix is being used... 2026-05-27T23:42:27.178521459Z ERROR mau.http: Failed to run handler
2026-05-27T23:42:27.178598415Z Traceback (most recent call last):
2026-05-27T23:42:27.178614959Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/client/syncer.py", line 241, in _catch_errors
2026-05-27T23:42:27.178621909Z await handler(data)
2026-05-27T23:42:27.178631138Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/machine.py", line 228, in handle_to_device_event
2026-05-27T23:42:27.178642085Z decrypted_evt = await self._decrypt_olm_event(evt)
2026-05-27T23:42:27.178648848Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-05-27T23:42:27.178654676Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/decrypt_olm.py", line 42, in _decrypt_olm_event
2026-05-27T23:42:27.178660457Z plaintext = await self._decrypt_olm_ciphertext(
2026-05-27T23:42:27.178666472Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-05-27T23:42:27.178672284Z evt.sender, evt.content.sender_key, own_content
2026-05-27T23:42:27.178678639Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-05-27T23:42:27.178684796Z )
2026-05-27T23:42:27.178692409Z ^
2026-05-27T23:42:27.178697802Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/decrypt_olm.py", line 88, in _decrypt_olm_ciphertext
2026-05-27T23:42:27.178739707Z session = await self._create_inbound_session(sender_key, message.body)
2026-05-27T23:42:27.178746647Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-05-27T23:42:27.178751257Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/decrypt_olm.py", line 128, in _create_inbound_session
2026-05-27T23:42:27.178755534Z session = self.account.new_inbound_session(sender_key, ciphertext)
2026-05-27T23:42:27.178760083Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/account.py", line 67, in new_inbound_session
2026-05-27T23:42:27.178769419Z session = olm.InboundSession(self, olm.OlmPreKeyMessage(ciphertext), sender_key)
2026-05-27T23:42:27.178773029Z File "/opt/hermes/.venv/lib/python3.13/site-packages/fresholm/compat/olm.py", line 348, in __init__
2026-05-27T23:42:27.178777236Z temp = account.new_inbound_session(identity_key, message)
2026-05-27T23:42:27.178781406Z File "/opt/hermes/.venv/lib/python3.13/site-packages/mautrix/crypto/account.py", line 67, in new_inbound_session
2026-05-27T23:42:27.178785355Z session = olm.InboundSession(self, olm.OlmPreKeyMessage(ciphertext), sender_key)
2026-05-27T23:42:27.178789104Z ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
2026-05-27T23:42:27.178792994Z File "/opt/hermes/.venv/lib/python3.13/site-packages/fresholm/compat/olm.py", line 71, in __init__
2026-05-27T23:42:27.178796954Z raise TypeError(f"ciphertext must be str or bytes, got {type(ciphertext)}")
2026-05-27T23:42:27.178800968Z TypeError: ciphertext must be str or bytes, got <class 'fresholm.compat.olm.OlmPreKeyMessage'>Unfortunately though, since I've now wasted countless hours on trying to get matrix E2EE to work again, to no avail, I'm scratching the idea of having a matrix-channel entirely. Not even creating a fresh new bot-account for hermes was able to get it to work again with the current codebase and dependency versions...
every single time... I suspect the extremely fractionalized ecosystem of Matrix clients/servers/SDKs to be the cause of all those recurring issues. |
Summary
Replace
python-olm(libolm C library) with fresholm (Rust/vodozemac-backed) for Matrix end-to-end encryption.Changes
mautrix[encryption]withmautrix>=0.20,<1+fresholm>=0.2.4import fresholm.import_hookbefore mautrix importsWhy fresholm over python-olm
The import hook intercepts
import olmand transparently redirects to fresholm, so mautrix's crypto layer works unchanged.Testing
Verified locally with Hermes gateway — Matrix/Beeper E2EE connects successfully:
import fresholm.import_hook; import olmloads correctly✓ matrix connectedwith E2EE enabledThis is a 2-file, 5-line change with no behavioral differences for users who don't install the
matrixextra.