text:
[DRAFT] BIP: Bitcoin Secure Multisig Setup (BSMS)

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.

Descriptor checksum cannot be used because the participant does not know it beforehand. What can be used instead is the fingerprint of the 'policy map' like wsh(sortedmulti(1,,,)) as Christopher Allen mentioned in his email (https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-February/018404.html).
When the descriptors are extended with miniscript, the position of the key becomes significant, as for example, in wsh(or(multi(2, <Alice>, <Bob>, <Carol>), older(1000, <Dylan>)), the Dylan position is privileged, as he will gain access to funds after timeout, if any two of (Alice, Bob, Carol) are prevented from spending the funds before timeout. If Dylan just checks that its xpub is in the descriptor, but the descriptor contains xpubs as per wsh(or(multi(2, <Alice>, <Bob>, <Dylan>), older(1000, <Carol>)), then Carol becomes the privileged party.
The position can be checked via a fingerprint of a policy map extended with position: wsh(or(multi(2,,,), older(1000,K)) where "K" denotes the position of the participant. A fingerprint of this policy map can be communicated along with TOKEN to the participant, who can then visually check the fingerprint, and the extended policy map. The signer device, upon finding its xpub in the descriptor provided by the coordinator, can create this extended policy map by removing other xpubs and replacing its own xpub with "K".

I feel this draft is missing (at least) two things:

each signer should be able to provide it's own description (e.g. "Stick's Trezor") which will be signed by the signer
the proposal should define a "multisig descriptor" - essentially a structure which contains all the collected answers and defines the multisig members (including descriptions, etc.) - plus points if this structure is standardized (e.g. as a protobuf structure), because then this structure could be saved as a file and transfered from one multisig wallet to another (i.e. it would be possible to setup multisig using multisig wallet A, but later this file will allow the migration to multisig wallet B with no hassle) - of course the signers are welcome to store this data inside of their storages, but it should be possible to recover these from the host in case the signer's storage is wiped (and the seed restored via the mnemonic).

Love this! Thanks for doing this @hugohn et al.
Some notes/comments/questions:

Why was #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses) determined out of scope?
For example, if multisig configuration is correct/not tampered with (1), and persists in storage (2), yet is not properly used to generate and verify receive/change addresses, the addresses could be owned by an attacker. I don't believe this is a comprehensive secure multisig standard without #4.

Should BIP174 (PSBTs) also be a prerequisite, in addition to BIP32 and descriptors?

I'm really glad you've added an encryption/authentication scheme! I like that there can be one token for all Signers or one per Signer.

Also very cool that the user or signer can choose the derivation path.  Great comment on avoiding reusing XPUBs.  Maybe I'm misunderstanding this, (I see continued discussion on this on bitcoin-dev) but I believe you said the token could double as a session ID and could solve this issue? If not, I agree solving the XPUB issue should be a separate BIP as to not stall this.

Under Round 2: Coordinator (it's probably assumed), but protocol should also abort if there hasn't been N distinct key records (with valid sigs) received (no more or less).

I am not a cryptographer, but is encryption (instead of a signature) being used to verify integrity of the descriptor? (from coordinator -> signers).

If all checks pass, the Signer persists the descriptor record in its storage.

Maybe make this language stronger? For example, "Signer must persist the descriptor...", or "if not, protocol aborts."  I agree with your opinion on the mailing list that lack of support on some devices shouldn't prevent us from setting a good standard here and that this is crucial.

The Signer should subsequently use the descriptor to generate and verify receive and change addresses.

Is this not #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses).

Some other checks that should possibly occur at the address level:
Keypath restrictions to prevent ransom attacks
Receive/change addresses encodes hash of an ordinary multisig redeem script with no other spending conditions

I agree with @prusnak 's concern with converting the token to BIP39 mnemonic.  Decimal number and QR code sounds great to me.

Glad to see BlockchainCommon's 2020-005 QR standard in here as well.  They also have a C++ reference implementation here:  https://github.com/BlockchainCommons/bc-ur

I see you link to the BRC-2020-015 research as well. That's for when the signer starts the process, not the coordinator. The co-signers send an array of descriptors for all script types for the coordinator to select the correct one.  I think it'd be great for a comprehensive protocol to allow either the coordinator or co-signers to start the process; however, it does make use of 'BIP'48 which I know @hugohn has also complained about, especially because descriptors take care of this.

@dgpv

Descriptor checksum cannot....When the descriptors are extended with miniscript, the position of the key becomes significant

Visual inspection of the entire descriptor and comparing descriptor checksums should work, which I believe is what is recommended.

@prusnak Does this (https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#multisig) not meet your second point? Or could be expanded to do so?

I feel this draft is missing (at least) two things:

each signer should be able to provide it's own description (e.g. "Stick's Trezor") which will be signed by the signer

👍 we can add a label field in the key record.

the proposal should define a "multisig descriptor" - essentially a structure which contains all the collected answers and defines the multisig members (including descriptions, etc.) - plus points if this structure is standardized (e.g. as a protobuf structure), because then this structure could be saved as a file and transfered from one multisig wallet to another (i.e. it would be possible to setup multisig using multisig wallet A, but later this file will allow the migration to multisig wallet B with no hassle) - of course the signers are welcome to store this data inside of their storages, but it should be possible to recover these from the host in case the signer's storage is wiped (and the seed restored via the mnemonic).

The descriptor language was created precisely for this purpose, unless I'm missing something here? It defines the multisig script and the members of the multisig in an interoperable, vendor-agnostic format (plus a checksum) that could readily be exported into another wallet. @prusnak

@Rspigler

Visual inspection of the entire descriptor and comparing descriptor checksums should work, which I believe is what is recommended.

The idea with fingerprints vs checksums is that you can transfer the fingerprint at the beginning of the setup, along with token. The checksum is only transferred when all xpubs are known. The checksum can be used to automatically check that the descriptor is not altered, but cannot be used as a quick way to visually check that the structure of the descriptor did not change from the time of the beginning of the setup. Maybe this is not that important, though. Maybe more important for visual check is to show the 'policy map with position' like wsh(or(multi(2,_,_,_), older(1000,K)) to the user, so the visual inspection won't be hindered by all the xpubs

Ok it should probably motivate it(maybe I missed it)
On Tue, Feb 16, 2021, 5:15 PM Dmitry Petukhov notifications@github.com
wrote:

@dgpv commented on this pull request.
In bsms.mediawiki
https://github.com/nunchuk-io/bips/pull/1#discussion_r576662343:

+* 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 (M and N).
+* 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 TOKEN to each Signer over a secure channel. The Signer can use the TOKEN to derive an ENCRYPTION_KEY. Refer to the Encryption section below for details on the TOKEN, the key derivation function and the encryption scheme. Depending on the use case, the Coordinator can decide whether to share one common TOKEN for all Signers, or to have one per Signer.
+* If encryption is disabled, TOKEN is set to 0, and all the encryption/decryption steps below can be skipped.

+=====Signer=====
+
+* The Signer initiates a new secure multisig setup session by setting the TOKEN. The Signer derives an ENCRYPTION_KEY from the TOKEN. The Signer can keep the session open until a different value for the TOKEN 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 TOKEN. The second line must be the KEY. The KEY is an XPUB plus its key origin information, written in the descriptor-defined format, i.e.: [{master key fingerprint}/{derivation path}]{XPUB}. The third line must be a SIG, whereas SIG 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 ENCRYPTION_KEY.
+
+====Round 2====
+
+=====Coordinator=====
+
+* The Coordinator gathers key records from all participating Signers. Abort the setup if the wallet setup session has expired.
timeout allows the encryption key to have lower entropy
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/nunchuk-io/bips/pull/1#discussion_r576662343, or
unsubscribe
https://github.com/notifications/unsubscribe-auth/ABMAFU2F6NCQ3UI3EKQ6QELS7IZTVANCNFSM4XUICRUA
.

Thanks everyone! Lots of good stuff here. I'll take some time to parse through the comments.

The descriptor language was created precisely for this purpose,

@hugohn the descriptor language does not contain label fields or does it?

The descriptor language was created precisely for this purpose,

@hugohn the descriptor language does not contain label fields or does it?

@prusnak yeah maybe that's the only thing missing from your list. I'd argue it's a good thing though because what descriptors capture are 100% on-chain stuff. Labels are off-chain data that don't have meaning outside of where they are used.

@Rspigler As mentioned above - the descriptor language does not contain labels. It could be expanded to something like this, however:
sh(multi(2,{Alice}022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,{Bob}03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe))

or
wsh(sortedmulti(1,{Alice}xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,{Bob}xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*))

I am not a cryptographer, but is encryption (instead of a signature) being used to verify integrity of the descriptor? (from coordinator -> signers).

In short, privacy benefits. Encryption helps prevent XPUBs from being leaked during the setup. This is another improvement over the status quo, on top of the security improvements.
@Rspigler (I'll get to your other comments, but this one stands out and a great question.)

Thanks for your proposal!
I only read the maling list thread briefly, so apologies if this has already been asked: are there any plans to support more complex descriptor other than just multisig?
Also, another thing I don't think has been mentioned anywhere: I also had a similar idea a while back, with a coordinator and some "participants" that would interact with it to build a descriptor. In my idea there were also participants with no keys, meaning that they would see all the public keys but do not provide any keys of their own.
It would be basically like giving "read-only" access to other people, which I thought would be pretty cool and useful in some environments, for instance to audit the process and to then monitor the addresses of the descriptor.
Does this make sense to anybody else? Would this be worth adding to this BIP?
Thanks!

are there any plans to support more complex descriptor other than just multisig?

Might be better to deal with it in a separate BIP, because this adds complexity (relevant comments here: https://github.com/nunchuk-io/bips/pull/1#issuecomment-779158449 and https://github.com/nunchuk-io/bips/pull/1#discussion_r577410600)

In my idea there were also participants with no keys, meaning that they would see all the public keys but do not provide any keys of their own.

A coordinator can implement this without contradicting this BIP. My understanding is that this BIP is mostly concerned with the compatibility of different signer devices, and Coordinator is presumed a very flexible role. After receiving xpubs from participants, the Coordinator can share the complete descriptor with other interested parties.

Hi @afilini !

Thanks for your proposal!
I only read the maling list thread briefly, so apologies if this has already been asked: are there any plans to support more complex descriptor other than just multisig?

Yes, in theory you can put any arbitrary MPC script in the descriptor. As long the Signers can interpret the descriptor (to generate addresses and to construct the spending script/new type of signature such as Schnorr), this scheme would work as-is.
One challenge with more complex scripts is that the order of the XPUBs might matter, so you'd have to perform additional checks when registering the descriptor. See @dgpv 's comment above.
https://github.com/nunchuk-io/bips/pull/1#issuecomment-779158449

Also, another thing I don't think has been mentioned anywhere: I also had a similar idea a while back, with a coordinator and some "participants" that would interact with it to build a descriptor. In my idea there were also participants with no keys, meaning that they would see all the public keys but do not provide any keys of their own.
It would be basically like giving "read-only" access to other people, which I thought would be pretty cool and useful in some environments, for instance to audit the process and to then monitor the addresses of the descriptor.
Does this make sense to anybody else? Would this be worth adding to this BIP?

That's an interesting idea. Although I don't think you could enforce "read-only" with the current scheme. Anyone who have the TOKEN can potentially modify the descriptor.
For something like "read-only" to work, I think you'd need to have all participants share their public keys prior to the setup. Mark the participants with write privileges by their keys, and all submissions need to be signed. I think that might be a bit too much for this proposal.

Thanks!

Anyone who have the TOKEN can potentially modify the descriptor.

That's up to Coordinator. If Coordinator have one TOKEN per participant, it can decide which one has the 'write' privilege (discard any changes from those without privilege). Or Coordinator can have read-TOKEN and write-TOKEN, and give the former to 'spectators' and later to 'signers'. Or simply distribute the finalized descriptor out-of-band, via conventional channels. If the descriptor is needed for monitoring, why would anyone want to enter it on hww or airgapped device ? Most likely it will be entered into some online system, there's only risk to privacy rather than to the funds, so there's probably no need to use the scheme with TOKENs at all.

That's up to Coordinator. If Coordinator have one TOKEN per participant, it can decide which one has the 'write' privilege (discard any changes from those without privilege). Or Coordinator can have read-TOKEN and write-TOKEN, and give the former to 'spectators' and later to 'signers'.

Good point. I totally forgot we can have one TOKEN per signer now :) Yeah so in that case, it's up to the Coordinator software.

Yes, descriptor is simplest method for watch-only.  No reason to complicate that.  However, this also creates an issue that some users have brought up, where no matter the M of N to spend, it is always 1 of N to view transaction history and balance.
This isn't an issue in the case of a multi-party cooperative multisig, but is a serious issue in the case of a single user multisig where the 'co-signers' are stored with other parties.
See here for an explanation and proposed solution.  Probably feature creep and should be a separate BIP.
Also see @prusnak proposal to add ranges to Descriptors: https://github.com/bitcoin/bitcoin/issues/21199

Love this! Thanks for doing this @hugohn et al.
Some notes/comments/questions:

Why was #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses) determined out of scope?
For example, if multisig configuration is correct/not tampered with (1), and persists in storage (2), yet is not properly used to generate and verify receive/change addresses, the addresses could be owned by an attacker. I don't believe this is a comprehensive secure multisig standard without #4.

Should BIP174 (PSBTs) also be a prerequisite, in addition to BIP32 and descriptors?

I'm really glad you've added an encryption/authentication scheme! I like that there can be one token for all Signers or one per Signer.

Also very cool that the user or signer can choose the derivation path.  Great comment on avoiding reusing XPUBs.  Maybe I'm misunderstanding this, (I see continued discussion on this on bitcoin-dev) but I believe you said the token could double as a session ID and could solve this issue? If not, I agree solving the XPUB issue should be a separate BIP as to not stall this.

Under Round 2: Coordinator (it's probably assumed), but protocol should also abort if there hasn't been N distinct key records (with valid sigs) received (no more or less).

I am not a cryptographer, but is encryption (instead of a signature) being used to verify integrity of the descriptor? (from coordinator -> signers).

If all checks pass, the Signer persists the descriptor record in its storage.

Maybe make this language stronger? For example, "Signer must persist the descriptor...", or "if not, abort the setup."  I agree with your opinion on the mailing list that lack of support on some devices shouldn't prevent us from setting a good standard here and that this is crucial.

The Signer should subsequently use the descriptor to generate and verify receive and change addresses.

Is this not #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses).

Some other checks that should possibly occur at the address level:
Keypath restrictions to prevent ransom attacks
Receive/change addresses encodes hash of an ordinary multisig redeem script with no other spending conditions

I agree with @prusnak 's concern with converting the token to BIP39 mnemonic.  Decimal number and QR code sounds great to me.

Glad to see BlockchainCommon's 2020-005 QR standard in here as well.

I see you link to the BRC-2020-015 research as well. That's for when the signer starts the process, not the coordinator. The co-signers send an array of descriptors for all script types for the coordinator to select the correct one.  I think it'd be great for a comprehensive protocol to allow either the coordinator or co-signers to start the process; however, it does make use of 'BIP'48 which I know @hugohn has also complained about, especially because descriptors take care of this.

@dgpv

Descriptor checksum cannot be used....When the descriptors are extended with miniscript, the position of the key becomes significant

Visual inspection of the entire descriptor and comparing descriptor checksums should work, which I believe is what is recommended.

@prusnak Does this (https://github.com/bitcoin/bitcoin/blob/master/doc/descriptors.md#multisig) not meet your second point? Or could be expanded to do so?

#1

#1

#1

Yes, descriptor is simplest method for watch-only.  No reason to complicate that.  However, this also creates an issue that some users have brought up, where no matter the M of N to spend, it is always 1 of N to view transaction history and balance.
This isn't an issue in the case of a multi-party cooperative multisig, but is a serious issue in the case of a single user multisig where the 'co-signers' are stored with other parties.
See here for an explanation and proposed solution.  Probably feature creep and should be a separate BIP.
Also see @prusnak proposal to add ranges to Descriptors: https://github.com/bitcoin/bitcoin/issues/21199

Updated BIP to address some of the comments above. Pending items:

Wondering if we should add labels to the key records, despite labels not being a part of the descriptor language yet? cc @prusnak
Encryption to be fleshed out further

@dgpv @prusnak @Rspigler BIP updated https://github.com/nunchuk-io/bips/commit/1577802b99b0cb33776720045f68f3ae4ef18aa3

Fleshed out the encryption scheme. @dgpv I've left out authentication for now. We can ask security experts for further feedback and whether a MAC is needed (basically upgrading from AES-CTR to AES-GCM).
Added labels to the key record - they can be easily added to the descriptor record once the language starts supporting them
Some minor edits

I like most (if not all) of the changes.  Just still have some original questions unanswered from here: https://github.com/nunchuk-io/bips/pull/1#issuecomment-779488535

Why was #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses) determined out of scope?

This is now #5.  This seems to be contradicted. Line 35/41 says that it is out of scope, while Line 94 says otherwise.

Should BIP174 (PSBTs) also be a prerequisite, in addition to BIP32 and descriptors?

Great comment on avoiding reusing XPUBs. Maybe I'm misunderstanding this, (I see continued discussion on this on bitcoin-dev) but I believe you said the token could double as a session ID and could solve this issue? If not, I agree solving the XPUB issue should be a separate BIP as to not stall this.

Under Round 2: Coordinator (it's probably assumed), but protocol should also abort if there hasn't been N distinct key records (with valid sigs) received (no more or less).

I see this has been added in commit da9f1546834bc596585dfbfdc814bbee9d69f352

If all checks pass, the Signer persists the descriptor record in its storage.
Maybe make this language stronger?

I see this was also added in commit da9f1546834bc596585dfbfdc814bbee9d69f352

Some other checks that should possibly occur at the address level:
Keypath restrictions to prevent ransom attacks
Receive/change addresses encodes hash of an ordinary multisig redeem script with no other spending conditions

I see you link to the BRC-2020-015 research as well. That's for when the signer starts the process, not the coordinator. The co-signers send an array of descriptors for all script types for the coordinator to select the correct one. I think it'd be great for a comprehensive protocol to allow either the coordinator or co-signers to start the process; however, it does make use of 'BIP'48 which I know @hugohn has also complained about, especially because descriptors take care of this.

I have serious concerns about BIP48
Besides the above, ACK changes made in commit 4373dd7d1f635376d35691445f35202c60c30ec1, commit 9c18c8569e58961762df5f02a9391c613ff98949, commit 1577802b99b0cb33776720045f68f3ae4ef18aa3 [except for debate around authentication, encryption specifics, etc - I am not a cryptographer], and commit da9f1546834bc596585dfbfdc814bbee9d69f352.

Thanks @Rspigler .

I like most (if not all) of the changes. Just still have some original questions unanswered from here: #1 (comment)

Why was #4 (Whether Signer subsequently uses the multisig configuration to generate and verify receive/change addresses) determined out of scope?

This is now #5. This seems to be contradicted. Line 35/41 says that it is out of scope, while Line 94 says otherwise.

I think this is fine. By saying "out of scope" what we mean is that we don't define how exactly this is achieved, it is only a recommendation. It is similar to the recommendation that HWWs should avoid XPUB reuse, without specifying the how.

Should BIP174 (PSBTs) also be a prerequisite, in addition to BIP32 and descriptors?

I don't think so because this BIP is strictly about setting up multisig wallets. This process must happen first before transacting can happen. If anything, it's actually the opposite: PSBT should list this as a pre-requisite :-)

Great comment on avoiding reusing XPUBs. Maybe I'm misunderstanding this, (I see continued discussion on this on bitcoin-dev) but I believe you said the token could double as a session ID and could solve this issue? If not, I agree solving the XPUB issue should be a separate BIP as to not stall this.

As mentioned above, we only offer a recommendation here as far as XPUB reuse is concerned, and not the how. I think it is out of scope.

Under Round 2: Coordinator (it's probably assumed), but protocol should also abort if there hasn't been N distinct key records (with valid sigs) received (no more or less).

I see this has been added in commit da9f154

If all checks pass, the Signer persists the descriptor record in its storage.

Maybe make this language stronger?

I see this was also added in commit da9f154

Some other checks that should possibly occur at the address level:
Keypath restrictions to prevent ransom attacks
Receive/change addresses encodes hash of an ordinary multisig redeem script with no other spending conditions

I see you link to the BRC-2020-015 research as well. That's for when the signer starts the process, not the coordinator. The co-signers send an array of descriptors for all script types for the coordinator to select the correct one. I think it'd be great for a comprehensive protocol to allow either the coordinator or co-signers to start the process; however, it does make use of 'BIP'48 which I know @hugohn has also complained about, especially because descriptors take care of this.

I have serious concerns about BIP48

I do think BIP48 is made redundant with the invention/adoption of output descriptors, but again I think this is out of scope. Unfortunately we can't solve everything at once here :-(

Besides the above, ACK changes made in commit 4373dd7, commit 9c18c85, commit 1577802 [except for debate around authentication, encryption specifics, etc - I am not a cryptographer], and commit da9f154.

I think this is fine. By saying "out of scope" what we mean is that we don't define how exactly this is achieved, it is only a recommendation. It is similar to the recommendation that HWWs should avoid XPUB reuse, without specifying the how.

Added nit here that I think clarifies.  https://github.com/nunchuk-io/bips/pull/1#discussion_r584234539
Just commenting for my own notes and so I don't forget.  Perhaps a standard will be needed for 'Secure Multisig Flow' after this Setup is complete, that covers how to best handle

BIP174 (PSBTs)
reusing XPUBs
Some other checks that should possibly occur at the address level:
Keypath restrictions to prevent ransom attacks
Receive/change addresses encodes hash of an ordinary multisig redeem script with no other spending conditions
BIP48

Researched changes in crypto, so light concept ACK there. Glad authenticated encryption is being used now.
ACK most recent commits: 71d7745df79180a7de80446ef1b274523fdd3271 and 709d5886e001f0d0137d0e27fde51df295a22274, except for dgpv's suggested changes, which I will review when done.

Updated https://github.com/nunchuk-io/bips/pull/1/commits/8316c2424cbfe716b658b4c17c1633d163b94612

Clarify MAC / IV usage
I removed the "Abort the setup if there are any KEY duplicates" line because it occurred to me with Taproot and complex scripts, one can have the same XPUB in different taproot branches. HWWs should still check for duplicates for basic multisig, but we probably should leave this out of the spec.
Minor edits

I believe most comments have been addressed. The main one pending is:

Encoding format for TOKEN / MAC

Grammar fix: https://github.com/nunchuk-io/bips/pull/1/commits/987c0093145e00b8982adad0920d10219242bd16

Added encoding for TOKEN and MAC: https://github.com/nunchuk-io/bips/pull/1/commits/b9c73f2ebffcf72933ed7d1fc45b4d14b5228e48 .

Hex. Please. For all the reasons you give above.

I'm also leaning towards hex as the encoding format. Seems like the pros are worth a few extra bytes here.

The key derivation function is PBKDF2, with PRF = SHA512. Specifically:
DK = PBKDF2(PRF, Password, Salt, c, dkLen)

@prusnak @peter-conalgo what do you guys think about using SHA256 as the PRF for PBKDF2 key derivation? Do Trezor/Coldcard support it?

Pro of using SHA512 as PRF: we can reuse BIP39 code.
Prof of using SHA256 as PRF: more consistent with the rest of the scheme proposed here, which is all 256-bit.

@hugohn If a system supports PBKDF2-SHA512 it is trivial to modify it to support PBKDF2-SHA256 - it's just a matter of switching the PRF. Using SHA256 has also the advantage of being not as much faster on 64-bit processors, while SHA512 performs better on 64-bit processors than on 32-bit processors. In another word, if sha256 is K-times faster on 64-bit than on 32-bit processor then sha512 is around 2K-4K -times faster on 64-bit processor vs 32-bit processor. So we are losing around 1-2 bits of protection against brute-force when using sha512 instead of sha256.

Thanks @prusnak. Agreed with your analysis. Waiting to hear from others.
I have also added higher-entropy options for the TOKEN in the EXTENDED mode, just to be future-proof and stronger privacy guarantees.
https://github.com/nunchuk-io/bips/pull/1/commits/d7ee9ef6a41c297019b6325033783c4ef46d0750

I have also added higher-entropy options for the TOKEN in the EXTENDED mode, just to be future-proof and stronger privacy guarantees.

Objection against using 160-bit or 224-bit extended nonce encoded as BIP39 words. The number of words collides with the original usage of BIP39 - the very same reason why we excluded 128-bit and 256-bit nonces in the past.

I have also added higher-entropy options for the TOKEN in the EXTENDED mode, just to be future-proof and stronger privacy guarantees.

Objection against using 160-bit or 224-bit extended nonce encoded as BIP39 words. The number of words collides with the original usage of BIP39 - the very same reason why we excluded 128-bit and 256-bit nonces in the past.

Just to be clear, you are not against a higher number of bits, just the encoding (as BIP39 words), correct? @prusnak

Just to be clear, you are not against a higher number of bits, just the encoding (as BIP39 words), correct?

Right.

Are there wallets in the wild that use 15- or 21- word seeds?

Not sure. There are hundreds of them ...

As I understand, the risk in allowing > 9 words for token is that the wallet key mnemonic could be accidentally used as token mnemonic, with increased risk of leaking the wallet key because handling encryption key mnemonic might have lower security requirements than wallet key mnemonic. The risk stems from the fact that mnemonics will be visually similar. It seems that there's no way to avoid this risk except not using number of words obviously smaller than allowed by BIP39.
You could still take first 9 words of the wallet mnemonic and try to use it for encryption (and may even succeed because there's only 3 bit checksum), but this seems to be a mistake that is much less probable. Still, if we are talking about probability, given that 12 or 24 word is conventional and other lengths are not widespread, we could say that mistake with 15 or 21 words is also not very probable, unless these wordcounts will start to be used more often (which we can't predict).
One way to increase the number of bits while remaining at 9 words is to combine them with digital input. 9 words + 32 bit integer entered as decimal number = 12 bit.
Other option would be to not try to increase the number of bits, because to protect the key for the duration of the setup session, 96 bits seems adequate (for short enough sessions), and the risk is only that the key record or descriptor would be decrypted afterwards, with a loss of privacy.
We could say that privacy-related matters should be handled by upper layers, by conventional encryption. Because if your host (that could additionally encrypt the xpub record for further privacy) is compromised, you're likely have bigger privacy problems and an attacker likely has other means to find out the addresses you are using

Please add a file extension to the spec. It's best if this is standardized at the start. I propose ".bsms" but I'm not married to it.

I'm not clear on the serialization of the data under the encryption. A few examples would solve that. If it's a text file (ie. lines of 'descriptors') then it may be harder to extend this standard later.

ACK commit 987c0093145e00b8982adad0920d10219242bd16, b9c73f2ebffcf72933ed7d1fc45b4d14b5228e48, 7ed617ee107ab718cb46401f85c805f4c1e5921d, 0310218509435e298222211950238b8425315ca5, d7ee9ef6a41c297019b6325033783c4ef46d0750
No comment on hex vs base64
I like the greater entropy options for the EXTENDED mode.  If it is an issue for the BIP39 encoding, we could restrict the encoding for that mode, rather than removing the options for higher bits and negatively effect the security options of implementations.
In commit 7ed617ee107ab718cb46401f85c805f4c1e5921d, why was the change made from (ciphertext || MAC) to (MAC || ciphertext) ?

https://github.com/nunchuk-io/bips/pull/1/commits/99fda08bf52145d0c48a035db4389327f249b083

Corrected IV to be the first 16 bytes of the MAC, as per AES standard
Specify a .bsms extension, as @peter-conalgo suggested

In commit 7ed617e, why was the change made from (ciphertext || MAC) to (MAC || ciphertext) ?

@Rspigler no particular reason. The typical convention AFAIU is to prepend the IV and append the MAC to the data. In our case the MAC doubles as the IV so it doesn't really matter we append or prepend. I thought that prepending it might make it a bit easier to extract the MAC/IV (which are fixed sizes).
I'm still thinking about whether we should / how to accommodate higher entropy options without confusing the users.

I'm not clear on the serialization of the data under the encryption. A few examples would solve that. If it's a text file (ie. lines of 'descriptors') then it may be harder to extend this standard later.

Perhaps adding a VERSION field will be sufficient, in case we want to add to the spec later?
I'm not sure if we need to go all-out with a key-value representation like [https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki BIP-0174] did. It doesn't seem necessary to me, but open to hear otherwise.

ACK commit 99fda08bf52145d0c48a035db4389327f249b083
+1 on VERSION field

Should we add something about what the coordinator should do if signers send key records with different specification versions?
I'm neutral on the descriptor containing the specification version as well.  What is the reason for this?
I agree with @hugohn point #3, especially because I'm not aware of any wallet implementation that uses a 15 word or 21 word mnemomic, although I guess technically one could.  I was just trying to help with @prusnak 's concerns, although I agree it's less clean and prefer what is being proposed.

I prefer pbkdf2_sha512 for KDF since all hardware wallets supporting BIP39 will have it on hand.

Thanks @peter-conalgo.
Given existing widespread support of BIP39, let's stick with pbkdf2_sha512 for key derivation then. As @prusnak pointed out, we might lose 1-2 bits of protection against modern hardware, but compatibility with existing systems seems like a good trade-off to make.

Should we add something about what the coordinator should do if signers send key records with different specification versions?

I'll add a note for the coordinator.

I'm neutral on the descriptor containing the specification version as well. What is the reason for this?

Right now it's not needed, but I included it just to be consistent on both sides.

I agree with @hugohn point #3, especially because I'm not aware of any wallet implementation that uses a 15 word or 21 word mnemomic, although I guess technically one could. I was just trying to help with @prusnak 's concerns, although I agree it's less clean and prefer what is being proposed.

ACK commit 1bf9309f87da9b097952fcc2883173280b7b21ef, edd25285127a8b4059f384531065e6312d1d21db, 3824950d39a4e097f63df353992d8c17cdf15c90, edd42786e3993ef7f0e2436199b2760787791387, 0e8c4f8060e37902e27b577548c0593b4101eae3

ACK commit 47acd15515292afc24b15b5b3ae243795c4fdeab

Updated the Security section https://github.com/nunchuk-io/bips/pull/1/commits/409d96b1e05b49772d547aa6a4f478f29f47adff

This is true even post-setup, and can be done as a periodic check

Why, if the descriptor and checksum is persisted in each signer's storage?
With this change there's a bit of a contradiction.  On line 103/104 we are telling Signers to confirm checksum, M, and N, with each other.  On Line 170-1744, we are telling Signers to independently view checksum, M, and N, and then confirm just the checksum with other parties.

This is true even post-setup, and can be done as a periodic check

Why, if the descriptor and checksum is persisted in each signer's storage?
With this change there's a bit of a contradiction. On line 103/104 we are telling Signers to confirm checksum, M, and N, with each other. On Line 170-1744, we are telling Signers to independently view checksum, M, and N, and then confirm just the checksum with other parties.

Good points. Will fix.

ACK commit 409d96b1e05b49772d547aa6a4f478f29f47adff, commit 1ae72ecd69c3b904ed9ebd38a03b37462253f323,
commit 970ecf20332cd3e5846a26e8a025f0db866144f5

I've decided to restrict the EXTENDED mode to 96-bit after some consideration: https://github.com/nunchuk-io/bips/pull/1/commits/4988ba49b9f5439f333f0f926e2d3829966810fc .
It addresses @prusnak's concern about potential user confusion between BIP39 seed mnemonic and token mnemonic.
96-bit of security is still very strong:

The fastest computer today is listed at 442 PFLOPS. 1 PFLOPS ~= 2^50 FLOPS.
Assuming it takes 1 FLOP / key, it would take around 2^96 / (442 * 2^50 * 60 * 60 * 24 * 365) ~= 5000 years currently to crack one key.

The usual caveat about the threat of Quantum Computing applies. But even with QC, I feel like 96-bit token still offers "good enough" security for 2 reasons:

The short timeout window offsets the lack of higher entropy.
If the TOKEN is cracked after the wallet has been set up, only privacy is affected. No funds are lost.

Lastly, if the users really really wants stronger privacy guarantee, they can apply custom encryption on top of the spec.
So all in all, restricting EXTENDED to 96-bit feels like a good compromise.

ACK commit 4988ba49b9f5439f333f0f926e2d3829966810fc

Added test vectors https://github.com/nunchuk-io/bips/pull/1/commits/ced8229ca0c5cf461ccc021e5aedddb272645f9f.

Added test vectors ced8229.

I see you assume the signer supports sortedmulti (BIP67), but that's not always true. There are signers that support only multi, there are signers that support only sortedmulti and there are signers that support both.
Maybe you should collect this information from the signers and generate the final descriptor that can be signed by all signers?  That might not be always possible and in that case you should probably throw an error.

Added test vectors ced8229.

I see you assume the signer always supports sortedmulti (BIP67), but that's not always true. There are signers that support only multi, there are signers that support only sortedmulti and there are signers that support both.
One option is to collect this information from the signers and generate the final descriptor that can be signed by all signers? That might not be always possible and in that case you should probably throw an error.
Other option is that this setting should be set by the coordinator (same as ADDRESS_TYPE) and the signer would just throw an error if unsupported setting is required.
The latter is easier to implement and makes the whole process easier.

Thanks @prusnak. I think we can generalize the problem as following: there might be features of the descriptor language that a Signer will not support. It can be a particular script type or address type or whatever.
I'm also leaning towards your option 2. Simpler process, less overhead. I will add something about the Signer throwing an error in the main text.
The test vectors serve mostly as a reference for the encoding/decoding + encryption/decryption process. The actual script used is actually not important for this purpose, so I don't think they need to be changed. But let me know if anyone thinks it's helpful to have one example with a simple multi script.

I really like that this scheme reduces the number of human operations to verify a set of xpubs in a multisig from O(n^2) to O(n). Meatspace cryptographic verification is incredibly hard, so this could make a difference. Thanks @hugohn for putting this together!
Unfortunately, the current implementation is only secure if Coordinator can be trusted, which is a bad assumption given that this device is almost always on an hot-machine.
Even if all m Signers are behaving correctly and verify the m-of-n, that their seed phrase controls 1 xpub, and the checksum is the same across all devices, a compromised coordinator can still trick those devices to display attackers' receive addresses (and potentially trust an attackers' change addresses). Note that this is true regardless of which encryption scheme is used (including none) and has nothing to do with the quality of the airgap.
Bitcoin core's 40-bit checksum are designed "to protect against typos or copy-paste errors". These checksums do not have sufficient entropy to withstand an active attacker who has compromised the Coordinator, as collisions could be brute-forced.
Here, we assume Coordinator is malware and demonstrate a successful MITM collision attack in the 1-of-2 case:

Signers A and B present their legitmate xpub, path, and root fingerprint to malware Coordinator. The legitimate output descriptor should be wsh(sortedmulti(1,[xfpfora/48'/1'/1']xpubforA/0/*,[xfpforb/48'/1'/1']xpubforB/0/*))#checksum
Before presenting the output descriptor to Signer A (for the user to confirm it and register it on the device), malware Coordinator swaps out Signer B's xpub for the attacker's xpub X. Coordinator calculates this checksum value and gets a result of foobar12. At this point, the output descriptor looks like this: wsh(sortedmulti(1,[xfpfora/48'/1'/1']xpubforA/0/*,[xfpforx/48'/1'/1']xpubforX/0/*))#foobar12. Signer A has no knowledge of Signer B up until this point, so Signer A can only validate that it is in fact a 1-of-2, that Signer A controls 1 key at the given path, and that the checksum foobar12 appears correct (Signer A displays this checksum to the user, which matches what the malware Coordinator displays).
Now here is the clever twist. Malware Coordinator brute forces a pubkey Y to substitute for A when displaying the checksum to Signer B. After an average of 2^40 attempts they discover extended key Y such that this string derives the same checksum via brute-force collision: wsh(sortedmulti(1,[xfpfory/48'/1'/1']xpubforY/0/*,[xfpforb/48'/1'/1']xpubforb/0/*))#foobar12. Signer B has no knowledge of Signer A up until this point, so Signer B can only validate that it is in fact a 1-of-2, that Signer B controls 1 key at the given path, and that the checksum foobar12 appears correct (Signer B displays this checksum to the user, just as the malware Coordinator does and Signer A previously did).
When funds are deposited to an address that appeared on malware coordinator and Signer A's trusted display, the attacker automatically sweeps them!

Obviously, 1-of-2 is not good multisig, but it's easiest to demonstrate the attack with 1-of-2. Once you understand how it works, you can see how this could be extended to 2-of-3 or 3-of-5 with more brute-forcing.
This attack is not as devastating as it seems:

The malware coordinator could not trick multiple honest Signers into displaying the same address belonging to the attacker (though it could display on each Signer a different address that belonged to the attacker). So an end-user who was wise enough to confirm an address on >= 2 trusted displays would be safe from this attack. However, many end-users falsely consider their Coordinator plus 1 Signer to be "2  devices", whereas this attack renders them effectively 1. This is especially common in hosted/collaborative multisig services like Casa/Unchained.
This attack cannot be exploited if end-users are also validating every xpub on each Signer. But then the main benefit (eliminating the O(n^2) xpub validation) of the BIP disappears.
2^40 is a lot if the user is setting up the multisig live. However, it could be enough to complete if the user goes away while syncing their node, has to fly to secure locations in other geographies, or a sophisticated attacker targets multisig whales by renting cloud hardware to scale on demand, etc. It may be prohibitively expensive given that the success rate on this attack would be below 100% (and an exploit in the wild could change user behavior).

This is not the lowest hanging fruit for malware authors, but this checksum is a weak foundation to build on. A longer checksum seems like the obvious solution. Unfortunately, this is not currently supported by bitcoin core :(

Higher level thoughts
I think the BIP should be focused primarily on solving the O(n^2) xpub verification problem. It is the step in setting up secure multisig that I get the most questions on.
I'd like to see the use of an (optional) signature by each Signer when initializing the multisig setup. This would allow stateless hardware wallets (such as Trezor or my CLI wallet multiwallet) to participate relatively safely in a multisig quorum's receive address verification. The current proposal requires persistent storage, which is ideal but not all use-cases are able to accommodate it. A simple signature could allow for tamper-proof storage at the Coordinator, who would be unable to alter the contents without invalidating the signature.
The verification of BIP39 nonce words is incredibly hard for end-users, and I don't see what it accomplishes. I have never had a user setup multisig and relay concern about xpub privacy between their computer and their hardware wallet. Users have been trained to believe that BIP39 words are for seed phrases, and many users will get confused here. I cringe at the thought of (a tiny percent of) future bitcoiners who would mistakenly write down their 6/9 BIP39 nonce words and not their 12/15/18/21/24 BIP39 seed phrase words. I'm struggling to identify an example of a user for whom I'd recommend using this optional feature.

I really like that this scheme reduces the number of human operations to verify a set of xpubs in a multisig from O(n^2) to O(n). Meatspace cryptographic verification is incredibly hard, so this could make a difference. Thanks @hugohn for putting this together!

Thanks.

Unfortunately, the current implementation is only secure if Coordinator can be trusted

This is not true.

Now here is the clever twist. Malware Coordinator brute forces a pubkey Y to substitute for A when displaying the checksum to Signer B. After an average of 2^40 attempts they discover extended key Y such that this string derives the same checksum via brute-force collision: wsh(sortedmulti(1,[xfpfory/48'/1'/1']xpubforY/0/*,[xfpforb/48'/1'/1']xpubforb/0/*))#foobar12. Signer B has no knowledge of Signer A up until this point, so Signer B can only validate that it is in fact a 1-of-2, that Signer B controls 1 key at the given path, and that the checksum foobar12 appears correct (Signer B displays this checksum to the user, just as the malware Coordinator does and Signer A previously did).

No security scheme is 100% foolproof.
The CHECKSUM being there doesn't mean that the user could not or should not check the actual descriptor especially when the situation calls for it, e.g. when the amount of funds at stake is significant or the Coordinator could not be trusted. The ability to check the entire script doesn't go away. It's not an either/or here.
Note that visual inspection of the script (which is how things are done currently in most multisig solutions) is a manual process. Therefore, it is inherently error-prone and scales terribly, i.e. when the number of signers and/or the complexity of the script grows (think multiple Taproot branches). Humans are just not good at reading long random strings.
Generally speaking, visual inspection is always the last resort but it should never be relied upon as the primary security mechanism. Instead, visual inspection should be combined with other tools, such as the TOKEN/CHECKSUM introduced here. This is essentially the defense-in-depth principle.

... this checksum is a weak foundation to build on. A longer checksum seems like the obvious solution. Unfortunately, this is not currently supported by bitcoin core

Kinda agreed but another goal of the proposal is to have an interoperable standard. The descriptor language is going to be adopted across the industry, given the growing complexity of the MPC smart contracts. IMO introducing another checksum format here will make things harder to support.
I'll get to your other comments later. Just want to respond to the above first.

I'd like to see the use of an (optional) signature by each Signer when initializing the multisig setup. This would allow stateless hardware wallets (such as Trezor or my CLI wallet multiwallet) to participate relatively safely in a multisig quorum's receive address verification. The current proposal requires persistent storage, which is ideal but not all use-cases are able to accommodate it. A simple signature could allow for tamper-proof storage at the Coordinator, who would be unable to alter the contents without invalidating the signature.

Signature is already part of the proposal.
One of the fundamental problems facing multisig is this: in a multisig a Signer must know who the other 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 way. I don't see how keeping signatures at the Coordinator at setup would help you go stateless at the Signer. You don't have to alter the "contents" in the Coordinator to tamper with each transaction.
Also strongly disagree that going stateless is the direction we should pursue when it comes to multisig. Not only this approach results in a lot of cognitive overhead, it has serious privacy implications.

The verification of BIP39 nonce words is incredibly hard for end-users.

What verification are you talking about? If you enter the wrong token, you simply fail to set up the multisig wallet.

... and I don't see what it accomplishes.

Please refer to the Motivation section.

I have never had a user setup multisig and relay concern about xpub privacy between their computer and their hardware wallet.

I'm guessing that you are focusing too much on local multisig setups use case, of which you might have some experience. Please be aware that multisig isn't restricted to local setups.
Generally speaking, using a limited set of past anecdotal data is a poor approach to design safe and future-proof security systems.

Users have been trained to believe that BIP39 words are for seed phrases, and many users will get confused here. I cringe at the thought of (a tiny percent of) future bitcoiners who would mistakenly write down their 6/9 BIP39 nonce words and not their 12/15/18/21/24 BIP39 seed phrase words.

We already discussed in this thread how to address the potential confusion, please read the thread. In short, 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 incredibly 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. The only reason we included here is purely for convenience and existing hardware support. All the TOKEN represents is a certain amount of entropy. BIP39 is just one possible encoding, out of many.

I'm struggling to identify an example of a user for whom I'd recommend using this optional feature.

Anyone who actually cares about minimizing the risks of multisig setup.

Specify that Signers should check if they can support the descriptor string, as @prusnak suggested https://github.com/nunchuk-io/bips/pull/1/commits/3108fb858979ee97d32288dd7778248e181c9110
Update test vectors; include examples for both multi and sortedmulti scripts

ACK commit 69fa479cb36554ca57aeb4771fafc11b0a3219b1, ced8229ca0c5cf461ccc021e5aedddb272645f9f, 574a5939e323206b3d94b11fd4fb62d00ca695dc, 3108fb858979ee97d32288dd7778248e181c9110, c8dac9e6a2524969a105968ab1539b99da6871ff
According to this (https://github.com/bitcoin/bips/pull/1072/files) m/48 specifies:

m / purpose' / coin_type' / account' / script_type' / change / address_index

So shouldn't the paths in the tests be:
m/48' /0' /0' /1' (Nested Segwit)
or
m/48' /0' /0' /2' (Native Segwit)
They seem incomplete at the moment (stopping at account', not specifying script_type'?

@Rspigler technically "BIP48" isn't really a BIP... (and the one being linked is still pending). Output descriptors make the derivation scheme posed by BIP48-like proposals largely redundant, especially the script_type portion.
Having said that, I guess there's no harm in showing examples that mirror actual usages in the wild right now.

I completely agree with you.
I actually requested removing the reference to BCR-2020-015 here because it makes use of "BIP"48.  I'd much rather usage of it stop, and I'm writing an updated derivation scheme here (https://github.com/Rspigler/bips-1/pull/1).
Just got a concept ACK from you though, so you know this :)
If we keep references to it in BSMS, I believe it should be used correctly however (which I believe it isn't at the moment, could be wrong).

ACK commit 8ddce677ea974632007b6fc549ee5ed5d63e5a79, b267b20b661b8055233363707feec90f9b6edebe

Also, in the descriptor, is it:
[Master_Key_Fingerprint/Derivation_Path]XPUB/*
or
[Master_Key_Fingerprint/Derivation_Path]XPUB/0/*

Also, in the descriptor, is it:
[Master_Key_Fingerprint/Derivation_Path]XPUB/*
or
[Master_Key_Fingerprint/Derivation_Path]XPUB/0/*

The former. We leave path restrictions up to the Signers, as specified here:

The Signer can choose to further restrict post-XPUB derivation paths, such as to those defined in BIP-0044.

The advantage of this is that there is only one descriptor to confirm (vs two or more).

The advantage of this is that there is only one descriptor to confirm (vs two or more).
The descriptor a/* will not discover the keys stored at a/0/*, a/1/*, only the keys stored immediately under a.

The advantage of this is that there is only one descriptor to confirm (vs two or more).

The descriptor a/* will not discover the keys stored at a/0/*, a/1/*, only the keys stored immediately under a.

What do you mean? Change/receive XPUBs are derived using non-hardened derivation.

You should be able to get to a/0 and a/1 from a. Then from there, a/0/* and a/1/*.

Your descriptor examples (such as this one) do not use a/0/* and a/1/*, only a/*. So they will not work as expected, which is the point that @Rspigler raised.

You should be able to get to a/0 and a/1 from a. Then from there, a/0/* and a/1/*.

Your descriptor examples (such as this one) do not use a/0/* and a/1/*, only a/*. So they will not work as expected, which is the point that @Rspigler raised.

Aren't a/0/* and a/1/* subsets of a/*? I don't get what the concern is.
AFAIU, we have 2 choices here:

The Coordinator creates both change/receive descriptor strings (a/0/* and a/1/*).
The Coordinator creates only the parent descriptor string (a/*), and let the Signers further derive the sub-descriptor strings for change/receive indices (and potentially more indices in the future for things like Pay-to-Contract).

The advantage of (1) is that it is more explicit.
The advantage of (2) is that it only requires one descriptor string to be confirmed at setup time.

2. The Coordinator creates only the parent descriptor string (a/*), and let the Signers further derive the sub-descriptor strings for change/receive indices (and potentially more indices in the future for things like Pay-to-Contract).

So you just assume that the signer will take the definition wsh(sortedmulti(2,a/*,b/*)) from BSMS and modify it automatically to wsh(sortedmulti(2,a/0/*,b/0/*)) + wsh(sortedmulti(2,a/1/*,b/1/*))?
If this is a yes, then you probably don't even need to add /* and just use wsh(sortedmulti(2,a,b)) because it is confusing and you can't use the descriptor as is anyway.
How would the signer know that they should replace /* with /0/* + /1/*? By looking at the xpub path in the descriptor? It seems this introduces a lot of logic to the signers, where it actually should be on the coordinator's side of things.

So, this is definitely an ongoing problem/debate.
People have suggested representing multiple derivation paths within one descriptor, although this was NACK'd by @sipa here.
@prusnak Then came up with adding groups and labels to descriptors.
However, it seems most wallets do what @hugohn is proposing, according to this thread/post https://github.com/bitcoin/bitcoin/issues/17190#issuecomment-761517669

I think @mflaxman brings up some interesting concerns.
I agree with @hugohn's responses.
I also think we have to think about the different ways people can set up multisig wallets.  I am guilty of often only thinking of single party multisig (where one person handles all co-signers), since that is what I do for my own funds, and often setup for clients.  In that situation, the coordinator is also owned by the 'owner'.
But obviously, there are multiparty multisignature setups. In this case, one of the co-signers would be the coordinator, or perhaps there could be a 3rd party handling coordination?

Unfortunately, the current implementation is only secure if Coordinator can be trusted, which is a bad assumption given that this device is almost always on an hot-machine.

All multisig setups, offline or not, need a node to use bitcoin securely. A node, obviously, is online.  Without it, you can't tell whether or not bitcoin you send have been broadcasted or not, or whether bitcoin you receive are genuine or fake. Private keys aren't the only software/device you need to secure with bitcoin, so I don't think is a good reason to NACK this BIP.
But it brings up a good point.  First, you should probably never use a 3rd party coordinator.  Second, what if you are setting up a multiparty multisig wallet?  The coordinator should be secured (so no general malware on it), but the coordinator could be malicious in the sense that the co-signer who owns it has maliciously set it up to enable control of the wallet.
Solutions offered by mflaxman are:

Have co-signers (who aren't coordinator) confirm generated addresses
Confirm full descriptor
Expand checksum in descriptor language

Perhaps we should mention 1 and/or 2 in the doc, or open an issue for 3?

The Coordinator creates only the parent descriptor string (a/*), and let the Signers further derive the sub-descriptor strings for change/receive indices (and potentially more indices in the future for things like Pay-to-Contract).

So you just assume that the signer will take the definition wsh(sortedmulti(2,a/*,b/*)) from BSMS and modify it automatically to wsh(sortedmulti(2,a/0/*,b/0/*)) + wsh(sortedmulti(2,a/1/*,b/1/*))?
If this is a yes, then you probably don't even need to add /* to the descriptor and just use wsh(sortedmulti(2,a,b)) because you can't use the descriptor as-is anyway (plus it is superconfusing).

I did consider that option yeah. I'm not against that idea actually, but IMO /* is more syntactically correct under the current descriptor language.
With the descriptor being /* we are saying: "We are entering a multisig contract whose addresses will include all subpaths under the submitted XPUBs." Without /*, that corresponds to one single address in the current descriptor language. Convenient yes, but not syntactically correct. If we don't care about syntax, then I guess it's fine.
Note that this approach of using one single configuration is also how most multisig wallets on the market (Coldcard, Shift Crypto, Electrum, Sparrow, Unchained, to name a few) do it at the moment -- some without descriptors and some with. The setup process usually involves submitting XPUBs without adding any qualifying sub-paths. We're just trying to replicate that here but with a more precise and interoperable language.

How would the signer know that they should replace /* with /0/* + /1/*? By looking at the xpub path in the descriptor? It seems this introduces a lot of logic to the signers, where it actually should be on the coordinator's side of things.

I think it's pretty trivial to expand the /* string into /0/* and `/1/* strings? You should be able to do this even without a full parser.
(There's the 3rd option, which is to have the Coordinator include both the parent descriptor -- for confirmation/backup -- and the sub-descriptors -- for Signers to generate addresses -- in the descriptor record. So this shifts some logic to the Coordinator's side. But with this option, the Signers need to make sure that the sub-descriptors are legitimate children of the parent descriptor, so some minimal amount of parsing is still required on the part of the Signer.)

So, this is definitely an ongoing problem/debate.
People have suggested representing multiple derivation paths within one descriptor, although this was NACK'd by @sipa here.
@prusnak Then came up with adding groups and labels to descriptors.
However, it seems most wallets do what @hugohn is proposing, according to this thread/post bitcoin/bitcoin#17190 (comment)

Ranged descriptors as proposed in bitcoin/bitcoin#17190 would have been nice, as you can capture both change/receive addresses using one single descriptor: xpub...{0,1}/*
Until we have something like that in the language, this is the workaround.
In general I think it makes sense to stick with one single configuration because it greatly simplifies both the wallet setup and recovery problems.

Until we have something like that in the language, this is the workaround.

I don't think something like that belongs in descriptors. They describe lists of scriptPubKeys, together with information on how to spend from them. Nothing more.
I understand this means that a typical wallet configuration needs multiple descriptors, with redundancy between them. That does ask for a solution, but I don't think this belongs on the layer of descriptors. They have other purposes than just defining wallets, so I'd rather not widen the notion of what a descriptor is to avoid complexity/interoperability issues.
So, to be clear: not saying something like this is undesirable, but I don't think it should be part of descriptors themselves. It can be done in a layer that translates to descriptors for wallet definition, perhaps.

Until we have something like that in the language, this is the workaround.

I don't think something like that belongs in descriptors. They describe lists of scriptPubKeys, together with information on how to spend from them. Nothing more.

@sipa I'm curious, in your opinion what makes a ranged descriptor conceptually different from a /* descriptor?
To me they both describe a set of scriptPubKeys. Just that one is a subset of the other. If we already have an expression for a set, it isn't a big stretch to include an expression for sub-sets, no?

I think there is a big difference, yes - in the interface you need to interact with them.
A single descriptor (now) is a one-dimensional list, you explore it with a index (a single number) as parameter, and get a scriptPubKey. You'd remember how many you have explored already, perhaps a gap limit, a birth date, ...
This isn't true for a /{0,1}/* descriptor. You now need a two-dimensional way to index into it. And you cannot just think of it as a single thing - you want to remember for each of the two subchains how far you've explored them, what gap limit to use, etc.
That's my point: a ranged descriptor isn't something you want to interact with as a single thing. It's something that expands into two lists, and you want metadata for each of them separately anyway.

I think there is a big difference, yes - in the interface you need to interact with them.
A single descriptor (now) is a one-dimensional list, you explore it with a index (a single number) as parameter, and get a scriptPubKey. You'd remember how many you have explored already, perhaps a gap limit, a birth date, ...
This isn't true for a /{0,1}/* descriptor. You now need a two-dimensional way to index into it. And you cannot just think of it as a single thing - you want to remember for each of the two subchains how far you've explored them, what gap limit to use, etc.

Agreed. But signers already need to keep track of key index and gap limit independent of descriptors, so isn't there an argument here that since it's not the descriptor language's responsibility to begin with, or to enforce it, it shouldn't have to worry about that problem for ranged descriptors either?
The assumption here is that whoever uses a ranged descriptor should know how to keep track of each subchain separately, just like it would know how to track a single chain. But that responsibility ultimately falls on the Signer.

Signers aren't the only things that may want to interact with descriptors. I don't want to force the complexity of dealing with this onto everything that wants to be compatible with descriptors.
E.g. the scantxoutset RPC. It takes a list of descriptors with associated ranges. It has no concept of wallets or payment addresses or change. If it'd want to deal with a /{0,1}/* descriptor, it needs an interface to accept a range per subchain. It just feels so much simpler to only support one-dimensional things with their own range. That's sufficient to anything you want to do with them. Yes, in some cases that means redundancy, so deal with it at the level that redundancy is created.

so much simpler to only support one-dimensional things with their own range. That's sufficient to anything you want to do with them. Yes, in some cases that means redundancy, so deal with it at the level that redundancy is created.

Makes sense.

not saying something like this is undesirable, but I don't think it should be part of descriptors themselves. It can be done in a layer that translates to descriptors for wallet definition, perhaps.

What would this look like?

not saying something like this is undesirable, but I don't think it should be part of descriptors themselves. It can be done in a layer that translates to descriptors for wallet definition, perhaps.

What would this look like?

I imagine it'd be something like this specification - we can define how a configuration translates into descriptors.
In the current proposal, we say the Signers settle on a parent /* descriptor for setup/recovery, and leave the responsibility of expanding /* into /0/* and /1/* to either the Signers or the Coordinator.
Perhaps we can add a step where the parties in the multisig agree on the post-setup restriction. For example: BIP44 can be a field in the key record to signal that a Signer will enforce subpaths according to BIP44. And all Signers should signal the same or we abort the setup.

Taking the above discussion into consideration, I have added derivation path restrictions to the spec: https://github.com/nunchuk-io/bips/pull/1/commits/bb95912a220aafcc57212a8dd06034fde6d0bb10
Here is an example of a BSMS descriptor record under the updated proposal:
BSMS 1.0
/0/*,/1/*
wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/*))#3xh7ch2h

The Signer can check if it is compatible with the included restrictions, then use the restrictions to expand the parent descriptor into sub-descriptors (e.g. /* --> /0/* and `/1/*). I believe this fits with @sipa's idea of translating a wallet configuration into more concrete descriptors.
With this proposal:

We are able to stick with one descriptor for setup/recovery.
The Coordinator is responsible for specifying path restrictions. These restrictions are part of the configuration file.
The Signers is responsible for applying the restrictions when generating addresses.

Let me know if anyone has any concern with this approach.

Let me know if anyone has any concern with this approach.

I think it would be better to work on expanding the descriptor spec first (e.g https://github.com/bitcoin/bitcoin/issues/17190, https://github.com/bitcoin/bitcoin/issues/21197, etc.), then use the improved descriptors for BSMS.
Otherwise you'll be designing something that cannot be used in Bitcoin Core out-of-the box and it will need to be replaced anyway sooner or later.

How about supporting 2 descriptors: a "main" / "deposit" descriptor, and another for "change". Specifying the change one would be optional, but typical wallets today would be provide both, with a common prefix, and ending in ../0/* and ../1/* respectively.
Nice thing about being explicit about the purpose of the descriptor is it allows the signer to enforce additional policy rules if desired.

Let me know if anyone has any concern with this approach.

I think it would be better to work on expanding the descriptor spec first (e.g bitcoin/bitcoin#17190, bitcoin/bitcoin#21197, etc.), then use the improved descriptors for BSMS.
Otherwise you'll be designing something that cannot be used in Bitcoin Core out-of-the box and it will need to be replaced anyway sooner or later.
If there is motivation to get something out of the door ASAP, then I understand, but in this case let's keep in mind this will need to get upgraded in the future.

AFAIU the descriptor language is pretty final, except for maybe the possibility of having labels. There's no plan for ranged descriptors based on bitcoin/bitcoin#17190 and the conversation here in this thread. So I don't think it should hold off this BIP. @sipa can correct me if I'm wrong.
Also note that I generally try to keep the parts involving descriptors fairly generic, to account for future changes. The main thing that might need to be updated, if the language does evolve, is the test vectors.
The test vectors I have so far work out-of-the-box with Bitcoin Core. In fact, Core was used to generate the example descriptors.

How about supporting 2 descriptors: a "main" / "deposit" descriptor, and another for "change". Specifying the change one would be optional, but typical wallets today would be provide both, with a common prefix, and ending in ../0/* and ../1/* respectively.
Nice thing about being explicit about the purpose of the descriptor is it allows the signer to enforce additional policy rules if desired.

The problem with this approach is that this greatly complicates the setup and recovery processes. The user would need to confirm AND back up two descriptors instead of one.
The approach I propose above is functionally equivalent to the two-descriptor approach, with the main difference being that the user has to confirm / back up only one single descriptor.
Most vendors on the market also prefer single descriptor backup (check out the comments in bitcoin/bitcoin#17190 and I think it makes sense. Multisig wallet recovery is already a fairly involving process (multiple seeds + descriptor), so we want to simplify this as much as possible IMO.

The test vectors I have so far work out-of-the-box with Bitcoin Core. In fact, Core was used to generate the example descriptors.

Can you please explain how entering this into Bitcoin Core:
wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/*))#3xh7ch2h

ended up discovering the correct UTXO set? (with /0/* and /1/*)

The test vectors I have so far work out-of-the-box with Bitcoin Core. In fact, Core was used to generate the example descriptors.

Can you please explain how entering this into Bitcoin Core:
wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/*))#3xh7ch2h

ended up discovering the correct BIP48 UTXO set (with /0/* and /1/*)?

Ah I think I misunderstood your question.
Yeah so to import that multisig wallet into Bitcoin Core, a bit of preprocessing is needed.
The parent descriptor
> wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/*))

Needs to be expanded into 2 sub-descriptors:
> wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/0/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/0/*))

> wsh(sortedmulti(2,[13ed1d6b/48'/0'/1']xpub6C1ZaeNEhaDvTca8RMRHH5XxzuHXJMPQ7YRJm3GDFQhsyeDyrwn7BdVrwiCPQTTKVTSLHnSwB5XXWMaMiVHPwYaL6YVXivbLpkzenTdQCke/1/*,[89cec7aa/48'/0'/1']xpub6Bm4952Tchn5aS2mdqXgpTWUEdyyF1nQM3e8biFmXcBP2wwLnBpoXKoLsSCSNHgeUGxx9oXWs5FRjxsuXGn1XZ6oyD57qyeaGXZQuApWma9/1/*))

You can then import this into a Core native descriptor wallet using importmulti or importdescriptors command.

Yeah so to import that multisig wallet into Bitcoin Core, a bit of preprocessing is needed.

Okay, good, so we are on the same page. Thanks for confirming this.

Yeah so to import that multisig wallet into Bitcoin Core, a bit of preprocessing is needed.

Okay, good, so we are on the same page. Thanks for confirming this. The need for "preprocessing" is what I meant by "cannot be used in Bitcoin Core out-of-the box".

Yup, the tradeoff here, as mentioned above, is a simplified setup/recovery process.

ACK commit bb95912a220aafcc57212a8dd06034fde6d0bb10 and e716f821fdec5bdd82334282117c3865506d1f92
Do the rest of the tests need to be updated?

With this proposal:
We are able to stick with one descriptor for setup/recovery.
The Coordinator is responsible for specifying path restrictions. These restrictions are part of the configuration file.
The Signers are responsible for applying the restrictions when generating addresses.

I like how you did this.  And I believe descriptors can be updated for labels independently from this (I don't believe that labels solve this issue by themselves)

Updated test vectors: https://github.com/nunchuk-io/bips/pull/1/commits/8d6e5375a540725f4e8060ec3fc6d10465c6fb42.

Updates:

explicitly mandate that the full descriptor must be available for review when confirming the wallet.
also recommend Signer to show a preview of the first address(es) when confirming the wallet.

These should allay @mflaxman's concern. https://github.com/nunchuk-io/bips/pull/1/commits/e9bdddcaa8a8613b4fdf1393cca455e4db1c1c0c

There are no pending items and I feel pretty good about the current state of the spec.
I'd give it a couple of more days. If there are no other concerns, I'd re-submit this to the mailing list and ask for an official BIP number.

Concept ACK on the last three commits.  Will go over them, and the whole doc, more carefully tomorrow for one final ACK.

ACK commit 8d6e5375a540725f4e8060ec3fc6d10465c6fb42, e9bdddcaa8a8613b4fdf1393cca455e4db1c1c0c, 8916011976346c73d58dc949743d9b78fe08d89e
Also made some final notes

Updated https://github.com/nunchuk-io/bips/pull/1/commits/16dbb0bbd158e1647455093010487be4c1f2cfee.

ACK commit 16dbb0bbd158e1647455093010487be4c1f2cfee
Looks ready to submit as a BIP :tada:

ACK with the latest changes.

Thanks @stepansnigirev @Rspigler.
Super minor edit: https://github.com/nunchuk-io/bips/pull/1/commits/dfe7c9b29f419c9ff6e884688c6e39abdbe49ba0.

ACK commit https://github.com/nunchuk-io/bips/commit/dfe7c9b29f419c9ff6e884688c6e39abdbe49ba0

ACK commit dfe7c9b29f419c9ff6e884688c6e39abdbe49ba0

@ all: I have converted this to a PR on the Bitcoin repo: https://github.com/bitcoin/bips/pull/1097
Would appreciate it if you could re-ACK it over there as well. Thank you.

ACK commit dfe7c9b

authors: Rspigler aaronisme afilini dgpv hamedtayeban hugohn instagibbs mflaxman peter-conalgo prusnak sipa stepansnigirev

repo: nunchuk-io/bips


text:
[W6.1f][F09-B4] Liu Hang

@liuhang0213 Accepting this PR with minimal review. No issues spotted!

source: gharchive/pull-request

license: MIT

license_type: permissive

license_source: github-api


text:
Added some initial documentation to be expanded later.

Any additional thoughts @zunath @Jorteck ?

authors: Wytchwood urothis


text:
Bump ovirt-nodejs-modules version to 1.0.19

Blocked by https://gerrit.ovirt.org/#/c/80580/

repo: oVirt/ovirt-web-ui

license_source: bigquery


text:
Feat/success failure indicator

Codecov Report

Merging #39 (d0bbf94) into develop (b5b382e) will decrease coverage by 0.31%.
The diff coverage is 48.88%.

@@             Coverage Diff             @@
##           develop      #39      +/-   ##
===========================================
- Coverage    86.39%   86.07%   -0.32%
===========================================
  Files           17       18       +1
  Lines          676      718      +42
  Branches       171      188      +17
===========================================
+ Hits           584      618      +34
- Misses          91       98       +7
- Partials         1        2       +1

Impacted Files
Coverage Δ

src/index.tsx
84.52% <ø> (+19.04%)
:arrow_up:

src/Components/Main.tsx
62.96% <20.68%> (-17.53%)
:arrow_down:

src/Components/Indicator.tsx
100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b5b382e...d0bbf94. Read the comment docs.

repo: odemolliens/react-native-netwatch


text:
How to prevent this error: terminate called after throwing an instance of 'std::runtime_error'   what():  Connection timed out

So if my server remains idle for too long, It shuts down with this error. Any help would be greatly appreciated :) thanks

run the server under "strace" and examine the log.
/usr/bin/strace -o /tmp/server.log -f ./${your_server_binary}
(or equivalent)

This error occurs if I keep the server running and keep it idle. It might take me a few days to replicate this error.

source: gharchive/issue

repo: oktal/pistache


text:
Polish i18n

:+1:

authors: Tymek olefredrik

repo: olefredrik/FoundationPress

license: mit


text:
Add proposer for batch-submitter

Codecov Report

Merging #71 (531c5aa) into develop (b3886da) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff            @@
##           develop      #71   +/-   ##
========================================
  Coverage    82.26%   82.26%
========================================
  Files           49       49
  Lines         1900     1900
  Branches       303      303
========================================
  Hits          1563     1563
  Misses         337      337

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b3886da...531c5aa. Read the comment docs.

repo: omgnetwork/optimism


text:
fix #51 [skip ci]

Oops - the initial commit message caused CI to not run at all when merging - thus the new Docker image didn't get pushed. Will follow up with an update triggering that push...

repo: open-quantum-safe/profiling


text:
0.13.0

@joneit Groupview Fixes

repo: openfin/hyper-analytics


text:
Add git annex repo for holding Matt's production-sample database (and share it with all the developers)

git-annex looks like a pain.  It seems like its just a way to add a symlink to git.  We would still have to set up and manage some remote location to host the file.  And then to use git-annex every dev needs to download it separately.

repo: openforis/collect-earth-online


text:
Fix bug of multi winners on dutch phase

Coverage decreased (-0.2%) to 85.759% when pulling 522f3328f28e4fc723983bbe8de2325f3f34d853 on VDigitall:sandbox into 482d9b6e2b2fa9e16d2f3cd11e9d9b0d54036c14 on openprocurement:sandbox.

authors: VDigitall coveralls


text:
Added host monitoring cron job for cron-send-ec2-ebs-volumes-in-stuck-state

This PR was +1d in STG PR #2462

repo: openshift/openshift-tools


text:
[stg] add terminating pod check script to rpm

👍

authors: BlueShells bmeng


text:
Chef-2357/2358: support cwd and environment on Windows shell_out

I have made it so that we only call cmd.exe when we need to, and so that we throw ENOENT when we can't find the file (and aren't using the shell).  This gives parity with Unix, though we're not as exact as the Ruby win32/win32.c code that decides whether to call cmd.exe or not.

Totally awesome. I say merge it if there's nothing left to do.

authors: danielsdeleo jkeiser-oc

repo: opscode/chef


text:
removing commented/incomplete test code

why do we not want this test? i might have missed something

authors: markxnelson vanajamukkara

repo: oracle/weblogic-kubernetes-operator


text:
sqlServer08  如果用了列转行，分页就不能用了

08需要解析sql改结构，无法解析时就会报错。

repo: pagehelper/Mybatis-PageHelper


text:
如果我要迁移，需要修改哪些文件呢?

Google Translation: If I want to migrate, which files need to be modified?
Question: From where do you want to migrate to where? Do you want to upgrade Pagekit or do you want to switch from another CMS to Pagekit?

只是迁移到另一台服务器，可能数据库名和数据库版本不完全一样。

Chinese native translate: He wants to migrate from one server (web host) to another, the database name and database version may be not the same as before.

I see three different possible solutions:

For small projects: Set up the page manually and copy the content page for page.

Try to use the backup extension: https://spqr.wtf/projects/backups
However I do not know whether this will work for moving a page and whether the import will work as intended.

Set up a second page with exactly the same extensions installed. Pagekit version, extension versions should all be the same to avoid issues. Now, only the files in your storage folder and the database content needs to be copied: Simply copy the files from the storage folder to the new page. Additionally, create a database dump and load it into the database of the new page. Overwrite all content of the database of the new page.

authors: brentybh fxzxmicah tobbexiv

repo: pagekit/pagekit


text:
add a file

Opened as a test with zenhub, closing

repo: paketo-buildpacks/yarn-install


text:
fix typo

Thanks!!!


text:
Adding feature tests

:+1: :rocket:

authors: TeslaDethray bensheldon

repo: pantheon-systems/cli


text:
client: fix log filters

I don't think this fixes @shawntabrizi's problem though -- currently, one still has to explicitly pass RUST_LOG=cranelife_wasm=warn to suppress those should-be-by-default-disabled logs. I'm still investigating that.

bot merge

authors: andresilva sorpaas

repo: paritytech/substrate


text:
resize is now a public method

@fnicollet had the (much better) idea to just check for the existence of _resize() to support both the public and private method simultaneously.
https://github.com/mapbox/mapbox-gl-leaflet/commit/43e888604a91f5dddc1b5b215fbf5607a44320a9

Yes, that's what I ended up doing
Le 6 déc. 2016 04:07, "john gravois" notifications@github.com a écrit :

@fnicollet https://github.com/fnicollet had the (much better) idea to
just check for the existence of _resize() to support both the public and
private method simultaneously.
mapbox@43e8886
https://github.com/mapbox/mapbox-gl-leaflet/commit/43e888604a91f5dddc1b5b215fbf5607a44320a9
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/patrickarlt/mapbox-gl-leaflet/pull/1#issuecomment-265048210,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABLtoWUYxJqJ43BuPaAO7Y1VyFNKb5Apks5rFNFUgaJpZM4K5scs
.

Just in case mapbox changes his mind again :)
Le 6 déc. 2016 08:49, "Fabien Nicollet" fnicollet@gmail.com a écrit :

Yes, that's what I ended up doing
Le 6 déc. 2016 04:07, "john gravois" notifications@github.com a écrit :

@fnicollet https://github.com/fnicollet had the (much better) idea to
just check for the existence of _resize() to support both the public and
private method simultaneously.
mapbox@43e8886
https://github.com/mapbox/mapbox-gl-leaflet/commit/43e888604a91f5dddc1b5b215fbf5607a44320a9
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/patrickarlt/mapbox-gl-leaflet/pull/1#issuecomment-265048210,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABLtoWUYxJqJ43BuPaAO7Y1VyFNKb5Apks5rFNFUgaJpZM4K5scs
.

authors: fnicollet jgravois

repo: patrickarlt/mapbox-gl-leaflet

license: ISC


text:
CI for Node

Initializes with two players
Starts the game with a random player
Sets the current player to be whoever it is not


text:
merge with nephila

Current coverage is 92.43% (diff: 100%)

No coverage report found for develop at 71cb669.

Powered by Codecov. Last update 71cb669...183975d

authors: Air-Mark codecov-io

repo: peacedata/djangocms-blog


text:
Mobile optimization for sign in page

It definitely looks ok on mobile now -- although we'll have to get a real mobile to test for sure I guess. Now on non-mobile, when the browser is full screen, the box stretches very wide, and it's a little strange-looking. Anything we can do about that? Do we need media queries for that? Also, any way we can get the input text fields to be symmetrical?

Cool. I think we still need to remove con-format, but I'll merge and we can do that later.

authors: elliottyates hansss

repo: penzance/askup


text:
Add logo

Logo is added

repo: pepelev/Comparation


text:
Cross-compile jackproxy for both OSX and linux.

@djones just cc'ing you for some visibility on this PR, going to merge. Happy to chat about this offline.

repo: percy/jackproxy


text:
add script for aws-opsworks-smooth-deploy

@petrabarus please review

rebase

lgtm. let me know when the commits squashed.

repo: petrabarus/aws-opsworks-smooth-deploy


text:
Picoin

Sure but picoin no network to send
On Mon, 1 Jun 2020, 02:12 Henry Watson, notifications@github.com wrote:

Hi I like what you are doing with a widely available to mine cryptocurrency
for the wider public is there any chance you can donate me some picoin
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/picoin/picoin_v1/issues/3, or unsubscribe
https://github.com/notifications/unsubscribe-auth/AGLYGEBOPI6E75LUS5ZOT7LRUK6LJANCNFSM4NPJ7CQA
.

authors: gkdbay henry-glitch


text:
Releasing 1.2.1

This just updates the CHANGELOG, merging it myself.

repo: pilosa/python-pilosa


text:
Add firstOrNull

supported


text:
Get started on landing page is hard to see

Fixed with e7ec61d1b35fa761572d6145324a25f9ba3349b8

repo: pions/website


text:
Allow for other shells

Make sure we're only using posix shell scripts

We could switch to /bin/sh

Why be prescriptive? Just use the users shell as this will allow them to do things like inline for loops in their preferred style:
https://github.com/andrewjanke/qbatch/blob/master/qbatch#L104
and
https://github.com/andrewjanke/qbatch/blob/master/qbatch#L124

Good thought, we have to be careful that our qbatch magics support other shells.
I recall there being some "interesting" interactions between cluster software and the shell types, including what's "allowed" as a shell.

This would also fix the "I need to use a login shell" problem we may be experiencing for some users on scinet.

Method:
Expose shebang as QBATCH_SHEBANG
Expose as command-line option
Use in header of jobfiles
Use as spawner for single-job commands.

authors: andrewjanke gdevenyi pipitone

repo: pipitone/qbatch

license: unlicense


text:
README: Add guidelines for incompatible grep

Actually, I fixed the dependency on GNU sed yesterday, and the grep commands seem to work with both GNU and BSD grep.

authors: fangyi-zhou wenkokke


text:
Last Week in Pony - September 16, 2018

Audio from the September 12, 2018 Pony development sync is now available:
https://pony.groups.io/g/dev/files/Pony Sync/2018_09_12

I created a channel called ponylang in the Strange Loop 2018 Slack, in case anyone going to Strange Loop wants to talk about Pony.

authors: SeanTAllen aturley jdhorwitz


text:
Ppcoin master testfix

Not sure what you are trying to achieve.
But merging in Peershares code won't be accepted.
And changing this amount lines of code: +38,153 −22,716 ?
Better close this pull request and propose one fix at a time with a decent description.

repo: ppcoin/ppcoin


text:
Feature/har 97

:+1:

authors: dbreedt msinovcic

repo: praekelt/gem-survey-tool


text:
Banner tag image

@projectmushroom @saeedmb8
Please review

repo: praekelt/molo-gem


text:
Implement Vumi Dispatcher Router for Portia.

@justinvdm @rudigiesler @hodgestar & @jerith ready for review. I'm unsure about what to do about un-routable messages, currently I'm raising an exception but perhaps I should nack those at the dispatcher level?

@smn -- regarding unroutable messages: I think raising an error is an acceptable first pass. Returning a nack would be nice but I don't think our dispatchers support that very well currently.

First pass of reviewing done. One major comment about switching to (badly named) endpoint_dispatchers, otherwise looks pretty good.

Other than moving to the dispatchers that support dispatching based on the connector name rather than the transport name, looks good.

@hodgestar ready for review. I'm not entirely convinced I went about it correctly, endpoints & connector names still confuse me at times.

Review done. Looks good. Outstanding things:

Question about whether we want to add a custom error handler for if the MNO received from portia isn't in the reverse mapping.
Adding a separate issue for neatening up the config error handling.

After those I think it can land.

I'm having trouble testing the outbound dispatched messages, the helpers simply return the message dispatched but I'd prefer they raise the exception raised so I can use assertFailure. The exception is being raised though I'm just not able to trap it in the test.

I'm having trouble testing the outbound dispatched messages, the helpers simply return the message dispatched but I'd prefer they raise the exception raised so I can use assertFailure. The exception is being raised though I'm just not able to trap it in the test.

Does flushLoggedErrors (http://twistedmatrix.com/documents/current/api/twisted.trial.unittest.SynchronousTestCase.html#flushLoggedErrors) help?

@hodgestar no, it returns [].

@hodgestar nope, sorry it does return the failure \o/. thanks.

\o/

@hodgestar ready for re-review.

:+1:

authors: hodgestar smn

repo: praekelt/vxportia