Sphinx + WebAssembly for coronavirus tracking app privacy

Many privacy geeks have long regarded mixnets as one of the ultimate technologies for user privacy online. Up until now, they were the unicorns of the computer security world: you might have heard about them, but you’d never actually see one in action.

If you need a simple introduction to mixnets, I’ve previously written one. The short version: like Tor, mixnets bounce messages around between networked nodes (computers) in different locations, to obscure who is talking to who.

Mixnets do an additional thing, making them potentially even better than Tor: they shuffle packets together to re-order packets inside the nodes. If there’s enough packets being shuffled, then even if you’re God, Google, or the NSA, it’s pretty much impossible to see what path a packet took, or de-anonymize anyone using the mixnet.

Up until now, this technology has been extremely hard to use. But in light of the wave of data totalitarianism which is poised to roll over the planet, it seemed worth helping the privacy side of the argument. So at Nym, we’ve been hard at work over the several weeks trying to make mixnets accessible to people who may need them to develop coronavirus tracking apps that respect user privacy.

I’ll do a follow-up post for a more general audience in the next few days, detailing how mixnets can be used in tracking apps. That’ll take a little bit of time, so I’ll make a simple announcement first: we have just built a Sphinx mixnet packet that is usable from any web browser or mobile app that can use WebAssembly.

Applications in web browsers and phones can now create anonymizing Sphinx messages for transmission through a mixnet (we have one of those too). This makes mixnets available for use by browser and mobile applications, for the first time ever.

Shorn of some utility functions for an HTTP request and a websocket connection, and expressed in the most primitive possible JavaScript (for clarity!), it looks like this:

class Route {
    constructor(nodes) {
        this.nodes = nodes;
    }
}

class NodeData {
    constructor(address, public_key) {
        this.address = address;
        this.public_key = public_key;
    }
}

async function main() {
    var gatewayUrl = "wss://path.to.mixnet.gateway:1793";
    var directoryUrl = "https://directory.nymtech.net:8080/api/presence/topology";

    // Get the current mixnet topology
    const topology = await getTopology(directoryUrl);

    // Set up a websocket connection to the gateway node
    // <omitted>

    // Set up the send button
    const sendButton = document.querySelector('#send-button');
    sendButton.onclick = function () {
        sendMessageToMixnet(websocket, topology);
    }
}

// Create a Sphinx packet and send it to the mixnet through the Gateway node. 
function sendMessageToMixnet(websocket, topology) {
    let route = constructRoute(topology);
    var recipient = document.getElementById("recipient").value;
    var sendText = document.getElementById("sendtext").value;
    let packet = wasm.create_sphinx_packet(JSON.stringify(route), sendText, recipient);
    websocket.send(packet);
}

// Construct a route from the current network topology so we can get wasm to build us a Sphinx packet
function constructRoute(topology) {
    const mixnodes = topology.mixNodes;
    const provider = topology.mixProviderNodes[0];
    let nodes = [];
    mixnodes.forEach(node => {
        let n = new NodeData(node.host, node.pubKey);
        nodes.push(n);
    });
    let p = new NodeData(provider.mixnetListener, provider.pubKey)
    nodes.push(p);
    return new Route(nodes);
}

main();

Sphinx WebAssembly, as well as the mixnet that it connects to, and documentation about exactly how to use it, will be available in our next code release. That’s due at the end of next week (we’re working on it).

As far as the packet part goes, it still needs to be fully packaged and pushed up to npm, but it’s starting to be usable if you want to experiment with it. Any help from JavaScripters, or interest from tracking app teams, is very welcome!

If you’d like to chat about it with our development team, come say hello in our friendly KeyBase channel. Start keybase, search for channel nymtech.friends#dev, and say hi!

For a more technical introduction to mixnets, try Ania’s mixnet intro video from Usenix or read some articles in the Nym blog. If you want to find out a bit more about Nym’s privacy platform, there are some links in our documentation which give a good overview. Note: the docs are for our previous platform version, released about three weeks ago. WebAssembly docs are not yet up to date.

Lastly, the WebAssembly Sphinx code is available on Github.