Adventures in Open Source

NeoChat, encryption, and thanks for all the olms

Ever since work on NeoChat has started in 2020, the most requested feature has been support for end-to-end (E2EE) encrypted rooms. Unfortunately, while libQuotient, the library NeoChat uses for dealing with the Matrix protocol, had some pre-existing support for E2EE, it was not in a functional state at that time and was thus not enabled by default.


Early in 2021, Carl and I were made aware of NLnet, a dutch foundation that sponsors many open source projects, and decided to apply for some funding there to expedite the development process. Fortunately, the application process at NLnet is very light-weight, so there isn't a lot of risk involved in applying for funding. A while after sending our application, NLnet got back to us with the good news that they would indeed be funding E2EE work for NeoChat and libQuotient.

The actual development work started with creating Qt-Style bindings for libOlm, the library that provides implementations of the cryptographic functions required for implementing end-to-end encryption in matrix. Most of this work was done by Carl and is now merged into libQuotient.

Building on this foundation, we implemented support for reading and sending encrypted messages into libQuotient. This includes support for all of the different types like texts, images, files, audio and others. By integrating this into libQuotient, this is almost completely transparent to the actual application, meaning that for the most part, app developers building on top of libQuotient do not need to do extra work for supporting E2EE. There are some parts, like loading images and notifications, that will need slight adaptions from how they were implemented before supporting E2EE. If you, as an app developer, have questions about those, come talk to us in

The last part of end-to-end encryption that has been implemented so far is device verification. Device verification allows users to verify that their devices are actually who they claim they are and are not subject to, for example, a man-in-the-middle attack.

What works right now

For this to work, you need to use a dev-branch build of libQuotient with the correct build flags and a build of NeoChat from the master branch. (You will not find the correct versions of libQuotient or NeoChat in your package manager yet; if you do, please tell the packagers not to ship them yet 😃).

NeoChat can show new messages in all of your encrypted rooms and send useful notifications for them. It can also send all types of messages in those rooms, including through the Quick-Reply feature KNotifications offers on some platforms.

You can also verify your other devices by comparing emojis. This can be started either from a different client or from NeoChat's device settings page.

There is one known bug that sometimes causes the first message sent from a megolm session (this typically means the first message sent from a specific device) to not be decryptable. This is purely a UI bug and restarting NeoChat should fix it. This is actually a bug in Qt that will hopefully be fixed upstream soon.

Coming soon

The immediate next step is releasing version 0.7 of libQuotient, which will contain all of the previously mentioned features. We're currently in a phase of several beta releases for this, which means that the final release will be coming very soon. At that point, distros will be able to start shipping E2EE-enabled versions of libQuotient and NeoChat. (At this point i should probably mention that this is still not the most mature work and will thus not be enabled by default 😃)

Next steps

The next features we will implement are:

  • Cross-signing, which allows users to verify the identity of other users in a simple way.
  • Recovery from undecryptable messages, building on the previous device verification work
  • Secure Secret Storage and Sharing (SSSS), which is a method of securely storing encryption keys server-side, which allows us to load existing messages on a new device.
  • By this time, the matrix community will have probably come up with more amazing things to implement 😃

Special Thanks

  • NLnet, for funding this work (Sorry for taking so long!)
  • Alexey Rusakov, maintainer of libQuotient, for spending a lot of his time reviewing my merge requests and a lot of the rest of his time working on libQuotient in general
  • Carl Schwan, for reviewing all of my merge requests and working on NeoChat in general
  • James & Jan, for reporting a lot of bugs, fixing a lot of bugs and adding many new features & improvements
  • Everybody else who uses & tests NeoChat, reports bugs, fixes bugs, implements features, ...

Lessons learned

  • Implementing end-to-end encryption is hard
  • It is also a lot of fun :)
  • Applying for an NLnet grant is easy, you should do it

Getting involved

There's always more things to do in NeoChat. Come talk to us in and have a look at