wirehub - decentralized, peer-to-peer and secure overlay networks built with WireGuard

Gawen ARAB g at wenarab.com
Wed Jan 30 16:25:41 CET 2019

Hey Steve,

Thank you for your feedback.

> - uses extra crypto functionality which is not already part of wireguard;
> - passes messages across public networks using that functionality; and
> For what it's worth, if it would be possible to also encapsulate your
control protocol inside wireguard, that would be vastly preferable: it
allows the transport cryptography to be implemented in one place, once
(i.e. in wireguard), and lets wirehub be a purely organisational overlay
for managing links, rather than touching the crypto and introducing
troubling extra complexities.

I agree.

The main issue to implement this is to accept message_handshake_initiation
packet from unknown initiators. WireHub peers discover themselves through
DHT. One peer does not know in advance what peers will communicate with it.
current implementation of WireGuard drops packets from unset peers.

I plan to implement a replay mechanism of the message_handshake_initiation
packet, where WireHub peeks it, decrypts the initiator's public key, and if
unknown and has enough workbit, will add it to WireGuard's peers before
replaying the packet. The main advantage is to avoid adding usage-specific
features to WireGuard, but I need to re-implement part of the WireGuard
scheme (plus the replay mechanism might be a little dirty).

Another approach might be to modify WireGuard to add a hook called when a
unknown peer initiates a session. When it happens, a userland app (here,
WireHub) is called to accept or reject dynamically the initiator. This
the overhead of processing twice the message_handshake_initiation packet
the previous solution, but it would add complexity to the WireGuard's code.

    on_message_handshake_initiation(m) {
        // decrypt static_public

        if (unknown_peer(static_public)) {
            if (hook) {
                r = hook(static_public)     // call dynamically WireHub

            // if no hook or hook rejects initiator, drop packet
            if (!hook or !r.accept_initiator) {
                return drop();

            // else add iniatiator to peers

        // process message_handshake_initiation

> - clamps the wireguard keys in some unspecified way to embed a
proof-of-work (in fairness, I haven't read the code, so please correct me
if I have misunderstood).

The workbit of a Curve25519 key is the count of trailing zeros of a
of the public key.

    workbit(sk, namespace='public') {
        k = pub(sk)
        h = blake2b(k ⊕ namespace)
        wb = trailing_0s(h) // see __builtin_clz
        return wb

WireHub peers only accept peers which public key has enough workbits. This
identity expensive to generate, which mitigates Sybil attacks.

When workbit is incremented by one, the count of possible Curve25519 keys is
divided by 2. I don't know if it's a problem? I explored other PoW scheme,
the current implementation is the simplest one I found.

> I would also love to see some sort of PKI option with this project, to
avoid having to explicitly trust all the peers. I'd prefer to be able to
simply provide the peers with a signature they can present to other peers
that proves they can be trusted (or even better, have that signature
generated by a nominated host at connect / setup time for each peer, which
avoids much of the shenanigans involved with handling expiry, revocations
etc.) Having the ability to tell all peers on the network to immediately
terminate all connections with a specific compromised peer would also be

I plan to build this on top of WireHub, once it will be more mature.

A PKI daemon may read peer's certificates, signed by a given authority,
keeps a
list of the trusted peers and updates in live the wirehub's conf file.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.zx2c4.com/pipermail/wireguard/attachments/20190130/ee95393b/attachment.html>

More information about the WireGuard mailing list