Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a BIP which resolves human readable names into payment info #1551

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
118 changes: 118 additions & 0 deletions bip-XXXX.mediawiki
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<pre>
BIP: XXXX
Layer: Applications
Title: DNS Payment Instructions
Author: Matt Corallo <bipxxx@bluematt.me>
Bastien Teinturier <bastien@acinq.fr>
Comments-Summary: No comments yet.
Status: Draft
Type: Standards Track
Created: 2024-02-10
TheBlueMatt marked this conversation as resolved.
Show resolved Hide resolved
</pre>

==Abstract==
This BIP proposes a standard format for encoding [[bip-0021.mediawiki|BIP 21]] URI schemes in DNS TXT records.

==Motivation==
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be very helpful if this section was extended with a number of concrete use cases and also mention which use cases are not covered or not a good fit.

At first this seems like an interesting solution to display domain names instead of addresses on hardware wallets for improved security, but for exchanges/brokers/merchants, they'd need a unique address per user and per deposit. For this use-case this does not seem to be a good fit. Downsides / blockers could be:

  • if it is generated on the fly during e.g. a deposit action on an exchange or a shop checkout of a merchant, the TXT record might not propagate quickly enough for the lookup to succeed
  • publishing a new address after the previous one has been used also might not propagate in time to prevent re-using an address
  • bad privacy for the merchant/exchange
  • not quite sure if it is practical to have a lot of txt records for services that serve a lot of users

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if it is generated on the fly during e.g. a deposit action on an exchange or a shop checkout of a merchant, the TXT record might not propagate quickly enough for the lookup to succeed

This would violate Bitcoin wallets MUST NOT prefer to use DNS-based resolving when methods with explicit public keys are available.

publishing a new address after the previous one has been used also might not propagate in time to prevent re-using an address

That's okay. Address reuse prevention is probabilistic anyway.

bad privacy for the merchant/exchange

Hmm? If you're a merchant or exchange, you're probably already using a domain anyway :).

not quite sure if it is practical to have a lot of txt records for services that serve a lot of users

Yes, please see lightning/blips#32 and its discussion of wildcard records :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's okay. Address reuse prevention is probabilistic anyway.

.well-known approach can prevent address reuse completely, if HTTP server generates new address for every request.

Various Bitcoin and other cryptocurrency applications have developed human-readable names for payment instructions over time, with marketplace adoption signaling strong demand for it from users.

The DNS provides a standard, global, hierarchical namespace mapping human-readable labels to records of various forms. Using DNSSEC, the DNS provides cryptographic guarantees using a straightforward PKI which follows the hierarchical nature of the DNS, allowing for stateless and even offline validation of DNS records from a single trusted root.

Further, because DNS queries are generally proxied through ISP-provided or other resolvers, DNS queries usually do not directly expose the queryer's IP address. Further, because of the prevalence of open resolvers, the simplicity of the protocol, and broad availability of DNS recursive resolver implementations, finding a proxy for DNS records is trivial.

Thus, using TXT records to store Bitcoin payment instructions allows for human-readable Bitcoin payment destinations which can be trivially verified on hardware wallets and which can be resolved relatively privately.

==Specification==

=== General rules for handling ===
Bitcoin wallets MUST NOT prefer to use DNS-based resolving when methods with explicit public keys or addresses are available. In other words, if a standard Bitcoin address or direct BIP 21 URI is available or would suffice, Bitcoin wallets MUST prefer to use that instead.

=== Records ===
Payment instructions are indexed by both a user and a domain. Instructions for a given `user` and `domain` are stored at `user`.user._bitcoin-payment.`domain` in a single TXT record.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, why the leading underscore (_bitcoin-payment), is that a best practice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, just makes it less likely to collide with any existing actual domain names that exist in the wild.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand the scheme here. What is the purpose of the "user" label? (Future protocol expansions where something besides "users" can be identified?). Also why not order the labels with the underscores more like existing schemes for example, TLSA:

_443._tcp.mailhardener.com TLSA ...

So I'd expect something like:

_bitcoin-payment.matt.mattcorallo.com TXT ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pinheadmz

I'd expect something like:

_bitcoin-payment.matt.mattcorallo.com TXT ...

I'm not DNS expert, but the Wikipedia article about wildcard DNS entries says, "A wildcard DNS record is specified by using a * as the leftmost label (part) of a domain name, e.g. *.example.com." I think @TheBlueMatt wants to allow wildcards for the username portion for LN (see the proposed BIP21 parameter omlookup (onion message lookup) in this commit). If only the leftmost label can be a wildcard, then _bitcoin-payment.*.mattcorallo.com wouldn't be allowed.


All payment instructions MUST be DNSSEC-signed.

Payment instructions MAY resolve through CNAME or DNAME records as long as all such records and the ultimate records pointed to by them are DNSSEC signed.

User and domain names which are not expressible using standard printable ASCII MUST be encoded using the punycode IDN encoding defined in [[https://datatracker.ietf.org/doc/html/rfc3492|RFC 3492]] and [[https://datatracker.ietf.org/doc/html/rfc5891|RFC 5891]].
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really worth supporting (instead of restricting to ASCII characters)? This forces all clients to potentially support those encodings, which is a likely source of issues...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not, I mean punycode itself is pretty easy, but dealing with homograph attacks is...quite nontrivial. So, indeed, I'm down to just remove all the non-ASCII support.


Note that because resolvers are not required to support resolving non-ASCII identifiers, wallets SHOULD avoid using non-ASCII identifiers.

=== Resolution ===

Clients resolving Bitcoin payment instructions MUST ignore any TXT records at the same label which do not begin with (ignoring case) "bitcoin:". Resolvers encountering multiple "bitcoin:"-matching TXT records at the same label MUST treat the records as invalid and refuse to use any payment instructions therein.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When do you encounter multiple matching TXT records?

Is this due to querying twice and getting different results due to TTL?

Or a malformed TXT record: "bitcoin:........;bitcoin:......"

Or just two independent TXT records with the same key and different values?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two TXT records.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I had to guess at the rationale, this is meant to protect against the particular kind of configuration error where you intend to update the record, but mistakenly end up adding another instead. This protects against bitcoins getting sent to lost or compromised addresses.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly I didn't have a specific issue in mind more a general feeling that issues could crop up, this is a good example of one such issue.


Clients resolving Bitcoin payment instructions MUST fully validate DNSSEC signatures leading to the DNS root (including any relevant CNAME or DNAME records) and MUST NOT accept DNSSEC signatures which use SHA-1 or RSA with keys shorter than 1024 bits. Resolvers MAY accept SHA-1 DS records.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recently, a vulnerability related to DNSSEC design, KeyTrap (CVE-2023-50387), was disclosed.

https://www.athene-center.de/en/keytrap

Is this requirement not affected by this vulnerability? Isn't it necessary to consider mitigation measures that existing resolvers take?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

KeyTrap observed that validation of DNSSEC signatures can be superlinear in the number of signatures/keys. The mitigations that ~all validators have deployed addresses that, and should be used here. However, "be up to date with the latest security fixes" is a general thing and doesn't really need to be specified here :)


Clients resolving Bitcoin payment instructions MUST NOT trust a remote resolver to validate DNSSEC records on their behalf.

Clients resolving Bitcoin payment instructions MUST support resolving through CNAME or DNAME records.

Resolvers MAY support resolving non-ASCII user and domain identifiers. Resolvers which do support non-ASCII user and domain identifiers MUST take precautions to prevent homograph attacks and SHOULD consider denying paste functionality when entering non-ASCII identifiers. Wallets which do not take any such precautions MUST instead display non-ASCII user and domain identifiers using their raw punycode. As such, wallets SHOULD NOT create identifiers which are not entirely printable ASCII.

While clients MAY cache the payment instructions they receive from the DNS, clients MUST NOT cache the payment instructions received from the DNS for longer than the TTL provided by their DNS resolver, and further MUST NOT cache the payment instructions for longer than the lowest initial TTL (which is signed as a part of DNSSEC signatures) received in the full DNSSEC chain leading from the DNS root to the resolved TXT record.

=== Address Reuse ===

Payment instructions with on-chain addresses which will be re-used SHOULD be rotated as regularly as possible to reduce address reuse. Such payment instructions SHOULD also use a relatively short DNS TTL to ensure regular rotation takes effect quickly. In cases where this is not practical, payment instructions SHOULD NOT contain on-chain addresses (i.e. the URI path SHOULD be empty).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By only rotating the onchain address after receiving a payment, anyone with the human readable name can continually poll your address(es) and monitor the onchain transactions you receive.

It requires a more active attack on privacy, but still very easy.

I still think it is worthwhile to include onchain, it's nice to support any BIP21 type. But could discourage onchain in favour of silent payments / BOLT12.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still think it is worthwhile to include onchain, it's nice to support any BIP21 type. But could discourage onchain in favour of silent payments / BOLT12.

That's definitely the goal.


Payment instructions which do contain on-chain addresses which will be re-used SHOULD be rotated after any transaction to such an address is confirmed on-chain.

=== Display ===

Wallets SHOULD parse recipient information in the form `user`@`domain` or ₿`user`@`domain` and resolve such entry into recipient information using the above record. Similarly, wallets accepting payment information from external devices (e.g. hardware wallets) SHOULD accept RFC 9102-formatted proofs (as a series of unsorted `AuthenticationChain` records) and, if they verify, SHOULD display the recipient in the form ₿`user`@`domain`. For the avoidance of doubt, the ₿ is *not* included in the DNS label which is resolved.

Wallets providing users the ability to "copy" their address information generally SHOULD copy the underlying URI directly in order to avoid the DNS indirection. However, wallets providing users the ability to copy their human-readable address information MUST include the ₿ prefix (i.e. copy it in the form ₿`user`@`domain`).

== Rationale ==

=== Display ===

There are several ways in which human-readable payment instructions could be displayed in wallets. In order to ensure compatibility with existing human-readable names schemes, @ is used as the separator between the `user` and `domain` parts. However, simply using the @ separator can lead to confusion between emails on a given domain and payment instructions on a domain. In order to somewhat reduce the incidence of such confusion, a ₿ prefix is used.
TheBlueMatt marked this conversation as resolved.
Show resolved Hide resolved

=== Rotation ===

On-chain addresses which are re-used (i.e. not including schemes like Silent Payments) need to be rotated to avoid contributing substantially to address reuse. However, rotating them on a timer or any time a transaction enters the mempool could lead to substantial overhead from excess address generation. Instead, rotating addresses any time a transaction is confirmed on-chain ensures address rotation happens often while bounding the maximum number of addresses needed to one per block, which grows very slowly and will not generate an address set too large to handle while scanning the chain going forward.
TheBlueMatt marked this conversation as resolved.
Show resolved Hide resolved

=== Alternatives ===
There are many existing schemes to resolve human-readable names to cryptocurrency payment instructions. Sadly, these current schemes suffer from a myriad of drawbacks, including (a) lacking succinct proofs of namespace to public key mappings, (b) revealing sender IP addresses to recipients or other intermediaries as a side-effect of payment, (c) relying on the bloated TLS Certificate Authority infrastructure, or (d) lacking open access, not allowing anyone to create a namespace mapping.

==== DNS Rather than blockchain-based solutions ====
There are many blockchain-based alternatives to the DNS which feature better censorship-resistance and, in many cases, security. However, here we chose to use the standard ICANN-managed DNS namespace as many blockchain-based schemes suffer from (a), above (though in some cases this could be addressed with cryptographic SNARK schemes). Further, because they do not have simple client-side querying ability, many of these schemes use trusted intermediaries which resolve names on behalf of clients. This reintroduces drawbacks (b) and often (c) as well.

Finally, its worth noting that none of the blockchain-based alternatives to the DNS have had material adoption outside of their specific silos, and committing Bitcoin wallets to rely on a separate system which doesn't see broad adoption may not be sustainable.
TheBlueMatt marked this conversation as resolved.
Show resolved Hide resolved

==== DNS Rather than HTTP-based solutions ====
HTTP(s)-based payment instruction resolution protocols suffer from drawbacks (a), (b), and (c), above, and generally shouldn't be considered a serious alternative for payment instruction resolution.

==== Private DNS Querying ====
While public recursive DNS resolvers are very common (e.g. 1.1.1.1, 8.8.8.8, and 9.9.9.9), using such resolvers directly (even after validating DNSSEC signatures) introduces drawback (b), at least in regard to a centralized intermediary. Resolving payment instructions recursively locally using a resolver on the same local network or in the paying application would instead introduce drawback (b) directly to the recipient, which may well be worse.

For payers not using VPN or other proxying technologies, they generally trust their ISP to not snoop on their DNS requests anyway, so using ISP-provided recursive DNS resolvers is likely the best option.

However, for the best privacy, payers are encouraged to perform DNS resolution over Tor or another VPN technology.

Lightning payers should consider utilizing DNS resolution over native onion messages, using the protocol described in [[BLIP 32|https://github.com/lightning/blips/blob/master/blip-0032.md]]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File not found

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that's because Matt used the link that will work once that bLIP is merged, since we expect bLIPs to be merged more quickly than BIPs :)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned above the page is 404, but also in mediawiki format, links are encoded [[url|name]] instead of [[name|url]].

Suggested change
Lightning payers should consider utilizing DNS resolution over native onion messages, using the protocol described in [[BLIP 32|https://github.com/lightning/blips/blob/master/blip-0032.md]]
Lightning payers should consider utilizing DNS resolution over native onion messages, using the protocol described in [[https://github.com/lightning/blips/blob/master/blip-0032.md|BLIP 32]]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make sure it gets merged before this does :)


=== DNS Enumeration ===

In most cases where payments are accepted from any third-party, user enumeration is practical by simply attempting to send small value payments to a list of possible user names. However, storing all valid users in the DNS directly may make such enumeration marginally more practical. Thus, those wishing to avoid such enumeration should carefully ensure all DNS names return valid payment instructions. Note when doing so that wildcard records are identified as such by the DNSSEC RRSIG labels counter and are differentiable from non-wildcard records.

== Examples ==

`matt@mattcorallo.com` resolves to
`matt.user._bitcoin-payment.mattcorallo.com. 3600 IN TXT "bitcoin:?lno=lno1qsgqmqvgm96frzdg8m0gc6nzeqffvzsqzrxqy32afmr3jn9ggkwg3egfwch2hy0l6jut6vfd8vpsc3h89l6u3dm4q2d6nuamav3w27xvdmv3lpgklhg7l5teypqz9l53hj7zvuaenh34xqsz2sa967yzqkylfu9xtcd5ymcmfp32h083e805y7jfd236w9afhavqqvl8uyma7x77yun4ehe9pnhu2gekjguexmxpqjcr2j822xr7q34p078gzslf9wpwz5y57alxu99s0z2ql0kfqvwhzycqq45ehh58xnfpuek80hw6spvwrvttjrrq9pphh0dpydh06qqspp5uq4gpyt6n9mwexde44qv7lstzzq60nr40ff38u27un6y53aypmx0p4qruk2tf9mjwqlhxak4znvna5y"`
Note that `lno` indicates a value containing a lightning BOLT12 offer.

== Reference Implementations ==
* A DNSSEC proof generation and validation implementation can be found at https://git.bitcoin.ninja/index.cgi?p=dnssec-prover;a=summary
* A lightning-specific name to payment instruction resolver can be found at https://git.bitcoin.ninja/index.cgi?p=lightning-resolver;a=summary
* Reference implementations for parsing the URI contents can be found in [[bip-0021.mediawiki|BIP 21]].

== Acknowledgements ==

Thanks to Rusty Russell for the concrete address rotation suggestion.

Thanks to the Bitcoin Design Community, and especially Christoph Ono for lots of discussion, analysis, and UX mockups in how human-readable payment instructions should be displayed.

Thanks to Andrew Kaizer for the suggestion to explicitly restrict cache lifetime to the relevant DNS TTLs.