github.com/decred/dcrlnd@v0.7.6/zpay32/decode.go (about) 1 package zpay32 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "strings" 8 "time" 9 10 "github.com/decred/dcrd/bech32" 11 "github.com/decred/dcrd/chaincfg/chainhash" 12 "github.com/decred/dcrd/chaincfg/v3" 13 "github.com/decred/dcrd/dcrec/secp256k1/v4" 14 "github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa" 15 "github.com/decred/dcrd/txscript/v4/stdaddr" 16 17 "github.com/decred/dcrlnd/lnwire" 18 ) 19 20 // Decode parses the provided encoded invoice and returns a decoded Invoice if 21 // it is valid by BOLT-0011 and matches the provided active network. 22 func Decode(invoice string, net *chaincfg.Params) (*Invoice, error) { 23 decodedInvoice := Invoice{} 24 25 // Before bech32 decoding the invoice, make sure that it is not too large. 26 // This is done as an anti-DoS measure since bech32 decoding is expensive. 27 if len(invoice) > maxInvoiceLength { 28 return nil, ErrInvoiceTooLarge 29 } 30 31 // Decode the invoice using the modified bech32 decoder. 32 hrp, data, err := bech32.DecodeNoLimit(invoice) 33 if err != nil { 34 return nil, err 35 } 36 37 // We expect the human-readable part to at least have ln + one char 38 // encoding the network. 39 if len(hrp) < 3 { 40 return nil, fmt.Errorf("hrp too short") 41 } 42 43 // First two characters of HRP should be "ln". 44 if hrp[:2] != "ln" { 45 return nil, fmt.Errorf("prefix should be \"ln\"") 46 } 47 48 // The next characters should be a valid prefix for a segwit BIP173 49 // address that match the active network. 50 if !strings.HasPrefix(hrp[2:], decredHRPPrefixes[net.Name]) { 51 return nil, fmt.Errorf( 52 "invoice not for current active network '%s'", net.Name) 53 } 54 decodedInvoice.Net = net 55 56 // Optionally, if there's anything left of the HRP after ln + the segwit 57 // prefix, we try to decode this as the payment amount. 58 hrpNet := decredHRPPrefixes[net.Name] 59 var netPrefixLength = len(hrpNet) + 2 60 if len(hrp) > netPrefixLength { 61 amount, err := decodeAmount(hrp[netPrefixLength:]) 62 if err != nil { 63 return nil, err 64 } 65 decodedInvoice.MilliAt = &amount 66 } 67 68 // Everything except the last 520 bits of the data encodes the invoice's 69 // timestamp and tagged fields. 70 invoiceData := data[:len(data)-signatureBase32Len] 71 72 // Parse the timestamp and tagged fields, and fill the Invoice struct. 73 if err := parseData(&decodedInvoice, invoiceData, net); err != nil { 74 return nil, err 75 } 76 77 // The last 520 bits (104 groups) make up the signature. 78 sigBase32 := data[len(data)-signatureBase32Len:] 79 sigBase256, err := bech32.ConvertBits(sigBase32, 5, 8, true) 80 if err != nil { 81 return nil, err 82 } 83 var sig lnwire.Sig 84 copy(sig[:], sigBase256[:64]) 85 recoveryID := sigBase256[64] 86 87 // The signature is over the hrp + the data the invoice, encoded in 88 // base 256. 89 taggedDataBytes, err := bech32.ConvertBits(invoiceData, 5, 8, true) 90 if err != nil { 91 return nil, err 92 } 93 94 toSign := append([]byte(hrp), taggedDataBytes...) 95 96 // We expect the signature to be over the single SHA-256 hash of that 97 // data. 98 hash := chainhash.HashB(toSign) 99 100 // If the destination pubkey was provided as a tagged field, use that 101 // to verify the signature, if not do public key recovery. 102 if decodedInvoice.Destination != nil { 103 signature, err := sig.ToSignature() 104 if err != nil { 105 return nil, fmt.Errorf("unable to deserialize "+ 106 "signature: %v", err) 107 } 108 if !signature.Verify(hash, decodedInvoice.Destination) { 109 return nil, fmt.Errorf("invalid invoice signature") 110 } 111 } else { 112 headerByte := recoveryID + 27 + 4 113 compactSign := append([]byte{headerByte}, sig[:]...) 114 pubkey, _, err := ecdsa.RecoverCompact(compactSign, hash) 115 if err != nil { 116 return nil, err 117 } 118 decodedInvoice.Destination = pubkey 119 } 120 121 // If no feature vector was decoded, populate an empty one. 122 if decodedInvoice.Features == nil { 123 decodedInvoice.Features = lnwire.NewFeatureVector( 124 nil, lnwire.Features, 125 ) 126 } 127 128 // Now that we have created the invoice, make sure it has the required 129 // fields set. 130 if err := validateInvoice(&decodedInvoice); err != nil { 131 return nil, err 132 } 133 134 return &decodedInvoice, nil 135 } 136 137 // parseData parses the data part of the invoice. It expects base32 data 138 // returned from the bech32.Decode method, except signature. 139 func parseData(invoice *Invoice, data []byte, net *chaincfg.Params) error { 140 // It must contain the timestamp, encoded using 35 bits (7 groups). 141 if len(data) < timestampBase32Len { 142 return fmt.Errorf("data too short: %d", len(data)) 143 } 144 145 t, err := parseTimestamp(data[:timestampBase32Len]) 146 if err != nil { 147 return err 148 } 149 invoice.Timestamp = time.Unix(int64(t), 0) 150 151 // The rest are tagged parts. 152 tagData := data[7:] 153 return parseTaggedFields(invoice, tagData, net) 154 } 155 156 // parseTimestamp converts a 35-bit timestamp (encoded in base32) to uint64. 157 func parseTimestamp(data []byte) (uint64, error) { 158 if len(data) != timestampBase32Len { 159 return 0, fmt.Errorf("timestamp must be 35 bits, was %d", 160 len(data)*5) 161 } 162 163 return base32ToUint64(data) 164 } 165 166 // parseTaggedFields takes the base32 encoded tagged fields of the invoice, and 167 // fills the Invoice struct accordingly. 168 func parseTaggedFields(invoice *Invoice, fields []byte, net *chaincfg.Params) error { 169 index := 0 170 for len(fields)-index > 0 { 171 // If there are less than 3 groups to read, there cannot be more 172 // interesting information, as we need the type (1 group) and 173 // length (2 groups). 174 // 175 // This means the last tagged field is broken. 176 if len(fields)-index < 3 { 177 return ErrBrokenTaggedField 178 } 179 180 typ := fields[index] 181 dataLength, err := parseFieldDataLength(fields[index+1 : index+3]) 182 if err != nil { 183 return err 184 } 185 186 // If we don't have enough field data left to read this length, 187 // return error. 188 if len(fields) < index+3+int(dataLength) { 189 return ErrInvalidFieldLength 190 } 191 base32Data := fields[index+3 : index+3+int(dataLength)] 192 193 // Advance the index in preparation for the next iteration. 194 index += 3 + int(dataLength) 195 196 switch typ { 197 case fieldTypeP: 198 if invoice.PaymentHash != nil { 199 // We skip the field if we have already seen a 200 // supported one. 201 continue 202 } 203 204 invoice.PaymentHash, err = parse32Bytes(base32Data) 205 case fieldTypeS: 206 if invoice.PaymentAddr != nil { 207 // We skip the field if we have already seen a 208 // supported one. 209 continue 210 } 211 212 invoice.PaymentAddr, err = parse32Bytes(base32Data) 213 case fieldTypeD: 214 if invoice.Description != nil { 215 // We skip the field if we have already seen a 216 // supported one. 217 continue 218 } 219 220 invoice.Description, err = parseDescription(base32Data) 221 case fieldTypeN: 222 if invoice.Destination != nil { 223 // We skip the field if we have already seen a 224 // supported one. 225 continue 226 } 227 228 invoice.Destination, err = parseDestination(base32Data) 229 case fieldTypeH: 230 if invoice.DescriptionHash != nil { 231 // We skip the field if we have already seen a 232 // supported one. 233 continue 234 } 235 236 invoice.DescriptionHash, err = parse32Bytes(base32Data) 237 case fieldTypeX: 238 if invoice.expiry != nil { 239 // We skip the field if we have already seen a 240 // supported one. 241 continue 242 } 243 244 invoice.expiry, err = parseExpiry(base32Data) 245 case fieldTypeC: 246 if invoice.minFinalCLTVExpiry != nil { 247 // We skip the field if we have already seen a 248 // supported one. 249 continue 250 } 251 252 invoice.minFinalCLTVExpiry, err = parseMinFinalCLTVExpiry(base32Data) 253 case fieldTypeF: 254 if invoice.FallbackAddr != nil { 255 // We skip the field if we have already seen a 256 // supported one. 257 continue 258 } 259 260 invoice.FallbackAddr, err = parseFallbackAddr(base32Data, net) 261 case fieldTypeR: 262 // An `r` field can be included in an invoice multiple 263 // times, so we won't skip it if we have already seen 264 // one. 265 routeHint, err := parseRouteHint(base32Data) 266 if err != nil { 267 return err 268 } 269 270 invoice.RouteHints = append(invoice.RouteHints, routeHint) 271 case fieldType9: 272 if invoice.Features != nil { 273 // We skip the field if we have already seen a 274 // supported one. 275 continue 276 } 277 278 invoice.Features, err = parseFeatures(base32Data) 279 default: 280 // Ignore unknown type. 281 } 282 283 // Check if there was an error from parsing any of the tagged 284 // fields and return it. 285 if err != nil { 286 return err 287 } 288 } 289 290 return nil 291 } 292 293 // parseFieldDataLength converts the two byte slice into a uint16. 294 func parseFieldDataLength(data []byte) (uint16, error) { 295 if len(data) != 2 { 296 return 0, fmt.Errorf("data length must be 2 bytes, was %d", 297 len(data)) 298 } 299 300 return uint16(data[0])<<5 | uint16(data[1]), nil 301 } 302 303 // parse32Bytes converts a 256-bit value (encoded in base32) to *[32]byte. This 304 // can be used for payment hashes, description hashes, payment addresses, etc. 305 func parse32Bytes(data []byte) (*[32]byte, error) { 306 var paymentHash [32]byte 307 308 // As BOLT-11 states, a reader must skip over the 32-byte fields if 309 // it does not have a length of 52, so avoid returning an error. 310 if len(data) != hashBase32Len { 311 return nil, nil 312 } 313 314 hash, err := bech32.ConvertBits(data, 5, 8, false) 315 if err != nil { 316 return nil, err 317 } 318 319 copy(paymentHash[:], hash) 320 321 return &paymentHash, nil 322 } 323 324 // parseDescription converts the data (encoded in base32) into a string to use 325 // as the description. 326 func parseDescription(data []byte) (*string, error) { 327 base256Data, err := bech32.ConvertBits(data, 5, 8, false) 328 if err != nil { 329 return nil, err 330 } 331 332 description := string(base256Data) 333 334 return &description, nil 335 } 336 337 // parseDestination converts the data (encoded in base32) into a 33-byte public 338 // key of the payee node. 339 func parseDestination(data []byte) (*secp256k1.PublicKey, error) { 340 // As BOLT-11 states, a reader must skip over the destination field 341 // if it does not have a length of 53, so avoid returning an error. 342 if len(data) != pubKeyBase32Len { 343 return nil, nil 344 } 345 346 base256Data, err := bech32.ConvertBits(data, 5, 8, false) 347 if err != nil { 348 return nil, err 349 } 350 351 return secp256k1.ParsePubKey(base256Data) 352 } 353 354 // parseExpiry converts the data (encoded in base32) into the expiry time. 355 func parseExpiry(data []byte) (*time.Duration, error) { 356 expiry, err := base32ToUint64(data) 357 if err != nil { 358 return nil, err 359 } 360 361 duration := time.Duration(expiry) * time.Second 362 363 return &duration, nil 364 } 365 366 // parseMinFinalCLTVExpiry converts the data (encoded in base32) into a uint64 367 // to use as the minFinalCLTVExpiry. 368 func parseMinFinalCLTVExpiry(data []byte) (*uint64, error) { 369 expiry, err := base32ToUint64(data) 370 if err != nil { 371 return nil, err 372 } 373 374 return &expiry, nil 375 } 376 377 // parseFallbackAddr converts the data (encoded in base32) into a fallback 378 // on-chain address. 379 func parseFallbackAddr(data []byte, net *chaincfg.Params) (stdaddr.Address, error) { 380 // Checks if the data is empty or contains a version without an address. 381 if len(data) < 2 { 382 return nil, fmt.Errorf("empty fallback address field") 383 } 384 385 var addr stdaddr.Address 386 387 version := data[0] 388 switch version { 389 case 0: 390 return nil, fmt.Errorf("witness program addresses not supported") 391 case 17: 392 pubKeyHash, err := bech32.ConvertBits(data[1:], 5, 8, false) 393 if err != nil { 394 return nil, err 395 } 396 397 addr, err = stdaddr.NewAddressPubKeyHashEcdsaSecp256k1V0(pubKeyHash, net) 398 if err != nil { 399 return nil, err 400 } 401 case 18: 402 scriptHash, err := bech32.ConvertBits(data[1:], 5, 8, false) 403 if err != nil { 404 return nil, err 405 } 406 407 addr, err = stdaddr.NewAddressScriptHashV0FromHash(scriptHash, net) 408 if err != nil { 409 return nil, err 410 } 411 default: 412 // Ignore unknown version. 413 } 414 415 return addr, nil 416 } 417 418 // parseRouteHint converts the data (encoded in base32) into an array containing 419 // one or more routing hop hints that represent a single route hint. 420 func parseRouteHint(data []byte) ([]HopHint, error) { 421 base256Data, err := bech32.ConvertBits(data, 5, 8, false) 422 if err != nil { 423 return nil, err 424 } 425 426 // Check that base256Data is a multiple of hopHintLen. 427 if len(base256Data)%hopHintLen != 0 { 428 return nil, fmt.Errorf("expected length multiple of %d bytes, "+ 429 "got %d", hopHintLen, len(base256Data)) 430 } 431 432 var routeHint []HopHint 433 434 for len(base256Data) > 0 { 435 hopHint := HopHint{} 436 hopHint.NodeID, err = secp256k1.ParsePubKey(base256Data[:33]) 437 if err != nil { 438 return nil, err 439 } 440 hopHint.ChannelID = binary.BigEndian.Uint64(base256Data[33:41]) 441 hopHint.FeeBaseMAtoms = binary.BigEndian.Uint32(base256Data[41:45]) 442 hopHint.FeeProportionalMillionths = binary.BigEndian.Uint32(base256Data[45:49]) 443 hopHint.CLTVExpiryDelta = binary.BigEndian.Uint16(base256Data[49:51]) 444 445 routeHint = append(routeHint, hopHint) 446 447 base256Data = base256Data[51:] 448 } 449 450 return routeHint, nil 451 } 452 453 // parseFeatures decodes any feature bits directly from the base32 454 // representation. 455 func parseFeatures(data []byte) (*lnwire.FeatureVector, error) { 456 rawFeatures := lnwire.NewRawFeatureVector() 457 err := rawFeatures.DecodeBase32(bytes.NewReader(data), len(data)) 458 if err != nil { 459 return nil, err 460 } 461 462 return lnwire.NewFeatureVector(rawFeatures, lnwire.Features), nil 463 } 464 465 // base32ToUint64 converts a base32 encoded number to uint64. 466 func base32ToUint64(data []byte) (uint64, error) { 467 // Maximum that fits in uint64 is ceil(64 / 5) = 12 groups. 468 if len(data) > 13 { 469 return 0, fmt.Errorf("cannot parse data of length %d as uint64", 470 len(data)) 471 } 472 473 val := uint64(0) 474 for i := 0; i < len(data); i++ { 475 val = val<<5 | uint64(data[i]) 476 } 477 return val, nil 478 }