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  }