Return-Path: Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id DD61CCAA for ; Mon, 17 Dec 2018 19:08:47 +0000 (UTC) X-Greylist: from auto-whitelisted by SQLgrey-1.7.6 Received: from sender-of-o51.zoho.com (sender-of-o51.zoho.com [135.84.80.216]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id A04647DB for ; Mon, 17 Dec 2018 19:08:46 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; t=1545073713; cv=none; d=zoho.com; s=zohoarc; b=IoQgA4zTII11nfGTrumm+je97KxzzgfEVJxJcLx0h0YSYri+2RkkutHRjPxd4IxpRt5Vzy+rhTK4xLICBrs+d3BERcvDDgm4QoTTQXbb1V9erBuw/YSwUlpttbBlR0DpCSau+iO03jUXLzSb/CJEgyAmc8iJO6f20BYzaBXKR/s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1545073713; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:To:ARC-Authentication-Results; bh=NeTy6BWtqLV9hQ1LZa/kDGRqlA2annd/PE6Hg7SZ0Iw=; b=nbp5sdXOGLr3xl4I692tjfJeTVXHZW2qV/s7X2rQNGqPQcVqhCLgWQfHaKjpWTbkg5vzBoF2REd+R5CJcW48T9an1gWcG4IfmXBkZuo/oLPt0Tnn6ZeR583HXMJvbQGNKvqHlJ22qdP7Eb17GQ68DVb8sicPuPGG4n0w3/qJ0/k= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass header.i=xbt.hk; spf=pass smtp.mailfrom=jl2012@xbt.hk; dmarc=pass header.from= header.from= Received: from [10.8.0.105] (n218103234118.netvigator.com [218.103.234.118]) by mx.zohomail.com with SMTPS id 1545073711035550.7491078070161; Mon, 17 Dec 2018 11:08:31 -0800 (PST) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 12.0 \(3445.100.39\)) From: Johnson Lau In-Reply-To: <8736qyhsej.fsf@rustcorp.com.au> Date: Tue, 18 Dec 2018 03:08:26 +0800 Content-Transfer-Encoding: quoted-printable Message-Id: <6DE5291C-629D-4080-9B0C-E18BEFA28B16@xbt.hk> References: <87ftv3xerx.fsf@rustcorp.com.au> <87pnu6s3v5.fsf@rustcorp.com.au> <87h8fiqn1z.fsf@rustcorp.com.au> <20181214093002.p2nvfrlaycqblww3@erisian.com.au> <8736qyhsej.fsf@rustcorp.com.au> To: Rusty Russell , bitcoin-dev X-Mailer: Apple Mail (2.3445.100.39) X-ZohoMailClient: External X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org X-Mailman-Approved-At: Tue, 18 Dec 2018 02:17:16 +0000 Subject: Re: [bitcoin-dev] Safer sighashes and more granular SIGHASH_NOINPUT X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 17 Dec 2018 19:08:48 -0000 > On 16 Dec 2018, at 2:55 PM, Rusty Russell via bitcoin-dev = wrote: >=20 > Anthony Towns via bitcoin-dev = writes: >> On Thu, Dec 13, 2018 at 11:07:28AM +1030, Rusty Russell via = bitcoin-dev wrote: >>> And is it worthwhile doing the mask complexity, rather than just >>> removing the commitment to script with NOINPUT? It *feels* safer to >>> restrict what scripts we can sign, but is it? >>=20 >> If it's not safer in practice, we've spent a little extra complexity >> committing to a subset of the script in each signature to no gain. If >> it is safer in practice, we've prevented people from losing funds. = I'm >> all for less complexity, but not for that tradeoff. >=20 > There are many complexities we could add, each of which would prevent > loss of funds in some theoretical case. Every security measures are overkill, until someone get burnt. If these = security measures are really effective, no one will get burnt. The = inevitable conclusion is: every effective security measures are = overkill. >=20 > =46rom practical experience; reuse of private keys between lightning = and > other things is not how people will lose funds[1]. Assuming an user holds a private key exclusively and securely, currently = there are only 2 ways to lose funds by private key reuse: 1. reusing the = same signature nonce; 2. signing the hash =E2=80=9Cone=E2=80=9D, for the = SIGHASH_SINGLE consensus bug. People lost money for the first reason. Since this is a feature of the = signature schemes we use, unavoidably that will happen again from time = to time. The second one has been fixed in segwit (though incompletely), = and could be completely fixed with a simple softfork. Overall speaking, while private key reuse hurts fungibility and privacy, = it is not terribly insecure, as long as you use rfc6979 and are not = foolish enough to sign hash =E2=80=9Cone=E2=80=9D. This actually thanks = to the fact that signatures always committed to the previous txid. It = makes sure that a signature is never valid for more than one UTXO. = Unfortunately, the guarantee of non-replayability incentified the = practice of key-reuse, since the day-one of bitcoin. While NOINPUT = fundamentally changes this security assumption, it won=E2=80=99t change = this long-established culture of key reuse. So you argument seems just begging the question. Without NOINPUT, it is = just impossible to lose money by key reuse, and this is exactly the = topic we are debating. >=20 > It *is* however non-trivially more complicated for wallets; they > currently have a set of script templates which they will sign (ie. no > OP_CODESEPARATOR) and I implemented BIP 143 with only the simplest of > naive code[2]. In particular, there is no code to parse scripts. Sorry that I=E2=80=99m not familiar with the implementation details of = your wallet. But as you don=E2=80=99t have code to parse scripts, I = assume your wallet can=E2=80=99t handle OP_CODESEPARATOR? However, this = is exactly what you should do: only implement what you actually need, = and ignore those unrelated details. Also, trying to faithfully and completely reproduce the consensus code = in a wallet (even if you don=E2=80=99t need that at all) could be = extremely dangerous. Such wallet might be tricked, for example, to sign = the hash =E2=80=9Cone=E2=80=9D and get all money stolen (I was told = someone really did that, but I don=E2=80=99t know the details) If you didn=E2=80=99t implement OP_CODESEPARATOR because you didn=E2=80=99= t use it, there is no reason for you to fully implement OP_MASKEDPUSH = nor script parsing. In existing signature schemes (e.g. BIP143), = signatures always commit to the script being executed (the = =E2=80=9CscriptCode=E2=80=9D). I assume that all wallets would = re-construct the scriptCode at signing time, based on the limited set of = script templates they support. If a wallet had a function called = GetScriptCodeForMultiSig() for this purpose, all they need now is a = GetMaskedScriptCodeForMultiSig() that returns the masked template, or a = new option in the existing GetScriptCodeForMultiSig(). It does not need = to be something like GetMaskedScript(GetScriptCodeForMultiSig()). After = all, only a very small number of script templates really need NOINPUT. A = GetMaskedScript() in a wallet is just an overkill (and a vulnerability = if mis-implemented)=20 >=20 > Bitcoind developers are not in a good position to assess complexity > here. They have to implement *everything*, so each increment seems > minor. In addition, none of these new script versions will ever make > bitcoind simpler, since they have to support all prior ones. Wallets, > however, do not have to. >=20 > I also think that minimal complexity for (future) wallets is an > underappreciated feature: the state of wallets in bitcoin is poor[3] > so simplicity should be a key goal. It is a 3-way tradeoff of security, complexity, and functionality. While = not everyone might appreciate this, security seems to always be the = dominent factor in bitcoin protocol development. It was the reason why = most core contributors were hesitant towards BIP148, despite they all = love the functionality of segwit. It=E2=80=99s also about functionality here: as I mentioned in another = reply, OP_CODESEPARATOR couldn=E2=80=99t function properly with NOINPUT = but without OP_MASKEDPUSH This debate happens because NOINPUT introduces the third way to lose = fund with key reuse. And once it is deployed, we have to support it = forever, and is not something that we could softfork it away. >=20 > Respectfully, > Rusty. >=20 > [1] Reusing your revocation base point across two channels will lose > funds in a much more trivial way, as will reusing payment hashes > across invoices. > [2] In fact, I added SIGHASH_ANYONECANPAY and SIGHASH_SINGLE recently > for Segwit and it worked first time! Kudos to BIP143's authors for > such a clear guide. > [3] Bitcoind's wallet can't restore from seed; this neatly = demonstrates > how hard the wallet problem is, but there are many others. >=20 >=20 >=20 >=20 >=20 >=20 >=20 >=20 >=20 >=20 >=20 >=20 > code, as modern wallets currently don't have to parse the scripts they > sign. >=20 >=20 >=20 >=20 >=20 >=20 >=20 > I'm telling you that this is not how people are losing funds. >=20 >=20 >=20 >>=20 >> Also, saying "I can't see how to break this, so it's probably good >> enough, even if other people have a bad feeling about it" is a crypto >> anti-pattern, isn't it? >>=20 >> I don't see how you could feasibly commit to more information than = script >> masking does for use cases where you want to be able to spend = different >> scripts with the same signature [0]. If that's possible, I'd probably >> be for it. >>=20 >> At the same time, script masking does seem feasible, both for >> lightning/eltoo, and even for possibly complex variations of scripts. = So >> committing to less doesn't seem wise. >>=20 >>> You already need both key-reuse and amount-reuse to be exploited. >>> SIGHASH_MASK only prevents you from reusing this input for a = "normal" >>> output; if you used this key for multiple scripts of the same form, >>> you're vulnerable[1]. >>=20 >> For example, script masking seems general enough to prevent footguns >> even if (for some reason) key and value reuse across eltoo channels >> were a requirement, rather than prohibited: you'd make the script be >> " MASK CLTV 2DROP CHECKSIG", and = your >> signature will only apply to that channel, even if another channel = has >> the same capacity and uses the same keys, a and b. >>=20 >>> So I don't think it's worth it. SIGHASH_NOINPUT is simply dangerous >>> with key-reuse, and Don't Do That. >>=20 >> For my money, "NOINPUT" commits to dangerously little context, and >> doesn't really feel safe to include as a primitive -- as evidenced by >> the suggestion to add "_UNSAFE" or similar to its name. Personally, = I'm >> willing to accept a bit of risk, so that feeling doesn't make me = strongly >> against the idea; but it also makes it hard for me to want to support >> adding it. To me, committing to a masked script is a huge = improvement. >>=20 >> Heck, if it also makes it easier to do something safer, that's also >> probably a win... >>=20 >> Cheers, >> aj >>=20 >> [0] You could, perhaps, commit to knowing the private keys for all = the >> *outputs* you're spending to, as well as the inputs, which comes >> close to saying "I know this is a scary NOINPUT transaction, but >> we're paying to ourselves, so it will all be okay". >> _______________________________________________ >> 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