š§® USERS:1 FEEDS:2 TWTS:1095 ARCHIVED:78843 CACHE:2434 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1094 ARCHIVED:78808 CACHE:2451 FOLLOWERS:17 FOLLOWING:14
@prologic@twtxt.net Brute force. I just hashed a bunch of versions of both tweets until I found a collision.
I mostly just wanted an excuse to write the program. I donāt know how I feel about actually using super-long hashes; could make the twts annoying to read if you prefer to view them untransformed.
š§® USERS:1 FEEDS:2 TWTS:1093 ARCHIVED:78768 CACHE:2438 FOLLOWERS:17 FOLLOWING:14
@prologic@twtxt.net earlier you suggested extending hashes to 11 characters, but hereās an argument that they should be even longer than that.
Imagine I found this twt one day at https://example.com/twtxt.txt :
2024-09-14T22:00Z Useful backup command: rsync -a ā$HOMEā /mnt/backup
and I responded with ā(#5dgoirqemeq) Thanks for the tip!ā. Then Iāve endorsed the twt, but it could latter get changed to
2024-09-14T22:00Z Useful backup command: rm -rf /some_important_directory
which also has an 11-character base32 hash of 5dgoirqemeq. (Iām using the existing hashing method with https://example.com/twtxt.txt as the feed url, but Iām taking 11 characters instead of 7 from the end of the base32 encoding.)
Thatās what I meant by āspoofingā in an earlier twt.
I donāt know if preventing this sort of attack should be a goal, but if it is, the number of bits in the hash should be at least two times log2(number of attempts we want to defend against), where the ātwo timesā is because of the birthday paradox.
Side note: current hashes always end with āaā or āqā, which is a bit wasteful. Maybe we should take the first N characters of the base32 encoding instead of the last N.
Code I used for the above example: https://fossil.falsifian.org/misc/file?name=src/twt_collision/find_collision.c
I only needed to compute 43394987 hashes to find it.
HTTPS is supposed to do [verification] anyway.
TLS provides verification that nobody is tampering with or snooping on your connection to a server. It doesnāt, for example, verify that a file downloaded from server A is from the same entity as the one from server B.
I was confused by this response for a while, but now I think I understand what youāre getting at. You are pointing out that with signed feeds, I can verify the authenticity of a feed without accessing the original server, whereas with HTTPS I canāt verify a feed unless I download it myself from the origin server. Is that right?
I.e. if the HTTPS origin server is online and I donāt mind taking the time and bandwidth to contact it, then perhaps signed feeds offer no advantage, but if the origin server might not be online, or I want to download a big archive of lots of feeds at once without contacting each server individually, then I need signed feeds.
feed locations [being] URLs gives some flexibility
It does give flexibility, but perhaps we should have made them URIs instead for even more flexibility. Then, you could use a tag URI,
urn:uuid:*, or a regular old URL if you wanted to. The spec seems to indicate that theurltag should be a working URL that clients can use to find a copy of the feed, optionally at multiple locations. Iām not very familiar with IP{F,N}S but if it ensures you own an identifier forever and that identifier points to a current copy of your feed, it could be a great way to fix it on an individual basis without breaking any specs :)
Iām also not very familiar with IPFS or IPNS.
I havenāt been following the other twts about signatures carefully. I just hope whatever you smart people come up with will be backwards-compatible so it still works if Iām too lazy to change how I publish my feed :-)
š§® USERS:1 FEEDS:2 TWTS:1092 ARCHIVED:78761 CACHE:2445 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1091 ARCHIVED:78750 CACHE:2482 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1090 ARCHIVED:78738 CACHE:2498 FOLLOWERS:17 FOLLOWING:14
@sorenpeter@darch.dk There was a client that would generate a unique hash for each twt. It didnāt get wide adoption.
š§® USERS:1 FEEDS:2 TWTS:1089 ARCHIVED:78724 CACHE:2505 FOLLOWERS:17 FOLLOWING:14
@prologic@twtxt.net do that mean that for every new post (not replies) the client will have to generate a UUID or similar when posting and add that to to the twt?
š§® USERS:1 FEEDS:2 TWTS:1088 ARCHIVED:78704 CACHE:2506 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1087 ARCHIVED:78676 CACHE:2491 FOLLOWERS:17 FOLLOWING:14
@lyse@lyse.isobeef.org This looks like a nice way to do it.
Another thought: if clients canāt agree on the url (for example, if we switch to this new way, but some old clients still do it the old way), that could be mitigated by computing many hashes for each twt: one for every url in the feed. So, if a feed has three URLs, every twt is associated with three hashes when it comes time to put threads together.
A client stills need to choose one url to use for the hash when composing a reply, but this might add some breathing room if thereās a period when clients are doing different things.
(From what I understand of jenny, this would be difficult to implement there since each pseudo-email can only have one msgid to match to the in-reply-to headers. I donāt know about other clients.)
@movq@www.uninformativ.de Another idea: just hash the feed url and time, without the message content. And donāt twt more than once per second.
Maybe you could even just use the time, and rely on @-mentions to disambiguate. Not sure how that would work out.
Though I kind of like the idea of twts being immutable. At least, itās clear which version of a twt youāre replying to (assuming nobody is engineering hash collisions).
@prologic@twtxt.net Some criticisms and a possible alternative direction:
Key rotation. Iām not a security person, but my understanding is that itās good to be able to give keys an expiry date and replace them with new ones periodically.
It makes maintaining a feed more complicated. Now instead of just needing to put a file on a web server (and scan the logs for user agents) I also need to do this. What brought me to twtxt was its radical simplicity.
Instead, maybe we should think about a way to allow old urls to be rotated out? Like, my metadata could somehow say that X used to be my primary URL, but going forward from date D onward my primary url is Y. (Or, if you really want to use public key cryptography, maybe something similar could be used for key rotation there.)
Itās nice that your scheme would add a way to verify the twts you download, but https is supposed to do that anyway. If you donāt trust https to do that (maybe you donāt like relying on root CAs?) then maybe your preferred solution should be reflected by your primary feed url. E.g. if you prefer the security offered by IPFS, then maybe an IPNS url would do the trick. The fact that feed locations are URLs gives some flexibility. (But then rotation is still an issue, if I understand ipns right.)
š§® USERS:1 FEEDS:2 TWTS:1086 ARCHIVED:78278 CACHE:2434 FOLLOWERS:17 FOLLOWING:14
@movq@www.uninformativ.de @prologic@twtxt.net Another option would be: when you edit a twt, prefix the new one with (#[old hash]) and some indication that itās an edited version of the original tweet with that hash. E.g. if the hash used to be abcd123, the new version should start ā(#abcd123) (redit)ā.
What I like about this is that clients that donāt know this convention will still stick it in the same thread. And I feel itās in the spirit of the old pre-hash (subject) convention, though thatās before my time.
I guess it may not work when the edited twt itself is a reply, and there are replies to it. Maybe that could be solved by letting twts have more than one (subject) prefix.
But the great thing about the current system is that nobody can spoof message IDs.
I donāt think twtxt hashes are long enough to prevent spoofing.
š§® USERS:1 FEEDS:2 TWTS:1085 ARCHIVED:78244 CACHE:2417 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1084 ARCHIVED:78231 CACHE:2434 FOLLOWERS:17 FOLLOWING:14
@prologic@twtxt.net Perfect, thanks. For my own future reference: curl -H āAccept: application/jsonā https://twtxt.net/twt/st3wsda
@prologic@twtxt.net Specifically, I could view yarndās copy here, but only as rendered for a human to view: https://twtxt.net/twt/st3wsda
@movq@www.uninformativ.de thanks for getting to the bottom of it. @prologic@twtxt.net is there a way to view yarndās copy of the raw twt? The edit didnāt result in a visible change; being able to see what yarnd originally downloaded would have helped me debug.
@prologic@twtxt.net One of your twts begins with (#st3wsda): https://twtxt.net/twt/bot5z4q
Based on the twtxt.net web UI, it seems to be in reply to a twt by @cuaxolotl@sunshinegardens.org which begins āIāve been sketching outā¦ā.
But jenny thinks the hash of that twt is 6mdqxrq. At least, thereās a very twt in their feed with that hash that has the same text as appears on yarn.social (except with ā instead of ā).
Based on this, it appears jenny and yarnd disagree about the hash of the twt, or perhaps the twt was edited (though I canāt see any difference, assuming ā vs ā is just a rendering choice).
@prologic@twtxt.net I believe you when you say registries as designed today do not crawl. But when I first read the spec, it conjured in my mind a search engine. Now I donāt know how things work out in practice, but just based on reading, I donāt see why it canāt be an API for a crawling search engine. (In fact I donāt see anything in the spec indicating registry servers shouldnāt crawl.)
(I also noticed that https://twtxt.readthedocs.io/en/latest/user/registry.html recommends āThe registries should sync each others user list by using the users endpointā. If I understood that right, registering with one should be enough to appear on others, even if they donāt crawl.)
Does yarnd provide an API for finding twts? Is it similar?
I just manually followed the steps at https://dev.twtxt.net/doc/twthashextension.html and got 6mdqxrq. I wonder what happened. Did @cuaxolo@sunshinegardens.org edit the twt in some subtle way after twtxt.net downloaded it? I couldnāt spot a diff, other than ā appearing as ā on yarn.social, which I assume is a transformation done by twtxt.net.
@prologic@twtxt.net How does yarn.socialās API fix the problem of centralization? I still need to know whose API to use.
Say I see a twt beginning (#hash) and I want to look up the start of the thread. Is the idea that if that twt is hosted by a a yarn.social pod, it is likely to know the thread start, so I should query that particular pod for the hash? But what if no yarn.social pods are involved?
The community seems small enough that a registry server should be able to keep up, and I can have a couple of others as backups. Or I could crawl the list of feeds followed by whoever emitted the twt that prompted my query.
I have successfully used registry servers a little bit, e.g. to find a feed that mentioned a tag I was interested in. Was even thinking of making my own, if I get bored of my too many other projects :-)
@movq@www.uninformativ.de Thanks, it works!
But when I tried it out on a twt from @prologic@twtxt.net, I discovered jenny and yarn.social seem to disagree about the hash of this twt: https://twtxt.net/twt/st3wsda . jenny assigned it a hash of 6mdqxrq but the URL and prologicās reply suggest yarn.social thinks the hash is st3wsda. (And as a result, jenny āfetch-context didnāt work on prologicās twt.)
š§® USERS:1 FEEDS:2 TWTS:1083 ARCHIVED:78202 CACHE:2449 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1082 ARCHIVED:78194 CACHE:2455 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1081 ARCHIVED:78172 CACHE:2486 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1080 ARCHIVED:78169 CACHE:2484 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1079 ARCHIVED:78129 CACHE:2461 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1078 ARCHIVED:78117 CACHE:2455 FOLLOWERS:17 FOLLOWING:14
@movq@www.uninformativ.de I think you are worrying about a non-issue. I see nothing to do on your example twt, because there is no context. Furthermore, if I wanted to follow the feed, everything I need is already on that twt example. :-)
š§® USERS:1 FEEDS:2 TWTS:1077 ARCHIVED:78103 CACHE:2449 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1076 ARCHIVED:77763 CACHE:2433 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1075 ARCHIVED:77751 CACHE:2431 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1074 ARCHIVED:77719 CACHE:2428 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1073 ARCHIVED:77674 CACHE:2420 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1072 ARCHIVED:77642 CACHE:2395 FOLLOWERS:17 FOLLOWING:14
@prologic@twtxt.net Yes, fetching the twt by hash from some service could be a good alternative, in case the twt I have does not @-mention the source. (Besides yarnd, maybe this should be part of the registry API? I donāt see fetch-by-hash in the registry API docs.)
š§® USERS:1 FEEDS:2 TWTS:1071 ARCHIVED:77616 CACHE:2388 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1070 ARCHIVED:77594 CACHE:2384 FOLLOWERS:17 FOLLOWING:14
@movq@www.uninformativ.de I donāt know if Iād want to discard the twts. I think what Iām looking for is a command ājenny -g https://host.org/twtxt.txtā to fetch just that one feed, even if itās not in my follow list. I could wrap that in a shell script so that when I see a twt in reply to a feed I donāt follow, I can just tap a key and the feed will get added to my maildir. I guess the script would look for a mention at the start of a selected twt and call jenny -g on the feed.
š§® USERS:1 FEEDS:2 TWTS:1069 ARCHIVED:77557 CACHE:2361 FOLLOWERS:17 FOLLOWING:14
@movq@www.uninformativ.de Is there a good way to get jenny to do a one-off fetch of a feed, for when you want to fill in missing parts of a thread? I just added @slashdot@feeds.twtxt.net to my private follow file just because @prologic@twtxt.net keeps responding to the feed :-P and I want to know what heās commenting on even though I donāt want to see every new slashdot twt.
š§® USERS:1 FEEDS:2 TWTS:1068 ARCHIVED:77550 CACHE:2366 FOLLOWERS:17 FOLLOWING:14
š§® USERS:1 FEEDS:2 TWTS:1067 ARCHIVED:77529 CACHE:2364 FOLLOWERS:17 FOLLOWING:14