





I proposed this project to improve on Radicle’s p2p model by using Tor for universal, straightforward seeding of git repos.
Original discussion thread - https://bounties.monero.social/posts/207/
One of the project’s git repos linked in that thread - https://radicle.network/nodes/iris.radicle.network/rad:z2ydYmUCJvDfNFTVTpEbQmm55EPt1/history
Project website - https://cradicle.xyz/
The dev who took the project also expanded it into a project to reimplement Radicle in C.
Since I’m not a coder and I don’t have any git repos of my own, I can only test from the viewpoint of an average layman using the GUI app to seed repos.
It’s impossible for me to properly gauge how the project is progressing without engagement from coders who try using it for their git repos.
If the project doesn’t currently interest you, your suggestions on how to start getting users on board would also be welcome.
Edit - bear in mind that because decentralized discussion platforms like this are currently quite broken, there are comments showing up in the thread when I’m not signed in that don’t show up for me when I’m signed in. Here’s a screenshot of all the comments showing up for me right now where I’m signed in and able to reply, as of UNIX time 1779670288

I’d encourage discussion of this project moreso on nostr (equally broken but my preferred platform) or the discussion thread linked above (seemingly more functional)
using Tor for universal, straightforward seeding of git repos.
That doesn’t sound right. Maybe design/implementation details would make it less nonsensical.
C implementation of radicle
Now this just sounds like a bad joke. Especially with the tor project itself spending all this effort to give us arti as a readily usable embeddable rust crate.
That doesn’t sound right. Maybe design/implementation details would make it less nonsensical.
The proposal used Tor’s onion addresses as an answer to Radicle (unlike BitTorrent) requiring seeders to have fixed IP addresses or domain names (edit - or preconfigured onion proxies or something making onion addresses complex to use). Another reply suggests this problem with Radicle has been fixed or they’ve started fixing it while this project was in development. I haven’t really kept up with the news on Radicle in that timeframe.
sounds like a bad joke
I don’t see why. If radicle is a serious decentralized project at the scale of potentially replacing github, it should of course end up with multiple implementations in multiple programming languages. Can you clarify your view more?
There’s almost zero reason to choose C for any greenfield project. C / C++ have been plagued with extremely serious problems throughout history because they are not memory safe. The world needs to move on from memory unsafe languages whenever it can.
Choosing C for something like this would be idiotic.
The proposal used Tor’s onion addresses as an answer to Radicle (unlike BitTorrent) requiring seeders to have fixed IP addresses or domain names
That’s an even worse use-case mismatch than anything I had in mind, forcing anonymous transport via a traffic-pressured network primarily used for outproxying, just to get fixed network addressing.
In the past I’ve recommended onions for port forwarding. It’s more simple than alternatives and using the network is free.

The authors or Tor really don’t want their network used for torrenting though. They do support JS, and by extension I would argue the authors intended for their users to be able to use YouTube. In comparison to video, git traffic is insignificant. I don’t see anything wrong with it, but then again, users of torrents don’t usually have issues downloading without port forwarding.
That was kind of my point. Why would you bring TOR into this?
If you effectively want a DNS alternative for users, you can use GNS or Handshake or whatever.
If you need port forwarding too, or sockets or whatever, then you can use something like iroh for that.
Cloning git repos from fast hosts is slow(ish) enough already. Forcing a supposed alternative to push traffic over TOR for not even a compelling reason like anonymity is very weird.
I don’t get what you mean by “traffic-pressured.” If you’re referring to the Tor devs recommending against the use of torrents, that’s because torrents typically involve out-of-Tor traffic which burdens exit nodes. Cradicle isn’t torrents, the Tor devs don’t recommend against using onion addresses for their intended purpose of traffic within the Tor network, that wouldn’t make much sense.
Regardless, if you have a better way to implement one-click seeding like bittorrent clients have, feel free to suggest it or build it.
The bottlenecks don’t only exist at the exit nodes. You didn’t actually think you will be getting Gigabit speeds using hidden-services, did you?
You seem to be suggesting 3 things:
Are we on the same page with these 3 bullet points, or am I still not understanding you?
Tor is slow. People use it when they need the anonymity. Using it when it’s not strictly needed doesn’t help you (or the network, but that’s besides the point).
The problem you presented, as I understand it at least, doesn’t require Tor at all, and can be solved with much lighterweight solutions. For example, did you know that PKARR exits?
Anonymity makes sense in this case. Radicle is often proposed as a solution to the censorship of projects in other repos, things like Nintendo Switch emulators, Hayase streaming client, etc. These projects want to remain anonymous to avoid legal threats on their actual identity
If Tor gets more users, they can run Tor nodes. The network scales to the traffic because it’s decentralized. You’re making up a problem that isn’t there. The Tor project does not recommend against creating traffic using onion services, again it wouldn’t make sense, there would be nothing to do with onion services then.
I’m really not understanding your point about anonymity. Why would we want every user in a P2P network to expose their clearnet IP address to every other user? It seems like if you flipped the release dates of Tor and BitTorrent, then Bram Cohen probably would have designed BitTorrent with Tor in mind from the start and it wouldn’t burden exit nodes so much. People would only use it without Tor when speed is more of a priority than security. But instead BitTorrent came first and already relied on an out-of-Tor network.
So I gave the actual code a one minute look (literally).
Picked src/radicle/util.c, since that was the last file touched.
The level of defensive programming doesn’t look that good (and I’m trying to be nice here).
Here is an example, and note that I didn’t do C in a while:
#include <stdio.h>
#include <string.h>
void rad_rstrip_nl(char* str) {
int len_str = strlen(str);
if (str[len_str-1]=='\n') {
str[len_str-1] = 0;
}
}
bool rad_get_input (char* str, size_t bufsiz) {
if (!fgets(str,bufsiz,stdin)) return false;
rad_rstrip_nl(str);
return true;
}
int main() {
char a[] = {0,0,0,0};
bool i = rad_get_input(a, 4);
printf("%lu\n", strlen(a));
rad_rstrip_nl(a);
return i;
}
The two functions above main() are copy-pasted from that file.
Let’s zoom in:
int len_str = strlen(str);
if (str[len_str-1]=='\n') {
Here we’re accessing str[len_str-1] without checking len_str first.
But you might be thinking, maybe len_str can’t be zero!
Let’s compile first with the AddressSanitizer enabled:
# compile
% gcc -Wall -fsanitize=address t.c -o t
Now let’s see how easily we can have fun:
% echo -n '\0' | ./t
=================================================================
==2949689==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ba827af001f at pc 0x56032434d259 bp 0x7fff1d199010 sp 0x7fff1d199000
READ of size 1 at 0x7ba827af001f thread T0
#0 0x56032434d258 in rad_rstrip_nl (/tmp/t+0x1258) (BuildId: 1ee68e4d67960002de80ae290c8811c63f94aa51)
#1 0x56032434d311 in rad_get_input (/tmp/t+0x1311) (BuildId: 1ee68e4d67960002de80ae290c8811c63f94aa51)
#2 0x56032434d3e4 in main (/tmp/t+0x13e4) (BuildId: 1ee68e4d67960002de80ae290c8811c63f94aa51)
#3 0x7fa82a227740 (/usr/lib/libc.so.6+0x27740) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
#4 0x7fa82a227878 in __libc_start_main (/usr/lib/libc.so.6+0x27878) (BuildId: 020d6f7c33b2413f4fe10814c4729dce1387f049)
#5 0x56032434d124 in _start (/tmp/t+0x1124) (BuildId: 1ee68e4d67960002de80ae290c8811c63f94aa51)
(The rest of AddressSanitizer output omitted.)
Another function from the same file:
char* rad_strcpy (char* out, const char* inp, int from, int len) {
const char* inp_shifted = inp+from;
int len_inp_shifted = strlen(inp_shifted);
if (len <= len_inp_shifted) {
memcpy(out,inp,len);
out[len] = 0;
}
else {
memcpy(out,inp,len_inp_shifted);
out[len_inp_shifted] = 0;
}
return out;
}
Here, inp is shifted before inp length is checked, which doesn’t look safe. But my one minute is up, so I didn’t dive into the function callers.
Pretending C is a good choice in 2026, then not being extra vigilant with defensive programming, is not a good look. I remember myself being more vigilant in my wrappers even when I was a beginner.
This is made worse by the developer repeating literal memes like:
One issue I have with rust is that it adds another layer of trusting the compiler isn’t backdoored. All UNIX/Linux systems use the gcc toolchain
Maybe such an enlightened developer should know that you can bootstrap rustc from mrustc using GCC.
Awesome, I think you’re the first person to give Cradicle a bit of a code audit. Thank you. I’ll check your feedback with a more C-focused programming community to see what others think before passing it onto the dev.
This reminds me of another reason I thought the dev made an interesting choice with C: by using C, we might attract “red team” volunteers to provide scrutiny.
But why? Radicle supports TOR and I2P (see changelog).
At the time I made the proposal, I couldn’t figure out a simple way to seed repos with Radicle like I was familiar with from GUI-based BitTorrent clients, and when I asked people in the community why it was so complicated, the answer I ended up with was that it was due to domain names / static IP addresses being required instead of onion addresses (or other decentralized cryptographic addresses)
Has that changed since then? Doesn’t quite seem clear to me from the link you posted
Edit - after thinking about it a little more, I remember it may have been possible to use Tor via a proxy at the time I made the proposal, but it didn’t work fully and wasn’t anywhere near a 1 click solution like bittorrent. Still not sure if that’s changed
Radicle doesn’t have a 1-click solution to TOR and I2P, but there is a guide. Granted, radicle could do with a GUI configuration tool, but I think a fork and C rewrite are unnecessary to achieve that. A script around it could probably achieve the same. On nixos, it would be a simple matter of writing and sharing a configuration.
Is Tor really “straightforward”? It sounds anything but.
Also C? In 2026? Radicle seems to be written mostly in Rust, with Typescript for the web interface. Why on earth would you want to downgrade to C?
Cradicle’s web interface improves security by keeping all the complex functionality in the HTML server and serving pure scriptless HTML to web browsers instead.
That isn’t really any more secure.
I hear it allows more control over compiler behavior
Not in a good way - more like a “oh good what compiler flags do I need to mess with to make this code work?” way 😄
there should be radicle apps in multiple coding languages, like there are BitTorrent apps in multiple coding languages.
Reasonable. C is still a poor choice though.
That isn’t really any more secure.
It is when javascript vulnerabilities are exploited, that’s why Tor Browser’s “safest” preset doesn’t allow js
Ah you’re expecting users to browse with no JS enabled. Does Radicle’s web interface actually require JS anyway? And either way that’s no reason to pick C over Typescript.
I don’t remember the exact extent or know if it’s changed, but Radicle’s web interface definitely used javascript excessively at the time I posted the original proposal.
It sounds like I was confused about Typescript, I thought it was more closely related to js
Typescript is JavaScript, just with static type annotations.
I don’t see the point of forking Radicle. Radicle itself barely has any users, how many users do you expect your fork to have? Think about re-writing Radicle in another language later. It’s not certain Radicle will even exist a year from now
deleted by creator