public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Pieter Wuille <pieter.wuille@gmail•com>
To: "David A. Harding" <dave@dtrt•org>,
	Bitcoin Dev <bitcoin-dev@lists•linuxfoundation.org>
Subject: Re: [bitcoin-dev] Bech32 weakness and impact on bip-taproot addresses
Date: Sun, 10 Nov 2019 13:51:48 -0800	[thread overview]
Message-ID: <CAPg+sBgus6HgYPVbXaAx51nO2ArsR3-6=obe2AwkO8kh11fB6Q@mail.gmail.com> (raw)
In-Reply-To: <20191108021541.n3jk54vucplryrbl@ganymede>

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

On Thu, Nov 7, 2019, 18:16 David A. Harding <dave@dtrt•org> wrote:

> On Thu, Nov 07, 2019 at 02:35:42PM -0800, Pieter Wuille via bitcoin-dev
> wrote:
> > In the current draft, witness v1 outputs of length other
> > than 32 remain unencumbered, which means that for now such an
> > insertion or erasure would result in an output that can be spent by
> > anyone. If that is considered unacceptable, it could be prevented by
> > for example outlawing v1 witness outputs of length 31 and 33.
>
> Either a consensus rule or a standardness rule[1] would require anyone
> using a bech32 library supporting v1+ segwit to upgrade their library.
> Otherwise, users of old libraries will still attempt to pay v1 witness
> outputs of length 31 or 33, causing their transactions to get rejected
> by newer nodes or get stuck on older nodes.  This is basically the
> problem #15846[2] was meant to prevent.
>
> If we're going to need everyone to upgrade their bech32 libraries
> anyway, I think it's probably best that the problem is fixed in the
> bech32 algorithm rather than at the consensus/standardness layer.
>

Admittedly, this affecting development of consensus or standardness rules
would feel unnatural. In addition, it also has the potential downside of
breaking batched transactions in some settings (ask an exchange for a
withdrawal to a invalid/nonstandard version, which they batch with other
outputs that then get stuck because the transaction does not go through).

So, Ideally this is indeed solved entirely on the bech32/address encoding
side of things. I did not initially expect the discussion here to go in
that direction, as that could come with all problems that rolling out a new
address scheme in the first place has. However, there may be a way to
mostly avoid those problems for the time being, while also not having any
impact on consensus or standardness rules.

I believe that most new witness programs we'd want to introduce anyway will
be 32 bytes in the future, if the option exists. It's enough for a 256-bit
hash (which has up to 128-bit collision security, and more than 128 bits is
hard to achieve in Bitcoin anyway), or for X coordinates directly. Either
of those, plus a small version number to indicate the commitment structure
should be enough to encode any spendability condition we'd want with any
achievable security level.

With that observation, I propose the following. We amend BIP173 to be
restricted to witness programs of length 20 or 32 (but still support
versions other than 0). This seems like it may be sufficient for several
years, until version numbers run out. I believe that some wallet
implementations already restrict sending to known versions only, which
means effectively no change for them in addition to normal deployment.

In the mean time we develop a variant of bech32 with better
insertion/erasure detecting properties, which will be used for witness
programs of length different from 20 or 32. If we make sure that there are
never two distinct valid checksum algorithms for the same output, I don't
believe there is any need for a new address scheme or a different HRP. The
latter is something I'd strongly try to avoid anyway, as it would mean
additional cognitive load on users because of another visually distinct
address style, plus more logistical overhead (coordination and keeping
track of 2 HRPs per chain).

I believe improving bech32 itself is preferable over changing the way
segwit addresses use bech32, as that can be done without making addresses
even longer. Furthermore, the root of the issue is in bech32, and it is
simplest to fix things there. The easiest solution is to simply change the
constant 1 that is xor'ed into the checksum before encoding it to a 30-bit
number. This has the advantage that a single checksum is never valid for
both algoritgms simultaneously. Another approach is to implicitly including
the length into the checksummed data.

What do people think?

Cheers,

-- 
Pieter

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

  parent reply	other threads:[~2019-11-10 21:52 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-07 22:35 Pieter Wuille
2019-11-07 22:45 ` Greg Sanders
2019-11-08  0:41   ` Matt Corallo
2019-11-08  2:15 ` David A. Harding
2019-11-08  3:15   ` Eric Voskuil
2019-11-10 21:51   ` Pieter Wuille [this message]
2019-11-11  1:02     ` Matt Corallo
2019-11-13  2:56       ` Clark Moody
2019-11-13  5:32         ` ZmnSCPxj
2019-11-13  6:30           ` Pieter Wuille
2020-07-15 20:56             ` Russell O'Connor
2020-07-15 21:05               ` Greg Sanders
2020-07-15 21:11                 ` Russell O'Connor
2019-11-08  5:11 ` ZmnSCPxj
2019-11-08 13:03   ` Russell O'Connor
2019-11-08 13:42     ` Damian Mee

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAPg+sBgus6HgYPVbXaAx51nO2ArsR3-6=obe2AwkO8kh11fB6Q@mail.gmail.com' \
    --to=pieter.wuille@gmail$(echo .)com \
    --cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
    --cc=dave@dtrt$(echo .)org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox