BIP 353 Resolution and PSBT Inclusion
Now that BIP 353 DNSSEC proofs are formally defined in PSBT outputs, wallets can start doing Human Readable Name resolutions and providing that info to Hardware Wallets in a way they can validate and display, massively improving security when compared to the normal UX of a user comparing what's on their screen to what the Hardware Wallet displays (which accomplishes nothing against most malware lol).
Should be fairly straightforward to add since the data is self-authenticating, might just take a dependency on https://docs.rs/dnssec-prover/latest/dnssec_prover/to do the DNS resolution and build a proof (eg by connection to 8.8.8.8:53 over Tor). Might also be nice to store the proof with other transaction metadata as it represents "proof of payment".
I've been reluctant to support this for standard on-chain addresses because of potential address reuse/gap limit issues, as it's not possible to match the timeframe of DNS updates to address usage. If I've misunderstood this, please let me know.
While it can't be perfect, it's totally possible to do as well as is reasonable - assuming a smart server, it can rotate any time it sees the address it is serving used on-chain. While you may get two payments back-to-back and end up reusing addresses, I'm not convinced it's common enough to matter.
More generally, however, I don't think we should let perfect be the enemy of the good here - if a receiver wants to reuse addresses, they're going to whether it's in a 353 or not, so supporting the sending side I don't buy is gonna drive a lot of address reuse. The "donation" and "P2P payments" use cases of bitcoin have largely moved to lightning at this point, with on chain being used for savings and moving funds into an exchange to sell.
In that specific use-case, exchanges currently strongly encourage a fixed address for security reasons (so users who deposit regularly can verify the address with test deposits and compare against previous addresses). With 353, they instead have a good way to rotate addresses while retaining the same security properties they care about.
There will no doubt be cases where 353 drives some address reuse (though of course the ability to opportunistically switch to silent payments will help) but there will also hopefully be cases where the opposite is true, especially once we get hardware wallet adoption.
Fair points, there are cases where address reuse may be decreased as you suggest.
I am finding the new BIP174 field BIP 353 DNSSEC proof to be little unclear as to what exactly should be included or not. Can you verify that the following represents the minimum/canonical list of records required to provide the RFC9102 proof for your HRN of [email protected]? I am excluding the NSEC3 and SOA records, but including the root records.
matt.user._bitcoin-payment.mattcorallo.com. 3497 IN TXT "bitcoin:bc1qztwy6xen3zdtt7z0vrgapmjtfz8acjkfp5fp7l?lno=lno1zr5qyugqgskrk70kqmuq7v3dnr2fnmhukps9n8hut48vkqpqnskt2svsqwjakp7k6pyhtkuxw7y2kqmsxlwruhzqv0zsnhh9q3t9xhx39suc6qsr07ekm5esdyum0w66mnx8vdquwvp7dp5jp7j3v5cp6aj0w329fnkqqv60q96sz5nkrc5r95qffx002q53tqdk" "8x9m2tmt85jtpmcycvfnrpx3lr45h2g7na3sec7xguctfzzcm8jjqtj5ya27te60j03vpt0vq9tm2n9yxl2hngfnmygesa25s4u4zlxewqpvp94xt7rur4rhxunwkthk9vly3lm5hh0pqv4aymcqejlgssnlpzwlggykkajp7yjs5jvr2agkyypcdlj280cy46jpynsezrcj2kwa2lyr8xvd6lfkph4xrxtk2xc3lpq"
matt.user._bitcoin-payment.mattcorallo.com. 3497 IN RRSIG TXT 13 5 3600 20250726050200 20250712033200 42773 mattcorallo.com. 5jGA8jrWaN6SIlF4ZgdtkfT5Bw6rToZrks4Tq/03T4gpCNfAzsk7yrghn6QZ7/Y5kQ1AJvBpqLJ3gwFUPYQQFw==
mattcorallo.com. 19980 IN DNSKEY 257 3 13 7HwfoXUklcQtIiTqzpbtdBROnLgRYI3ZFZSXS9xyP9xbOKN8M0Dx3spop+yCJIgilUsplN5ayZ/26duV/ULJSw==
mattcorallo.com. 19980 IN DNSKEY 256 3 13 /Z28NMtQU6LEprPQ3GD8ZdipktweCA9t7t26f+ayUhdzDeZMmhzphrP4H1Vogf4Oe1sgyK44HE/v28MRqn0i7g==
mattcorallo.com. 19980 IN RRSIG DNSKEY 13 2 604800 20250729070202 20250715053202 58101 mattcorallo.com. xO1XmpKZCAuvSgnr2pM2YVh/UD/WX8wQpk2lO9zY87JvH+cDhNSflJIT5d6iVqsklw94CmUgu7w/iLiUYVvr0A==
mattcorallo.com. 18827 IN DS 58101 13 2 F0E161567D468087FF27B051ABC94476178A7CB635DA1AA705E05C77CA81DE52
mattcorallo.com. 18827 IN DS 40704 13 2 594D2813E04A1D2660FF3C0AFC5579B9EC0FE72CC206DC6F248BBE6DD652E195
mattcorallo.com. 18827 IN RRSIG DS 13 2 86400 20250723020521 20250716005521 20545 com. GhW9lS7DOKICtl2V/X6hCIUNFiiKsx+AH3ogmoLkaOECh4LJ3jovzHeXS5O9s0SQrYUHUcDuEYz3urJXSewCbw==
com. 1894 IN DNSKEY 256 3 13 8Xtg+1bVIvhjQVPnhcCpeFMup23jnTS7NW09BC4H8p97mSF2zIOs73t46nUEJSA7GPK4Ios83SvH6xPD4wNafg==
com. 1894 IN DNSKEY 256 3 13 /L1iK7+vk9/xnk/lIfYbxgKsMts1KA09X/hNRRqolimHaVj9W+Qng/+irvLjbkyRKENf00mzPzGvNLRrDTTMqw==
com. 1894 IN DNSKEY 257 3 13 tx8EZRAd2+K/DJRV0S+hbBzaRPS/G6JVNBitHzqpsGlz8huE61Ms9ANe6NSDLKJtiTBqfTJWDAywEp1FCsEINQ==
com. 1894 IN RRSIG DNSKEY 13 1 86400 20250726140235 20250711135735 19718 com. HP6Rma/CdLpiUjmBYHvmY2MvxuQGn4s+07paVQ2E08SDwzbuJWLQ6oJrxW43jmorCJraqYJPP5jRbMbj2wP5ww==
com. 38486 IN DS 19718 13 2 8ACBB0CD28F41250A80A491389424D341522D946B0DA0C0291F2D3D771D7805A
com. 38486 IN RRSIG DS 8 1 86400 20250729200000 20250716190000 46441 . PkCG9DvT4t+PTaOBfEpTqVmJIbpLMMvQeIUDDGJPi75wCRSnr0gqzzZGRMkNJ8QZrZ0OjiEDUp9zrpPcSjAHYclr1PYMMNtI0wq9XovCPIrR9pIDZF67Nzp6EgDmbKr3Ccj/gj/WoHQNtGJK2jZcom5hksD3T3z97edh8lcHA97+h+qX6mrbtNvmBlN9qjSK7iqDtgOaT2OQc+a5RjbH4gJFCRT+3+gCj935AR73/yXWsWc7Ae8xCpwGuriO0hD7f6HBoJh4ZmdMniiXOXtCnhiGHjVrWysBBczzCkSWkg+Tn+uij/7+xDTOYbndUrwK8sR+RxqnAHrYd+ifxKezzg==
. 81892 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=
. 81892 IN DNSKEY 256 3 8 AwEAAbauxLSFZ+KSWi2cT6TJbm3d+GIVqb2N1XnDjMsRme0b6JlGp/cvwmM5CaJ5LQ7tG1r7LuTHjYZadtbNk2nZmclq9r4KInS48ungoAZb0gJXVw8IvBTBb1YWQmiBqD285pJuORwTii7DF++nNJJk3i55HJt9SmBI7m7t8nvx7OOY/w0inxg3fLH2uY0SKO8he4FGwMc4Ubiab8N8Yhyhh+FkKKdD/+oAcuGF75PjlSXO460B4MlNLlEcjDEzIsKauRYx4YVgSaNomGhMMFblmXRzgW+1R6ywvm5mC9+omlyyizZp2GJfPwGMezuKSGDndO6CYYEc5/lsRhvBYsGjdPM=
. 81892 IN DNSKEY 256 3 8 AwEAAbEbGCpGTDrcZTWqWWE72nphyshpRcILdzCVlBGU9Ln1Fui9kkseUOP+g5GLUeVFKdTloeRTA9+EYiQdXgWXmXmuW/nGxZjAikluF/O9NzLVrr5iZnth2xu+F48nrJlAgWWiMNau54NI5sZ3iVQfhFsq2pZmf43RauRPniYMShOLO7EBWWXr5glDSgZGS9fSm6xHwwF+g8D4m8oanjvdCBNxXzSEKS31ibxjLifTfvwCg3y4XXcNW9U6Nu3JmoKUdxqpPPIkBvVQbIz4UO2FwaR13uXC03ALP1Yx2QNSS4SZlcIMtAftQR9wtCiuPWQnFv4jkzWqlhp1Lmf7bcoL9yk=
. 81892 IN DNSKEY 257 3 8 AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc=
. 81892 IN RRSIG DNSKEY 8 0 172800 20250801000000 20250711000000 20326 . WwWSfJzdfRVlUhGNEnrahgVWN54iU6fIm3g0XhxC1f3yxbK7s1iQFZpKwJ0xNQkBeBFA0/sb7N4DnZVn1gdF9F8oOQ5sDllyjewNoDjAgtyN+inLgl9Ta/aK1Tn183K0P0jevWG8MmbIC8TCmbv/SvyDTZK3BIMsQ+HGu8jloGYgIgbliKrG14GtXcF2jcjLFaIT7J1j1pO1ErcUrgd7hmfEC9emCZbDuQAtRQ+mWJL9NNTj6RToAUxA8sI4kEgrslBAzzc6co7TbhediJ/2ya1in+nLTCBHV53oL1JGITWaGwMflcDwQEkWFJ0dRxhNDkKvuDCRz3VnPaAkDPLrbA==
That is correct for this name, but you can't universally exclude NSEC3/NSEC records, they may be needed in cases where you hit a wildcard. There's a pretty good set of tests at https://git.bitcoin.ninja/?p=dnssec-prover;a=blob;f=src/validation.rs;h=6417f0945e8ee9f213d36df2c767935d5c5676e5;hb=HEAD
There's also logic to build a proof you can crib from at https://git.bitcoin.ninja/?p=dnssec-prover;a=blob;f=src/query.rs;h=cd7fe6a01a4be19858310f9b55a3d435daa9cfb4;hb=HEAD
Implemented in https://github.com/sparrowwallet/drongo/commit/58cc096f8e5a1274945a252907100c1dc051a996 and 5f625237.
BIP353 HRNs can be entered into the Pay to field, and if they resolve correctly will be accepted as a valid address. If the label is empty, it will default to To <HRN>. The HRNs are displayed in the transaction diagram tooltip and diagram label during the transaction creation and signing process, and the DNSSEC proof is included in the associated PSBT. Once broadcast, the HRN will be saved as part of the transaction, address and UTXO labels if the user has left it included.
@TheBlueMatt I'm happy to provide a pre-release build for testing, let me know what OS and arch you're on.
Nice! I could test a Linux/x64 build.
Thanks, here you go: https://github.com/craigraw/beta/releases/tag/2.2.4-bip353
Ah, I guess its a bit hard for me to test without funds in a sparrow wallet 😅 . I hacked up a quick and dirty tester at https://satsto.me/prooftest.html which you can use to test the proofs you generate are compatible with my validator, though. Just paste in the HRN and the hex of the DNSSEC proof (as you'd pass it to a PSBT, just with the the HRN prefix separated into the other box).
It also has two example names which you should probably test explicitly as they rely on wildcards and inclusion of NSECs in the proof.
Thanks for the tool, very useful. I've made some fixes in https://github.com/sparrowwallet/drongo/commit/056d5f83a6296ad8f673066ea9dbc68972a183e9 to improve handling of CNAMEs and wildcards, and tested that the example names validate against the resolved DNSSEC proofs both in your tool and in drongo's own unit tests.
I think this issue can now be closed, unless there are other test cases to be verified?
Nice! I think those are the ones that are most likely to be broken (they test many of the edge-cases - cross-TLD linking, wilcards, and NSEC inclusion), as long as those (and, of course, simple cases) work I'd agree this can be closed 🎉
Thanks, good to hear!
A couple of comments from my side:
- I often felt while working on this that "BIP 353 HRNs" need a better name. The obvious is "bitcoin address" but that's already widely used for normal onchain addresses. I'm not sure what the answer is, but it's worth thinking about IMO.
- Having some example test cases in the BIP would probably help with adoption. By test cases I mean providing the HRN, hex proof and date of retrieval, especially for the edge cases.
- BIP 353 HRNs may be a good addition to BIP 329 in a new field for the
outputtyped records.
I often felt while working on this that "BIP 353 HRNs" need a better name. The obvious is "bitcoin address" but that's already widely used for normal onchain addresses. I'm not sure what the answer is, but it's worth thinking about IMO.
There's a page dedicated to this on the Bitcoin Design Guide, which seems like the appropriate place for such a discussion. https://bitcoin.design/guide/how-it-works/human-readable-addresses/
Having some example test cases in the BIP would probably help with adoption. By test cases I mean providing the HRN, hex proof and date of retrieval, especially for the edge cases.
Honestly I expected most wallets to just use my rust resolver and not bother trying to implement DNS stuff by hand :). But indeed, I can try to make the tester page cleaner and link it from the BIP. Proof validation is a little harder to test because an implementation can happily ignore things like the missing NSEC and consider a proof valid even though its not, so I'll have to put some effort into that.
BIP 353 HRNs may be a good addition to BIP 329 in a new field for the output typed records.
IMO any such export should include the DNSSEC proof as well. One surprising UX gotcha of 353 is that a txid is no longer sufficient "proof of payment", you now need the DNSSEC proof as well. Of course, a 353 proof of payment is much stronger than a simple txid (the merchant/recipient can't claim that the address wasn't theirs, eg in the case of a hack now you can squarely lay blame at the sender or recipient, which is nice), but you really need the DNSSEC proof to get there.
There's a page dedicated to this on the Bitcoin Design Guide, which seems like the appropriate place for such a discussion.
I couldn't find a place to discuss it there, but I propose Bitcoin Readable Address (BRA).
Honestly I expected most wallets to just use my rust resolver and not bother trying to implement DNS stuff by hand :).
I try to avoid non-Java dependencies these days :) For HWW adoption, I suspect a MicroPython implementation is going to be necessary.
One surprising UX gotcha of 353 is that a txid is no longer sufficient "proof of payment", you now need the DNSSEC proof as well.
I'm not sure that a txid was ever a "proof of payment" without checking the address it sends to is yours, but probably I just haven't fully understood what you're saying. I agree though that an HRN with a DNS proof makes it much easier to check.
I couldn't find a place to discuss it there, but I propose Bitcoin Readable Address (BRA).
I believe you can open an issue on https://github.com/BitcoinDesign/Guide/ AFAIR the conclusion of the UX and designers working on the guide decided it was best to stick with referring to it as simply an "address" rather than trying to teach everyone a new name, but you should hash it out with them, its good for wallets to be consistent here.
I try to avoid non-Java dependencies these days :)
Fair enough, the Java build system world is...hostile to custom stuff or native dependencies, IME.
For HWW adoption, I suspect a MicroPython implementation is going to be necessary.
Hmm, maybe? They should have no problem with calling Rust code from MicroPython, though. I'll wait and see what folks say.
I'm not sure that a txid was ever a "proof of payment" without checking the address it sends to is yours, but probably I just haven't fully understood what you're saying. I agree though that an HRN with a DNS proof makes it much easier to check.
My point is that users very often will provide a txid to a recipient as proof they paid. eg if a recipient claim they haven't been paid, or more often when a service processes a withdraw to the user, the txid is a thing users expect to use for payment proofs. Indeed, its not really a proof because the address could be wrong, but now users are going to be confused - they're used to entering the txid into the block explorer and seeing the recipient address they selected in the window, now they will not. Storing the proof (and maybe we need a page on satsto.me to link to with the proof) seems like an important step towards retaining common user behavior.