One of the defining principles behind web technologies is building things once and making them available everywhere regardless of the device or platform. This inspired us to build a web version of that anyone could use in a WebRTC-enabled browser. Wire However, there’s one major challenge with web applications. JavaScript, the web’s programming language, was built for programmer productivity . It was the right decision by Brendan Eich when he to make interactive websites a reality. at the expense of performance efficiency created JavaScript in 1995 But the internet has evolved since then, and so have the expectations of users and web developers. , , and are the new norm for developers, and JavaScript serves as the foundation for these technologies. Hardware access offline operation real-time communication Since JavaScript is an interpreted language, code compilation is done at runtime. This requires extra computational time during program execution compared to compiled programming languages. The impact depends on the application — the speed difference is not very noticeable when displaying static images or text, but can have a significant effect during cryptographic calculations. Wire’s end-to-end encryption protocol , originally written in Rust, makes use of cryptographic primitives from the implementations of HMAC-SHA256, Curve25519 and HKDF. These algorithms are essential for everything that happens in Wire and are provided by the . Proteus Sodium crypto library The Sodium library is available for numerous platforms — a native version written in C ( ), bindings for Rust ( ) and a pure JavaScript version ( ), which has been compiled using . libsodium rust_sodium libsodium.js Emscripten The Rust version of Proteus is tightly integrated in our and uses the Rust bindings to libsodium, which are significantly faster than their JavaScript counterparts: mobile apps Neon is the one This speed difference between libsodium and libsodium.js forced us to look for alternatives that could increase the encryption and decryption speed in our web application. Fortunately we came across , a Rust abstraction layer for native Node.js modules. Neon As Wire desktop apps are built with (which runs Node.js), using Neon proved an ideal way to achieve near-native encryption and decryption performance. Electron We created a Node.js module that provides a JavaScript interface, which can talk to the Rust bindings of libsodium. This interface is publicly available as “ ” on GitHub. libsodium-neon The reason for using rust_sodium instead of the well-known is that we rely on libsodium’s system functions — which means every Wire user would need to have libsodium installed, or libsodium-neon would not work at all. However, rust_sodium provides an option to download libsodium in advance and integrate it into the finished Node.js module. That’s the only functionality that sets it apart from sodiumoxide. sodiumoxide Up to 141× faster We then analyzed the cryptographic functions according to their performance in interpreted code (provided by libsodium.js), compiled code for Node.js (provided by libsodium-neon) and compiled code for native programs (provided by rust_sodium). The benchmark results were very positive: Tested with Linux Debian 9, 64-bit (2.7 GHz Intel Core i7, 16 GB RAM) As expected, rust_sodium is the fastest. It’s the big difference between libsodium-neon and libsodium.js that was a pleasant surprise. In almost all the functions the difference in speed is significant — up to 141 times faster. The additional benefit is that we gain type safety as a result of the Rust bindings that are used by libsodium-neon. Both of these advantages made Neon a very appealing choice. With a strict adherence to a well-defined interface, replacing existing calls to libsodium.js with libsodium-neon was as easy as this: libsodium.js const sodium = require('libsodium-wrapper-sumo'); sodium.crypto_sign_verify_detached(signature, message, this.pub_edward); libsodium-neon const sodium = require('libsodium-neon'); sodium.crypto_sign_verify_detached(signature, message, this.pub_edward); After implementing these changes, Wire on macOS and Linux is visibly faster on startup for example, when decrypting 1000 new messages: Captured from the internal desktop build to show speed difference. We’re happy to share that libsodium-neon has been already integrated into the latest versions of our macOS & Linux apps. Windows will get the update soon. A big “Thank You!” to , the creator of Neon, who’s been collaborating with us on speeding up encryption in Wire. Dave Herman The next step is to research a solution to bring similar speed improvements to the web version of Wire. You can keep an eye on our progress and check out our code on . GitHub Benny Neugebauer, Florian Keller — Wire web/desktop team