Using a v3 onion address as both the cryptographic identity and the NAT traversal layer is such a clean architectural choice. No STUN/TURN servers, no hole punching, you just boot the script and Tor handles routing.
For those who use Tor regularly for things other than web browsing: how bad is the real-world latency for pushing a ~20KB Opus audio chunk over Tor these days? Are we talking a 2-3 second delay, or is it much worse?
The real world delay is about 2-3 seconds your spot on. I initially started with a full duplex version but it was absolutely terrible. Walkie talkie kinda forces the recieve, listen, response from the users so the latency isn't as much of an issue.
Is audio transmitted while it is being recorded or afterwards? Is it played before everything is received or is everything buffered? In the later case, I find it more akin an audio message on Signal or similar, than as a walkie-talkie, which is much more "dynamic".
It's not streamed. It gets recorded, compressed, (voice effects if you want), encrypted on device, then piped through, reverse process, auto played on reciever end.
Also, once it's decrypted and played back, the message gets destroyed.
Small suggestion, maybe you should send a “key down” notice when you begin recording, that generates a subtle sound on the receiving end. This would act as something like a typing indicator on a text messaging client.
Added link for clarity. Seems like you could get more or less realtime, udp streaming, full duplex communication . Once you have the first part of that built, then adding things like voip or video calls or what have you becomes a lot easier.
The problem is the UDP packets from the application will ultimately be in a TCP wrapper over tor. Which will add even more latency.
I know you can set up mumble over Tor but it's going to have the same latency drawbacks.
Another commenter noted the ability to configure only 1 hop instead of the standard 3. I wonder how much latency would be gained back. I want to play around with this.
Sorry if I was unclear, this stuff does get tangled, lol. I was talking about setting up a parallel veilid connection - a private route exchange between the two ends that goes straight over the veilid network, outside of tor. It's got comparable privacy and security assurance. There only a few thousand nodes/peers right now, but it's gaining steam.
You could use tor to anchor a common relay, then do key and route exchange to establish veilid, then the realtime app uses that for a very secure private route unique to the two endpoints.
From what I can tell, because of the design, veilid would be excellent, comparable to many commercial voip offerings, with 150-500ms latency . More nodes and users would quickly ramp that up. There are a ton of downstream benefits of something like this; faster file exchange for ipfs, bittorent, etc, that doesn't gum up the tor layer, a kind of implicit defense in depth, but also low latency, efficient peer to peer routing.
It'd almost be zero knowledge by construction; you could build a multi-hop escrow style key exchange.
If Musk integrated tor relays and veilid peers throughout Starlink, you could get near-native latency for wherever you connect in the world, more than enough to add timing attack noise and layer in other security features.
STUN/TUN are important because of bandwidth. With STUN the bandwidth used is only between the two connected devices, with VPN like Tor there is a bandwidth cost on all the servers where this data is passing. This is a big blocker for anyone hosting the service on a VPS with a few GB of traffic data per month.
Very cool, happy to see more IRL applications of onion services as a backend. Arti onion client support should soon be available, which will make Tor embeddable in applications as a Rust library. Hopefully this encourages even more usage.
More applications using the network means more cover traffic as well.
The library is openssl and that comes with all these ciphers available. No other reason than because we can!
I wish AES-GCM was available...but openssl can't do it on its own without further dependencies to parse the authentication correctly.
Really this whole layer is complelty redundant actually. It's already E2EE without openssl via Tor. I like that it's encrypted before I hit the network pipe though.
If a library doesn't do what you need, you need a different library, but this is impossible from a short bash script, so it's one of the tradeoffs of your design.
Then maybe your scientists should spend some time to stop and consider whether they should ;)
But seriously, I'd just limit this to one option on the selection side, even if you continue supporting more than that at the protocol level for cryptographic agility.
Fair point. But what I'm getting at is that if you aren't an expert on cryptography (and perhaps even if you are!) rather than imposing your personal preferences on others simply deferring to a trusted third party library can make a lot of sense.
So in addition to a sensible default I guess it would also be a good idea to tag choices that you believe to be outdated with a large warning. That way you haven't rolled your own crypto, you haven't forced your views on others, but you have done your best to enable end users to operate your tool in a sensible manner.
I would rather avoid cipher fixation. Give me thousands of protocol / cipher / mac / mode combinations. Fixation only benefits nations wanting to crack something.
Adding to that, cryptography is just mathematical obfuscation and often repeated here is that security through obscurity is not security at all. I will stick with my own principals of not fixating on a cipher. The only people that benefit are lazy spooks.
Rather than what is accepted as the strongest ciphers I prefer ciphers not optimized by CPU's and GPU's. Spooks will have to cycle through every combination of protocol + cipher + mac + mode + passphrase + whatever other obfuscation I shim inside that tunnel. Keep 'em on their toes. Even better I will also cycle through these encoding methods [1] if I am in a good mood otherwise I will rot13 their ass and then force them to use a Drogan’s Decoder Wheel.
Thanks! My realistic use case is that I am already speaking to someone who I know and trust, so ideally exchange credentials in person. A preferred out of band secure messanger of choice is probably fine.
You could put your onion address into an “oh by code”[1] and just write it down … or chalk it on the sidewalk for someone to see … post it on a physical bulletin board.. hold it up on a sign…
This way you could establish communication with an unknown future party, totally offline.
Trying to repurpose hex literal notation as a "recognizable" URL shortener seems like a questionable idea. At least write it as 0x.co/FFFF so it's obvious to readers how to interpret it.
If you're printing something why not go with a QR code?
However, if you're walking down the street and need to quickly generate and apply a message, how will you pass along a QR code to an unknown future viewer ?
Can you draw a QR code with chalk or freehand with a pen, etc. ?
I will admit that the use-cases for "oh by codes" are weird and infrequent but I am convinced they will emerge ...
I don't disagree that URL shortening is incredibly useful at times. Merely that writing out the whole url is almost certainly a better approach and that any sufficiently short domain name is fit for purpose.
> Exclude Countries -- Exclude specific countries from your Tor circuits. Presets for Five Eyes, Nine Eyes, and Fourteen Eyes alliances, or enter custom country codes. Uses ExcludeNodes with StrictNodes in the torrc.
Interesting that people do this, I wonder how much it improves security? Afterall, any serious surveillance would involve running relays and exits in foreign lands.
This was another one of those things I built in because we can. I really don't know... But the Tor developers built this in as an option on the torrc so there must be something to it. We know there are definitely compromised nodes...I think it's just neat that you can have that level of control regardless if it's effective.
Forgive my ignorance, but can this be setup for a group like how a group can all be on the same frequency with walkie talkies? Or it is strictly one to one. Either way, it’s a really cool concept.
It actually can since its just symmetric encryption. Any key holder could decrypt the payload. In fact, the channel could simply be the shared secret.
Let's say we have 10 people in a call, 5 share a key and the other 5 share a different key. Without the shared key audio simply will not decrypt. You could have two private channels with one host.
The walkie-talkie model is a smart design choice given Tor's latency profile. Real-time bidirectional audio has pretty unforgiving requirements (~150ms round-trip max before it feels awkward), and Tor typically adds 50-200ms per hop. Going store-and-forward sidesteps the whole problem—you're not fighting the network's characteristics, you're designing around them.
Curious what codec you're using for the audio compression. Opus would be the obvious choice for speech but the tradeoffs change a bit when you're not doing real-time streaming.
Yes it's encoding in opus, and optionally you can configure encoding quality from 6kbs to 64kbs.
I was really surprised at the intelligability even at 6kbs.
The caviot is if your on termux we have to use the seperate termux API application to pipe audio to termux, and ffmpeg to convert MP4 to opus. Unfortunately termux cannot activate the mic on its own.
By MP4 I assume you mean AAC in MP4. I'm a bit confused by this. What emits AAC that then needs transcoding to Opus? Not that transcoding losses really matter for this application, but the pipeline is not clear to me?
So this is only for termux compatibility. On a standard distro it skips this step entirely and goes straight from raw pcm to opus.
On termux 'termux-microphone-record' is a wrapper around androids 'mediarecorder'. It doesn't support raw pcm output. It records AAC in m4a wrapper and then the extra ffmpeg package converts this to rawpcm so it can follow the same pipeline.
I love it for the same reason I love email and text communication. Think about what you want to say before you say it. Exclude the useless tangents: formalities, movie quotes, humble brags, cliches, etc. A few second delay is enough to get even the worst offenders to get to the point.
Oh I’m curious. Love bash, and learning new things about it.
I can understand why [ is not ideal. Can you explain the rest to me? I use || true for custom error handling often (with the right set -euo pipefail of course)
You may like this one then. It's kinda the same thing, but text only and multiple people can connect at once. It's setup so anyone can be a host, or a client.
Still: Using a line based protocol and base64 encoding the audio data? Not my first choice.
The README doesn't mention it, but I assume both parties have to be online at the same time?
Regarding encryption - what's the point? When communicating with a tor hidden service, the data is already encrypted.
Only starting the sending audio data after the speaker has stopped talking means much longer delays than necessary. Imagine someone talking for a minute.
The base64 encoding adds about 30% overhead. It's not ideal but it was a limitation of bash. Passing raw binary does not work in bash (or I couldn't get it to work).
To receive a call, you either need to be online and actively listening for calls, or optionally, you can enable auto listening. When another user calls you it will automatically put you in the call. On end call you will be put back in listening mode. I'm not really sure a great way to get around this without overly complicating it.
I believe because of the small overhead that's added there is just no reason not to layer encryption. At the end of the day I just wanted to see the bits I'm sending over the wire with my own eyes for assurance it's protected regardless of the fact that tor is protecting the data.
The streaming would be a nice improvement for latency. I would have to look into how this would work for the optional audio processing. Having one set file for transport also simplifys the some of the flow with encryption like salting and optional hmac authentication as these are derived from the sum of the entire file, not a portion of it.
Sorry for hijacking but I came across a firefox send replacement which worked in linux command line. Anyone know what it was? (It was online though, as in no storage for later)
Looks awesome in many ways. The use of a shared secret instead of PKI limits the real-world applications pretty severely, but adding PKI support doesn't seem too difficult. If the PKI key was only used to establish the session "shared secret", virtually no changes would be needed in the main code.
When I started prototyping it's started as full duplex. I was up for the challenge and wanted to understand why this already didn't really exist.
It ended up being awful. A standard real time call your able to interject and talk over someone and this works because of the low latency. The other person can stop talking and the conversation still flows.
The latency from Tor just makes it awkward to the point that you have to almost relearn how to have a conversation since by the time your interjecting and they hear the interjection, a whole 6 seconds may have passed and they may already be on a whole other train of thought. Walkie talkie architecture just forces you to listen and digest the message, think, respond.
There are two layers of encryption here. Tor, which already is encrypting the data, and locally via openssl before transmit.
I have 21 ciphers programed in from the openSSL library. There's a lot more available in the library but these are supposedly the strongest. The cipher used is not secret so while in the call you can see your cipher, and the remote cipher real time.
The authentication is resting entirely in the users lap. It's up to them how to come up with key exchange.
For me, I would be comfortable enough knowing the other side is who I think it is by the simple fact that audio is passing through. Establishing a connection once in person is most ideal.
Because the .onion is derived on device, an attacker can't just forge that. You need also need the private key for a connection to be established.
Let's say an attacker copies the directory from one of the endpoints and has the private key now and can launch tor under your static address. Well, because the additional shared secret is encrypted with another password known only to the user it's useless. The other side will not be receiving forged audio because of this barrier. They may get as far as being in a call, but no audio is going to be played back because the shared secret was successful protected. Even if you pass your message to the attacker, decryption will fail and nothing will pass.
Directly after sending, we run rm -f on $raw_file, $opus_file, $enc_file.
Audio is recived to /audio folder. After audio is decrypted and played we run rm -f $enc_file, $dec_file. There is only a split second that it lives on disk until it's gone.
For those who use Tor regularly for things other than web browsing: how bad is the real-world latency for pushing a ~20KB Opus audio chunk over Tor these days? Are we talking a 2-3 second delay, or is it much worse?
Also, once it's decrypted and played back, the message gets destroyed.
edit: https://veilid.com/
Added link for clarity. Seems like you could get more or less realtime, udp streaming, full duplex communication . Once you have the first part of that built, then adding things like voip or video calls or what have you becomes a lot easier.
I know you can set up mumble over Tor but it's going to have the same latency drawbacks.
Another commenter noted the ability to configure only 1 hop instead of the standard 3. I wonder how much latency would be gained back. I want to play around with this.
You could use tor to anchor a common relay, then do key and route exchange to establish veilid, then the realtime app uses that for a very secure private route unique to the two endpoints.
From what I can tell, because of the design, veilid would be excellent, comparable to many commercial voip offerings, with 150-500ms latency . More nodes and users would quickly ramp that up. There are a ton of downstream benefits of something like this; faster file exchange for ipfs, bittorent, etc, that doesn't gum up the tor layer, a kind of implicit defense in depth, but also low latency, efficient peer to peer routing.
It'd almost be zero knowledge by construction; you could build a multi-hop escrow style key exchange.
If Musk integrated tor relays and veilid peers throughout Starlink, you could get near-native latency for wherever you connect in the world, more than enough to add timing attack noise and layer in other security features.
Modulo cool project love show HN etc.
More applications using the network means more cover traffic as well.
Why!? That sounds like approximately 20 too many.
I wish AES-GCM was available...but openssl can't do it on its own without further dependencies to parse the authentication correctly.
Really this whole layer is complelty redundant actually. It's already E2EE without openssl via Tor. I like that it's encrypted before I hit the network pipe though.
great attitude for approximately everything except, perhaps, cryptography.
especially since the initial encryption is mostly redundant, i would encourage that you, at some point, consider reducing the number of ciphers.
Then maybe your scientists should spend some time to stop and consider whether they should ;)
But seriously, I'd just limit this to one option on the selection side, even if you continue supporting more than that at the protocol level for cryptographic agility.
It still supports a bunch of outdated crap including (on my system) RC4, RC2(!) and DES (yes, the 56 bit key one, not just 3DES).
So in addition to a sensible default I guess it would also be a good idea to tag choices that you believe to be outdated with a large warning. That way you haven't rolled your own crypto, you haven't forced your views on others, but you have done your best to enable end users to operate your tool in a sensible manner.
Rather than what is accepted as the strongest ciphers I prefer ciphers not optimized by CPU's and GPU's. Spooks will have to cycle through every combination of protocol + cipher + mac + mode + passphrase + whatever other obfuscation I shim inside that tunnel. Keep 'em on their toes. Even better I will also cycle through these encoding methods [1] if I am in a good mood otherwise I will rot13 their ass and then force them to use a Drogan’s Decoder Wheel.
[1] - https://github.com/qntm/base2048
I think it's a pretty light background process.
This way you could establish communication with an unknown future party, totally offline.
[1] https://0x.co
If you're printing something why not go with a QR code?
However, if you're walking down the street and need to quickly generate and apply a message, how will you pass along a QR code to an unknown future viewer ?
Can you draw a QR code with chalk or freehand with a pen, etc. ?
I will admit that the use-cases for "oh by codes" are weird and infrequent but I am convinced they will emerge ...
Interesting that people do this, I wonder how much it improves security? Afterall, any serious surveillance would involve running relays and exits in foreign lands.
Let's say we have 10 people in a call, 5 share a key and the other 5 share a different key. Without the shared key audio simply will not decrypt. You could have two private channels with one host.
Curious what codec you're using for the audio compression. Opus would be the obvious choice for speech but the tradeoffs change a bit when you're not doing real-time streaming.
I was really surprised at the intelligability even at 6kbs.
The caviot is if your on termux we have to use the seperate termux API application to pipe audio to termux, and ffmpeg to convert MP4 to opus. Unfortunately termux cannot activate the mic on its own.
Very interesting project, by the way.
On termux 'termux-microphone-record' is a wrapper around androids 'mediarecorder'. It doesn't support raw pcm output. It records AAC in m4a wrapper and then the extra ffmpeg package converts this to rawpcm so it can follow the same pipeline.
'|| true' 76 matches 'echo ""' 50 matches ' [ ' 261 matches '=$(' 90 matches
I can understand why [ is not ideal. Can you explain the rest to me? I use || true for custom error handling often (with the right set -euo pipefail of course)
Basically IRC, but for Tor.
https://gitlab.com/here_forawhile/torch
Still: Using a line based protocol and base64 encoding the audio data? Not my first choice.
The README doesn't mention it, but I assume both parties have to be online at the same time?
Regarding encryption - what's the point? When communicating with a tor hidden service, the data is already encrypted.
Only starting the sending audio data after the speaker has stopped talking means much longer delays than necessary. Imagine someone talking for a minute.
by the spooks that wrote it. no harm in having another turtle in the stack.
To receive a call, you either need to be online and actively listening for calls, or optionally, you can enable auto listening. When another user calls you it will automatically put you in the call. On end call you will be put back in listening mode. I'm not really sure a great way to get around this without overly complicating it.
I believe because of the small overhead that's added there is just no reason not to layer encryption. At the end of the day I just wanted to see the bits I'm sending over the wire with my own eyes for assurance it's protected regardless of the fact that tor is protecting the data.
The streaming would be a nice improvement for latency. I would have to look into how this would work for the optional audio processing. Having one set file for transport also simplifys the some of the flow with encryption like salting and optional hmac authentication as these are derived from the sum of the entire file, not a portion of it.
Do you mean IVs? Can't you (for most algorithms) just use a monotonic counter when streaming blocks?
> optional hmac authentication
Wouldn't that just be done per-chunk instead of per-file?
Thanks for contributing!
It ended up being awful. A standard real time call your able to interject and talk over someone and this works because of the low latency. The other person can stop talking and the conversation still flows.
The latency from Tor just makes it awkward to the point that you have to almost relearn how to have a conversation since by the time your interjecting and they hear the interjection, a whole 6 seconds may have passed and they may already be on a whole other train of thought. Walkie talkie architecture just forces you to listen and digest the message, think, respond.
There are two layers of encryption here. Tor, which already is encrypting the data, and locally via openssl before transmit.
I have 21 ciphers programed in from the openSSL library. There's a lot more available in the library but these are supposedly the strongest. The cipher used is not secret so while in the call you can see your cipher, and the remote cipher real time.
The authentication is resting entirely in the users lap. It's up to them how to come up with key exchange.
For me, I would be comfortable enough knowing the other side is who I think it is by the simple fact that audio is passing through. Establishing a connection once in person is most ideal.
Because the .onion is derived on device, an attacker can't just forge that. You need also need the private key for a connection to be established.
Let's say an attacker copies the directory from one of the endpoints and has the private key now and can launch tor under your static address. Well, because the additional shared secret is encrypted with another password known only to the user it's useless. The other side will not be receiving forged audio because of this barrier. They may get as far as being in a call, but no audio is going to be played back because the shared secret was successful protected. Even if you pass your message to the attacker, decryption will fail and nothing will pass.
Directly after sending, we run rm -f on $raw_file, $opus_file, $enc_file.
Audio is recived to /audio folder. After audio is decrypted and played we run rm -f $enc_file, $dec_file. There is only a split second that it lives on disk until it's gone.