What is Zbay?

Rumble Fish Software Development
10 min readFeb 3, 2021

Zbay is a decentralized online platform that offers team chat services similar to Discord, Keybase, or Slack.

Zbay provides users with a comparable level of reliability and usability, however, the chats are encrypted on the privacy-focused Zcash blockchain, making them more secure alternatives which offer protection against data breaches.

Since Zbay is based on the Zcash blockchain, the cryptocurrency can be used by the Zbay users to pay for things. They can also register usernames for themselves and their communities and may be able to use Zcash to purchase additional services in the future.

How does it work?

The starting point

Zbay uses shielded transactions on the Zcash blockchain to transfer messages between users. Every message sent actually translates to a UTXO spend on the blockchain level, where the encrypted memo field of the output is used to contain and transport the message from one user to another. In order to read a message, a user must have the appropriate viewing key matching the target address of that spend. This summarizes the basics of how Zcash primitives are translated by Zbay into interactions between its users.

The details of how Zbay messaging transportation works are undergoing modifications as we switch over to libp2p instead of Tor.

Direct messages

Sending someone a direct message is the simplest form of communication. Using Zbay, this translates to using the message field in a zero-valued transaction sent directly to the address of the user you wish to contact. Similar to PGP-encrypted emails, the recipient holds the viewing key to the message, ensuring complete privacy. The only exception is that in this case the recipient’s address is also the public key. Unlike Ethereum or Bitcoin, where anyone can trace a full history of interactions between users, Zcash’s unique design ensures that the exchange between addresses cannot be traced by third party viewers. The blockchain layer’s privacy is what makes it possible for Zbay to exist.

Private channels

Private channels provide a place for three or more Zbay users to communicate with each other. However, unlike direct messages, channels require some setup first. If a group of users wish to use a private channel, one of them must first create a new Zcash address. The user then shares the address’ viewing key with whoever they wish to invite to the channel. The invitees then add the viewing key to their wallets, permitting them to decrypt any messages sent within the channel.

Invitations to channels are still based on the ‘direct message’ function, as this is how viewing keys are sent to users.

Public channels

Public channels serve as a place for open broadcast communication with anyone who wants to join them. When it comes to the implementation of a public channel, it does not differ much from a private channel. Public channel viewing keys are available to all users by being posted in a meta-channel named the “Channel of Channels”, which every Zbay user follows.

Users can choose to join a public channel by adding the appropriate viewing key to their wallet.

User identity

During the first run of the application, every new Zbay client chooses a username for themselves. Each user must come up with a unique username to maintain security and prevent impersonations.

While creating a new profile, Zbay creates and stores a keypair for the client. One of the keys is private and is used for signing every message sent by that user. Zbay uses a signing scheme that makes it possible to extract public keys from the signature and signed data. This helps prevent message spoofing and tampering, adding to the security of the system.

At the same time, Zbay posts the new user’s public key and username to a meta-channel tracked by all Zbay instances which is called “Users Channel”. Due to the fact that the blockchain shows everyone the same order of transaction, Zbay username ownership is based on the rule “it’s owned by the public key which claimed it first”.

Technical stack

Zbay was built using the Electron framework, and NodeJS was used for the OS. The front-end of the app was developed using React, Redux, and Material UI. The codebase was initially in Javascript, but is now being moved to Typescript.

Zbay supports Windows, Linux, and macOS. Using Github Actions, the app is cross-compiled to each of the systems.

Zbay is open source and the app’s code repository is available here.

History of the project

The full node phase

Development work on the app started in February 2019, a few months after the Sapling Zcash update. This update made Zbay a feasible project thanks to some changes in the Zcash protocol. However, it wasn’t smooth sailing from the start. One of the first challenges we experienced was finding a way to import viewing keys into Zbay clients’ wallets. At the time, the Zcash node didn’t support this feature, so we had to fork its repository and introduce the appropriate support on our own. It took a lot of work maintaining our fork and keeping track of new releases, so we could merge the necessary changes to our fork, but the prototype was worth it. Finally, the Zcash project implemented our fork’s features and we could leave the Zcash node codebase alone.

Initially, it was assumed that every Zbay user would have a local Zcash note, which could be started and monitored by the Zbay process. In theory, this was the appropriate way to interact with Zcash’s blockchain.

This method worked at first, but it had its flaws. Most importantly, it was time-consuming, and required a lot of CPU usage and disk space to sync new clients with the blockchain. The system required a lot of work to fix these issues. In the end, we were able to optimize the time required to onboard new clients, and what had once been a few days was now approximately a few hours (considering differences in network, CPU and disk speed). Unfortunately, nothing could be done to lower the high CPU usage and required 10+ GB of disk space.

At this time, most of our work was devoted to optimization, monitoring external processes, and making backups.

The light client phase (current)

At the start of last year, we introduced Zbay light, which is the current production version of the app. During this stage, we’ve moved away from working with a local Zcash node, and are instead utilizing tools from the Zecwallet Lite project. This was a profound shift of direction and carries both positive and negative implications:

- Advantage: it takes merely a few minutes to fully sync and run the app for a new client

- Advantage: the app needs very little disk space, as it no longer needs to download the entirety of the blockchain’s history

- Disadvantage: the app relies on an external cloud system (Lighwallet servers), which is operated by a trusted party. This could have an impact on privacy and security.

- Disadvantage: we no longer receive 0-confirmation messages nor are we able to display them before they are included in the block by a miner.

The Lightwallet protocol ensures privacy by decrypting data locally. This is done by retrieving data about new blocks in their pure (encrypted) form, and using the same computer Zbay is running on to decrypt them.

However, to make the process more efficient, the protocol strips out the information which Zbay relies on, called memo data. Considering the fact that different clients require different memos, this creates a space for a deanonymization attack, should someone successfully persuade the Lightwallet server operators into cooperating.

Confidential cryptographic information is completely secure, by being safely logged in a wallet where all the decrypting takes place.

Regarding the implementation process, switching over to “Zbay light” involved a lot of adaptation work. For example, Lightwallet-cli is written in Rust, although Zbay is written in NodeJS. We had to figure out how to effectively use the code in an interoperable way. We definitely could have just generated the subprocess every time we needed to run Rust code, but this would result in excessive process forking, which would in turn be extremely inefficient. Instead, we import Rust components with the help of node-gyp bindings and call Rust functions straight from NodeJS.

Present and future perspectives

Possible challenges

We must say we’re very happy with our achievements, but we know that we still have a long way to go. We realize that as long as Zbay is based on Zcash, the speed of its message transport will be limited to that of the blockchain, which isn’t necessarily fast. For the time being, the block time on Zcash is 75 seconds, which isn’t even comparable to the UX of other instant messaging apps available today. Considering that Zbay’s messages are stored on-chain, they can never be forgotten or removed, which could develop into a serious privacy and security issue if the keys were ever compromised.

“Websocket over Tor” phase

Recently, we’ve released a version of the app that enables both parties to instantly and efficiently direct message one another when online.

Zbay sets up a local tor client, which configures it to expose a v3 onion service. This service enables Zbay instances to open private websocket servers that other Zbays connect to via the servers’ onion addresses. In the sense of a Websocket layer, it offers a direct connection, but as it passes over Tor, there are in fact 6 tor nodes in between, forming a Tor circuit. This effectively anonymizes the connection on the TCP protocol layer and offers metadata protection against a wide range of attacks.

Thanks to this approach, Direct Messages are now fully instant as well.

Libp2p over Websocket over Tor

Direct websocket connections are perfect for direct messages, but can they be used the same way for private and public channels? How would it function with hundreds or even thousands of users? Can we create a well-connected network of Websocket connections, also opening o(n2) connections? This is not an optimal solution.

We are currently working on developing a mesh of Websocket-over-Tor connections using the libp2p library. We rely on the libp2p library to create the connection instead of creating it directly ourselves. The topology of the Mesh is created by using the library’s DHT implementation. Instead of requiring everyone to connect with everyone else, we use gossip and pubsub protocols (libp2p’s GossipSub). As of this moment, we are load testing the communication logic on hundreds of machines running on AWS. The results are looking bright, and they are clearly indicating what our next steps should be.

Persistent channel history

There is one more significant consequence to moving the messaging part of communication off the blockchain. By using Zcash to deliver messages, we were also provided with a permanent record of interactions in each channel and direct message thread.

By shifting to using pubsub for communication, we no longer have access to that history, since you must be subscribed in order to receive messages over pubsub. There aren’t any central servers that could retain the data when users go offline, so the solution would be to find a reliable system that could save records of communication history and reconcile the network partitions which occur when some users go offline while others continue chatting. Therefore, we are currently working on finding a solution that could retain the state of the channel between channel members.

We are considering using git as well as some extra cryptography in order to solve our problem. We are using Tor’s v3 onion services to expose read-only git repositories, which in turn allows users to sync their history using git pull. Of course, this is just an overview of the solution, which in fact is a bit more detailed. We thought about designing our own protocol or borrowing from solutions in the peer-to-peer social networking protocol SecureScuttlebutt, but we decided to try git first. It’s fast and well-recognized, and our problem appeared to overlap in significant ways with the use case and functionality offered by git. So far, the result has been promising!

More privacy in Private Channels

Although we are now using some features offered by Tor and Libp2p, we’d like to stress the fact that we are not resigning from Zcash and we will continue to use the cryptography model offered by the blockchain. For example, Private Channels will continue to use the same encrypted messaging system based on sharing keys in the ‘note’ field of a Zcash transaction output.

Nevertheless, we plan to implement some updates to Private Channels. The existing cryptographic design has some restrictions that need revising:

- The channel has only one shared viewing key.

- Once someone receives a key, there is no mechanism that could make him ‘lose it’. That means that once a user has access to a Private channel, it cannot be revoked. This is an important feature that should exist, but it’s difficult to roll into the current design.

- We’d like to implement forward and backward confidentiality for Private Channels. If an attacker were to intercept a team’s encrypted network traffic and manage to obtain the private key to a channel by way of a malware attack or theft of a device, he shouldn’t be able to decrypt deleted messages that were intercepted in transit. The attacker should also lose the ability to decrypt messages immediately or shortly after the device compromise.

- We’re also looking to offer protection to private channels against metadata leaks to users who aren’t members of the team. In this case, encrypting messages won’t suffice. It would be best to transfer private channels to their own mesh networks (connecting over Tor, but only to other team members), and find a secure way to allow new peers to join these networks.

Final thoughts

Zbay is a groundbreaking and thrilling project that pushes the limits of what open-source technologies and decentralization can do for us. We’ve put a lot of work into this project over the past two years and it shows in the progress we’ve made. We have a clear concept of our future work and how we plan to do it.

Finally, we are a growing team looking for new developers fascinated by cryptography, decentralization and Tor.

--

--

Rumble Fish Software Development

Rumble Fish is a Software Development House specializing in Blockchain, FinTech, AWS Cloud Applocations and e-commerce.