--- Day changed Wed Oct 02 2019 01:28 -!- jonatack [~jon@2a01:e35:8aba:8220:6627:dad:d967:649d] has quit [Ping timeout: 250 seconds] 02:10 -!- jonatack [~jon@87-231-197-177.rev.numericable.fr] has joined ##hwi 03:46 -!- jonatack [~jon@87-231-197-177.rev.numericable.fr] has quit [Ping timeout: 268 seconds] 04:24 -!- jonatack [~jon@54.76.13.109.rev.sfr.net] has joined ##hwi 04:58 -!- jonatack [~jon@54.76.13.109.rev.sfr.net] has quit [Ping timeout: 250 seconds] 05:19 -!- warren [~warren@fedora/wombat/warren] has quit [Ping timeout: 245 seconds] 05:21 -!- warren [~warren@fedora/wombat/warren] has joined ##hwi 05:32 -!- jonatack [~jon@2a01:e35:8aba:8220:6627:dad:d967:649d] has joined ##hwi 08:09 < instagibbs> provoostenator, bip67, heh. 08:20 -!- jonatack [~jon@2a01:e35:8aba:8220:6627:dad:d967:649d] has quit [Quit: jonatack] 08:32 < provoostenator> https://github.com/bitcoin/bitcoin/pull/17023 08:33 < provoostenator> I just ran head first into that while testing a ColdCard + DIY Specter multisig (testnet). 08:33 -!- jonatack [~jon@2a01:e35:8aba:8220:6627:dad:d967:649d] has joined ##hwi 08:33 < provoostenator> ColdCard started screaming "Change address fraud" at me :-) 08:34 < provoostenator> There goes my 1 tBTC :-) 08:42 < provoostenator> instagibbs: rebased https://github.com/bitcoin/bitcoin/pull/16944, hopefully making your "Yes" -> "Send" commit very short lived. 08:49 < ghost43> provoostenator: the point of bip67 is that it does not matter in what order you specify the cosigners during wallet creation/restoration 08:50 < ghost43> it's very counterintuitive to users that that would matter 08:51 < ghost43> I actually raised this concern during the optech in Paris, you were there too IIRC, not sure if you remember. I said back then, that what the multi() descriptor is doing is not compatible with what e.g. electrum is doing 08:51 < provoostenator> ghost43: I get that, but I think it's better to require a specific order in the seed fingerprints. Wallet software can hide that contraint from the UI completely 08:51 < provoostenator> I don't remember; I wasn't working on multisig back then :-) 08:52 < ghost43> the advantage of sorting based on individual pubkeys in the scriptcode is that it works for both single addresses and HD wallets 08:52 < ghost43> you don't need separate rules 08:53 < provoostenator> For a single pubkey the "master" key fingerprint is based on that single pubkey, so I think it's identical. But not sure if it takes the first or last characters for the fingerprint. 08:55 < ghost43> but what if you create an individual multisig from the first pubkeys of an HD wallet 08:56 < ghost43> and then later you restore from the xpubs 08:56 < ghost43> you might end up with different orders 08:56 < ghost43> hence a different scriptPubKey for that first "address" in the chain 08:57 < ghost43> there are many fingerprints potentially for a bip32 node, given how much contextual information you have 08:57 < ghost43> pubkeys in the scriptCode are self-contained 08:57 < ghost43> it's the multi() output script descriptors that has a design issue, not the other way around. you are just trying to come up with a workaround that keeps the descriptor as is 08:58 < ghost43> but the actual solution would be to introduce a new descriptor, sorted-multi 08:58 < instagibbs> provoostenator, here's to hoping :) 08:58 < provoostenator> Descriptors aren't set in stone, so changing them does seem like an option. 08:58 < ghost43> the best solution would have been to design multi as sorted-multi in the first place, but that ship has sailed 08:58 < provoostenator> The recovery scenario I had in mind is this: plug in a bunch of hardware wallets, then have software bruteforce the various thresholds. 08:59 < provoostenator> That scenario works with BIP67 as well as with BIP32-fingerprint ordering, I think. 09:01 < instagibbs> descriptors are meant to be able to describe Core wallet entries 09:01 < instagibbs> so there'd have to be both 09:01 < provoostenator> instagibbs: we don't store them yet though 09:01 < instagibbs> Core wallet lets you import any ordering, so it needs to be representable 09:02 < provoostenator> And inferred descriptors don't use wildcards 09:02 < instagibbs> ranged is a different story sure 09:02 < instagibbs> but the oredering in multi matters is my point 09:02 < instagibbs> and it would be surprising to suddenly be different with * 09:03 < provoostenator> Yeah, so multi67() it is then :-) 09:03 < instagibbs> now to plug that into miniscript.... 09:04 < instagibbs> I wonder what they do there 09:05 < instagibbs> oh of course miniscript is agnostic to these choices 09:24 < provoostenator> ghost43: I'm not sure what you mean with the "how much contextual information" argument. 09:25 < provoostenator> Do you mean using the fingerprint of a deeper deriviation path? 09:25 < ghost43> yes, see the example I gave immediately before that comment 09:25 < provoostenator> But in that case, you have to remember your custom deriviation path, and you'll always know the new "master" fingerprint. 09:27 < ghost43> imagine you have 2 xpubs, you take the first pubkey along some path from them both, and then you create a single multisig 2of2 from those two pubkeys. now if you create a multisig 2of2 from the two xpubs, specifying the same derivation path and a range with a wildcard, it would be nice if the address created at the beginning would be part of the HD wallet 09:27 < provoostenator> If you don't remember the derivation path of that xpub, you'll never be able to spend. 09:28 < provoostenator> I would say that a "single multisig 2of2 from those two pubkeys" is really a different wallet. 09:29 < ghost43> but with your suggested scheme of using fingerprints it would be probabilistic if they are subwallets of each other or not! 09:29 < ghost43> with bip67 it is deterministic 09:29 < ghost43> "is really a different wallet" < 50 % of the time you mean 09:30 < provoostenator> It's still deterministic if that signle key wallet use its account xpub. 09:30 < provoostenator> It's seem rather contrived to grab a key from an HD wallet and then treat it as a non-HD key. 09:31 < ghost43> it's a frequent request by users of electrum 09:31 < ghost43> apparently many darknet markets use single address multisig 09:31 < ghost43> where users need to specify their own pubkey 09:31 < ghost43> and a 2of3 is created 09:31 < ghost43> i.e. derivation information lost 09:32 < ghost43> it is a real world usecase 09:32 < provoostenator> Those wallets sound unrecoverable 09:32 < provoostenator> They presumably don't even use the same index? 09:34 < ghost43> yes you are right, in that case it's not about recovering from HD keys 09:34 < provoostenator> That use case could be a good argument to treat those as "m/" wallets add the fingerprint of each used pubkey to any PSBT. 09:34 < provoostenator> That way, when trying to recover, your wallet can use a previous PSBT to at least find the right index by brute force. 09:36 < provoostenator> Though this ad hoc "wallet" wouldn't have a change address. You'd really want to spend it all in one go. 09:36 < ghost43> yes the darknet multisig usecase is about escrow, no need for change 09:37 < provoostenator> Maybe something like BIP322 signatures can be combined with PSBT. https://github.com/bitcoin/bips/blob/master/bip-0322.mediawiki 09:37 < provoostenator> In order to prove that the escrow is actually spendable, you'd create a joint signature. The signature metadata could be stored in a PSBT like format. 09:38 < provoostenator> That can be used a metadata backup as well. 09:38 < ghost43> I don't like the fingerprint approach, as there are many possible nodes to consider the fingerprint of. in electrum, if you restore from a bip39 seed, we don't store the whole derivation path you specify during wallet creation. we derive an xprv that is going to be the root from the wallet's perspective and only store that. so if someone has the full derivation they would derive different addresses because of different pubkey-ordering 09:38 < provoostenator> And I suppose for privacy reasons you want to be able to make multiple mutlisig addresses without revealing your master fingerprint to other parties. 09:40 < provoostenator> Why would you not store the full deriviation path? That sounds like it makes a future restore really hard. 09:41 < provoostenator> A BIP39 + descriptors + transaction nodes should be all you need for a full backup 09:41 < provoostenator> *notes 09:42 < ghost43> for historical reasons I guess. it was never needed in the past for anything. and electrum seeds are superior in that they encode a derivation path and script type implicitly, so only bip39 would want this. bip39 was implemented as an afterthought when multibit died, to allow those users to migrate 09:46 < ghost43> the point is not that electrum does that but rather that this is an approach of doing things which does not play well with fingerprint-based-pubkey-ordering 09:48 < provoostenator> I don't think that's true. As long as each wallet is consistant. Electrum can just use the account level as m/ 09:50 < provoostenator> But if you want wallet compatibility, then you need a standard like BIP44/49/84, and in that case the wallet should be aware of the master fingerprint. 09:50 < provoostenator> I assume Electrum knows this anyway, because it needs to communicate the full deriviation to any connected hardware wallet. 09:50 < ghost43> hw wallets are special-cased yes, they do have full paths 09:52 < ghost43> but you are missing the point I think. say I have two trezors. say I use bitcoin core and hwi to create a 2of2 multisig. I specify paths m/48'/0'/0'/2'/0/i for receive addresses and m/48'/0'/0'/2'/1/j for change. then in electrum I do the same. now electrum will see paths as m/0/i and m/1/j. the user expects the same addresses but only 50% of them will be the same. 09:52 < provoostenator> Right, I guess there's (at least) two multi sig use cases to think about: multiple hardware wallets, and more ad hoc escrow between walelts that may or may not be hardware 09:52 < ghost43> with bip67, everything works out 09:53 < provoostenator> But Electrum has to know the full deriviation in your example, so why ignore it? 09:54 < ghost43> if they are trezors then yes. but if they are not hardware wallets then no it does not need to know it. 09:54 < ghost43> it could just be given xprvs at some intermediate derivation 09:54 < provoostenator> Both fingerprints and BIP67 require some thinking from wallet developers. Neither is "free". 09:55 < ghost43> bip67 is an existing standard in use by electrum since 2015, also used by Armory and potentially others 09:55 < ghost43> are there any existing implementations that use fingerprint based sorting? 09:55 < ghost43> why come up with a new standard? when it's not even better, at best not worse 09:55 < provoostenator> Right, so backwards compatibilty can be a good argument for BIP67. But I'm trying to see if that's the _only_ argument for it. 09:56 < ghost43> what is the argument for fingerprint based sorting is my question then :) 09:56 < provoostenator> Not needing BIP67 09:56 < provoostenator> Only needing to figure out sorting at wallet creation and recovering time. 09:57 < ghost43> well the argument for bip67 then is not needing fingerprint-based sorting >.< :) 09:57 < provoostenator> And not having to put much thinking into how BIP67 would apply to something more complicated like a taproot with various timelocks. 09:58 < provoostenator> BIP67 requires sorting every time you derive an address, rather than once. 09:58 < ghost43> it's negligible computation to do that 09:58 < ghost43> the EC operations are vastly more expensive 09:58 < ghost43> you can even sort it in linear time as they are constant sized pubkeys 09:58 < provoostenator> Code complexity is the issue here, not computation 10:01 < provoostenator> I don't know how much complexity, maybe it's not too bad. instagibbs has the most experience with multisig here probably, with liquid 10:01 < instagibbs> it's not a lot, I'm not super excited or against it :P 10:01 < provoostenator> I also wonder what the impact is on threshold schemes 10:01 < instagibbs> MuSig requires an ordering anyways 10:01 < provoostenator> Ah, that's interesting, what kind of ordering does MuSig enforce? 10:02 < instagibbs> well, you need an ordering so you can all tweak keys the same way 10:02 < provoostenator> Ah, but you don't know the public key until you've done the ordering 10:02 < provoostenator> Which seems a (small) argument in favor of ordering by fingerprint. 10:02 < instagibbs> you know individual keys but not the inner key 10:02 < provoostenator> Oh, no then. 10:03 < instagibbs> to me it's just a bit weird that ordering of keys flops around, if there's no privacy gain 10:03 < instagibbs> bip67 in context of bitcoin today at least has the theoretical privacy gain of not learning which key corresponds to what slot 10:05 < provoostenator> On chain privacy, that's an argument I hadn't thought of yet. 10:05 < instagibbs> isn't that the main benefit for bip67? :) 10:05 < instagibbs> like bip69 but for pubkeys 10:06 < instagibbs> taproot, at least the outer keys(taproot output, inner pubkey) don't matter 10:06 < provoostenator> Right, maybe just make it random then? 10:06 < instagibbs> :shrug: 10:06 < ghost43> good luck restoring from seed words if it's random 10:07 < instagibbs> eh it's stupid but not broken 10:08 < instagibbs> I think fixed or sorted lexigraphically are both fine in reality, multisig is very imprinting right now 10:08 < provoostenator> JK, it's just that folks suggest randomness instead of BIP69 :-) 10:09 < instagibbs> in Core we were doing reverse BIP69 for outputs ;P 10:09 < instagibbs> accidentally 10:09 < provoostenator> Speaking of deriviations. Is the 48h/1h/0h/2h standard documented anywhere? 10:09 < provoostenator> In particular, does that explictly menion BIP67? 10:10 < ghost43> nah, I came up with it because there was no standard 10:10 < ghost43> let me find PRs 10:12 < ghost43> https://github.com/spesmilo/electrum/pull/4465 https://github.com/spesmilo/electrum/issues/4352 10:17 < provoostenator> ghost43: I saw that comment recently. I was really hoping there was more to the standard than that :-) 10:17 < ghost43> unless someone wrote something after-the-fact, then no 10:17 < provoostenator> And although not written, this assumes BIP67? At least from what I saw today on ColdCard it seems to. 10:19 < ghost43> at the time, no one seemed interested in segwit multisig for bip39/hw wallets; except for electrum users. we already had segwit multisig if you were using an electrum seed or Ypub/Zpub but not bip39. I asked around; what the best derivation path would be, but apart from johoe there, no one had constructive input. 10:19 < ghost43> provoostenator: electrum uses bip67 internally for all multisig; so I assume coldcard wrote their code to conform to that then 10:20 < provoostenator> Yeah, I think the time is more ripe now for standardization. 10:20 < provoostenator> now-ish I mean, could still be a year :-) 10:21 < provoostenator> I'll modify this PR to either use a new multi67() descriptor or a different derivation path: https://github.com/bitcoin/bitcoin/pull/16895 10:23 < ghost43> I would really like sorted-multi / multi67 descriptor because at some point we might use descriptors in electrum and we would simply need that to describe current wallets 10:24 < instagibbs> seems reasonable, provoostenator make it a base PR please :) 10:25 < provoostenator> instagibbs: I'm not putting multi-sig into a non-descriptor wallet, so you'll just have to get achow101's mega-PRs merged. 10:25 < provoostenator> Deploy the lizards! 10:26 < instagibbs> non-keypool import, fair enough tho 10:30 < achow101> we can just add more descriptor types 10:30 < achow101> I would rather have both sorted and unsorted multi descriptors 10:30 < instagibbs> achow101, you're late, it's already been decided 10:30 < achow101> I read the first third of the convo, and the last third :p 10:32 < ghost43> sorting is also a requirement in bip45 btw, which copay wrote. so I assume they sort too https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki#address-generation-procedure 10:33 < achow101> istm bip45 and bip67 describe the same thing? 10:33 < achow101> ah, 45 also specifies derivation paths 10:33 < instagibbs> provoostenator, if you make transactions internally be psbt-like, I think bip69-ing it becomes pretty trivial too 10:33 < instagibbs> optional flag 10:34 < achow101> bip69 is dumb :) 10:35 < provoostenator> Meanwhile, you can use the existing multi() descriptor by just skipping address indexes that violate BIP67 10:35 * provoostenator ducks 10:36 < ghost43> :D 10:37 < achow101> also, I'm pretty sure it's easy to add a sortedmulti() to core right now. I'll probably take a crack at it today 10:43 -!- justinmoon [~manjaro-i@cpe-70-112-175-160.austin.res.rr.com] has joined ##hwi 10:47 -!- justinmoon_ [~quassel@157.245.122.126] has joined ##hwi 10:47 -!- justinmoon [~manjaro-i@cpe-70-112-175-160.austin.res.rr.com] has quit [Remote host closed the connection] 10:49 -!- justinmoon_ [~quassel@157.245.122.126] has quit [Client Quit] 10:51 -!- justinmoon [~quassel@157.245.122.126] has joined ##hwi 11:56 < provoostenator> Turns out justinmoon was way ahead of me: https://github.com/justinmoon/junction/blob/master/junction.py#L205 11:57 < justinmoon> That sucks big time. Makes large multisigs not possible 11:58 < provoostenator> Sorting a list is cheap. But you might hit the gap limit. So a sortedmulti() descriptor is a better solution. 11:59 < provoostenator> Though Bitcoin Core keeps 1000 entries around, so the BIP44 gap limit of 20 isn't an issue there. 13:02 < instagibbs> you could generate each entry yourself instead of using ranged descriptors :troll: 13:13 < justinmoon> descriptors are a scam!