Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

erincandescent 💜

@erincandescent.akko.erincandescent.net.ap.brid.gy
8 followers 1 following 38 posts

immigrant | software engineer in card payments liker of ISO 8583, the 8051, ASN.1, SS7 and EBCDIC. 30-something who's grew up online and has seen […] 🌉 bridged from ⁂ akko.erincandescent.net/users/erinc…, follow @ap.brid.gy to interact

PostsRepliesMedia
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 16/10/2026
Hallelujah.
002 2
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 16/10/2026
Can't believe the definition of UNIX Time was so unfixably bad we as a society decided we had to abolish UTC instead (The CGPM has voted to abolish the leap second)
111 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 14/10/2026
Mandatory email OTP is one of the most infuriating creations of mankind
002 2
Reposted by erincandescent 💜
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 13/10/2026
Please stop hashing the public key first (or: ML-DSA's µ annoys me): blog.erincandescent.net/2026/10/mu-…
blog.erincandescent.net
Please stop hashing the public key first (or: ML-DSA's µ annoys me)
A goal one might have when designing a signing algorithm is to prevent signing a message one has not seen. Signing a message one hasn't seen might sound difficult at first, but most classical signature algorithms, as commonly used, sign a hash of the message, rather than the message itself. This kind of arrangement is necessitated by the fact that the underlying algorithms are only capable of signing messages of a limited size. You might not have seen the message, but you might have seen the hash of it, or another signature which encodes said hash. In many protocols, this lets you produce a valid signature on a message you've never seen. That's rarely a problem in practice, but it can be surprising, and it's a pitfall for the unsuspecting protocol designer. More recent algorithms take steps to prevent this: * Ed25519 signs `SHA-512(R || PubK || M)` where R is functionally a random curve point, PubK is the public key, M is the message, and `||` is the concatenation operator * ML-DSA signs `SHAKE-256(SHAKE-256(PubK, 64) || 0x00 || len(ctx) || ctx || m, 64)` (where ctx is a 0 to 255 byte context string) This can complicate your signing code, particularly when dealing with HSMs or smart cards, but it doesn't require majorly reworking your signing process. Unfortunately, on the verification side things are less rosy. ## The challenge As a general rule of thumb, we should avoid touching the body of a signed message until we've verified the signature. Also as a general rule of thumb, cryptographic protocols where there are multiple signers put the signer's identity within said body (X.509, most JWT and CWT usages, SAML, I'm looking at all of you, but you're not the only ones). This means the verification process ends up being 1. Gingerly parse the message 2. Dig through as much message as necessary to identify the signing key 3. Actually verify the message 4. Actually consume the message Often (JWT, CWT and SAML again), there's either no key identifier present in the signed message, or it's permitted for multiple signing keys to share a key identifier†. This means that, if the issuer has multiple keys, you may have to do multiple trial-verifications to work out if the message is actually valid. One nice property that all of these protocols have (except XML Digital Signatures, but _nobody_ thinks XML Digital Signatures were a good idea) is that they carry the signing method in a header. So, with a traditional signing algorithm, you have the option of 1. Parsing the header 2. Identify algorithm and hence the hash algorithm 3. Hash the message 4. Gingerly parse the message 5. Dig through as much message as necessary to identify the signing key 6. Actually verify the message 7. Actually consume the message This comes with two advantages: 1. After step 3, you can throw away the raw message, reducing memory usage 2. In step 6, you pay for the cost of verifying a signature for every attempted key rather than also the cost of re-hashing the message. In most cases messages are small and this cost is also small, but every little helps. Unfortunately, it has the slight flaw that it doesn't work with either Ed25519 or ML-DSA as defined. For ML-DSA, it would have been quite easy to re-arrange matters. If we instead computed `SHAKE-256(0x00 || len(ctx) || ctx || m || SHAKE-256(PubK, 64), 64)` (i.e. we put the public key hash in _at the end_), then we can hold our SHAKE-256 context around and copy it for each trial verification. We'd end up keeping just over 200 bytes of SHAKE-256 context around (instead of 64 bytes of output), but that's not too bad. Unfortunately, that's not the choice that was made and we'll just have to deal with it. Ed25519 is slightly more challenging. If we reversed the hash computation to be `SHA-512(M || R || PubK)` instead, it would be vulnerable to length extension attacks (for any `SHA-512(X)` you can extend it into `SHA-512(X || some predictable garbage || Y)` for any arbitrary Y). Fixing that when Ed25519 was published in 2011 would be somewhat tricky, though the easiest option without truncating the hash is just to sign `SHA-512(SHA-512("ed25519 domain separation" || M || R || PubK))`. Since we don't have a time machine, it's all a bit academic. In 2026 you can just avoid the problem by using SHA-3, BLAKE2, a truncated SHA-2 variant, or any other modern hash function which isn't vulnerable to length extension attacks. In the meantime I'll just sigh and hope we can reduce the number of signatures we pass around, given they're really becoming rather large and expensive. * * * † You may be thinking it somewhat defeats the purpose of having a key identifier if they aren't unique. I don't disagree!
011 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 13/10/2026
Please stop hashing the public key first (or: ML-DSA's µ annoys me): blog.erincandescent.net/2026/10/mu-…
blog.erincandescent.net
Please stop hashing the public key first (or: ML-DSA's µ annoys me)
A goal one might have when designing a signing algorithm is to prevent signing a message one has not seen. Signing a message one hasn't seen might sound difficult at first, but most classical signature algorithms, as commonly used, sign a hash of the message, rather than the message itself. This kind of arrangement is necessitated by the fact that the underlying algorithms are only capable of signing messages of a limited size. You might not have seen the message, but you might have seen the hash of it, or another signature which encodes said hash. In many protocols, this lets you produce a valid signature on a message you've never seen. That's rarely a problem in practice, but it can be surprising, and it's a pitfall for the unsuspecting protocol designer. More recent algorithms take steps to prevent this: * Ed25519 signs `SHA-512(R || PubK || M)` where R is functionally a random curve point, PubK is the public key, M is the message, and `||` is the concatenation operator * ML-DSA signs `SHAKE-256(SHAKE-256(PubK, 64) || 0x00 || len(ctx) || ctx || m, 64)` (where ctx is a 0 to 255 byte context string) This can complicate your signing code, particularly when dealing with HSMs or smart cards, but it doesn't require majorly reworking your signing process. Unfortunately, on the verification side things are less rosy. ## The challenge As a general rule of thumb, we should avoid touching the body of a signed message until we've verified the signature. Also as a general rule of thumb, cryptographic protocols where there are multiple signers put the signer's identity within said body (X.509, most JWT and CWT usages, SAML, I'm looking at all of you, but you're not the only ones). This means the verification process ends up being 1. Gingerly parse the message 2. Dig through as much message as necessary to identify the signing key 3. Actually verify the message 4. Actually consume the message Often (JWT, CWT and SAML again), there's either no key identifier present in the signed message, or it's permitted for multiple signing keys to share a key identifier†. This means that, if the issuer has multiple keys, you may have to do multiple trial-verifications to work out if the message is actually valid. One nice property that all of these protocols have (except XML Digital Signatures, but _nobody_ thinks XML Digital Signatures were a good idea) is that they carry the signing method in a header. So, with a traditional signing algorithm, you have the option of 1. Parsing the header 2. Identify algorithm and hence the hash algorithm 3. Hash the message 4. Gingerly parse the message 5. Dig through as much message as necessary to identify the signing key 6. Actually verify the message 7. Actually consume the message This comes with two advantages: 1. After step 3, you can throw away the raw message, reducing memory usage 2. In step 6, you pay for the cost of verifying a signature for every attempted key rather than also the cost of re-hashing the message. In most cases messages are small and this cost is also small, but every little helps. Unfortunately, it has the slight flaw that it doesn't work with either Ed25519 or ML-DSA as defined. For ML-DSA, it would have been quite easy to re-arrange matters. If we instead computed `SHAKE-256(0x00 || len(ctx) || ctx || m || SHAKE-256(PubK, 64), 64)` (i.e. we put the public key hash in _at the end_), then we can hold our SHAKE-256 context around and copy it for each trial verification. We'd end up keeping just over 200 bytes of SHAKE-256 context around (instead of 64 bytes of output), but that's not too bad. Unfortunately, that's not the choice that was made and we'll just have to deal with it. Ed25519 is slightly more challenging. If we reversed the hash computation to be `SHA-512(M || R || PubK)` instead, it would be vulnerable to length extension attacks (for any `SHA-512(X)` you can extend it into `SHA-512(X || some predictable garbage || Y)` for any arbitrary Y). Fixing that when Ed25519 was published in 2011 would be somewhat tricky, though the easiest option without truncating the hash is just to sign `SHA-512(SHA-512("ed25519 domain separation" || M || R || PubK))`. Since we don't have a time machine, it's all a bit academic. In 2026 you can just avoid the problem by using SHA-3, BLAKE2, a truncated SHA-2 variant, or any other modern hash function which isn't vulnerable to length extension attacks. In the meantime I'll just sigh and hope we can reduce the number of signatures we pass around, given they're really becoming rather large and expensive. * * * † You may be thinking it somewhat defeats the purpose of having a key identifier if they aren't unique. I don't disagree!
011 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 13/10/2026
Deutsche Leute, hast jemand gestern in irgendeines Supermarkt, Kühlschrank Problemen gesehen? Ich war in einem Supermarkt in Berlin, wo die Kühlschränke komplett leer oder zugeklebt war, und ich glaube es ist wahrscheinlich nicht einer Zufall… (Boosts OK)
tomshardware.com
'Unprecedented' Cyberattack cripples supermarket fridges across Europe as hackers activate automatic defrosting
A cyberattack has hit supermarkets in Europe, disabling refrigerators.
100 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 11/10/2026
In the continuing tale of networking hauntedness, I've had some mysteriously slow downloads for months, that finally annoyed me enough to go properly debugging 😭 Turns out that fiber that looked plugged into the SFP wasn't and I had 1-5% packet loss on a primary link on our LAN
100 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 06/10/2026
"Mistral said Le Chonk - officially named Mistral Large 4 - will be made fully public on October 27." How is this real text from a real Reuters article?! 😭https://www.reuters.com/world/china/mistral-ceo-says-new-ai-model-beats-chinese-ones-some-areas-2026-10-06/
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 05/10/2026
Prediction: A track created substantially with Generative AI will wedge itself solidly inside our collective heads and refuse to be evicted in the next 12 months. Think something "Baby shark"-esque
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 03/10/2026
"Why on earth am I compiling DuckDB today?!" and other NixOS induced horrors beyond my comprehension
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 03/10/2026
Spent the morning debugging a confusing networking problem (ARPs from VM not being bridged onto the network). Turns out: NIC driver's haunted. Newer kernel exorcises the bug.
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 26/09/2026
I picked up Silent Hill: Townfall on a whim and while it's not without flaws, it nails the feeling of 90s working class Britain (when it's not just nailing the feeling of desperation required of a horror game)
Two Belisha Beacons (striped poles with flashing amber lights on top), a zebra crossing,...
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 24/09/2026
What on earth are Apple cooking www.applemusichall.com
applemusichall.com
Apple Music Hall
Apple’s first-ever live venue inside the iconic Battersea Power Station, London. Opening September, 28. A new venue from Apple Music.
001 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 22/09/2026
Short story idea: an astronomer many billions of years into the future muses over the fact that they know other galaxies once existed from many records and photos, but all evidence is now gone from the night's sky
100 1
Reposted by erincandescent 💜
dra!_kulix @drakulix.de · 22/09/2026
[ranty, KDE, DDH, big tech] I swear FOSS discourse has evolved into the same reactionary infighting seen in leftist spaces. It is wild to me, how a bunch of people scream “nazi bar”, when a certain guest speaker in the KDE space brings up Omarchy as a bad example and publicly denounces DDH […]
social.dreampi.es
Original post on social.dreampi.es
031 3
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 20/09/2026
Chat my k8s control plane was crashing every 15 minutes for **two whole months** and I didn't notice >_>
200 2
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 17/09/2026
If your multi-page essay on why LLMs can't be conscious fundamentally boils down the idea that man can't create a soul, then it's not a scientific or philosophical argument but in fact a religious one. I expect better epistemics.
101 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 12/09/2026
If there's one thing my LLM loving and hating friends all agree on, it's that Dario Amodei (CEO of Anthropic) should shut the fuck up with his sinophobic rambling
110 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 10/09/2026
Wee woo, says the siren across the border on Brandenburg but not my phone?!
100 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 10/09/2026
It has taken all of a couple of months for work to go from "everyone gets a Claude license!" to "Sonnet is blocked and maybe tomorrow we'll block Opus too". Incredible levels of own-goal scoring from team Anthropic lately.
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 09/09/2026
"Why am I having so much trouble concentrating on work today?" wonders woman who's forgotten to feed her caffeine addiction
000 0
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 08/09/2026
On finding bugs in Ceph(X): blog.erincandescent.net/2026/09/on-…
blog.erincandescent.net
On finding bugs in Ceph(X)
On the 28th August 2026, the Ceph project released fixes for CVE-2025-30156 and CVE-2026-39944. I first reported these to the project on the 20th December 2024; they were independently rediscovered in the meantime. These are high risk bugs that are also _extremely_ difficult to remediate, and require coordination across a lot of projects (not just Ceph itself, but the Linux kernel, Rook, and other related projects). They also required implementing methods of doing cluster key rotations. On the one hand, I understand why it took so long to fix these; on the other hand, it is still disappointing that the resolution timeline took over 18 months. Nontheless, my thanks to the Ceph team for their handling of this. These were human findings. Today, I expect you could throw an LLM at the Ceph codebase and these sorts of bugs would fall out quite quickly, but that wasn't the case in 2024. ## Background Ceph RGW has functionality which integrates with OpenStacks KeyStone, and also emulates the AWS STS API. I was investigating how these worked, looking at the possibility of doing an integration. As I was doing this, I noticed that the same `CryptoKeyHandler` class was used for to hold keys for both HMAC-SHA256 MACs and AES-CBC encryption. This piqued my curiosity; mixing keys with different algorithms like this is a code smell. In the end, the same keys are never reused with both, so while this is suboptimal design it isn't a security problem as written. However, this lead me to look at the AES-CBC encryption code, where I discovered that fixed keys were reused with hardcoded nonces. AES-CBC is not an authenticated-encryption mode (meaning it does not protect against message alteration, though it does hinder it), and also degrades in security significantly when nonces are reused. As I discovered, this use of AES-CBC was the _only_ protection applied to messages protected with CephX, and to RGW session tokens. As the CLYSO researchers who also found this bug demonstrated, it is possible to elevate privileges on vulnerable RGW installs with simple bitflips. This is sadly not a complicated issue to find; any junior cryptographic engineer should have several klaxons going off in their head at the sight of a hardcoded nonce without good justification. I was not searching through the Ceph codebase for a critical security vulnerability; I just happened to stumble upon it. ## Takeaways Ceph is an old project; the design of CephX likely predates the wide dissemination of the AEAD construct. We should pay attention to other codebases of similar vintage which also sometimes had to hand-roll their cryptographic protocols out of necessity.
021 2
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 07/09/2026
I feel like over the weekend the magnitude of the change happening in my field really hit me and it leaves me feeling profoundly wistful
010 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 05/09/2026
:drgn_think__w_: Cuddle me like a crimped Ferule cuddles the end of a stranded wire
000 0
Reposted by erincandescent 💜
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 03/09/2026
Kaufen eine Ersatzteile für unser Vapcap und ich sehe dies… Ja ich würde gern einen Großbuchstabe kaufen, bitte gib mir eine E.
Shop menu mit Möglichkeiten "Alle teile", "Zusatsteile, CCDs & O-Ringe", "Grossbuchstaben" (sic), "Tipps", "Mittelsektionen & Kondensatoren", "Ball-Vaporizer"
001 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 03/09/2026
Kaufen eine Ersatzteile für unser Vapcap und ich sehe dies… Ja ich würde gern einen Großbuchstabe kaufen, bitte gib mir eine E.
Shop menu mit Möglichkeiten "Alle teile", "Zusatsteile, CCDs & O-Ringe", "Grossbuchstaben" (sic), "Tipps", "Mittelsektionen & Kondensatoren", "Ball-Vaporizer"
001 1
erincandescent 💜 @erincandescent.akko.erincandescent.net.ap.brid.gy · 03/09/2026
You cannot believe how unreasonably excited I was when I went to import this months colocation invoices and instead of PDFs they were XML files :drgn __w_ : No more telling the accounting software “no, _that_ field contains the invoice number. _that_ field contains the invoice total amount […]
akko.erincandescent.net
Original post on akko.erincandescent.net
010 1