NaCl-based Cryptographic Relay
Zax is a NaCl-based Cryptographic Relay, easily accessed via the Glow library. You can read the full technical specification here. Zax relay nodes are asyncronous "dead drops" for mobile communications. Relays are intended to be multiplied for reliability and form a distributed network. Individual devices send messages to a mutually determenistic subset of relays and check the same for response traffic.
Each Zax deployment includes (via /public
) a test Dashboard app, that uses Glow client library to provide user-friend access point to given relay internal mailboxes. We maintain live Test Server that runs our latest build. For testing purposes expiration on that relay is set for 30 minutes.
Any device can communicate with any other device via Zax relays. The address space is global, and each device uses a hash of a long-term identity public key as the “address” in the global network of relays. Devices can generate as many keys as they need and implement communication ratchet protocols on the client level.
Clients start by sending a POST request to /start_session
with a random token. The relay responds with a simple proof of work challenge based on that token. If the relay is configured for dynamic difficulty adjustment, the proof of work function will increase in difficulty as the relay experiences heavier load (thus increasing the client time required for a new session handshake and reducing load).
After answering the challenge to /verify_session
, clients receive temporary session keys, and can start posting commands to /command
. The command to relay is encrypted with session keys, while payload of command is usually encrypted with recipient public key, and is inaccessible to the relay. Using upload
, messageStatus
, download
and delete
commands, client devices can start sending end-to-end encrypted messages to each other.
Details of the protocol can be found in the full technical spec. The full client library for messaging commands is implemented in the Glow library.
File commands API leverages the existing anonymous message exchange mechanism of Zax relays to bootstrap file exchange metadata and key exchange. After parties have exchanged information about the file, new commands allow for the bulk content of an encrypted file to be exchanged.
Sending a file from Alice to Bob follows the following protocol:
pkA
and pkB
). The relay doesn’t store these public keys, and identifies Alice and Bob by the hash of public key as hpkA
and hpkB
.startFileUpload
command that contains the hpk_to
address of Bob in a command data block. The data block also includes the metadata encrypted pkA => pkB
using NaCl crypto_box
, so the whole metadata block is inaccessible to the Zax relay. That metadata block also includes the NaCl symmetric key for crypto_secretbox
that will be used later to encrypt the file contents.startFileUpload
generates a regular Alice => Bob message on the relay, and can be downloaded by Bob with a regular download
command. Alice receives the unique uploadID
from the relay that is used for all subsequent commands about the given file. The relay response data block includes the maximum size of file chunk that clients can upload at once. Default is set to 100kb, but clients can modify that value in config, which will require appropriate changes to the size of the maximum POST command in the web server configuration.uploadID
only in that initial startFileUpload
message, stored in Bob’s mailbox (hpk_to
) as a message from Alice (hpk_from
). Once Bob or Alice deletes that message via the delete
command or it expires as a part of the regular Redis expiration timeout, the relay will have no record of uploadID
generated for the file. The relay uses either secret_seed.txt
in shared/uploads
or a config value to associate the uploadID
given to clients and storage_id
used by the relay to derive storage file names. If secret_seed.txt
is deleted, there is no way to recover an association between files on the relay and client commands.uploadID
obtained from the relay, Alice can now issue the uploadFileChunk
command, that requires that uploadID
. In the command datablock, Alice provides the nonce
used to encrypt this file chunk using the symmetric NaCl key for crypto_secretbox
. Outside of the command datablock (encrypted as usual with Alice => Relay session key), the encrypted file contents produced by secretbox
are posted as additional POST lines to the uploadFileChunk
command.shared/uploads
and derives a storage name from the uploadID
and the local secret_seed.txt
file. The nonce for each chunk is stored in Redis and subject to the usual time expiration rules.uploadID
and secret key for this file when it gets the initial startFileUpload
message (by downloading it via the messaging family download
command). Bob uses uploadID
to issue downloadFileChunk
commands to download the file chunk by chunk. It contains in its datablock (encrypted to Bob) the nonce of the given chunk, and the symmetrically encrypted chunk itself is the last line of the POST response to downloadFileChunk
command.uploadID
and fileStatus
command. If the relay deletes or refreshes secret_seed.txt
present during initial startFileUpload
, all requests for the old uploadID
will fail.uploadID
and the deleteFile
command.deleteFile
command, after Redis expiration, the relay will delete old files via a cleanup job. The cleanup job will also delete files that have lost association with their storage id, which is the case if the secret_seed.txt
is changed or deleted.The full client library of file commands is implemented in the Glow library.
Zax requires Redis to run.
We suggest that you use the Ruby Version Manager (RVM) to install Ruby and to build and install the gems you need to run Zax.
If you don't already have RVM installed, install it from here.
Zax requires at least version 2.7.2 of Ruby and version 1.29.10 of RVM to run.
To check your Ruby version, type the following in a terminal:
ruby -v
If you do not have version 2.7.2 or higher, then type the following in a terminal:
rvm install 2.7.2
In a terminal, navigate to the directory in which you'd like to install Zax and type the following:
# get the source
git clone https://github.com/vault12/zax.git
# create the gemset
cd zax
rvm use ruby-2.7.2
rvm gemset create zax
rvm gemset use zax
# run the installation script
gem install bundler
bundle install
If bundle install
command fails with a message for libxml2 or Nokogiri, see the Troubleshooting section.
To bring up Zax run this command:
rails s -p 8080
To make Zax accept connections from all hosts:
rails s -p 8080 --binding=0.0.0.0
To test groups of tests you can run any of these commands:
rake test
rake test -v
rake test:controllers
rake test:integration
To run individual tests
rake test test/integration/command_test.rb
rake test test/integration/command_test.rb -v
Zax uses Nokogiri which uses libxml2. Here is an example installation via Brew on an OSX system:
brew install libxml2
bundle config build.nokogiri --use-system-libraries
For other platforms than OS X, please consult Installing Nokogiri for further instructions.
cd zax
mkdir tools
echo "*" > tools/.gitignore
echo "rvm gemset use zax" > tools/init
echo "# empty; prevent saving to disk" > tools/redis.conf
echo "redis-server ./tools/redis.conf" > tools/redis
echo "rails s -p 8080 --binding=0.0.0.0" > tools/relay
Then you can do e.g.:
cd zax
. tools/init
. tools/relay
. tools/redis # new console window
To see Glow and Zax in action, check out the Live Demo. This is a test project included in Zax called Zax Dashboard.
We encourage you to contribute to Zax using pull requests! Please check out the Contributing to Zax Guide for guidelines about how to proceed.
Project | Description |
---|---|
Glow | Client library for interacting with Zax Cryptographic Relay |
Zax Dashboard | Sample dashboard app for Zax Cryptographic Relay |
TrueEntropy | High volume thermal entropy generator |
Zax is released under the MIT License.
Exporting/importing and/or use of strong cryptography software, providing cryptography hooks, or even just communicating technical details about cryptography software is illegal in some parts of the world. If you import this software to your country, re-distribute it from there or even just email technical suggestions or provide source patches to the authors or other people you are strongly advised to pay close attention to any laws or regulations which apply to you. The authors of this software are not liable for any violations you make - it is your responsibility to be aware of and comply with any laws or regulations which apply to you.