Hacker News discussion of the bitcoin++ writeup
hn-dettmer-writeup-thread
Latest reviewed change
source content difference between and
New comment by jki275 (2026-08-07T01:18:26Z) replying to nullc about what telegraphs competence. No other thread changes.
"children": [
{
"author": "nullc",
- "children": [],
+ "children": [
+ {
+ "author": "jki275",
+ "children": [],
First lines only. The complete diff is in the timeline below.
- Organisation
- Hacker News
- Evidence role
- Reporting
- Published
- 2026-08-02
- Source changes
- 4
- Detected differences
- 10
- Unreviewed
- 0
- Copies held
- 11
The thread on Dettmer's commit-history writeup, and the place where the correction this archive already holds separately was published: Greg Maxwell's comment disputing the small-flag-change framing sits inside it, registered as hn-maxwell-mechanism. Held for the discussion around that correction rather than for the article itself, which is tracked as btcpp-dettmer-commit-history.
The held text recursively flattens the item tree by stable comment id, decodes the API's HTML and omits point totals, so a new or edited comment stays loud without vote changes producing revisions.
Every check is recorded, including checks that found no text change. A detected edit is therefore bounded between two checks. The publisher's exact save time is not observable from this record. Last checked .
This post is held twice: here, with this project's own note on why it matters, and again as part of the conversation captured at , which is polled for changes. Both copies are the same post; neither is a separate event.
Snapshot and diff bodies for this chain monitor are held in the local evidence archive but withheld from the public site because they can contain the addresses of people who published nothing themselves. Capture times and reviewed change summaries remain available below.
Held captures
-
The collector changed this Algolia item from pretty-printed API JSON to deterministic readable thread text; the same discussion tree is held, with HTML decoded and volatile API fields omitted.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 1416 lines
-{ - "author": "Funes-", - "children": [ - { - "author": "anonymousiam", - "children": [ - { - "author": "Sharlin", - "children": [], - "created_at": "2026-08-02T05:01:23.000Z", - "created_at_i": 1785646883, - "id": 49141270, - "options": [], - "parent_id": 49141102, - "points": null, - "story_id": 49140405, - "text": "Hanlon’s razor.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "eru", - "children": [ - { - "author": "thin_carapace", - "children": [ - { - "author": "scott_w", - "children": [ - { - "author": "nullc", - "children": [ - { - "author": "scott_w", - "children": [], - "created_at": "2026-08-02T21:07:14.000Z", - "created_at_i": 1785704834, - "id": 49148323, - "options": [], - "parent_id": 49146618, - "points": null, - "story_id": 49140405, - "text": "Fair point: I was using the information in the article to form my opinion. I still think that, if the developer in question ignored a compiler error as described, that’s a serious competence issue. It’s harder to spot after the fact because any reviewers wouldn’t have had a chance to see the compiler output.<p>The article makes the fair point of the size of the change and the complete lack of information in the commit message, which should have set off alarm bells…", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T17:47:08.000Z", - "created_at_i": 1785692828, - "id": 49146618, - "options": [], - "parent_id": 49145347, - "points": null, - "story_id": 49140405, - "text": "> the error from the C compiler is something that a competent programmer would be able to interpret,<p>contrary to the post, this was almost certainly not an issue of compilers throwing errors.<p>Reduced familarity with C could have played a role, but given the number of C experts that looked at this knowing there was an error and <i>still</i> misidentified the cause I don't think we need to reach for that powerful an explanation.<p>Confusion of definedness vs value check would make for a fine underhanded C entry. The flaw was not particularly clear from the source... and most common QA procedures could not distinguish a PRNG from TRNG once the error happened.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "eru", - "children": [], - "created_at": "2026-08-03T01:07:07.000Z", - "created_at_i": 1785719227, - "id": 49150082, - "options": [], - "parent_id": 49145347, - "points": null, - "story_id": 49140405, - "text": "Of course, being a total novice and claiming to produce a super secure gadget are not to things you want to go together.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "Scoundreller", - "children": [], - "created_at": "2026-08-04T03:07:05.000Z", - "created_at_i": 1785812825, - "id": 49163987, - "options": [], - "parent_id": 49145347, - "points": null, - "story_id": 49140405, - "text": "Hey now, I'm totally incompetent, so my code writes entries in a log file for virtually everything because otherwise I have no idea if it's doing what I expect. Would've caught some critical function not being called at all.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T15:07:55.000Z", - "created_at_i": 1785683275, - "id": 49145347, - "options": [], - "parent_id": 49141474, - "points": null, - "story_id": 49140405, - "text": "Honestly, I'm going to be a bit harsher: I think they're either:<p>1. A novice who doesn't know how to debug issues.<p>2. Totally incompetent and copying code from Stack Overflow.<p>I don't think it's specific to microcontrollers, either, the error from the C compiler is something that a competent programmer would be able to interpret, or at least see it as a signal to get someone more experienced in the domain to learn about.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T05:43:31.000Z", - "created_at_i": 1785649411, - "id": 49141474, - "options": [], - "parent_id": 49141340, - "points": null, - "story_id": 49140405, - "text": "I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "jgilias", - "children": [], - "created_at": "2026-08-02T05:44:29.000Z", - "created_at_i": 1785649469, - "id": 49141482, - "options": [], - "parent_id": 49141340, - "points": null, - "story_id": 49140405, - "text": "The bug has been up since before the LLM shift.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "jki275", - "children": [ - { - "author": "nullc", - "children": [ - { - "author": "jki275", - "children": [], - "created_at": "2026-08-07T01:18:26.000Z", - "created_at_i": 1786065506, - "id": 49204786, - "options": [], - "parent_id": 49146607, - "points": null, - "story_id": 49140405, - "text": "I think some things telegraph competence and some the opposite -- and our experiences over the years tend to shape what we see that way.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T17:46:05.000Z", - "created_at_i": 1785692765, - "id": 49146607, - "options": [], - "parent_id": 49144692, - "points": null, - "story_id": 49140405, - "text": "> Also running python on a microcontroller to do cryptography is fucking insane.<p>I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color.<p>Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T13:49:05.000Z", - "created_at_i": 1785678545, - "id": 49144692, - "options": [], - "parent_id": 49141340, - "points": null, - "story_id": 49140405, - "text": "C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem.<p>Also running python on a microcontroller to do cryptography is fucking insane.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T05:16:48.000Z", - "created_at_i": 1785647808, - "id": 49141340, - "options": [], - "parent_id": 49141102, - "points": null, - "story_id": 49140405, - "text": "Also: writing this stuff in C just begs for bugs.<p>LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "karamanolev", - "children": [], - "created_at": "2026-08-02T07:39:00.000Z", - "created_at_i": 1785656340, - "id": 49142040, - "options": [], - "parent_id": 49141102, - "points": null, - "story_id": 49140405, - "text": "Per the article, not my opinion.<p>It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "silvestrov", - "children": [ - { - "author": "inigyou", - "children": [], - "created_at": "2026-08-02T12:45:18.000Z", - "created_at_i": 1785674718, - "id": 49144064, - "options": [], - "parent_id": 49142714, - "points": null, - "story_id": 49140405, - "text": "The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T09:33:07.000Z", - "created_at_i": 1785663187, - "id": 49142714, - "options": [], - "parent_id": 49141102, - "points": null, - "story_id": 49140405, - "text": "When looking through all the other commits the user has made: they all lack a good commit message.<p>This is systematic for that user. Either the user needs to improve or let go.<p>The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "anonymars", - "children": [], - "created_at": "2026-08-02T12:51:01.000Z", - "created_at_i": 1785675061, - "id": 49144132, - "options": [], - "parent_id": 49141102, - "points": null, - "story_id": 49140405, - "text": "Ironic:<p>> NEW POLICY If I don't know you, I don't merge you! Thanks XZ!<p><a href=\"https://github.com/switck/libngu\" rel=\"nofollow\">https://github.com/switck/libngu</a>", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T04:30:52.000Z", - "created_at_i": 1785645052, - "id": 49141102, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "systemsweird", - "children": [ - { - "author": "jonathanlydall", - "children": [ - { - "author": "smithcoin", - "children": [], - "created_at": "2026-08-02T08:36:14.000Z", - "created_at_i": 1785659774, - "id": 49142362, - "options": [], - "parent_id": 49142227, - "points": null, - "story_id": 49140405, - "text": "I think what is the author is getting at is that if you are cavalier in your commit messages when the stakes are low, chances are you aren’t taking writing code <i>that handles money</i> seriously. Made me think of some merges I could have taken more seriously.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T08:14:31.000Z", - "created_at_i": 1785658471, - "id": 49142227, - "options": [], - "parent_id": 49141837, - "points": null, - "story_id": 49140405, - "text": "This does not seem to be a good write up at all, see nullc’s explanation in this discussion of (what seems to me) the actual root cause whereas this article spent a lot of words making the argument that bad commit messages <i>must</i> mean bad code, later using the assertion to try “prove” what the technical problem was.<p>I agree that a bad commit message combined with a big commit is a huge smell, but as it’s just metadata for the code and not the code itself, it is not in itself evidence in any form.<p>That being said, probably okay after explaining the technical code issues for the author add a couple of a sentences about how all this was was part of 1000s of a lines of code changed in commits with useless messages which demonstrates generally bad code hygiene.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T06:58:01.000Z", - "created_at_i": 1785653881, - "id": 49141837, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "Very good writeup and an astonishing level of negligence for an extremely security critical piece of code. The losses are going to surpass 100 million, these guys should be thrown in jail.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "nullc", - "children": [ - { - "author": "nullc", - "children": [ - { - "author": "RustyRussell", - "children": [], - "created_at": "2026-08-02T09:04:47.000Z", - "created_at_i": 1785661487, - "id": 49142559, - "options": [], - "parent_id": 49142014, - "points": null, - "story_id": 49140405, - "text": "Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T07:34:54.000Z", - "created_at_i": 1785656094, - "id": 49142014, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "smithcoin", - "children": [ - { - "author": "nullc", - "children": [], - "created_at": "2026-08-02T17:54:43.000Z", - "created_at_i": 1785693283, - "id": 49146689, - "options": [], - "parent_id": 49142373, - "points": null, - "story_id": 49140405, - "text": "Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T08:37:43.000Z", - "created_at_i": 1785659863, - "id": 49142373, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities?", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "dist-epoch", - "children": [], - "created_at": "2026-08-02T10:28:58.000Z", - "created_at_i": 1785666538, - "id": 49143073, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input.<p>Hard problem in general, but with LLMs surely this is possible now, either with them inspecting or by them providing some sort of "formal" proof - this function calls this function which reads this buffer which gets input from here...", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "egwor", - "children": [], - "created_at": "2026-08-02T11:30:10.000Z", - "created_at_i": 1785670210, - "id": 49143450, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "Although I might disagree with the style of the write up, I think it is right that there are weak engineering practices applied:<p>- not enough information provided in commit message. \n- this change ought to have been split into smaller chunks (e.g. introduce indirection whilst code continues to use hardware)\n- limited (automated) testing\n- potential confusion by the author over C concepts\n- additional complexity which could have been hidden behind a cleaner interface rather than using defines<p>I agree about your points about:<p>- defines over multiple repo's made this more complicated that was necessary. \n- fault injections would have been the appropriate way to test this (or maybe mocks)\n- testing of randomness needs careful design, e.g. RNG seeding can be a good way<p>Taking a step back, we as a community of excellence need to emphasise that this isn't a criticism about the person/author. There needs to be a clear analysis of what went wrong whilst being kind to the person/people involved.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "inigyou", - "children": [ - { - "author": "nullc", - "children": [ - { - "author": "dale_glass", - "children": [ - { - "author": "nullc", - "children": [ - { - "author": "inigyou", - "children": [ - { - "author": "nullc", - "children": [], - "created_at": "2026-08-02T17:40:41.000Z", - "created_at_i": 1785692441, - "id": 49146562, - "options": [], - "parent_id": 49146187, - "points": null, - "story_id": 49140405, - "text": "Right, that's particularly a concern for DSA nonces. Coldcard uses RFC 6979 however, and duplicates at the 32-bit word level is a different matter than at the byte level.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T16:57:49.000Z", - "created_at_i": 1785689869, - "id": 49146187, - "options": [], - "parent_id": 49146167, - "points": null, - "story_id": 49140405, - "text": "There have been cases where a small statistical bias like avoiding duplicate bytes can be amplified to a full break. I don't think this problem is applicable to a bitcoin private key though.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T16:55:41.000Z", - "created_at_i": 1785689741, - "id": 49146167, - "options": [], - "parent_id": 49145802, - "points": null, - "story_id": 49140405, - "text": "I have absolutely no interest in defending this code-- and already considered it untrusthworthy before any of this. But in the interest of accuracy:<p>> It does a memcpy of a minimum of 4 bytes<p>This is a common misreading of MIN(). MIN(4,x) is a number that is a MAXIMUM of 4, not a minimum.<p>Count is the number of bytes remaining in the buffer. The input to the copy is a 4-byte word. min(4,count) will produce a number 0-4 which is always equal to or less than count. The copy will not overflow the buffer or overrun the input: If count is 3, for example, then here will be 3 and it will copy 3 bytes.<p>> believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output.<p>It's been a while since I looked but I believe the STM32 manual advises you to throw away data when this happens, because the rng is updated async with the processor and reads that are too fast will produce 0s or duplicate values. Entropy loss from doing so is generally negligible. Were it me I'd read enough into a cryptographic hash to render the output cryptographically close to uniform and not have to worry about it further. (particularly since some uses of cryptographic numbers are extremely sensitive to even small biases)<p>I do wonder how fatal MP_EFAULT actually is...-- on a device like this being jumpy at failing the RNG is reasonable, but if it bricks the device (for example) that would be too much for a condition that (IIRC) the datasheet says can happen. If that error is worse than causing a reboot then it might be the case that their emergency fix deployment might have the effect of causing problems by deploying never-actually-tested code into the wild. When I initially looked at this code before finding the flaw I was somewhat surprised that this test didn't produce spurious failures.<p>[Maybe someone who isn't traveling and on vacation might want to trace out that error condition, -- and check my vague recollection of the STM32 datasheets, as I could be remembering some other part]", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T16:08:18.000Z", - "created_at_i": 1785686898, - "id": 49145802, - "options": [], - "parent_id": 49145062, - "points": null, - "story_id": 49140405, - "text": "The my_random_bytes implementation doesn't look good at all at first glance. Let's see:<p>1. I believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output.<p>2. "here" is a terrible name for a length<p>3. It does a memcpy of a minimum of 4 bytes to the destination, even if count is lower. It'll also overflow longer buffers with a length not divisible by 4.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T14:32:44.000Z", - "created_at_i": 1785681164, - "id": 49145062, - "options": [], - "parent_id": 49144079, - "points": null, - "story_id": 49140405, - "text": "<a href=\"https://github.com/switck/libngu/blob/537519a829259622ea6b0334fbafd6cae852852f/ngu/random.c#L77\" rel=\"nofollow\">https://github.com/switck/libngu/blob/537519a829259622ea6b03...</a><p>vs<p><a href=\"https://github.com/Coldcard/micropython/blob/4107246f8a080807b62c3b4838e71e812ea68b6f/ports/stm32/rng.c#L55\" rel=\"nofollow\">https://github.com/Coldcard/micropython/blob/4107246f8a08080...</a>", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T12:46:41.000Z", - "created_at_i": 1785674801, - "id": 49144079, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "At no point did I ever think that setting "enable HW RNG" to 0 "provided a more aggressive handling of fault/error conditions". I always assumed it disabled the HW RNG.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "mlcrypto", - "children": [], - "created_at": "2026-08-02T16:16:51.000Z", - "created_at_i": 1785687411, - "id": 49145865, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003"", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "killerstorm", - "children": [], - "created_at": "2026-08-02T18:52:59.000Z", - "created_at_i": 1785696779, - "id": 49147215, - "options": [], - "parent_id": 49141886, - "points": null, - "story_id": 49140405, - "text": "Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?").<p>So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T07:08:53.000Z", - "created_at_i": 1785654533, - "id": 49141886, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "This writeup isn't very good and misses/misunderstands the programming error that leads to the flaw.<p>I'm commenting because I think it's important to understand the issue.<p>The article would have you think that the change in question was a tiny change to a flag to make it compile, but in reality the commit in question is a 1533 line addition of the entire RNG infrastructure.<p>The fundamental cause is a mixup between a value test and a definedness test.<p>Coldcard attempted to replace the micropython wrapper on the hardware TRNG, apparently in order to provide a more aggressive handling of fault/error conditions.<p>The micropython hwrng code is gated by an #if check, the replacement HWRNG code is gated by an ifndef. So "#define MICROPY_HW_ENABLE_RNG (0)" deactivated the micropython implementation but <i>failed</i> to activate the internal one (which was #ifndef MICROPY_HW_ENABLE_RNG ... which didn't fire because MICROPY_HW_ENABLE_RNG was _defined_).<p>This was easier to miss because the usages weren't only in different files-- they were in different repositories.<p>There is a more abstract point to make that in cryptographic software the absence of a secure randomness source (the STM32 TRNG) should never fall back to an insecure source (a trivial PRNG which might have only had on the order of 20-bits of uncertainty in its input). But the code that had the fallback was micropython which was not authored by the coldcard creators and is presumably not intended for cryptographic applications...<p>In later code (for MK4+ devices) the issue was further masked without being corrected by xor-ing in another insecure PRNG seeded by 32-bits from another TRNG. ... itself acting like an additional insecure fallback. (Why it first hashes 64-bits of TRNG output then throws away half the entropy is a mystery...)<p>RNG failures can be difficult to detect because the real randomness and a PRNG are indistinguishable by any simple tests of the output. I understand the coldcard developers ran extensive tests on the randomness generated by these devices-- they may well have been just testing the PRNG. It's something of a "color of your bits" issue ( <a href=\"https://ansuz.sooke.bc.ca/entry/23\" rel=\"nofollow\">https://ansuz.sooke.bc.ca/entry/23</a> ).<p>The same sort of issue happens at multiple levels of the stack, e.g. IIRC the STM32 TRNG itself does some kind of whitening that could have the same effect of concealing an RNG failure.<p>The existence of insecure fake randomness in the code at all was a red flag that had been noted previously -- though the really bad one was hidden away in the micropython code and not even obviously at play. I think this is a rare case of a bug that would be more easily found from binary analysis than review of the source code (e.g. no access to the STM32 TRNG at all).<p>Without these fallbacks the failure to use the TRNG would have been immediately detected by the developers (e.g. when every attempt generated the same seed), and a review could be validated by fault injection (NOP out the hwrng and verify that the test fails).", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "dmitrygr", - "children": [], - "created_at": "2026-08-02T07:22:02.000Z", - "created_at_i": 1785655322, - "id": 49141953, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "<p><pre><code> >Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming.\n</code></pre>\nAmen.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "londons_explore", - "children": [ - { - "author": "dist-epoch", - "children": [ - { - "author": "londons_explore", - "children": [], - "created_at": "2026-08-02T10:23:55.000Z", - "created_at_i": 1785666235, - "id": 49143043, - "options": [], - "parent_id": 49142900, - "points": null, - "story_id": 49140405, - "text": "Need not be the NSA. Might just be some regular thief.<p>The longer they wait, the more they get to steal after all.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "josephg", - "children": [], - "created_at": "2026-08-02T11:02:22.000Z", - "created_at_i": 1785668542, - "id": 49143269, - "options": [], - "parent_id": 49142900, - "points": null, - "story_id": 49140405, - "text": "> And do you think the NSA desperately needed $90 mil (the amount stolen so far)<p>If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T10:04:43.000Z", - "created_at_i": 1785665083, - "id": 49142900, - "options": [], - "parent_id": 49142187, - "points": null, - "story_id": 49140405, - "text": "And they waited 5 years to exploit it?<p>And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet?<p>All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T08:08:06.000Z", - "created_at_i": 1785658086, - "id": 49142187, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "I am getting suspicious of "random number generator not actually returning random numbers" bugs....<p>They are the perfect bug for someone trying to "accidentally" make a secure system insecure.<p>I wonder if bribe money was involved or three letter agencies...", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "nonfamous", - "children": [ - { - "author": "dist-epoch", - "children": [ - { - "author": "catlifeonmars", - "children": [], - "created_at": "2026-08-02T15:22:26.000Z", - "created_at_i": 1785684146, - "id": 49145449, - "options": [], - "parent_id": 49142927, - "points": null, - "story_id": 49140405, - "text": "A lot of the vulnerabilities being discovered are low hanging fruit. An LLM could discover them, but so could a human.<p>Let me amend your statement:<p>If the industry most seasoned experts are not engaging in regular security reviews of their firmware, they are not experts, but clowns.<p>LLMs are useful for this but not absolutely necessary to address the core issue.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T10:07:59.000Z", - "created_at_i": 1785665279, - "id": 49142927, - "options": [], - "parent_id": 49142449, - "points": null, - "story_id": 49140405, - "text": "If the industry most seasoned experts are not using LLMs right now to front-run the discovery of vulnerabilities in the code they are responsible for, they are not experts, but clowns.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "abecedarius", - "children": [ - { - "author": "nullc", - "children": [], - "created_at": "2026-08-02T17:52:04.000Z", - "created_at_i": 1785693124, - "id": 49146659, - "options": [], - "parent_id": 49144476, - "points": null, - "story_id": 49140405, - "text": "This flaw would probably be easier to find from the binary: the source itself was misleading, but if you analyized the binary you'd find that there was no access to the hwrng at all (assuming the dead code got eliminated by the compiler) or that the only function that accessed it was never called.<p>One lesson out of this is that now that AI has made a certain grade of review cheap is that it would be useful to perform security review both against the source code and against the resulting binary.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T13:24:39.000Z", - "created_at_i": 1785677079, - "id": 49144476, - "options": [], - "parent_id": 49142449, - "points": null, - "story_id": 49140405, - "text": "If your source is <i>not</i> open that's barely a speedbump, given a binary. At least that's my impression of the current state.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T08:47:18.000Z", - "created_at_i": 1785660438, - "id": 49142449, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "From the Twitter advisory on the issue being referenced here [1]:<p>>>> To every other developer: we believe this is a sober reality of the new AI paradigm. AI-assisted code review can now find latent bugs at a speed that is outpacing even the industry’s most seasoned experts. If your firmware is open-source or has ever been public, assume it's already being read by attackers and defenders alike.<p>Kinda turns the “many eyes” principle of OSS on its head, eh?<p>[1] <a href=\"https://x.com/nvk/status/2083216713693151552?s=61\" rel=\"nofollow\">https://x.com/nvk/status/2083216713693151552?s=61</a>", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "PunchyHamster", - "children": [], - "created_at": "2026-08-02T09:36:32.000Z", - "created_at_i": 1785663392, - "id": 49142733, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16.<p>the commit message is not 235 character long, the commit message is this<p>> splice-script: Test for msat chan balances\n> splice-script: Round channel balances down<p>author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed.<p>So yeah it is better but nothing to actually brag about", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "hypeatei", - "children": [ - { - "author": "inigyou", - "children": [ - { - "author": "anonymars", - "children": [], - "created_at": "2026-08-02T12:55:18.000Z", - "created_at_i": 1785675318, - "id": 49144163, - "options": [], - "parent_id": 49144084, - "points": null, - "story_id": 49140405, - "text": "Banking-related errors have recourse", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "hypeatei", - "children": [ - { - "author": "inigyou", - "children": [ - { - "author": "anonymars", - "children": [], - "created_at": "2026-08-02T15:19:15.000Z", - "created_at_i": 1785683955, - "id": 49145422, - "options": [], - "parent_id": 49144682, - "points": null, - "story_id": 49140405, - "text": "Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "hypeatei", - "children": [], - "created_at": "2026-08-02T16:07:23.000Z", - "created_at_i": 1785686843, - "id": 49145792, - "options": [], - "parent_id": 49144682, - "points": null, - "story_id": 49140405, - "text": "If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right?<p>Also infrequent purchases != storing wealth in Bitcoin.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T13:48:14.000Z", - "created_at_i": 1785678494, - "id": 49144682, - "options": [], - "parent_id": 49144432, - "points": null, - "story_id": 49140405, - "text": "Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T13:19:10.000Z", - "created_at_i": 1785676750, - "id": 49144432, - "options": [], - "parent_id": 49144084, - "points": null, - "story_id": 49140405, - "text": "No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void.<p>There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T12:47:02.000Z", - "created_at_i": 1785674822, - "id": 49144084, - "options": [], - "parent_id": 49143286, - "points": null, - "story_id": 49140405, - "text": "I take it you get your paycheck in cash?", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "DJBunnies", - "children": [ - { - "author": "hypeatei", - "children": [ - { - "author": "firmretention", - "children": [], - "created_at": "2026-08-05T11:38:08.000Z", - "created_at_i": 1785929888, - "id": 49181406, - "options": [], - "parent_id": 49145759, - "points": null, - "story_id": 49140405, - "text": "While I agree self-custody is too onerous for the average person, Coldcard's own documentation had a section on generating secure seeds with dice and why that's more secure. It wasn't some esoteric knowledge - anyone who RTFM on the device they intended to store their savings on was fine. That's not an absolution of Coldcard of course, but it's not "new cope".", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T16:03:16.000Z", - "created_at_i": 1785686596, - "id": 49145759, - "options": [], - "parent_id": 49145624, - "points": null, - "story_id": 49140405, - "text": "> If one uses a good source of entropy then one will not "get screwed."<p>How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it.<p>> dice rolls<p>Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure.<p>1: <a href=\"https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls_for_a_24word_seed_two_questions/p13ch4q/\" rel=\"nofollow\">https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls...</a>", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T15:47:05.000Z", - "created_at_i": 1785685625, - "id": 49145624, - "options": [], - "parent_id": 49143286, - "points": null, - "story_id": 49140405, - "text": "The "right thing" here is subjective.<p>If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed."<p>> I don't know why anyone would keep their wealth in something that requires so much technical excellence.<p>It's not for everybody, for sure.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T11:05:33.000Z", - "created_at_i": 1785668733, - "id": 49143286, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think.<p>Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence.", - "title": null, - "type": "comment", - "url": null - }, - { - "author": "koolba", - "children": [ - { - "author": "coldbrewed", - "children": [], - "created_at": "2026-08-02T17:52:13.000Z", - "created_at_i": 1785693133, - "id": 49146661, - "options": [], - "parent_id": 49143727, - "points": null, - "story_id": 49140405, - "text": "We shouldn't tolerate slop in any form, especially not in commit comments. What we should care about is communicating design decisions, intent, and especially we should explain concerns that can't be intuited from reading the code. A longer, more detailed comment that explains some significant detail can be especially valuable but it should earn the weight that it carries.<p>I think we're all in agreement that a one word "runs" commit and a 6 paragraph slop commit both fail to communicate effectively.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T12:07:24.000Z", - "created_at_i": 1785672444, - "id": 49143727, - "options": [], - "parent_id": 49140405, - "points": null, - "story_id": 49140405, - "text": "> A good goal as a developer is a high commit message to change ratio. The more lines of code that you change, the more comments explaining why you’re changing the code. More message and less code changes per commit is generally a good idea.<p>No! Blanket statements like this is how you end up with 40 pages of slop AI comments in PRs that nobody reads.<p>Comments should be terse and meaningful. They should document surprising behavior or choices. The less comments you have, the more meaningful each one becomes because your time and eyeballs are limited as well.", - "title": null, - "type": "comment", - "url": null - } - ], - "created_at": "2026-08-02T02:08:26.000Z", - "created_at_i": 1785636506, - "id": 49140405, - "options": [], - "parent_id": null, - "points": 94, - "story_id": 49140405, - "text": null, - "title": "When random.bytes() runs but doesn't work", - "type": "story", - "url": "https://insider.btcpp.dev/p/when-randombytes-runs-but-doesnt" -} +story: 49140405 +author: Funes- +created_at: 2026-08-02T02:08:26.000Z +title: +When random.bytes() runs but doesn't work +url: https://insider.btcpp.dev/p/when-randombytes-runs-but-doesnt +body: +[deleted] + +comment: 49141102 +parent: 49140405 +author: anonymousiam +created_at: 2026-08-02T04:30:52.000Z +body: +This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. + +comment: 49141270 +parent: 49141102 +author: Sharlin +created_at: 2026-08-02T05:01:23.000Z +body: +Hanlon’s razor. + +comment: 49141340 +parent: 49141102 +author: eru +created_at: 2026-08-02T05:16:48.000Z +body: +Also: writing this stuff in C just begs for bugs. +LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust. + +comment: 49141474 +parent: 49141340 +author: thin_carapace +created_at: 2026-08-02T05:43:31.000Z +body: +I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller + +comment: 49141482 +parent: 49141340 +author: jgilias +created_at: 2026-08-02T05:44:29.000Z +body: +The bug has been up since before the LLM shift. + +comment: 49141837 +parent: 49140405 +author: systemsweird +created_at: 2026-08-02T06:58:01.000Z +body: +Very good writeup and an astonishing level of negligence for an extremely security critical piece of code. The losses are going to surpass 100 million, these guys should be thrown in jail. + +comment: 49141886 +parent: 49140405 +author: nullc +created_at: 2026-08-02T07:08:53.000Z +body: +This writeup isn't very good and misses/misunderstands the programming error that leads to the flaw. +I'm commenting because I think it's important to understand the issue. +The article would have you think that the change in question was a tiny change to a flag to make it compile, but in reality the commit in question is a 1533 line addition of the entire RNG infrastructure. +The fundamental cause is a mixup between a value test and a definedness test. +Coldcard attempted to replace the micropython wrapper on the hardware TRNG, apparently in order to provide a more aggressive handling of fault/error conditions. +The micropython hwrng code is gated by an #if check, the replacement HWRNG code is gated by an ifndef. So "#define MICROPY_HW_ENABLE_RNG (0)" deactivated the micropython implementation but failed to activate the internal one (which was #ifndef MICROPY_HW_ENABLE_RNG ... which didn't fire because MICROPY_HW_ENABLE_RNG was _defined_). +This was easier to miss because the usages weren't only in different files-- they were in different repositories. +There is a more abstract point to make that in cryptographic software the absence of a secure randomness source (the STM32 TRNG) should never fall back to an insecure source (a trivial PRNG which might have only had on the order of 20-bits of uncertainty in its input). But the code that had the fallback was micropython which was not authored by the coldcard creators and is presumably not intended for cryptographic applications... +In later code (for MK4+ devices) the issue was further masked without being corrected by xor-ing in another insecure PRNG seeded by 32-bits from another TRNG. ... itself acting like an additional insecure fallback. (Why it first hashes 64-bits of TRNG output then throws away half the entropy is a mystery...) +RNG failures can be difficult to detect because the real randomness and a PRNG are indistinguishable by any simple tests of the output. I understand the coldcard developers ran extensive tests on the randomness generated by these devices-- they may well have been just testing the PRNG. It's something of a "color of your bits" issue ( https://ansuz.sooke.bc.ca/entry/23 ). +The same sort of issue happens at multiple levels of the stack, e.g. IIRC the STM32 TRNG itself does some kind of whitening that could have the same effect of concealing an RNG failure. +The existence of insecure fake randomness in the code at all was a red flag that had been noted previously -- though the really bad one was hidden away in the micropython code and not even obviously at play. I think this is a rare case of a bug that would be more easily found from binary analysis than review of the source code (e.g. no access to the STM32 TRNG at all). +Without these fallbacks the failure to use the TRNG would have been immediately detected by the developers (e.g. when every attempt generated the same seed), and a review could be validated by fault injection (NOP out the hwrng and verify that the test fails). + +comment: 49141953 +parent: 49140405 +author: dmitrygr +created_at: 2026-08-02T07:22:02.000Z +body: +>Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming. +Amen. + +comment: 49142014 +parent: 49141886 +author: nullc +created_at: 2026-08-02T07:34:54.000Z +body: +Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors. + +comment: 49142040 +parent: 49141102 +author: karamanolev +created_at: 2026-08-02T07:39:00.000Z +body: +Per the article, not my opinion. +It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. + +comment: 49142187 +parent: 49140405 +author: londons_explore +created_at: 2026-08-02T08:08:06.000Z +body: +I am getting suspicious of "random number generator not actually returning random numbers" bugs.... +They are the perfect bug for someone trying to "accidentally" make a secure system insecure. +I wonder if bribe money was involved or three letter agencies... + +comment: 49142227 +parent: 49141837 +author: jonathanlydall +created_at: 2026-08-02T08:14:31.000Z +body: +This does not seem to be a good write up at all, see nullc’s explanation in this discussion of (what seems to me) the actual root cause whereas this article spent a lot of words making the argument that bad commit messages must mean bad code, later using the assertion to try “prove” what the technical problem was. +I agree that a bad commit message combined with a big commit is a huge smell, but as it’s just metadata for the code and not the code itself, it is not in itself evidence in any form. +That being said, probably okay after explaining the technical code issues for the author add a couple of a sentences about how all this was was part of 1000s of a lines of code changed in commits with useless messages which demonstrates generally bad code hygiene. + +comment: 49142362 +parent: 49142227 +author: smithcoin +created_at: 2026-08-02T08:36:14.000Z +body: +I think what is the author is getting at is that if you are cavalier in your commit messages when the stakes are low, chances are you aren’t taking writing code <i>that handles money</i> seriously. Made me think of some merges I could have taken more seriously. + +comment: 49142373 +parent: 49141886 +author: smithcoin +created_at: 2026-08-02T08:37:43.000Z +body: +Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities? + +comment: 49142449 +parent: 49140405 +author: nonfamous +created_at: 2026-08-02T08:47:18.000Z +body: +From the Twitter advisory on the issue being referenced here [1]: +>>> To every other developer: we believe this is a sober reality of the new AI paradigm. AI-assisted code review can now find latent bugs at a speed that is outpacing even the industry’s most seasoned experts. If your firmware is open-source or has ever been public, assume it's already being read by attackers and defenders alike. +Kinda turns the “many eyes” principle of OSS on its head, eh? +[1] https://x.com/nvk/status/2083216713693151552?s=61 + +comment: 49142559 +parent: 49142014 +author: RustyRussell +created_at: 2026-08-02T09:04:47.000Z +body: +Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined. + +comment: 49142714 +parent: 49141102 +author: silvestrov +created_at: 2026-08-02T09:33:07.000Z +body: +When looking through all the other commits the user has made: they all lack a good commit message. +This is systematic for that user. Either the user needs to improve or let go. +The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. + +comment: 49142733 +parent: 49140405 +author: PunchyHamster +created_at: 2026-08-02T09:36:32.000Z +body: +> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16. +the commit message is not 235 character long, the commit message is this +> splice-script: Test for msat chan balances +> splice-script: Round channel balances down +author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed. +So yeah it is better but nothing to actually brag about + +comment: 49142900 +parent: 49142187 +author: dist-epoch +created_at: 2026-08-02T10:04:43.000Z +body: +And they waited 5 years to exploit it? +And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? +All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. + +comment: 49142927 +parent: 49142449 +author: dist-epoch +created_at: 2026-08-02T10:07:59.000Z +body: +If the industry most seasoned experts are not using LLMs right now to front-run the discovery of vulnerabilities in the code they are responsible for, they are not experts, but clowns. + +comment: 49143043 +parent: 49142900 +author: londons_explore +created_at: 2026-08-02T10:23:55.000Z +body: +Need not be the NSA. Might just be some regular thief. +The longer they wait, the more they get to steal after all. + +comment: 49143073 +parent: 49141886 +author: dist-epoch +created_at: 2026-08-02T10:28:58.000Z +body: +I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input. +Hard problem in general, but with LLMs surely this is possible now, either with them inspecting or by them providing some sort of "formal" proof - this function calls this function which reads this buffer which gets input from here... + +comment: 49143269 +parent: 49142900 +author: josephg +created_at: 2026-08-02T11:02:22.000Z +body: +> And do you think the NSA desperately needed $90 mil (the amount stolen so far) +If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. + +comment: 49143286 +parent: 49140405 +author: hypeatei +created_at: 2026-08-02T11:05:33.000Z +body: +> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think. +Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence. + +comment: 49143450 +parent: 49141886 +author: egwor +created_at: 2026-08-02T11:30:10.000Z +body: +Although I might disagree with the style of the write up, I think it is right that there are weak engineering practices applied: +- not enough information provided in commit message. +- this change ought to have been split into smaller chunks (e.g. introduce indirection whilst code continues to use hardware) +- limited (automated) testing +- potential confusion by the author over C concepts +- additional complexity which could have been hidden behind a cleaner interface rather than using defines +I agree about your points about: +- defines over multiple repo's made this more complicated that was necessary. +- fault injections would have been the appropriate way to test this (or maybe mocks) +- testing of randomness needs careful design, e.g. RNG seeding can be a good way +Taking a step back, we as a community of excellence need to emphasise that this isn't a criticism about the person/author. There needs to be a clear analysis of what went wrong whilst being kind to the person/people involved. + +comment: 49143727 +parent: 49140405 +author: koolba +created_at: 2026-08-02T12:07:24.000Z +body: +> A good goal as a developer is a high commit message to change ratio. The more lines of code that you change, the more comments explaining why you’re changing the code. More message and less code changes per commit is generally a good idea. +No! Blanket statements like this is how you end up with 40 pages of slop AI comments in PRs that nobody reads. +Comments should be terse and meaningful. They should document surprising behavior or choices. The less comments you have, the more meaningful each one becomes because your time and eyeballs are limited as well. + +comment: 49144064 +parent: 49142714 +author: inigyou +created_at: 2026-08-02T12:45:18.000Z +body: +The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. + +comment: 49144079 +parent: 49141886 +author: inigyou +created_at: 2026-08-02T12:46:41.000Z +body: +At no point did I ever think that setting "enable HW RNG" to 0 "provided a more aggressive handling of fault/error conditions". I always assumed it disabled the HW RNG. + +comment: 49144084 +parent: 49143286 +author: inigyou +created_at: 2026-08-02T12:47:02.000Z +body: +I take it you get your paycheck in cash? + +comment: 49144132 +parent: 49141102 +author: anonymars +created_at: 2026-08-02T12:51:01.000Z +body: +Ironic: +> NEW POLICY If I don't know you, I don't merge you! Thanks XZ! +https://github.com/switck/libngu + +comment: 49144163 +parent: 49144084 +author: anonymars +created_at: 2026-08-02T12:55:18.000Z +body: +Banking-related errors have recourse + +comment: 49144432 +parent: 49144084 +author: hypeatei +created_at: 2026-08-02T13:19:10.000Z +body: +No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void. +There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place. + +comment: 49144476 +parent: 49142449 +author: abecedarius +created_at: 2026-08-02T13:24:39.000Z +body: +If your source is <i>not</i> open that's barely a speedbump, given a binary. At least that's my impression of the current state. + +comment: 49144682 +parent: 49144432 +author: inigyou +created_at: 2026-08-02T13:48:14.000Z +body: +Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs. + +comment: 49144692 +parent: 49141340 +author: jki275 +created_at: 2026-08-02T13:49:05.000Z +body: +C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem. +Also running python on a microcontroller to do cryptography is fucking insane. + +comment: 49145062 +parent: 49144079 +author: nullc +created_at: 2026-08-02T14:32:44.000Z +body: +https://github.com/switck/libngu/blob/537519a829259622ea6b03... +vs +https://github.com/Coldcard/micropython/blob/4107246f8a08080... + +comment: 49145347 +parent: 49141474 +author: scott_w +created_at: 2026-08-02T15:07:55.000Z +body: +Honestly, I'm going to be a bit harsher: I think they're either: +1. A novice who doesn't know how to debug issues. +2. Totally incompetent and copying code from Stack Overflow. +I don't think it's specific to microcontrollers, either, the error from the C compiler is something that a competent programmer would be able to interpret, or at least see it as a signal to get someone more experienced in the domain to learn about. + +comment: 49145422 +parent: 49144682 +author: anonymars +created_at: 2026-08-02T15:19:15.000Z +body: +Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make + +comment: 49145449 +parent: 49142927 +author: catlifeonmars +created_at: 2026-08-02T15:22:26.000Z +body: +A lot of the vulnerabilities being discovered are low hanging fruit. An LLM could discover them, but so could a human. +Let me amend your statement: +If the industry most seasoned experts are not engaging in regular security reviews of their firmware, they are not experts, but clowns. +LLMs are useful for this but not absolutely necessary to address the core issue. + +comment: 49145624 +parent: 49143286 +author: DJBunnies +created_at: 2026-08-02T15:47:05.000Z +body: +The "right thing" here is subjective. +If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed." +> I don't know why anyone would keep their wealth in something that requires so much technical excellence. +It's not for everybody, for sure. + +comment: 49145759 +parent: 49145624 +author: hypeatei +created_at: 2026-08-02T16:03:16.000Z +body: +> If one uses a good source of entropy then one will not "get screwed." +How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it. +> dice rolls +Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure. +1: https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls... + +comment: 49145792 +parent: 49144682 +author: hypeatei +created_at: 2026-08-02T16:07:23.000Z +body: +If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right? +Also infrequent purchases != storing wealth in Bitcoin. + +comment: 49145802 +parent: 49145062 +author: dale_glass +created_at: 2026-08-02T16:08:18.000Z +body: +The my_random_bytes implementation doesn't look good at all at first glance. Let's see: +1. I believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output. +2. "here" is a terrible name for a length +3. It does a memcpy of a minimum of 4 bytes to the destination, even if count is lower. It'll also overflow longer buffers with a length not divisible by 4. + +comment: 49145865 +parent: 49141886 +author: mlcrypto +created_at: 2026-08-02T16:16:51.000Z +body: +The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003" + +comment: 49146167 +parent: 49145802 +author: nullc +created_at: 2026-08-02T16:55:41.000Z +body: +I have absolutely no interest in defending this code-- and already considered it untrusthworthy before any of this. But in the interest of accuracy: +> It does a memcpy of a minimum of 4 bytes +This is a common misreading of MIN(). MIN(4,x) is a number that is a MAXIMUM of 4, not a minimum. +Count is the number of bytes remaining in the buffer. The input to the copy is a 4-byte word. min(4,count) will produce a number 0-4 which is always equal to or less than count. The copy will not overflow the buffer or overrun the input: If count is 3, for example, then here will be 3 and it will copy 3 bytes. +> believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output. +It's been a while since I looked but I believe the STM32 manual advises you to throw away data when this happens, because the rng is updated async with the processor and reads that are too fast will produce 0s or duplicate values. Entropy loss from doing so is generally negligible. Were it me I'd read enough into a cryptographic hash to render the output cryptographically close to uniform and not have to worry about it further. (particularly since some uses of cryptographic numbers are extremely sensitive to even small biases) +I do wonder how fatal MP_EFAULT actually is...-- on a device like this being jumpy at failing the RNG is reasonable, but if it bricks the device (for example) that would be too much for a condition that (IIRC) the datasheet says can happen. If that error is worse than causing a reboot then it might be the case that their emergency fix deployment might have the effect of causing problems by deploying never-actually-tested code into the wild. When I initially looked at this code before finding the flaw I was somewhat surprised that this test didn't produce spurious failures. +[Maybe someone who isn't traveling and on vacation might want to trace out that error condition, -- and check my vague recollection of the STM32 datasheets, as I could be remembering some other part] + +comment: 49146187 +parent: 49146167 +author: inigyou +created_at: 2026-08-02T16:57:49.000Z +body: +There have been cases where a small statistical bias like avoiding duplicate bytes can be amplified to a full break. I don't think this problem is applicable to a bitcoin private key though. + +comment: 49146562 +parent: 49146187 +author: nullc +created_at: 2026-08-02T17:40:41.000Z +body: +Right, that's particularly a concern for DSA nonces. Coldcard uses RFC 6979 however, and duplicates at the 32-bit word level is a different matter than at the byte level. + +comment: 49146607 +parent: 49144692 +author: nullc +created_at: 2026-08-02T17:46:05.000Z +body: +> Also running python on a microcontroller to do cryptography is fucking insane. +I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color. +Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't. + +comment: 49146618 +parent: 49145347 +author: nullc +created_at: 2026-08-02T17:47:08.000Z +body: +> the error from the C compiler is something that a competent programmer would be able to interpret, +contrary to the post, this was almost certainly not an issue of compilers throwing errors. +Reduced familarity with C could have played a role, but given the number of C experts that looked at this knowing there was an error and still misidentified the cause I don't think we need to reach for that powerful an explanation. +Confusion of definedness vs value check would make for a fine underhanded C entry. The flaw was not particularly clear from the source... and most common QA procedures could not distinguish a PRNG from TRNG once the error happened. + +comment: 49146659 +parent: 49144476 +author: nullc +created_at: 2026-08-02T17:52:04.000Z +body: +This flaw would probably be easier to find from the binary: the source itself was misleading, but if you analyized the binary you'd find that there was no access to the hwrng at all (assuming the dead code got eliminated by the compiler) or that the only function that accessed it was never called. +One lesson out of this is that now that AI has made a certain grade of review cheap is that it would be useful to perform security review both against the source code and against the resulting binary. + +comment: 49146661 +parent: 49143727 +author: coldbrewed +created_at: 2026-08-02T17:52:13.000Z +body: +We shouldn't tolerate slop in any form, especially not in commit comments. What we should care about is communicating design decisions, intent, and especially we should explain concerns that can't be intuited from reading the code. A longer, more detailed comment that explains some significant detail can be especially valuable but it should earn the weight that it carries. +I think we're all in agreement that a one word "runs" commit and a 6 paragraph slop commit both fail to communicate effectively. + +comment: 49146689 +parent: 49142373 +author: nullc +created_at: 2026-08-02T17:54:43.000Z +body: +Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners. + +comment: 49147215 +parent: 49141886 +author: killerstorm +created_at: 2026-08-02T18:52:59.000Z +body: +Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?"). +So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated. + +comment: 49148323 +parent: 49146618 +author: scott_w +created_at: 2026-08-02T21:07:14.000Z +body: +Fair point: I was using the information in the article to form my opinion. I still think that, if the developer in question ignored a compiler error as described, that’s a serious competence issue. It’s harder to spot after the fact because any reviewers wouldn’t have had a chance to see the compiler output. +The article makes the fair point of the size of the change and the complete lack of information in the commit message, which should have set off alarm bells… + +comment: 49150082 +parent: 49145347 +author: eru +created_at: 2026-08-03T01:07:07.000Z +body: +Of course, being a total novice and claiming to produce a super secure gadget are not to things you want to go together. + +comment: 49163987 +parent: 49145347 +author: Scoundreller +created_at: 2026-08-04T03:07:05.000Z +body: +Hey now, I'm totally incompetent, so my code writes entries in a log file for virtually everything because otherwise I have no idea if it's doing what I expect. Would've caught some critical function not being called at all. + +comment: 49181406 +parent: 49145759 +author: firmretention +created_at: 2026-08-05T11:38:08.000Z +body: +While I agree self-custody is too onerous for the average person, Coldcard's own documentation had a section on generating secure seeds with dice and why that's more secure. It wasn't some esoteric knowledge - anyone who RTFM on the device they intended to store their savings on was fine. That's not an absolution of Coldcard of course, but it's not "new cope". + +comment: 49204786 +parent: 49146607 +author: jki275 +created_at: 2026-08-07T01:18:26.000Z +body: +I think some things telegraph competence and some the opposite -- and our experiences over the years tend to shape what we see that way.Extracted text as captured
story: 49140405 author: Funes- created_at: 2026-08-02T02:08:26.000Z title: When random.bytes() runs but doesn't work url: https://insider.btcpp.dev/p/when-randombytes-runs-but-doesnt body: [deleted] comment: 49141102 parent: 49140405 author: anonymousiam created_at: 2026-08-02T04:30:52.000Z body: This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. comment: 49141270 parent: 49141102 author: Sharlin created_at: 2026-08-02T05:01:23.000Z body: Hanlon’s razor. comment: 49141340 parent: 49141102 author: eru created_at: 2026-08-02T05:16:48.000Z body: Also: writing this stuff in C just begs for bugs. LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust. comment: 49141474 parent: 49141340 author: thin_carapace created_at: 2026-08-02T05:43:31.000Z body: I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller comment: 49141482 parent: 49141340Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
New comment by jki275 (2026-08-07T01:18:26Z) replying to nullc about what telegraphs competence. No other thread changes.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 18 lines
"children": [ { "author": "nullc", - "children": [], + "children": [ + { + "author": "jki275", + "children": [], + "created_at": "2026-08-07T01:18:26.000Z", + "created_at_i": 1786065506, + "id": 49204786, + "options": [], + "parent_id": 49146607, + "points": null, + "story_id": 49140405, + "text": "I think some things telegraph competence and some the opposite -- and our experiences over the years tend to shape what we see that way.", + "title": null, + "type": "comment", + "url": null + } + ], "created_at": "2026-08-02T17:46:05.000Z", "created_at_i": 1785692765, "id": 49146607,Extracted text as captured
{ "author": "Funes-", "children": [ { "author": "anonymousiam", "children": [ { "author": "Sharlin", "children": [], "created_at": "2026-08-02T05:01:23.000Z", "created_at_i": 1785646883, "id": 49141270, "options": [], "parent_id": 49141102, "points": null, "story_id": 49140405, "text": "Hanlon’s razor.", "title": null, "type": "comment", "url": null }, { "author": "eru", "children": [ { "author": "thin_carapace", "children": [ { "author": "scott_w", "children": [ { "author": "nullc", "children": [ { "author": "scott_w", "children": [], "created_at": "2026-08-02T21:07:14.000Z", "created_at_i": 1785704834, "id": 49148323, "options": [],Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
Same move to the Hacker News item API as hn-maxwell-mechanism, for the same 429. The thread is now held as pretty-printed JSON: 58 nodes with absolute timestamps, replacing the rendered page and its relative times. No comment text changed across the switch.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 1164 lines
-Hacker Newsnew | past | comments | ask | show | jobs | submitlogin -When random.bytes() runs but doesn't work (btcpp.dev) -94 points by Funes- 3 days ago | hide | past | favorite | 57 comments -help -londons_explore 3 days ago | next [–] -I am getting suspicious of "random number generator not actually returning random numbers" bugs.... -They are the perfect bug for someone trying to "accidentally" make a secure system insecure. -I wonder if bribe money was involved or three letter agencies... -reply -dist-epoch 3 days ago | parent | next [–] -And they waited 5 years to exploit it? -And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? -All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. -reply -londons_explore 3 days ago | root | parent | next [–] -Need not be the NSA. Might just be some regular thief. -The longer they wait, the more they get to steal after all. -reply -josephg 3 days ago | root | parent | prev | next [–] -> And do you think the NSA desperately needed $90 mil (the amount stolen so far) -If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. -reply -anonymousiam 3 days ago | prev | next [–] -This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. -reply -karamanolev 3 days ago | parent | next [–] -Per the article, not my opinion. -It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. -reply -silvestrov 3 days ago | parent | prev | next [–] -When looking through all the other commits the user has made: they all lack a good commit message. -This is systematic for that user. Either the user needs to improve or let go. -The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. -reply -inigyou 3 days ago | root | parent | next [–] -The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. -reply -anonymars 3 days ago | parent | prev | next [–] -Ironic: -> NEW POLICY If I don't know you, I don't merge you! Thanks XZ! -https://github.com/switck/libngu -reply -Sharlin 3 days ago | parent | prev | next [–] -Hanlon’s razor. -reply -eru 3 days ago | parent | prev | next [–] -Also: writing this stuff in C just begs for bugs. -LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust. -reply -jki275 3 days ago | root | parent | next [–] -C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem. -Also running python on a microcontroller to do cryptography is fucking insane. -reply -nullc 3 days ago | root | parent | next [–] -> Also running python on a microcontroller to do cryptography is fucking insane. -I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color. -Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't. -reply -thin_carapace 3 days ago | root | parent | prev | next [–] -I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller -reply -scott_w 3 days ago | root | parent | next [–] -Honestly, I'm going to be a bit harsher: I think they're either: -1. A novice who doesn't know how to debug issues. -2. Totally incompetent and copying code from Stack Overflow. -I don't think it's specific to microcontrollers, either, the error from the C compiler is something that a competent programmer would be able to interpret, or at least see it as a signal to get someone more experienced in the domain to learn about. -reply -nullc 3 days ago | root | parent | next [–] -> the error from the C compiler is something that a competent programmer would be able to interpret, -contrary to the post, this was almost certainly not an issue of compilers throwing errors. -Reduced familarity with C could have played a role, but given the number of C experts that looked at this knowing there was an error and still misidentified the cause I don't think we need to reach for that powerful an explanation. -Confusion of definedness vs value check would make for a fine underhanded C entry. The flaw was not particularly clear from the source... and most common QA procedures could not distinguish a PRNG from TRNG once the error happened. -reply -scott_w 2 days ago | root | parent | next [–] -Fair point: I was using the information in the article to form my opinion. I still think that, if the developer in question ignored a compiler error as described, that’s a serious competence issue. It’s harder to spot after the fact because any reviewers wouldn’t have had a chance to see the compiler output. -The article makes the fair point of the size of the change and the complete lack of information in the commit message, which should have set off alarm bells… -reply -Scoundreller 1 day ago | root | parent | prev | next [–] -Hey now, I'm totally incompetent, so my code writes entries in a log file for virtually everything because otherwise I have no idea if it's doing what I expect. Would've caught some critical function not being called at all. -reply -eru 2 days ago | root | parent | prev | next [–] -Of course, being a total novice and claiming to produce a super secure gadget are not to things you want to go together. -reply -jgilias 3 days ago | root | parent | prev | next [–] -The bug has been up since before the LLM shift. -reply -dmitrygr 3 days ago | prev | next [–] ->Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming. -Amen. -reply -PunchyHamster 3 days ago | prev | next [–] -> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16. -the commit message is not 235 character long, the commit message is this -> splice-script: Test for msat chan balances -> splice-script: Round channel balances down -author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed. -So yeah it is better but nothing to actually brag about -reply -hypeatei 3 days ago | prev | next [–] -> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think. -Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence. -reply -DJBunnies 3 days ago | parent | next [–] -The "right thing" here is subjective. -If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed." -> I don't know why anyone would keep their wealth in something that requires so much technical excellence. -It's not for everybody, for sure. -reply -hypeatei 3 days ago | root | parent | next [–] -> If one uses a good source of entropy then one will not "get screwed." -How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it. -> dice rolls -Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure. -1: https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls... -reply -firmretention 9 hours ago | root | parent | next [–] -While I agree self-custody is too onerous for the average person, Coldcard's own documentation had a section on generating secure seeds with dice and why that's more secure. It wasn't some esoteric knowledge - anyone who RTFM on the device they intended to store their savings on was fine. That's not an absolution of Coldcard of course, but it's not "new cope". -reply -inigyou 3 days ago | parent | prev | next [–] -I take it you get your paycheck in cash? -reply -hypeatei 3 days ago | root | parent | next [–] -No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void. -There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place. -reply -inigyou 3 days ago | root | parent | next [–] -Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs. -reply -anonymars 3 days ago | root | parent | next [–] -Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make -reply -hypeatei 3 days ago | root | parent | prev | next [–] -If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right? -Also infrequent purchases != storing wealth in Bitcoin. -reply -anonymars 3 days ago | root | parent | prev | next [–] -Banking-related errors have recourse -reply -nullc 3 days ago | prev | next [–] -This writeup isn't very good and misses/misunderstands the programming error that leads to the flaw. -I'm commenting because I think it's important to understand the issue. -The article would have you think that the change in question was a tiny change to a flag to make it compile, but in reality the commit in question is a 1533 line addition of the entire RNG infrastructure. -The fundamental cause is a mixup between a value test and a definedness test. -Coldcard attempted to replace the micropython wrapper on the hardware TRNG, apparently in order to provide a more aggressive handling of fault/error conditions. -The micropython hwrng code is gated by an #if check, the replacement HWRNG code is gated by an ifndef. So "#define MICROPY_HW_ENABLE_RNG (0)" deactivated the micropython implementation but failed to activate the internal one (which was #ifndef MICROPY_HW_ENABLE_RNG ... which didn't fire because MICROPY_HW_ENABLE_RNG was _defined_). -This was easier to miss because the usages weren't only in different files-- they were in different repositories. -There is a more abstract point to make that in cryptographic software the absence of a secure randomness source (the STM32 TRNG) should never fall back to an insecure source (a trivial PRNG which might have only had on the order of 20-bits of uncertainty in its input). But the code that had the fallback was micropython which was not authored by the coldcard creators and is presumably not intended for cryptographic applications... -In later code (for MK4+ devices) the issue was further masked without being corrected by xor-ing in another insecure PRNG seeded by 32-bits from another TRNG. ... itself acting like an additional insecure fallback. (Why it first hashes 64-bits of TRNG output then throws away half the entropy is a mystery...) -RNG failures can be difficult to detect because the real randomness and a PRNG are indistinguishable by any simple tests of the output. I understand the coldcard developers ran extensive tests on the randomness generated by these devices-- they may well have been just testing the PRNG. It's something of a "color of your bits" issue ( https://ansuz.sooke.bc.ca/entry/23 ). -The same sort of issue happens at multiple levels of the stack, e.g. IIRC the STM32 TRNG itself does some kind of whitening that could have the same effect of concealing an RNG failure. -The existence of insecure fake randomness in the code at all was a red flag that had been noted previously -- though the really bad one was hidden away in the micropython code and not even obviously at play. I think this is a rare case of a bug that would be more easily found from binary analysis than review of the source code (e.g. no access to the STM32 TRNG at all). -Without these fallbacks the failure to use the TRNG would have been immediately detected by the developers (e.g. when every attempt generated the same seed), and a review could be validated by fault injection (NOP out the hwrng and verify that the test fails). -reply -egwor 3 days ago | parent | next [–] -Although I might disagree with the style of the write up, I think it is right that there are weak engineering practices applied: -- not enough information provided in commit message. -- this change ought to have been split into smaller chunks (e.g. introduce indirection whilst code continues to use hardware) -- limited (automated) testing -- potential confusion by the author over C concepts -- additional complexity which could have been hidden behind a cleaner interface rather than using defines -I agree about your points about: -- defines over multiple repo's made this more complicated that was necessary. -- fault injections would have been the appropriate way to test this (or maybe mocks) -- testing of randomness needs careful design, e.g. RNG seeding can be a good way -Taking a step back, we as a community of excellence need to emphasise that this isn't a criticism about the person/author. There needs to be a clear analysis of what went wrong whilst being kind to the person/people involved. -reply -inigyou 3 days ago | parent | prev | next [–] -At no point did I ever think that setting "enable HW RNG" to 0 "provided a more aggressive handling of fault/error conditions". I always assumed it disabled the HW RNG. -reply -nullc 3 days ago | root | parent | next [–] -https://github.com/switck/libngu/blob/537519a829259622ea6b03... -vs -https://github.com/Coldcard/micropython/blob/4107246f8a08080... -reply -dale_glass 3 days ago | root | parent | next [–] -The my_random_bytes implementation doesn't look good at all at first glance. Let's see: -1. I believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output. -2. "here" is a terrible name for a length -3. It does a memcpy of a minimum of 4 bytes to the destination, even if count is lower. It'll also overflow longer buffers with a length not divisible by 4. -reply -nullc 3 days ago | root | parent | next [–] -I have absolutely no interest in defending this code-- and already considered it untrusthworthy before any of this. But in the interest of accuracy: -> It does a memcpy of a minimum of 4 bytes -This is a common misreading of MIN(). MIN(4,x) is a number that is a MAXIMUM of 4, not a minimum. -Count is the number of bytes remaining in the buffer. The input to the copy is a 4-byte word. min(4,count) will produce a number 0-4 which is always equal to or less than count. The copy will not overflow the buffer or overrun the input: If count is 3, for example, then here will be 3 and it will copy 3 bytes. -> believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output. -It's been a while since I looked but I believe the STM32 manual advises you to throw away data when this happens, because the rng is updated async with the processor and reads that are too fast will produce 0s or duplicate values. Entropy loss from doing so is generally negligible. Were it me I'd read enough into a cryptographic hash to render the output cryptographically close to uniform and not have to worry about it further. (particularly since some uses of cryptographic numbers are extremely sensitive to even small biases) -I do wonder how fatal MP_EFAULT actually is...-- on a device like this being jumpy at failing the RNG is reasonable, but if it bricks the device (for example) that would be too much for a condition that (IIRC) the datasheet says can happen. If that error is worse than causing a reboot then it might be the case that their emergency fix deployment might have the effect of causing problems by deploying never-actually-tested code into the wild. When I initially looked at this code before finding the flaw I was somewhat surprised that this test didn't produce spurious failures. -[Maybe someone who isn't traveling and on vacation might want to trace out that error condition, -- and check my vague recollection of the STM32 datasheets, as I could be remembering some other part] -reply -inigyou 3 days ago | root | parent | next [–] -There have been cases where a small statistical bias like avoiding duplicate bytes can be amplified to a full break. I don't think this problem is applicable to a bitcoin private key though. -reply -nullc 3 days ago | root | parent | next [–] -Right, that's particularly a concern for DSA nonces. Coldcard uses RFC 6979 however, and duplicates at the 32-bit word level is a different matter than at the byte level. -reply -nullc 3 days ago | parent | prev | next [–] -Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors. -reply -RustyRussell 3 days ago | root | parent | next [–] -Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined. -reply -killerstorm 3 days ago | parent | prev | next [–] -Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?"). -So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated. -reply -dist-epoch 3 days ago | parent | prev | next [–] -I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input. -Hard problem in general, but with LLMs surely this is possible now, either with them inspecting or by them providing some sort of "formal" proof - this function calls this function which reads this buffer which gets input from here... -reply -smithcoin 3 days ago | parent | prev | next [–] -Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities? -reply -nullc 3 days ago | root | parent | next [–] -Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners. -reply -mlcrypto 3 days ago | parent | prev | next [–] -The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003" -reply -koolba 3 days ago | prev | next [–] -> A good goal as a developer is a high commit message to change ratio. The more lines of code that you change, the more comments explaining why you’re changing the code. More message and less code changes per commit is generally a good idea. -No! Blanket statements like this is how you end up with 40 pages of slop AI comments in PRs that nobody reads. -Comments should be terse and meaningful. They should document surprising behavior or choices. The less comments you have, the more meaningful each one becomes because your time and eyeballs are limited as well. -reply -coldbrewed 3 days ago | parent | next [–] -We shouldn't tolerate slop in any form, especially not in commit comments. What we should care about is communicating design decisions, intent, and especially we should explain concerns that can't be intuited from reading the code. A longer, more detailed comment that explains some significant detail can be especially valuable but it should earn the weight that it carries. -I think we're all in agreement that a one word "runs" commit and a 6 paragraph slop commit both fail to communicate effectively. -reply -nonfamous 3 days ago | prev | next [–] -From the Twitter advisory on the issue being referenced here [1]: ->>> To every other developer: we believe this is a sober reality of the new AI paradigm. AI-assisted code review can now find latent bugs at a speed that is outpacing even the industry’s most seasoned experts. If your firmware is open-source or has ever been public, assume it's already being read by attackers and defenders alike. -Kinda turns the “many eyes” principle of OSS on its head, eh? -[1] https://x.com/nvk/status/2083216713693151552?s=61 -reply -abecedarius 3 days ago | parent | next [–] -If your source is not open that's barely a speedbump, given a binary. At least that's my impression of the current state. -reply -nullc 3 days ago | root | parent | next [–] -This flaw would probably be easier to find from the binary: the source itself was misleading, but if you analyized the binary you'd find that there was no access to the hwrng at all (assuming the dead code got eliminated by the compiler) or that the only function that accessed it was never called. -One lesson out of this is that now that AI has made a certain grade of review cheap is that it would be useful to perform security review both against the source code and against the resulting binary. -reply -dist-epoch 3 days ago | parent | prev | next [–] -If the industry most seasoned experts are not using LLMs right now to front-run the discovery of vulnerabilities in the code they are responsible for, they are not experts, but clowns. -reply -catlifeonmars 3 days ago | root | parent | next [–] -A lot of the vulnerabilities being discovered are low hanging fruit. An LLM could discover them, but so could a human. -Let me amend your statement: -If the industry most seasoned experts are not engaging in regular security reviews of their firmware, they are not experts, but clowns. -LLMs are useful for this but not absolutely necessary to address the core issue. -reply -systemsweird 3 days ago | prev | next [–] -Very good writeup and an astonishing level of negligence for an extremely security critical piece of code. The losses are going to surpass 100 million, these guys should be thrown in jail. -reply -jonathanlydall 3 days ago | parent | next [–] -This does not seem to be a good write up at all, see nullc’s explanation in this discussion of (what seems to me) the actual root cause whereas this article spent a lot of words making the argument that bad commit messages must mean bad code, later using the assertion to try “prove” what the technical problem was. -I agree that a bad commit message combined with a big commit is a huge smell, but as it’s just metadata for the code and not the code itself, it is not in itself evidence in any form. -That being said, probably okay after explaining the technical code issues for the author add a couple of a sentences about how all this was was part of 1000s of a lines of code changed in commits with useless messages which demonstrates generally bad code hygiene. -reply -smithcoin 3 days ago | root | parent | next [–] -I think what is the author is getting at is that if you are cavalier in your commit messages when the stakes are low, chances are you aren’t taking writing code that handles money seriously. Made me think of some merges I could have taken more seriously. -reply -Consider applying for YC's Fall 2026 batch! Applications are open till July 27. -Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact -Search: +{ + "author": "Funes-", + "children": [ + { + "author": "anonymousiam", + "children": [ + { + "author": "Sharlin", + "children": [], + "created_at": "2026-08-02T05:01:23.000Z", + "created_at_i": 1785646883, + "id": 49141270, + "options": [], + "parent_id": 49141102, + "points": null, + "story_id": 49140405, + "text": "Hanlon’s razor.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "eru", + "children": [ + { + "author": "thin_carapace", + "children": [ + { + "author": "scott_w", + "children": [ + { + "author": "nullc", + "children": [ + { + "author": "scott_w", + "children": [], + "created_at": "2026-08-02T21:07:14.000Z", + "created_at_i": 1785704834, + "id": 49148323, + "options": [], + "parent_id": 49146618, + "points": null, + "story_id": 49140405, + "text": "Fair point: I was using the information in the article to form my opinion. I still think that, if the developer in question ignored a compiler error as described, that’s a serious competence issue. It’s harder to spot after the fact because any reviewers wouldn’t have had a chance to see the compiler output.<p>The article makes the fair point of the size of the change and the complete lack of information in the commit message, which should have set off alarm bells…", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T17:47:08.000Z", + "created_at_i": 1785692828, + "id": 49146618, + "options": [], + "parent_id": 49145347, + "points": null, + "story_id": 49140405, + "text": "> the error from the C compiler is something that a competent programmer would be able to interpret,<p>contrary to the post, this was almost certainly not an issue of compilers throwing errors.<p>Reduced familarity with C could have played a role, but given the number of C experts that looked at this knowing there was an error and <i>still</i> misidentified the cause I don't think we need to reach for that powerful an explanation.<p>Confusion of definedness vs value check would make for a fine underhanded C entry. The flaw was not particularly clear from the source... and most common QA procedures could not distinguish a PRNG from TRNG once the error happened.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "eru", + "children": [], + "created_at": "2026-08-03T01:07:07.000Z", + "created_at_i": 1785719227, + "id": 49150082, + "options": [], + "parent_id": 49145347, + "points": null, + "story_id": 49140405, + "text": "Of course, being a total novice and claiming to produce a super secure gadget are not to things you want to go together.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "Scoundreller", + "children": [], + "created_at": "2026-08-04T03:07:05.000Z", + "created_at_i": 1785812825, + "id": 49163987, + "options": [], + "parent_id": 49145347, + "points": null, + "story_id": 49140405, + "text": "Hey now, I'm totally incompetent, so my code writes entries in a log file for virtually everything because otherwise I have no idea if it's doing what I expect. Would've caught some critical function not being called at all.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T15:07:55.000Z", + "created_at_i": 1785683275, + "id": 49145347, + "options": [], + "parent_id": 49141474, + "points": null, + "story_id": 49140405, + "text": "Honestly, I'm going to be a bit harsher: I think they're either:<p>1. A novice who doesn't know how to debug issues.<p>2. Totally incompetent and copying code from Stack Overflow.<p>I don't think it's specific to microcontrollers, either, the error from the C compiler is something that a competent programmer would be able to interpret, or at least see it as a signal to get someone more experienced in the domain to learn about.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T05:43:31.000Z", + "created_at_i": 1785649411, + "id": 49141474, + "options": [], + "parent_id": 49141340, + "points": null, + "story_id": 49140405, + "text": "I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "jgilias", + "children": [], + "created_at": "2026-08-02T05:44:29.000Z", + "created_at_i": 1785649469, + "id": 49141482, + "options": [], + "parent_id": 49141340, + "points": null, + "story_id": 49140405, + "text": "The bug has been up since before the LLM shift.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "jki275", + "children": [ + { + "author": "nullc", + "children": [], + "created_at": "2026-08-02T17:46:05.000Z", + "created_at_i": 1785692765, + "id": 49146607, + "options": [], + "parent_id": 49144692, + "points": null, + "story_id": 49140405, + "text": "> Also running python on a microcontroller to do cryptography is fucking insane.<p>I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color.<p>Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T13:49:05.000Z", + "created_at_i": 1785678545, + "id": 49144692, + "options": [], + "parent_id": 49141340, + "points": null, + "story_id": 49140405, + "text": "C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem.<p>Also running python on a microcontroller to do cryptography is fucking insane.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T05:16:48.000Z", + "created_at_i": 1785647808, + "id": 49141340, + "options": [], + "parent_id": 49141102, + "points": null, + "story_id": 49140405, + "text": "Also: writing this stuff in C just begs for bugs.<p>LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "karamanolev", + "children": [], + "created_at": "2026-08-02T07:39:00.000Z", + "created_at_i": 1785656340, + "id": 49142040, + "options": [], + "parent_id": 49141102, + "points": null, + "story_id": 49140405, + "text": "Per the article, not my opinion.<p>It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "silvestrov", + "children": [ + { + "author": "inigyou", + "children": [], + "created_at": "2026-08-02T12:45:18.000Z", + "created_at_i": 1785674718, + "id": 49144064, + "options": [], + "parent_id": 49142714, + "points": null, + "story_id": 49140405, + "text": "The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T09:33:07.000Z", + "created_at_i": 1785663187, + "id": 49142714, + "options": [], + "parent_id": 49141102, + "points": null, + "story_id": 49140405, + "text": "When looking through all the other commits the user has made: they all lack a good commit message.<p>This is systematic for that user. Either the user needs to improve or let go.<p>The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "anonymars", + "children": [], + "created_at": "2026-08-02T12:51:01.000Z", + "created_at_i": 1785675061, + "id": 49144132, + "options": [], + "parent_id": 49141102, + "points": null, + "story_id": 49140405, + "text": "Ironic:<p>> NEW POLICY If I don't know you, I don't merge you! Thanks XZ!<p><a href=\"https://github.com/switck/libngu\" rel=\"nofollow\">https://github.com/switck/libngu</a>", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T04:30:52.000Z", + "created_at_i": 1785645052, + "id": 49141102, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "systemsweird", + "children": [ + { + "author": "jonathanlydall", + "children": [ + { + "author": "smithcoin", + "children": [], + "created_at": "2026-08-02T08:36:14.000Z", + "created_at_i": 1785659774, + "id": 49142362, + "options": [], + "parent_id": 49142227, + "points": null, + "story_id": 49140405, + "text": "I think what is the author is getting at is that if you are cavalier in your commit messages when the stakes are low, chances are you aren’t taking writing code <i>that handles money</i> seriously. Made me think of some merges I could have taken more seriously.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T08:14:31.000Z", + "created_at_i": 1785658471, + "id": 49142227, + "options": [], + "parent_id": 49141837, + "points": null, + "story_id": 49140405, + "text": "This does not seem to be a good write up at all, see nullc’s explanation in this discussion of (what seems to me) the actual root cause whereas this article spent a lot of words making the argument that bad commit messages <i>must</i> mean bad code, later using the assertion to try “prove” what the technical problem was.<p>I agree that a bad commit message combined with a big commit is a huge smell, but as it’s just metadata for the code and not the code itself, it is not in itself evidence in any form.<p>That being said, probably okay after explaining the technical code issues for the author add a couple of a sentences about how all this was was part of 1000s of a lines of code changed in commits with useless messages which demonstrates generally bad code hygiene.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T06:58:01.000Z", + "created_at_i": 1785653881, + "id": 49141837, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "Very good writeup and an astonishing level of negligence for an extremely security critical piece of code. The losses are going to surpass 100 million, these guys should be thrown in jail.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "nullc", + "children": [ + { + "author": "nullc", + "children": [ + { + "author": "RustyRussell", + "children": [], + "created_at": "2026-08-02T09:04:47.000Z", + "created_at_i": 1785661487, + "id": 49142559, + "options": [], + "parent_id": 49142014, + "points": null, + "story_id": 49140405, + "text": "Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T07:34:54.000Z", + "created_at_i": 1785656094, + "id": 49142014, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "smithcoin", + "children": [ + { + "author": "nullc", + "children": [], + "created_at": "2026-08-02T17:54:43.000Z", + "created_at_i": 1785693283, + "id": 49146689, + "options": [], + "parent_id": 49142373, + "points": null, + "story_id": 49140405, + "text": "Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T08:37:43.000Z", + "created_at_i": 1785659863, + "id": 49142373, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities?", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "dist-epoch", + "children": [], + "created_at": "2026-08-02T10:28:58.000Z", + "created_at_i": 1785666538, + "id": 49143073, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input.<p>Hard problem in general, but with LLMs surely this is possible now, either with them inspecting or by them providing some sort of "formal" proof - this function calls this function which reads this buffer which gets input from here...", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "egwor", + "children": [], + "created_at": "2026-08-02T11:30:10.000Z", + "created_at_i": 1785670210, + "id": 49143450, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "Although I might disagree with the style of the write up, I think it is right that there are weak engineering practices applied:<p>- not enough information provided in commit message. \n- this change ought to have been split into smaller chunks (e.g. introduce indirection whilst code continues to use hardware)\n- limited (automated) testing\n- potential confusion by the author over C concepts\n- additional complexity which could have been hidden behind a cleaner interface rather than using defines<p>I agree about your points about:<p>- defines over multiple repo's made this more complicated that was necessary. \n- fault injections would have been the appropriate way to test this (or maybe mocks)\n- testing of randomness needs careful design, e.g. RNG seeding can be a good way<p>Taking a step back, we as a community of excellence need to emphasise that this isn't a criticism about the person/author. There needs to be a clear analysis of what went wrong whilst being kind to the person/people involved.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "inigyou", + "children": [ + { + "author": "nullc", + "children": [ + { + "author": "dale_glass", + "children": [ + { + "author": "nullc", + "children": [ + { + "author": "inigyou", + "children": [ + { + "author": "nullc", + "children": [], + "created_at": "2026-08-02T17:40:41.000Z", + "created_at_i": 1785692441, + "id": 49146562, + "options": [], + "parent_id": 49146187, + "points": null, + "story_id": 49140405, + "text": "Right, that's particularly a concern for DSA nonces. Coldcard uses RFC 6979 however, and duplicates at the 32-bit word level is a different matter than at the byte level.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T16:57:49.000Z", + "created_at_i": 1785689869, + "id": 49146187, + "options": [], + "parent_id": 49146167, + "points": null, + "story_id": 49140405, + "text": "There have been cases where a small statistical bias like avoiding duplicate bytes can be amplified to a full break. I don't think this problem is applicable to a bitcoin private key though.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T16:55:41.000Z", + "created_at_i": 1785689741, + "id": 49146167, + "options": [], + "parent_id": 49145802, + "points": null, + "story_id": 49140405, + "text": "I have absolutely no interest in defending this code-- and already considered it untrusthworthy before any of this. But in the interest of accuracy:<p>> It does a memcpy of a minimum of 4 bytes<p>This is a common misreading of MIN(). MIN(4,x) is a number that is a MAXIMUM of 4, not a minimum.<p>Count is the number of bytes remaining in the buffer. The input to the copy is a 4-byte word. min(4,count) will produce a number 0-4 which is always equal to or less than count. The copy will not overflow the buffer or overrun the input: If count is 3, for example, then here will be 3 and it will copy 3 bytes.<p>> believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output.<p>It's been a while since I looked but I believe the STM32 manual advises you to throw away data when this happens, because the rng is updated async with the processor and reads that are too fast will produce 0s or duplicate values. Entropy loss from doing so is generally negligible. Were it me I'd read enough into a cryptographic hash to render the output cryptographically close to uniform and not have to worry about it further. (particularly since some uses of cryptographic numbers are extremely sensitive to even small biases)<p>I do wonder how fatal MP_EFAULT actually is...-- on a device like this being jumpy at failing the RNG is reasonable, but if it bricks the device (for example) that would be too much for a condition that (IIRC) the datasheet says can happen. If that error is worse than causing a reboot then it might be the case that their emergency fix deployment might have the effect of causing problems by deploying never-actually-tested code into the wild. When I initially looked at this code before finding the flaw I was somewhat surprised that this test didn't produce spurious failures.<p>[Maybe someone who isn't traveling and on vacation might want to trace out that error condition, -- and check my vague recollection of the STM32 datasheets, as I could be remembering some other part]", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T16:08:18.000Z", + "created_at_i": 1785686898, + "id": 49145802, + "options": [], + "parent_id": 49145062, + "points": null, + "story_id": 49140405, + "text": "The my_random_bytes implementation doesn't look good at all at first glance. Let's see:<p>1. I believe it errors out if the HWRNG returns the same value twice. That's actually a thing that can legitimately happen. "0" is also a legitimate output.<p>2. "here" is a terrible name for a length<p>3. It does a memcpy of a minimum of 4 bytes to the destination, even if count is lower. It'll also overflow longer buffers with a length not divisible by 4.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T14:32:44.000Z", + "created_at_i": 1785681164, + "id": 49145062, + "options": [], + "parent_id": 49144079, + "points": null, + "story_id": 49140405, + "text": "<a href=\"https://github.com/switck/libngu/blob/537519a829259622ea6b0334fbafd6cae852852f/ngu/random.c#L77\" rel=\"nofollow\">https://github.com/switck/libngu/blob/537519a829259622ea6b03...</a><p>vs<p><a href=\"https://github.com/Coldcard/micropython/blob/4107246f8a080807b62c3b4838e71e812ea68b6f/ports/stm32/rng.c#L55\" rel=\"nofollow\">https://github.com/Coldcard/micropython/blob/4107246f8a08080...</a>", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T12:46:41.000Z", + "created_at_i": 1785674801, + "id": 49144079, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "At no point did I ever think that setting "enable HW RNG" to 0 "provided a more aggressive handling of fault/error conditions". I always assumed it disabled the HW RNG.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "mlcrypto", + "children": [], + "created_at": "2026-08-02T16:16:51.000Z", + "created_at_i": 1785687411, + "id": 49145865, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003"", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "killerstorm", + "children": [], + "created_at": "2026-08-02T18:52:59.000Z", + "created_at_i": 1785696779, + "id": 49147215, + "options": [], + "parent_id": 49141886, + "points": null, + "story_id": 49140405, + "text": "Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?").<p>So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T07:08:53.000Z", + "created_at_i": 1785654533, + "id": 49141886, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "This writeup isn't very good and misses/misunderstands the programming error that leads to the flaw.<p>I'm commenting because I think it's important to understand the issue.<p>The article would have you think that the change in question was a tiny change to a flag to make it compile, but in reality the commit in question is a 1533 line addition of the entire RNG infrastructure.<p>The fundamental cause is a mixup between a value test and a definedness test.<p>Coldcard attempted to replace the micropython wrapper on the hardware TRNG, apparently in order to provide a more aggressive handling of fault/error conditions.<p>The micropython hwrng code is gated by an #if check, the replacement HWRNG code is gated by an ifndef. So "#define MICROPY_HW_ENABLE_RNG (0)" deactivated the micropython implementation but <i>failed</i> to activate the internal one (which was #ifndef MICROPY_HW_ENABLE_RNG ... which didn't fire because MICROPY_HW_ENABLE_RNG was _defined_).<p>This was easier to miss because the usages weren't only in different files-- they were in different repositories.<p>There is a more abstract point to make that in cryptographic software the absence of a secure randomness source (the STM32 TRNG) should never fall back to an insecure source (a trivial PRNG which might have only had on the order of 20-bits of uncertainty in its input). But the code that had the fallback was micropython which was not authored by the coldcard creators and is presumably not intended for cryptographic applications...<p>In later code (for MK4+ devices) the issue was further masked without being corrected by xor-ing in another insecure PRNG seeded by 32-bits from another TRNG. ... itself acting like an additional insecure fallback. (Why it first hashes 64-bits of TRNG output then throws away half the entropy is a mystery...)<p>RNG failures can be difficult to detect because the real randomness and a PRNG are indistinguishable by any simple tests of the output. I understand the coldcard developers ran extensive tests on the randomness generated by these devices-- they may well have been just testing the PRNG. It's something of a "color of your bits" issue ( <a href=\"https://ansuz.sooke.bc.ca/entry/23\" rel=\"nofollow\">https://ansuz.sooke.bc.ca/entry/23</a> ).<p>The same sort of issue happens at multiple levels of the stack, e.g. IIRC the STM32 TRNG itself does some kind of whitening that could have the same effect of concealing an RNG failure.<p>The existence of insecure fake randomness in the code at all was a red flag that had been noted previously -- though the really bad one was hidden away in the micropython code and not even obviously at play. I think this is a rare case of a bug that would be more easily found from binary analysis than review of the source code (e.g. no access to the STM32 TRNG at all).<p>Without these fallbacks the failure to use the TRNG would have been immediately detected by the developers (e.g. when every attempt generated the same seed), and a review could be validated by fault injection (NOP out the hwrng and verify that the test fails).", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "dmitrygr", + "children": [], + "created_at": "2026-08-02T07:22:02.000Z", + "created_at_i": 1785655322, + "id": 49141953, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "<p><pre><code> >Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming.\n</code></pre>\nAmen.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "londons_explore", + "children": [ + { + "author": "dist-epoch", + "children": [ + { + "author": "londons_explore", + "children": [], + "created_at": "2026-08-02T10:23:55.000Z", + "created_at_i": 1785666235, + "id": 49143043, + "options": [], + "parent_id": 49142900, + "points": null, + "story_id": 49140405, + "text": "Need not be the NSA. Might just be some regular thief.<p>The longer they wait, the more they get to steal after all.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "josephg", + "children": [], + "created_at": "2026-08-02T11:02:22.000Z", + "created_at_i": 1785668542, + "id": 49143269, + "options": [], + "parent_id": 49142900, + "points": null, + "story_id": 49140405, + "text": "> And do you think the NSA desperately needed $90 mil (the amount stolen so far)<p>If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T10:04:43.000Z", + "created_at_i": 1785665083, + "id": 49142900, + "options": [], + "parent_id": 49142187, + "points": null, + "story_id": 49140405, + "text": "And they waited 5 years to exploit it?<p>And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet?<p>All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T08:08:06.000Z", + "created_at_i": 1785658086, + "id": 49142187, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "I am getting suspicious of "random number generator not actually returning random numbers" bugs....<p>They are the perfect bug for someone trying to "accidentally" make a secure system insecure.<p>I wonder if bribe money was involved or three letter agencies...", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "nonfamous", + "children": [ + { + "author": "dist-epoch", + "children": [ + { + "author": "catlifeonmars", + "children": [], + "created_at": "2026-08-02T15:22:26.000Z", + "created_at_i": 1785684146, + "id": 49145449, + "options": [], + "parent_id": 49142927, + "points": null, + "story_id": 49140405, + "text": "A lot of the vulnerabilities being discovered are low hanging fruit. An LLM could discover them, but so could a human.<p>Let me amend your statement:<p>If the industry most seasoned experts are not engaging in regular security reviews of their firmware, they are not experts, but clowns.<p>LLMs are useful for this but not absolutely necessary to address the core issue.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T10:07:59.000Z", + "created_at_i": 1785665279, + "id": 49142927, + "options": [], + "parent_id": 49142449, + "points": null, + "story_id": 49140405, + "text": "If the industry most seasoned experts are not using LLMs right now to front-run the discovery of vulnerabilities in the code they are responsible for, they are not experts, but clowns.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "abecedarius", + "children": [ + { + "author": "nullc", + "children": [], + "created_at": "2026-08-02T17:52:04.000Z", + "created_at_i": 1785693124, + "id": 49146659, + "options": [], + "parent_id": 49144476, + "points": null, + "story_id": 49140405, + "text": "This flaw would probably be easier to find from the binary: the source itself was misleading, but if you analyized the binary you'd find that there was no access to the hwrng at all (assuming the dead code got eliminated by the compiler) or that the only function that accessed it was never called.<p>One lesson out of this is that now that AI has made a certain grade of review cheap is that it would be useful to perform security review both against the source code and against the resulting binary.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T13:24:39.000Z", + "created_at_i": 1785677079, + "id": 49144476, + "options": [], + "parent_id": 49142449, + "points": null, + "story_id": 49140405, + "text": "If your source is <i>not</i> open that's barely a speedbump, given a binary. At least that's my impression of the current state.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T08:47:18.000Z", + "created_at_i": 1785660438, + "id": 49142449, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "From the Twitter advisory on the issue being referenced here [1]:<p>>>> To every other developer: we believe this is a sober reality of the new AI paradigm. AI-assisted code review can now find latent bugs at a speed that is outpacing even the industry’s most seasoned experts. If your firmware is open-source or has ever been public, assume it's already being read by attackers and defenders alike.<p>Kinda turns the “many eyes” principle of OSS on its head, eh?<p>[1] <a href=\"https://x.com/nvk/status/2083216713693151552?s=61\" rel=\"nofollow\">https://x.com/nvk/status/2083216713693151552?s=61</a>", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "PunchyHamster", + "children": [], + "created_at": "2026-08-02T09:36:32.000Z", + "created_at_i": 1785663392, + "id": 49142733, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16.<p>the commit message is not 235 character long, the commit message is this<p>> splice-script: Test for msat chan balances\n> splice-script: Round channel balances down<p>author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed.<p>So yeah it is better but nothing to actually brag about", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "hypeatei", + "children": [ + { + "author": "inigyou", + "children": [ + { + "author": "anonymars", + "children": [], + "created_at": "2026-08-02T12:55:18.000Z", + "created_at_i": 1785675318, + "id": 49144163, + "options": [], + "parent_id": 49144084, + "points": null, + "story_id": 49140405, + "text": "Banking-related errors have recourse", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "hypeatei", + "children": [ + { + "author": "inigyou", + "children": [ + { + "author": "anonymars", + "children": [], + "created_at": "2026-08-02T15:19:15.000Z", + "created_at_i": 1785683955, + "id": 49145422, + "options": [], + "parent_id": 49144682, + "points": null, + "story_id": 49140405, + "text": "Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "hypeatei", + "children": [], + "created_at": "2026-08-02T16:07:23.000Z", + "created_at_i": 1785686843, + "id": 49145792, + "options": [], + "parent_id": 49144682, + "points": null, + "story_id": 49140405, + "text": "If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right?<p>Also infrequent purchases != storing wealth in Bitcoin.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T13:48:14.000Z", + "created_at_i": 1785678494, + "id": 49144682, + "options": [], + "parent_id": 49144432, + "points": null, + "story_id": 49140405, + "text": "Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T13:19:10.000Z", + "created_at_i": 1785676750, + "id": 49144432, + "options": [], + "parent_id": 49144084, + "points": null, + "story_id": 49140405, + "text": "No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void.<p>There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T12:47:02.000Z", + "created_at_i": 1785674822, + "id": 49144084, + "options": [], + "parent_id": 49143286, + "points": null, + "story_id": 49140405, + "text": "I take it you get your paycheck in cash?", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "DJBunnies", + "children": [ + { + "author": "hypeatei", + "children": [ + { + "author": "firmretention", + "children": [], + "created_at": "2026-08-05T11:38:08.000Z", + "created_at_i": 1785929888, + "id": 49181406, + "options": [], + "parent_id": 49145759, + "points": null, + "story_id": 49140405, + "text": "While I agree self-custody is too onerous for the average person, Coldcard's own documentation had a section on generating secure seeds with dice and why that's more secure. It wasn't some esoteric knowledge - anyone who RTFM on the device they intended to store their savings on was fine. That's not an absolution of Coldcard of course, but it's not "new cope".", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T16:03:16.000Z", + "created_at_i": 1785686596, + "id": 49145759, + "options": [], + "parent_id": 49145624, + "points": null, + "story_id": 49140405, + "text": "> If one uses a good source of entropy then one will not "get screwed."<p>How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it.<p>> dice rolls<p>Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure.<p>1: <a href=\"https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls_for_a_24word_seed_two_questions/p13ch4q/\" rel=\"nofollow\">https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls...</a>", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T15:47:05.000Z", + "created_at_i": 1785685625, + "id": 49145624, + "options": [], + "parent_id": 49143286, + "points": null, + "story_id": 49140405, + "text": "The "right thing" here is subjective.<p>If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed."<p>> I don't know why anyone would keep their wealth in something that requires so much technical excellence.<p>It's not for everybody, for sure.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T11:05:33.000Z", + "created_at_i": 1785668733, + "id": 49143286, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think.<p>Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence.", + "title": null, + "type": "comment", + "url": null + }, + { + "author": "koolba", + "children": [ + { + "author": "coldbrewed", + "children": [], + "created_at": "2026-08-02T17:52:13.000Z", + "created_at_i": 1785693133, + "id": 49146661, + "options": [], + "parent_id": 49143727, + "points": null, + "story_id": 49140405, + "text": "We shouldn't tolerate slop in any form, especially not in commit comments. What we should care about is communicating design decisions, intent, and especially we should explain concerns that can't be intuited from reading the code. A longer, more detailed comment that explains some significant detail can be especially valuable but it should earn the weight that it carries.<p>I think we're all in agreement that a one word "runs" commit and a 6 paragraph slop commit both fail to communicate effectively.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T12:07:24.000Z", + "created_at_i": 1785672444, + "id": 49143727, + "options": [], + "parent_id": 49140405, + "points": null, + "story_id": 49140405, + "text": "> A good goal as a developer is a high commit message to change ratio. The more lines of code that you change, the more comments explaining why you’re changing the code. More message and less code changes per commit is generally a good idea.<p>No! Blanket statements like this is how you end up with 40 pages of slop AI comments in PRs that nobody reads.<p>Comments should be terse and meaningful. They should document surprising behavior or choices. The less comments you have, the more meaningful each one becomes because your time and eyeballs are limited as well.", + "title": null, + "type": "comment", + "url": null + } + ], + "created_at": "2026-08-02T02:08:26.000Z", + "created_at_i": 1785636506, + "id": 49140405, + "options": [], + "parent_id": null, + "points": null, + "story_id": 49140405, + "text": null, + "title": "When random.bytes() runs but doesn't work", + "type": "story", + "url": "https://insider.btcpp.dev/p/when-randombytes-runs-but-doesnt" +}Extracted text as captured
{ "author": "Funes-", "children": [ { "author": "anonymousiam", "children": [ { "author": "Sharlin", "children": [], "created_at": "2026-08-02T05:01:23.000Z", "created_at_i": 1785646883, "id": 49141270, "options": [], "parent_id": 49141102, "points": null, "story_id": 49140405, "text": "Hanlon’s razor.", "title": null, "type": "comment", "url": null }, { "author": "eru", "children": [ { "author": "thin_carapace", "children": [ { "author": "scott_w", "children": [ { "author": "nullc", "children": [ { "author": "scott_w", "children": [], "created_at": "2026-08-02T21:07:14.000Z", "created_at_i": 1785704834, "id": 49148323, "options": [],Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
The discussion gained a comment arguing that COLDCARD documentation had explained dice-based seed generation, while noting that this does not absolve the vendor.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 17 lines
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) -94 points by Funes- <relative-time> | hide | past | favorite | 56 comments +94 points by Funes- <relative-time> | hide | past | favorite | 57 comments help londons_explore <relative-time> | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... > dice rolls Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure. 1: https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls... +reply +firmretention <relative-time> | root | parent | next [–] +While I agree self-custody is too onerous for the average person, Coldcard's own documentation had a section on generating secure seeds with dice and why that's more secure. It wasn't some esoteric knowledge - anyone who RTFM on the device they intended to store their savings on was fine. That's not an absolution of Coldcard of course, but it's not "new cope". reply inigyou <relative-time> | parent | prev | next [–] I take it you get your paycheck in cash? nullc <relative-time> | root | parent | next [–] Right, that's particularly a concern for DSA nonces. Coldcard uses RFC 6979 however, and duplicates at the 32-bit word level is a different matter than at the byte level. reply +nullc <relative-time> | parent | prev | next [–] +Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors. +reply +RustyRussell <relative-time> | root | parent | next [–] +Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined. +reply killerstorm <relative-time> | parent | prev | next [–] Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?"). So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated. -reply -nullc <relative-time> | parent | prev | next [–] -Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors. -reply -RustyRussell <relative-time> | root | parent | next [–] -Always use -Wundef. For CCAN all config vars use #if and we lint for ifdefs of them, because you have to pick a side here, and sometimes using HAVE_X in C code is useful, so I prefer always-defined. reply dist-epoch <relative-time> | parent | prev | next [–] I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input.Extracted text as captured
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) 94 points by Funes- 3 days ago | hide | past | favorite | 57 comments help londons_explore 3 days ago | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... They are the perfect bug for someone trying to "accidentally" make a secure system insecure. I wonder if bribe money was involved or three letter agencies... reply dist-epoch 3 days ago | parent | next [–] And they waited 5 years to exploit it? And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. reply londons_explore 3 days ago | root | parent | next [–] Need not be the NSA. Might just be some regular thief. The longer they wait, the more they get to steal after all. reply josephg 3 days ago | root | parent | prev | next [–] > And do you think the NSA desperately needed $90 mil (the amount stolen so far) If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. reply anonymousiam 3 days ago | prev | next [–] This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. reply karamanolev 3 days ago | parent | next [–] Per the article, not my opinion. It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. reply silvestrov 3 days ago | parent | prev | next [–] When looking through all the other commits the user has made: they all lack a good commit message. This is systematic for that user. Either the user needs to improve or let go. The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. reply inigyou 3 days ago | root | parent | next [–] The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. reply anonymars 3 days ago | parent | prev | next [–] Ironic: > NEW POLICY If I don't know you, I don't merge you! Thanks XZ!Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
A further Hacker News comment was added to the discussion; surrounding comments were reordered by thread position.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 20 lines
Also: writing this stuff in C just begs for bugs. LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust. reply -thin_carapace <relative-time> | root | parent | next [–] +jki275 <relative-time> | root | parent | next [–] +C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem. +Also running python on a microcontroller to do cryptography is fucking insane. +reply +nullc <relative-time> | root | parent | next [–] +> Also running python on a microcontroller to do cryptography is fucking insane. +I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color. +Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't. +reply +thin_carapace <relative-time> | root | parent | prev | next [–] I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller reply scott_w <relative-time> | root | parent | next [–] reply jgilias <relative-time> | root | parent | prev | next [–] The bug has been up since before the LLM shift. -reply -jki275 <relative-time> | root | parent | prev | next [–] -C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem. -Also running python on a microcontroller to do cryptography is fucking insane. -reply -nullc <relative-time> | root | parent | next [–] -> Also running python on a microcontroller to do cryptography is fucking insane. -I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color. -Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't. reply PunchyHamster <relative-time> | prev | next [–] > The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16.Extracted text as captured
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) 94 points by Funes- 2 days ago | hide | past | favorite | 56 comments help londons_explore 2 days ago | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... They are the perfect bug for someone trying to "accidentally" make a secure system insecure. I wonder if bribe money was involved or three letter agencies... reply dist-epoch 2 days ago | parent | next [–] And they waited 5 years to exploit it? And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. reply londons_explore 2 days ago | root | parent | next [–] Need not be the NSA. Might just be some regular thief. The longer they wait, the more they get to steal after all. reply josephg 2 days ago | root | parent | prev | next [–] > And do you think the NSA desperately needed $90 mil (the amount stolen so far) If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. reply anonymousiam 2 days ago | prev | next [–] This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. reply karamanolev 2 days ago | parent | next [–] Per the article, not my opinion. It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. reply silvestrov 2 days ago | parent | prev | next [–] When looking through all the other commits the user has made: they all lack a good commit message. This is systematic for that user. Either the user needs to improve or let go. The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. reply inigyou 2 days ago | root | parent | next [–] The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. reply anonymars 2 days ago | parent | prev | next [–] Ironic: > NEW POLICY If I don't know you, I don't merge you! Thanks XZ!Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
New Hacker News comments were added to the discussion, including discussion of software-engineering practice and implementation choices.
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 131 lines
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) -94 points by Funes- <relative-time> | hide | past | favorite | 55 comments +94 points by Funes- <relative-time> | hide | past | favorite | 56 comments help londons_explore <relative-time> | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... Also: writing this stuff in C just begs for bugs. LLM agents are cheap and good enough that you can write in eg Lean or whatever. Or at least write it in Rust. reply -jgilias <relative-time> | root | parent | next [–] -The bug has been up since before the LLM shift. -reply -thin_carapace <relative-time> | root | parent | prev | next [–] +thin_carapace <relative-time> | root | parent | next [–] I get the feeling that the bugs found in this instance can be more directly attributed to the author having zero experience operating a microcontroller reply scott_w <relative-time> | root | parent | next [–] 2. Totally incompetent and copying code from Stack Overflow. I don't think it's specific to microcontrollers, either, the error from the C compiler is something that a competent programmer would be able to interpret, or at least see it as a signal to get someone more experienced in the domain to learn about. reply -eru <relative-time> | root | parent | next [–] +Scoundreller <relative-time> | root | parent | next [–] +Hey now, I'm totally incompetent, so my code writes entries in a log file for virtually everything because otherwise I have no idea if it's doing what I expect. Would've caught some critical function not being called at all. +reply +eru <relative-time> | root | parent | prev | next [–] Of course, being a total novice and claiming to produce a super secure gadget are not to things you want to go together. reply nullc <relative-time> | root | parent | prev | next [–] Fair point: I was using the information in the article to form my opinion. I still think that, if the developer in question ignored a compiler error as described, that’s a serious competence issue. It’s harder to spot after the fact because any reviewers wouldn’t have had a chance to see the compiler output. The article makes the fair point of the size of the change and the complete lack of information in the commit message, which should have set off alarm bells… reply +jgilias <relative-time> | root | parent | prev | next [–] +The bug has been up since before the LLM shift. +reply jki275 <relative-time> | root | parent | prev | next [–] C isn't the problem here. one might argue that the combination of micro python and C and the person writing it having no understanding of how either one works is the problem. Also running python on a microcontroller to do cryptography is fucking insane. > Also running python on a microcontroller to do cryptography is fucking insane. I feel like I should confess to snubbing this (and some other) hardware wallet projects for the fact it used micropython. I think it's hard to draw the line between systems programmer snobbery and good advice... and I feel a little like a cop guilty of stop-and-frisk on the basis of skin color. Because in general the ideas necessary to produce reliable software aren't well understood or agreed on there is a risk of letting style preferences which are only correlated with good engineering but aren't causative of good engineering get mistaken-- and this can cause errors in both directions, both mistaking stuff as good because it uses the "right" tools, or mistaking something as bad because it doesn't. +reply +PunchyHamster <relative-time> | prev | next [–] +> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16. +the commit message is not 235 character long, the commit message is this +> splice-script: Test for msat chan balances +> splice-script: Round channel balances down +author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed. +So yeah it is better but nothing to actually brag about +reply +dmitrygr <relative-time> | prev | next [–] +>Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming. +Amen. +reply +hypeatei <relative-time> | prev | next [–] +> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think. +Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence. +reply +DJBunnies <relative-time> | parent | next [–] +The "right thing" here is subjective. +If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed." +> I don't know why anyone would keep their wealth in something that requires so much technical excellence. +It's not for everybody, for sure. +reply +hypeatei <relative-time> | root | parent | next [–] +> If one uses a good source of entropy then one will not "get screwed." +How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it. +> dice rolls +Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure. +1: https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls... +reply +inigyou <relative-time> | parent | prev | next [–] +I take it you get your paycheck in cash? +reply +hypeatei <relative-time> | root | parent | next [–] +No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void. +There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place. +reply +inigyou <relative-time> | root | parent | next [–] +Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs. +reply +anonymars <relative-time> | root | parent | next [–] +Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make +reply +hypeatei <relative-time> | root | parent | prev | next [–] +If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right? +Also infrequent purchases != storing wealth in Bitcoin. +reply +anonymars <relative-time> | root | parent | prev | next [–] +Banking-related errors have recourse reply nullc <relative-time> | prev | next [–] This writeup isn't very good and misses/misunderstands the programming error that leads to the flaw. Well, if the developer read libngu's random.c he would have noticed that it uses rng_get() and that it's asking for MICROPY_HW_ENABLE_RNG (albeit the failsafe is defective, reading it should have at least triggered "wait, what?"). So I'd say the root cause that the developer didn't check what random.bytes() does under the hood or how libngu expects random to be generated. reply -smithcoin <relative-time> | parent | prev | next [–] -Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities? -reply -nullc <relative-time> | root | parent | next [–] -Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners. -reply -mlcrypto <relative-time> | parent | prev | next [–] -The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003" -reply nullc <relative-time> | parent | prev | next [–] Aside, I'm somewhat surprised that MISRA (as of 2012 at least) doesn't have a directive related to definedness vs value errors. reply dist-epoch <relative-time> | parent | prev | next [–] I wonder if some sort of "taint" analysis could be used - you generate a byte of randomness and trace it back through code until you see all the sources of entropy which were used as input. Hard problem in general, but with LLMs surely this is possible now, either with them inspecting or by them providing some sort of "formal" proof - this function calls this function which reads this buffer which gets input from here... +reply +smithcoin <relative-time> | parent | prev | next [–] +Have you found a write up you’d recommend on how the threat actors actually exploited the vulnerabilities? +reply +nullc <relative-time> | root | parent | next [–] +Hopefully people are being a little circumspect right now with explotation instructions because there are still vulnerable coins out there (particularly from mk4+ wallets, as well ones with passwords that are not strong enough) which have not been taken or rescued yet and may still be rescued by owners. +reply +mlcrypto <relative-time> | parent | prev | next [–] +The article clearly indicates the size of the changes: "The commit message is 5 characters and is simply the word “runs.” The commit changes 1534 lines of code making the ratio 5/1534 = ~0.003" reply koolba <relative-time> | prev | next [–] > A good goal as a developer is a high commit message to change ratio. The more lines of code that you change, the more comments explaining why you’re changing the code. More message and less code changes per commit is generally a good idea. If the industry most seasoned experts are not engaging in regular security reviews of their firmware, they are not experts, but clowns. LLMs are useful for this but not absolutely necessary to address the core issue. reply -dmitrygr <relative-time> | prev | next [–] ->Micropython creates the illusion embedded developers do not need to understand C, their CPU, or other advanced concepts to do embedded programming. -Amen. -reply -PunchyHamster <relative-time> | prev | next [–] -> The commit message is 235 characters, and the commit changes 15 lines of code. That’s a ratio of 235/15 = ~16. -the commit message is not 235 character long, the commit message is this -> splice-script: Test for msat chan balances -> splice-script: Round channel balances down -author mistakes commit message for PR which doesn't get persisted into code's history and don't even contain the ID of bug being fixed. -So yeah it is better but nothing to actually brag about -reply -hypeatei <relative-time> | prev | next [–] -> You, as a developer working on Bitcoin, need to take your time to understand your changes, document them clearly, and verify they do what you think. -Or, you could realize that using a financial technology which relies on no software bugs ever is probably flawed at its core. "Not your keys, not your coins" was (is?) the zeitgeist but even people who did the "right thing" and used a cold wallet still got screwed. I don't know why anyone would keep their wealth in something that requires so much technical excellence. -reply -DJBunnies <relative-time> | parent | next [–] -The "right thing" here is subjective. -If one uses a good source of entropy (e.g. dice rolls) then one will not "get screwed." -> I don't know why anyone would keep their wealth in something that requires so much technical excellence. -It's not for everybody, for sure. -reply -hypeatei <relative-time> | root | parent | next [–] -> If one uses a good source of entropy then one will not "get screwed." -How many users were told to verify the source code to make sure it was using good entropy? How many would actually do that even if told? Obviously not even the most hardline bitcoiners were looking at it. -> dice rolls -Yes, the new cope I've seen is that you should've been using casino-grade dice[1] to make sure your entropy is good LOL. Mass adoption soon, I'm sure. -1: https://old.reddit.com/r/Bitcoin/comments/1vcr4r4/dice_rolls... -reply -inigyou <relative-time> | parent | prev | next [–] -I take it you get your paycheck in cash? -reply -anonymars <relative-time> | root | parent | next [–] -Banking-related errors have recourse -reply -hypeatei <relative-time> | root | parent | prev | next [–] -No, via direct deposit. I had a co-worker once who miskeyed his routing+account numbers and guess what? He still got his money a few days later and it wasn't lost to the void. -There is no blockchain, seed phrases, nor cold wallets required for this amazing feat of money transfer/remediation to take place. -reply -inigyou <relative-time> | root | parent | next [–] -Great! Maybe the government should stop over regulating the banking system so the same protection will also be available to someone who buys drugs. -reply -anonymars <relative-time> | root | parent | next [–] -Wait, is the argument now that cryptocurrency only exists and is useful for buying drugs? It's tough to keep track of what point you're trying to make -reply -hypeatei <relative-time> | root | parent | prev | next [–] -If your argument is that Bitcoin is only good for illicit purchases, then I sort of agree with you but there are better alternatives like Monero. Regardless, you would agree that current valuations are insane given that's the only real use-case, right? -Also infrequent purchases != storing wealth in Bitcoin. -reply systemsweird <relative-time> | prev | next [–] Very good writeup and an astonishing level of negligence for an extremely security critical piece of code. The losses are going to surpass 100 million, these guys should be thrown in jail. replyExtracted text as captured
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) 94 points by Funes- 2 days ago | hide | past | favorite | 56 comments help londons_explore 2 days ago | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... They are the perfect bug for someone trying to "accidentally" make a secure system insecure. I wonder if bribe money was involved or three letter agencies... reply dist-epoch 2 days ago | parent | next [–] And they waited 5 years to exploit it? And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. reply londons_explore 2 days ago | root | parent | next [–] Need not be the NSA. Might just be some regular thief. The longer they wait, the more they get to steal after all. reply josephg 2 days ago | root | parent | prev | next [–] > And do you think the NSA desperately needed $90 mil (the amount stolen so far) If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. reply anonymousiam 2 days ago | prev | next [–] This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. reply karamanolev 2 days ago | parent | next [–] Per the article, not my opinion. It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. reply silvestrov 2 days ago | parent | prev | next [–] When looking through all the other commits the user has made: they all lack a good commit message. This is systematic for that user. Either the user needs to improve or let go. The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. reply inigyou 2 days ago | root | parent | next [–] The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. reply anonymars 2 days ago | parent | prev | next [–] Ironic: > NEW POLICY If I don't know you, I don't merge you! Thanks XZ!Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
-
Recovered from the Internet Archive rather than captured by this project. The row records that third-party provenance separately from captures made by this project.
What changed from the previous capture 0 lines
Extracted text as captured
Hacker Newsnew | past | comments | ask | show | jobs | submitlogin When random.bytes() runs but doesn't work (btcpp.dev) 92 points by Funes- 23 hours ago | hide | past | favorite | 55 comments help londons_explore 17 hours ago | next [–] I am getting suspicious of "random number generator not actually returning random numbers" bugs.... They are the perfect bug for someone trying to "accidentally" make a secure system insecure. I wonder if bribe money was involved or three letter agencies... reply dist-epoch 15 hours ago | parent | next [–] And they waited 5 years to exploit it? And do you think the NSA desperately needed $90 mil (the amount stolen so far), so they created this elaborate backdoor? Or were they waiting until Satoshi or Binance decided to deposit a billion dollars into this wallet? All the employees which touched the code will be on watch lists now anyway. And sudden new house or yacht will be immediately flagged. reply londons_explore 15 hours ago | root | parent | next [–] Need not be the NSA. Might just be some regular thief. The longer they wait, the more they get to steal after all. reply josephg 14 hours ago | root | parent | prev | next [–] > And do you think the NSA desperately needed $90 mil (the amount stolen so far) If this was done as part of an operation, we would have no idea what it was actually used for. It’s very unlikely that the crypto wallet thefts we know about were the intended target. reply anonymousiam 20 hours ago | prev | next [–] This post assumed that the author of the "runs" commit was not acting maliciously. Has that been established? It's not mentioned in this article. reply karamanolev 17 hours ago | parent | next [–] Per the article, not my opinion. It has been established that "I didn't do it on purpose" is not enough in some cases. You have to _not do it_ _on purpose_. That "fake it till you make it", in this case, understanding what your code does, is perfectly fine in some contexts, not in others, like this one. reply silvestrov 15 hours ago | parent | prev | next [–] When looking through all the other commits the user has made: they all lack a good commit message. This is systematic for that user. Either the user needs to improve or let go. The organization needs to learn that good commit messages are a requirement for anything to do with crypto and payment systems. reply inigyou 12 hours ago | root | parent | next [–] The commit message is just a surface level manifestation of a deeper issue. Fixing the commit message does not fix the issue. reply anonymars 12 hours ago | parent | prev | next [–] Ironic: > NEW POLICY If I don't know you, I don't merge you! Thanks XZ!Excerpt only. The complete copy is held offline and backs quotations on this site. The original publication remains the canonical public source.
4 presentation-noise differences. Sidebar, ticker and other page chrome churn that our review classified as not being changes to what the source says.
- +7 -7 Only the rendered order of existing Hacker News comments changed.
- +4 -4 An existing comment moved within the captured reply ordering. No Hacker News comment text was added, edited or removed.
- +1 -1 Only the live score counter moved, from 93 to 94 points; the comment count stayed at 55 and no comment text changed.
- +20 -20 Only live counters and comment ordering changed: the story score went from 92 to 93 points and several existing comments (koolba, coldbrewed, killerstorm, smithcoin, nullc) moved to different positions. No comment text was added, removed or altered.
The excerpts and plain unified diffs above show the text this project held and how it changed. To verify a quotation, compare it against the page itself or against the Internet Archive's copies, which are independent of this project.
Complete captures are held offline rather than mirrored here, so this page shows diffs and excerpts. If a quotation is ever disputed, the full copy can be produced. Ask.
Compare the screenshot or a quotation against the original while it is available.