Broken libraries

Todays newsletter continues with chapter 4 from Bitcoin: A Work in Progress.

libsecp256k1 and software libraries

Last week we explained why including libraries in the software download can be a good idea.

But even when libraries are included in a download, things can go wrong when a software developer decides to update a library to a newer version.

Someone out there is maintaining the library. They don’t have time to test each of their changes in every single software package out there that uses their library. So if you’re not paying attention to what the library maintainer is doing — either by looking at changes in the release notes or by checking out the code itself — they might break something.

Then, when you download the library along with the rest of Bitcoin Core, your computer now uses that changed part of the library. But what if the Bitcoin Core developers didn’t notice this particular change that happened to the library? Then, all of a sudden, the stuff they wanted Bitcoin Core to do isn’t actually happening.

Most breaking changes in libraries are accidents, but not all. Chapter 9 about Guix goes deeper into the process of checking dependencies and attacks from rogue dependency maintainers.

A breaking change in how a library behaves is particularly problematic when it causes a change in the interpretation of the rules of the blockchain: Bitcoin Core would consider a particular block valid in one version of the library, and in another version, it’d consider that same block invalid. This leads to a chain split.

This is exactly what happened with a past version of Bitcoin Core: There was a bug in OpenSSL, which meant the developers of Bitcoin Core had to upgrade OpenSSL because the old version was simply no longer safe. But unbeknownst to the Core developers, there was another change in OpenSSL when they upgraded.

This particular change dealt with what happened with signatures and whether or not they’re considered valid. The original version of OpenSSL was pretty relaxed, so it would accept signatures as valid even if they didn’t meet the exact specifications. They couldn’t be signed by somebody else, so it wasn’t about stealing funds, but it was more about the fact that the notation could be a bit sloppy.

Now, the new version was extremely picky. If you used Bitcoin software to create a transaction, that wasn’t a problem, because any Bitcoin transaction was signed strictly, according to the protocol. And if you decided to validate these transactions using old software, it would see the sloppy version that was also made with the old software, and it wouldn’t have an issue with the transaction. However, the new software would say it’s invalid, because it doesn’t accept these sloppy signatures. So all of a sudden, there’s an accidental soft fork, which is what happens when previously valid transactions become invalid.

Fortunately, some developers became aware of this problem in time. Had they not noticed this, there could’ve been a big chain split once the updated OpenSSL library was bundled in a Bitcoin Core release binary. Instead, several measures were taken to defuse this timebomb. We’ll cover those next week.