Re: [bitcoin-dev] Taproot proposal
> >> >> Some way to sign an additional script (not committed to by the witness >> program) seems like it could be a trivial addition. > > It seems to me the annex can be used for this, by having it contain both the > script and the signature somehow concatenated. This is not possible since the whole annex is signed. It is possible if the signed “script” does not require further input, like per-input lock-time, relative lock-time, check block hash > > Regards, > ZmnSCPxj > ___ > bitcoin-dev mailing list > bitcoin-dev@lists.linuxfoundation.org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Adding xpub field to PSBT to make multisig more secure
> Therefore, the input==output check is sufficient: if I use the same > set of signers for an input and an output, I can be sure that the > change goes to the same multisig wallet. This is sufficient, in a simple case. I consider cases where spending from different wallets ('wallet compartments') can be aggregated into one transaction, for efficiency and convenience in certain circumstances. (ex: legacy addresses that cannot be abandoned due to users still sending to them, but managing them separately is inconvenient; wallet 'compartments' that each have different multisig policies and spending priorities, and change would go to most secure compartment used, etc.) This is most likely a 'borader problem', as you said, but this is just what my code already does, although with stateful signers that store trusted xpubs. I had an idea how to apply this to stateless hw wallets, and shared it. > > This would allow to distinguish the trusted output even if the > > inputs are not all derived from the same set of xpubs, that could > > happen in more complex scenarios (batching, key rotation, etc.), > > and can possibly be used to have several different types of > > 'trusted' outputs. > > This seems to be an attempt at a different, much broader problem. And > it won't help if the attacker can replay a different trusted-xpub > package (e.g., one that contains a revoked previously compromised > key). The auxiliary text can be constructed to include some code word that would mark 'epoch' of the package, and will be displayed prominently. Upon compromise, new trusted-xpub packages would use different 'epoch' code word. This is one method to make it stateless (stateful way would be to just have a counter inside hw wallet and check package version against it). ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Adding xpub field to PSBT to make multisig more secure
hello, On 07. 05. 19 15:40, Dmitry Petukhov via bitcoin-dev wrote: > At the setup phase, hardware wallet can sign a message that consists of > xpubs of participants, and some auxiliary text. It can use the key > derived from the master key, with path chosen specifically for this > purpose. This seems overly complicated. What is your threat model? IIUC, each individual multisig signature also signs the set of signers (through signing redeem-script (or scriptPubKey in address-based multisig)) So if an attacker gives me bad xpubs, i will sign them, but the signature won't be valid for the given multisig output - even if the attacker manages to trick 2 of 3 signers and recombine their signatures. Therefore, the input==output check is sufficient: if I use the same set of signers for an input and an output, I can be sure that the change goes to the same multisig wallet. Or is there something I'm missing? The weak spot is the part where you generate receiving address, because that "creates" the particular multisig wallet. But that's nothing to do with PSBT. > This would allow to distinguish the trusted output even if the inputs > are not all derived from the same set of xpubs, that could happen in > more complex scenarios (batching, key rotation, etc.), and can possibly > be used to have several different types of 'trusted' outputs. This seems to be an attempt at a different, much broader problem. And it won't help if the attacker can replay a different trusted-xpub package (e.g., one that contains a revoked previously compromised key). regards m. ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Taproot proposal
On Monday 06 May 2019 20:17:09 Luke Dashjr via bitcoin-dev wrote: > Some way to sign an additional script (not committed to by the witness > program) seems like it could be a trivial addition. This would be especially useful for things like OP_CHECKBLOCKATHEIGHT: https://github.com/bitcoin/bips/blob/master/bip-0115.mediawiki ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Taproot proposal
Good morning Sjors, sorry everyone for the double-posting... > I believe this is the "hash to a point" technique. > > The scalar behind the above point cannot be known, unless either the hash > function is broken, or ECDLP is broken. > (perhaps a better cryptographer can give the proper qualifications, any > corrections, and etc etc) > > As the point is just an arbitrary point on the curve, it is unknown to the > rest of the world whether somebody knows the scalar, or nobody knows. Now that I think further, everyone can use *the same* point generated from an arbitrary "hash to a point". For example, we can define the "script-only point" as the point whose X coordinate (or is it Y...) is equal to SHA256("Pieter Wuille is really great!"). Add more "really " until we get a point on the curve. Provided everyone knows what the exact data to hash is, and the exact hash function, the above procedure is sufficient for everybody to verify that Pieter Wuille (and anyone else for that matter) cannot, in fact, spend the coin unilaterally, and that nobody can actually spend the coin, except via a script. Since the point on the output is tweaked by the script merkle tree root, varying your pubkey for each use will be enough to blind the use of the "script-only point" until you have to reveal it during spending anyway. If you *absolutely* insist on reusing your pubkeys, then adding a `OP_PUSH() OP_DROP` to at least one script, with a random salt, should be enough to blind the use of the script-only point until you have to reveal the script you want to use. Or even just further tweak the point before using it as the taproot internal pubkey, so that not even a coin spend reveals that the "everyone agrees" branch was never actually an option. > Or just use pubkeys given by both participants, that should be enough to > ensure the "everyone agrees" branch is never taken if we write our software > such that we never agree to sign with it (i.e. just get points from both > sides and MuSig them; then each side can just erase the scalar generating it > from memory and whatever caches exist on the system; a node might even just > generate a single random point from a scalar it subsequently erases, and just > use some non-hardened derivation path from that for every HTLC it has to > make). > This technique is "sufficiently provably unknown" since each participant > knows that it deliberately erased the only means of knowing the complete > discrete log by erasing its share. > In short, "everyone agrees" is trivially easy to make "nobody can agree" by a > single participant never agreeing to let itself be ripped off. > The "taproot assumption" is that there exists some finite set of participants that is interested in how the coin will be spent. Under the taproot assumption then, any "truster" that assigns time-limited control of a coin to a "trustee" is part of that finite set interested in the coin spend conditions. So the truster should in fact be asked for a pubkey to be added in the taproot internal pubkey that enables the "everyone agrees" branch. Then the truster can simply generate a point without knowing its private key, or by forgetting this private key. If one is sufficiently schizophrenic, one can split oneself into a "truster" and "trustee" as above and deliberately forget the truster private key. Then one is sufficiently unable to spend under duress by deleting the "truster" sub-agent and providing real-world access to the "trustee" sub-agent that can only spend under specific SCRIPT-defined conditions. (the above paragraph should not be taken to mean that I am an agent-based AI) That is, it should be enough for everyone to agree to lock the "everyone agrees" branch and throw away their own key, to keep that branch locked. Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Taproot proposal
Good morning Sjors, Sent with ProtonMail Secure Email. ‐‐‐ Original Message ‐‐‐ On Wednesday, May 8, 2019 4:42 AM, Sjors Provoost via bitcoin-dev wrote: > Hey Pieter, > > I think this is a reasonable collection of changes that make sense in > combination. Some initial feedback and questions. > > From the BIP: > > > If one or more of the spending conditions consist of just a single key > > (after aggregation), > > he most likely one should be made the internal key. If no such condition > > exists, it may > > be worthwhile adding one that consists of an aggregation of all keys > > participating in all > > scripts combined; effectively adding an "everyone agrees" branch. If that > > is inacceptable, > > pick as internal key a point with unknown discrete logarithm (TODO). > > I assume Luke Dashjr referred to the above when saying: > > > Is there any way to use the Taproot construct here while retaining external > > script limitations that the involved party(ies) cannot agree to override? > > For example, it is conceivable that one might wish to have an unconditional > > CLTV enforced in all circumstances. > > One reason why someone would want to avoid a "everone agrees" branch, is > duress (or self-discipline, or limiting powers of a trustee). In particular > with respect to time-locks. > > Can this "unknown discrete logarithm" be made provably unknown, so all > signers are assured of this property? Bonus points if the outside world can't > tell. The exact mechanism could be outside the scope of the BIP, but knowing > that it's possible is useful. As I understand it, it is possible to take some random data, hash it with SHA256 and acquire a 256-bit number. Then treat that number as an X coordinate (or is it Y...), and see if there exists a point on the secp256k1 curve at that coordinate. If not, try another random data, or just hash the same number again. As I understand it, about half the possible X coordinates will have a point on the curve. I believe this is the "hash to a point" technique. The scalar behind the above point cannot be known, unless either the hash function is broken, or ECDLP is broken. (perhaps a better cryptographer can give the proper qualifications, any corrections, and etc etc) As the point is just an arbitrary point on the curve, it is unknown to the rest of the world whether somebody knows the scalar, or nobody knows. > > Perhaps Lightning devs have an opinion on "everyone agrees" with respect to > hash pre-images. I suspect there is no benefit in guaranteeing that a > pre-image must be revealed or a timeout must be waited for and there's no way > around that condition. The "everyone agrees" branch in Lightning is basically the "cooperative close" of the channel. So it is not likely we will need an "everyone agrees" branch in the actual HTLCs we transfer *within* the channel. So if we need to use hashes still, we will likely use the "hash to a point" technique above. Or just use pubkeys given by both participants, that should be enough to ensure the "everyone agrees" branch is never taken if we write our software such that we never agree to sign with it (i.e. just get points from both sides and MuSig them; then each side can just erase the scalar generating it from memory and whatever caches exist on the system; a node might even just generate a single random point from a scalar it subsequently erases, and just use some non-hardened derivation path from that for every HTLC it has to make). This technique is "sufficiently provably unknown" since each participant knows that it deliberately erased the only means of knowing the complete discrete log by erasing its share. In short, "everyone agrees" is trivially easy to make "nobody can agree" by a single participant never agreeing to let itself be ripped off. Do note that it is likely Lightning will eventually switch to using payment points/scalars instead of hashes/preimages. This will allow us to have path decorrelation, both within a route, and in multiple routes of the same payment. This is enabled by Schnorr, as this requires Scriptless Script. (granted 2p-ECDSA also enables Scriptless Script, but we decided to wait for Schnorr to hit base layer instead) This means we would be using the "everyone agrees" path only, with everyone agreeing to first create a `nLockTime` backout tx, then everyone agreeing to create a transaction where one side has knowledge of a secret scalar that is learned by the other side upon completion of the signature. Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Taproot proposal
Good morning Luke, > Is there any way to use the Taproot construct here while retaining external > script limitations that the involved party(ies) cannot agree to override? > For example, it is conceivable that one might wish to have an unconditional > CLTV enforced in all circumstances. Perhaps this can be enforced offchain, by participants refusing to sign a transaction unless it has an `nLockTime` of the agreed-upon "unconditional CLTV". Then the CLTV need only be on branches which have a strict subset of the participants as signers. > > It may be useful to have a way to add a salt to tap branches. Would not adding `OP_PUSH() OP_DROP` to the leaves work? If you enforce always salting with a 32-byte salt, that "only" saves 3 bytes of witness data (for the `OP_PUSHDATA1+size` and `OP_DROP` opcodes). Or do you refer to always salting every node? (I am uncertain, but would not adding a salt to every leaf be sufficient?) (in any case, if you use different pubkeys for each contract, rather than reusing keys, is that not enough randomization to prevent creating rainbow tables of scripts?) > > Some way to sign an additional script (not committed to by the witness > program) seems like it could be a trivial addition. It seems to me the annex can be used for this, by having it contain both the script and the signature somehow concatenated. Regards, ZmnSCPxj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Re: [bitcoin-dev] Taproot proposal
Thanks for the comments so far! I'm going to respond to some of the comments here. Things which I plan to address with changes in the BIP I'll leave for later. On Mon, 6 May 2019 at 13:17, Luke Dashjr wrote: > Tagged hashes put the tagging at the start of the hash input. This means > implementations can pre-cache SHA2 states, but it also means they can't reuse > states to produce data for different contexts. (I'm not sure if there is a > use for doing so... but maybe as part of further hiding MAST branches?) It's true you can't cache/precompute things across tags, but I also think there is no need. The type of data hashed in a sighash vs a merkle branch/leaf vs a tweak is fundamentally different. I think this is perhaps a good guidance to include about when separate tags are warranted vs. simply making sure the input does not collide: there shouldn't be much or any shared data with things that are expected to be inputs under other tags. > Is there any way to use the Taproot construct here while retaining external > script limitations that the involved party(ies) *cannot* agree to override? > For example, it is conceivable that one might wish to have an unconditional > CLTV enforced in all circumstances. Yes, absolutely - you can use a point with unknown discrete logarithm as internal key. This will result in only script path spends being available. For the specific goal you're stating an alternative may be using a valid known private key, using it to pre-sign a timelocked transaction, and destroying the key. > It may be useful to have a way to add a salt to tap branches. If you don't reuse public keys, effectively every branch is automatically salted (and the position in the tree gets randomized automatically when doing so, providing a small additional privacy benefit). >> Some way to sign an additional script (not committed to by the witness >> program) seems like it could be a trivial addition. > This would be especially useful for things like OP_CHECKBLOCKATHEIGHT: > https://github.com/bitcoin/bips/blob/master/bip-0115.mediawiki If you're talking about the ability to sign over the ability to spend to another script ("delegation"), there are lots of interesting applications and ways to implement it. But it overlaps with Graftroot, and doing it efficiently in general has some interesting and non-obvious engineering challenges (for example, signing over to a script that enforces "f(tx)=y" for some f can be done by only storing f and then including y in the sighash). For the specific example of BIP115's functionality, that seems like a reasonable thing that could be dealt with using the annex construction in the proposed BIP. A consensus rule could define a region inside the annex that functions as a height-blockhash assertion. The annex is included in all sighashes, so it can't be removed from the input; later opcodes could include the ability to inspect that assertion even. On Tue, 7 May 2019 at 13:43, Sjors Provoost wrote: > One reason why someone would want to avoid a "everone agrees" branch, is > duress (or self-discipline, or limiting powers of a trustee). In particular > with respect to time-locks.> Indeed, though as I suggested above, you can also use timelocked transactions (but using only CLTV branches is more flexible certainly). > Can this "unknown discrete logarithm" be made provably unknown, so all > signers are assured of this property? Bonus points if the outside world can't > tell. The exact mechanism could be outside the scope of the BIP, but knowing > that it's possible is useful. Yes, that's a TODO that's left in the draft, but this is absolutely possible (using a hash-to-curve operation). As ZmnSCPxj already suggested, there can even be a fixed known constant you can use for this. However, you get better privacy by taking this fixed known constant (call it C) and using as internal key a blinded version of it (C+rG, for some random value r, and G the normal secp256k1 generator); as long as the DL between G and C is unknown, this is safe (and does not reveal to the world that in fact no key-path was permitted when spending). > Regarding usage of Schnorr: do I understand correctly that the "everyone > agrees" internal key MUST use Schnorr, and that individual branches MAY use > Schnorr, but only if they're marked as tapscript spend? > > Why is tapscript not mandatory? Spending using the internal key always uses a single Schnorr signature and nothing else. When you spend using a script path, you must reveal both the script and its leaf version. If that leaf version is 0xc0, the script is interpreted as a tapscript (in which only Schnorr opcodes exist). If that leaf version is not 0xc0, the script is undefined, and is unconditionally valid. This is one of the included extension mechanisms, allowing replacing the whole script language with something else, but without revealing it unless a branch using it is actually used (different Merkle tree leaves can have a distin
Re: [bitcoin-dev] Taproot proposal
On Mon, May 06, 2019 at 08:17:09PM +, Luke Dashjr via bitcoin-dev wrote: > Some way to sign an additional script (not committed to by the witness > program) seems like it could be a trivial addition. Aside: if you want to commit to something extra *with* the witness program, you could use either an unsolvable tapleaf branch (eg, one that uses OP_RETURN and also pushes the data you want to commit to), or a p2c construction like: Taproot: Q = P + H_TapTweak(P || S)*G P2C: P = R + H_"myp2c"(R || Contract)*G If you don't have any scripts for S, you could set S=["OP_RETURN"] to ensure there are no scripts. Having either the TapTweak formula or the H_myp2c hash should be enough to ensure that your contract can't get maliciously reinterpreted as a valid tapscript, having both is just belts and suspenders. But to address your question: if you want to commit to something extra at spending/signing time rather than when creating the address, then that's what the annex should be useful for. eg as a simple example, your annex might be: 0x50 [flag] 0x25 [entry size] 0x77 [annex entry id] 0x0008c618 [block height == 575000] 0x0007df59824a0c86d1cc21b90eb25259dd2dba5170cea5f5 [block hash for block at 575000] which would allow you to commit to a particular block hash, and there could be a soft fork that added the restriction that such a commitment invalidates the transaction if the block at the given height doesn't match the provided hash. You still need to the soft-fork to do the enforcing, but once you have that, *every* existing taproot address automatically gets "upgraded" to allow you to make the commitment, including via key path spends, which seems pretty nice. (That construction (ie size,id,data) lets you have multiple entries in the annex reasonably efficiently) Cheers, aj ___ bitcoin-dev mailing list bitcoin-dev@lists.linuxfoundation.org https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev