Differential Fuzzing of Bitcoin implementations


We recently added support for btcd and we discovered and could reproduce more bugs.

rust-miniscript: Some miniscripts were unexpectedly being rejected

rust-bitcoin: During witness verification, rust-bitcoin doesn’t check if a transaction has the witness flag but empty witnesses.

btcd: Not a bug but an API mismatch with Bitcoin Core. When decoding a transaction, Bitcoin Core fails if the input was not entirely consumed, btcd doesn’t.

Bitcoin Core/rust-miniscript: When validating miniscripts from string, there is an inconsistence between rust-miniscript and Bitcoin Core. We noticed that Bitcoin Core accepts the usage of the + sign, e.g. (l:older(+1) , u:after(+1) ), because of ParseInt64 function. However, rust-miniscript checks the character itself, so it only accepts “1”, “2”, “3”…“9”.

rust-miniscript: The parser function is still recursive while Core isn’t anymore. It makes some miniscripts valid for Core but rejected by rust-miniscript due to the max recursion depth. (We didn’t find this, we just could reproduce by running the harness with the seed corpus from Core)