Proposal: Bitcoin Secure Multisig Setup

Proposal: Bitcoin Secure Multisig Setup
2021-02-09  9:33 ` Craig Raw
                   ` (5 more replies)
  
From: Hugo Nguyen @ 2021-02-08 23:14 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 8303 bytes --]

Hi all,
I would like to propose a new BIP for Secure Multisig Setup.
This proposal has taken inputs from folks at Coldcard, Shift Crypto and
Cobo -- listed below as co-authors.

This was inspired by my own experience working with hardware wallets on the
market, as well as existing research into the challenges of multisig.

Cheers,
Hugo

<pre>
  BIP: To be determined
  Layer: Applications
  Title: Bitcoin Secure Multisig Setup (BSMS)
  Author: Hugo Nguyen <hugo@nunchuk•io>, Peter Gray <peter@coinkite•com>,
Marko Bencun <marko@shiftcrypto•ch>, Aaron Chen <aarondongchen@gmail•com>,
Rodolfo Novak <rodolfo@coinkite•com>
  Comments-Summary: No comments yet.
  Comments-URI:
  Status: Proposed
  Type: Standards Track
  Created: 2020-11-10
  License: BSD-2-Clause
</pre>

==Introduction==

===Abstract===

This document proposes a mechanism to set up multisig wallets securely.

===Copyright===

This BIP is licensed under the 2-clause BSD license.

===Motivation===

The Bitcoin multisig experience has been greatly streamlined under [
https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
(Partially Signed Bitcoin Transaction)]. However, what is still missing is
a standardized process for setting up multisig wallets securely across
different vendors.

There are a number of concerns when it comes to setting up a multisig
wallet:

# Whether the multisig configuration, such as Signer membership, script
type, derivation paths and number of signatures required, is correct and
not tampered with.
# Whether Signer persists the multisig configuration in their respective
storage, and under what format.
# Whether Signer's storage is tamper-proof.
# Whether Signer subsequently uses the multisig configuration to generate
and verify receive and change addresses.

An attacker who can modify the multisig configuration can steal or hold
funds to ransom by duping the user into sending funds to the wrong address.

This proposal seeks to address concerns #1 and #2: to mitigate the risk of
tampering during the initial setup phase, and to define an interoperable
multisig configuration format.

Concerns #3 and #4 should be handled by Signers and is out of scope of this
proposal.

==Specification==

===Prerequisites===
This proposal assumes the parties in the multisig support [
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32], [
https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
descriptor language] and encryption.

==Roles==
===Coordinator===

The Coordinator initiates the multisig setup. The Coordinator determines
what type of multisig is used and how many members and signatures are
needed. If encryption is enabled, the Coordinator generates a secret token,
to be shared among the parties for secure communication. The Coordinator
gathers information from the Signers to generate a descriptor record. The
Coordinator distributes the descriptor record back to the Signers.

===Signer===

The Signer is a participating member in the multisig. Its responsibilities
include providing its XPUB to the Coordinator, verifying that its XPUB is
included in the descriptor record and persisting the descriptor record in
its storage.

==Setup Process==

===Round 1===

====Coordinator====

* The Coordinator creates a multisig wallet creation session. The
Coordinator determines the type of multisig script used and the signing
configuration (<tt>M</tt> and <tt>N</tt>).
* If encryption is enabled, the Coordinator also generates a secret token,
hereby denoted <tt>TOKEN</tt>.
* TOKEN is in ASCII format and must have a minimum of 8 characters. TOKEN
should expire after some time period determined by the Coordinator, e.g.,
24 hours.
* TOKEN acts as an encryption key among the parties. The method of
encryption is AES, CTR mode. The encryption key can be calculated by
performing a double hash operation on the TOKEN: <tt>ENCRYPTION_KEY =
SHA256(SHA256(TOKEN))</tt>.
* A TOKEN value of <tt>-1</tt> means that encryption is disabled and all
the encryption/decryption steps below can be skipped.
* The Coordinator shares the TOKEN with all participating Signers over a
secure channel.

====Signer====

* The Signer generates a key record by prompting the user for the TOKEN and
a derivation path.
* The first line in the record must be the <tt>TOKEN</tt>. If encryption is
disabled, set the TOKEN to -1. The second line must be the <tt>KEY</tt>,
whereas KEY is an XPUB. KEY must include key origin information and written
in the descriptor-defined format, i.e.: <tt>[{master key
fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a
<tt>SIG</tt>, whereas SIG is the signature generated by using the
corresponding private key to sign the first two lines. Finally, the Signer
encrypts the entire record with ENCRYPTION_KEY.

===Round 2===

====Coordinator====

* The Coordinator gathers key records from all participating Signers. Abort
the setup if TOKEN has expired.
* For each key record, the Coordinator decrypts it using ENCRYPTION_KEY.
The Coordinator verifies that the included SIG is valid given the KEY.
* If all key records look good, the Coordinator generates a descriptor
record, which is simply the descriptor string plus a <tt>CHECKSUM</tt>, all
in one line. The CHECKSUM has BECH32 encoding and is described at [
https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums].
The Coordinator encrypts this descriptor record with ENCRYPTION_KEY.
* The Coordinator sends the encrypted descriptor record to all
participating Signers.

====Signer====

* The Signer imports the descriptor record, decrypts it by prompting the
user for TOKEN.
* The Signer calculates and verifies the descriptor’s CHECKSUM. Abort the
setup if the CHECKSUM is incorrect.
* The Signer checks whether one of the KEYs in the descriptor belongs to
it, using path and fingerprint information included in the descriptor. The
check must perform an exact match on the KEYs, and not using shortcuts such
as matching fingerprints (which is trivial to spoof). Abort the setup if it
doesn’t detect its own KEY.
* For confirmation, the Signer must display to the user the descriptor's
CHECKSUM, plus other configurations, such as M and N. The total number of
Signers, N, is important to prevent a KEY insertion attack. All
participating Signers should be able to display the same confirmation.
* If all checks pass, the Signer persists the descriptor record in its
storage. The Signer should subsequently use the descriptor to generate and
verify receive and change addresses.

This completes the setup.

==QR Codes==
For signers that use QR codes to transmit data, key and descriptor records
can be converted to QR codes, following [
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
the BCR standard].

==Security==

This proposal introduce two layers of protection. The first one is a
temporary, secret token, used to encrypt the two rounds of communication
between the Signers and the Coordinator. The second one is through the
descriptor checksum and visual inspection of the descriptor itself.

The token is only needed during the setup phase, and can be safely thrown
away afterwards. The token does not guarantee that the Signer membership
set is not modified, since that depends on the overall security of all
parties in the setup, but it can make it significantly harder for an
attacker to do so.

There are three ways an attacker can modify the membership set: by changing
an existing member, by removing an existing member, or by adding a new
member.

For the first two methods, one of the Signers will be able to detect that
its membership has been changed or removed, and reject the final
descriptor. Thus, it is vital that all participating Signers check that
their membership is intact in the descriptor. Even one Signer failing to
check for its membership means that the setup could be compromised.

For the third type of attack, the descriptor checksum and visual inspection
of the descriptor itself are the only way to guard against malicious
members from being inserted into the set.

[-- Attachment #2: Type: text/html, Size: 9302 bytes --]

 permalink raw reply	[|nested]
2021-02-09  9:33 ` 
                   ` 
  
From: Hugo Nguyen @ 2021-02-08 23:14 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 8303 bytes --]

Hi all,
I would like to propose a new BIP for Secure Multisig Setup.
This proposal has taken inputs from folks at Coldcard, Shift Crypto and
Cobo -- listed below as co-authors.

This was inspired by my own experience working with hardware wallets on the
market, as well as existing research into the challenges of multisig.

Cheers,
Hugo

<pre>
  BIP: To be determined
  Layer: Applications
  Title: Bitcoin Secure Multisig Setup (BSMS)
  Author: Hugo Nguyen <hugo@nunchuk•io>, Peter Gray <peter@coinkite•com>,
Marko Bencun <marko@shiftcrypto•ch>, Aaron Chen <aarondongchen@gmail•com>,
Rodolfo Novak <rodolfo@coinkite•com>
  Comments-Summary: No comments yet.
  Comments-URI:
  Status: Proposed
  Type: Standards Track
  Created: 2020-11-10
  License: BSD-2-Clause
</pre>

==Introduction==

===Abstract===

This document proposes a mechanism to set up multisig wallets securely.

===Copyright===

This BIP is licensed under the 2-clause BSD license.

===Motivation===

The Bitcoin multisig experience has been greatly streamlined under [
https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
(Partially Signed Bitcoin Transaction)]. However, what is still missing is
a standardized process for setting up multisig wallets securely across
different vendors.

There are a number of concerns when it comes to setting up a multisig
wallet:

# Whether the multisig configuration, such as Signer membership, script
type, derivation paths and number of signatures required, is correct and
not tampered with.
# Whether Signer persists the multisig configuration in their respective
storage, and under what format.
# Whether Signer's storage is tamper-proof.
# Whether Signer subsequently uses the multisig configuration to generate
and verify receive and change addresses.

An attacker who can modify the multisig configuration can steal or hold
funds to ransom by duping the user into sending funds to the wrong address.

This proposal seeks to address concerns #1 and #2: to mitigate the risk of
tampering during the initial setup phase, and to define an interoperable
multisig configuration format.

Concerns #3 and #4 should be handled by Signers and is out of scope of this
proposal.

==Specification==

===Prerequisites===
This proposal assumes the parties in the multisig support [
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32], [
https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
descriptor language] and encryption.

==Roles==
===Coordinator===

The Coordinator initiates the multisig setup. The Coordinator determines
what type of multisig is used and how many members and signatures are
needed. If encryption is enabled, the Coordinator generates a secret token,
to be shared among the parties for secure communication. The Coordinator
gathers information from the Signers to generate a descriptor record. The
Coordinator distributes the descriptor record back to the Signers.

===Signer===

The Signer is a participating member in the multisig. Its responsibilities
include providing its XPUB to the Coordinator, verifying that its XPUB is
included in the descriptor record and persisting the descriptor record in
its storage.

==Setup Process==

===Round 1===

====Coordinator====

* The Coordinator creates a multisig wallet creation session. The
Coordinator determines the type of multisig script used and the signing
configuration (<tt>M</tt> and <tt>N</tt>).
* If encryption is enabled, the Coordinator also generates a secret token,
hereby denoted <tt>TOKEN</tt>.
* TOKEN is in ASCII format and must have a minimum of 8 characters. TOKEN
should expire after some time period determined by the Coordinator, e.g.,
24 hours.
* TOKEN acts as an encryption key among the parties. The method of
encryption is AES, CTR mode. The encryption key can be calculated by
performing a double hash operation on the TOKEN: <tt>ENCRYPTION_KEY =
SHA256(SHA256(TOKEN))</tt>.
* A TOKEN value of <tt>-1</tt> means that encryption is disabled and all
the encryption/decryption steps below can be skipped.
* The Coordinator shares the TOKEN with all participating Signers over a
secure channel.

====Signer====

* The Signer generates a key record by prompting the user for the TOKEN and
a derivation path.
* The first line in the record must be the <tt>TOKEN</tt>. If encryption is
disabled, set the TOKEN to -1. The second line must be the <tt>KEY</tt>,
whereas KEY is an XPUB. KEY must include key origin information and written
in the descriptor-defined format, i.e.: <tt>[{master key
fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a
<tt>SIG</tt>, whereas SIG is the signature generated by using the
corresponding private key to sign the first two lines. Finally, the Signer
encrypts the entire record with ENCRYPTION_KEY.

===Round 2===

====Coordinator====

* The Coordinator gathers key records from all participating Signers. Abort
the setup if TOKEN has expired.
* For each key record, the Coordinator decrypts it using ENCRYPTION_KEY.
The Coordinator verifies that the included SIG is valid given the KEY.
* If all key records look good, the Coordinator generates a descriptor
record, which is simply the descriptor string plus a <tt>CHECKSUM</tt>, all
in one line. The CHECKSUM has BECH32 encoding and is described at [
https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums].
The Coordinator encrypts this descriptor record with ENCRYPTION_KEY.
* The Coordinator sends the encrypted descriptor record to all
participating Signers.

====Signer====

* The Signer imports the descriptor record, decrypts it by prompting the
user for TOKEN.
* The Signer calculates and verifies the descriptor’s CHECKSUM. Abort the
setup if the CHECKSUM is incorrect.
* The Signer checks whether one of the KEYs in the descriptor belongs to
it, using path and fingerprint information included in the descriptor. The
check must perform an exact match on the KEYs, and not using shortcuts such
as matching fingerprints (which is trivial to spoof). Abort the setup if it
doesn’t detect its own KEY.
* For confirmation, the Signer must display to the user the descriptor's
CHECKSUM, plus other configurations, such as M and N. The total number of
Signers, N, is important to prevent a KEY insertion attack. All
participating Signers should be able to display the same confirmation.
* If all checks pass, the Signer persists the descriptor record in its
storage. The Signer should subsequently use the descriptor to generate and
verify receive and change addresses.

This completes the setup.

==QR Codes==
For signers that use QR codes to transmit data, key and descriptor records
can be converted to QR codes, following [
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
the BCR standard].

==Security==

This proposal introduce two layers of protection. The first one is a
temporary, secret token, used to encrypt the two rounds of communication
between the Signers and the Coordinator. The second one is through the
descriptor checksum and visual inspection of the descriptor itself.

The token is only needed during the setup phase, and can be safely thrown
away afterwards. The token does not guarantee that the Signer membership
set is not modified, since that depends on the overall security of all
parties in the setup, but it can make it significantly harder for an
attacker to do so.

There are three ways an attacker can modify the membership set: by changing
an existing member, by removing an existing member, or by adding a new
member.

For the first two methods, one of the Signers will be able to detect that
its membership has been changed or removed, and reject the final
descriptor. Thus, it is vital that all participating Signers check that
their membership is intact in the descriptor. Even one Signer failing to
check for its membership means that the setup could be compromised.

For the third type of attack, the descriptor checksum and visual inspection
of the descriptor itself are the only way to guard against malicious
members from being inserted into the set.

[-- Attachment #2: Type: text/html, Size: 9302 bytes --]

 permalink raw reply	[|nested]
[not found] ` <CACrqygA1JRA293joYOxxpSepiuFD=uVvQQy3wpuosYyLQHff-A@mail.gmail.com>

  2021-02-09 10:05   ` Hugo Nguyen
  
From: Christopher Allen @ 2021-02-09  9:38 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 982 bytes --]

In the Airgapped Wallet Community we also have been investigating
solutions, in particular as current common practice is is reuse the same
xpub for all multisigs, for instance [90081696/48'/0'/0'/2']
xpub6DYLEkDfCdHzh5FHGHDJksQvFqu6kYANa1sfo6fA8n5ZWkSwyCRVVzyq9LY2eNGB6T9BKDeGJp2ZarjRZHd7WB95nSaFEDhFMK6zSV6D49b

We’ve also have been looking into multi round commitment scheme, but wanted
to align the UX so that it would work like to musig for users. Discussion
on it is scattered, for instance
https://github.com/BlockchainCommons/Airgapped-Wallet-Community/discussions/16#discussioncomment-212013

Nothing got as far as your version though.

So Concept ACK from Blockchain Commons. Less clear on your specifics
though. We will review.

Note that we are releasing a descriptor & multisig centric iOS and Android
reference wallet soon so solving this correctly and having interoperability
with others is very important for our roadmap.

— Christopher Allen

[-- Attachment #2: Type: text/html, Size: 1421 bytes --]

 permalink raw reply	[|nested]
[not found] ` <CAPR5oBNWGLcnw97yPJBCgrj=EwoNdxz_RS9HM6EMpuX2-90JnQ@mail.gmail.com>

  
From: Hugo Nguyen @ 2021-02-09  9:45 UTC (permalink / raw)
  To: Craig Raw;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 13240 bytes --]

Hi Craig,
Comments inline.

On Tue, Feb 9, 2021 at 1:17 AM Craig Raw <craigraw@gmail•com> wrote:

> Hi Hugo,
>
> Thanks for raising this again - I'll note there has already been much
> discussion on this topic. With respect to your "two layers of protection":
>
> > The Coordinator shares the TOKEN with all participating Signers over a
> secure channel.
>
> What secure channel do you propose? Currently, with the default of a
> software wallet coordinator talking to hardware wallets, we have USB, file
> (microSD), and QR as communication channels. It's unclear to me why the
> token and encryption process is necessary - in fact it's easier to verify
> what is going on using clear text, and the majority of setups will be
> locally done with the reasonable assumption of a secure environment. When
> the setup is remote, it's simpler to just transmit the key information over
> the secure channel which presumably already has encryption.
>
>
In short, a shared secret (the TOKEN) is needed because without it you
cannot guarantee that the devices you are connecting to are legitimate
members of the multisig wallet. Yes, the connection between the coordinator
and each device could be secure - but a malicious actor can establish a
secure channel just as well as a good one. You are correct that this is
less of an issue for local setups, but this is especially important for
distributed multisig - where you cannot physically see what's on the other
side.

I would love to remove the shared secret/encryption aspect out of the
proposal, but so far I haven't found any way around this issue, aside from
establishing a shared secret prior to setting up the wallet...

I also realized that supporting this could be a big ask for vendors, so
I've made this part of the proposal optional.

Another note here is that right after I posted the proposal (classic...), I
also realized there could be another optimization: the secure session
established by the shared secret can remain open indefinitely on the device
side - until a different TOKEN is entered. That way the user needs to enter
the TOKEN only once, saving us one interaction.


> > The second one is through the descriptor checksum and visual inspection
> of the descriptor itself.
>
> This is a reasonable suggestion, although it's worth noting that support
> for storing multisig setups on hardware wallets varies. Coldcard supports
> this through importing of a proprietary .txt format file (which has been
> adopted by a number of other vendors). Trezor and Ledger (AFAIK) do not
> however store multisig setups, which could make this step confusing. With
> that said, the use of an output descriptor is certainly a more standardised
> approach, albeit one without the wallet name included. By the use of the
> singular, I assume you mean a descriptor without the /0/* or /1/* suffix
> (which I think is a good idea).
>
>
I'm aware that Trezor and Ledger currently cannot support this. But IMHO
lack of support on some devices shouldn't prevent us from setting a good
standard here. Cosigner registration on the device is crucial, as you don't
have to rely on everything being included in the PSBT (which also adds
mental overhead as the user has to verify each and every transaction).

Yes, descriptor without the /0/* and /1/* - Thanks for clarifying. Will
update the proposal.



> WRT to QR codes, using the BCR UR2.0 standard you linked to is IMO the
> right approach. I'll link directly to the two BCR UR2.0 formats here which
> are relevant:
>
> 1. For sharing the sharing the BIP44 account information from the signers
> to the coordinator, the crypto-account format: [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
> ]
> 2. For sharing the output descriptor from the coordinator to the signers,
> the crypto-output format: [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
> ]
>
>
Thanks, will update!


> Craig
>
>
>
> On Tue, Feb 9, 2021 at 9:53 AM Hugo Nguyen via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> Hi all,
>> I would like to propose a new BIP for Secure Multisig Setup.
>> This proposal has taken inputs from folks at Coldcard, Shift Crypto and
>> Cobo -- listed below as co-authors.
>>
>> This was inspired by my own experience working with hardware wallets on
>> the market, as well as existing research into the challenges of multisig.
>>
>> Cheers,
>> Hugo
>>
>> <pre>
>>   BIP: To be determined
>>   Layer: Applications
>>   Title: Bitcoin Secure Multisig Setup (BSMS)
>>   Author: Hugo Nguyen <hugo@nunchuk•io>, Peter Gray <peter@coinkite•com>,
>> Marko Bencun <marko@shiftcrypto•ch>, Aaron Chen <aarondongchen@gmail•com>,
>> Rodolfo Novak <rodolfo@coinkite•com>
>>   Comments-Summary: No comments yet.
>>   Comments-URI:
>>   Status: Proposed
>>   Type: Standards Track
>>   Created: 2020-11-10
>>   License: BSD-2-Clause
>> </pre>
>>
>> ==Introduction==
>>
>> ===Abstract===
>>
>> This document proposes a mechanism to set up multisig wallets securely.
>>
>> ===Copyright===
>>
>> This BIP is licensed under the 2-clause BSD license.
>>
>> ===Motivation===
>>
>> The Bitcoin multisig experience has been greatly streamlined under [
>> https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
>> (Partially Signed Bitcoin Transaction)]. However, what is still missing is
>> a standardized process for setting up multisig wallets securely across
>> different vendors.
>>
>> There are a number of concerns when it comes to setting up a multisig
>> wallet:
>>
>> # Whether the multisig configuration, such as Signer membership, script
>> type, derivation paths and number of signatures required, is correct and
>> not tampered with.
>> # Whether Signer persists the multisig configuration in their respective
>> storage, and under what format.
>> # Whether Signer's storage is tamper-proof.
>> # Whether Signer subsequently uses the multisig configuration to generate
>> and verify receive and change addresses.
>>
>> An attacker who can modify the multisig configuration can steal or hold
>> funds to ransom by duping the user into sending funds to the wrong address.
>>
>> This proposal seeks to address concerns #1 and #2: to mitigate the risk
>> of tampering during the initial setup phase, and to define an interoperable
>> multisig configuration format.
>>
>> Concerns #3 and #4 should be handled by Signers and is out of scope of
>> this proposal.
>>
>> ==Specification==
>>
>> ===Prerequisites===
>> This proposal assumes the parties in the multisig support [
>> https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32], [
>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
>> descriptor language] and encryption.
>>
>> ==Roles==
>> ===Coordinator===
>>
>> The Coordinator initiates the multisig setup. The Coordinator determines
>> what type of multisig is used and how many members and signatures are
>> needed. If encryption is enabled, the Coordinator generates a secret token,
>> to be shared among the parties for secure communication. The Coordinator
>> gathers information from the Signers to generate a descriptor record. The
>> Coordinator distributes the descriptor record back to the Signers.
>>
>> ===Signer===
>>
>> The Signer is a participating member in the multisig. Its
>> responsibilities include providing its XPUB to the Coordinator, verifying
>> that its XPUB is included in the descriptor record and persisting the
>> descriptor record in its storage.
>>
>> ==Setup Process==
>>
>> ===Round 1===
>>
>> ====Coordinator====
>>
>> * The Coordinator creates a multisig wallet creation session. The
>> Coordinator determines the type of multisig script used and the signing
>> configuration (<tt>M</tt> and <tt>N</tt>).
>> * If encryption is enabled, the Coordinator also generates a secret
>> token, hereby denoted <tt>TOKEN</tt>.
>> * TOKEN is in ASCII format and must have a minimum of 8 characters. TOKEN
>> should expire after some time period determined by the Coordinator, e.g.,
>> 24 hours.
>> * TOKEN acts as an encryption key among the parties. The method of
>> encryption is AES, CTR mode. The encryption key can be calculated by
>> performing a double hash operation on the TOKEN: <tt>ENCRYPTION_KEY =
>> SHA256(SHA256(TOKEN))</tt>.
>> * A TOKEN value of <tt>-1</tt> means that encryption is disabled and all
>> the encryption/decryption steps below can be skipped.
>> * The Coordinator shares the TOKEN with all participating Signers over a
>> secure channel.
>>
>> ====Signer====
>>
>> * The Signer generates a key record by prompting the user for the TOKEN
>> and a derivation path.
>> * The first line in the record must be the <tt>TOKEN</tt>. If encryption
>> is disabled, set the TOKEN to -1. The second line must be the <tt>KEY</tt>,
>> whereas KEY is an XPUB. KEY must include key origin information and written
>> in the descriptor-defined format, i.e.: <tt>[{master key
>> fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a
>> <tt>SIG</tt>, whereas SIG is the signature generated by using the
>> corresponding private key to sign the first two lines. Finally, the Signer
>> encrypts the entire record with ENCRYPTION_KEY.
>>
>> ===Round 2===
>>
>> ====Coordinator====
>>
>> * The Coordinator gathers key records from all participating Signers.
>> Abort the setup if TOKEN has expired.
>> * For each key record, the Coordinator decrypts it using ENCRYPTION_KEY.
>> The Coordinator verifies that the included SIG is valid given the KEY.
>> * If all key records look good, the Coordinator generates a descriptor
>> record, which is simply the descriptor string plus a <tt>CHECKSUM</tt>, all
>> in one line. The CHECKSUM has BECH32 encoding and is described at [
>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums].
>> The Coordinator encrypts this descriptor record with ENCRYPTION_KEY.
>> * The Coordinator sends the encrypted descriptor record to all
>> participating Signers.
>>
>> ====Signer====
>>
>> * The Signer imports the descriptor record, decrypts it by prompting the
>> user for TOKEN.
>> * The Signer calculates and verifies the descriptor’s CHECKSUM. Abort the
>> setup if the CHECKSUM is incorrect.
>> * The Signer checks whether one of the KEYs in the descriptor belongs to
>> it, using path and fingerprint information included in the descriptor. The
>> check must perform an exact match on the KEYs, and not using shortcuts such
>> as matching fingerprints (which is trivial to spoof). Abort the setup if it
>> doesn’t detect its own KEY.
>> * For confirmation, the Signer must display to the user the descriptor's
>> CHECKSUM, plus other configurations, such as M and N. The total number of
>> Signers, N, is important to prevent a KEY insertion attack. All
>> participating Signers should be able to display the same confirmation.
>> * If all checks pass, the Signer persists the descriptor record in its
>> storage. The Signer should subsequently use the descriptor to generate and
>> verify receive and change addresses.
>>
>> This completes the setup.
>>
>> ==QR Codes==
>> For signers that use QR codes to transmit data, key and descriptor
>> records can be converted to QR codes, following [
>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
>> the BCR standard].
>>
>> ==Security==
>>
>> This proposal introduce two layers of protection. The first one is a
>> temporary, secret token, used to encrypt the two rounds of communication
>> between the Signers and the Coordinator. The second one is through the
>> descriptor checksum and visual inspection of the descriptor itself.
>>
>> The token is only needed during the setup phase, and can be safely thrown
>> away afterwards. The token does not guarantee that the Signer membership
>> set is not modified, since that depends on the overall security of all
>> parties in the setup, but it can make it significantly harder for an
>> attacker to do so.
>>
>> There are three ways an attacker can modify the membership set: by
>> changing an existing member, by removing an existing member, or by adding a
>> new member.
>>
>> For the first two methods, one of the Signers will be able to detect that
>> its membership has been changed or removed, and reject the final
>> descriptor. Thus, it is vital that all participating Signers check that
>> their membership is intact in the descriptor. Even one Signer failing to
>> check for its membership means that the setup could be compromised.
>>
>> For the third type of attack, the descriptor checksum and visual
>> inspection of the descriptor itself are the only way to guard against
>> malicious members from being inserted into the set.
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>

[-- Attachment #2: Type: text/html, Size: 15599 bytes --]

 permalink raw reply	[|nested]
[not found] ` <CACrqygA1JRA293joYOxxpSepiuFD=uVvQQy3wpuosYyLQHff-A@mail.gmail.com>
  2021-02-09  9:38   ` Christopher Allen

       [not found]     ` <CACrqygDhuateDtJMBSWd9sGRu1yzrZBw2yZ75OyKD1Xmzix3Cw@mail.gmail.com>
  
From: Hugo Nguyen @ 2021-02-09 10:05 UTC (permalink / raw)
  To: Christopher Allen;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1622 bytes --]

Hi Christopher,
Comments inline.

On Tue, Feb 9, 2021 at 1:31 AM Christopher Allen <
ChristopherA@lifewithalacrity•com> wrote:

> In the Airgapped Wallet Community we also have been investigating
> solutions, in particular as current common practice is is reuse the same
> xpub for all multisigs, for instance [90081696/48'/0'/0'/2']
> xpub6DYLEkDfCdHzh5FHGHDJksQvFqu6kYANa1sfo6fA8n5ZWkSwyCRVVzyq9LY2eNGB6T9BKDeGJp2ZarjRZHd7WB95nSaFEDhFMK6zSV6D49b
>
>
I don't think reusing XPUBs inside different multisig wallets is a good
idea... For starters, loss of privacy in one wallet will immediately affect
privacy of other wallets. I think multisig wallets should be completely
firewalled from each other. That means one unique XPUB per wallet. This is
what we have been doing with the Nunchuk wallet.



> We’ve also have been looking into multi round commitment scheme, but
> wanted to align the UX so that it would work like to musig for users.
> Discussion on it is scattered, for instance
>
> https://github.com/BlockchainCommons/Airgapped-Wallet-Community/discussions/16#discussioncomment-212013
>
> Nothing got as far as your version though.
>
> So Concept ACK from Blockchain Commons. Less clear on your specifics
> though. We will review.
>
> Note that we are releasing a descriptor & multisig centric iOS and Android
> reference wallet soon so solving this correctly and having interoperability
> with others is very important for our roadmap.
>

Thank you and good to know ! Look forward to solving this correctly as well.

Best,

Hugo


>
> — Christopher Allen
>
>

[-- Attachment #2: Type: text/html, Size: 2617 bytes --]

 permalink raw reply	[|nested]
[not found]     ` <CACrqygDhuateDtJMBSWd9sGRu1yzrZBw2yZ75OyKD1Xmzix3Cw@mail.gmail.com>

  2021-02-11 13:25         ` Pavol Rusnak
  
From: Hugo Nguyen @ 2021-02-09 10:58 UTC (permalink / raw)
  To: Christopher Allen;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]

On Tue, Feb 9, 2021 at 2:19 AM Christopher Allen <
ChristopherA@lifewithalacrity•com> wrote:

>
>
> On Tue, Feb 9, 2021 at 2:06 AM Hugo Nguyen <hugo@nunchuk•io> wrote:
>
>>
>> I don't think reusing XPUBs inside different multisig wallets is a good
>> idea... For starters, loss of privacy in one wallet will immediately affect
>> privacy of other wallets. I think multisig wallets should be completely
>> firewalled from each other. That means one unique XPUB per wallet. This is
>> what we have been doing with the Nunchuk wallet.
>>
>
> To be clear, I have stated repeatedly that xpub reuse into multisig is a
> poor practice. However, finding a trustless solution when a wallet is
> airgapped with no network, or is stateless like Trezor, is quite hard.
>
> The challenge also includes how does an airgapped or stateless wallet know
> that it is talking to the same process on the other side that that it gave
> the xpub to in the first place. Without state to allow for a commitment, or
> at least a TOFU, a cosigner who thought he was part of a 3 of 5 could
> discover that he instead is in a 2 of 3, or in a script with an OR, as some
> form of scam.
>

The shared secret approach that I mentioned in the proposal actually can
help you here. The TOKEN doubles as a session ID - thereby establishing a
common state on both sides.

Best,
Hugo


>
> — Christopher Allen
>
>>

[-- Attachment #2: Type: text/html, Size: 2585 bytes --]

 permalink raw reply	[|nested]
2021-02-09 10:58       ` Hugo Nguyen

  2021-02-11 13:45           ` Hugo Nguyen
  
From: Pavol Rusnak @ 2021-02-11 13:25 UTC (permalink / raw)
  To: Hugo Nguyen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2327 bytes --]

> ENCRYPTION_KEY = SHA256(SHA256(TOKEN))

This scheme might be vulnerable to rainbow table attack.

The following scheme might be more secure:

DESCRIPTION = ASCII description provided by user
NONCE = 256-bit random number
ENCRYPTION_KEY = hmac-sha256(key=NONCE, msg=DESCRIPTION)

Coordinator distributes DESCRIPTION (fka TOKEN) together with NONCE to the
signers.

Also, is there any reason why you'd want to disable encryption? Why not
keep that as mandatory?


On Tue, 9 Feb 2021 at 12:39, Hugo Nguyen via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

>
>
> On Tue, Feb 9, 2021 at 2:19 AM Christopher Allen <
> ChristopherA@lifewithalacrity•com> wrote:
>
>>
>>
>> On Tue, Feb 9, 2021 at 2:06 AM Hugo Nguyen <hugo@nunchuk•io> wrote:
>>
>>>
>>> I don't think reusing XPUBs inside different multisig wallets is a good
>>> idea... For starters, loss of privacy in one wallet will immediately affect
>>> privacy of other wallets. I think multisig wallets should be completely
>>> firewalled from each other. That means one unique XPUB per wallet. This is
>>> what we have been doing with the Nunchuk wallet.
>>>
>>
>> To be clear, I have stated repeatedly that xpub reuse into multisig is a
>> poor practice. However, finding a trustless solution when a wallet is
>> airgapped with no network, or is stateless like Trezor, is quite hard.
>>
>> The challenge also includes how does an airgapped or stateless wallet
>> know that it is talking to the same process on the other side that that it
>> gave the xpub to in the first place. Without state to allow for a
>> commitment, or at least a TOFU, a cosigner who thought he was part of a 3
>> of 5 could discover that he instead is in a 2 of 3, or in a script with an
>> OR, as some form of scam.
>>
>
> The shared secret approach that I mentioned in the proposal actually can
> help you here. The TOKEN doubles as a session ID - thereby establishing a
> common state on both sides.
>
> Best,
> Hugo
>
>
>>
>> — Christopher Allen
>>
>>> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>


-- 
Best Regards / S pozdravom,

Pavol "stick" Rusnak
CTO, SatoshiLabs

[-- Attachment #2: Type: text/html, Size: 4676 bytes --]

 permalink raw reply	[|nested]
2021-02-11 13:25         ` Pavol Rusnak

  2021-02-11 16:29             ` Dmitry Petukhov
  
From: Hugo Nguyen @ 2021-02-11 13:45 UTC (permalink / raw)
  To: Pavol Rusnak;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3169 bytes --]

Hi Pavol,

On Thu, Feb 11, 2021 at 5:25 AM Pavol Rusnak <stick@satoshilabs•com> wrote:

> > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))
>
> This scheme might be vulnerable to rainbow table attack.
>

Thank you for pointing this out! Incidentally, Dmitry Petukhov also told me
the same privately.


>
> The following scheme might be more secure:
>
> DESCRIPTION = ASCII description provided by user
> NONCE = 256-bit random number
> ENCRYPTION_KEY = hmac-sha256(key=NONCE, msg=DESCRIPTION)
>
> Coordinator distributes DESCRIPTION (fka TOKEN) together with NONCE to
> the signers.
>

This does seem to add a lot more entropy. The challenge is to balance the
security requirement with UX. In the absence of some handshake protocol to
exchange the shared secrets (DESCRIPTION / NONCE) , the user will have to
enter these manually on the devices. I'll think about this some more.


>
> Also, is there any reason why you'd want to disable encryption? Why not
> keep that as mandatory?
>

Making it mandatory would be nice, but IMHO not all use cases might require
encryption. For example, if you are setting up the multisig locally under a
safe environment you control, encryption might be an overkill.

Best,
Hugo



>
>
> On Tue, 9 Feb 2021 at 12:39, Hugo Nguyen via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>>
>>
>> On Tue, Feb 9, 2021 at 2:19 AM Christopher Allen <
>> ChristopherA@lifewithalacrity•com> wrote:
>>
>>>
>>>
>>> On Tue, Feb 9, 2021 at 2:06 AM Hugo Nguyen <hugo@nunchuk•io> wrote:
>>>
>>>>
>>>> I don't think reusing XPUBs inside different multisig wallets is a good
>>>> idea... For starters, loss of privacy in one wallet will immediately affect
>>>> privacy of other wallets. I think multisig wallets should be completely
>>>> firewalled from each other. That means one unique XPUB per wallet. This is
>>>> what we have been doing with the Nunchuk wallet.
>>>>
>>>
>>> To be clear, I have stated repeatedly that xpub reuse into multisig is a
>>> poor practice. However, finding a trustless solution when a wallet is
>>> airgapped with no network, or is stateless like Trezor, is quite hard.
>>>
>>> The challenge also includes how does an airgapped or stateless wallet
>>> know that it is talking to the same process on the other side that that it
>>> gave the xpub to in the first place. Without state to allow for a
>>> commitment, or at least a TOFU, a cosigner who thought he was part of a 3
>>> of 5 could discover that he instead is in a 2 of 3, or in a script with an
>>> OR, as some form of scam.
>>>
>>
>> The shared secret approach that I mentioned in the proposal actually can
>> help you here. The TOKEN doubles as a session ID - thereby establishing a
>> common state on both sides.
>>
>> Best,
>> Hugo
>>
>>
>>>
>>> — Christopher Allen
>>>
>>>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>
>
> --
> Best Regards / S pozdravom,
>
> Pavol "stick" Rusnak
> CTO, SatoshiLabs
>
>

[-- Attachment #2: Type: text/html, Size: 6239 bytes --]

 permalink raw reply	[|nested]
2021-02-11 13:45           ` Hugo Nguyen

  2021-02-11 19:11               ` Hugo Nguyen
  2021-02-12 16:55               ` Hugo Nguyen
  
From: Dmitry Petukhov @ 2021-02-11 16:29 UTC (permalink / raw)
  To: Hugo Nguyen via bitcoin-dev

В Thu, 11 Feb 2021 05:45:33 -0800
Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
wrote:

> > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))  
> >
> > This scheme might be vulnerable to rainbow table attack.
> >  
> 
> Thank you for pointing this out! Incidentally, Dmitry Petukhov also
> told me the same privately.

My thought was that if TOKEN has the characteristics of a password
(short ASCII string), then it would be better to use key derivation
function designed for passwords, like PBKDF2.

The counter-argument to this is that this adds another code dependency
for vendors, if the device firmware does not already have the required
key derivation function.

Maybe this could be solved by going into opposite direction - make the
"token" even longer, use the mnemoic.

The issue is that entering long data of the shared key into the device
manually is difficult UX-wise.

Hww vendors that allow to enter custom keys into their device already
have to face this issue, and those who allow to enter custom keys via
mnemonic probably tackled this somehow.

Maybe the shared key for multisig setup can be entered in the same way
? (with maybe additional visual check via some fingerprint).

Although we would then have another issue of potential confusion
between two procedures (entering the main key and entering the shared
key for multisig setup), and the measures has to be taken to prevent
such confusion.

The approaches can be combined - specify a key derivation function
suitable for passwords; via secure channel, share a password and/or the
derived key. If hww supports derivation function, it can derive the key
from password. If hww supports only keys, the key can be entered raw or
via mnemonic.


 permalink raw reply	[|nested]
2021-02-11 16:29             ` Dmitry Petukhov

  2021-02-11 19:11                 ` Hugo Nguyen
  2021-02-12 16:55               ` Hugo Nguyen
  
From: Hugo Nguyen @ 2021-02-11 19:11 UTC (permalink / raw)
  To: Dmitry Petukhov, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2495 bytes --]

Hi Pavol,

On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> В Thu, 11 Feb 2021 05:45:33 -0800
> Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
> wrote:
>
> > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))
> > >
> > > This scheme might be vulnerable to rainbow table attack.
> > >
> >
> > Thank you for pointing this out! Incidentally, Dmitry Petukhov also
> > told me the same privately.
>
> My thought was that if TOKEN has the characteristics of a password
> (short ASCII string), then it would be better to use key derivation
> function designed for passwords, like PBKDF2.
>
> The counter-argument to this is that this adds another code dependency
> for vendors, if the device firmware does not already have the required
> key derivation function.
>
> Maybe this could be solved by going into opposite direction - make the
> "token" even longer, use the mnemoic.
>
> The issue is that entering long data of the shared key into the device
> manually is difficult UX-wise.
>
> Hww vendors that allow to enter custom keys into their device already
> have to face this issue, and those who allow to enter custom keys via
> mnemonic probably tackled this somehow.
>
> Maybe the shared key for multisig setup can be entered in the same way
> ? (with maybe additional visual check via some fingerprint).
>

You just gave me a great idea! We can reuse the BIP32 seed words list!
Perhaps the encryption key can just be 6 words, but it'll be derived the
same way. BIP39 also uses PBKDF2 as a key derivation function, so it
matches with what you described here.

And all HWW should have this functionality already.

Best,
Hugo


>
> Although we would then have another issue of potential confusion
> between two procedures (entering the main key and entering the shared
> key for multisig setup), and the measures has to be taken to prevent
> such confusion.
>
> The approaches can be combined - specify a key derivation function
> suitable for passwords; via secure channel, share a password and/or the
> derived key. If hww supports derivation function, it can derive the key
> from password. If hww supports only keys, the key can be entered raw or
> via mnemonic.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 3372 bytes --]

 permalink raw reply	[|nested]
2021-02-11 19:11               ` Hugo Nguyen

  2021-02-11 22:29                   ` Christopher Allen
  
From: Hugo Nguyen @ 2021-02-11 19:11 UTC (permalink / raw)
  To: Dmitry Petukhov, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2674 bytes --]

*BIP39 seed words list.

On Thu, Feb 11, 2021 at 11:11 AM Hugo Nguyen <hugo@nunchuk•io> wrote:

> Hi Pavol,
>
> On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> В Thu, 11 Feb 2021 05:45:33 -0800
>> Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
>> wrote:
>>
>> > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))
>> > >
>> > > This scheme might be vulnerable to rainbow table attack.
>> > >
>> >
>> > Thank you for pointing this out! Incidentally, Dmitry Petukhov also
>> > told me the same privately.
>>
>> My thought was that if TOKEN has the characteristics of a password
>> (short ASCII string), then it would be better to use key derivation
>> function designed for passwords, like PBKDF2.
>>
>> The counter-argument to this is that this adds another code dependency
>> for vendors, if the device firmware does not already have the required
>> key derivation function.
>>
>> Maybe this could be solved by going into opposite direction - make the
>> "token" even longer, use the mnemoic.
>>
>> The issue is that entering long data of the shared key into the device
>> manually is difficult UX-wise.
>>
>> Hww vendors that allow to enter custom keys into their device already
>> have to face this issue, and those who allow to enter custom keys via
>> mnemonic probably tackled this somehow.
>>
>> Maybe the shared key for multisig setup can be entered in the same way
>> ? (with maybe additional visual check via some fingerprint).
>>
>
> You just gave me a great idea! We can reuse the BIP32 seed words list!
> Perhaps the encryption key can just be 6 words, but it'll be derived the
> same way. BIP39 also uses PBKDF2 as a key derivation function, so it
> matches with what you described here.
>
> And all HWW should have this functionality already.
>
> Best,
> Hugo
>
>
>>
>> Although we would then have another issue of potential confusion
>> between two procedures (entering the main key and entering the shared
>> key for multisig setup), and the measures has to be taken to prevent
>> such confusion.
>>
>> The approaches can be combined - specify a key derivation function
>> suitable for passwords; via secure channel, share a password and/or the
>> derived key. If hww supports derivation function, it can derive the key
>> from password. If hww supports only keys, the key can be entered raw or
>> via mnemonic.
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>

[-- Attachment #2: Type: text/html, Size: 3759 bytes --]

 permalink raw reply	[|nested]
2021-02-11 19:11                 ` Hugo Nguyen

  2021-02-12 12:31                     ` Hugo Nguyen
  2021-02-12 13:48                     ` Peter D. Gray
  
From: Christopher Allen @ 2021-02-11 22:29 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 2741 bytes --]

I think the key issue here is avoiding xpub key reuse in multisig. Not only
in the future with Schnorr, but we need it today!

Current common practice by hardware wallets is the 48'/0'/0'/2' derivation
for segwit multsig ( e.g.
[90081696/48'/0'/0'/2']xpub6DYLEkDfCdHzh5FHGHDJksQvFqu6kYANa1sfo6fA8n5ZWkSwyCRVVzyq9LY2eNGB6T9BKDeGJp2ZarjRZHd7WB95nSaFEDhFMK6zSV6D49b
) is the only one used for ALL multisigs offered by that hardware wallet.

As Pieter said, leveraging a HD path parameters can help, but we need a
better, less reusable path for the index.

I personally suggest a simpler solution, which is to create an index using
a PBKDF of the Account Policy (a descriptor with all xpubs and keys
removed), plus optional notes. (BTW, I think double sha256 or HMAC is
overkill).

Example: for the reference bit descriptor that might result in:

```
wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))
```

What Blockchain Commons (and the Airgapped Wallet Community) call a policy
map would be

```
wsh(sortedmulti(1,,,))
```

A PBKDF of that as would be unique for all 2 of 3 segwig transactions. With
the addition of the addition of the Policy Map creators optional note, it
would be truly unique. The Policy Map and/or PBKDF are small and could
easily added to existing APIs.

So for legacy hardware, we can use existing 48' subtree, but 3' as the
format for this form (2' is segwit), then the desktop can just ask for the
/48'/0'/0'/3'/PBKDF' when it requests a new xpub from the hardware token.
More sophisticated Airgapped apps you can send
"wsh(sortedmulti(1,,,))"+label and let the cosigner app do the PBKDF, and
optionally allow it return something different in a full keyset (i.e.
"[90081696/48'/0'/0'/3'/af3948cg…'/]xpub6DYLEk…", and then the requesting
app, knowing that it is different from the PBKDF can know what to do if it
needs to what to ask for in the future.

The other advantage of this technique is that the cosigner app can know
what policy it is participating in, before the descriptor is completed. It
may decide it doesn't want to participate in some funky 4:9 with a weird
script, and not return an xpub at all.

Long term I think a commitment scheme should be used, so that you don't
reveal what xpub you offered until all the parties xpubs are shared, but as
Pieter said, we can do that at the same time we do the musig. But we need
to prevent xpub reuse NOW, and I think my proposal easy and could the job.

-- Christopher Allen, Blockchain Commons

[-- Attachment #2: Type: text/html, Size: 2926 bytes --]

 permalink raw reply	[|nested]
2021-02-11 22:29                   ` Christopher Allen

  2021-02-12 13:48                     ` Peter D. Gray
  
From: Hugo Nguyen @ 2021-02-12 12:31 UTC (permalink / raw)
  To: Christopher Allen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 5447 bytes --]

On Thu, Feb 11, 2021 at 3:05 PM Christopher Allen via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> What Blockchain Commons (and the Airgapped Wallet Community) call a policy
> map would be
>
> ```
> wsh(sortedmulti(1,,,))
> ```
>
> A PBKDF of that as would be unique for all 2 of 3 segwig transactions.
> With the addition of the addition of the Policy Map creators optional note,
> it would be truly unique. The Policy Map and/or PBKDF are small and could
> easily added to existing APIs.
>
> So for legacy hardware, we can use existing 48' subtree, but 3' as the
> format for this form (2' is segwit), then the desktop can just ask for the
> /48'/0'/0'/3'/PBKDF' when it requests a new xpub from the hardware token.
> More sophisticated Airgapped apps you can send
> "wsh(sortedmulti(1,,,))"+label and let the cosigner app do the PBKDF, and
> optionally allow it return something different in a full keyset (i.e.
> "[90081696/48'/0'/0'/3'/af3948cg…'/]xpub6DYLEk…", and then the requesting
> app, knowing that it is different from the PBKDF can know what to do if it
> needs to what to ask for in the future.
>

Thanks Christopher, very interesting ideas... A couple of thoughts:
1/ Generating the path index using the policy is clever. However, I think
it has 2 problems. Number #1 is with the above scheme now you have a hard
dependency on (policy map + note) - losing (policy map + note) means that
you will lose access to PBKDF', and hence the funds permanently. At least
with the current soluttions, you can look up what the most common
derivation paths and indices are to recover funds in the worst case.
2/ Number #2 is that this wouldn't necessarily prevent XPUB reuse. It seems
like the above scheme depends on (a) the Coordinator keeping track
accurately of all the existing PBKDF-ed indices and (b) the Signer
truthfully gives the XPUB at the path that the Coordinator asks for. In
reality, neither of these conditions can be guaranteed. For example, the
Signer could lie about the XPUB at /48'/0'/0'/3'/PBKDF' when it just keeps
reusing the XPUB at /48'/0'/0'/2'
3/ Preventing XPUB reuse is an interesting problem, but IMHO it is beyond
the scope of the current proposal. Maybe worth a separate BIP?

Best,
Hugo



On Thu, Feb 11, 2021 at 3:05 PM Christopher Allen via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> I think the key issue here is avoiding xpub key reuse in multisig. Not
> only in the future with Schnorr, but we need it today!
>
> Current common practice by hardware wallets is the 48'/0'/0'/2' derivation
> for segwit multsig ( e.g.
> [90081696/48'/0'/0'/2']xpub6DYLEkDfCdHzh5FHGHDJksQvFqu6kYANa1sfo6fA8n5ZWkSwyCRVVzyq9LY2eNGB6T9BKDeGJp2ZarjRZHd7WB95nSaFEDhFMK6zSV6D49b
> ) is the only one used for ALL multisigs offered by that hardware wallet.
>
> As Pieter said, leveraging a HD path parameters can help, but we need a
> better, less reusable path for the index.
>
> I personally suggest a simpler solution, which is to create an index using
> a PBKDF of the Account Policy (a descriptor with all xpubs and keys
> removed), plus optional notes. (BTW, I think double sha256 or HMAC is
> overkill).
>
> Example: for the reference bit descriptor that might result in:
>
> ```
>
> wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))
> ```
>
> What Blockchain Commons (and the Airgapped Wallet Community) call a policy
> map would be
>
> ```
> wsh(sortedmulti(1,,,))
> ```
>
> A PBKDF of that as would be unique for all 2 of 3 segwig transactions.
> With the addition of the addition of the Policy Map creators optional note,
> it would be truly unique. The Policy Map and/or PBKDF are small and could
> easily added to existing APIs.
>
> So for legacy hardware, we can use existing 48' subtree, but 3' as the
> format for this form (2' is segwit), then the desktop can just ask for the
> /48'/0'/0'/3'/PBKDF' when it requests a new xpub from the hardware token.
> More sophisticated Airgapped apps you can send
> "wsh(sortedmulti(1,,,))"+label and let the cosigner app do the PBKDF, and
> optionally allow it return something different in a full keyset (i.e.
> "[90081696/48'/0'/0'/3'/af3948cg…'/]xpub6DYLEk…", and then the requesting
> app, knowing that it is different from the PBKDF can know what to do if it
> needs to what to ask for in the future.
>
> The other advantage of this technique is that the cosigner app can know
> what policy it is participating in, before the descriptor is completed. It
> may decide it doesn't want to participate in some funky 4:9 with a weird
> script, and not return an xpub at all.
>
> Long term I think a commitment scheme should be used, so that you don't
> reveal what xpub you offered until all the parties xpubs are shared, but as
> Pieter said, we can do that at the same time we do the musig. But we need
> to prevent xpub reuse NOW, and I think my proposal easy and could the job.
>
> -- Christopher Allen, Blockchain Commons
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 6397 bytes --]

 permalink raw reply	[|nested]
2021-02-11 22:29                   ` Christopher Allen
  2021-02-12 12:31                     ` Hugo Nguyen

  
From: Peter D. Gray @ 2021-02-12 13:48 UTC (permalink / raw)
  To: Christopher Allen;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3534 bytes --]

Hard no to this idea:

On Thu, Feb 11, 2021 at 02:29:46PM -0800, Christopher Allen proposed:
...
> /48'/0'/0'/3'/PBKDF(complex string)'

As someone who has helped people find UTXO at key paths they didn't
know/want, this is a terrible idea. Key derivation paths should be
small, sequential integers, so they can be searched in reasonable time.

Of course when things are working it doesn't matter, but the stakes
can be very high when they stop working.

This is true for multisig and single signer.

---
Peter D. Gray  ||  Founder, Coinkite  ||  Twitter: @dochex  ||  GPG: A3A31BAD 5A2A5B10

On Thu, Feb 11, 2021 at 02:29:46PM -0800, Christopher Allen wrote:
> I think the key issue here is avoiding xpub key reuse in multisig. Not only
> in the future with Schnorr, but we need it today!
> 
> Current common practice by hardware wallets is the 48'/0'/0'/2' derivation
> for segwit multsig ( e.g.
> [90081696/48'/0'/0'/2']xpub6DYLEkDfCdHzh5FHGHDJksQvFqu6kYANa1sfo6fA8n5ZWkSwyCRVVzyq9LY2eNGB6T9BKDeGJp2ZarjRZHd7WB95nSaFEDhFMK6zSV6D49b
> ) is the only one used for ALL multisigs offered by that hardware wallet.
> 
> As Pieter said, leveraging a HD path parameters can help, but we need a
> better, less reusable path for the index.
> 
> I personally suggest a simpler solution, which is to create an index using
> a PBKDF of the Account Policy (a descriptor with all xpubs and keys
> removed), plus optional notes. (BTW, I think double sha256 or HMAC is
> overkill).
> 
> Example: for the reference bit descriptor that might result in:
> 
> ```
> wsh(sortedmulti(2,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))
> ```
> 
> What Blockchain Commons (and the Airgapped Wallet Community) call a policy
> map would be
> 
> ```
> wsh(sortedmulti(1,,,))
> ```
> 
> A PBKDF of that as would be unique for all 2 of 3 segwig transactions. With
> the addition of the addition of the Policy Map creators optional note, it
> would be truly unique. The Policy Map and/or PBKDF are small and could
> easily added to existing APIs.
> 
> So for legacy hardware, we can use existing 48' subtree, but 3' as the
> format for this form (2' is segwit), then the desktop can just ask for the
> /48'/0'/0'/3'/PBKDF' when it requests a new xpub from the hardware token.
> More sophisticated Airgapped apps you can send
> "wsh(sortedmulti(1,,,))"+label and let the cosigner app do the PBKDF, and
> optionally allow it return something different in a full keyset (i.e.
> "[90081696/48'/0'/0'/3'/af3948cg…'/]xpub6DYLEk…", and then the requesting
> app, knowing that it is different from the PBKDF can know what to do if it
> needs to what to ask for in the future.
> 
> The other advantage of this technique is that the cosigner app can know
> what policy it is participating in, before the descriptor is completed. It
> may decide it doesn't want to participate in some funky 4:9 with a weird
> script, and not return an xpub at all.
> 
> Long term I think a commitment scheme should be used, so that you don't
> reveal what xpub you offered until all the parties xpubs are shared, but as
> Pieter said, we can do that at the same time we do the musig. But we need
> to prevent xpub reuse NOW, and I think my proposal easy and could the job.
> 
> -- Christopher Allen, Blockchain Commons



[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

 permalink raw reply	[|nested]
2021-02-11 16:29             ` Dmitry Petukhov
  2021-02-11 19:11               ` Hugo Nguyen

  2021-02-12 17:42                 ` Dmitry Petukhov
  
From: Hugo Nguyen @ 2021-02-12 16:55 UTC (permalink / raw)
  To: Dmitry Petukhov, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3423 bytes --]

Thanks everyone who has provided inputs so far!

This is the new proposal for the encryption aspect of the scheme, based on
all the feedback.

The key derivation function would be PBKDF2, with PRF = SHA512. This should
be readily available on today's hardware already, as they are used for
BIP39.

DK = PBKDF2(PRF, Password, Salt, c, dkLen)
PRF = SHA512
Pwd = HUMAN_READABLE_TITLE
Salt = NONCE
c = 2048
dkLen = 256

HUMAN_READABLE_TITLE is in ASCII format, minimum length = 8, maximum length
= 20.
NONCE is a 64-bit number.

Reason for going with SHA512 is due to legacy support on some hardware.
c=2048 also mimics BIP39. It takes about ~3 seconds to derive
the encryption key on a 80Mhz MCU. We feel like this is a good enough
tradeoff for this use case. The assumption here is that the secure session
is only needed temporarily for a few hours, maybe up to one day.

The Coordinator and Signers agree and exchange these 2 secrets prior to the
setup. The NONCE can be converted to either:
(a) a 6-word phrase using BIP39 wordlist
(b) a 20-digit decimal number
(c) a QR code

Depending on the vendor. This flexibility in the data format allows each
vendor to customize the UX based on their respective device capabilities.

Best,
Hugo

On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> В Thu, 11 Feb 2021 05:45:33 -0800
> Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
> wrote:
>
> > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))
> > >
> > > This scheme might be vulnerable to rainbow table attack.
> > >
> >
> > Thank you for pointing this out! Incidentally, Dmitry Petukhov also
> > told me the same privately.
>
> My thought was that if TOKEN has the characteristics of a password
> (short ASCII string), then it would be better to use key derivation
> function designed for passwords, like PBKDF2.
>
> The counter-argument to this is that this adds another code dependency
> for vendors, if the device firmware does not already have the required
> key derivation function.
>
> Maybe this could be solved by going into opposite direction - make the
> "token" even longer, use the mnemoic.
>
> The issue is that entering long data of the shared key into the device
> manually is difficult UX-wise.
>
> Hww vendors that allow to enter custom keys into their device already
> have to face this issue, and those who allow to enter custom keys via
> mnemonic probably tackled this somehow.
>
> Maybe the shared key for multisig setup can be entered in the same way
> ? (with maybe additional visual check via some fingerprint).
>
> Although we would then have another issue of potential confusion
> between two procedures (entering the main key and entering the shared
> key for multisig setup), and the measures has to be taken to prevent
> such confusion.
>
> The approaches can be combined - specify a key derivation function
> suitable for passwords; via secure channel, share a password and/or the
> derived key. If hww supports derivation function, it can derive the key
> from password. If hww supports only keys, the key can be entered raw or
> via mnemonic.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 4198 bytes --]

 permalink raw reply	[|nested]
2021-02-12 16:55               ` Hugo Nguyen

  2021-02-12 17:48                   ` Dmitry Petukhov
  2021-02-12 17:54                   ` Hugo Nguyen
  
From: Dmitry Petukhov @ 2021-02-12 17:42 UTC (permalink / raw)
  To: Hugo Nguyen;  Bitcoin Protocol Discussion

If HUMAN_READABLE_TITLE is the additional secret, the user would need
to enter it on the device in addition to the nonce, wouldn't it defeat
the advantage in UX that was gained by using (relatively) short nonce ?

Is 64 bit nonce not enough ?

It seems that to crack this with fixed Pwd and 64 bit nonce, the
attacker will need to be about 10^15 more powerful than 80Mhz MCU:
(2^64)/(0.3*10^15)/3600 = 17 hours. I don't know if 10^15 is realistic
scale. Average desktop cpu seems to be about 10^3 more powerful than
the mentioned MCU for this task.

Maybe for the UX it would be better to choose the number of rounds to
use in PBKDF2, instead of using variable Pwd. Number of rounds will be
easier to enter on the device (or just choose it from a set of
pre-defined values). The more money is at stake, the higher number of
rounds could the coordinator choose (taking into account the
characteristics of the participant devices)

В Fri, 12 Feb 2021 08:55:55 -0800
Hugo Nguyen <hugo@nunchuk•io> wrote:

> Thanks everyone who has provided inputs so far!
> 
> This is the new proposal for the encryption aspect of the scheme,
> based on all the feedback.
> 
> The key derivation function would be PBKDF2, with PRF = SHA512. This
> should be readily available on today's hardware already, as they are
> used for BIP39.
> 
> DK = PBKDF2(PRF, Password, Salt, c, dkLen)
> PRF = SHA512
> Pwd = HUMAN_READABLE_TITLE
> Salt = NONCE
> c = 2048
> dkLen = 256
> 
> HUMAN_READABLE_TITLE is in ASCII format, minimum length = 8, maximum
> length = 20.
> NONCE is a 64-bit number.
> 
> Reason for going with SHA512 is due to legacy support on some
> hardware. c=2048 also mimics BIP39. It takes about ~3 seconds to
> derive the encryption key on a 80Mhz MCU. We feel like this is a good
> enough tradeoff for this use case. The assumption here is that the
> secure session is only needed temporarily for a few hours, maybe up
> to one day.
> 
> The Coordinator and Signers agree and exchange these 2 secrets prior
> to the setup. The NONCE can be converted to either:
> (a) a 6-word phrase using BIP39 wordlist
> (b) a 20-digit decimal number
> (c) a QR code
> 
> Depending on the vendor. This flexibility in the data format allows
> each vendor to customize the UX based on their respective device
> capabilities.
> 
> Best,
> Hugo
> 
> On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
> 
> > В Thu, 11 Feb 2021 05:45:33 -0800
> > Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
> > wrote:
> >  
> > > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))  
> > > >
> > > > This scheme might be vulnerable to rainbow table attack.
> > > >  
> > >
> > > Thank you for pointing this out! Incidentally, Dmitry Petukhov
> > > also told me the same privately.  
> >
> > My thought was that if TOKEN has the characteristics of a password
> > (short ASCII string), then it would be better to use key derivation
> > function designed for passwords, like PBKDF2.
> >
> > The counter-argument to this is that this adds another code
> > dependency for vendors, if the device firmware does not already
> > have the required key derivation function.
> >
> > Maybe this could be solved by going into opposite direction - make
> > the "token" even longer, use the mnemoic.
> >
> > The issue is that entering long data of the shared key into the
> > device manually is difficult UX-wise.
> >
> > Hww vendors that allow to enter custom keys into their device
> > already have to face this issue, and those who allow to enter
> > custom keys via mnemonic probably tackled this somehow.
> >
> > Maybe the shared key for multisig setup can be entered in the same
> > way ? (with maybe additional visual check via some fingerprint).
> >
> > Although we would then have another issue of potential confusion
> > between two procedures (entering the main key and entering the
> > shared key for multisig setup), and the measures has to be taken to
> > prevent such confusion.
> >
> > The approaches can be combined - specify a key derivation function
> > suitable for passwords; via secure channel, share a password and/or
> > the derived key. If hww supports derivation function, it can derive
> > the key from password. If hww supports only keys, the key can be
> > entered raw or via mnemonic.
> > _______________________________________________
> > bitcoin-dev mailing list
> > bitcoin-dev@lists•linuxfoundation.org
> > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> >  



 permalink raw reply	[|nested]
2021-02-12 17:42                 ` Dmitry Petukhov

  2021-02-12 17:54                   ` Hugo Nguyen
  
From: Dmitry Petukhov @ 2021-02-12 17:48 UTC (permalink / raw)
  To: Hugo Nguyen;  Bitcoin Protocol Discussion

В Fri, 12 Feb 2021 18:42:31 +0100
Dmitry Petukhov <dp@simplexum•com> wrote:

> Maybe for the UX it would be better to choose the number of rounds to
> use in PBKDF2, instead of using variable Pwd. Number of rounds will be
> easier to enter on the device (or just choose it from a set of
> pre-defined values). The more money is at stake, the higher number of
> rounds could the coordinator choose (taking into account the
> characteristics of the participant devices)

Or simply allow bigger entropy (more than 6 mnemonic words), if
the coordinator feels that 64 bit of entropy is not enough.


 permalink raw reply	[|nested]
2021-02-12 17:42                 ` Dmitry Petukhov
  2021-02-12 17:48                   ` Dmitry Petukhov

  2021-02-14 10:37                     ` Dmitry Petukhov
  
From: Hugo Nguyen @ 2021-02-12 17:54 UTC (permalink / raw)
  To: Dmitry Petukhov;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 5330 bytes --]

On Fri, Feb 12, 2021 at 9:36 AM Dmitry Petukhov <dp@simplexum•com> wrote:

> If HUMAN_READABLE_TITLE is the additional secret, the user would need
> to enter it on the device in addition to the nonce, wouldn't it defeat
> the advantage in UX that was gained by using (relatively) short nonce ?
>
> Is 64 bit nonce not enough ?
>
>
Good question. If we don't need the extra entropy, we can fix
the HUMAN_READABLE_TITLE string.

Something like "No SPOF". (No Single Point Of Failure).



> It seems that to crack this with fixed Pwd and 64 bit nonce, the
> attacker will need to be about 10^15 more powerful than 80Mhz MCU:
> (2^64)/(0.3*10^15)/3600 = 17 hours. I don't know if 10^15 is realistic
> scale. Average desktop cpu seems to be about 10^3 more powerful than
> the mentioned MCU for this task.
>
> Maybe for the UX it would be better to choose the number of rounds to
> use in PBKDF2, instead of using variable Pwd. Number of rounds will be
> easier to enter on the device (or just choose it from a set of
> pre-defined values). The more money is at stake, the higher number of
> rounds could the coordinator choose (taking into account the
> characteristics of the participant devices)
>

> Or simply allow bigger entropy (more than 6 mnemonic words), if
> the coordinator feels that 64 bit of entropy is not enough.


That could work. Allowing variable iteration count is probably better
UX-wise.

Best,
Hugo


>
> В Fri, 12 Feb 2021 08:55:55 -0800
> Hugo Nguyen <hugo@nunchuk•io> wrote:
>
> > Thanks everyone who has provided inputs so far!
> >
> > This is the new proposal for the encryption aspect of the scheme,
> > based on all the feedback.
> >
> > The key derivation function would be PBKDF2, with PRF = SHA512. This
> > should be readily available on today's hardware already, as they are
> > used for BIP39.
> >
> > DK = PBKDF2(PRF, Password, Salt, c, dkLen)
> > PRF = SHA512
> > Pwd = HUMAN_READABLE_TITLE
> > Salt = NONCE
> > c = 2048
> > dkLen = 256
> >
> > HUMAN_READABLE_TITLE is in ASCII format, minimum length = 8, maximum
> > length = 20.
> > NONCE is a 64-bit number.
> >
> > Reason for going with SHA512 is due to legacy support on some
> > hardware. c=2048 also mimics BIP39. It takes about ~3 seconds to
> > derive the encryption key on a 80Mhz MCU. We feel like this is a good
> > enough tradeoff for this use case. The assumption here is that the
> > secure session is only needed temporarily for a few hours, maybe up
> > to one day.
> >
> > The Coordinator and Signers agree and exchange these 2 secrets prior
> > to the setup. The NONCE can be converted to either:
> > (a) a 6-word phrase using BIP39 wordlist
> > (b) a 20-digit decimal number
> > (c) a QR code
> >
> > Depending on the vendor. This flexibility in the data format allows
> > each vendor to customize the UX based on their respective device
> > capabilities.
> >
> > Best,
> > Hugo
> >
> > On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
> > bitcoin-dev@lists•linuxfoundation.org> wrote:
> >
> > > В Thu, 11 Feb 2021 05:45:33 -0800
> > > Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org>
> > > wrote:
> > >
> > > > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))
> > > > >
> > > > > This scheme might be vulnerable to rainbow table attack.
> > > > >
> > > >
> > > > Thank you for pointing this out! Incidentally, Dmitry Petukhov
> > > > also told me the same privately.
> > >
> > > My thought was that if TOKEN has the characteristics of a password
> > > (short ASCII string), then it would be better to use key derivation
> > > function designed for passwords, like PBKDF2.
> > >
> > > The counter-argument to this is that this adds another code
> > > dependency for vendors, if the device firmware does not already
> > > have the required key derivation function.
> > >
> > > Maybe this could be solved by going into opposite direction - make
> > > the "token" even longer, use the mnemoic.
> > >
> > > The issue is that entering long data of the shared key into the
> > > device manually is difficult UX-wise.
> > >
> > > Hww vendors that allow to enter custom keys into their device
> > > already have to face this issue, and those who allow to enter
> > > custom keys via mnemonic probably tackled this somehow.
> > >
> > > Maybe the shared key for multisig setup can be entered in the same
> > > way ? (with maybe additional visual check via some fingerprint).
> > >
> > > Although we would then have another issue of potential confusion
> > > between two procedures (entering the main key and entering the
> > > shared key for multisig setup), and the measures has to be taken to
> > > prevent such confusion.
> > >
> > > The approaches can be combined - specify a key derivation function
> > > suitable for passwords; via secure channel, share a password and/or
> > > the derived key. If hww supports derivation function, it can derive
> > > the key from password. If hww supports only keys, the key can be
> > > entered raw or via mnemonic.
> > > _______________________________________________
> > > bitcoin-dev mailing list
> > > bitcoin-dev@lists•linuxfoundation.org
> > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> > >
>
>

[-- Attachment #2: Type: text/html, Size: 7243 bytes --]

 permalink raw reply	[|nested]
2021-02-12 17:54                   ` Hugo Nguyen

  2021-02-14 11:28                       ` Dmitry Petukhov
  
From: Dmitry Petukhov @ 2021-02-14 10:37 UTC (permalink / raw)
  To: Hugo Nguyen;  Bitcoin Protocol Discussion

I think that it is better to issue individual TOKEN for each
participant. Otherwise it will be possible for one participant to
attack another (intercept and replace their xpub sent to the
coordinator).

It will also be convenient to have a public 'participant id', derived
from the token. It can be derived from the same token, but with
different (but fixed) `Pwd`. With unique token per participant, such
derivation will uniquely identify each participant, so the coordinator
won't need to try all the tokens to decrypt the data.

It will also be easier to deal with more elaborate setups where the
position of the xpub in the descriptor does matter - for example, with
miniscript-extended descriptors. With a descriptor template such as

`wsh(or(multi(2, <Alice>, <Bob>, <Carol>), older(1000, <Dylan>))`

The coordinator will be able to store the map between the participant
labels (Alice, Bob, Carol, Dylan) and their participant ids (and the
TOKENs). When the data from Alice comes with participant id attached,
the coordinator will immediately know which TOKEN to use, and which
place in the descriptor the xpub should be put in.

Of course this is all possible without 'participant id' derived from
token, as long as there's unique TOKEN per participant - the coordinator
can always try all the tokens to decrypt the data from participant. But
implementors will likely invent their own ways to introduce
'participant id' anyway, as this is more convenient, and it might make
sense to have this standardized, for interoperability. 

В Fri, 12 Feb 2021 09:54:57 -0800
Hugo Nguyen <hugo@nunchuk•io> wrote:

> On Fri, Feb 12, 2021 at 9:36 AM Dmitry Petukhov <dp@simplexum•com>
> wrote:
> 
> > If HUMAN_READABLE_TITLE is the additional secret, the user would
> > need to enter it on the device in addition to the nonce, wouldn't
> > it defeat the advantage in UX that was gained by using (relatively)
> > short nonce ?
> >
> > Is 64 bit nonce not enough ?
> >
> >  
> Good question. If we don't need the extra entropy, we can fix
> the HUMAN_READABLE_TITLE string.
> 
> Something like "No SPOF". (No Single Point Of Failure).
> 
> 
> 
> > It seems that to crack this with fixed Pwd and 64 bit nonce, the
> > attacker will need to be about 10^15 more powerful than 80Mhz MCU:
> > (2^64)/(0.3*10^15)/3600 = 17 hours. I don't know if 10^15 is
> > realistic scale. Average desktop cpu seems to be about 10^3 more
> > powerful than the mentioned MCU for this task.
> >
> > Maybe for the UX it would be better to choose the number of rounds
> > to use in PBKDF2, instead of using variable Pwd. Number of rounds
> > will be easier to enter on the device (or just choose it from a set
> > of pre-defined values). The more money is at stake, the higher
> > number of rounds could the coordinator choose (taking into account
> > the characteristics of the participant devices)
> >  
> 
> > Or simply allow bigger entropy (more than 6 mnemonic words), if
> > the coordinator feels that 64 bit of entropy is not enough.  
> 
> 
> That could work. Allowing variable iteration count is probably better
> UX-wise.
> 
> Best,
> Hugo
> 
> 
> >
> > В Fri, 12 Feb 2021 08:55:55 -0800
> > Hugo Nguyen <hugo@nunchuk•io> wrote:
> >  
> > > Thanks everyone who has provided inputs so far!
> > >
> > > This is the new proposal for the encryption aspect of the scheme,
> > > based on all the feedback.
> > >
> > > The key derivation function would be PBKDF2, with PRF = SHA512.
> > > This should be readily available on today's hardware already, as
> > > they are used for BIP39.
> > >
> > > DK = PBKDF2(PRF, Password, Salt, c, dkLen)
> > > PRF = SHA512
> > > Pwd = HUMAN_READABLE_TITLE
> > > Salt = NONCE
> > > c = 2048
> > > dkLen = 256
> > >
> > > HUMAN_READABLE_TITLE is in ASCII format, minimum length = 8,
> > > maximum length = 20.
> > > NONCE is a 64-bit number.
> > >
> > > Reason for going with SHA512 is due to legacy support on some
> > > hardware. c=2048 also mimics BIP39. It takes about ~3 seconds to
> > > derive the encryption key on a 80Mhz MCU. We feel like this is a
> > > good enough tradeoff for this use case. The assumption here is
> > > that the secure session is only needed temporarily for a few
> > > hours, maybe up to one day.
> > >
> > > The Coordinator and Signers agree and exchange these 2 secrets
> > > prior to the setup. The NONCE can be converted to either:
> > > (a) a 6-word phrase using BIP39 wordlist
> > > (b) a 20-digit decimal number
> > > (c) a QR code
> > >
> > > Depending on the vendor. This flexibility in the data format
> > > allows each vendor to customize the UX based on their respective
> > > device capabilities.
> > >
> > > Best,
> > > Hugo
> > >
> > > On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev <
> > > bitcoin-dev@lists•linuxfoundation.org> wrote:
> > >  
> > > > В Thu, 11 Feb 2021 05:45:33 -0800
> > > > Hugo Nguyen via bitcoin-dev
> > > > <bitcoin-dev@lists•linuxfoundation.org> wrote:
> > > >  
> > > > > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))  
> > > > > >
> > > > > > This scheme might be vulnerable to rainbow table attack.
> > > > > >  
> > > > >
> > > > > Thank you for pointing this out! Incidentally, Dmitry Petukhov
> > > > > also told me the same privately.  
> > > >
> > > > My thought was that if TOKEN has the characteristics of a
> > > > password (short ASCII string), then it would be better to use
> > > > key derivation function designed for passwords, like PBKDF2.
> > > >
> > > > The counter-argument to this is that this adds another code
> > > > dependency for vendors, if the device firmware does not already
> > > > have the required key derivation function.
> > > >
> > > > Maybe this could be solved by going into opposite direction -
> > > > make the "token" even longer, use the mnemoic.
> > > >
> > > > The issue is that entering long data of the shared key into the
> > > > device manually is difficult UX-wise.
> > > >
> > > > Hww vendors that allow to enter custom keys into their device
> > > > already have to face this issue, and those who allow to enter
> > > > custom keys via mnemonic probably tackled this somehow.
> > > >
> > > > Maybe the shared key for multisig setup can be entered in the
> > > > same way ? (with maybe additional visual check via some
> > > > fingerprint).
> > > >
> > > > Although we would then have another issue of potential confusion
> > > > between two procedures (entering the main key and entering the
> > > > shared key for multisig setup), and the measures has to be
> > > > taken to prevent such confusion.
> > > >
> > > > The approaches can be combined - specify a key derivation
> > > > function suitable for passwords; via secure channel, share a
> > > > password and/or the derived key. If hww supports derivation
> > > > function, it can derive the key from password. If hww supports
> > > > only keys, the key can be entered raw or via mnemonic.
> > > > _______________________________________________
> > > > bitcoin-dev mailing list
> > > > bitcoin-dev@lists•linuxfoundation.org
> > > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> > > >  
> >
> >  



 permalink raw reply	[|nested]
2021-02-14 10:37                     ` Dmitry Petukhov

  
From: Dmitry Petukhov @ 2021-02-14 11:28 UTC (permalink / raw)
  To: Hugo Nguyen;  Bitcoin Protocol Discussion

After off-list discussion with Hugo, I'm convinced that
adding a requirement for signers to derive participant ids is
unnecessary complication that only buys slight convenience for
coordinator, and this is not a net positive tradeoff.

And since the coordinator can choose to generate unique TOKEN per
participant without participants even knowing about this, there's
probably no reason to mention this possibility in the spec, either.

В Sun, 14 Feb 2021 11:37:52 +0100
Dmitry Petukhov <dp@simplexum•com> wrote:

> I think that it is better to issue individual TOKEN for each
> participant. Otherwise it will be possible for one participant to
> attack another (intercept and replace their xpub sent to the
> coordinator).
> 
> It will also be convenient to have a public 'participant id', derived
> from the token. It can be derived from the same token, but with
> different (but fixed) `Pwd`. With unique token per participant, such
> derivation will uniquely identify each participant, so the coordinator
> won't need to try all the tokens to decrypt the data.
> 
> It will also be easier to deal with more elaborate setups where the
> position of the xpub in the descriptor does matter - for example, with
> miniscript-extended descriptors. With a descriptor template such as
> 
> `wsh(or(multi(2, <Alice>, <Bob>, <Carol>), older(1000, <Dylan>))`
> 
> The coordinator will be able to store the map between the participant
> labels (Alice, Bob, Carol, Dylan) and their participant ids (and the
> TOKENs). When the data from Alice comes with participant id attached,
> the coordinator will immediately know which TOKEN to use, and which
> place in the descriptor the xpub should be put in.
> 
> Of course this is all possible without 'participant id' derived from
> token, as long as there's unique TOKEN per participant - the
> coordinator can always try all the tokens to decrypt the data from
> participant. But implementors will likely invent their own ways to
> introduce 'participant id' anyway, as this is more convenient, and it
> might make sense to have this standardized, for interoperability. 
> 
> В Fri, 12 Feb 2021 09:54:57 -0800
> Hugo Nguyen <hugo@nunchuk•io> wrote:
> 
> > On Fri, Feb 12, 2021 at 9:36 AM Dmitry Petukhov <dp@simplexum•com>
> > wrote:
> >   
> > > If HUMAN_READABLE_TITLE is the additional secret, the user would
> > > need to enter it on the device in addition to the nonce, wouldn't
> > > it defeat the advantage in UX that was gained by using
> > > (relatively) short nonce ?
> > >
> > > Is 64 bit nonce not enough ?
> > >
> > >    
> > Good question. If we don't need the extra entropy, we can fix
> > the HUMAN_READABLE_TITLE string.
> > 
> > Something like "No SPOF". (No Single Point Of Failure).
> > 
> > 
> >   
> > > It seems that to crack this with fixed Pwd and 64 bit nonce, the
> > > attacker will need to be about 10^15 more powerful than 80Mhz MCU:
> > > (2^64)/(0.3*10^15)/3600 = 17 hours. I don't know if 10^15 is
> > > realistic scale. Average desktop cpu seems to be about 10^3 more
> > > powerful than the mentioned MCU for this task.
> > >
> > > Maybe for the UX it would be better to choose the number of rounds
> > > to use in PBKDF2, instead of using variable Pwd. Number of rounds
> > > will be easier to enter on the device (or just choose it from a
> > > set of pre-defined values). The more money is at stake, the higher
> > > number of rounds could the coordinator choose (taking into account
> > > the characteristics of the participant devices)
> > >    
> >   
> > > Or simply allow bigger entropy (more than 6 mnemonic words), if
> > > the coordinator feels that 64 bit of entropy is not enough.    
> > 
> > 
> > That could work. Allowing variable iteration count is probably
> > better UX-wise.
> > 
> > Best,
> > Hugo
> > 
> >   
> > >
> > > В Fri, 12 Feb 2021 08:55:55 -0800
> > > Hugo Nguyen <hugo@nunchuk•io> wrote:
> > >    
> > > > Thanks everyone who has provided inputs so far!
> > > >
> > > > This is the new proposal for the encryption aspect of the
> > > > scheme, based on all the feedback.
> > > >
> > > > The key derivation function would be PBKDF2, with PRF = SHA512.
> > > > This should be readily available on today's hardware already, as
> > > > they are used for BIP39.
> > > >
> > > > DK = PBKDF2(PRF, Password, Salt, c, dkLen)
> > > > PRF = SHA512
> > > > Pwd = HUMAN_READABLE_TITLE
> > > > Salt = NONCE
> > > > c = 2048
> > > > dkLen = 256
> > > >
> > > > HUMAN_READABLE_TITLE is in ASCII format, minimum length = 8,
> > > > maximum length = 20.
> > > > NONCE is a 64-bit number.
> > > >
> > > > Reason for going with SHA512 is due to legacy support on some
> > > > hardware. c=2048 also mimics BIP39. It takes about ~3 seconds to
> > > > derive the encryption key on a 80Mhz MCU. We feel like this is a
> > > > good enough tradeoff for this use case. The assumption here is
> > > > that the secure session is only needed temporarily for a few
> > > > hours, maybe up to one day.
> > > >
> > > > The Coordinator and Signers agree and exchange these 2 secrets
> > > > prior to the setup. The NONCE can be converted to either:
> > > > (a) a 6-word phrase using BIP39 wordlist
> > > > (b) a 20-digit decimal number
> > > > (c) a QR code
> > > >
> > > > Depending on the vendor. This flexibility in the data format
> > > > allows each vendor to customize the UX based on their respective
> > > > device capabilities.
> > > >
> > > > Best,
> > > > Hugo
> > > >
> > > > On Thu, Feb 11, 2021 at 8:25 AM Dmitry Petukhov via bitcoin-dev
> > > > < bitcoin-dev@lists•linuxfoundation.org> wrote:
> > > >    
> > > > > В Thu, 11 Feb 2021 05:45:33 -0800
> > > > > Hugo Nguyen via bitcoin-dev
> > > > > <bitcoin-dev@lists•linuxfoundation.org> wrote:
> > > > >    
> > > > > > > > ENCRYPTION_KEY = SHA256(SHA256(TOKEN))    
> > > > > > >
> > > > > > > This scheme might be vulnerable to rainbow table attack.
> > > > > > >    
> > > > > >
> > > > > > Thank you for pointing this out! Incidentally, Dmitry
> > > > > > Petukhov also told me the same privately.    
> > > > >
> > > > > My thought was that if TOKEN has the characteristics of a
> > > > > password (short ASCII string), then it would be better to use
> > > > > key derivation function designed for passwords, like PBKDF2.
> > > > >
> > > > > The counter-argument to this is that this adds another code
> > > > > dependency for vendors, if the device firmware does not
> > > > > already have the required key derivation function.
> > > > >
> > > > > Maybe this could be solved by going into opposite direction -
> > > > > make the "token" even longer, use the mnemoic.
> > > > >
> > > > > The issue is that entering long data of the shared key into
> > > > > the device manually is difficult UX-wise.
> > > > >
> > > > > Hww vendors that allow to enter custom keys into their device
> > > > > already have to face this issue, and those who allow to enter
> > > > > custom keys via mnemonic probably tackled this somehow.
> > > > >
> > > > > Maybe the shared key for multisig setup can be entered in the
> > > > > same way ? (with maybe additional visual check via some
> > > > > fingerprint).
> > > > >
> > > > > Although we would then have another issue of potential
> > > > > confusion between two procedures (entering the main key and
> > > > > entering the shared key for multisig setup), and the measures
> > > > > has to be taken to prevent such confusion.
> > > > >
> > > > > The approaches can be combined - specify a key derivation
> > > > > function suitable for passwords; via secure channel, share a
> > > > > password and/or the derived key. If hww supports derivation
> > > > > function, it can derive the key from password. If hww supports
> > > > > only keys, the key can be entered raw or via mnemonic.
> > > > > _______________________________________________
> > > > > bitcoin-dev mailing list
> > > > > bitcoin-dev@lists•linuxfoundation.org
> > > > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
> > > > >    
> > >
> > >    
> 



 permalink raw reply	[|nested]
2021-02-08 23:14 [bitcoin-dev] Proposal: Bitcoin Secure Multisig Setup Hugo Nguyen
                   ` (2 preceding siblings ...)
       [not found] ` <CACrqygA1JRA293joYOxxpSepiuFD=uVvQQy3wpuosYyLQHff-A@mail.gmail.com>

  2021-02-15 13:53   ` Craig Raw
  2021-04-05  7:02 ` Hugo Nguyen
  2021-04-10 13:53 ` Erik Aronesty
  
From: Hugo Nguyen @ 2021-02-15  8:44 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 11791 bytes --]

Hi all,
I have updated the proposal based on further feedback. The new spec is
included at the bottom.

I have also created a public Github PR to make it easier to comment on the
text of the spec itself: https://github.com/nunchuk-io/bips/pull/1 .

Could someone please let me know what else needs to be done before a BIP
number can be assigned?


=== Quick summary of changes from last update ===

1. Define encryption modes

# NO_ENCRYPTION: Encryption is disabled.
# STANDARD : the TOKEN is a 64-bit nonce.
# EXTENDED : the TOKEN is a 128-bit nonce.

2. Define signature algorithm

Follow BIP-0322, legacy format allowed.

3. Multiple TOKENs (optional)

Also add an option where the Coordinator can choose to use one common TOKEN
for all Signers, or use one per Signer.

=== End of summary ===


Cheers,
Hugo


<pre>
  BIP: To be determined
  Layer: Applications
  Title: Bitcoin Secure Multisig Setup (BSMS)
  Author: Hugo Nguyen <hugo at nunchuk.io>, Peter Gray <peter at
coinkite.com>, Marko Bencun <marko at shiftcrypto.ch>, Pavol Rusnak <
stick@satoshilabs•com>, Aaron Chen <aarondongchen at gmail.com>, Rodolfo
Novak <rodolfo at coinkite.com>
  Comments-Summary: No comments yet.
  Comments-URI:
  Status: Proposed
  Type: Standards Track
  Created: 2020-11-10
  License: BSD-2-Clause
</pre>

==Introduction==

===Abstract===

This document proposes a mechanism to set up multisig wallets securely.

===Copyright===

This BIP is licensed under the 2-clause BSD license.

===Motivation===

The Bitcoin multisig experience has been greatly streamlined under [
https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
(Partially Signed Bitcoin Transaction)]. However, what is still missing is
a standardized process for setting up multisig wallets securely across
different vendors.

There are a number of concerns when it comes to setting up a multisig
wallet:

# Whether the multisig configuration, such as Signer membership, script
type, derivation paths and number of signatures required, is correct and
not tampered with.
# Whether Signer persists the multisig configuration in their respective
storage, and under what format.
# Whether Signer's storage is tamper-proof.
# Whether Signer subsequently uses the multisig configuration to generate
and verify receive and change addresses.

An attacker who can modify the multisig configuration can steal or hold
funds to ransom by duping the user into sending funds to the wrong address.

This proposal seeks to address concerns #1 and #2: to mitigate the risk of
tampering during the initial setup phase, and to define an interoperable
multisig configuration format.

Concerns #3 and #4 should be handled by Signers and is out of scope of this
proposal.

==Specification==

===Prerequisites===
This proposal assumes the parties in the multisig support [
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032], [
https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
descriptor language] and encryption.

===Roles===
====Coordinator====

The Coordinator initiates the multisig setup. The Coordinator determines
what type of multisig is used and the exact policy script. If encryption is
enabled, the Coordinator also distributes a shared secret or shared secrets
to the parties involved for secure communication. The Coordinator gathers
information from the Signers to generate a descriptor record. The
Coordinator distributes the descriptor record back to the Signers.

====Signer====

The Signer is a participating member in the multisig. Its responsibilities
include providing its key record -- which contains an Extended Public Key
(XPUB) -- to the Coordinator, verifying that its XPUB is included in the
descriptor record and persisting the descriptor record in its storage.

===Setup Process===

====Round 1====

=====Coordinator=====

* The Coordinator creates a multisig wallet creation session. The
Coordinator constructs the multisig script and its policy parameters, such
as the total number of signers and the required number of signatures
(<tt>M</tt> and <tt>N</tt>).
* The session should expire after some time period determined by the
Coordinator, e.g., 24 hours.
* If encryption is enabled, the Coordinator distributes a secret
<tt>TOKEN</tt> to each Signer over a secure channel. The Signer can use the
<tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to the
Encryption section below for details on the <tt>TOKEN</tt>, the key
derivation function and the encryption scheme. Depending on the use case,
the Coordinator can decide whether to share one common <tt>TOKEN</tt> for
all Signers, or to have one per Signer.
* If encryption is disabled, <tt>TOKEN</tt> is set to <tt>0</tt>, and all
the encryption/decryption steps below can be skipped.

=====Signer=====

* The Signer initiates a new secure multisig setup session by setting the
<tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from the
<tt>TOKEN</tt>. The Signer can keep the session open until a different
value for the <tt>TOKEN</tt> is set.
* The Signer generates a key record by prompting the user for a multisig
derivation path and retrieves the XPUB at that derivation path. Optionally,
the Signer can choose a path on behalf of the user. If the Signer chooses
the path, it should try to avoid reusing XPUBs for different wallets.
* The first line in the record must be the <tt>TOKEN</tt>. The second line
must be the <tt>KEY</tt>. The <tt>KEY</tt> is an XPUB plus its key origin
information, written in the descriptor-defined format, i.e.: <tt>[{master
key fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a
<tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by using the
private key associated with the XPUB to sign the first two lines.  The
signature should follow [
https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322],
legacy format accepted. Finally, the Signer encrypts the entire record with
<tt>ENCRYPTION_KEY</tt>.

====Round 2====

=====Coordinator=====

* The Coordinator gathers key records from all participating Signers. Abort
the setup if the wallet setup session has expired.
* For each key record, the Coordinator decrypts it using
<tt>ENCRYPTION_KEY</tt>. The Coordinator verifies that the included
<tt>SIG</tt> is valid given the <tt>KEY</tt>.
* If all key records look good, the Coordinator fills in all necessary
information to generate a descriptor record, which is simply the descriptor
string plus a <tt>CHECKSUM</tt>, all in one line. The <tt>CHECKSUM</tt> has
[https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
BECH32 encoding].
* The Coordinator encrypts this descriptor record with
<tt>ENCRYPTION_KEY</tt>.
* The Coordinator sends the encrypted descriptor record to all
participating Signers.

=====Signer=====

* The Signer imports the descriptor record, decrypts it using the
<tt>ENCRYPTION_KEY</tt> derived from the open session.
* The Signer calculates and verifies the descriptor’s <tt>CHECKSUM</tt>.
Abort the setup if the <tt>CHECKSUM</tt> is incorrect.
* The Signer checks whether one of the <tt>KEY</tt>s in the descriptor
belongs to it, using path and fingerprint information included in the
descriptor. The check must perform an exact match on the <tt>KEY</tt>s, and
not using shortcuts such as matching fingerprints (which is trivial to
spoof). Abort the setup if it doesn’t detect its own <tt>KEY</tt>.
* For confirmation, the Signer must display to the user the
<tt>CHECKSUM</tt>, plus other configurations, such as <tt>M</tt> and
<tt>N</tt>. The total number of Signers, <tt>N</tt>, is important to
prevent a <tt>KEY</tt> insertion attack. All participating Signers should
be able to display the same confirmation.
* If all checks pass, the Signer persists the descriptor record in its
storage.
* The Signer can choose to further restrict post-XPUB derivation paths,
such as to those defined in [
https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP-0044].
* The Signer should subsequently use the descriptor to generate and verify
receive and change addresses.

This completes the setup.

===Encryption===

====The Token====
We define three modes of encryption.

# <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>.
Encryption is disabled.
# <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
# <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 128-bit nonce.

The <tt>TOKEN</tt> can be converted to one of these formats:
* A mnemonic phrase using [
https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039]
word list (6 words in <tt>STANDARD</tt> mode, 12 words in <tt>EXTENDED</tt>
mode)
* A decimal number (20 digits in <tt>STANDARD</tt> mode, 40 digits in
<tt>EXTENDED</tt> mode)
* A QR code
* Other formats

The flexibility in the data format allows each Signer to customize the User
Experience based on its respective capabilities.

====Key Derivation====
The key derivation function is [https://tools.ietf.org/html/rfc2898
PBKDF2], with PRF = SHA512. Specifically:

<tt>DK = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>

Whereas:

* PRF = <tt>SHA512</tt>
* Password = <tt>"No SPOF"</tt>
* Salt = <tt>TOKEN</tt>
* c = <tt>2048</tt>
* dkLen = <tt>256</tt>
* DK = Derived <tt>ENCRYPTION_KEY</tt>

====Encryption Scheme====
The encryption scheme is [https://tools.ietf.org/html/rfc3686 AES, CTR
mode].

==QR Codes==
For signers that use QR codes to transmit data, key and descriptor records
can be converted to QR codes, following [
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
the BCR standard].

Also refer to [
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
UR Type Definition for BIP44 Accounts] and [
https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
UR Type Definition for Bitcoin Output Descriptors] for more details.

==Security==

This proposal introduces two layers of protection. The first one is a
temporary, secret token, used to encrypt the two rounds of communication
between the Signer and the Coordinator. The second one is through the
descriptor checksum and visual inspection of the descriptor itself.

The token is only needed during the setup phase, and can be safely thrown
away afterwards. The token does not guarantee that the Signer membership
set is not modified, since that depends on the overall security of all
parties in the setup, but it can make it significantly harder for an
attacker to do so.

There are three ways an attacker can modify the membership set: by changing
an existing member, by removing an existing member, or by adding a new
member.

For the first two methods, one of the Signers will be able to detect that
its membership has been changed or removed, and reject the final
descriptor. Thus, it is vital that all participating Signers check that
their membership is intact in the descriptor. Even one Signer failing to
check for its membership means that the setup could be compromised.

For the third type of attack, the descriptor checksum and visual inspection
of the descriptor itself are the only way to guard against malicious
members from being inserted into the set.

==Acknowledgement==

Special thanks to Dmitry Petukhov, Christopher Allen, Craig Raw and others
for their feedback on the specification.

==References==

Original mailing list thread:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html

[-- Attachment #2: Type: text/html, Size: 14221 bytes --]

 permalink raw reply	[|nested]
2021-02-15  8:44 ` Hugo Nguyen

  2021-02-15 14:19     ` Hugo Nguyen
  
From: Craig Raw @ 2021-02-15 13:53 UTC (permalink / raw)
  To: Hugo Nguyen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 14243 bytes --]

Hi all,

Hugo and I have discussed off-list, and I have two concerns with this
proposal:

1. I believe adding the TOKEN and encryption to the exchange adds
complexity to already notoriously complex multisig, without adding much in
the way of security. This is because the shared secret (TOKEN) must still
be shared securely, and if you have established an (off-protocol) secure
channel to do this, why not just share the actual multisig configuration
data directly in that channel? If you are able to do so, you retain the
advantage of being able to inspect the data directly.

2. Asking the user to enter the derivation into the Signer also adds (IMO
unnecessary) complexity to the multisig setup process. A different way of
doing it, which is specified in the UR crypto-account format linked to
previously, has the Signer provide as many common derivations (along with
their xpubs) as it can support for a given BIP44 account number. This has
the dual advantage of making things simpler for the user (they only have to
provide an optional account number) and increasing the standardisation on
common derivation paths. On receiving these derivation/xpub pairs, the
Coordinator can simply pick the appropriate one.

These concerns noted, I agree it's a good idea to have Signers save the
multisig configuration as proposed, and it would be great to have
standardisation in hww import and export formats (not just for multisig).
On that note, I'd love to see greater adoption of the efficient UR2.0
standard and associated formats for airgapped data transmission using QR
codes.

Craig


On Mon, Feb 15, 2021 at 11:13 AM Hugo Nguyen via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Hi all,
> I have updated the proposal based on further feedback. The new spec is
> included at the bottom.
>
> I have also created a public Github PR to make it easier to comment on the
> text of the spec itself: https://github.com/nunchuk-io/bips/pull/1 .
>
> Could someone please let me know what else needs to be done before a BIP
> number can be assigned?
>
>
> === Quick summary of changes from last update ===
>
> 1. Define encryption modes
>
> # NO_ENCRYPTION: Encryption is disabled.
> # STANDARD : the TOKEN is a 64-bit nonce.
> # EXTENDED : the TOKEN is a 128-bit nonce.
>
> 2. Define signature algorithm
>
> Follow BIP-0322, legacy format allowed.
>
> 3. Multiple TOKENs (optional)
>
> Also add an option where the Coordinator can choose to use one common
> TOKEN for all Signers, or use one per Signer.
>
> === End of summary ===
>
>
> Cheers,
> Hugo
>
>
> <pre>
>   BIP: To be determined
>   Layer: Applications
>   Title: Bitcoin Secure Multisig Setup (BSMS)
>   Author: Hugo Nguyen <hugo at nunchuk.io>, Peter Gray <peter at
> coinkite.com>, Marko Bencun <marko at shiftcrypto.ch>, Pavol Rusnak <
> stick@satoshilabs•com>, Aaron Chen <aarondongchen at gmail.com>, Rodolfo
> Novak <rodolfo at coinkite.com>
>   Comments-Summary: No comments yet.
>   Comments-URI:
>   Status: Proposed
>   Type: Standards Track
>   Created: 2020-11-10
>   License: BSD-2-Clause
> </pre>
>
> ==Introduction==
>
> ===Abstract===
>
> This document proposes a mechanism to set up multisig wallets securely.
>
> ===Copyright===
>
> This BIP is licensed under the 2-clause BSD license.
>
> ===Motivation===
>
> The Bitcoin multisig experience has been greatly streamlined under [
> https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
> (Partially Signed Bitcoin Transaction)]. However, what is still missing is
> a standardized process for setting up multisig wallets securely across
> different vendors.
>
> There are a number of concerns when it comes to setting up a multisig
> wallet:
>
> # Whether the multisig configuration, such as Signer membership, script
> type, derivation paths and number of signatures required, is correct and
> not tampered with.
> # Whether Signer persists the multisig configuration in their respective
> storage, and under what format.
> # Whether Signer's storage is tamper-proof.
> # Whether Signer subsequently uses the multisig configuration to generate
> and verify receive and change addresses.
>
> An attacker who can modify the multisig configuration can steal or hold
> funds to ransom by duping the user into sending funds to the wrong address.
>
> This proposal seeks to address concerns #1 and #2: to mitigate the risk of
> tampering during the initial setup phase, and to define an interoperable
> multisig configuration format.
>
> Concerns #3 and #4 should be handled by Signers and is out of scope of
> this proposal.
>
> ==Specification==
>
> ===Prerequisites===
> This proposal assumes the parties in the multisig support [
> https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP-0032],
> [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
> descriptor language] and encryption.
>
> ===Roles===
> ====Coordinator====
>
> The Coordinator initiates the multisig setup. The Coordinator determines
> what type of multisig is used and the exact policy script. If encryption is
> enabled, the Coordinator also distributes a shared secret or shared secrets
> to the parties involved for secure communication. The Coordinator gathers
> information from the Signers to generate a descriptor record. The
> Coordinator distributes the descriptor record back to the Signers.
>
> ====Signer====
>
> The Signer is a participating member in the multisig. Its responsibilities
> include providing its key record -- which contains an Extended Public Key
> (XPUB) -- to the Coordinator, verifying that its XPUB is included in the
> descriptor record and persisting the descriptor record in its storage.
>
> ===Setup Process===
>
> ====Round 1====
>
> =====Coordinator=====
>
> * The Coordinator creates a multisig wallet creation session. The
> Coordinator constructs the multisig script and its policy parameters, such
> as the total number of signers and the required number of signatures
> (<tt>M</tt> and <tt>N</tt>).
> * The session should expire after some time period determined by the
> Coordinator, e.g., 24 hours.
> * If encryption is enabled, the Coordinator distributes a secret
> <tt>TOKEN</tt> to each Signer over a secure channel. The Signer can use the
> <tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to the
> Encryption section below for details on the <tt>TOKEN</tt>, the key
> derivation function and the encryption scheme. Depending on the use case,
> the Coordinator can decide whether to share one common <tt>TOKEN</tt> for
> all Signers, or to have one per Signer.
> * If encryption is disabled, <tt>TOKEN</tt> is set to <tt>0</tt>, and all
> the encryption/decryption steps below can be skipped.
>
> =====Signer=====
>
> * The Signer initiates a new secure multisig setup session by setting the
> <tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from the
> <tt>TOKEN</tt>. The Signer can keep the session open until a different
> value for the <tt>TOKEN</tt> is set.
> * The Signer generates a key record by prompting the user for a multisig
> derivation path and retrieves the XPUB at that derivation path. Optionally,
> the Signer can choose a path on behalf of the user. If the Signer chooses
> the path, it should try to avoid reusing XPUBs for different wallets.
> * The first line in the record must be the <tt>TOKEN</tt>. The second line
> must be the <tt>KEY</tt>. The <tt>KEY</tt> is an XPUB plus its key origin
> information, written in the descriptor-defined format, i.e.: <tt>[{master
> key fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a
> <tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by using the
> private key associated with the XPUB to sign the first two lines.  The
> signature should follow [
> https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki BIP-0322],
> legacy format accepted. Finally, the Signer encrypts the entire record with
> <tt>ENCRYPTION_KEY</tt>.
>
> ====Round 2====
>
> =====Coordinator=====
>
> * The Coordinator gathers key records from all participating Signers.
> Abort the setup if the wallet setup session has expired.
> * For each key record, the Coordinator decrypts it using
> <tt>ENCRYPTION_KEY</tt>. The Coordinator verifies that the included
> <tt>SIG</tt> is valid given the <tt>KEY</tt>.
> * If all key records look good, the Coordinator fills in all necessary
> information to generate a descriptor record, which is simply the descriptor
> string plus a <tt>CHECKSUM</tt>, all in one line. The <tt>CHECKSUM</tt> has
> [
> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
> BECH32 encoding].
> * The Coordinator encrypts this descriptor record with
> <tt>ENCRYPTION_KEY</tt>.
> * The Coordinator sends the encrypted descriptor record to all
> participating Signers.
>
> =====Signer=====
>
> * The Signer imports the descriptor record, decrypts it using the
> <tt>ENCRYPTION_KEY</tt> derived from the open session.
> * The Signer calculates and verifies the descriptor’s <tt>CHECKSUM</tt>.
> Abort the setup if the <tt>CHECKSUM</tt> is incorrect.
> * The Signer checks whether one of the <tt>KEY</tt>s in the descriptor
> belongs to it, using path and fingerprint information included in the
> descriptor. The check must perform an exact match on the <tt>KEY</tt>s, and
> not using shortcuts such as matching fingerprints (which is trivial to
> spoof). Abort the setup if it doesn’t detect its own <tt>KEY</tt>.
> * For confirmation, the Signer must display to the user the
> <tt>CHECKSUM</tt>, plus other configurations, such as <tt>M</tt> and
> <tt>N</tt>. The total number of Signers, <tt>N</tt>, is important to
> prevent a <tt>KEY</tt> insertion attack. All participating Signers should
> be able to display the same confirmation.
> * If all checks pass, the Signer persists the descriptor record in its
> storage.
> * The Signer can choose to further restrict post-XPUB derivation paths,
> such as to those defined in [
> https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP-0044].
> * The Signer should subsequently use the descriptor to generate and verify
> receive and change addresses.
>
> This completes the setup.
>
> ===Encryption===
>
> ====The Token====
> We define three modes of encryption.
>
> # <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>.
> Encryption is disabled.
> # <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
> # <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 128-bit nonce.
>
> The <tt>TOKEN</tt> can be converted to one of these formats:
> * A mnemonic phrase using [
> https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039]
> word list (6 words in <tt>STANDARD</tt> mode, 12 words in <tt>EXTENDED</tt>
> mode)
> * A decimal number (20 digits in <tt>STANDARD</tt> mode, 40 digits in
> <tt>EXTENDED</tt> mode)
> * A QR code
> * Other formats
>
> The flexibility in the data format allows each Signer to customize the
> User Experience based on its respective capabilities.
>
> ====Key Derivation====
> The key derivation function is [https://tools.ietf.org/html/rfc2898
> PBKDF2], with PRF = SHA512. Specifically:
>
> <tt>DK = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>
>
> Whereas:
>
> * PRF = <tt>SHA512</tt>
> * Password = <tt>"No SPOF"</tt>
> * Salt = <tt>TOKEN</tt>
> * c = <tt>2048</tt>
> * dkLen = <tt>256</tt>
> * DK = Derived <tt>ENCRYPTION_KEY</tt>
>
> ====Encryption Scheme====
> The encryption scheme is [https://tools.ietf.org/html/rfc3686 AES, CTR
> mode].
>
> ==QR Codes==
> For signers that use QR codes to transmit data, key and descriptor records
> can be converted to QR codes, following [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
> the BCR standard].
>
> Also refer to [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
> UR Type Definition for BIP44 Accounts] and [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
> UR Type Definition for Bitcoin Output Descriptors] for more details.
>
> ==Security==
>
> This proposal introduces two layers of protection. The first one is a
> temporary, secret token, used to encrypt the two rounds of communication
> between the Signer and the Coordinator. The second one is through the
> descriptor checksum and visual inspection of the descriptor itself.
>
> The token is only needed during the setup phase, and can be safely thrown
> away afterwards. The token does not guarantee that the Signer membership
> set is not modified, since that depends on the overall security of all
> parties in the setup, but it can make it significantly harder for an
> attacker to do so.
>
> There are three ways an attacker can modify the membership set: by
> changing an existing member, by removing an existing member, or by adding a
> new member.
>
> For the first two methods, one of the Signers will be able to detect that
> its membership has been changed or removed, and reject the final
> descriptor. Thus, it is vital that all participating Signers check that
> their membership is intact in the descriptor. Even one Signer failing to
> check for its membership means that the setup could be compromised.
>
> For the third type of attack, the descriptor checksum and visual
> inspection of the descriptor itself are the only way to guard against
> malicious members from being inserted into the set.
>
> ==Acknowledgement==
>
> Special thanks to Dmitry Petukhov, Christopher Allen, Craig Raw and others
> for their feedback on the specification.
>
> ==References==
>
> Original mailing list thread:
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html
>
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 17055 bytes --]

 permalink raw reply	[|nested]
2021-02-15 13:53   ` Craig Raw

  2021-02-15 16:45       ` Hugo Nguyen
  
From: Hugo Nguyen @ 2021-02-15 14:19 UTC (permalink / raw)
  To: Craig Raw;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 16261 bytes --]

Hi Craig,
Thanks for the feedback! Sharing my comments inline.

On Mon, Feb 15, 2021 at 5:53 AM Craig Raw <craigraw@gmail•com> wrote:

> Hi all,
>
> Hugo and I have discussed off-list, and I have two concerns with this
> proposal:
>
> 1. I believe adding the TOKEN and encryption to the exchange adds
> complexity to already notoriously complex multisig, without adding much in
> the way of security.
>

I disagree that this doesn't add security. This proposal was inspired by a
real vulnerability we discovered in the wild while experimenting with HWWs,
and during that process I noticed that there is little in the way of a an
attacker to pull off a MITM attack, where he/she can intercept and tamper
with the multisig configuration file, potentially swapping in their own
XPUBs. This is especially important for remote multisig setups - which is
not common now but I imagine will be a lot more common in the future.

This is because the shared secret (TOKEN) must still be shared securely,
> and if you have established an (off-protocol) secure channel to do this,
> why not just share the actual multisig configuration data directly in that
> channel?


Because multisig is inherently an interactive process. If we can create the
multisig configuration in one shot for everybody, you're correct that this
is not necessary! But the fact that multisig is by nature interactive and
requires a few rounds of communication (since it needs each Signer to
voluntarily share its XPUB before a wallet can be created) makes this
necessary IMO.

If you are able to do so, you retain the advantage of being able to inspect
> the data directly.


Note that some manual inspection is still part of the proposal. But instead
of exclusively relying on manual inspection (which is error-prone, and also
doesn't scale very well for a large number of signers), we strengthen this
process by automating some of the checks and making it harder to tamper
with.


>
> 2. Asking the user to enter the derivation into the Signer also adds (IMO
> unnecessary) complexity to the multisig setup process. A different way of
> doing it, which is specified in the UR crypto-account format linked to
> previously, has the Signer provide as many common derivations (along with
> their xpubs) as it can support for a given BIP44 account number. This has
> the dual advantage of making things simpler for the user (they only have to
> provide an optional account number) and increasing the standardisation on
> common derivation paths. On receiving these derivation/xpub pairs, the
> Coordinator can simply pick the appropriate one.
>

Note that in the updated proposal, I added the option of the Signer
automatically filling in the derivation paths on behalf of the user (and
also should take care not to reuse XPUBs). Perhaps this can be made the
default behavior.

Best,
Hugo


>
> These concerns noted, I agree it's a good idea to have Signers save the
> multisig configuration as proposed, and it would be great to have
> standardisation in hww import and export formats (not just for multisig).
> On that note, I'd love to see greater adoption of the efficient UR2.0
> standard and associated formats for airgapped data transmission using QR
> codes.
>
> Craig
>
>
> On Mon, Feb 15, 2021 at 11:13 AM Hugo Nguyen via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> wrote:
>
>> Hi all,
>> I have updated the proposal based on further feedback. The new spec is
>> included at the bottom.
>>
>> I have also created a public Github PR to make it easier to comment on
>> the text of the spec itself: https://github.com/nunchuk-io/bips/pull/1 .
>>
>> Could someone please let me know what else needs to be done before a BIP
>> number can be assigned?
>>
>>
>> === Quick summary of changes from last update ===
>>
>> 1. Define encryption modes
>>
>> # NO_ENCRYPTION: Encryption is disabled.
>> # STANDARD : the TOKEN is a 64-bit nonce.
>> # EXTENDED : the TOKEN is a 128-bit nonce.
>>
>> 2. Define signature algorithm
>>
>> Follow BIP-0322, legacy format allowed.
>>
>> 3. Multiple TOKENs (optional)
>>
>> Also add an option where the Coordinator can choose to use one common
>> TOKEN for all Signers, or use one per Signer.
>>
>> === End of summary ===
>>
>>
>> Cheers,
>> Hugo
>>
>>
>> <pre>
>>   BIP: To be determined
>>   Layer: Applications
>>   Title: Bitcoin Secure Multisig Setup (BSMS)
>>   Author: Hugo Nguyen <hugo at nunchuk.io>, Peter Gray <peter at
>> coinkite.com>, Marko Bencun <marko at shiftcrypto.ch>, Pavol Rusnak <
>> stick@satoshilabs•com>, Aaron Chen <aarondongchen at gmail.com>, Rodolfo
>> Novak <rodolfo at coinkite.com>
>>   Comments-Summary: No comments yet.
>>   Comments-URI:
>>   Status: Proposed
>>   Type: Standards Track
>>   Created: 2020-11-10
>>   License: BSD-2-Clause
>> </pre>
>>
>> ==Introduction==
>>
>> ===Abstract===
>>
>> This document proposes a mechanism to set up multisig wallets securely.
>>
>> ===Copyright===
>>
>> This BIP is licensed under the 2-clause BSD license.
>>
>> ===Motivation===
>>
>> The Bitcoin multisig experience has been greatly streamlined under [
>> https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
>> (Partially Signed Bitcoin Transaction)]. However, what is still missing
>> is a standardized process for setting up multisig wallets securely across
>> different vendors.
>>
>> There are a number of concerns when it comes to setting up a multisig
>> wallet:
>>
>> # Whether the multisig configuration, such as Signer membership, script
>> type, derivation paths and number of signatures required, is correct and
>> not tampered with.
>> # Whether Signer persists the multisig configuration in their respective
>> storage, and under what format.
>> # Whether Signer's storage is tamper-proof.
>> # Whether Signer subsequently uses the multisig configuration to generate
>> and verify receive and change addresses.
>>
>> An attacker who can modify the multisig configuration can steal or hold
>> funds to ransom by duping the user into sending funds to the wrong address.
>>
>> This proposal seeks to address concerns #1 and #2: to mitigate the risk
>> of tampering during the initial setup phase, and to define an interoperable
>> multisig configuration format.
>>
>> Concerns #3 and #4 should be handled by Signers and is out of scope of
>> this proposal.
>>
>> ==Specification==
>>
>> ===Prerequisites===
>> This proposal assumes the parties in the multisig support [
>> https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
>> BIP-0032], [
>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
>> descriptor language] and encryption.
>>
>> ===Roles===
>> ====Coordinator====
>>
>> The Coordinator initiates the multisig setup. The Coordinator determines
>> what type of multisig is used and the exact policy script. If encryption is
>> enabled, the Coordinator also distributes a shared secret or shared secrets
>> to the parties involved for secure communication. The Coordinator gathers
>> information from the Signers to generate a descriptor record. The
>> Coordinator distributes the descriptor record back to the Signers.
>>
>> ====Signer====
>>
>> The Signer is a participating member in the multisig. Its
>> responsibilities include providing its key record -- which contains an
>> Extended Public Key (XPUB) -- to the Coordinator, verifying that its XPUB
>> is included in the descriptor record and persisting the descriptor record
>> in its storage.
>>
>> ===Setup Process===
>>
>> ====Round 1====
>>
>> =====Coordinator=====
>>
>> * The Coordinator creates a multisig wallet creation session. The
>> Coordinator constructs the multisig script and its policy parameters, such
>> as the total number of signers and the required number of signatures
>> (<tt>M</tt> and <tt>N</tt>).
>> * The session should expire after some time period determined by the
>> Coordinator, e.g., 24 hours.
>> * If encryption is enabled, the Coordinator distributes a secret
>> <tt>TOKEN</tt> to each Signer over a secure channel. The Signer can use the
>> <tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to the
>> Encryption section below for details on the <tt>TOKEN</tt>, the key
>> derivation function and the encryption scheme. Depending on the use case,
>> the Coordinator can decide whether to share one common <tt>TOKEN</tt> for
>> all Signers, or to have one per Signer.
>> * If encryption is disabled, <tt>TOKEN</tt> is set to <tt>0</tt>, and all
>> the encryption/decryption steps below can be skipped.
>>
>> =====Signer=====
>>
>> * The Signer initiates a new secure multisig setup session by setting the
>> <tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from the
>> <tt>TOKEN</tt>. The Signer can keep the session open until a different
>> value for the <tt>TOKEN</tt> is set.
>> * The Signer generates a key record by prompting the user for a multisig
>> derivation path and retrieves the XPUB at that derivation path. Optionally,
>> the Signer can choose a path on behalf of the user. If the Signer chooses
>> the path, it should try to avoid reusing XPUBs for different wallets.
>> * The first line in the record must be the <tt>TOKEN</tt>. The second
>> line must be the <tt>KEY</tt>. The <tt>KEY</tt> is an XPUB plus its key
>> origin information, written in the descriptor-defined format, i.e.:
>> <tt>[{master key fingerprint}/{derivation path}]{XPUB}</tt>. The third line
>> must be a <tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by
>> using the private key associated with the XPUB to sign the first two
>> lines.  The signature should follow [
>> https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
>> BIP-0322], legacy format accepted. Finally, the Signer encrypts the entire
>> record with <tt>ENCRYPTION_KEY</tt>.
>>
>> ====Round 2====
>>
>> =====Coordinator=====
>>
>> * The Coordinator gathers key records from all participating Signers.
>> Abort the setup if the wallet setup session has expired.
>> * For each key record, the Coordinator decrypts it using
>> <tt>ENCRYPTION_KEY</tt>. The Coordinator verifies that the included
>> <tt>SIG</tt> is valid given the <tt>KEY</tt>.
>> * If all key records look good, the Coordinator fills in all necessary
>> information to generate a descriptor record, which is simply the descriptor
>> string plus a <tt>CHECKSUM</tt>, all in one line. The <tt>CHECKSUM</tt> has
>> [
>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
>> BECH32 encoding].
>> * The Coordinator encrypts this descriptor record with
>> <tt>ENCRYPTION_KEY</tt>.
>> * The Coordinator sends the encrypted descriptor record to all
>> participating Signers.
>>
>> =====Signer=====
>>
>> * The Signer imports the descriptor record, decrypts it using the
>> <tt>ENCRYPTION_KEY</tt> derived from the open session.
>> * The Signer calculates and verifies the descriptor’s <tt>CHECKSUM</tt>.
>> Abort the setup if the <tt>CHECKSUM</tt> is incorrect.
>> * The Signer checks whether one of the <tt>KEY</tt>s in the descriptor
>> belongs to it, using path and fingerprint information included in the
>> descriptor. The check must perform an exact match on the <tt>KEY</tt>s, and
>> not using shortcuts such as matching fingerprints (which is trivial to
>> spoof). Abort the setup if it doesn’t detect its own <tt>KEY</tt>.
>> * For confirmation, the Signer must display to the user the
>> <tt>CHECKSUM</tt>, plus other configurations, such as <tt>M</tt> and
>> <tt>N</tt>. The total number of Signers, <tt>N</tt>, is important to
>> prevent a <tt>KEY</tt> insertion attack. All participating Signers should
>> be able to display the same confirmation.
>> * If all checks pass, the Signer persists the descriptor record in its
>> storage.
>> * The Signer can choose to further restrict post-XPUB derivation paths,
>> such as to those defined in [
>> https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki BIP-0044].
>> * The Signer should subsequently use the descriptor to generate and
>> verify receive and change addresses.
>>
>> This completes the setup.
>>
>> ===Encryption===
>>
>> ====The Token====
>> We define three modes of encryption.
>>
>> # <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>.
>> Encryption is disabled.
>> # <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
>> # <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 128-bit nonce.
>>
>> The <tt>TOKEN</tt> can be converted to one of these formats:
>> * A mnemonic phrase using [
>> https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki BIP-0039]
>> word list (6 words in <tt>STANDARD</tt> mode, 12 words in <tt>EXTENDED</tt>
>> mode)
>> * A decimal number (20 digits in <tt>STANDARD</tt> mode, 40 digits in
>> <tt>EXTENDED</tt> mode)
>> * A QR code
>> * Other formats
>>
>> The flexibility in the data format allows each Signer to customize the
>> User Experience based on its respective capabilities.
>>
>> ====Key Derivation====
>> The key derivation function is [https://tools.ietf.org/html/rfc2898
>> PBKDF2], with PRF = SHA512. Specifically:
>>
>> <tt>DK = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>
>>
>> Whereas:
>>
>> * PRF = <tt>SHA512</tt>
>> * Password = <tt>"No SPOF"</tt>
>> * Salt = <tt>TOKEN</tt>
>> * c = <tt>2048</tt>
>> * dkLen = <tt>256</tt>
>> * DK = Derived <tt>ENCRYPTION_KEY</tt>
>>
>> ====Encryption Scheme====
>> The encryption scheme is [https://tools.ietf.org/html/rfc3686 AES, CTR
>> mode].
>>
>> ==QR Codes==
>> For signers that use QR codes to transmit data, key and descriptor
>> records can be converted to QR codes, following [
>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
>> the BCR standard].
>>
>> Also refer to [
>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
>> UR Type Definition for BIP44 Accounts] and [
>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
>> UR Type Definition for Bitcoin Output Descriptors] for more details.
>>
>> ==Security==
>>
>> This proposal introduces two layers of protection. The first one is a
>> temporary, secret token, used to encrypt the two rounds of communication
>> between the Signer and the Coordinator. The second one is through the
>> descriptor checksum and visual inspection of the descriptor itself.
>>
>> The token is only needed during the setup phase, and can be safely thrown
>> away afterwards. The token does not guarantee that the Signer membership
>> set is not modified, since that depends on the overall security of all
>> parties in the setup, but it can make it significantly harder for an
>> attacker to do so.
>>
>> There are three ways an attacker can modify the membership set: by
>> changing an existing member, by removing an existing member, or by adding a
>> new member.
>>
>> For the first two methods, one of the Signers will be able to detect that
>> its membership has been changed or removed, and reject the final
>> descriptor. Thus, it is vital that all participating Signers check that
>> their membership is intact in the descriptor. Even one Signer failing to
>> check for its membership means that the setup could be compromised.
>>
>> For the third type of attack, the descriptor checksum and visual
>> inspection of the descriptor itself are the only way to guard against
>> malicious members from being inserted into the set.
>>
>> ==Acknowledgement==
>>
>> Special thanks to Dmitry Petukhov, Christopher Allen, Craig Raw and
>> others for their feedback on the specification.
>>
>> ==References==
>>
>> Original mailing list thread:
>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html
>>
>>
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>
>

[-- Attachment #2: Type: text/html, Size: 19632 bytes --]

 permalink raw reply	[|nested]
2021-02-15 14:19     ` Hugo Nguyen

  
From: Hugo Nguyen @ 2021-02-15 16:45 UTC ( / )
  To: Craig Raw;  Bitcoin Protocol Discussion



I would also like to add 2 notes for those who are concerned about the
potential complexity that comes with encryption - which is understandable:

1. As mentioned elsewhere in the thread, I've made the encryption aspect
entirely optional. In scenarios where encryption is an overkill -- such as
when you're setting things up under an environment you control 100% -- you
can turn encryption off, and things are unchanged from the way they are
now. The "session" would be unencrypted and XPUBs and descriptor records
are simply shared in plaintext.

2. Multisig setup is a one-time operation! After the multisig wallet has
been set up and registered with the Signers, you don't have to worry about
sharing XPUBs ever again (not even in PSBTs which is an additional benefit
of the stateful registration approach). I believe this one-time cost is
worth it if the amount of funds you are securing are significant, e.g., few
millions of dollars or even billions of dollars. But it's important that we
have this extra level of security if necessary IMHO.

Best,
Hugo

On Mon, Feb 15, 2021 at 6:19 AM Hugo Nguyen <hugo@nunchuk•io> wrote:

> Hi Craig,
> Thanks for the feedback! Sharing my comments inline.
>
> On Mon, Feb 15, 2021 at 5:53 AM Craig Raw <craigraw@gmail•com> wrote:
>
>> Hi all,
>>
>> Hugo and I have discussed off-list, and I have two concerns with this
>> proposal:
>>
>> 1. I believe adding the TOKEN and encryption to the exchange adds
>> complexity to already notoriously complex multisig, without adding much in
>> the way of security.
>>
>
> I disagree that this doesn't add security. This proposal was inspired by a
> real vulnerability we discovered in the wild while experimenting with HWWs,
> and during that process I noticed that there is little in the way of a an
> attacker to pull off a MITM attack, where he/she can intercept and tamper
> with the multisig configuration file, potentially swapping in their own
> XPUBs. This is especially important for remote multisig setups - which is
> not common now but I imagine will be a lot more common in the future.
>
> This is because the shared secret (TOKEN) must still be shared securely,
>> and if you have established an (off-protocol) secure channel to do this,
>> why not just share the actual multisig configuration data directly in that
>> channel?
>
>
> Because multisig is inherently an interactive process. If we can create
> the multisig configuration in one shot for everybody, you're correct that
> this is not necessary! But the fact that multisig is by nature interactive
> and requires a few rounds of communication (since it needs each Signer to
> voluntarily share its XPUB before a wallet can be created) makes this
> necessary IMO.
>
> If you are able to do so, you retain the advantage of being able to
>> inspect the data directly.
>
>
> Note that some manual inspection is still part of the proposal. But
> instead of exclusively relying on manual inspection (which is error-prone,
> and also doesn't scale very well for a large number of signers), we
> strengthen this process by automating some of the checks and making it
> harder to tamper with.
>
>
>>
>> 2. Asking the user to enter the derivation into the Signer also adds (IMO
>> unnecessary) complexity to the multisig setup process. A different way of
>> doing it, which is specified in the UR crypto-account format linked to
>> previously, has the Signer provide as many common derivations (along with
>> their xpubs) as it can support for a given BIP44 account number. This has
>> the dual advantage of making things simpler for the user (they only have to
>> provide an optional account number) and increasing the standardisation on
>> common derivation paths. On receiving these derivation/xpub pairs, the
>> Coordinator can simply pick the appropriate one.
>>
>
> Note that in the updated proposal, I added the option of the Signer
> automatically filling in the derivation paths on behalf of the user (and
> also should take care not to reuse XPUBs). Perhaps this can be made the
> default behavior.
>
> Best,
> Hugo
>
>
>>
>> These concerns noted, I agree it's a good idea to have Signers save the
>> multisig configuration as proposed, and it would be great to have
>> standardisation in hww import and export formats (not just for multisig).
>> On that note, I'd love to see greater adoption of the efficient UR2.0
>> standard and associated formats for airgapped data transmission using QR
>> codes.
>>
>> Craig
>>
>>
>> On Mon, Feb 15, 2021 at 11:13 AM Hugo Nguyen via bitcoin-dev <
>> bitcoin-dev@lists•linuxfoundation.org> wrote:
>>
>>> Hi all,
>>> I have updated the proposal based on further feedback. The new spec is
>>> included at the bottom.
>>>
>>> I have also created a public Github PR to make it easier to comment on
>>> the text of the spec itself: https://github.com/nunchuk-io/bips/pull/1 .
>>>
>>> Could someone please let me know what else needs to be done before a BIP
>>> number can be assigned?
>>>
>>>
>>> === Quick summary of changes from last update ===
>>>
>>> 1. Define encryption modes
>>>
>>> # NO_ENCRYPTION: Encryption is disabled.
>>> # STANDARD : the TOKEN is a 64-bit nonce.
>>> # EXTENDED : the TOKEN is a 128-bit nonce.
>>>
>>> 2. Define signature algorithm
>>>
>>> Follow BIP-0322, legacy format allowed.
>>>
>>> 3. Multiple TOKENs (optional)
>>>
>>> Also add an option where the Coordinator can choose to use one common
>>> TOKEN for all Signers, or use one per Signer.
>>>
>>> === End of summary ===
>>>
>>>
>>> Cheers,
>>> Hugo
>>>
>>>
>>> <pre>
>>>   BIP: To be determined
>>>   Layer: Applications
>>>   Title: Bitcoin Secure Multisig Setup (BSMS)
>>>   Author: Hugo Nguyen <hugo at nunchuk.io>, Peter Gray <peter at
>>> coinkite.com>, Marko Bencun <marko at shiftcrypto.ch>, Pavol Rusnak <
>>> stick@satoshilabs•com>, Aaron Chen <aarondongchen at gmail.com>,
>>> Rodolfo Novak <rodolfo at coinkite.com>
>>>   Comments-Summary: No comments yet.
>>>   Comments-URI:
>>>   Status: Proposed
>>>   Type: Standards Track
>>>   Created: 2020-11-10
>>>   License: BSD-2-Clause
>>> </pre>
>>>
>>> ==Introduction==
>>>
>>> ===Abstract===
>>>
>>> This document proposes a mechanism to set up multisig wallets securely.
>>>
>>> ===Copyright===
>>>
>>> This BIP is licensed under the 2-clause BSD license.
>>>
>>> ===Motivation===
>>>
>>> The Bitcoin multisig experience has been greatly streamlined under [
>>> https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174
>>> (Partially Signed Bitcoin Transaction)]. However, what is still missing
>>> is a standardized process for setting up multisig wallets securely across
>>> different vendors.
>>>
>>> There are a number of concerns when it comes to setting up a multisig
>>> wallet:
>>>
>>> # Whether the multisig configuration, such as Signer membership, script
>>> type, derivation paths and number of signatures required, is correct and
>>> not tampered with.
>>> # Whether Signer persists the multisig configuration in their respective
>>> storage, and under what format.
>>> # Whether Signer's storage is tamper-proof.
>>> # Whether Signer subsequently uses the multisig configuration to
>>> generate and verify receive and change addresses.
>>>
>>> An attacker who can modify the multisig configuration can steal or hold
>>> funds to ransom by duping the user into sending funds to the wrong address.
>>>
>>> This proposal seeks to address concerns #1 and #2: to mitigate the risk
>>> of tampering during the initial setup phase, and to define an interoperable
>>> multisig configuration format.
>>>
>>> Concerns #3 and #4 should be handled by Signers and is out of scope of
>>> this proposal.
>>>
>>> ==Specification==
>>>
>>> ===Prerequisites===
>>> This proposal assumes the parties in the multisig support [
>>> https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
>>> BIP-0032], [
>>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the
>>> descriptor language] and encryption.
>>>
>>> ===Roles===
>>> ====Coordinator====
>>>
>>> The Coordinator initiates the multisig setup. The Coordinator determines
>>> what type of multisig is used and the exact policy script. If encryption is
>>> enabled, the Coordinator also distributes a shared secret or shared secrets
>>> to the parties involved for secure communication. The Coordinator gathers
>>> information from the Signers to generate a descriptor record. The
>>> Coordinator distributes the descriptor record back to the Signers.
>>>
>>> ====Signer====
>>>
>>> The Signer is a participating member in the multisig. Its
>>> responsibilities include providing its key record -- which contains an
>>> Extended Public Key (XPUB) -- to the Coordinator, verifying that its XPUB
>>> is included in the descriptor record and persisting the descriptor record
>>> in its storage.
>>>
>>> ===Setup Process===
>>>
>>> ====Round 1====
>>>
>>> =====Coordinator=====
>>>
>>> * The Coordinator creates a multisig wallet creation session. The
>>> Coordinator constructs the multisig script and its policy parameters, such
>>> as the total number of signers and the required number of signatures
>>> (<tt>M</tt> and <tt>N</tt>).
>>> * The session should expire after some time period determined by the
>>> Coordinator, e.g., 24 hours.
>>> * If encryption is enabled, the Coordinator distributes a secret
>>> <tt>TOKEN</tt> to each Signer over a secure channel. The Signer can use the
>>> <tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to the
>>> Encryption section below for details on the <tt>TOKEN</tt>, the key
>>> derivation function and the encryption scheme. Depending on the use case,
>>> the Coordinator can decide whether to share one common <tt>TOKEN</tt> for
>>> all Signers, or to have one per Signer.
>>> * If encryption is disabled, <tt>TOKEN</tt> is set to <tt>0</tt>, and
>>> all the encryption/decryption steps below can be skipped.
>>>
>>> =====Signer=====
>>>
>>> * The Signer initiates a new secure multisig setup session by setting
>>> the <tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from the
>>> <tt>TOKEN</tt>. The Signer can keep the session open until a different
>>> value for the <tt>TOKEN</tt> is set.
>>> * The Signer generates a key record by prompting the user for a multisig
>>> derivation path and retrieves the XPUB at that derivation path. Optionally,
>>> the Signer can choose a path on behalf of the user. If the Signer chooses
>>> the path, it should try to avoid reusing XPUBs for different wallets.
>>> * The first line in the record must be the <tt>TOKEN</tt>. The second
>>> line must be the <tt>KEY</tt>. The <tt>KEY</tt> is an XPUB plus its key
>>> origin information, written in the descriptor-defined format, i.e.:
>>> <tt>[{master key fingerprint}/{derivation path}]{XPUB}</tt>. The third line
>>> must be a <tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by
>>> using the private key associated with the XPUB to sign the first two
>>> lines.  The signature should follow [
>>> https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
>>> BIP-0322], legacy format accepted. Finally, the Signer encrypts the entire
>>> record with <tt>ENCRYPTION_KEY</tt>.
>>>
>>> ====Round 2====
>>>
>>> =====Coordinator=====
>>>
>>> * The Coordinator gathers key records from all participating Signers.
>>> Abort the setup if the wallet setup session has expired.
>>> * For each key record, the Coordinator decrypts it using
>>> <tt>ENCRYPTION_KEY</tt>. The Coordinator verifies that the included
>>> <tt>SIG</tt> is valid given the <tt>KEY</tt>.
>>> * If all key records look good, the Coordinator fills in all necessary
>>> information to generate a descriptor record, which is simply the descriptor
>>> string plus a <tt>CHECKSUM</tt>, all in one line. The <tt>CHECKSUM</tt> has
>>> [
>>> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
>>> BECH32 encoding].
>>> * The Coordinator encrypts this descriptor record with
>>> <tt>ENCRYPTION_KEY</tt>.
>>> * The Coordinator sends the encrypted descriptor record to all
>>> participating Signers.
>>>
>>> =====Signer=====
>>>
>>> * The Signer imports the descriptor record, decrypts it using the
>>> <tt>ENCRYPTION_KEY</tt> derived from the open session.
>>> * The Signer calculates and verifies the descriptor’s <tt>CHECKSUM</tt>.
>>> Abort the setup if the <tt>CHECKSUM</tt> is incorrect.
>>> * The Signer checks whether one of the <tt>KEY</tt>s in the descriptor
>>> belongs to it, using path and fingerprint information included in the
>>> descriptor. The check must perform an exact match on the <tt>KEY</tt>s, and
>>> not using shortcuts such as matching fingerprints (which is trivial to
>>> spoof). Abort the setup if it doesn’t detect its own <tt>KEY</tt>.
>>> * For confirmation, the Signer must display to the user the
>>> <tt>CHECKSUM</tt>, plus other configurations, such as <tt>M</tt> and
>>> <tt>N</tt>. The total number of Signers, <tt>N</tt>, is important to
>>> prevent a <tt>KEY</tt> insertion attack. All participating Signers should
>>> be able to display the same confirmation.
>>> * If all checks pass, the Signer persists the descriptor record in its
>>> storage.
>>> * The Signer can choose to further restrict post-XPUB derivation paths,
>>> such as to those defined in [
>>> https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
>>> BIP-0044].
>>> * The Signer should subsequently use the descriptor to generate and
>>> verify receive and change addresses.
>>>
>>> This completes the setup.
>>>
>>> ===Encryption===
>>>
>>> ====The Token====
>>> We define three modes of encryption.
>>>
>>> # <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>.
>>> Encryption is disabled.
>>> # <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
>>> # <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 128-bit nonce.
>>>
>>> The <tt>TOKEN</tt> can be converted to one of these formats:
>>> * A mnemonic phrase using [
>>> https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
>>> BIP-0039] word list (6 words in <tt>STANDARD</tt> mode, 12 words in
>>> <tt>EXTENDED</tt> mode)
>>> * A decimal number (20 digits in <tt>STANDARD</tt> mode, 40 digits in
>>> <tt>EXTENDED</tt> mode)
>>> * A QR code
>>> * Other formats
>>>
>>> The flexibility in the data format allows each Signer to customize the
>>> User Experience based on its respective capabilities.
>>>
>>> ====Key Derivation====
>>> The key derivation function is [https://tools.ietf.org/html/rfc2898
>>> PBKDF2], with PRF = SHA512. Specifically:
>>>
>>> <tt>DK = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>
>>>
>>> Whereas:
>>>
>>> * PRF = <tt>SHA512</tt>
>>> * Password = <tt>"No SPOF"</tt>
>>> * Salt = <tt>TOKEN</tt>
>>> * c = <tt>2048</tt>
>>> * dkLen = <tt>256</tt>
>>> * DK = Derived <tt>ENCRYPTION_KEY</tt>
>>>
>>> ====Encryption Scheme====
>>> The encryption scheme is [https://tools.ietf.org/html/rfc3686 AES, CTR
>>> mode].
>>>
>>> ==QR Codes==
>>> For signers that use QR codes to transmit data, key and descriptor
>>> records can be converted to QR codes, following [
>>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
>>> the BCR standard].
>>>
>>> Also refer to [
>>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
>>> UR Type Definition for BIP44 Accounts] and [
>>> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
>>> UR Type Definition for Bitcoin Output Descriptors] for more details.
>>>
>>> ==Security==
>>>
>>> This proposal introduces two layers of protection. The first one is a
>>> temporary, secret token, used to encrypt the two rounds of communication
>>> between the Signer and the Coordinator. The second one is through the
>>> descriptor checksum and visual inspection of the descriptor itself.
>>>
>>> The token is only needed during the setup phase, and can be safely
>>> thrown away afterwards. The token does not guarantee that the Signer
>>> membership set is not modified, since that depends on the overall security
>>> of all parties in the setup, but it can make it significantly harder for an
>>> attacker to do so.
>>>
>>> There are three ways an attacker can modify the membership set: by
>>> changing an existing member, by removing an existing member, or by adding a
>>> new member.
>>>
>>> For the first two methods, one of the Signers will be able to detect
>>> that its membership has been changed or removed, and reject the final
>>> descriptor. Thus, it is vital that all participating Signers check that
>>> their membership is intact in the descriptor. Even one Signer failing to
>>> check for its membership means that the setup could be compromised.
>>>
>>> For the third type of attack, the descriptor checksum and visual
>>> inspection of the descriptor itself are the only way to guard against
>>> malicious members from being inserted into the set.
>>>
>>> ==Acknowledgement==
>>>
>>> Special thanks to Dmitry Petukhov, Christopher Allen, Craig Raw and
>>> others for their feedback on the specification.
>>>
>>> ==References==
>>>
>>> Original mailing list thread:
>>> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html
>>>
>>>
>>> _______________________________________________
>>> bitcoin-dev mailing list
>>> bitcoin-dev@lists•linuxfoundation.org
>>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>>>
>>
2021-02-08 23:14 [bitcoin-dev] Proposal: Bitcoin Secure Multisig Setup Hugo Nguyen
                   ` (3 preceding siblings ...)
  2021-02-15  8:44 ` Hugo Nguyen

  2021-04-09 12:07   ` Sjors Provoost
  2021-04-11  2:34   ` Michael.flaxman
  2021-04-10 13:53 ` Erik Aronesty
  
From: Hugo Nguyen @ 2021-04-05  7:02 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 38078 bytes --]

Hi all,

Please find below the complete draft of the Bitcoin Secure Multisig Setup
(BSMS) BIP. The spec has gone through a number of important updates in the
last month or so. Thanks everyone who has participated in the review
process.

As a PR: https://github.com/bitcoin/bips/pull/1097

A few notes:
* PBKDF2-SHA512 was chosen instead of PBKDF2-SHA256 for the key derivation
function, due to widespread existing hardware support for PBKDF2-SHA512
* Only one descriptor is stored in the multisig configuration - this
simplifies wallet setup and recovery
(For the full review and relevant discussions, please check out
https://github.com/nunchuk-io/bips/pull/1).

Best,
Hugo

<pre>
  BIP: To be determined
  Layer: Applications
  Title: Bitcoin Secure Multisig Setup (BSMS)
  Author: Hugo Nguyen <hugo at nunchuk.io>, Peter Gray <peter at
coinkite.com>, Marko Bencun <marko at shiftcrypto.ch>, Aaron Chen
<aarondongchen at gmail.com>, Rodolfo Novak <rodolfo at coinkite.com>
  Comments-Summary: No comments yet.
  Comments-URI:
  Status: Proposed
  Type: Standards Track
  Created: 2020-11-10
  License: BSD-2-Clause
</pre>

==Introduction==

===Abstract===

This document proposes a mechanism to set up multisig wallets securely.

===Copyright===

This BIP is licensed under the 2-clause BSD license.

===Motivation===

The Bitcoin multisig experience has been greatly streamlined under
[https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
BIP-0174
(Partially Signed Bitcoin Transaction)]. However, what is still
missing is a standardized process for setting up multisig wallets
securely across different vendors.

There are a number of concerns when it comes to setting up a multisig wallet:

# Whether the multisig configuration, such as Signer membership,
script type, derivation paths and number of signatures required, is
correct and not tampered with.
# Whether the keys or the multisig configuration are leaked during the setup.
# Whether the Signer persists the multisig configuration in their
respective storage, and under what format.
# Whether the Signer's storage is tamper-proof.
# Whether the Signer subsequently uses the multisig configuration to
generate and verify receive and change addresses.

An attacker who can modify the multisig configuration can steal or
hold funds for ransom by duping the user into sending funds to the
wrong address. An attacker who cannot modify the configuration but can
learn about the keys and/or the configuration can monitor transactions
in the wallet, resulting in loss of privacy.

This proposal seeks to address concerns #1, #2 and #3: to mitigate the
risk of tampering during the initial setup phase, and to define an
interoperable multisig configuration format.

Concerns #4 and #5 should be handled by Signers and are out of scope
of this proposal.

==Specification==

===Prerequisites===
This proposal assumes the parties in the multisig support
[https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
BIP-0032], [https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
BIP-0322], [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md
the descriptor language] and [https://tools.ietf.org/html/rfc3686 AES
encryption].

===File Extension===
All descriptor and key records should have a <tt>.bsms</tt> file
extension. Encrypted data should have a <tt>.dat</tt> extension.

===Roles===
====Coordinator====

The Coordinator initiates the multisig setup. The Coordinator
determines what type of multisig is used and the exact policy script.
If encryption is enabled, the Coordinator also distributes a shared
secret or shared secrets to the parties involved for secure
communication. The Coordinator gathers information from the Signers to
generate a descriptor record. The Coordinator distributes the
descriptor record back to the Signers.

====Signer====

The Signer is a participating member in the multisig. Its
responsibilities include providing its key record -- which contains an
Extended Public Key (XPUB) -- to the Coordinator, verifying that its
XPUB is included in the descriptor record and persisting the
descriptor record in its storage.

===Setup Process===

====Round 1====

=====Coordinator=====

* The Coordinator creates a new multisig wallet creation session. The
Coordinator constructs the multisig script and its policy parameters,
such as the required number of signatures and the total number of
Signers (<tt>M</tt> and <tt>N</tt>).
* The session should expire after some time period determined by the
Coordinator, e.g., 24 hours. The timeout allows the encryption key to
have lower entropy.
* If encryption is enabled, the Coordinator distributes a secret
<tt>TOKEN</tt> to each Signer over a secure channel. The Signer can
use the <tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to
the Encryption section below for details on the <tt>TOKEN</tt>, the
key derivation function and the encryption scheme. Depending on the
use case, the Coordinator can decide whether to share one common
<tt>TOKEN</tt> for all Signers, or to have one per Signer.
* If encryption is disabled, the <tt>TOKEN</tt> is set to <tt>0</tt>,
and all the encryption/decryption steps below can be skipped.

=====Signer=====

* The Signer initiates the multisig wallet creation session by setting
the <tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from
the <tt>TOKEN</tt>. The Signer can keep the session open until a
different value for the <tt>TOKEN</tt> is set.
* The Signer generates a key record by prompting the user for a
multisig derivation path and retrieves the XPUB at that derivation
path. Alternatively, the Signer can choose a path on behalf of the
user. If the Signer chooses the path, it should try to avoid reusing
XPUBs for different wallets.
* The first line in the record must be the specification version
(<tt>BSMS 1.0</tt> as of this writing). The second line must be the
hex-encoded <tt>TOKEN</tt>. The third line must be the <tt>KEY</tt>.
The <tt>KEY</tt> is an XPUB plus its key origin information, written
in the descriptor-defined format, i.e.: <tt>[{master key
fingerprint}/{derivation path}]{XPUB}</tt>. The fourth line is a text
description of the key, 80 characters maximum. The fifth line must be
a <tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by
using the private key associated with the XPUB to sign the first four
lines. The signature should follow
[https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
BIP-0322], legacy format accepted.
* The Signer calculates the Message Authentication Code (<tt>MAC</tt>)
for the record. The first 16 bytes of the <tt>MAC</tt> serves as the
Initialization Vector (<tt>IV</tt>) for the encryption.
* The Signer encrypts the key record with the <tt>ENCRYPTION_KEY</tt>
and <tt>IV</tt>.
* The Signer encodes the <tt>MAC</tt> and the ciphertext into
hexadecimal format, then concatenates the results: <tt>(MAC ||
ciphertext)</tt>.

====Round 2====

=====Coordinator=====

* The Coordinator gathers key records from all participating Signers.
The Coordinator verifies that there are exactly <tt>N</tt> unique key
records before the wallet setup session expires.
* For each key record, the Coordinator extracts the <tt>MAC</tt> from
the data, sets <tt>IV</tt> to the first 16 bytes of the <tt>MAC</tt>,
then decrypts the ciphertext using the <tt>ENCRYPTION_KEY</tt> and
<tt>IV</tt>.
* The Coordinator verifies that the included <tt>MAC</tt> is valid
given the plaintext.
* The Coordinator verifies that the key records have compatible
specification versions.
* The Coordinator verifies that the included <tt>SIG</tt> is valid
given the <tt>KEY</tt>.
* If all key records look good, the Coordinator fills in all necessary
information to generate a descriptor record.
* The first line in the descriptor record must be the specification
version (<tt>BSMS 1.0</tt> as of this writing). The second line must
be a comma-separated list of accepted derivation paths that the
Signers can use to generate addresses from the included XPUBs. The
paths must start with <tt>/</tt> and use non-hardened derivation. For
example, <tt>/0/*</tt> and <tt>/1/*</tt> are some common paths. If
there are no restrictions, it must say <tt>No path restrictions</tt>.
The third line must be the descriptor string plus a <tt>CHECKSUM</tt>,
all in one line. The <tt>CHECKSUM</tt> has
[https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
BECH32 encoding].
* The Coordinator calculates the <tt>MAC</tt> for the record. The
first 16 bytes of the <tt>MAC</tt> serves as the <tt>IV</tt> for the
encryption..
* The Coordinator encrypts the descriptor record with the
<tt>ENCRYPTION_KEY</tt> and <tt>IV</tt>.
* The Coordinator encodes the <tt>MAC</tt> and the ciphertext into
hexadecimal format, then concatenates the results: <tt>(MAC ||
ciphertext)</tt>.
* The Coordinator sends the encrypted descriptor record to all
participating Signers.

=====Signer=====

* The Signer imports the descriptor record.
* The Signer extracts the <tt>MAC</tt> from the data, sets <tt>IV</tt>
to the first 16 bytes of the <tt>MAC</tt>, then decrypts the
ciphertext using the <tt>ENCRYPTION_KEY</tt> (derived from the open
session) and <tt>IV</tt>.
* The Signer verifies that the included <tt>MAC</tt> is valid given
the plaintext.
* The Signer verifies that it can support the included specification version.
* The Signer verifies that it is compatible with the derivation path
restrictions.
* The Signer verifies the descriptor’s <tt>CHECKSUM</tt>.
* The Signer verifies that it can support the descriptor.
* The Signer checks that its <tt>KEY</tt> is included in the
descriptor, using path and fingerprint information provided. The check
must perform an exact match on the <tt>KEY</tt>s and not using
shortcuts such as matching fingerprints, which is trivial to spoof.
* For confirmation, the Signer must display to the user the
<tt>CHECKSUM</tt>, the derivation path restrictions and the policy
parameters, such as <tt>M</tt>, <tt>N</tt> and the position(s) of its
own XPUB in the policy script. The total number of Signers,
<tt>N</tt>, is important to prevent a <tt>KEY</tt> insertion attack.
The position is important for scripts where key order matters. When
applicable, all positions of the XPUB must be displayed. The full
descriptor must also be available for review upon user request.
* When possible, the Signer should also show a preview of the first
address(es) of the wallet.
* Parties must check with each other that all Signers have verified
the descriptor and has the same confirmation (except for the key
positions).
* If all checks pass, the Signer must persist the descriptor record in
its storage.

This completes the setup.

===Encryption===

====The Token====
We define three modes of encryption.

# <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>.
Encryption is disabled.
# <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
# <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 96-bit nonce.

The <tt>TOKEN</tt> can be converted to one of these formats:
* A decimal number (recommended). The number must not exceed the
maximum value of the nonce.
* A mnemonic phrase using
[https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
BIP-0039] word list (6 words in <tt>STANDARD</tt> mode; 9 words in
<tt>EXTENDED</tt> mode).
* A QR code.
* Other formats.

The flexibility in the data format allows each Signer to customize the
User Experience based on its respective capabilities.

====Key Derivation====
The key derivation function is [https://tools.ietf.org/html/rfc2898
PBKDF2], with PRF = SHA512. Specifically:

<tt>DKey = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>

Whereas:

* PRF = SHA512
* Password = "No SPOF"
* Salt = <tt>TOKEN</tt>
* c = 2048
* dkLen = 256
* DKey = Derived <tt>ENCRYPTION_KEY</tt>

====Encryption Scheme====
The encryption scheme is [https://tools.ietf.org/html/rfc3686 AES-256-CTR].

<tt>MAC = HMAC-SHA256(HMAC_Key, hex-encoded TOKEN || Data)</tt>

<tt>IV = First 16 bytes of MAC</tt>

<tt>Ciphertext = AES-256-CTR-Encrypt(Plaintext, DKey, IV)</tt>

<tt>Plaintext = AES-256-CTR-Decrypt(Ciphertext, DKey, IV)</tt>

Whereas:
* DKey = <tt>ENCRYPTION_KEY</tt>
* HMAC_Key = SHA256(<tt>ENCRYPTION_KEY</tt>)
* Data = the plaintext, e.g. the entire key record in round 1 and the
entire descriptor record in round 2

The <tt>MAC</tt> is to be sent along with the key and descriptor
record, as specified above. Because it is a <tt>MAC</tt> over the
entire plaintext, this is essentially an
[https://en.wikipedia.org/wiki/Authenticated_encryption#Encrypt-and-MAC_(E&M)
Encrypt-and-MAC] form of authenticated encryption.

==QR Codes==
For signers that use QR codes to transmit data, key and descriptor
records can be converted to QR codes, following
[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
the BCR standard].

Also refer to [https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
UR Type Definition for BIP44 Accounts] and
[https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
UR Type Definition for Bitcoin Output Descriptors] for more details.

==Security==

This proposal introduces two layers of protection. The first one is a
temporary, secret <tt>TOKEN</tt>. The second one is the descriptor
<tt>CHECKSUM</tt>.

The <tt>TOKEN</tt> is used to encrypt the two rounds of communication
between the Signer and the Coordinator. A <tt>MAC</tt> is also
generated from the <tt>TOKEN</tt> and plaintext to authenticate the
data being exchanged. The <tt>TOKEN</tt> is only needed during the
setup phase, and can be safely discarded afterwards.

The descriptor <tt>CHECKSUM</tt>, on the other hand, can be used to
verify the integrity of the multisig configuration. An attacker who
tampers with the multisig configuration must also change the
descriptor <tt>CHECKSUM</tt>. Parties must check with each other that
all Signers have the same <tt>CHECKSUM</tt>, along with the policy
parameters, to reduce the chance of tampering. The <tt>CHECKSUM</tt>
must be persisted along with the descriptor in each Signer’s storage.

The <tt>TOKEN</tt> and the <tt>CHECKSUM</tt> can’t guarantee complete
protection, since that depends on the overall security of all parties
in the setup, but they can make it significantly harder for an
attacker to tamper with the multisig configuration.

==Privacy==
Encryption helps improve the privacy of the wallet by avoiding sharing
XPUBs and descriptors in plaintext.

If the parties wish to have stronger privacy, it is recommended to use
a higher number of bits for the <tt>TOKEN</tt>, and to completely
erase knowledge of the <tt>TOKEN</tt> after the multisig wallet has
been set up.

==Test Vectors==

===Mode: <tt>NO_ENCRYPTION</tt>===
====ROUND 1====
* Coordinator
** M-of-N: 2/2
** ADDRESS_TYPE: NATIVE_SEGWIT
** TOKEN: 0

* Signer 1
** MASTER_KEY_FINGERPRINT: 539f3d89
** PRIVATE_KEY (m/48'/0'/0'/2'):
KyoXqiwiz6qm21BSYebiZFfNF7obkhiJW6TdPMZTQQMF4kZtfD78
** XPUB (m/48'/0'/0'/2'):
xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa
** Legacy signature
** <tt>signer_1_key.bsms</tt>:
<pre>BSMS 1.0
00
[539f3d89/48'/0'/0'/2']xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa
Signer 1 key
IPXsnNSZb8M6H4fAWtpjAc75hyHHd89fskpM5o7qFg+mPDzEPc1k2mjuIpVIIzaCe45FwPfAAa91RaStfC5Sak0=</pre>

* Signer 2
** MASTER_KEY_FINGERPRINT: f8b12aa6
** PRIVATE_KEY (m/48'/0'/0'/2'):
L1zht7muKnUYFMdzC3jwXd78u8tGoKr46AXGh4waF9nphUYWq7ow
** XPUB (m/48'/0'/0'/2'):
xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM
** Legacy signature
** <tt>signer_2_key.bsms</tt>:
<pre>BSMS 1.0
00
[f8b12aa6/48'/0'/0'/2']xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM
Signer 2 key
H38+lp9iaesBeCN05BDTH/SnmarlH6+X+Kmw1pgCk+c1Pc1evYIdBag9Nc0nsKhvPtfEbRt9r/qsUVZ5onCtBTc=</pre>

====ROUND 2====
* Coordinator
** <tt>my_multisig_wallet.bsms</tt>:
<pre>BSMS 1.0
/0/*,/1/*
wsh(sortedmulti(2,[539f3d89/48'/0'/0'/2']xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa/*,[f8b12aa6/48'/0'/0'/2']xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM/*))#fntxdj7p</pre>

===Mode: <tt>STANDARD</tt> Encryption===
====ROUND 1====
* Coordinator
** M-of-N: 2/2
** ADDRESS_TYPE: NATIVE_SEGWIT
** TOKEN (hex): 1ed4ba49e96336b8
*** TOKEN (decimal): 2221605342811469496
*** TOKEN (mnemonic): burst place mystery spot cricket foster
** ENCRYPTION_KEY (hex):
72185a0e25b4efc5d6ac0f8ed32b0165199100e32385040e3a48eb30164bf492

* Signer 1
** MASTER_KEY_FINGERPRINT: 98d79e95
** PRIVATE_KEY (m/48'/0'/0'/2'):
KydC7hZFtWe56oQUAw14HvQ3gKeKVd3m8frFgVMxUqpuhKHvcmm3
** XPUB (m/48'/0'/0'/2'):
xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt
** Legacy signature
** <tt>signer_1_key.bsms</tt>:
<pre>BSMS 1.0
1ed4ba49e96336b8
[98d79e95/48'/0'/0'/2']xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt
Signer 1 key
HxtPoP0DrQSac/7ypcwC07R2s6jjpXR6Li2Q92zXj/FSIMQcV5yOU0/ONsDgHXamq0gD5DfPbvuVCp9ZJubclV4=</pre>

* Signer 1 encryption
** HMAC_KEY (hex):
4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
** MAC (hex): afe99e92f0eadc3308eb990045e90a4f54e9f59d22aae5034ac3d866d29c508d
** IV (hex) : afe99e92f0eadc3308eb990045e90a4f
** CIPHERTEXT (hex):
214ec9a861a238ba7f0412305a97a6e0faa332be15af09127e131d669e5d55d73891580a5808cea5d2bf39f43496d3c0f8236eff3854fcc7446daf9d2b58fd40d97ce3b1745de2959e29767039b99969821400eca0c3517fae56d2d24d5235a3430af1ed894b68681d706cce7c75adf35d8580603aa302bc01fef06d0336a37f19dd46100baa9e4eabd8796a810e13941ad0980c126ad55d6a4bbef11a7bf893b7d2ed8fb0d8324c4c9b512d4d1e75096c63511e15018fc832816b5639d58fc28c60c049487d04bd5a6cb32aa1381d0809660d54376b9f63325c18cfd1ac5024088e74cb703fe165972cc4485abb1feefe92a0b4ea297fe2f4f7416eeee1efc9b942540931ef
** <tt>signer_1_key.dat</tt>:
<pre>afe99e92f0eadc3308eb990045e90a4f54e9f59d22aae5034ac3d866d29c508d214ec9a861a238ba7f0412305a97a6e0faa332be15af09127e131d669e5d55d73891580a5808cea5d2bf39f43496d3c0f8236eff3854fcc7446daf9d2b58fd40d97ce3b1745de2959e29767039b99969821400eca0c3517fae56d2d24d5235a3430af1ed894b68681d706cce7c75adf35d8580603aa302bc01fef06d0336a37f19dd46100baa9e4eabd8796a810e13941ad0980c126ad55d6a4bbef11a7bf893b7d2ed8fb0d8324c4c9b512d4d1e75096c63511e15018fc832816b5639d58fc28c60c049487d04bd5a6cb32aa1381d0809660d54376b9f63325c18cfd1ac5024088e74cb703fe165972cc4485abb1feefe92a0b4ea297fe2f4f7416eeee1efc9b942540931ef</pre>

* Signer 2
** MASTER_KEY_FINGERPRINT: 3e94b5a1
** PRIVATE_KEY (m/48'/0'/0'/2'):
KyPh5XYjExjNHPiBjYhp8iAntAehrDziiwRv7y9Ln6eK9QU2xP55
** XPUB (m/48'/0'/0'/2'):
xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c
** Legacy signature
** <tt>signer_2_key.bsms</tt>:
<pre>BSMS 1.0
1ed4ba49e96336b8
[3e94b5a1/48'/0'/0'/2']xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c
Signer 2 key
ILR49QLy9+xkMS11TIXJRSMgOQOzGbAaooq4/ZRcd8VgM6j5upJMI0mjJHseQOMYSGk8FqjXZbMvBGyiX9wdutM=</pre>

* Signer 2 encryption
** HMAC_KEY (hex):
4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
** MAC (hex): 5c7cb2ac407cd60b1f2b86ef46077d3a312b6ce921df2a141347e8bf1e5c6573
** IV (hex) : 5c7cb2ac407cd60b1f2b86ef46077d3a
** CIPHERTEXT (hex):
f23e6c76ff45d308dea6014030a274127ad437228f1d5ec2431d2ea9e3cedd5b0a207a9efa6f926d5420205003f3cb9c4b82b2d595180e62a173a2e5aa0322de48a70a873f641bdae1764e6b1667c241e0fe03a4ccdc3fe0cfa5f75b239d6497c3b69dca17bb685ba70b307d1243836d8fb198ce727cfae4057ee0b4fdcb09f4ba5ae127f49c5de780edb4e40aec96303c8a7b98b1b8e53dd5e07e01d4f3ffd836763209a1f0cbc61adcfdc2951e77528ee7b6e68114c3a4bec38875d285021e68ae8aa913bb1e2e65dd52c649a0e98bfb4e8bab6dd10295c1167a0854ba44f094feb75d2fb00c944f07d4b47114f483df9838459316f3ddbc4a82e6507881931f8e20f5b805
** <tt>signer_2_key.dat</tt>:
<pre>5c7cb2ac407cd60b1f2b86ef46077d3a312b6ce921df2a141347e8bf1e5c6573f23e6c76ff45d308dea6014030a274127ad437228f1d5ec2431d2ea9e3cedd5b0a207a9efa6f926d5420205003f3cb9c4b82b2d595180e62a173a2e5aa0322de48a70a873f641bdae1764e6b1667c241e0fe03a4ccdc3fe0cfa5f75b239d6497c3b69dca17bb685ba70b307d1243836d8fb198ce727cfae4057ee0b4fdcb09f4ba5ae127f49c5de780edb4e40aec96303c8a7b98b1b8e53dd5e07e01d4f3ffd836763209a1f0cbc61adcfdc2951e77528ee7b6e68114c3a4bec38875d285021e68ae8aa913bb1e2e65dd52c649a0e98bfb4e8bab6dd10295c1167a0854ba44f094feb75d2fb00c944f07d4b47114f483df9838459316f3ddbc4a82e6507881931f8e20f5b805</pre>

====ROUND 2====
*Coordinator
** <tt>my_multisig_wallet.bsms</tt>:
<pre>BSMS 1.0
/0/*,/1/*
wsh(sortedmulti(2,[98d79e95/48'/0'/0'/2']xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt/*,[3e94b5a1/48'/0'/0'/2']xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c/*))#x0lx92qk</pre>

*Coordinator encryption
** HMAC_KEY (hex):
4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
** MAC (hex): df3d06db6c8b8a5f25de202e10ea225df6415d1ed0e36c64cc2be1b7e86c2a38
** IV (hex) : df3d06db6c8b8a5f25de202e10ea225d
** CIPHERTEXT (hex):
2761e6bfe839586b4c90954200bc4ce6d39ef164c5d14997755575d1691ee249ffd20beda526f57a7424907f839c6c2e3ecd46889ede290a2c81de22d3f33a7fa5e55ec95c0e26005c596d0f6346f819823f361f9f9f54d1eae48b325240d66c5888bd5ebab843061dcdd73b675346da982646c83026694d757661d31c2d654fb263c9ab3e874a258bc234c48532f15e9450c982fcf161404746e9f23d25e17b74139cd799983fd0c7a7a0386a823d3789b4578879a764172cc8ef96ab003eee24f6288007d31e2b999aff5a6d30cc524a0111a99730a29cf28ae41dbff6ce21ca6bc1df37074228178048e835584e6e70dba941154d024cd03cb6c56d0bde441ce464aa749de5e814dd30e21b75f62e831ac1f28eda1a7ba7e122076789e284402c8ba85b5a0e864bce220e3c78fa2f465e2bcf6b1d378816319de99f99ce7068
** <tt>my_multisig_wallet.dat</tt>:
<pre>df3d06db6c8b8a5f25de202e10ea225df6415d1ed0e36c64cc2be1b7e86c2a382761e6bfe839586b4c90954200bc4ce6d39ef164c5d14997755575d1691ee249ffd20beda526f57a7424907f839c6c2e3ecd46889ede290a2c81de22d3f33a7fa5e55ec95c0e26005c596d0f6346f819823f361f9f9f54d1eae48b325240d66c5888bd5ebab843061dcdd73b675346da982646c83026694d757661d31c2d654fb263c9ab3e874a258bc234c48532f15e9450c982fcf161404746e9f23d25e17b74139cd799983fd0c7a7a0386a823d3789b4578879a764172cc8ef96ab003eee24f6288007d31e2b999aff5a6d30cc524a0111a99730a29cf28ae41dbff6ce21ca6bc1df37074228178048e835584e6e70dba941154d024cd03cb6c56d0bde441ce464aa749de5e814dd30e21b75f62e831ac1f28eda1a7ba7e122076789e284402c8ba85b5a0e864bce220e3c78fa2f465e2bcf6b1d378816319de99f99ce7068</pre>

===Mode: <tt>EXTENDED</tt> Encryption===
====ROUND 1====
*Coordinator
** M-of-N: 2/3
** ADDRESS_TYPE: NESTED_SEGWIT
** TOKEN for Signer 1 (hex): 654d63309464afcda558c6aa
*** TOKEN (decimal): 31351541690484562733651510954
*** TOKEN (mnemonic): grab help slow churn enough traffic nice boat price
*** ENCRYPTION_KEY (hex):
4073adac2351e164b8d68039abd9d4b8e4d07adccfdf73ece6e236d60b107802
** TOKEN for Signer 2 (hex): b0344f51d5cb04083d598fa3
*** TOKEN (decimal): 54532600447720520868878192547
*** TOKEN (mnemonic): rabbit pen stamp process raccoon advice voice
cradle person
*** ENCRYPTION_KEY (hex):
6bae6b670e257d7468c3e90194029dd468a2f39d8b9a3ff187b08209b1d409b6
** TOKEN for Signer 3 (hex): 163fd307195982c4c39d50bb
*** TOKEN (decimal): 6885829092987042066541138107
*** TOKEN (mnemonic): bike write scrub crawl oblige give attack present rookie
*** ENCRYPTION_KEY (hex):
c78b94589214b6dc98b337ba4ce54380553ed00a1e5b1955fc540ce3b30d6566

* Signer 1
** MASTER_KEY_FINGERPRINT: 110dc257
** PRIVATE_KEY (m/48'/0'/0'/1'):
KzshDDEBhzyiwXHoyE7ZiLegzztEy54AG6Wq8N844LqHSQMHt4Ji
** XPUB (m/48'/0'/0'/1'):
xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk
** Legacy signature
** <tt>signer_1_key.bsms</tt>:
<pre>BSMS 1.0
654d63309464afcda558c6aa
[110dc257/48'/0'/0'/1']xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk
Signer 1 key
IDX6xLdM4XjetYPvVfpVBXAfT7oE3tHAOB4blZpbIst8bjJ+LbDeP4tZl4O8utAuys9igXE0G3kaHz1mg/+OU8w=</pre>

* Signer 1 encryption
** HMAC_KEY (hex):
f43c359a4b3d7b2e01be73c54519b12545ca9a23a86f824aadf577b314a7caa7
** MAC (hex): 40b6b43e2f1bc01b748eb242235d7e09fa8a2fd6cebe35784cf3adf81910ec98
** IV (hex) : 40b6b43e2f1bc01b748eb242235d7e09
** CIPHERTEXT (hex):
0877987764401c27e6c60ed2f1bb89dff1dbc5e8204149f682d53049bffe39553f24af3928aa2f78ac2d04ac5baa0c3ec39aaccf0d258e7bb6659a7b92e92f2c2784a94f4df8e8af2270d9d411bfff2cfb9f71b4e1ac87561c7d2ac57ca86a1f9716d5da7571719d24830fc8d015a0daf04b3742439484488798335357f2eeaa8e2db2ba630f9dffd88236e327ab5bfcfb6e29ee3ef6cc18e0b71c1731465c2351e76b92f7b1bd28ef6eff5414c22aa6c80090fa59b973c22e3044e92dbf3688990a49a42828e52c1e686f1193dcdf7b7118930e01419fe938c6811c58c84c36d692fd52846f998bc328471f1e73c22261791a08cda096ee3ac8b37f31afd0b1d9c335ff9ac67ff230eb0d69f2d7
** <tt>signer_1_key.dat</tt>:
<pre>40b6b43e2f1bc01b748eb242235d7e09fa8a2fd6cebe35784cf3adf81910ec980877987764401c27e6c60ed2f1bb89dff1dbc5e8204149f682d53049bffe39553f24af3928aa2f78ac2d04ac5baa0c3ec39aaccf0d258e7bb6659a7b92e92f2c2784a94f4df8e8af2270d9d411bfff2cfb9f71b4e1ac87561c7d2ac57ca86a1f9716d5da7571719d24830fc8d015a0daf04b3742439484488798335357f2eeaa8e2db2ba630f9dffd88236e327ab5bfcfb6e29ee3ef6cc18e0b71c1731465c2351e76b92f7b1bd28ef6eff5414c22aa6c80090fa59b973c22e3044e92dbf3688990a49a42828e52c1e686f1193dcdf7b7118930e01419fe938c6811c58c84c36d692fd52846f998bc328471f1e73c22261791a08cda096ee3ac8b37f31afd0b1d9c335ff9ac67ff230eb0d69f2d7</pre>

* Signer 2
** MASTER_KEY_FINGERPRINT: 5c890401
** PRIVATE_KEY (m/48'/0'/0'/1'):
L41Jnc9CdBtBJd18429MDGcTgP2DNoXaKyyGr271ndTprvrHXDQf
** XPUB (m/48'/0'/0'/1'):
xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q
** Legacy signature
** <tt>signer_2_key.bsms</tt>:
<pre>BSMS 1.0
b0344f51d5cb04083d598fa3
[5c890401/48'/0'/0'/1']xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q
Signer 2 key
H5kN6UHaK2xACB6iYdTxxQPD8qyFEYv9iMsQs5B0MRfCM7NA5GB+7EFgmBpSctwt6B122zWBr6mRjpYjKmj+7hs=</pre>

* Signer 2 encryption
** HMAC_KEY (hex):
e0a20b5f5285fbaa35aad08fb70f5626c9abbe1b384a4950735b28aca6325ff2
** MAC (hex): 3a6deec8dbdbd6606a52c7d7e64eca4f972a293cbabac6f62736629fbe77928a
** IV (hex) : 3a6deec8dbdbd6606a52c7d7e64eca4f
** CIPHERTEXT (hex):
bb0fb72f61b0c4858bd9c65235390b67651b94c4b0329238b0116dd6d3365ade33cb1c1b1619638968791a5d2d1d263d90280bdad8d9ca24c34a78e320076e0dccf59e7f729b541b44bbe40ba803dedd3b17c49765377cb2d913a856b86c3dd383dab475790e89226ed8ef2301574212d2809ed9c099aa67be434024ee2a4e82a146300acf755863da64807cb7bb2636f6616489636d254a870778d3540832aea44abac4328b5d90f3e6045ef36a526ce5d575f2305e3e4699dccbc713e9e68f50364036c1054c2a506aab77ea7c43a89536947c24330b09a62a90c3b4ae2d452f96ef34ec871af2c52d68ddede2503c87e2ba68d5cf9be589457879e06021ea6a6176f7dded820ba4c0e709e2a2
** <tt>signer_2_key.dat</tt>:
<pre>3a6deec8dbdbd6606a52c7d7e64eca4f972a293cbabac6f62736629fbe77928abb0fb72f61b0c4858bd9c65235390b67651b94c4b0329238b0116dd6d3365ade33cb1c1b1619638968791a5d2d1d263d90280bdad8d9ca24c34a78e320076e0dccf59e7f729b541b44bbe40ba803dedd3b17c49765377cb2d913a856b86c3dd383dab475790e89226ed8ef2301574212d2809ed9c099aa67be434024ee2a4e82a146300acf755863da64807cb7bb2636f6616489636d254a870778d3540832aea44abac4328b5d90f3e6045ef36a526ce5d575f2305e3e4699dccbc713e9e68f50364036c1054c2a506aab77ea7c43a89536947c24330b09a62a90c3b4ae2d452f96ef34ec871af2c52d68ddede2503c87e2ba68d5cf9be589457879e06021ea6a6176f7dded820ba4c0e709e2a2</pre>

* Signer 3
** MASTER_KEY_FINGERPRINT: 614cbf5f
** PRIVATE_KEY (m/48'/0'/0'/1'):
L2ccRLzH7GfVxWpU8YSY9y5UGyRoqW3UdeNT1vGfVbxAGhwU5qhD
** XPUB (m/48'/0'/0'/1'):
xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH
** Legacy signature
** <tt>signer_3_key.bsms</tt>:
<pre>BSMS 1.0
163fd307195982c4c39d50bb
[614cbf5f/48'/0'/0'/1']xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH
Signer 3 key
H0jf2JMtke5zDDIWys6fihOCA6QBmC5+hbgVB/c2mMPNPLB6tDXt0TFZU1f9wvaCR9762anKSc8CCqXLogw8V00=</pre>

* Signer 3 encryption
** HMAC_KEY (hex):
1f51ea067c121e2f86af5e1d484905046bc63e861573157d8b1ae9e7e47e224b
** MAC (hex): 1a5624fcb39cebabb6174456173eec19b756bc916cf2c9d815e9bcce070898c4
** IV (hex) : 1a5624fcb39cebabb6174456173eec19
** CIPHERTEXT (hex):
48d6e139bdc8c19e93cbbf5b4478340c8cf08aa91c28803084d5f58618773f7e615e0134492b496c4e7c130351c0350701f686918033f621378552d7040efedd5539d38c258bf936475de775f23da3953fe3ba5bbbd24816b8902b87a9a09700c446b085119dedee2395dd69665e742f72f2fb6da4ebe3f4704eaf45486fbfb84d764b718cc0b756e72f72ab6069d47765bdd3ebd4074af4fa99a95691a659675ce5f72235c28ddf3c3d53179e598cddc967fc896adc6e97edeeffc85b9e44611df748d923ff3dd921ad4d6e98e0de12359a37558e326faf585ba57e73ab45bc4a49f6e8a756f365f5d204e70f7c7bed269e81e9524a41e5d4cbaad0b6b442d6eea1e5da1ca345cc665a0cffe2c3
** <tt>signer_3_key.dat</tt>:
<pre>1a5624fcb39cebabb6174456173eec19b756bc916cf2c9d815e9bcce070898c448d6e139bdc8c19e93cbbf5b4478340c8cf08aa91c28803084d5f58618773f7e615e0134492b496c4e7c130351c0350701f686918033f621378552d7040efedd5539d38c258bf936475de775f23da3953fe3ba5bbbd24816b8902b87a9a09700c446b085119dedee2395dd69665e742f72f2fb6da4ebe3f4704eaf45486fbfb84d764b718cc0b756e72f72ab6069d47765bdd3ebd4074af4fa99a95691a659675ce5f72235c28ddf3c3d53179e598cddc967fc896adc6e97edeeffc85b9e44611df748d923ff3dd921ad4d6e98e0de12359a37558e326faf585ba57e73ab45bc4a49f6e8a756f365f5d204e70f7c7bed269e81e9524a41e5d4cbaad0b6b442d6eea1e5da1ca345cc665a0cffe2c3</pre>

====ROUND 2====
* Coordinator
** <tt>my_multisig_wallet.bsms</tt>:
<pre>BSMS 1.0
/0/*,/1/*
sh(wsh(multi(2,[110dc257/48'/0'/0'/1']xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk/*,[5c890401/48'/0'/0'/1']xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q/*,[614cbf5f/48'/0'/0'/1']xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH/*)))#j3ykhz7f</pre>

* Send to Signer 1:
** HMAC_KEY (hex):
f43c359a4b3d7b2e01be73c54519b12545ca9a23a86f824aadf577b314a7caa7
** MAC (hex): ee74a0f50943d7d1b65270028bb05133e87c832cdc1ef0a07c79db2093ca3432
** IV (hex) : ee74a0f50943d7d1b65270028bb05133
** CIPHERTEXT (hex):
8e3ba3dac0f979fad0d160bd00c8294ff1726d51b95ff3e1534e5a1900f3d7cd4f6d929985a94b9da2c11e4e0f7770cc53c6739fd099477323bd26a3eca9c8016e79848d15e274463424b8355cd73cced61f1816ac8bac87f8c650ee9052f50e347c52ad24b00794a9d5523714be2fdcf731f14b7a8d7c93eab44c258e1c417d2837b9676832e8ce7239dc28b4e1166803209947b8a875a99b9478ee94f7bc17399e886179ab2a0285dc11a3883f6fa439d0f2277dadbec8c355c379fc50e945897e1a738f6a55b09f6b8b6bdf6d4bc248219cbad3662a78a2f539c989e055e00b8efd42fbff978e1a5cc10f83df56117ece4d17f94a0a6d3803778ed53531419250c5a0fff6cad4ab401468dd054915b068cc8826ae1308a71b38060d68c9248d59eea11c2c52a66d5f6bc0d7ae6cb44305c36e56068456d293b70037902e7b05a3ee0af710201128dffc0c16c3306b66bd19b9ae5b91aded35ef33f07743e5b185a9f88a5c67d40270e3bbcf592167ceaf82ead693728d5129b50075edd5ce24863f3484b4b063599ed1327e1c87d0a2051fed3b1234a702722b686e4c9392a403b79726800dd6b691e516e44d9e836c190b10cf2bb262bba98293c97f2c323e59acd0a1f988c5
** <tt>my_multisig_wallet_for_signer_1.dat</tt>:
<pre>ee74a0f50943d7d1b65270028bb05133e87c832cdc1ef0a07c79db2093ca34328e3ba3dac0f979fad0d160bd00c8294ff1726d51b95ff3e1534e5a1900f3d7cd4f6d929985a94b9da2c11e4e0f7770cc53c6739fd099477323bd26a3eca9c8016e79848d15e274463424b8355cd73cced61f1816ac8bac87f8c650ee9052f50e347c52ad24b00794a9d5523714be2fdcf731f14b7a8d7c93eab44c258e1c417d2837b9676832e8ce7239dc28b4e1166803209947b8a875a99b9478ee94f7bc17399e886179ab2a0285dc11a3883f6fa439d0f2277dadbec8c355c379fc50e945897e1a738f6a55b09f6b8b6bdf6d4bc248219cbad3662a78a2f539c989e055e00b8efd42fbff978e1a5cc10f83df56117ece4d17f94a0a6d3803778ed53531419250c5a0fff6cad4ab401468dd054915b068cc8826ae1308a71b38060d68c9248d59eea11c2c52a66d5f6bc0d7ae6cb44305c36e56068456d293b70037902e7b05a3ee0af710201128dffc0c16c3306b66bd19b9ae5b91aded35ef33f07743e5b185a9f88a5c67d40270e3bbcf592167ceaf82ead693728d5129b50075edd5ce24863f3484b4b063599ed1327e1c87d0a2051fed3b1234a702722b686e4c9392a403b79726800dd6b691e516e44d9e836c190b10cf2bb262bba98293c97f2c323e59acd0a1f988c5</pre>

* Send to Signer 2:
** HMAC_KEY (hex):
e0a20b5f5285fbaa35aad08fb70f5626c9abbe1b384a4950735b28aca6325ff2
** MAC (hex): 81df9e064f1de1d5f754c4e20f9286f9d81b856d3965677a9f2430cb9297ad1f
** IV (hex) : 81df9e064f1de1d5f754c4e20f9286f9
** CIPHERTEXT (hex):
dcd82038ef627d6cb2deb62d04c4ccbaa3a354633d960e46312c22791f039f23fd9782a1e3a63504c1e5b3a0770bb8d32fdf168738b6c03278f1391dd5d01e9aafee7be2c8136ee018feff6fc8cdb926df13a36e115ddca8254934f56b7f700768c94cb8388a8297834de9affcd959417ae3d6ec3251387904f50f51f06306cc4d36eefc51418dd3b2c5454910a23ec67a40a3b918d2a740e812929aae949d8dde2c41cbbb3a2b7c2103788421c147f4794d6a26947c15ef4a99ceb825d0c5aaa78b8737d0ef712ba8e269a9941b1af5d217dcdd9cd06727fbdc70fabe3f5a8c09acff4e76992be7f27c6b12ca84739f62a6da86e5b79103d632c0dc8ab3f91fddb3cfbe67084dc4b861c4ac7c86fb171a058c98c67cffdc40ff17ae1533361cc6fb7b63657af0408cf30bf9d6d97aaacf9d3ff443eee61f207228cd91769ce83a0709c1be1847884c6a8fdc86ede66aef8e34fc509c49edf30f743bdc8f9052961ee340924ec2d1caadc6fd286bb3e233c153cd08c1934127752dc28e0d12efa92a050c4061653edb1cbf2fd4b2ba4e038f0b44f5735f198e92571c029156f65f534bfc149f38d611829901372cfc0176b9d2f9ac6512b7f37941a02dff701df0bceadaacfc6935
** <tt>my_multisig_wallet_for_signer_2.dat</tt>:
<pre>81df9e064f1de1d5f754c4e20f9286f9d81b856d3965677a9f2430cb9297ad1fdcd82038ef627d6cb2deb62d04c4ccbaa3a354633d960e46312c22791f039f23fd9782a1e3a63504c1e5b3a0770bb8d32fdf168738b6c03278f1391dd5d01e9aafee7be2c8136ee018feff6fc8cdb926df13a36e115ddca8254934f56b7f700768c94cb8388a8297834de9affcd959417ae3d6ec3251387904f50f51f06306cc4d36eefc51418dd3b2c5454910a23ec67a40a3b918d2a740e812929aae949d8dde2c41cbbb3a2b7c2103788421c147f4794d6a26947c15ef4a99ceb825d0c5aaa78b8737d0ef712ba8e269a9941b1af5d217dcdd9cd06727fbdc70fabe3f5a8c09acff4e76992be7f27c6b12ca84739f62a6da86e5b79103d632c0dc8ab3f91fddb3cfbe67084dc4b861c4ac7c86fb171a058c98c67cffdc40ff17ae1533361cc6fb7b63657af0408cf30bf9d6d97aaacf9d3ff443eee61f207228cd91769ce83a0709c1be1847884c6a8fdc86ede66aef8e34fc509c49edf30f743bdc8f9052961ee340924ec2d1caadc6fd286bb3e233c153cd08c1934127752dc28e0d12efa92a050c4061653edb1cbf2fd4b2ba4e038f0b44f5735f198e92571c029156f65f534bfc149f38d611829901372cfc0176b9d2f9ac6512b7f37941a02dff701df0bceadaacfc6935</pre>

* Send to Signer 3:
** HMAC_KEY (hex):
1f51ea067c121e2f86af5e1d484905046bc63e861573157d8b1ae9e7e47e224b
** MAC (hex): 159a91100cacd123480b7d085c8bb32ec8eb06f0391b6dc8fac07ae67eb37b81
** IV (hex) : 159a91100cacd123480b7d085c8bb32e
** CIPHERTEXT (hex):
c7269d8be21d1cfe172e35aa106760f1fdc929fce19da8fb7f74f759efec1ee02796fb1e8b008cf177f60a2021570f17aeeb41f8636858654082734b90959b98fd08419f901683c4ca3e76b3e482fea4c67162775e0d80bcb45df729f646c1364a3d8a7d1ff961717b00897e877c1c0554d3502942149726806269c546ad2dd34ba286ddf5cd336b83aabf7091fa25e607faf7e54017d84113e1e3ec440b3704addea188b89293469306fc0a98570afdcf269026b2d2e760f466c1f75bcf75fdf030c0a692e5681fd4487e59d6e96451ff5b6b9f2521b8e95e796ef4ab0a917794d91a30fdac7ee9ddbd89d174831bd133ab12a74f52f6283ee2c5fe3d5a957a7c1a15530b2c5224f76d90057dc94f2ee34e28b037ae7f518cc6dfe725cd3e657648de82b200ea77830eb93219f883998d3207a4ef5902d1119b0cde6b364bc1effb86109d9c2babc8ab26dce90329779d8cd0d737e9825a25586aa3c8fa5317e3e433ff235b82f629de0504e3c992f8e8de299f62751bc1fcb2e75e0262c7a27be7068cea69b14f303e97c24b99ed29cae142564e285657704b4c411d0d4f8c58819e2c0e0ffc3667eb5a408aad8a3023a5f00875e7deab95dc365d8757f7b79815a4fd9e6de2b3
** <tt>my_multisig_wallet_for_signer_3.dat</tt>:
<pre>159a91100cacd123480b7d085c8bb32ec8eb06f0391b6dc8fac07ae67eb37b81c7269d8be21d1cfe172e35aa106760f1fdc929fce19da8fb7f74f759efec1ee02796fb1e8b008cf177f60a2021570f17aeeb41f8636858654082734b90959b98fd08419f901683c4ca3e76b3e482fea4c67162775e0d80bcb45df729f646c1364a3d8a7d1ff961717b00897e877c1c0554d3502942149726806269c546ad2dd34ba286ddf5cd336b83aabf7091fa25e607faf7e54017d84113e1e3ec440b3704addea188b89293469306fc0a98570afdcf269026b2d2e760f466c1f75bcf75fdf030c0a692e5681fd4487e59d6e96451ff5b6b9f2521b8e95e796ef4ab0a917794d91a30fdac7ee9ddbd89d174831bd133ab12a74f52f6283ee2c5fe3d5a957a7c1a15530b2c5224f76d90057dc94f2ee34e28b037ae7f518cc6dfe725cd3e657648de82b200ea77830eb93219f883998d3207a4ef5902d1119b0cde6b364bc1effb86109d9c2babc8ab26dce90329779d8cd0d737e9825a25586aa3c8fa5317e3e433ff235b82f629de0504e3c992f8e8de299f62751bc1fcb2e75e0262c7a27be7068cea69b14f303e97c24b99ed29cae142564e285657704b4c411d0d4f8c58819e2c0e0ffc3667eb5a408aad8a3023a5f00875e7deab95dc365d8757f7b79815a4fd9e6de2b3</pre>

==Acknowledgement==

Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen,
Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael
Flaxman, Pieter Wuille and others for their feedback on the
specification.

==References==

Original mailing list thread:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html

[-- Attachment #2: Type: text/html, Size: 41762 bytes --]

 permalink raw reply	[|nested]
2021-04-05  7:02 ` Hugo Nguyen

  2021-04-09 14:09     ` Hugo Nguyen
  2021-04-09 14:54     ` Hugo Nguyen
  2021-04-11  2:34   ` Michael.flaxman
  
From: Sjors Provoost @ 2021-04-09 12:07 UTC (permalink / raw)
  To: Bitcoin Dev;  marko, aarondongchen, peter

[-- Attachment #1: Type: text/plain, Size: 3671 bytes --]

Hi all,

First of all thanks for your continued work on standardising multisig setup.

The use case I personally find most interesting is not a multi-party setup, but rather just combining a bunch of my own devices. Those might even be in the same room during the setup, only to be moved to my moon base later.

This means I've paid less attention to the encryption scheme, so I might set TOKEN=0, but nevertheless I am skeptical about it. The first step is for the Coordinator to generate a TOKEN, presumably using its own entropy. But IIUC anyone who intercepts that token can decrypt any future step in the setup process. This suggests a chicken-egg problem where you need some pre-existing secure communications channel.

To the list of concerns at the top of the BIP, I would add one: losing multisig setup context. E.g. in the event of a fire where you only recover your steel engraved mnemonic(s), but no longer have the wallet descriptors.

If you still have all devices and know (or guess) the threshold then BIP48 and sorted_multi descriptors will save you. But if you have a 2-of-3 setup and lost 1 device then without the metadata your coins are lost. In a future with musig(?) and miniscript increasingly the setup data is just as critical as the seeds.

A future standard (or extension of this one) should recommend an encryption convention for the descriptor data, ideally such that with *any* of the seeds you can decrypt a file that contains the full setup. That file could then just float redundantly around the internet and pieces of paper in various locations, without compromising privacy.

The proposed encryption system doesn't help with that though, because it's based on entropy from the Coordinator, rather than from the signers.


Smaller suggestions:
* link to this new mail thread in the BIP
* use magic bytes so .bsms so operating systems like Android / iOs can open the right app for them
* don't use separate file extensions for encrypted vs unencrypted content, just indicate somehow that a given field is encrypted
* although plain text files are handy for debugging, I think a binary format like PSBT is much powerful. Any device that can parse and write binary PSBT should be able to implement a similar parser / writer for a binary .bsms format.
* BIP48 and sorted_multi descriptors are useful in a loss-of-metadata scenario. The BIP uses both in the examples, but doesn't explictly endorse these derivations. It also contradicts them: "If the Signer chooses the path, it should try to avoid reusing XPUBs for different wallets.". Maybe this is out of scope.
   * one way to resolve xpub reuse would be to make the "BIP48" path a function of the co-signer fingerprints and wallet threshold, but this requires an extra communication round
* there should be a way for signers to communicate their capabilities, perhaps with a different xpub for each potential scheme. E.g. there's m/48' native SegWit now, MuSig and/or or Tapleaf based multisig in the future, or even generic Miniscript support.
* the idea of only storing the receive descriptor, not the change descriptor, is fine by me, though I'd prefer an extension to the descriptor format to deal with this

Sjors

> Op 5 apr. 2021, om 09:02 heeft Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> het volgende geschreven:
> 
> Hi all,
> 
> Please find below the complete draft of the Bitcoin Secure Multisig Setup (BSMS) BIP. The spec has gone through a number of important updates in the last month or so. Thanks everyone who has participated in the review process.
> 
> As a PR: https://github.com/bitcoin/bips/pull/1097


[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2021-04-09 12:07   ` Sjors Provoost

  2021-04-09 14:54     ` Hugo Nguyen
  
From: Hugo Nguyen @ 2021-04-09 14:09 UTC (permalink / raw)
  To: Sjors Provoost;  marko, Bitcoin Dev, aarondongchen, Peter Gray

[-- Attachment #1: Type: text/plain, Size: 3220 bytes --]

Hi Sjors
Thanks for the feedback!

The first step is for the Coordinator to generate a TOKEN, presumably using
> its own entropy. But IIUC anyone who intercepts that token can decrypt any
> future step in the setup process. This suggests a chicken-egg problem where
> you need some pre-existing secure communications channel.
>

The exchange of the TOKEN is frequently mistaken as the chicken-and-egg
problem, but it is not so.

To understand why this isn't chicken-and-egg, and why the TOKEN actually
adds value, consider *the scale of the communication operation needed to
exchange the TOKEN*, and *the scale of the communication operation needed
to gather data for the creation of the multisig wallet *(with or without
the TOKEN):

1) The TOKEN itself is a single piece of data that is 64- or 96-bit. It is
small enough to be easily exchanged (even memorized) and entered into
various devices. It requires only a single round of communication, but can
protect as many rounds of communication as needed.

2) The data needed to create the multisig wallet, on the other hand, are
quite involving:
(a) Each Signer needs to share its XPUB, which cannot be memorized
(b) The XPUBs also come with their own metadata
(c) The creation of the wallet requires at least two rounds of
communications since the Signers need to voluntarily share their XPUBs
first, only then can a Coordinator combine the XPUBs into a single multisig
script and pass back the configuration to the Signers. (Note that without a
Coordinator, you'll need O(N^2) rounds of communication).
(d) Because Signers are typically off-line cold storage, the paths between
the Signers / the Signers <> Coordinator likely involve multiple hops
through various media, such as unsecure USB connection. This is the way
most multisig solutions are currently being implemented. It means the XPUBs
and the multisig configuration are vulnerable to leaking and/or
modifications.

Note that (d) is especially problematic for remote multisig setups. The
more remote, the more potential hops along the way, the more problematic.

So you can see that *the TOKEN ultimately reduces the problem of sharing a
large amount of sensitive data back and forth, to the sharing of a single,
small piece of data upfront.* An added advantage of this approach is that
if the parties fail to establish a shared TOKEN, the scheme fails with no
harm done.

The Coordinator, on the other hand, adds value by solving the O(n^2)
communication problem. Some minimal amount of trust is needed for the
Coordinator, but this can be greatly mitigated by a number of ways that we
have defined in the spec, such as:
* Signers must check that their XPUBs are included in the final descriptor
* Signers must display to the user the multisig configuration: M/N,
relative position(s) of XPUBs, etc.
* Signers must display the full descriptor upon user request for manual
inspection - this one is important because it means that the new scheme
cannot be worse than the status quo.
* Signers are recommended to display a preview of the first receive
address(es).

All in all, the Coordinator's role helps ease the setup process, while its
ability to pull off any shenanigans is greatly limited.

Best,
Hugo

[-- Attachment #2: Type: text/html, Size: 3614 bytes --]

 permalink raw reply	[|nested]
2021-04-09 12:07   ` Sjors Provoost
  2021-04-09 14:09     ` Hugo Nguyen

  2021-04-09 15:33       ` Sjors Provoost
  
From: Hugo Nguyen @ 2021-04-09 14:54 UTC (permalink / raw)
  To: Sjors Provoost;  marko, Bitcoin Dev, aarondongchen, Peter Gray

[-- Attachment #1: Type: text/plain, Size: 5063 bytes --]

(Continue off last email: also keep in mind, that just like BIP174,
Coordinator and Signer are abstract roles. This means in theory a Signer
can be the Coordinator too. The same criteria for trust applies equally to
a Signer and a Coordinator.)

The use case I personally find most interesting is not a multi-party setup,
> but rather just combining a bunch of my own devices. Those might even be in
> the same room during the setup, only to be moved to my moon base later.
>

And that's fair. Both use cases (local and remote multisig) are valid and
currently being used. But IMO a standard should accommodate both.


> To the list of concerns at the top of the BIP, I would add one: losing
> multisig setup context. E.g. in the event of a fire where you only recover
> your steel engraved mnemonic(s), but no longer have the wallet descriptors.
>

Good point.


>
> If you still have all devices and know (or guess) the threshold then BIP48
> and sorted_multi descriptors will save you. But if you have a 2-of-3 setup
> and lost 1 device then without the metadata your coins are lost. In a
> future with musig(?) and miniscript increasingly the setup data is just as
> critical as the seeds.
>

How so? Each signer device should ideally have a copy of the multisig
configuration. If you lose 1 device in a 2-of-3, you can still spend from
the wallet? Unless I'm missing something here.


> A future standard (or extension of this one) should recommend an
> encryption convention for the descriptor data, ideally such that with *any*
> of the seeds you can decrypt a file that contains the full setup. That file
> could then just float redundantly around the internet and pieces of paper
> in various locations, without compromising privacy.
>

Post-wallet-creation, each Signer can apply extra encryption on top of BSMS
for the persistence of the configuration file any way it wants :) It
doesn't contradict with the current spec.


> The proposed encryption system doesn't help with that though, because it's
> based on entropy from the Coordinator, rather than from the signers.
>

They are for different purposes. The TOKEN-based encryption is only needed
temporarily for the setup.


> Smaller suggestions:
> * link to this new mail thread in the BIP
>

Will do.


> * use magic bytes so .bsms so operating systems like Android / iOs can
> open the right app for them
> * don't use separate file extensions for encrypted vs unencrypted content,
> just indicate somehow that a given field is encrypted
> * although plain text files are handy for debugging, I think a binary
> format like PSBT is much powerful. Any device that can parse and write
> binary PSBT should be able to implement a similar parser / writer for a
> binary .bsms format.
>

Will consider these points, but I prefer plaintext for wallet
configuration. Human readability for the wallet configuration is a pro not
a con IMO. Also helps when backing up.


> * BIP48 and sorted_multi descriptors are useful in a loss-of-metadata
> scenario. The BIP uses both in the examples, but doesn't explictly endorse
> these derivations. It also contradicts them: "If the Signer chooses the
> path, it should try to avoid reusing XPUBs for different wallets.". Maybe
> this is out of scope.
>    * one way to resolve xpub reuse would be to make the "BIP48" path a
> function of the co-signer fingerprints and wallet threshold, but this
> requires an extra communication round
>

We discussed this in the linked PR (
https://github.com/nunchuk-io/bips/pull/1), and decided that enforcing
against path reuse is out-of-scope. We give examples of sorted_multi and
multi because different vendors support different things.


> * there should be a way for signers to communicate their capabilities,
> perhaps with a different xpub for each potential scheme. E.g. there's m/48'
> native SegWit now, MuSig and/or or Tapleaf based multisig in the future, or
> even generic Miniscript support.
>

I considered Signers signaling capabilities (for a different reason), but
opted against it because it further complicates the scheme. Also BIP48-like
proposals are made redundant with the use of output descriptors.


> * the idea of only storing the receive descriptor, not the change
> descriptor, is fine by me, though I'd prefer an extension to the descriptor
> format to deal with this
>

That's not quite accurate. The spec stores the top-level descriptor
(XPUB/*) along with the path restrictions (/0/*,/1/*), not the receive
descriptor.

 The path restrictions would allow you to extend on the spec. There's also
a VERSION field.

Best,
Hugo


>
> Sjors
>
> > Op 5 apr. 2021, om 09:02 heeft Hugo Nguyen via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org> het volgende geschreven:
> >
> > Hi all,
> >
> > Please find below the complete draft of the Bitcoin Secure Multisig
> Setup (BSMS) BIP. The spec has gone through a number of important updates
> in the last month or so. Thanks everyone who has participated in the review
> process.
> >
> > As a PR: https://github.com/bitcoin/bips/pull/1097
>
>

[-- Attachment #2: Type: text/html, Size: 7136 bytes --]

 permalink raw reply	[|nested]
2021-04-09 14:54     ` Hugo Nguyen

  2021-04-10 19:32         ` Robert Spigler
  
From: Sjors Provoost @ 2021-04-09 15:33 UTC (permalink / raw)
  To: Bitcoin Dev;  marko, aarondongchen, Peter Gray


[-- Attachment #1.1: Type: text/plain, Size: 1206 bytes --]

Thanks for the detailed response. Just 1 thing I needed to clarify:

> To the list of concerns at the top of the BIP, I would add one: losing multisig setup context. E.g. in the event of a fire where you only recover your steel engraved mnemonic(s), but no longer have the wallet descriptors.
> 
> Good point.
> 
> 
> If you still have all devices and know (or guess) the threshold then BIP48 and sorted_multi descriptors will save you. But if you have a 2-of-3 setup and lost 1 device then without the metadata your coins are lost. In a future with musig(?) and miniscript increasingly the setup data is just as critical as the seeds.
> 
> How so? Each signer device should ideally have a copy of the multisig configuration. If you lose 1 device in a 2-of-3, you can still spend from the wallet? Unless I'm missing something here.

I was thinking about a scenario where all devices are destroyed. All you have left are the mnemonics. But indeed if at least one of your devices is still intact AND it has the configuration, you're also good.

But there are plenty of devices out there that can't do this. Those devices can still be useful, even if they can't fully check everything.

Sjors

[-- Attachment #1.2: Type: text/html, Size: 2024 bytes --]

[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2021-02-08 23:14 [bitcoin-dev] Proposal: Bitcoin Secure Multisig Setup Hugo Nguyen
                   ` (4 preceding siblings ...)
  2021-04-05  7:02 ` Hugo Nguyen

  
From: Erik Aronesty @ 2021-04-10 13:53 UTC (permalink / raw)
  To: Hugo Nguyen, Bitcoin Protocol Discussion

here's what we do for multisig:

- each member generates their own public/private key pair first and
publishes the pair to all other members
- members are then verified using a secondary channel, like a phone
call ... where the H128(pubk) is turned into BIP-words for
manual/visual verification
- multi-round DKG is used with appropriate commitments and
verification of components  (nice article:
https://link.springer.com/content/pdf/10.1007/s00145-006-0347-3.pdf)

without that, there's simply no guarantee that you're not
communicating with an attacker during setup.

On Tue, Feb 9, 2021 at 2:53 AM Hugo Nguyen via bitcoin-dev
<bitcoin-dev@lists•linuxfoundation.org> wrote:
>
> Hi all,
> I would like to propose a new BIP for Secure Multisig Setup.
> This proposal has taken inputs from folks at Coldcard, Shift Crypto and Cobo -- listed below as co-authors.
>
> This was inspired by my own experience working with hardware wallets on the market, as well as existing research into the challenges of multisig.
>
> Cheers,
> Hugo
>
> <pre>
>   BIP: To be determined
>   Layer: Applications
>   Title: Bitcoin Secure Multisig Setup (BSMS)
>   Author: Hugo Nguyen <hugo@nunchuk•io>, Peter Gray <peter@coinkite•com>, Marko Bencun <marko@shiftcrypto•ch>, Aaron Chen <aarondongchen@gmail•com>, Rodolfo Novak <rodolfo@coinkite•com>
>   Comments-Summary: No comments yet.
>   Comments-URI:
>   Status: Proposed
>   Type: Standards Track
>   Created: 2020-11-10
>   License: BSD-2-Clause
> </pre>
>
> ==Introduction==
>
> ===Abstract===
>
> This document proposes a mechanism to set up multisig wallets securely.
>
> ===Copyright===
>
> This BIP is licensed under the 2-clause BSD license.
>
> ===Motivation===
>
> The Bitcoin multisig experience has been greatly streamlined under [https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174 (Partially Signed Bitcoin Transaction)]. However, what is still missing is a standardized process for setting up multisig wallets securely across different vendors.
>
> There are a number of concerns when it comes to setting up a multisig wallet:
>
> # Whether the multisig configuration, such as Signer membership, script type, derivation paths and number of signatures required, is correct and not tampered with.
> # Whether Signer persists the multisig configuration in their respective storage, and under what format.
> # Whether Signer's storage is tamper-proof.
> # Whether Signer subsequently uses the multisig configuration to generate and verify receive and change addresses.
>
> An attacker who can modify the multisig configuration can steal or hold funds to ransom by duping the user into sending funds to the wrong address.
>
> This proposal seeks to address concerns #1 and #2: to mitigate the risk of tampering during the initial setup phase, and to define an interoperable multisig configuration format.
>
> Concerns #3 and #4 should be handled by Signers and is out of scope of this proposal.
>
> ==Specification==
>
> ===Prerequisites===
> This proposal assumes the parties in the multisig support [https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki BIP32], [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md the descriptor language] and encryption.
>
> ==Roles==
> ===Coordinator===
>
> The Coordinator initiates the multisig setup. The Coordinator determines what type of multisig is used and how many members and signatures are needed. If encryption is enabled, the Coordinator generates a secret token, to be shared among the parties for secure communication. The Coordinator gathers information from the Signers to generate a descriptor record. The Coordinator distributes the descriptor record back to the Signers.
>
> ===Signer===
>
> The Signer is a participating member in the multisig. Its responsibilities include providing its XPUB to the Coordinator, verifying that its XPUB is included in the descriptor record and persisting the descriptor record in its storage.
>
> ==Setup Process==
>
> ===Round 1===
>
> ====Coordinator====
>
> * The Coordinator creates a multisig wallet creation session. The Coordinator determines the type of multisig script used and the signing configuration (<tt>M</tt> and <tt>N</tt>).
> * If encryption is enabled, the Coordinator also generates a secret token, hereby denoted <tt>TOKEN</tt>.
> * TOKEN is in ASCII format and must have a minimum of 8 characters. TOKEN should expire after some time period determined by the Coordinator, e.g., 24 hours.
> * TOKEN acts as an encryption key among the parties. The method of encryption is AES, CTR mode. The encryption key can be calculated by performing a double hash operation on the TOKEN: <tt>ENCRYPTION_KEY = SHA256(SHA256(TOKEN))</tt>.
> * A TOKEN value of <tt>-1</tt> means that encryption is disabled and all the encryption/decryption steps below can be skipped.
> * The Coordinator shares the TOKEN with all participating Signers over a secure channel.
>
> ====Signer====
>
> * The Signer generates a key record by prompting the user for the TOKEN and a derivation path.
> * The first line in the record must be the <tt>TOKEN</tt>. If encryption is disabled, set the TOKEN to -1. The second line must be the <tt>KEY</tt>, whereas KEY is an XPUB. KEY must include key origin information and written in the descriptor-defined format, i.e.: <tt>[{master key fingerprint}/{derivation path}]{XPUB}</tt>. The third line must be a <tt>SIG</tt>, whereas SIG is the signature generated by using the corresponding private key to sign the first two lines. Finally, the Signer encrypts the entire record with ENCRYPTION_KEY.
>
> ===Round 2===
>
> ====Coordinator====
>
> * The Coordinator gathers key records from all participating Signers. Abort the setup if TOKEN has expired.
> * For each key record, the Coordinator decrypts it using ENCRYPTION_KEY. The Coordinator verifies that the included SIG is valid given the KEY.
> * If all key records look good, the Coordinator generates a descriptor record, which is simply the descriptor string plus a <tt>CHECKSUM</tt>, all in one line. The CHECKSUM has BECH32 encoding and is described at [https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums]. The Coordinator encrypts this descriptor record with ENCRYPTION_KEY.
> * The Coordinator sends the encrypted descriptor record to all participating Signers.
>
> ====Signer====
>
> * The Signer imports the descriptor record, decrypts it by prompting the user for TOKEN.
> * The Signer calculates and verifies the descriptor’s CHECKSUM. Abort the setup if the CHECKSUM is incorrect.
> * The Signer checks whether one of the KEYs in the descriptor belongs to it, using path and fingerprint information included in the descriptor. The check must perform an exact match on the KEYs, and not using shortcuts such as matching fingerprints (which is trivial to spoof). Abort the setup if it doesn’t detect its own KEY.
> * For confirmation, the Signer must display to the user the descriptor's CHECKSUM, plus other configurations, such as M and N. The total number of Signers, N, is important to prevent a KEY insertion attack. All participating Signers should be able to display the same confirmation.
> * If all checks pass, the Signer persists the descriptor record in its storage. The Signer should subsequently use the descriptor to generate and verify receive and change addresses.
>
> This completes the setup.
>
> ==QR Codes==
> For signers that use QR codes to transmit data, key and descriptor records can be converted to QR codes, following [https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md the BCR standard].
>
> ==Security==
>
> This proposal introduce two layers of protection. The first one is a temporary, secret token, used to encrypt the two rounds of communication between the Signers and the Coordinator. The second one is through the descriptor checksum and visual inspection of the descriptor itself.
>
> The token is only needed during the setup phase, and can be safely thrown away afterwards. The token does not guarantee that the Signer membership set is not modified, since that depends on the overall security of all parties in the setup, but it can make it significantly harder for an attacker to do so.
>
> There are three ways an attacker can modify the membership set: by changing an existing member, by removing an existing member, or by adding a new member.
>
> For the first two methods, one of the Signers will be able to detect that its membership has been changed or removed, and reject the final descriptor. Thus, it is vital that all participating Signers check that their membership is intact in the descriptor. Even one Signer failing to check for its membership means that the setup could be compromised.
>
> For the third type of attack, the descriptor checksum and visual inspection of the descriptor itself are the only way to guard against malicious members from being inserted into the set.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev


 permalink raw reply	[|nested]
2021-04-09 15:33       ` Sjors Provoost

  
From: Robert Spigler @ 2021-04-10 19:32 UTC (permalink / raw)
  To: Sjors Provoost, Bitcoin Protocol Discussion
  Cc: marko, aarondongchen, Peter Gray

[-- Attachment #1: Type: text/plain, Size: 3021 bytes --]

Hi Sjors,

Thanks for your comments.

>Chicken-egg problem

I agree with Hugo's detailed response here.

>Losing multisig setup context (in the event of a fire where you only recover your steel engraved mnemonic(s), but no longer have the wallet descriptors.)

Devices need to persist the descriptor, if they currently can't, they don't comply with this standard and they can't be used securely for multisig. There's no reasons the master seed and descriptor both can't be backed up outside of each device. I can't see a scenario where it would be possible to recover only the seed. (I don't know yet how Core will decide how to best backup this info, seeing as BIP39 was rejected).

>BIP48

I agree with Hugo that BIP48 is redundant with descriptors, please see https://github.com/bitcoin/bips/pull/1089 for a proposed updated hierarchy for multisignature wallets.

>An encryption convention for the descriptor data

I understand this concern. Like you mentioned previously, I too often set up multisignature wallets for clients where they are actually owned by the single party. A concern is that while the backup location owners cannot spend (due to the M-of-N restriction), they can view the wallet balance/history. As Hugo mentioned, you can apply any encryption you want after the setup, so a solution may be to use Shamir Secret Sharing (Blockchain Commons has done a lot of work on that here: https://github.com/BlockchainCommons/Airgapped-Wallet-Community/discussions/37#discussioncomment-287993)

>Plain text vs binary

I too favor plain text

Robert Spigler
Personal Fingerprint: BF0D 3C08 A439 5AC6 11C1 5395 B70B 4A77 F850 548F

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Friday, April 9, 2021 11:33 AM, Sjors Provoost via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:

> Thanks for the detailed response. Just 1 thing I needed to clarify:
>
>>> To the list of concerns at the top of the BIP, I would add one: losing multisig setup context. E.g. in the event of a fire where you only recover your steel engraved mnemonic(s), but no longer have the wallet descriptors.
>>
>> Good point.
>>
>>> If you still have all devices and know (or guess) the threshold then BIP48 and sorted_multi descriptors will save you. But if you have a 2-of-3 setup and lost 1 device then without the metadata your coins are lost. In a future with musig(?) and miniscript increasingly the setup data is just as critical as the seeds.
>>
>> How so? Each signer device should ideally have a copy of the multisig configuration. If you lose 1 device in a 2-of-3, you can still spend from the wallet? Unless I'm missing something here.
>
> I was thinking about a scenario where all devices are destroyed. All you have left are the mnemonics. But indeed if at least one of your devices is still intact AND it has the configuration, you're also good.
>
> But there are plenty of devices out there that can't do this. Those devices can still be useful, even if they can't fully check everything.
>
> Sjors

[-- Attachment #2: Type: text/html, Size: 4461 bytes --]

 permalink raw reply	[|nested]
2021-04-05  7:02 ` Hugo Nguyen
  2021-04-09 12:07   ` Sjors Provoost

  2021-04-11 16:45     ` Hugo Nguyen
  
From: Michael.flaxman @ 2021-04-11  2:34 UTC (permalink / raw)
  To: Hugo Nguyen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 45128 bytes --]

Hi Hugo,

I appreciate the effort you and everyone else is making to improve multisig in bitcoin!

I like that this BIP gets rid of SLIP132 version bytes, as those have been de-facto deprecated in favor of output descriptors for some time. Having a standard for how to communicate descriptor records (BSMS 1.0) also seems like a nice positive.

The most commonly raised issues from [the 10x security guide](https://btcguide.github.io/) are about how to properly verify that all hardware wallets are participants in the user's multisig quorum (and with the correct m-of-n). This shows up in two big ways:

- The O(n^2) xpub validation problem creates a bad UX and is hard for non-advanced users.
- The risk for stateless hardware wallets (like Trezor) to have their xpubs swapped out by a compromised Coordinator.

Unfortunately, this BIP does not improve either of these issues, while adding considerable complexity.

1. O(n^2) Xpub Validation

The proposed use of an output descriptor checksum has an obvious 40-bit MITM collision attack. A compromised Coordinator could trick a Signer into displaying an attacker's receive address, despite a correctly functioning Signers and the user properly validating the checksum ([github link](https://github.com/nunchuk-io/bips/pull/1/#issuecomment-801629857)).

Using a checksum with much higher entropy would reduce xpub validation to O(n) and create a very nice UX for signers. This would be a huge win for multisig! Instead, the recommended solution from the BIP is to validate all the key records manually, which is how multisig is currently done and what we desperately want to move away from. With a proper checksum, there’s no reason for a user to ever see an xpub.

Users should not be shown a checksum and asked to validate it in meatspace (across Signers) if an attacker’s address could still be substituted! Validating a single address across devices does solve this problem, but if you’re going to validate an address there’s no reason to display the checksum at all. However, validating an address is confusing to non-experts:

- Is it a wallet ID or a bitcoin address?

- Am I supposed to send funds to this address?

If creating a new checksum standard for the descriptor record is undesirable, we could use a child address (from an unhardened BIP32 path) and encode that in some way for end-users to verify it matches across all Signers. It would be strongly preferable for the encoding to be an unambiguously different format from a bitcoin address / BIP39 seed phrase, so that it’s clear it’s just a wallet ID. One non-ideal but simple solution is to use a hash function (i.e. dsha256) to calculate the digest of the child address, and display this in hexadecimal format. While hexadecimal is non-ideal for manual verification, it is already trivial for any bitcoin library to perform these steps.

2. Allow Support for Stateless Wallets

The current BIP states:

"If all checks pass, the Signer must persist the descriptor record in its storage."

While persistence has a lot of benefits, it is not a feature of the most sold multisig hardware wallet: Trezor. A simple solution here is to have each Signer sign the entire descriptor record at the end of round 2, not just its own key record in round 1. Then the data can be stored anywhere (including on the Signer itself) and played back to each Signer for validation when needed. The end-user would have no idea this was happening, but the device could refuse to display information it hasn’t fully validated (or at least add a warning message). Even a device with persistent storage would be better served using a signature, so that an evil maid couldn't tamper with the device (say in the no-encryption case for simplicity).

This existing vulnerability in stateless wallets is particularly bad for hosted multisig services like Casa/Unchained, where the service might control m-1 keys. It’s far easier for a hosted service to potentially trick non-expert users into displaying an attacker's receive address on their stateless Signer.

For example, assume the user is doing 2-of-3 multisig, where the Coordinator (service) controls 1 key. Here is how the Coordinator could trick their end-users:

- Coordinator swaps out 1 of the end-user’s xpubs, going from a 2-of-3 where the end-user has 2 seeds to a 2-of-3 where the Coordinator has 2 seeds.

- The end-user logs into the service to get a new receive address, and the service (Coordinator) displays malicious receive address X (as part of a 2-of-3).

- The end user connects stateless Signer 1 to the service (Coordinator), which under-the-hood gives stateless Signer 1 proof that it is included in this 2-of-3. Stateless singer 1 displays malicious receive address X!

- The end-user doesn't verify the address on Signer 2, as many users unfortunately don't -- perhaps it is in a far away location and the end-user (incorrectly) thinks that it’s already been validated in 2 places -- and makes a large deposit to receive address X. These funds now belong to the attacker and can be swept at any time!

If stateless Signer 1 required a signature to be replayed at step 3, stateless Signer 1 would refuse to display malicious receive address X (or at a minimum warn the end-user that it did not have enough info to properly validate the address).

This is also a concern for self-hosted multisig, I just used the hosted services as the best example.

It's also not just Trezor that is stateless. For example, I wrote [a simple CLI software multisig wallet as part of the buidl library](https://twitter.com/mflaxman/status/1321503036724989952) to be used mostly for emergency recovery. At 800 lines of code, it's too simple/minimal to touch the file system.

BIP39

While unrelated, the use of BIP39 words for session tokens seems like a big mistake, as end-users have learned over years that BIP39 words are for private key material. A small percent of users may backup their token BIP39 mnemonic and not their seed phrase BIP39 mnemonic! My suggestion is to just stick with the other two Token options: decimal and hex.

Conclusion

The main purpose/benefit of the BIP seems to be the encryption protocol. I wouldn't have strong objections if the BIP were simply renamed Bitcoin Multisig Encryption, as that more accurately reflects what it does. That said, I think this BIP is missing out on a real opportunity to improve security in setting up a multisig scheme, and if adopted in the current form will negatively impact multisig adoption.

I can't support this BIP in the current form, but I'd be happy to submit a PR if it's helpful.

Best,

Michael

https://btcguide.github.io/

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Monday, April 5, 2021 2:02 AM, Hugo Nguyen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:

> Hi all,
>
> Please find below the complete draft of the Bitcoin Secure Multisig Setup (BSMS) BIP. The spec has gone through a number of important updates in the last month or so. Thanks everyone who has participated in the review process.
>
> As a PR: https://github.com/bitcoin/bips/pull/1097
>
> A few notes:
> * PBKDF2-SHA512 was chosen instead of PBKDF2-SHA256 for the key derivation function, due to widespread existing hardware support for PBKDF2-SHA512
> * Only one descriptor is stored in the multisig configuration - this simplifies wallet setup and recovery
> (For the full review and relevant discussions, please check out https://github.com/nunchuk-io/bips/pull/1).
>
> Best,
> Hugo
>
> <pre>
>   BIP: To be determined
>   Layer: Applications
>   Title: Bitcoin Secure Multisig Setup (BSMS)
>   Author: Hugo Nguyen <hugo at
> nunchuk.io
>>, Peter Gray <peter at
> coinkite.com
>>, Marko Bencun <marko at
> shiftcrypto.ch
>>, Aaron Chen <aarondongchen at
> gmail.com
>>, Rodolfo Novak <rodolfo at
> coinkite.com
>>
>   Comments-Summary: No comments yet.
>   Comments-URI:
>   Status: Proposed
>   Type: Standards Track
>   Created: 2020-11-10
>   License: BSD-2-Clause
> </pre>
>
> ==Introduction==
>
> ===Abstract===
>
> This document proposes a mechanism to set up multisig wallets securely.
>
> ===Copyright===
>
> This BIP is licensed under the 2-clause BSD license.
>
> ===Motivation===
>
> The Bitcoin multisig experience has been greatly streamlined under [
> https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
> BIP-0174
> (Partially Signed Bitcoin Transaction)]. However, what is still missing is a standardized process for setting up multisig wallets securely across different vendors.
>
> There are a number of concerns when it comes to setting up a multisig wallet:
>
> # Whether the multisig configuration, such as Signer membership, script type, derivation paths and number of signatures required, is correct and not tampered with.
> # Whether the keys or the multisig configuration are leaked during the setup.
> # Whether the Signer persists the multisig configuration in their respective storage, and under what format.
> # Whether the Signer's storage is tamper-proof.
> # Whether the Signer subsequently uses the multisig configuration to generate and verify receive and change addresses.
>
> An attacker who can modify the multisig configuration can steal or hold funds for ransom by duping the user into sending funds to the wrong address. An attacker who cannot modify the configuration but can learn about the keys and/or the configuration can monitor transactions in the wallet, resulting in loss of privacy.
>
> This proposal seeks to address concerns #1, #2 and #3: to mitigate the risk of tampering during the initial setup phase, and to define an interoperable multisig configuration format.
>
> Concerns #4 and #5 should be handled by Signers and are out of scope of this proposal.
>
> ==Specification==
>
> ===Prerequisites===
> This proposal assumes the parties in the multisig support [
> https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
> BIP-0032], [
> https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
> BIP-0322], [
> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md
> the descriptor language] and [
> https://tools.ietf.org/html/rfc3686
> AES encryption].
>
> ===File Extension===
> All descriptor and key records should have a <tt>.bsms</tt> file extension. Encrypted data should have a <tt>.dat</tt> extension.
>
> ===Roles===
> ====Coordinator====
>
> The Coordinator initiates the multisig setup. The Coordinator determines what type of multisig is used and the exact policy script. If encryption is enabled, the Coordinator also distributes a shared secret or shared secrets to the parties involved for secure communication. The Coordinator gathers information from the Signers to generate a descriptor record. The Coordinator distributes the descriptor record back to the Signers.
>
> ====Signer====
>
> The Signer is a participating member in the multisig. Its responsibilities include providing its key record -- which contains an Extended Public Key (XPUB) -- to the Coordinator, verifying that its XPUB is included in the descriptor record and persisting the descriptor record in its storage.
>
> ===Setup Process===
>
> ====Round 1====
>
> =====Coordinator=====
>
> * The Coordinator creates a new multisig wallet creation session. The Coordinator constructs the multisig script and its policy parameters, such as the required number of signatures and the total number of Signers (<tt>M</tt> and <tt>N</tt>).
> * The session should expire after some time period determined by the Coordinator, e.g., 24 hours. The timeout allows the encryption key to have lower entropy.
> * If encryption is enabled, the Coordinator distributes a secret <tt>TOKEN</tt> to each Signer over a secure channel. The Signer can use the <tt>TOKEN</tt> to derive an <tt>ENCRYPTION_KEY</tt>. Refer to the Encryption section below for details on the <tt>TOKEN</tt>, the key derivation function and the encryption scheme. Depending on the use case, the Coordinator can decide whether to share one common <tt>TOKEN</tt> for all Signers, or to have one per Signer.
> * If encryption is disabled, the <tt>TOKEN</tt> is set to <tt>0</tt>, and all the encryption/decryption steps below can be skipped.
>
> =====Signer=====
>
> * The Signer initiates the multisig wallet creation session by setting the <tt>TOKEN</tt>. The Signer derives an <tt>ENCRYPTION_KEY</tt> from the <tt>TOKEN</tt>. The Signer can keep the session open until a different value for the <tt>TOKEN</tt> is set.
> * The Signer generates a key record by prompting the user for a multisig derivation path and retrieves the XPUB at that derivation path. Alternatively, the Signer can choose a path on behalf of the user. If the Signer chooses the path, it should try to avoid reusing XPUBs for different wallets.
> * The first line in the record must be the specification version (<tt>BSMS 1.0</tt> as of this writing). The second line must be the hex-encoded <tt>TOKEN</tt>. The third line must be the <tt>KEY</tt>. The <tt>KEY</tt> is an XPUB plus its key origin information, written in the descriptor-defined format, i.e.: <tt>[{master key fingerprint}/{derivation path}]{XPUB}</tt>. The fourth line is a text description of the key, 80 characters maximum. The fifth line must be a <tt>SIG</tt>, whereas <tt>SIG</tt> is the signature generated by using the private key associated with the XPUB to sign the first four lines. The signature should follow [
> https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki
> BIP-0322], legacy format accepted.
> * The Signer calculates the Message Authentication Code (<tt>MAC</tt>) for the record. The first 16 bytes of the <tt>MAC</tt> serves as the Initialization Vector (<tt>IV</tt>) for the encryption.
> * The Signer encrypts the key record with the <tt>ENCRYPTION_KEY</tt> and <tt>IV</tt>.
> * The Signer encodes the <tt>MAC</tt> and the ciphertext into hexadecimal format, then concatenates the results: <tt>(MAC || ciphertext)</tt>.
>
> ====Round 2====
>
> =====Coordinator=====
>
> * The Coordinator gathers key records from all participating Signers. The Coordinator verifies that there are exactly <tt>N</tt> unique key records before the wallet setup session expires.
> * For each key record, the Coordinator extracts the <tt>MAC</tt> from the data, sets <tt>IV</tt> to the first 16 bytes of the <tt>MAC</tt>, then decrypts the ciphertext using the <tt>ENCRYPTION_KEY</tt> and <tt>IV</tt>.
> * The Coordinator verifies that the included <tt>MAC</tt> is valid given the plaintext.
> * The Coordinator verifies that the key records have compatible specification versions.
> * The Coordinator verifies that the included <tt>SIG</tt> is valid given the <tt>KEY</tt>.
> * If all key records look good, the Coordinator fills in all necessary information to generate a descriptor record.
> * The first line in the descriptor record must be the specification version (<tt>BSMS 1.0</tt> as of this writing). The second line must be a comma-separated list of accepted derivation paths that the Signers can use to generate addresses from the included XPUBs. The paths must start with <tt>/</tt> and use non-hardened derivation. For example, <tt>/0/*</tt> and <tt>/1/*</tt> are some common paths. If there are no restrictions, it must say <tt>No path restrictions</tt>. The third line must be the descriptor string plus a <tt>CHECKSUM</tt>, all in one line. The <tt>CHECKSUM</tt> has [
> https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#checksums
> BECH32 encoding].
> * The Coordinator calculates the <tt>MAC</tt> for the record. The first 16 bytes of the <tt>MAC</tt> serves as the <tt>IV</tt> for the encryption..
> * The Coordinator encrypts the descriptor record with the <tt>ENCRYPTION_KEY</tt> and <tt>IV</tt>.
> * The Coordinator encodes the <tt>MAC</tt> and the ciphertext into hexadecimal format, then concatenates the results: <tt>(MAC || ciphertext)</tt>.
> * The Coordinator sends the encrypted descriptor record to all participating Signers.
>
> =====Signer=====
>
> * The Signer imports the descriptor record.
> * The Signer extracts the <tt>MAC</tt> from the data, sets <tt>IV</tt> to the first 16 bytes of the <tt>MAC</tt>, then decrypts the ciphertext using the <tt>ENCRYPTION_KEY</tt> (derived from the open session) and <tt>IV</tt>.
> * The Signer verifies that the included <tt>MAC</tt> is valid given the plaintext.
> * The Signer verifies that it can support the included specification version.
> * The Signer verifies that it is compatible with the derivation path restrictions.
> * The Signer verifies the descriptor’s <tt>CHECKSUM</tt>.
> * The Signer verifies that it can support the descriptor.
> * The Signer checks that its <tt>KEY</tt> is included in the descriptor, using path and fingerprint information provided. The check must perform an exact match on the <tt>KEY</tt>s and not using shortcuts such as matching fingerprints, which is trivial to spoof.
> * For confirmation, the Signer must display to the user the <tt>CHECKSUM</tt>, the derivation path restrictions and the policy parameters, such as <tt>M</tt>, <tt>N</tt> and the position(s) of its own XPUB in the policy script. The total number of Signers, <tt>N</tt>, is important to prevent a <tt>KEY</tt> insertion attack. The position is important for scripts where key order matters. When applicable, all positions of the XPUB must be displayed. The full descriptor must also be available for review upon user request.
> * When possible, the Signer should also show a preview of the first address(es) of the wallet.
> * Parties must check with each other that all Signers have verified the descriptor and has the same confirmation (except for the key positions).
> * If all checks pass, the Signer must persist the descriptor record in its storage.
>
> This completes the setup.
>
> ===Encryption===
>
> ====The Token====
> We define three modes of encryption.
>
> # <tt>NO_ENCRYPTION</tt> : the <tt>TOKEN</tt> is set to <tt>0</tt>. Encryption is disabled.
> # <tt>STANDARD</tt> : the <tt>TOKEN</tt> is a 64-bit nonce.
> # <tt>EXTENDED</tt> : the <tt>TOKEN</tt> is a 96-bit nonce.
>
> The <tt>TOKEN</tt> can be converted to one of these formats:
> * A decimal number (recommended). The number must not exceed the maximum value of the nonce.
> * A mnemonic phrase using [
> https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
> BIP-0039] word list (6 words in <tt>STANDARD</tt> mode; 9 words in <tt>EXTENDED</tt> mode).
> * A QR code.
> * Other formats.
>
> The flexibility in the data format allows each Signer to customize the User Experience based on its respective capabilities.
>
> ====Key Derivation====
> The key derivation function is [
> https://tools.ietf.org/html/rfc2898
> PBKDF2], with PRF = SHA512. Specifically:
>
> <tt>DKey = PBKDF2(PRF, Password, Salt, c, dkLen)</tt>
>
> Whereas:
>
> * PRF = SHA512
> * Password = "No SPOF"
> * Salt = <tt>TOKEN</tt>
> * c = 2048
> * dkLen = 256
> * DKey = Derived <tt>ENCRYPTION_KEY</tt>
>
> ====Encryption Scheme====
> The encryption scheme is [
> https://tools.ietf.org/html/rfc3686
> AES-256-CTR].
>
> <tt>MAC = HMAC-SHA256(HMAC_Key, hex-encoded TOKEN || Data)</tt>
>
> <tt>IV = First 16 bytes of MAC</tt>
>
> <tt>Ciphertext = AES-256-CTR-Encrypt(Plaintext, DKey, IV)</tt>
>
> <tt>Plaintext = AES-256-CTR-Decrypt(Ciphertext, DKey, IV)</tt>
>
> Whereas:
> * DKey = <tt>ENCRYPTION_KEY</tt>
> * HMAC_Key = SHA256(<tt>ENCRYPTION_KEY</tt>)
> * Data = the plaintext, e.g. the entire key record in round 1 and the entire descriptor record in round 2
>
> The <tt>MAC</tt> is to be sent along with the key and descriptor record, as specified above. Because it is a <tt>MAC</tt> over the entire plaintext, this is essentially an [
> https://en.wikipedia.org/wiki/Authenticated_encryption#Encrypt-and-MAC_(E&M)
> Encrypt-and-MAC] form of authenticated encryption.
>
> ==QR Codes==
> For signers that use QR codes to transmit data, key and descriptor records can be converted to QR codes, following [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-005-ur.md
> the BCR standard].
>
> Also refer to [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-015-account.md
> UR Type Definition for BIP44 Accounts] and [
> https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-010-output-desc.md
> UR Type Definition for Bitcoin Output Descriptors] for more details.
>
> ==Security==
>
> This proposal introduces two layers of protection. The first one is a temporary, secret <tt>TOKEN</tt>. The second one is the descriptor <tt>CHECKSUM</tt>.
>
> The <tt>TOKEN</tt> is used to encrypt the two rounds of communication between the Signer and the Coordinator. A <tt>MAC</tt> is also generated from the <tt>TOKEN</tt> and plaintext to authenticate the data being exchanged. The <tt>TOKEN</tt> is only needed during the setup phase, and can be safely discarded afterwards.
>
> The descriptor <tt>CHECKSUM</tt>, on the other hand, can be used to verify the integrity of the multisig configuration. An attacker who tampers with the multisig configuration must also change the descriptor <tt>CHECKSUM</tt>. Parties must check with each other that all Signers have the same <tt>CHECKSUM</tt>, along with the policy parameters, to reduce the chance of tampering. The <tt>CHECKSUM</tt> must be persisted along with the descriptor in each Signer’s storage.
>
> The <tt>TOKEN</tt> and the <tt>CHECKSUM</tt> can’t guarantee complete protection, since that depends on the overall security of all parties in the setup, but they can make it significantly harder for an attacker to tamper with the multisig configuration.
>
> ==Privacy==
> Encryption helps improve the privacy of the wallet by avoiding sharing XPUBs and descriptors in plaintext.
>
> If the parties wish to have stronger privacy, it is recommended to use a higher number of bits for the <tt>TOKEN</tt>, and to completely erase knowledge of the <tt>TOKEN</tt> after the multisig wallet has been set up.
>
> ==Test Vectors==
>
> ===Mode: <tt>NO_ENCRYPTION</tt>===
> ====ROUND 1====
> * Coordinator
> ** M-of-N: 2/2
> ** ADDRESS_TYPE: NATIVE_SEGWIT
> ** TOKEN: 0
>
> * Signer 1
> ** MASTER_KEY_FINGERPRINT: 539f3d89
> ** PRIVATE_KEY (m/48'/0'/0'/2'): KyoXqiwiz6qm21BSYebiZFfNF7obkhiJW6TdPMZTQQMF4kZtfD78
> ** XPUB (m/48'/0'/0'/2'): xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa
> ** Legacy signature
> ** <tt>signer_1_key.bsms</tt>:
> <pre>BSMS 1.0
> 00
> [539f3d89/48'/0'/0'/2']xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa
> Signer 1 key
> IPXsnNSZb8M6H4fAWtpjAc75hyHHd89fskpM5o7qFg+mPDzEPc1k2mjuIpVIIzaCe45FwPfAAa91RaStfC5Sak0=</pre>
>
> * Signer 2
> ** MASTER_KEY_FINGERPRINT: f8b12aa6
> ** PRIVATE_KEY (m/48'/0'/0'/2'): L1zht7muKnUYFMdzC3jwXd78u8tGoKr46AXGh4waF9nphUYWq7ow
> ** XPUB (m/48'/0'/0'/2'): xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM
> ** Legacy signature
> ** <tt>signer_2_key.bsms</tt>:
> <pre>BSMS 1.0
> 00
> [f8b12aa6/48'/0'/0'/2']xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM
> Signer 2 key
> H38+lp9iaesBeCN05BDTH/SnmarlH6+X+Kmw1pgCk+c1Pc1evYIdBag9Nc0nsKhvPtfEbRt9r/qsUVZ5onCtBTc=</pre>
>
> ====ROUND 2====
> * Coordinator
> ** <tt>my_multisig_wallet.bsms</tt>:
> <pre>BSMS 1.0
> /0/*,/1/*
> wsh(sortedmulti(2,[539f3d89/48'/0'/0'/2']xpub6ETerig7tq89mtaD8Gau2xRWxouRMBy6XHqciA8GZzC2dJv3w6FxfgoegH4b2qYF4oG6VBrhpLrauPs5E1q58GLCnhKp6g9QsV9ZA7J5JNa/*,[f8b12aa6/48'/0'/0'/2']xpub6EWPNhGSX86SN4J2DrBUaQ826o6V4egHqAJZUDJqnsthv9CcjBZV79u68M3YZkuTJnJBXfCrHuJy97fkVurntwgt3V7Ms5hXpJV2vS8fQZM/*))#fntxdj7p</pre>
>
> ===Mode: <tt>STANDARD</tt> Encryption===
> ====ROUND 1====
> * Coordinator
> ** M-of-N: 2/2
> ** ADDRESS_TYPE: NATIVE_SEGWIT
> ** TOKEN (hex): 1ed4ba49e96336b8
> *** TOKEN (decimal): 2221605342811469496
> *** TOKEN (mnemonic): burst place mystery spot cricket foster
> ** ENCRYPTION_KEY (hex): 72185a0e25b4efc5d6ac0f8ed32b0165199100e32385040e3a48eb30164bf492
>
> * Signer 1
> ** MASTER_KEY_FINGERPRINT: 98d79e95
> ** PRIVATE_KEY (m/48'/0'/0'/2'): KydC7hZFtWe56oQUAw14HvQ3gKeKVd3m8frFgVMxUqpuhKHvcmm3
> ** XPUB (m/48'/0'/0'/2'): xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt
> ** Legacy signature
> ** <tt>signer_1_key.bsms</tt>:
> <pre>BSMS 1.0
> 1ed4ba49e96336b8
> [98d79e95/48'/0'/0'/2']xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt
> Signer 1 key
> HxtPoP0DrQSac/7ypcwC07R2s6jjpXR6Li2Q92zXj/FSIMQcV5yOU0/ONsDgHXamq0gD5DfPbvuVCp9ZJubclV4=</pre>
>
> * Signer 1 encryption
> ** HMAC_KEY (hex): 4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
> ** MAC (hex): afe99e92f0eadc3308eb990045e90a4f54e9f59d22aae5034ac3d866d29c508d
> ** IV (hex) : afe99e92f0eadc3308eb990045e90a4f
> ** CIPHERTEXT (hex): 214ec9a861a238ba7f0412305a97a6e0faa332be15af09127e131d669e5d55d73891580a5808cea5d2bf39f43496d3c0f8236eff3854fcc7446daf9d2b58fd40d97ce3b1745de2959e29767039b99969821400eca0c3517fae56d2d24d5235a3430af1ed894b68681d706cce7c75adf35d8580603aa302bc01fef06d0336a37f19dd46100baa9e4eabd8796a810e13941ad0980c126ad55d6a4bbef11a7bf893b7d2ed8fb0d8324c4c9b512d4d1e75096c63511e15018fc832816b5639d58fc28c60c049487d04bd5a6cb32aa1381d0809660d54376b9f63325c18cfd1ac5024088e74cb703fe165972cc4485abb1feefe92a0b4ea297fe2f4f7416eeee1efc9b942540931ef
> ** <tt>signer_1_key.dat</tt>: <pre>afe99e92f0eadc3308eb990045e90a4f54e9f59d22aae5034ac3d866d29c508d214ec9a861a238ba7f0412305a97a6e0faa332be15af09127e131d669e5d55d73891580a5808cea5d2bf39f43496d3c0f8236eff3854fcc7446daf9d2b58fd40d97ce3b1745de2959e29767039b99969821400eca0c3517fae56d2d24d5235a3430af1ed894b68681d706cce7c75adf35d8580603aa302bc01fef06d0336a37f19dd46100baa9e4eabd8796a810e13941ad0980c126ad55d6a4bbef11a7bf893b7d2ed8fb0d8324c4c9b512d4d1e75096c63511e15018fc832816b5639d58fc28c60c049487d04bd5a6cb32aa1381d0809660d54376b9f63325c18cfd1ac5024088e74cb703fe165972cc4485abb1feefe92a0b4ea297fe2f4f7416eeee1efc9b942540931ef</pre>
>
> * Signer 2
> ** MASTER_KEY_FINGERPRINT: 3e94b5a1
> ** PRIVATE_KEY (m/48'/0'/0'/2'): KyPh5XYjExjNHPiBjYhp8iAntAehrDziiwRv7y9Ln6eK9QU2xP55
> ** XPUB (m/48'/0'/0'/2'): xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c
> ** Legacy signature
> ** <tt>signer_2_key.bsms</tt>:
> <pre>BSMS 1.0
> 1ed4ba49e96336b8
> [3e94b5a1/48'/0'/0'/2']xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c
> Signer 2 key
> ILR49QLy9+xkMS11TIXJRSMgOQOzGbAaooq4/ZRcd8VgM6j5upJMI0mjJHseQOMYSGk8FqjXZbMvBGyiX9wdutM=</pre>
>
> * Signer 2 encryption
> ** HMAC_KEY (hex): 4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
> ** MAC (hex): 5c7cb2ac407cd60b1f2b86ef46077d3a312b6ce921df2a141347e8bf1e5c6573
> ** IV (hex) : 5c7cb2ac407cd60b1f2b86ef46077d3a
> ** CIPHERTEXT (hex): f23e6c76ff45d308dea6014030a274127ad437228f1d5ec2431d2ea9e3cedd5b0a207a9efa6f926d5420205003f3cb9c4b82b2d595180e62a173a2e5aa0322de48a70a873f641bdae1764e6b1667c241e0fe03a4ccdc3fe0cfa5f75b239d6497c3b69dca17bb685ba70b307d1243836d8fb198ce727cfae4057ee0b4fdcb09f4ba5ae127f49c5de780edb4e40aec96303c8a7b98b1b8e53dd5e07e01d4f3ffd836763209a1f0cbc61adcfdc2951e77528ee7b6e68114c3a4bec38875d285021e68ae8aa913bb1e2e65dd52c649a0e98bfb4e8bab6dd10295c1167a0854ba44f094feb75d2fb00c944f07d4b47114f483df9838459316f3ddbc4a82e6507881931f8e20f5b805
> ** <tt>signer_2_key.dat</tt>: <pre>5c7cb2ac407cd60b1f2b86ef46077d3a312b6ce921df2a141347e8bf1e5c6573f23e6c76ff45d308dea6014030a274127ad437228f1d5ec2431d2ea9e3cedd5b0a207a9efa6f926d5420205003f3cb9c4b82b2d595180e62a173a2e5aa0322de48a70a873f641bdae1764e6b1667c241e0fe03a4ccdc3fe0cfa5f75b239d6497c3b69dca17bb685ba70b307d1243836d8fb198ce727cfae4057ee0b4fdcb09f4ba5ae127f49c5de780edb4e40aec96303c8a7b98b1b8e53dd5e07e01d4f3ffd836763209a1f0cbc61adcfdc2951e77528ee7b6e68114c3a4bec38875d285021e68ae8aa913bb1e2e65dd52c649a0e98bfb4e8bab6dd10295c1167a0854ba44f094feb75d2fb00c944f07d4b47114f483df9838459316f3ddbc4a82e6507881931f8e20f5b805</pre>
>
> ====ROUND 2====
> *Coordinator
> ** <tt>my_multisig_wallet.bsms</tt>:
> <pre>BSMS 1.0
> /0/*,/1/*
> wsh(sortedmulti(2,[98d79e95/48'/0'/0'/2']xpub6DvvwHS5pd1D36xt4YBGJvtdThWXfn8L9qRj9DbFMExMeP6eBE6Aw9WyBC7XUQwiPPDFurirewsKZpYv68yTV5RBy7SZmw45QEkaLka5BCt/*,[3e94b5a1/48'/0'/0'/2']xpub6E1W1DUYY29V2b8czCcpi36GG2uD33B11vwNopgTZwsVyfgAkA4kPCqLP5R4YzaRvzW17CQrDkgmDQbA848AdkR7W18nNvMKXzzCBSnZP9c/*))#x0lx92qk</pre>
>
> *Coordinator encryption
> ** HMAC_KEY (hex): 4dab3988cbc683ad7a8c93d43f9b11a78b63a93d5e33ea19c603f4b7b87ac284
> ** MAC (hex): df3d06db6c8b8a5f25de202e10ea225df6415d1ed0e36c64cc2be1b7e86c2a38
> ** IV (hex) : df3d06db6c8b8a5f25de202e10ea225d
> ** CIPHERTEXT (hex): 2761e6bfe839586b4c90954200bc4ce6d39ef164c5d14997755575d1691ee249ffd20beda526f57a7424907f839c6c2e3ecd46889ede290a2c81de22d3f33a7fa5e55ec95c0e26005c596d0f6346f819823f361f9f9f54d1eae48b325240d66c5888bd5ebab843061dcdd73b675346da982646c83026694d757661d31c2d654fb263c9ab3e874a258bc234c48532f15e9450c982fcf161404746e9f23d25e17b74139cd799983fd0c7a7a0386a823d3789b4578879a764172cc8ef96ab003eee24f6288007d31e2b999aff5a6d30cc524a0111a99730a29cf28ae41dbff6ce21ca6bc1df37074228178048e835584e6e70dba941154d024cd03cb6c56d0bde441ce464aa749de5e814dd30e21b75f62e831ac1f28eda1a7ba7e122076789e284402c8ba85b5a0e864bce220e3c78fa2f465e2bcf6b1d378816319de99f99ce7068
> ** <tt>my_multisig_wallet.dat</tt>: <pre>df3d06db6c8b8a5f25de202e10ea225df6415d1ed0e36c64cc2be1b7e86c2a382761e6bfe839586b4c90954200bc4ce6d39ef164c5d14997755575d1691ee249ffd20beda526f57a7424907f839c6c2e3ecd46889ede290a2c81de22d3f33a7fa5e55ec95c0e26005c596d0f6346f819823f361f9f9f54d1eae48b325240d66c5888bd5ebab843061dcdd73b675346da982646c83026694d757661d31c2d654fb263c9ab3e874a258bc234c48532f15e9450c982fcf161404746e9f23d25e17b74139cd799983fd0c7a7a0386a823d3789b4578879a764172cc8ef96ab003eee24f6288007d31e2b999aff5a6d30cc524a0111a99730a29cf28ae41dbff6ce21ca6bc1df37074228178048e835584e6e70dba941154d024cd03cb6c56d0bde441ce464aa749de5e814dd30e21b75f62e831ac1f28eda1a7ba7e122076789e284402c8ba85b5a0e864bce220e3c78fa2f465e2bcf6b1d378816319de99f99ce7068</pre>
>
> ===Mode: <tt>EXTENDED</tt> Encryption===
> ====ROUND 1====
> *Coordinator
> ** M-of-N: 2/3
> ** ADDRESS_TYPE: NESTED_SEGWIT
> ** TOKEN for Signer 1 (hex): 654d63309464afcda558c6aa
> *** TOKEN (decimal): 31351541690484562733651510954
> *** TOKEN (mnemonic): grab help slow churn enough traffic nice boat price
> *** ENCRYPTION_KEY (hex): 4073adac2351e164b8d68039abd9d4b8e4d07adccfdf73ece6e236d60b107802
> ** TOKEN for Signer 2 (hex): b0344f51d5cb04083d598fa3
> *** TOKEN (decimal): 54532600447720520868878192547
> *** TOKEN (mnemonic): rabbit pen stamp process raccoon advice voice cradle person
> *** ENCRYPTION_KEY (hex): 6bae6b670e257d7468c3e90194029dd468a2f39d8b9a3ff187b08209b1d409b6
> ** TOKEN for Signer 3 (hex): 163fd307195982c4c39d50bb
> *** TOKEN (decimal): 6885829092987042066541138107
> *** TOKEN (mnemonic): bike write scrub crawl oblige give attack present rookie
> *** ENCRYPTION_KEY (hex): c78b94589214b6dc98b337ba4ce54380553ed00a1e5b1955fc540ce3b30d6566
>
> * Signer 1
> ** MASTER_KEY_FINGERPRINT: 110dc257
> ** PRIVATE_KEY (m/48'/0'/0'/1'): KzshDDEBhzyiwXHoyE7ZiLegzztEy54AG6Wq8N844LqHSQMHt4Ji
> ** XPUB (m/48'/0'/0'/1'): xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk
> ** Legacy signature
> ** <tt>signer_1_key.bsms</tt>:
> <pre>BSMS 1.0
> 654d63309464afcda558c6aa
> [110dc257/48'/0'/0'/1']xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk
> Signer 1 key
> IDX6xLdM4XjetYPvVfpVBXAfT7oE3tHAOB4blZpbIst8bjJ+LbDeP4tZl4O8utAuys9igXE0G3kaHz1mg/+OU8w=</pre>
>
> * Signer 1 encryption
> ** HMAC_KEY (hex): f43c359a4b3d7b2e01be73c54519b12545ca9a23a86f824aadf577b314a7caa7
> ** MAC (hex): 40b6b43e2f1bc01b748eb242235d7e09fa8a2fd6cebe35784cf3adf81910ec98
> ** IV (hex) : 40b6b43e2f1bc01b748eb242235d7e09
> ** CIPHERTEXT (hex): 0877987764401c27e6c60ed2f1bb89dff1dbc5e8204149f682d53049bffe39553f24af3928aa2f78ac2d04ac5baa0c3ec39aaccf0d258e7bb6659a7b92e92f2c2784a94f4df8e8af2270d9d411bfff2cfb9f71b4e1ac87561c7d2ac57ca86a1f9716d5da7571719d24830fc8d015a0daf04b3742439484488798335357f2eeaa8e2db2ba630f9dffd88236e327ab5bfcfb6e29ee3ef6cc18e0b71c1731465c2351e76b92f7b1bd28ef6eff5414c22aa6c80090fa59b973c22e3044e92dbf3688990a49a42828e52c1e686f1193dcdf7b7118930e01419fe938c6811c58c84c36d692fd52846f998bc328471f1e73c22261791a08cda096ee3ac8b37f31afd0b1d9c335ff9ac67ff230eb0d69f2d7
> ** <tt>signer_1_key.dat</tt>: <pre>40b6b43e2f1bc01b748eb242235d7e09fa8a2fd6cebe35784cf3adf81910ec980877987764401c27e6c60ed2f1bb89dff1dbc5e8204149f682d53049bffe39553f24af3928aa2f78ac2d04ac5baa0c3ec39aaccf0d258e7bb6659a7b92e92f2c2784a94f4df8e8af2270d9d411bfff2cfb9f71b4e1ac87561c7d2ac57ca86a1f9716d5da7571719d24830fc8d015a0daf04b3742439484488798335357f2eeaa8e2db2ba630f9dffd88236e327ab5bfcfb6e29ee3ef6cc18e0b71c1731465c2351e76b92f7b1bd28ef6eff5414c22aa6c80090fa59b973c22e3044e92dbf3688990a49a42828e52c1e686f1193dcdf7b7118930e01419fe938c6811c58c84c36d692fd52846f998bc328471f1e73c22261791a08cda096ee3ac8b37f31afd0b1d9c335ff9ac67ff230eb0d69f2d7</pre>
>
> * Signer 2
> ** MASTER_KEY_FINGERPRINT: 5c890401
> ** PRIVATE_KEY (m/48'/0'/0'/1'): L41Jnc9CdBtBJd18429MDGcTgP2DNoXaKyyGr271ndTprvrHXDQf
> ** XPUB (m/48'/0'/0'/1'): xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q
> ** Legacy signature
> ** <tt>signer_2_key.bsms</tt>:
> <pre>BSMS 1.0
> b0344f51d5cb04083d598fa3
> [5c890401/48'/0'/0'/1']xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q
> Signer 2 key
> H5kN6UHaK2xACB6iYdTxxQPD8qyFEYv9iMsQs5B0MRfCM7NA5GB+7EFgmBpSctwt6B122zWBr6mRjpYjKmj+7hs=</pre>
>
> * Signer 2 encryption
> ** HMAC_KEY (hex): e0a20b5f5285fbaa35aad08fb70f5626c9abbe1b384a4950735b28aca6325ff2
> ** MAC (hex): 3a6deec8dbdbd6606a52c7d7e64eca4f972a293cbabac6f62736629fbe77928a
> ** IV (hex) : 3a6deec8dbdbd6606a52c7d7e64eca4f
> ** CIPHERTEXT (hex): bb0fb72f61b0c4858bd9c65235390b67651b94c4b0329238b0116dd6d3365ade33cb1c1b1619638968791a5d2d1d263d90280bdad8d9ca24c34a78e320076e0dccf59e7f729b541b44bbe40ba803dedd3b17c49765377cb2d913a856b86c3dd383dab475790e89226ed8ef2301574212d2809ed9c099aa67be434024ee2a4e82a146300acf755863da64807cb7bb2636f6616489636d254a870778d3540832aea44abac4328b5d90f3e6045ef36a526ce5d575f2305e3e4699dccbc713e9e68f50364036c1054c2a506aab77ea7c43a89536947c24330b09a62a90c3b4ae2d452f96ef34ec871af2c52d68ddede2503c87e2ba68d5cf9be589457879e06021ea6a6176f7dded820ba4c0e709e2a2
> ** <tt>signer_2_key.dat</tt>: <pre>3a6deec8dbdbd6606a52c7d7e64eca4f972a293cbabac6f62736629fbe77928abb0fb72f61b0c4858bd9c65235390b67651b94c4b0329238b0116dd6d3365ade33cb1c1b1619638968791a5d2d1d263d90280bdad8d9ca24c34a78e320076e0dccf59e7f729b541b44bbe40ba803dedd3b17c49765377cb2d913a856b86c3dd383dab475790e89226ed8ef2301574212d2809ed9c099aa67be434024ee2a4e82a146300acf755863da64807cb7bb2636f6616489636d254a870778d3540832aea44abac4328b5d90f3e6045ef36a526ce5d575f2305e3e4699dccbc713e9e68f50364036c1054c2a506aab77ea7c43a89536947c24330b09a62a90c3b4ae2d452f96ef34ec871af2c52d68ddede2503c87e2ba68d5cf9be589457879e06021ea6a6176f7dded820ba4c0e709e2a2</pre>
>
> * Signer 3
> ** MASTER_KEY_FINGERPRINT: 614cbf5f
> ** PRIVATE_KEY (m/48'/0'/0'/1'): L2ccRLzH7GfVxWpU8YSY9y5UGyRoqW3UdeNT1vGfVbxAGhwU5qhD
> ** XPUB (m/48'/0'/0'/1'): xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH
> ** Legacy signature
> ** <tt>signer_3_key.bsms</tt>:
> <pre>BSMS 1.0
> 163fd307195982c4c39d50bb
> [614cbf5f/48'/0'/0'/1']xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH
> Signer 3 key
> H0jf2JMtke5zDDIWys6fihOCA6QBmC5+hbgVB/c2mMPNPLB6tDXt0TFZU1f9wvaCR9762anKSc8CCqXLogw8V00=</pre>
>
> * Signer 3 encryption
> ** HMAC_KEY (hex): 1f51ea067c121e2f86af5e1d484905046bc63e861573157d8b1ae9e7e47e224b
> ** MAC (hex): 1a5624fcb39cebabb6174456173eec19b756bc916cf2c9d815e9bcce070898c4
> ** IV (hex) : 1a5624fcb39cebabb6174456173eec19
> ** CIPHERTEXT (hex): 48d6e139bdc8c19e93cbbf5b4478340c8cf08aa91c28803084d5f58618773f7e615e0134492b496c4e7c130351c0350701f686918033f621378552d7040efedd5539d38c258bf936475de775f23da3953fe3ba5bbbd24816b8902b87a9a09700c446b085119dedee2395dd69665e742f72f2fb6da4ebe3f4704eaf45486fbfb84d764b718cc0b756e72f72ab6069d47765bdd3ebd4074af4fa99a95691a659675ce5f72235c28ddf3c3d53179e598cddc967fc896adc6e97edeeffc85b9e44611df748d923ff3dd921ad4d6e98e0de12359a37558e326faf585ba57e73ab45bc4a49f6e8a756f365f5d204e70f7c7bed269e81e9524a41e5d4cbaad0b6b442d6eea1e5da1ca345cc665a0cffe2c3
> ** <tt>signer_3_key.dat</tt>: <pre>1a5624fcb39cebabb6174456173eec19b756bc916cf2c9d815e9bcce070898c448d6e139bdc8c19e93cbbf5b4478340c8cf08aa91c28803084d5f58618773f7e615e0134492b496c4e7c130351c0350701f686918033f621378552d7040efedd5539d38c258bf936475de775f23da3953fe3ba5bbbd24816b8902b87a9a09700c446b085119dedee2395dd69665e742f72f2fb6da4ebe3f4704eaf45486fbfb84d764b718cc0b756e72f72ab6069d47765bdd3ebd4074af4fa99a95691a659675ce5f72235c28ddf3c3d53179e598cddc967fc896adc6e97edeeffc85b9e44611df748d923ff3dd921ad4d6e98e0de12359a37558e326faf585ba57e73ab45bc4a49f6e8a756f365f5d204e70f7c7bed269e81e9524a41e5d4cbaad0b6b442d6eea1e5da1ca345cc665a0cffe2c3</pre>
>
> ====ROUND 2====
> * Coordinator
> ** <tt>my_multisig_wallet.bsms</tt>:
> <pre>BSMS 1.0
> /0/*,/1/*
> sh(wsh(multi(2,[110dc257/48'/0'/0'/1']xpub6EPQbDFezXYvVFHqnc8R7QUSE8hTepbyCXU7jJBT4dVm2rQHe1i6isqoj59qhyBiCdKquo6QsgMZNHvEz3BM4cNSszF25siTqLUCznBm8vk/*,[5c890401/48'/0'/0'/1']xpub6EW1SmjSXq9YwVwcan5qWEncgx89SozMvGNpYF6hfZHYNTikNZ4gsXuVhHTi6xYJCkmY4X4wpPPS5Gr7aY39dVJMS2TGfihr25oaspKtU8q/*,[614cbf5f/48'/0'/0'/1']xpub6F9TfWTFcMYy5Ycd2ka2az1brJj78J2isLAWptZnCpFsesss5sZv5B8xsgt71ZXfhDWhUtf4vng4zY6HUVrQbDMPDYRLYvFFoLnAYfzgYPH/*)))#j3ykhz7f</pre>
>
> * Send to Signer 1:
> ** HMAC_KEY (hex): f43c359a4b3d7b2e01be73c54519b12545ca9a23a86f824aadf577b314a7caa7
> ** MAC (hex): ee74a0f50943d7d1b65270028bb05133e87c832cdc1ef0a07c79db2093ca3432
> ** IV (hex) : ee74a0f50943d7d1b65270028bb05133
> ** CIPHERTEXT (hex): 8e3ba3dac0f979fad0d160bd00c8294ff1726d51b95ff3e1534e5a1900f3d7cd4f6d929985a94b9da2c11e4e0f7770cc53c6739fd099477323bd26a3eca9c8016e79848d15e274463424b8355cd73cced61f1816ac8bac87f8c650ee9052f50e347c52ad24b00794a9d5523714be2fdcf731f14b7a8d7c93eab44c258e1c417d2837b9676832e8ce7239dc28b4e1166803209947b8a875a99b9478ee94f7bc17399e886179ab2a0285dc11a3883f6fa439d0f2277dadbec8c355c379fc50e945897e1a738f6a55b09f6b8b6bdf6d4bc248219cbad3662a78a2f539c989e055e00b8efd42fbff978e1a5cc10f83df56117ece4d17f94a0a6d3803778ed53531419250c5a0fff6cad4ab401468dd054915b068cc8826ae1308a71b38060d68c9248d59eea11c2c52a66d5f6bc0d7ae6cb44305c36e56068456d293b70037902e7b05a3ee0af710201128dffc0c16c3306b66bd19b9ae5b91aded35ef33f07743e5b185a9f88a5c67d40270e3bbcf592167ceaf82ead693728d5129b50075edd5ce24863f3484b4b063599ed1327e1c87d0a2051fed3b1234a702722b686e4c9392a403b79726800dd6b691e516e44d9e836c190b10cf2bb262bba98293c97f2c323e59acd0a1f988c5
> ** <tt>my_multisig_wallet_for_signer_1.dat</tt>: <pre>ee74a0f50943d7d1b65270028bb05133e87c832cdc1ef0a07c79db2093ca34328e3ba3dac0f979fad0d160bd00c8294ff1726d51b95ff3e1534e5a1900f3d7cd4f6d929985a94b9da2c11e4e0f7770cc53c6739fd099477323bd26a3eca9c8016e79848d15e274463424b8355cd73cced61f1816ac8bac87f8c650ee9052f50e347c52ad24b00794a9d5523714be2fdcf731f14b7a8d7c93eab44c258e1c417d2837b9676832e8ce7239dc28b4e1166803209947b8a875a99b9478ee94f7bc17399e886179ab2a0285dc11a3883f6fa439d0f2277dadbec8c355c379fc50e945897e1a738f6a55b09f6b8b6bdf6d4bc248219cbad3662a78a2f539c989e055e00b8efd42fbff978e1a5cc10f83df56117ece4d17f94a0a6d3803778ed53531419250c5a0fff6cad4ab401468dd054915b068cc8826ae1308a71b38060d68c9248d59eea11c2c52a66d5f6bc0d7ae6cb44305c36e56068456d293b70037902e7b05a3ee0af710201128dffc0c16c3306b66bd19b9ae5b91aded35ef33f07743e5b185a9f88a5c67d40270e3bbcf592167ceaf82ead693728d5129b50075edd5ce24863f3484b4b063599ed1327e1c87d0a2051fed3b1234a702722b686e4c9392a403b79726800dd6b691e516e44d9e836c190b10cf2bb262bba98293c97f2c323e59acd0a1f988c5</pre>
>
> * Send to Signer 2:
> ** HMAC_KEY (hex): e0a20b5f5285fbaa35aad08fb70f5626c9abbe1b384a4950735b28aca6325ff2
> ** MAC (hex): 81df9e064f1de1d5f754c4e20f9286f9d81b856d3965677a9f2430cb9297ad1f
> ** IV (hex) : 81df9e064f1de1d5f754c4e20f9286f9
> ** CIPHERTEXT (hex): dcd82038ef627d6cb2deb62d04c4ccbaa3a354633d960e46312c22791f039f23fd9782a1e3a63504c1e5b3a0770bb8d32fdf168738b6c03278f1391dd5d01e9aafee7be2c8136ee018feff6fc8cdb926df13a36e115ddca8254934f56b7f700768c94cb8388a8297834de9affcd959417ae3d6ec3251387904f50f51f06306cc4d36eefc51418dd3b2c5454910a23ec67a40a3b918d2a740e812929aae949d8dde2c41cbbb3a2b7c2103788421c147f4794d6a26947c15ef4a99ceb825d0c5aaa78b8737d0ef712ba8e269a9941b1af5d217dcdd9cd06727fbdc70fabe3f5a8c09acff4e76992be7f27c6b12ca84739f62a6da86e5b79103d632c0dc8ab3f91fddb3cfbe67084dc4b861c4ac7c86fb171a058c98c67cffdc40ff17ae1533361cc6fb7b63657af0408cf30bf9d6d97aaacf9d3ff443eee61f207228cd91769ce83a0709c1be1847884c6a8fdc86ede66aef8e34fc509c49edf30f743bdc8f9052961ee340924ec2d1caadc6fd286bb3e233c153cd08c1934127752dc28e0d12efa92a050c4061653edb1cbf2fd4b2ba4e038f0b44f5735f198e92571c029156f65f534bfc149f38d611829901372cfc0176b9d2f9ac6512b7f37941a02dff701df0bceadaacfc6935
> ** <tt>my_multisig_wallet_for_signer_2.dat</tt>: <pre>81df9e064f1de1d5f754c4e20f9286f9d81b856d3965677a9f2430cb9297ad1fdcd82038ef627d6cb2deb62d04c4ccbaa3a354633d960e46312c22791f039f23fd9782a1e3a63504c1e5b3a0770bb8d32fdf168738b6c03278f1391dd5d01e9aafee7be2c8136ee018feff6fc8cdb926df13a36e115ddca8254934f56b7f700768c94cb8388a8297834de9affcd959417ae3d6ec3251387904f50f51f06306cc4d36eefc51418dd3b2c5454910a23ec67a40a3b918d2a740e812929aae949d8dde2c41cbbb3a2b7c2103788421c147f4794d6a26947c15ef4a99ceb825d0c5aaa78b8737d0ef712ba8e269a9941b1af5d217dcdd9cd06727fbdc70fabe3f5a8c09acff4e76992be7f27c6b12ca84739f62a6da86e5b79103d632c0dc8ab3f91fddb3cfbe67084dc4b861c4ac7c86fb171a058c98c67cffdc40ff17ae1533361cc6fb7b63657af0408cf30bf9d6d97aaacf9d3ff443eee61f207228cd91769ce83a0709c1be1847884c6a8fdc86ede66aef8e34fc509c49edf30f743bdc8f9052961ee340924ec2d1caadc6fd286bb3e233c153cd08c1934127752dc28e0d12efa92a050c4061653edb1cbf2fd4b2ba4e038f0b44f5735f198e92571c029156f65f534bfc149f38d611829901372cfc0176b9d2f9ac6512b7f37941a02dff701df0bceadaacfc6935</pre>
>
> * Send to Signer 3:
> ** HMAC_KEY (hex): 1f51ea067c121e2f86af5e1d484905046bc63e861573157d8b1ae9e7e47e224b
> ** MAC (hex): 159a91100cacd123480b7d085c8bb32ec8eb06f0391b6dc8fac07ae67eb37b81
> ** IV (hex) : 159a91100cacd123480b7d085c8bb32e
> ** CIPHERTEXT (hex): c7269d8be21d1cfe172e35aa106760f1fdc929fce19da8fb7f74f759efec1ee02796fb1e8b008cf177f60a2021570f17aeeb41f8636858654082734b90959b98fd08419f901683c4ca3e76b3e482fea4c67162775e0d80bcb45df729f646c1364a3d8a7d1ff961717b00897e877c1c0554d3502942149726806269c546ad2dd34ba286ddf5cd336b83aabf7091fa25e607faf7e54017d84113e1e3ec440b3704addea188b89293469306fc0a98570afdcf269026b2d2e760f466c1f75bcf75fdf030c0a692e5681fd4487e59d6e96451ff5b6b9f2521b8e95e796ef4ab0a917794d91a30fdac7ee9ddbd89d174831bd133ab12a74f52f6283ee2c5fe3d5a957a7c1a15530b2c5224f76d90057dc94f2ee34e28b037ae7f518cc6dfe725cd3e657648de82b200ea77830eb93219f883998d3207a4ef5902d1119b0cde6b364bc1effb86109d9c2babc8ab26dce90329779d8cd0d737e9825a25586aa3c8fa5317e3e433ff235b82f629de0504e3c992f8e8de299f62751bc1fcb2e75e0262c7a27be7068cea69b14f303e97c24b99ed29cae142564e285657704b4c411d0d4f8c58819e2c0e0ffc3667eb5a408aad8a3023a5f00875e7deab95dc365d8757f7b79815a4fd9e6de2b3
> ** <tt>my_multisig_wallet_for_signer_3.dat</tt>: <pre>159a91100cacd123480b7d085c8bb32ec8eb06f0391b6dc8fac07ae67eb37b81c7269d8be21d1cfe172e35aa106760f1fdc929fce19da8fb7f74f759efec1ee02796fb1e8b008cf177f60a2021570f17aeeb41f8636858654082734b90959b98fd08419f901683c4ca3e76b3e482fea4c67162775e0d80bcb45df729f646c1364a3d8a7d1ff961717b00897e877c1c0554d3502942149726806269c546ad2dd34ba286ddf5cd336b83aabf7091fa25e607faf7e54017d84113e1e3ec440b3704addea188b89293469306fc0a98570afdcf269026b2d2e760f466c1f75bcf75fdf030c0a692e5681fd4487e59d6e96451ff5b6b9f2521b8e95e796ef4ab0a917794d91a30fdac7ee9ddbd89d174831bd133ab12a74f52f6283ee2c5fe3d5a957a7c1a15530b2c5224f76d90057dc94f2ee34e28b037ae7f518cc6dfe725cd3e657648de82b200ea77830eb93219f883998d3207a4ef5902d1119b0cde6b364bc1effb86109d9c2babc8ab26dce90329779d8cd0d737e9825a25586aa3c8fa5317e3e433ff235b82f629de0504e3c992f8e8de299f62751bc1fcb2e75e0262c7a27be7068cea69b14f303e97c24b99ed29cae142564e285657704b4c411d0d4f8c58819e2c0e0ffc3667eb5a408aad8a3023a5f00875e7deab95dc365d8757f7b79815a4fd9e6de2b3</pre>
>
> ==Acknowledgement==
>
> Special thanks to Pavol Rusnak, Dmitry Petukhov, Christopher Allen, Craig Raw, Robert Spigler, Gregory Sanders, Ta Tat Tai, Michael Flaxman, Pieter Wuille and others for their feedback on the specification.
>
> ==References==
>
> Original mailing list thread:
> https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018385.html

[-- Attachment #2: Type: text/html, Size: 55372 bytes --]

 permalink raw reply	[|nested]
2021-04-11  2:34   ` Michael.flaxman

  2021-04-12 15:03       ` Salvatore Ingala
  
From: Hugo Nguyen @ 2021-04-11 16:45 UTC (permalink / raw)
  To: Michael.flaxman;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 11376 bytes --]

Hi Michael,
Comments inline.

On Sat, Apr 10, 2021 at 7:34 PM Michael.flaxman <
michael.flaxman@protonmail•com> wrote:

> Hi Hugo,
>
> I appreciate the effort you and everyone else is making to improve
> multisig in bitcoin!
>

Thanks.


> I like that this BIP gets rid of SLIP132 version bytes, as those have been
> de-facto deprecated in favor of output descriptors for some time. Having a
> standard for how to communicate descriptor records (BSMS 1.0) also seems
> like a nice positive.
>
> The most commonly raised issues from the 10x security guide
> <https://btcguide.github.io/> are about how to properly verify that all
> hardware wallets are participants in the user's multisig quorum (and with
> the correct m-of-n). This shows up in two big ways:
>
>    1. The O(n^2) xpub validation problem creates a bad UX and is hard for
>    non-advanced users.
>    2. The risk for stateless hardware wallets (like Trezor) to have their
>    xpubs swapped out by a compromised Coordinator.
>
> Unfortunately, this BIP does not improve either of these issues, while
> adding considerable complexity.
>
> *1. O(n^2) Xpub Validation*
>
> The proposed use of an output descriptor checksum has an obvious 40-bit
> MITM collision attack. A compromised Coordinator could trick a Signer into
> displaying an attacker's receive address, despite a correctly functioning
> Signers and the user properly validating the checksum (github link
> <https://github.com/nunchuk-io/bips/pull/1/#issuecomment-801629857>).
>
> Using a checksum with much higher entropy would reduce xpub validation to
> O(n) and create a very nice UX for signers. This would be a huge win for
> multisig! Instead, the recommended solution from the BIP is to validate all
> the key records manually, which is how multisig is currently done and what
> we desperately want to move away from. With a proper checksum, there’s no
> reason for a user to ever see an xpub.
>
> Users should not be shown a checksum and asked to validate it in meatspace
> (across Signers) if an attacker’s address could still be substituted!
> Validating a single address across devices does solve this problem, but if
> you’re going to validate an address there’s no reason to display the
> checksum at all. However, validating an address is confusing to non-experts:
>
>    - Is it a wallet ID or a bitcoin address?
>    - Am I supposed to send funds to this address?
>
> If creating a new checksum standard for the descriptor record is
> undesirable, we could use a child address (from an unhardened BIP32 path)
> and encode that in some way for end-users to verify it matches across all
> Signers. It would be strongly preferable for the encoding to be an
> unambiguously different format from a bitcoin address / BIP39 seed phrase,
> so that it’s clear it’s just a wallet ID. One non-ideal but simple solution
> is to use a hash function (i.e. dsha256) to calculate the digest of the
> child address, and display this in hexadecimal format. While hexadecimal is
> non-ideal for manual verification, it is already trivial for any bitcoin
> library to perform these steps.
>

As I have responded to your previous comment about the same on Github (
https://github.com/nunchuk-io/bips/pull/1), I do see the value of a
longer checksum.

There are trade-offs when it comes to designing checksum. Mainly complexity
and size. At one end of the spectrum you can have a single-byte XOR
checksum. At the other end you can have something like HMAC-SHA256 (which
we are using in the proposal to calculate the MACs for the key and
descriptor records). And then there's everything in between. But we should
know that nothing comes for free.

It's a good topic that warrants further discussion.

Confirming a single address is a promising direction, since it's something
the user should do anyway prior to using the wallet. Currently the proposal
recommends that the Signers show a preview of the first address(es) upon
wallet creation. But we can elevate this and make it a mandatory part of
the spec: have all Signers confirm that they have the same 1st receive
address. If we go with this approach, the checksum can stay as-is, and only
there for error detection. (We get the checksum for free with the
descriptor language anyway, so there's no reason to remove it).

Also nice to see that you have come around and agree that moving away from
manual inspection is desirable.


> *2. Allow Support for Stateless Wallets*
>
> The current BIP states:
>
> * "If all checks pass, the Signer must persist the descriptor record in
> its storage."*
>
> While persistence has a lot of benefits, it is not a feature of the most
> sold multisig hardware wallet: Trezor. A simple solution here is to have
> each Signer sign the entire descriptor record at the end of round 2, not
> just its own key record in round 1. Then the data can be stored anywhere
> (including on the Signer itself) and played back to each Signer for
> validation when needed. The end-user would have no idea this was happening,
> but the device could refuse to display information it hasn’t fully
> validated (or at least add a warning message). Even a device with
> persistent storage would be better served using a signature, so that an
> evil maid couldn't tamper with the device (say in the no-encryption case
> for simplicity).
>

I reiterate that I strongly disagree that going stateless is the direction
we want to pursue when it comes to multisig.

In a multisig or any type of MPC smart contract, any Signer in the contract
must know who the other co-Signers are at all times. You can choose to do
this verification once at setup and persist this info on the Signer, or
you'd have to re-do the verification for every single transaction. There is
no other choice.

Signing the descriptor record is insufficient, while also introducing a
great deal of complexity. Here are the problems:
1) The signature needs to be stored somewhere. Who stores it if it's not
the Signer itself? What if it gets lost? (If the Signer stores its own
signature, then the scheme is no longer stateless. You might as well store
the full descriptor).
2) When the signature is "played back" to the Signer, a copy of the
original descriptor must be included. Who stores the descriptor? What if it
gets lost? This is an under-appreciated aspect of the stateful approach:
every participant in the multisig has a full copy of the original contract,
which adds resilience to the wallet backup / recovery process.
3) Because the full descriptor must be "played back" for every single
transaction, this means every detail of the contract must be shared again
and again, indefinitely. Not only does this add overhead (engineering and
cognitive) to the spending process, it has massive privacy implications,
since the descriptor contains everything you need to know about the wallets
and its participants.

Here's an analogy in the physical world. Would you:
a) Enter any type of written contract and
b) Not keep a copy of the contract, forget about it, and
c) Later on rely on your counter-parties or a third-party to provide you
with the original contract and your signature, when the terms get carried
out?

One would be insane to enter such a contract in the real world.

I realize that some vendors are currently not stateful, but I take this as
an unfortunate fact, because multisig wasn't a priority when these hardware
were originally designed. But that is no reason to keep going with a broken
architecture. The industry is green enough that we still can learn and
recover from these sorts of flaws.

Since you mentioned Trezor, I want to thank Pavol in particular here,
because as Trezor CTO Pavol knows best that Trezor is currently stateless,
but he's still on-board with the general idea here, AFAIU.

Bottom line: IMO, signers in a multisig MUST be stateful.

This existing vulnerability in stateless wallets is particularly bad for
> hosted multisig services like Casa/Unchained, where the service might
> control m-1 keys. It’s far easier for a hosted service to potentially trick
> non-expert users into displaying an attacker's receive address on their
> stateless Signer.
>
> For example, assume the user is doing 2-of-3 multisig, where the
> Coordinator (service) controls 1 key. Here is how the Coordinator could
> trick their end-users:
>
>    1. Coordinator swaps out 1 of the end-user’s xpubs, going from a
>    2-of-3 where the end-user has 2 seeds to a 2-of-3 where the Coordinator has
>    2 seeds.
>    2. The end-user logs into the service to get a new receive address,
>    and the service (Coordinator) displays malicious receive address X (as part
>    of a 2-of-3).
>    3. The end user connects stateless Signer 1 to the service
>    (Coordinator), which under-the-hood gives stateless Signer 1 proof that it
>    is included in this 2-of-3. Stateless singer 1 displays malicious receive
>    address X!
>    4. The end-user doesn't verify the address on Signer 2, as many users
>    unfortunately don't -- perhaps it is in a far away location and the
>    end-user (incorrectly) thinks that it’s already been validated in 2 places
>    -- and makes a large deposit to receive address X. These funds now belong
>    to the attacker and can be swept at any time!
>
> If stateless Signer 1 required a signature to be replayed at step 3,
> stateless Signer 1 would refuse to display malicious receive address X (or
> at a minimum warn the end-user that it did not have enough info to properly
> validate the address).
>
> This is also a concern for self-hosted multisig, I just used the hosted
> services as the best example.
>
> It's also not just Trezor that is stateless. For example, I wrote a
> simple CLI software multisig wallet as part of the buidl library
> <https://twitter.com/mflaxman/status/1321503036724989952> to be used
> mostly for emergency recovery. At 800 lines of code, it's too
> simple/minimal to touch the file system.
>
> *BIP39*
>
> While unrelated, the use of BIP39 words for session tokens seems like a
> big mistake, as end-users have learned over years that BIP39 words are for
> private key material. A small percent of users may backup their token BIP39
> mnemonic and not their seed phrase BIP39 mnemonic! My suggestion is to just
> stick with the other two Token options: decimal and hex.
>

Repost of my previous response. We discussed this at length on the
linked Github PR:
"We decided to keep the TOKEN at 6-9 words, not 12 or anything above
precisely for this reason. Please note that the user has to back up their
Signers first, before proceeding to setting up the multisig wallet. So
there's no writing both things down at once or mixing of the two flows here.

I also find it hard to believe that someone who wants to invest in a safe
multisig solution (and therefore must know at minimum what keys and
multisig represent) will not know the difference between (permanent) 12
words and (one-time use) 6 words. Also note that the TOKEN can be used
without using BIP39 mnemonic at all."

We also made the decimal format, not BIP39 mnemonic, the recommended
encoding in the spec.

Best,
Hugo

[-- Attachment #2: Type: text/html, Size: 17483 bytes --]

 permalink raw reply	[|nested]
2021-04-11 16:45     ` Hugo Nguyen

  2021-04-12 17:55         ` Hugo Nguyen
  2021-04-12 18:45         ` Christopher Allen
  
From: Salvatore Ingala @ 2021-04-12 15:03 UTC (permalink / raw)
  To: Hugo Nguyen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 6907 bytes --]

Hi Hugo,

First of all, thank you for the impressive work on leading the
standardization efforts!

I believe one ought to more clearly distinguish the "Signer" (as in: one of
the parties in the multisig setup), from the "*Signing device*" (which is
likely a hardware wallet). BSMS defines a "Signer" as "a participating
member in the multisig",  therefore a person/entity who is likely using
both a hardware wallet and some BSMS-friendly software wallet (e.g. the
next version of Specter Desktop). It is therefore relevant to discuss which
parts of the BSMS mechanism are implemented in the Signer's software
wallet, and which should be in the Signer's hardware wallet.
From the discussion, it appears to me that different people might have
different expectations on what the signing device/HWW should do, so I would
like to comment on this point specifically (while I reckon that it mostly
falls within the realm of concerns #4 and #5 of the motivation paragraph,
which are explicitly left out of scope).

I fully agree that a *Signer* must persist the full wallet's description,
and should also create physical backups which include the full descriptor
and the cosigner's information. I would disagree, however, if any standards
were to force *hardware wallets* to persist any substantial amount of state
other than the seed, as I believe that it gives no substantial advantage
over externally stored signed data for many use cases.

The following is the *wallet registration flow* I am currently working on
(in the context of adding support to multisig wallets at Ledger). The goal
is to allow a *Signer* (the person) to persist a multisig setup in its
storage, while achieving a similar level of security you would have if you
were storing it on the hardware wallet itself (note that the following flow
would happen as part of Round 2):

1) The desktop wallet of the requests the HWW to register a new multisig
wallet. The request includes the full multisig wallet description, and some
extra metadata (e.g.: a name to be associated to this multisig wallet).
2) The HWW validates the wallet and verifies it with the user with the
trusted screen (as per BSMS Round 2); on confirmation, it returns a wallet
id (which is a vendor-specific hash of all the wallet description +
metadata) and signature
3) The desktop wallet stores the full wallet description/id/signature.
(Optionally, a backup could be stored elsewhere).

Whenever an operation related to the multisig wallet is required (verifying
a receiving address, or signing a spending transaction), the HWW first
receives and verifies all the data stored at step 3 above (without any user
interaction). Then it proceeds exactly the same way as if it had always
stored the multisig wallet in their own storage. I think this is basically
the same flow Michael Flaxman is suggesting here:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-April/018775.html

(Note that none of this is flow specific to Multisig wallet, as the same
flow would be unchanged for any arbitrary supported script that needs to be
"registered" on a stateless device, and can be generalized for MPC
protocols)

The only caveat I can think of is that the script registration is never
revocable if a signing key derived from the seed is used in step (2), which
might or might not be desirable. One could instead prefer to use a
different signing key that is destroyed if the device is wiped, which would
therefore need to be stored on the device. Note that the only thing that is
lost is the on-device multisig wallet registration, which could easily be
repeated from a backup.


On Sun, 11 Apr 2021 at 19:11, Hugo Nguyen via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> I reiterate that I strongly disagree that going stateless is the direction
> we want to pursue when it comes to multisig.
>
> In a multisig or any type of MPC smart contract, any Signer in the
> contract must know who the other co-Signers are at all times. You can
> choose to do this verification once at setup and persist this info on the
> Signer, or you'd have to re-do the verification for every single
> transaction. There is no other choice.
>

>
Signing the descriptor record is insufficient, while also introducing a
> great deal of complexity. Here are the problems:
> 1) The signature needs to be stored somewhere. Who stores it if it's not
> the Signer itself? What if it gets lost? (If the Signer stores its own
> signature, then the scheme is no longer stateless. You might as well store
> the full descriptor).
>

In the flow I describe above, the desktop wallet would indeed store the
signed descriptor record and wallet metadata. So yes, the *Signer* as in *the
party in the protocol* stores it, but not the signing device*. *The same
method could be used to store state temporarily between round 1 and 2,
where the only *state* on the hardware wallet would be the TOKEN, while
everything else is stored (encrypted and signed) on the Signer's desktop.


> 2) When the signature is "played back" to the Signer, a copy of the
> original descriptor must be included. Who stores the descriptor? What if it
> gets lost? This is an under-appreciated aspect of the stateful approach:
> every participant in the multisig has a full copy of the original contract,
> which adds resilience to the wallet backup / recovery process.
>

"Playing back" the signature and wallet's setup data to the hardware wallet
would indeed happen transparently from the Signer's wallet software. If the
Signer lost this data due to malware, faulty hardware, etc., the user would
indeed have to recover from backup, which seems ok to me.


> 3) Because the full descriptor must be "played back" for every single
> transaction, this means every detail of the contract must be shared again
> and again, indefinitely. Not only does this add overhead (engineering and
> cognitive) to the spending process, it has massive privacy implications,
> since the descriptor contains everything you need to know about the wallets
> and its participants.
>

I agree with some of these concerns, but I observe:
- The engineering overhead in handling externally-stored-signed-data is
paid once, and would mostly fall on the hardware wallet vendor. External
software only cares about storing certain data and sending it back later.
- Storing xpubs/descriptors in the desktop software that interacts with
the HWW is already common practice, and necessary for using any watch-only
wallet.

Summarizing, I argue that the stateful/stateless characteristic of a
hardware wallet does not really affect (modulo some extra work) the ability
to participate in the BSMS ceremony, whose *Signers* should indeed be
stateful.
Some more clarifications on the trust assumptions might help at clarifying
the best possible software/hardware implementation tradeoffs, either in
this or a follow-up BIP.

Best,
Salvatore Ingala

[-- Attachment #2: Type: text/html, Size: 8793 bytes --]

 permalink raw reply	[|nested]
2021-04-12 15:03       ` Salvatore Ingala

  2021-04-12 18:45         ` Christopher Allen
  
From: Hugo Nguyen @ 2021-04-12 17:55 UTC (permalink / raw)
  To: Salvatore Ingala;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3902 bytes --]

Hello Salvatore,

On Mon, Apr 12, 2021 at 8:03 AM Salvatore Ingala <salvatore.ingala@gmail•com>
wrote:

> Hi Hugo,
>
> First of all, thank you for the impressive work on leading the
> standardization efforts!
>
> I believe one ought to more clearly distinguish the "Signer" (as in: one
> of the parties in the multisig setup), from the "*Signing device*" (which
> is likely a hardware wallet).
>

Actually, in the current spec, a "Signer" is *any software/hardware that
possesses the private keys and can sign using those keys* -- it doesn't
have to be hardware. "Signer" does not mean the human user. I will clarify
the definition and clear up any ambiguous language in the spec. Thanks for
bringing this to my attention!


> BSMS defines a "Signer" as "a participating member in the multisig",
> therefore a person/entity who is likely using both a hardware wallet and
> some BSMS-friendly software wallet (e.g. the next version of Specter
> Desktop).
>

As mentioned above, "Signer" does not refer to the user or any entity that
does not have the private keys / signing capability.


> It is therefore relevant to discuss which parts of the BSMS mechanism are
> implemented in the Signer's software wallet, and which should be in the
> Signer's hardware wallet.
> From the discussion, it appears to me that different people might have
> different expectations on what the signing device/HWW should do, so I would
> like to comment on this point specifically (while I reckon that it mostly
> falls within the realm of concerns #4 and #5 of the motivation paragraph,
> which are explicitly left out of scope).
>
> I fully agree that a *Signer* must persist the full wallet's description,
> and should also create physical backups which include the full descriptor
> and the cosigner's information. I would disagree, however, if any standards
> were to force *hardware wallets* to persist any substantial amount of
> state other than the seed, as I believe that it gives no substantial
> advantage over externally stored signed data for many use cases.
>
> The following is the *wallet registration flow* I am currently working on
> (in the context of adding support to multisig wallets at Ledger). The goal
> is to allow a *Signer* (the person) to persist a multisig setup in its
> storage, while achieving a similar level of security you would have if you
> were storing it on the hardware wallet itself (note that the following flow
> would happen as part of Round 2):
>
> 1) The desktop wallet of the requests the HWW to register a new multisig
> wallet. The request includes the full multisig wallet description, and some
> extra metadata (e.g.: a name to be associated to this multisig wallet).
> 2) The HWW validates the wallet and verifies it with the user with the
> trusted screen (as per BSMS Round 2); on confirmation, it returns a wallet
> id (which is a vendor-specific hash of all the wallet description +
> metadata) and signature
> 3) The desktop wallet stores the full wallet description/id/signature.
> (Optionally, a backup could be stored elsewhere).
>

> Whenever an operation related to the multisig wallet is required
> (verifying a receiving address, or signing a spending transaction), the HWW
> first receives and verifies all the data stored at step 3 above (without
> any user interaction). Then it proceeds exactly the same way as if it had
> always stored the multisig wallet in their own storage.
>

Now that we're clear on definitions, then it should become obvious that
redefining the "Coordinator-Signer" pair as "a Signer" does not address the
underlying problem. (What you call "the desktop wallet" here is a
Coordinator, not a Signer).

As long as the Signer does not own up the task of storing the wallet
configuration, it must rely indefinitely on others for critical data when
working in a multisig wallet, as I have explained in my last email.

Best,
Hugo


>

[-- Attachment #2: Type: text/html, Size: 5255 bytes --]

 permalink raw reply	[|nested]
2021-04-12 15:03       ` Salvatore Ingala
  2021-04-12 17:55         ` Hugo Nguyen

  2021-04-12 20:43           ` Robert Spigler
  
From: Christopher Allen @ 2021-04-12 18:45 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4478 bytes --]

Though I am ACK on that we need to solve the problem of xpub privacy and
reuse, I'm NACK on this solution. It is currently too complex and doesn't
really solve the problem.

I believe that the ultimate solution will be some form of multi-round
cryptographic commitment scheme, and as musig threshold signatures with
Taproot/Schnoor also require multi-round scheme, we should start thinking
now about how maybe we can leverage that work to address this problem as
well. However, I'm not a cryptographer and don't have a specific solution
in this area to offer.

In the meantime, there are some possible measures we can take as new best
practices. This is not a formal list, and I'm open to other suggestions,
but each are currently relatively easy and are functional with some
existing wallets that CAN support state. Let us get it right with stateful
wallets, then we can return back to better best practices for stateless
wallets like Trezor, Ledger, etc.

A) We should accept that users must to backup their multisig account maps
(descriptor with only xpubs) along with their cosigner key material to be
able to recover funds. In the Airgap Community we make this very easy with
a simple UR code that works efficiently as a QR. I personally keep multiple
copies of this account map in multiple locations, as it is less of a risk
(mostly privacy) if one of the locations is compromised.

B) Cosigner wallets and transaction coordinator services should not share
the master xpub, only the derived co-signer xpubs required for that
specific account. Currently too many libraries, wallets and coordinators
only function if they get the master xpub — these should be updated to not
require them.

C) In many current wallets, the master xpub fingerprint is required — that
master fingerprint is also a privacy risk and should not be used. For
instance, the current practice of offering what the Airgap Community calls
a `crypto-hdkey` [604b93f2/48'/1'/0'/2'] with the master fingerprint root,
could instead be to only offer a single parent fingerprint [f93749a7/2']
from that grandparent master key. Thus different fingerprints can be
offered for each account, and only the signer knows the actual master
fingerprint and its children.

D) Given C, when creating a new multisig account, a transaction coordinator
may request a specific master fingerprint and/or a fixed 48' derivation
xpub from a cosigner wallet, but these are only hints. If it gets back a
different fingerprint or derivation, it should accept it. In the case of
the Airgap Community's specifications, in our "crypto-request" we actually
specifically allow for wildcard requests which makes this easy and
explicit. Yes, only stateful signers can know to return an xpub something
other than the fingerprint  and m/48'/1'/0'/2' default, but a transaction
coordinator should accept it if it receives it.

E) Transaction coordinators should send the cosigner "policy" (basically
the multisign descriptor without any keys in it) along with any request to
derive a new xpub for that new account. Stateful wallets can use this
policy to know later if they are asked to sign a PSBT that does not match
this policy.

F) Transaction coordinators should also send the final "account map" to all
the cosigner wallets as a best practice as well. This would replace the
temporary "policy" in D. If a PSBT request to sign using a key doesn't
match the original account map, the cosigner wallet can reject it.

These best practices don't solve the problem with stateless wallets like
Trezor, but they are possible now with the new generation of multisig
hardware and software wallets, such as Foundation Devices, CoboVault,
Sparrow, Bluwallet and my Gordian reference wallet tools. We have available
NOW working interoperable specifications, reference code, and example apps
that support these best practices, and some are already supported by
multiple wallets in the Airgapped Wallet Community hosted by Blockchain
Commons at https://github.com/blockchainCommons/airgapped-Wallet-Community.

I've put a copy of this rough proposal in our Airgapped Wallet Community
discussion area if you have suggestions or alternative best practices.

[Initial proposal for best practice to avoid XPUB reuse in multisig account
creation](
https://github.com/BlockchainCommons/Airgapped-Wallet-Community/discussions/53
)

-- Christopher Allen, Blockchain Commons

[-- Attachment #2: Type: text/html, Size: 5380 bytes --]

 permalink raw reply	[|nested]
2021-04-12 18:45         ` Christopher Allen

  
From: Robert Spigler @ 2021-04-12 20:43 UTC (permalink / raw)
  To: Christopher Allen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 6107 bytes --]

I don't quite understand your NACK.

The following are measures you say we should take as best practices, which I believe are all implemented:

>A) We should accept that users must to backup their multisig account maps (descriptor with only xpubs) along with their cosigner key material to be able to recover funds.

BSMS requires that the descriptor persist in storage and be able to be displayed when requested by the user. It is already industry standard that the same apply to cosigner key material. Backing up both is good practice. (My BIP for a new key hierarchy enforces this as well (https://github.com/bitcoin/bips/pull/1089))

>B) Cosigner wallets and transaction coordinator services should not share the master xpub
Again, check out my updated hierarchy for multisignature wallets, which enforces this and works very well with BSMS.

>C) In many current wallets, the master xpub fingerprint is required
I am confused by this - the descriptor language standardizes the master xpub fingerprint in the key origin information?

>E) Transaction coordinators should send the cosigner "policy"
There is no cosigner "policy" in this standard, but the same checks are implemented (N unique key records, key is included in descriptor, plus valid MAC, valid signatures, valid checksum, etc).

>F) Transaction coordinators should also send the final "account map" to all the cosigner wallets
This is done

Robert Spigler

Personal Fingerprint: BF0D 3C08 A439 5AC6 11C1 5395 B70B 4A77 F850 548F

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Monday, April 12, 2021 2:45 PM, Christopher Allen via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:

> Though I am ACK on that we need to solve the problem of xpub privacy and reuse, I'm NACK on this solution. It is currently too complex and doesn't really solve the problem.
>
> I believe that the ultimate solution will be some form of multi-round cryptographic commitment scheme, and as musig threshold signatures with Taproot/Schnoor also require multi-round scheme, we should start thinking now about how maybe we can leverage that work to address this problem as well. However, I'm not a cryptographer and don't have a specific solution in this area to offer.
>
> In the meantime, there are some possible measures we can take as new best practices. This is not a formal list, and I'm open to other suggestions, but each are currently relatively easy and are functional with some existing wallets that CAN support state. Let us get it right with stateful wallets, then we can return back to better best practices for stateless wallets like Trezor, Ledger, etc.
>
> A) We should accept that users must to backup their multisig account maps (descriptor with only xpubs) along with their cosigner key material to be able to recover funds. In the Airgap Community we make this very easy with a simple UR code that works efficiently as a QR. I personally keep multiple copies of this account map in multiple locations, as it is less of a risk (mostly privacy) if one of the locations is compromised.
>
> B) Cosigner wallets and transaction coordinator services should not share the master xpub, only the derived co-signer xpubs required for that specific account. Currently too many libraries, wallets and coordinators only function if they get the master xpub — these should be updated to not require them.
>
> C) In many current wallets, the master xpub fingerprint is required — that master fingerprint is also a privacy risk and should not be used. For instance, the current practice of offering what the Airgap Community calls a `crypto-hdkey` [604b93f2/48'/1'/0'/2'] with the master fingerprint root, could instead be to only offer a single parent fingerprint [f93749a7/2'] from that grandparent master key. Thus different fingerprints can be offered for each account, and only the signer knows the actual master fingerprint and its children.
>
> D) Given C, when creating a new multisig account, a transaction coordinator may request a specific master fingerprint and/or a fixed 48' derivation xpub from a cosigner wallet, but these are only hints. If it gets back a different fingerprint or derivation, it should accept it. In the case of the Airgap Community's specifications, in our "crypto-request" we actually specifically allow for wildcard requests which makes this easy and explicit. Yes, only stateful signers can know to return an xpub something other than the fingerprint and m/48'/1'/0'/2' default, but a transaction coordinator should accept it if it receives it.
>
> E) Transaction coordinators should send the cosigner "policy" (basically the multisign descriptor without any keys in it) along with any request to derive a new xpub for that new account. Stateful wallets can use this policy to know later if they are asked to sign a PSBT that does not match this policy.
>
> F) Transaction coordinators should also send the final "account map" to all the cosigner wallets as a best practice as well. This would replace the temporary "policy" in D. If a PSBT request to sign using a key doesn't match the original account map, the cosigner wallet can reject it.
>
> These best practices don't solve the problem with stateless wallets like Trezor, but they are possible now with the new generation of multisig hardware and software wallets, such as Foundation Devices, CoboVault, Sparrow, Bluwallet and my Gordian reference wallet tools. We have available NOW working interoperable specifications, reference code, and example apps that support these best practices, and some are already supported by multiple wallets in the Airgapped Wallet Community hosted by Blockchain Commons at https://github.com/blockchainCommons/airgapped-Wallet-Community.
>
> I've put a copy of this rough proposal in our Airgapped Wallet Community discussion area if you have suggestions or alternative best practices.
>
> [Initial proposal for best practice to avoid XPUB reuse in multisig account creation](https://github.com/BlockchainCommons/Airgapped-Wallet-Community/discussions/53)
>
> -- Christopher Allen, Blockchain Commons

[-- Attachment #2: Type: text/html, Size: 7694 bytes --]

 permalink raw reply	[|nested]