-
Notifications
You must be signed in to change notification settings - Fork 94
Home
This project is an experiment to see if it's possible to build a usable offline sneakernet using Bluetooth LE. Will it work? Who knows!
- Use the Bluetooth 4.0 Low Energy APIs on iOS and Android to allow for pairing-free promiscuous background synchronization for anyone with a protocol-compatible app installed.
- Be a 100% sneakernet protocol, with absolutely no internet functionality.
- Use modern crypto (via libsodium) that's tailored to the limitations of BLE and an ultra-high latency, unreliable sneakernet.
- Implement a familiar and friendly Twitter-style UI/UX with a public feed, replies, reposts and (maybe) direct messaging.
- Only show Gravatar-style avatars and hashes for other's identities until you verify keys in person, and somehow make this process seem enjoyable.
- How do you prevent people from tracking your daily movements and public key all the way back to your house? Maybe allow for multiple disposable identities per device, and a geofence / privacy radius that won't share your identity with untrusted peers within certain sensitive areas.
- Is it possible to achieve some level of forward secrecy for DMs given the extreme latency and unreliable delivery? Maybe exchange a bunch of disposable Axolotl-style pre-keys after verifying people in person.
- Given that someone could create modified clients to sniff and record geo-location information, would it make sense to have "nothing to hide" and do something crazy like include a low-accuracy public geohash with every message and build that into the user experience?
-
version
: Spec version, 1 byte -
timestamp
: Current 64-bit Unix timestamp, 8 bytes -
signature
: 512-bit Ed25519 signature, 64 bytes -
sender_public_key
: Your 256-bit Ed25519 public key, 32 bytes -
sender_private_key
: Your 512-bit Ed25519 private key, 64 bytes
-
display_name
: desired nickname, 35 bytes
-
message_body
: UTF-8 message body, 140 bytes -
reply_signature
:signature
of message you're replying to, 64 bytes
-
mac
: message authentication code (crypto_box_MACBYTES
in libsodium), 32 bytes
All text fields are UTF-8 and padded with " "
(0x20
) if shorter than the max length. All protocol data is always versioned, timestamped and signed in its entirety by your private key.
All data packets follow this format:
[key=#bytes]
[[version=1][timestamp=8][sender_public_key=32][payload_data=n]][signature=64]
signature = sign(version + timestamp + sender_public_key + payload_data, sender_private_key)
There is a constant 105-byte overhead for each data packet comprised of version
, timestamp
, sender_public_key
and signature
.
Your identity is revealed on the first read to the identity characteristic. Your public key is your unique identifier, and the display name can be anything. Subsequent reads give other people's identities signed by your own.
payload_data: [display_name=35]
full: [[version=1][timestamp=8][sender_public_key=32][display_name=35]][signature=64]
payload_data: [others_identity=140]
full: [[version=1][timestamp=8][sender_public_key=32][others_identity=140]][signature=64]
All public messages flowing over the network will have the following format. They are uniquely identified by their signature.
payload_data: [message=140][reply_signature=64]]
full: [[version=1][timestamp=8][sender_public_key=32][message=140][reply_signature=64]][signature=64]
Messages with valid message
but empty reply_signature
are considered general broadcast.
Messages with both message
and reply_signature
are considered replies to the original message.
Messages with an empty message
but still containing a valid reply_signature
are considered upvotes/reposts.
Convert Ed25519 keys to Curve25519 for authenticated asymmetric encryption.
{} denotes ciphertext encrypted to destination_public_key
payload_data: [destination_public_key=32][mac=32]{[message=140]}[reply_signature=64]
full: [[version=1][timestamp=8][sender_public_key=32][destination_public_key=32][mac=32]{[message=140]}[reply_signature=64]][signature=64]
This example doesn't yet provide forward secrecy. The performance characteristics of a BLE-only mesh may prevent PFS from working reliably.
When a direct message is received, a reply to the sender with an empty message
body will be sent to acknowledge the message has reached its destination. When clients who are forwarding direct messages see there has been a reply_signature
that matches the original message's signature
, it should check to see if the reply's signature
is from the correct destination_public_key
. If it matches, the original message can be deleted and cease propagating through the network.