diff --git a/zpay32/fuzz_test.go b/zpay32/fuzz_test.go index 5b7897998..696b09c3a 100644 --- a/zpay32/fuzz_test.go +++ b/zpay32/fuzz_test.go @@ -1,6 +1,7 @@ package zpay32 import ( + "strings" "testing" "github.com/btcsuite/btcd/chaincfg" @@ -12,9 +13,44 @@ func FuzzDecode(f *testing.F) { }) } +// appendChecksum returns a string containing bech followed by its bech32 +// checksum if a checksum could be calculated. Otherwise, the function returns +// bech unchanged. +// +// This code is based on checksum calculation in zpay32/bech32.go. +func appendChecksum(bech string) string { + lower := strings.ToLower(bech) + + // The string is invalid if the last '1' is non-existent or it is the + // first character of the string (no human-readable part). + one := strings.LastIndexByte(lower, '1') + if one < 1 { + return bech + } + hrp := lower[:one] + data := lower[one+1:] + + decoded, err := toBytes(data) + if err != nil { + return bech + } + + checksum, err := toChars(bech32Checksum(hrp, decoded)) + if err != nil { + return bech + } + + return bech + checksum +} + func FuzzEncode(f *testing.F) { f.Fuzz(func(t *testing.T, data string) { - inv, err := Decode(data, &chaincfg.TestNet3Params) + // Make it easier for the fuzzer to generate valid invoice + // encodings by adding the required prefix and valid checksum. + data = "lnbc" + data + data = appendChecksum(data) + + inv, err := Decode(data, &chaincfg.MainNetParams) if err != nil { return }