Hi Craig, > > IIUC, this creates a descriptor with a variable length. What if we encoded multiple labels in one number? For example, labels 1, 5, 10 are encoded into a 64-bit number by setting the corresponding bit positions to '1' so that the final number is '1058'. Using one number to encode the labels is very appealing to me. > Descriptors are generally of variable length, so I'm not sure why this is so appealing. Not only does this limit the range from 1 to 63, it has the added disadvantage of making this part of the descriptor unreadable to most humans. I was thinking about a descriptor with thousands of labels and I thought I could encode a large list of numbers into 64 bit number, but that’s impossible. Consider this idea, if we strictly increment the label by one, then just writing the max label, '10', in this example should be sufficient to tell the wallet to check for labels 1.. 10. The previous example used "1, 5, 10" as labels, but I'm not sure why we would we use label '1' and skip to '5', so writing just the max label should work? I'm still not in support of using new key formats for the descriptor, but I'll see if they receive popular support. Novo. On Fri, 12 Dec 2025, 10:18 am Craig Raw, wrote: > Hi Novo, > > Responses inline: > > > However, without the birthday, the descriptor will still be able to > describe its outputs. The birthday can be collected through some other > means, as we do with other descriptors today. > > Indeed, that is why it is an optional argument. Again however, other > descriptors do not have to bear the very significant computational overhead > that sp() descriptors do. For many deployment contexts, this will > effectively make the birthday a requirement to retrieve all silent payment > outputs in a wallet within a usable time frame. Other descriptors do not > share such a stark usability challenge. > > > With existing key formats, users and wallets will be able use their > existing master key to generate silent payment outputs using a descriptor > like: sp(/352h/1h/0h/1h/0,/352h/1h/0h/0h/0). > > You are requiring the user to specify their master xprv in an output > descriptor, even for a watch-only wallet. This is a non-starter. Today, > output descriptors are often stored in clear text alongside a hardware > wallet or similar as privacy-sensitive but not directly security-sensitive > information. > > > > The advantages of Bech32m encoding, including strong error detection > and unambiguous characters > > I'm not sure these are strong enough to warrant new key formats. > > To the contrary, the use of output descriptors today means they are often > written down (sometimes into durable media). In this context, the > advantages of strong error detection and unambiguous characters are > significant. > > > > Safety from accidentally mixing different unrelated scan and spend keys > > I'm not sure what the chance of this happening is.... If this is done > properly, then the keys should not be mixed up. > > It might also be done intentionally, with unexpected results. Regardless > of the cause, having one key expression discourages this. > > > We should use the descriptor prefix to indicate the silent payments > version instead of the keys. > > Indeed, silent payments version 1 may use a different script expression. > The versioning here is still useful though. > > > Things can be even simpler without the new key format. > > This is an unsubstantiated statement, suggesting that two key expressions > are somehow simpler than one. Again, it is simpler for wallet developers > and users to adapt to formats that are similar to those they are already > familiar with - and they are very familiar with xpubs. > > > IIUC, this creates a descriptor with a variable length. What if we > encoded multiple labels in one number? For example, labels 1, 5, 10 are > encoded into a 64-bit number by setting the corresponding bit positions to > '1' so that the final number is '1058'. Using one number to encode the > labels is very appealing to me. > > Descriptors are generally of variable length, so I'm not sure why this is > so appealing. Not only does this limit the range from 1 to 63, it has the > added disadvantage of making this part of the descriptor unreadable to most > humans. > > Best regards, > Craig > > On Fri, Dec 12, 2025 at 9:22 AM Oghenovo Usiwoma > wrote: > >> Hi Craig, >> >> I see how adding the birthday to the descriptor string could be >> beneficial for anyone trying to use a third-party scanning server; they >> will only have to submit the descriptor string, and the server will >> automatically determine what height to start scanning from. However, >> without the birthday, the descriptor will still be able to describe its >> outputs. The birthday can be collected through some other means, as we do >> with other descriptors today. >> >> I'm opposed to using new key formats because I do not think we have >> enough justification to do so. With existing key formats, users and wallets >> will be able use their existing master key to generate silent payment >> outputs using a descriptor like: >> sp(/352h/1h/0h/1h/0,/352h/1h/0h/0h/0). >> >> > A self-describing format which makes the use and sensitivity of the key >> material immediately obvious >> > The advantages of Bech32m encoding, including strong error detection >> and unambiguous characters >> I'm not sure these are strong enough to warrant new key formats. >> >> > Safety from accidentally mixing different unrelated scan and spend keys >> I'm not sure what the chance of this happening is. We already have >> descriptors with multiple keys having complex relationships. Compared to >> those, the "sp()" is simple. Users are supposed to back up the entire >> descriptor string. If this is done properly, then the keys should not be >> mixed up. >> >> > Versioning to indicate silent payments version 0 >> We should use the descriptor prefix to indicate the silent payments >> version instead of the keys. >> >> > A similar format to an xpub, the display of which is a common user >> interface element in many wallets, which makes things simpler for wallet >> developers and users alike >> Things can be even simpler without the new key format. >> >> From your original email: >> > Finally, zero or more positive integers may be specified as further >> arguments to scan for additional BIP352 labels. >> IIUC, this creates a descriptor with a variable length. What if we >> encoded multiple labels in one number? For example, labels 1, 5, 10 are >> encoded into a 64-bit number by setting the corresponding bit positions to >> '1' so that the final number is '1058'. Using one number to encode the >> labels is very appealing to me. >> >> Kind regards, >> Novo >> >> On Thu, Dec 4, 2025 at 12:02 PM Craig Raw wrote: >> >>> Hi Novo, >>> >>> Responses inline: >>> >>> > I'm not sure adding a block height does much to reduce scanning >>> burden. We can already scan from the taproot activation height and it won't >>> matter much anyway, because the chain will get longer and this only helps >>> temporarily. >>> >>> I'm not sure I follow here. Since we need to retrieve and compute >>> possible matching outputs for all eligible public keys in the chain, having >>> a block height later than the Taproot activation date can make a >>> significant difference, and will make a greater difference in future as the >>> chain grows. >>> >>> > Is there any reason to add the birthday to the descriptor? Other >>> descriptors do not do this. >>> >>> The difference between this and other descriptors is that it cannot >>> describe outputs without reference to the blockchain. This, combined with >>> the significant computational burden which other descriptors do not have to >>> bear, is reason enough I think to include it here as an optional argument. >>> >>> > For example, we can set the maximum number of labels in the bip; >>> wallets will only have to scan for this max number of labels during >>> recovery and if a wallet goes beyond this maximum number, they have gone >>> beyond the bip and are now responsible for ensuring full recovery of funds. >>> >>> The problem with this approach is that scanning for each additional >>> label adds incrementally and non-trivially to the computational burden. For >>> each label, there is an EC point addition and comparison against all >>> taproot outputs for an eligible transaction. Some benchmark numbers >>> indicating the relative cost of each additional label are in [1], >>> demonstrating that scanning for 100k labels is cost-prohibitive. As an >>> aside, I will add that labels have a limited use case, and in most cases a >>> new BIP44 account is a better choice for additional silent payment >>> addresses based on the same seed. >>> >>> > Given the above points, I argue that we don't need to introduce new >>> scan and spend key formats, and we can use "sp(scankey,spendkey)". >>> >>> While not strictly necessary, using spscan and spspend key >>> expressions make for a much better user experience and reduce the chance >>> for user error. With this encoding we get: >>> >>> 1. A self-describing format which makes the use and sensitivity of >>> the key material immediately obvious >>> 2. The advantages of Bech32m encoding, including strong error >>> detection and unambiguous characters >>> 3. Safety from accidentally mixing different unrelated scan and >>> spend keys >>> 4. Versioning to indicate silent payments version 0 >>> 5. A similar format to an xpub, the display of which is a common >>> user interface element in many wallets which makes things simpler for >>> wallet developers and users alike >>> >>> --Craig >>> >>> [1]: https://delvingbitcoin.org/t/bip352-private-key-formats/2080/11 >>> >>> On Thu, Dec 4, 2025 at 11:39 AM Oghenovo Usiwoma >>> wrote: >>> >>>> Hi Craig, thank you for taking this up. I have the following comments, >>>> based on a light inspection of your original email. >>>> >>>> > In order to reduce the scanning burden, a block height may be >>>> optionally specified in the sp() expression as a second argument for a >>>> wallet birthday. >>>> >>>> I'm not sure adding a block height does much to reduce scanning burden. >>>> We can already scan from the taproot activation height and it won't matter >>>> much anyway, because the chain will get longer and this only helps >>>> temporarily. >>>> >>>> Users can also specify a "wallet birthday" in their wallets which can >>>> be used for scanning. Is there any reason to add the birthday to the >>>> descriptor? Other descriptors do not do this. >>>> >>>> > Finally, zero or more positive integers may be specified as further >>>> arguments to scan for additional BIP352 labels. The change label (m = 0) is >>>> implicitly included. >>>> >>>> In >>>> https://github.com/bitcoin/bips/blob/master/bip-0352.mediawiki#backup-and-recovery >>>> , a strategy to recover funds from labels is specified. We can attempt to >>>> make this stronger and avoid the need to also include an integer for >>>> labels. For example, we can set the maximum number of labels in the bip; >>>> wallets will only have to scan for this max number of labels during >>>> recovery and if a wallet goes beyond this maximum number, they have gone >>>> beyond the bip and are now responsible for ensuring full recovery of funds. >>>> >>>> > In summary a new top level script expression sp() is defined, which >>>> takes as it's first argument one of two new key expressions: >>>> - spscan1q... which encodes the scan private key and the spend public >>>> key >>>> - spspend1q... which encodes the scan private key and the spend private >>>> key >>>> >>>> Given the above points, I argue that we don't need to introduce new >>>> scan and spend key formats, and we can use "sp(scankey,spendkey)". >>>> >>>> I'm happy to hear any counter arguments you have. >>>> >>>> Novo >>>> >>>> On Thu, 4 Dec 2025, 12:40 pm Craig Raw, wrote: >>>> >>>>> Hi all, >>>>> >>>>> There is a practical need for a silent payments output descriptor >>>>> format in order to enable wallet interoperability and backup/recovery. >>>>> There has been some prior discussion on this topic [1][2] which this BIP >>>>> proposal builds on: >>>>> >>>>> https://github.com/bitcoin/bips/pull/2047 >>>>> >>>>> In summary a new top level script expression sp() is defined, which >>>>> takes as it's first argument one of two new key expressions: >>>>> >>>>> - spscan1q... which encodes the scan private key and the spend >>>>> public key >>>>> - spspend1q... which encodes the scan private key and the spend >>>>> private key >>>>> >>>>> The outputs may then be generated by combining this key material with >>>>> the sender input public keys. >>>>> >>>>> In order to reduce the scanning burden, a block height may be >>>>> optionally specified in the sp() expression as a second argument for a >>>>> wallet birthday. Finally, zero or more positive integers may be specified >>>>> as further arguments to scan for additional BIP352 labels. The change label >>>>> (m = 0) is implicitly included. >>>>> >>>>> Examples: >>>>> sp(spscan1q...) >>>>> sp([deadbeef/352'/0'/0']spscan1q...,900000) >>>>> sp(spspend1q...,842579,1,2,3) >>>>> sp([deadbeef/352'/0'/0']spscan1q...,900000,1,5,10) >>>>> >>>>> --Craig >>>>> >>>>> [1]: >>>>> https://btctranscripts.com/bitcoin-core-dev-tech/2024-04/silent-payment-descriptors >>>>> [2]: https://delvingbitcoin.org/t/bip352-private-key-formats/2080 >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Bitcoin Development Mailing List" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to bitcoindev+unsubscribe@googlegroups.com. >>>>> To view this discussion visit >>>>> https://groups.google.com/d/msgid/bitcoindev/CAPR5oBNCd65XaipOF%3DeXW7PT%2BJRVC4m6ey%2BX42aQsKa1YzA-Xw%40mail.gmail.com >>>>> >>>>> . >>>>> >>>>> -- You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group. To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/CAOCjZ9QxuFK2-6pEKC9tgL%3DbThtF2RqxJV_T3MpKz-k084hHAA%40mail.gmail.com.