Return-Path: Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 3FC94B2B for ; Thu, 1 Jun 2017 15:11:18 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-ua0-f169.google.com (mail-ua0-f169.google.com [209.85.217.169]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 9A58F193 for ; Thu, 1 Jun 2017 15:11:17 +0000 (UTC) Received: by mail-ua0-f169.google.com with SMTP id u10so29302444uaf.1 for ; Thu, 01 Jun 2017 08:11:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=blockstream-io.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=JQkEYhLSgFQs5QMMQImNlqzKw1NvmsziJXjBLf6AvUw=; b=eRh4iVYKLXGZK5SJ4/OkaXx6XuT8fGe2jqU7l7d9VfJi8u95GAJKWc3JhgDaeW2Xo+ QV+6vuW4Z8MtcXGPZ89t6BtZYlgZHTlRejMekgeKOf9yshMc/DA26IBJwRrMMqfQKTZc L2FpFRexDognzI3ZU90uFhh1zBEmSYcHCWHuLB+1niTnlIgjI0PSaZn9fk9NMmU6oV88 NToCxqiy8xwsfRZLcarAk0jck0oFEy1lqapTfhMuZ0ooMGL1kOFWzlIDqomv24poaKAh WQ3TetsQFLsdOnvo7/WEwHqymcQ86eVsqtAj4TihXPlHQwZCCJne/DFHJirdsRMjhH5a EfmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=JQkEYhLSgFQs5QMMQImNlqzKw1NvmsziJXjBLf6AvUw=; b=L+SMu7B6L2n8NOpbO/h/E/H5mhWZ7nXYY3+OBD06obF4ITVCdIADbkkNYehiyKxUEI Rwb0mfNcKsl3QKvpCBYZG5UQRt4232alY0jM0HaIFWpM8FbQGVyrPAQKgxxvYX7Je/1d 1iDKZMeifPggCeXuqAxY+kYPBhmqvzuUVkhOjZ2msBXF5gPo7LBqJGYINfsS57jyUlfg RTlxYLWRt6oj4iMGIOm1WnKiGLUFNTUx0Bu+MCrP4Xjyy97Udf69zwaC2vqrThG3pXLx xSHggyaZbapP+3oBn1PXR+NwQ7NITPFTuIF3AUPhj/9Ho9UBryR4f7XCM1/aoniq/D1L CUqw== X-Gm-Message-State: AODbwcDQE6EWy2mrBdpeISzIdD/zwlZSdFRP4ewwHpihoPZZnfz/RmhC KuhKBmDEaWycH+tE2fSiTSwTblNiEkjPHZs= X-Received: by 10.159.35.197 with SMTP id 63mr1079609uao.134.1496329876628; Thu, 01 Jun 2017 08:11:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.176.95.90 with HTTP; Thu, 1 Jun 2017 08:10:56 -0700 (PDT) In-Reply-To: <20170529161059.GA7698@fedora-23-dvm> References: <20170528082624.GA14552@fedora-23-dvm> <20170529161059.GA7698@fedora-23-dvm> From: "Russell O'Connor" Date: Thu, 1 Jun 2017 11:10:56 -0400 Message-ID: To: Peter Todd Content-Type: multipart/alternative; boundary="94eb2c03dfe6c381460550e772d4" X-Spam-Status: No, score=-1.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Bitcoin Protocol Discussion Subject: Re: [bitcoin-dev] A Method for Computing Merkle Roots of Annotated Binary Trees 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: Thu, 01 Jun 2017 15:11:18 -0000 --94eb2c03dfe6c381460550e772d4 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Mon, May 29, 2017 at 12:10 PM, Peter Todd wrote: > On Mon, May 29, 2017 at 10:55:37AM -0400, Russell O'Connor wrote: > > Some of this proposal can be salvaged, I think, by putting the hash of > the > > tags into Sha256Compress's first argument: > > > > merkleRoot : Tree BitString -> Word256 > > merkleRoot (Leaf (t)) :=3D sha256Compress(sha256(t), > > 0b0^512) > > merkleRoot (Unary (t, child)) :=3D sha256Compress(sha256(t), > > merkleRoot(child) =E2=8B=85 0b0^256) > > merkleRoot (Binary (t, left, right)) :=3D sha256Compress(sha256(t), > > merkleRoot(left) =E2=8B=85 merkleRoot(right)) > > > > The Merkle--Damg=C3=A5rd property will still hold under the same condit= ions > > about tags determining the type of node (Leaf, Unary, or Binary) while > > avoiding the need for SHA256's padding. If you have a small number of > > tags, then you can pre-compute their hashes so that you only end up wit= h > > one call to SHA256 compress per node. If you have tags with a large > amount > > of data, you were going to be hashing them anyways. > > Notice how what you're proposing here is almost the same thing as using > SHA256 > directly, modulo the fact that you skip the final block containing the > message > length. > > Similarly, you don't need to compute sha256(t) - you can just as easily > compute > the midstate sha256Compress(IV, t), and cache that midstate if you can > reuse > tags. Again, the only difference is the last block. > Yes, either way would be fine. > > Unfortunately we lose the ability to cleverly avoid collisions between > the > > Sha256 and MerkleRoot functions by using safe tags. > > I think a better question to ask is why you want that property in the fir= st > place? > > My earlier python-proofmarshal(1) library had a scheme of per-use-case > tags, > but I eventually realised that depending on tags being unique is a > footgun. For > example, it's easy to see how two different systems could end up using th= e > same > tag due to designers forgetting to create new tags while copying and > pasting > old code. Similarly, if two such systems have to be integrated, you'll en= d > up > with tags getting reused for two different purposes. > > Now, if you design a system where that doesn't matter, then by extension > it'll > also be true that collisions between the sha256 and merkleroot functions > don't > matter either. And that system will be more robust to design mistakes, as > tags > only need to be unique "locally" to distinguish between different > sub-types in > a sum type (enum). > I was looking to add the property mostly because it was free to do with my original design when the set of tags was small and could make some applications more robust and/or easier to debug. --94eb2c03dfe6c381460550e772d4 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Mon, May 29, 2017 at 12:10 PM, Peter Todd <pete@petertodd.org&= gt; wrote:
On Mon= , May 29, 2017 at 10:55:37AM -0400, Russell O'Connor wrote:
<= span class=3D"">> Some of this proposal can be salvaged, I think, by put= ting the hash of the
> tags into Sha256Compress's first argument:
>
>=C2=A0 =C2=A0 =C2=A0merkleRoot : Tree BitString -> Word256
>=C2=A0 =C2=A0 =C2=A0merkleRoot (Leaf (t))=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 :=3D sha256Compress(sha256(t),
> 0b0^512)
>=C2=A0 =C2=A0 =C2=A0merkleRoot (Unary (t, child))=C2=A0 =C2=A0 =C2=A0 = =C2=A0 :=3D sha256Compress(sha256(t),
> merkleRoot(child) =E2=8B=85 0b0^256)
>=C2=A0 =C2=A0 =C2=A0merkleRoot (Binary (t, left, right)) :=3D sha256Com= press(sha256(t),
> merkleRoot(left) =E2=8B=85 merkleRoot(right))
>
> The Merkle--Damg=C3=A5rd property will still hold under the same condi= tions
> about tags determining the type of node (Leaf, Unary, or Binary) while=
> avoiding the need for SHA256's padding.=C2=A0 If you have a small = number of
> tags, then you can pre-compute their hashes so that you only end up wi= th
> one call to SHA256 compress per node. If you have tags with a large am= ount
> of data, you were going to be hashing them anyways.

Notice how what you're proposing here is almost the same thing a= s using SHA256
directly, modulo the fact that you skip the final block containing the mess= age
length.

Similarly, you don't need to compute sha256(t) - you can just as easily= compute
the midstate sha256Compress(IV, t), and cache that midstate if you can reus= e
tags. Again, the only difference is the last block.

Yes, either way would be fine.
=C2=A0
> Unfortunately we lose the ability to cleverly avoid collisions between= the
> Sha256 and MerkleRoot functions by using safe tags.

I think a better question to ask is why you want that property in th= e first
place?

My earlier python-proofmarshal(1) library had a scheme of per-use-case tags= ,
but I eventually realised that depending on tags being unique is a footgun.= For
example, it's easy to see how two different systems could end up using = the same
tag due to designers forgetting to create new tags while copying and pastin= g
old code. Similarly, if two such systems have to be integrated, you'll = end up
with tags getting reused for two different purposes.

Now, if you design a system where that doesn't matter, then by extensio= n it'll
also be true that collisions between the sha256 and merkleroot functions do= n't
matter either. And that system will be more robust to design mistakes, as t= ags
only need to be unique "locally" to distinguish between different= sub-types in
a sum type (enum).

I was looking to add= the property mostly because it was free to do with my original design when= the set of tags was small and could make some applications more robust and= /or easier to debug.
--94eb2c03dfe6c381460550e772d4--