* Re: [bitcoin-dev] Fast Merkle Trees
@ 2017-09-07 1:59 Russell O'Connor
2017-09-07 2:20 ` Mark Friedenbach
2017-09-07 5:55 ` Peter Todd
0 siblings, 2 replies; 9+ messages in thread
From: Russell O'Connor @ 2017-09-07 1:59 UTC (permalink / raw)
To: Mark Friedenbach, Bitcoin Protocol Discussion
[-- Attachment #1: Type: text/plain, Size: 832 bytes --]
The fast hash for internal nodes needs to use an IV that is not the
standard SHA-256 IV. Instead needs to use some other fixed value, which
should itself be the SHA-256 hash of some fixed string (e.g. the string
"BIP ???" or "Fash SHA-256").
As it stands, I believe someone can claim a leaf node as an internal node
by creating a proof that provides a phony right-hand branch claiming to
have hash 0x80000..0000100 (which is really the padding value for the
second half of a double SHA-256 hash).
(I was schooled by Peter Todd by a similar issue in the past.)
On Wed, Sep 6, 2017 at 8:38 PM, Mark Friedenbach via bitcoin-dev <
bitcoin-dev@lists.linuxfoundation.org> wrote:
> Fast Merkle Trees
> BIP: https://gist.github.com/maaku/41b0054de0731321d23e9da90ba4ee0a
> Code: https://github.com/maaku/bitcoin/tree/fast-merkle-tree
>
[-- Attachment #2: Type: text/html, Size: 1497 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 1:59 [bitcoin-dev] Fast Merkle Trees Russell O'Connor @ 2017-09-07 2:20 ` Mark Friedenbach 2017-09-07 15:43 ` Russell O'Connor 2017-09-07 5:55 ` Peter Todd 1 sibling, 1 reply; 9+ messages in thread From: Mark Friedenbach @ 2017-09-07 2:20 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 1169 bytes --] This design purposefully does not distinguish leaf nodes from internal nodes. That way it chained invocations can be used to validate paths longer than 32 branches. Do you see a vulnerability due to this lack of distinction? > On Sep 6, 2017, at 6:59 PM, Russell O'Connor <roconnor@blockstream.io> wrote: > > The fast hash for internal nodes needs to use an IV that is not the standard SHA-256 IV. Instead needs to use some other fixed value, which should itself be the SHA-256 hash of some fixed string (e.g. the string "BIP ???" or "Fash SHA-256"). > > As it stands, I believe someone can claim a leaf node as an internal node by creating a proof that provides a phony right-hand branch claiming to have hash 0x80000..0000100 (which is really the padding value for the second half of a double SHA-256 hash). > > (I was schooled by Peter Todd by a similar issue in the past.) > >> On Wed, Sep 6, 2017 at 8:38 PM, Mark Friedenbach via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: >> Fast Merkle Trees >> BIP: https://gist.github.com/maaku/41b0054de0731321d23e9da90ba4ee0a >> Code: https://github.com/maaku/bitcoin/tree/fast-merkle-tree [-- Attachment #2: Type: text/html, Size: 2032 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 2:20 ` Mark Friedenbach @ 2017-09-07 15:43 ` Russell O'Connor 2017-09-07 17:42 ` Mark Friedenbach 0 siblings, 1 reply; 9+ messages in thread From: Russell O'Connor @ 2017-09-07 15:43 UTC (permalink / raw) To: Mark Friedenbach; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 3928 bytes --] In that case, you may as well remove all references to leaves and double SHA-256 from your BIP since your design has no method for distinguishing between internal nodes and leaves. I think that if this design stands, it will play a role in some future CVEs. The BIP itself is too abstract about its data contents to specifically say that it has a vulnerability; however, I believe it is inviting vulnerabilities. For example, I might agree with a counterparty to a design of some sort of smart contract in the form of a MAST. My counterparty has shown me all the "leaves" of our MAST and I can verify its Merkle root computation. After being deployed, I found out that one of the leaves wasn't really a leaf but is instead a specially crafted "script" with a fake pubkey chosen by my couterparty so that this leaf can also be interpreted as a fake internal node (i.e. an internal node with a right branch of 0x8000...100). Because the Fast Merkle Tree design doesn't distinguish between leaves and internal nodes my counter party gets away with building an Inclusion Proof through this "leaf" to reveal the evil code that they had designed into the MAST at a deeper level. Turns out my counterparty was grinding their evil code to produce an internal node that can also be parsed as an innocent script. They used their "pubkey" to absorb excess random data from their grinding that they cannot eliminate. (The counterparty doesn't actually know the discrete log of this "pubkey", they just claimed it was their pubkey and I believed them). Having ambiguity about whether a node is a leaf or an internal node is a security risk. Furthermore, changing the design so that internal node and leaves are distinguishable still allows chained invocations. Arbitrary data can be stored in Fast Merkle Tree leaves, including the Merkle root of another Fast Merkle Tree. Applications that are limited to proof with paths no longer than 32 branches can still circumvent this limit by staging these Fast Merkle Trees in explicit layers (as opposed to the implicit layers with the current design). By storing a inner Fast Merkle Tree root inside the (explicit) leaf of an outer Fast Merkle Tree, the application can verify a Inclusion Proof of the inner Fast Merkle Tree Root in the outer Fast Merkle Tree Root, and then verify a second Inclusion Proof of the desired data in the inner Faster Merkle Tree Root. The application will need to tag their data to distinguish between inner Fast Merkle Tree Roots and other application data, but that is just part of the general expectation that applications not store ambiguous data inside the leaves of Fast Merkle Trees. On Wed, Sep 6, 2017 at 10:20 PM, Mark Friedenbach <mark@friedenbach.org> wrote: > This design purposefully does not distinguish leaf nodes from internal > nodes. That way it chained invocations can be used to validate paths longer > than 32 branches. Do you see a vulnerability due to this lack of > distinction? > > On Sep 6, 2017, at 6:59 PM, Russell O'Connor <roconnor@blockstream.io> > wrote: > > The fast hash for internal nodes needs to use an IV that is not the > standard SHA-256 IV. Instead needs to use some other fixed value, which > should itself be the SHA-256 hash of some fixed string (e.g. the string > "BIP ???" or "Fash SHA-256"). > > As it stands, I believe someone can claim a leaf node as an internal node > by creating a proof that provides a phony right-hand branch claiming to > have hash 0x80000..0000100 (which is really the padding value for the > second half of a double SHA-256 hash). > > (I was schooled by Peter Todd by a similar issue in the past.) > > On Wed, Sep 6, 2017 at 8:38 PM, Mark Friedenbach via bitcoin-dev < > bitcoin-dev@lists.linuxfoundation.org> wrote: > >> Fast Merkle Trees >> BIP: https://gist.github.com/maaku/41b0054de0731321d23e9da90ba4ee0a >> Code: https://github.com/maaku/bitcoin/tree/fast-merkle-tree >> > [-- Attachment #2: Type: text/html, Size: 5320 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 15:43 ` Russell O'Connor @ 2017-09-07 17:42 ` Mark Friedenbach 2017-09-07 18:55 ` Russell O'Connor 0 siblings, 1 reply; 9+ messages in thread From: Mark Friedenbach @ 2017-09-07 17:42 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 6087 bytes --] I've been puzzling over your email since receiving it. I'm not sure it is possible to perform the attack you describe with the tree structure specified in the BIP. If I may rephrase your attack, I believe you are seeking a solution to the following: Want: An innocuous script and a malign script for which double-SHA256(innocuous) is equal to either fast-SHA256(double-SHA256(malign) || r) or fast-SHA256(r || double-SHA256(malign)) where r is a freely chosen 32-byte nonce. This would allow the attacker to reveal the innocuous script before funds are sent to the MAST, then use the malign script to spend. Because of the double-SHA256 construction I do not see how this can be accomplished without a full break of SHA256. The trick of setting r equal to the padding only works when a single SHA256 is used for leaf values. This is why double-SHA256 is specified in the BIP, and I will edit the text to make that more clear. Which brings us to the point that I think your original request of separating the hash function of leaves from internal nodes is already in the specification. I misunderstood your request at first to be that MERKLEBRANCHVERIFY should itself perform this hash, which I objected to as it closes of certain use cases such as chained verification of proofs. But it is explicitly the case that leaf values and internal updates are calculated with different hash functions. I'm not intrinsicly opposed to using a different IV for fast-SHA256 so as to remove the incompatability with single-SHA256 as the leaf hash function, if that is the consensus of the community. It just adds complication to implementations and so I want to make sure that complication is well justified. Sincerely, Mark Friedenbach > On Sep 7, 2017, at 8:43 AM, Russell O'Connor <roconnor@blockstream.io> wrote: > > In that case, you may as well remove all references to leaves and double SHA-256 from your BIP since your design has no method for distinguishing between internal nodes and leaves. > > I think that if this design stands, it will play a role in some future CVEs. The BIP itself is too abstract about its data contents to specifically say that it has a vulnerability; however, I believe it is inviting vulnerabilities. > For example, I might agree with a counterparty to a design of some sort of smart contract in the form of a MAST. My counterparty has shown me all the "leaves" of our MAST and I can verify its Merkle root computation. > After being deployed, I found out that one of the leaves wasn't really a leaf but is instead a specially crafted "script" with a fake pubkey chosen by my couterparty so that this leaf can also be interpreted as a fake internal node (i.e. an internal node with a right branch of 0x8000...100). > Because the Fast Merkle Tree design doesn't distinguish between leaves and internal nodes my counter party gets away with building an Inclusion Proof through this "leaf" to reveal the evil code that they had designed into the MAST at a deeper level. > > Turns out my counterparty was grinding their evil code to produce an internal node that can also be parsed as an innocent script. They used their "pubkey" to absorb excess random data from their grinding that they cannot eliminate. > (The counterparty doesn't actually know the discrete log of this "pubkey", they just claimed it was their pubkey and I believed them). > > > Having ambiguity about whether a node is a leaf or an internal node is a security risk. Furthermore, changing the design so that internal node and leaves are distinguishable still allows chained invocations. > Arbitrary data can be stored in Fast Merkle Tree leaves, including the Merkle root of another Fast Merkle Tree. > Applications that are limited to proof with paths no longer than 32 branches can still circumvent this limit by staging these Fast Merkle Trees in explicit layers (as opposed to the implicit layers with the current design). > > By storing a inner Fast Merkle Tree root inside the (explicit) leaf of an outer Fast Merkle Tree, the application can verify a Inclusion Proof of the inner Fast Merkle Tree Root in the outer Fast Merkle Tree Root, and then verify a second Inclusion Proof of the desired data in the inner Faster Merkle Tree Root. The application will need to tag their data to distinguish between inner Fast Merkle Tree Roots and other application data, but that is just part of the general expectation that applications not store ambiguous data inside the leaves of Fast Merkle Trees. > > > On Wed, Sep 6, 2017 at 10:20 PM, Mark Friedenbach <mark@friedenbach.org <mailto:mark@friedenbach.org>> wrote: > This design purposefully does not distinguish leaf nodes from internal nodes. That way it chained invocations can be used to validate paths longer than 32 branches. Do you see a vulnerability due to this lack of distinction? > > On Sep 6, 2017, at 6:59 PM, Russell O'Connor <roconnor@blockstream.io <mailto:roconnor@blockstream.io>> wrote: > >> The fast hash for internal nodes needs to use an IV that is not the standard SHA-256 IV. Instead needs to use some other fixed value, which should itself be the SHA-256 hash of some fixed string (e.g. the string "BIP ???" or "Fash SHA-256"). >> >> As it stands, I believe someone can claim a leaf node as an internal node by creating a proof that provides a phony right-hand branch claiming to have hash 0x80000..0000100 (which is really the padding value for the second half of a double SHA-256 hash). >> >> (I was schooled by Peter Todd by a similar issue in the past.) >> >> On Wed, Sep 6, 2017 at 8:38 PM, Mark Friedenbach via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org <mailto:bitcoin-dev@lists.linuxfoundation.org>> wrote: >> Fast Merkle Trees >> BIP: https://gist.github.com/maaku/41b0054de0731321d23e9da90ba4ee0a <https://gist.github.com/maaku/41b0054de0731321d23e9da90ba4ee0a> >> Code: https://github.com/maaku/bitcoin/tree/fast-merkle-tree <https://github.com/maaku/bitcoin/tree/fast-merkle-tree> > [-- Attachment #2: Type: text/html, Size: 9042 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 17:42 ` Mark Friedenbach @ 2017-09-07 18:55 ` Russell O'Connor 2017-09-07 20:04 ` Mark Friedenbach 0 siblings, 1 reply; 9+ messages in thread From: Russell O'Connor @ 2017-09-07 18:55 UTC (permalink / raw) To: Mark Friedenbach; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 2308 bytes --] On Thu, Sep 7, 2017 at 1:42 PM, Mark Friedenbach <mark@friedenbach.org> wrote: > I've been puzzling over your email since receiving it. I'm not sure it > is possible to perform the attack you describe with the tree structure > specified in the BIP. If I may rephrase your attack, I believe you are > seeking a solution to the following: > > Want: An innocuous script and a malign script for which > > double-SHA256(innocuous) > > is equal to either > > fast-SHA256(double-SHA256(malign) || r) or > fast-SHA256(r || double-SHA256(malign)) > or fast-SHA256(fast-SHA256(double-SHA256(malign) || r1) || r0) or fast-SHA256(fast-SHA256(r1 || double-SHA256(malign)) || r0) or ... > where r is a freely chosen 32-byte nonce. This would allow the > attacker to reveal the innocuous script before funds are sent to the > MAST, then use the malign script to spend. > > Because of the double-SHA256 construction I do not see how this can be > accomplished without a full break of SHA256. > The particular scenario I'm imagining is a collision between double-SHA256(innocuous) and fast-SHA256(fast-SHA256(fast-SHA256(double-SHA256(malign) || r2) || r1) || r0). where innocuous is a Bitcoin Script that is between 32 and 55 bytes long. Observe that when data is less than 55 bytes then double-SHA256(data) = fast-SHA256(fast-SHA256(padding-SHA256(data)) || 0x8000...100) (which is really the crux of the matter). Therefore, to get our collision it suffices to find a collision between padding-SHA256(innocuous) and fast-SHA256(double-SHA256(malign) || r2) || r1 r1 can freely be set to the second half of padding-SHA256(innocuous), so it suffices to find a collision between fast-SHA256(double-SHA256(malign) || r2) and the first half of padding-SHA256(innocuous) which is equal to the first 32 bytes of innocuous. Imagine the first opcode of innocuous is the push of a value that the attacker claims to be his 33-byte public key. So long as the attacker doesn't need to prove that they know the discrete log of this pubkey, they can grind r2 until the result of fast-SHA256(double-SHA256(malign) || r2) contains the correct first couple of bytes for the script header and the opcode for a 33-byte push. I believe that is only about 3 or 4 bytes of they need to grind out. [-- Attachment #2: Type: text/html, Size: 3539 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 18:55 ` Russell O'Connor @ 2017-09-07 20:04 ` Mark Friedenbach 2017-09-12 11:44 ` Johnson Lau 0 siblings, 1 reply; 9+ messages in thread From: Mark Friedenbach @ 2017-09-07 20:04 UTC (permalink / raw) To: Russell O'Connor; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 5551 bytes --] TL;DR I'll be updating the fast Merkle-tree spec to use a different IV, using (for infrastructure compatability reasons) the scheme provided by Peter Todd. This is a specific instance of a general problem where you cannot trust scripts given to you by another party. Notice that we run into the same sort of problem when doing key aggregation, in which you must require the other party to prove knowledge of the discrete log before using their public key, or else key cancellation can occur. With script it is a little bit more complicated as you might want zero-knowledge proofs of hash pre-images for HTLCs as well as proofs of DL knowledge (signatures), but the basic idea is the same. Multi- party wallet level protocols for jointly constructing scriptPubKeys should require a 'delinearization' step that proves knowledge of information necessary to complete each part of the script, as part of proving the safety of a construct. I think my hangup before in understanding the attack you describe was in actualizing it into a practical attack that actually escalates the attacker's capabilities. If the attacker can get you to agree to a MAST policy that is nothing more than a CHECKSIG over a key they presumably control, then they don't need to do any complicated grinding. The attacker in that scenario would just actually specify a key they control and take the funds that way. Where this presumably leads to an actual exploit is when you specify a script that a curious counter-party actually takes the time to investigate and believes to be secure. For example, a script that requires a signature or pre-image revelation from that counter-party. That would require grinding not a few bytes, but at minimum 20-33 bytes for either a HASH160 image or the counter-party's key. If I understand the revised attack description correctly, then there is a small window in which the attacker can create a script less than 55 bytes in length, where nearly all of the first 32 bytes are selected by the attacker, yet nevertheless the script seems safe to the counter-party. The smallest such script I was able to construct was the following: <fake-pubkey> CHECKSIGVERIFY HASH160 <preimage> EQUAL This is 56 bytes and requires only 7 bits of grinding in the fake pubkey. But 56 bytes is too large. Switching to secp256k1 serialized 32-byte pubkeys (in a script version upgrade, for example) would reduce this to the necessary 55 bytes with 0 bits of grinding. A smaller variant is possible: DUP HASH160 <fake-pubkey-hash> EQUALVERIFY CHECKSIGVERIFY HASH160 <preimage> EQUAL This is 46 bytes, but requires grinding 96 bits, which is a bit less plausible. Belts and suspenders are not so terrible together, however, and I think there is enough of a justification here to look into modifying the scheme to use a different IV for hash tree updates. This would prevent even the above implausible attacks. > On Sep 7, 2017, at 11:55 AM, Russell O'Connor <roconnor@blockstream.io> wrote: > > > > On Thu, Sep 7, 2017 at 1:42 PM, Mark Friedenbach <mark@friedenbach.org <mailto:mark@friedenbach.org>> wrote: > I've been puzzling over your email since receiving it. I'm not sure it > is possible to perform the attack you describe with the tree structure > specified in the BIP. If I may rephrase your attack, I believe you are > seeking a solution to the following: > > Want: An innocuous script and a malign script for which > > double-SHA256(innocuous) > > is equal to either > > fast-SHA256(double-SHA256(malign) || r) or > fast-SHA256(r || double-SHA256(malign)) > > or fast-SHA256(fast-SHA256(double-SHA256(malign) || r1) || r0) > or fast-SHA256(fast-SHA256(r1 || double-SHA256(malign)) || r0) > or ... > > where r is a freely chosen 32-byte nonce. This would allow the > attacker to reveal the innocuous script before funds are sent to the > MAST, then use the malign script to spend. > > Because of the double-SHA256 construction I do not see how this can be > accomplished without a full break of SHA256. > > The particular scenario I'm imagining is a collision between > > double-SHA256(innocuous) > > and > > fast-SHA256(fast-SHA256(fast-SHA256(double-SHA256(malign) || r2) || r1) || r0). > > where innocuous is a Bitcoin Script that is between 32 and 55 bytes long. > > Observe that when data is less than 55 bytes then double-SHA256(data) = fast-SHA256(fast-SHA256(padding-SHA256(data)) || 0x8000...100) (which is really the crux of the matter). > > Therefore, to get our collision it suffices to find a collision between > > padding-SHA256(innocuous) > > and > > fast-SHA256(double-SHA256(malign) || r2) || r1 > > r1 can freely be set to the second half of padding-SHA256(innocuous), so it suffices to find a collision between > > fast-SHA256(double-SHA256(malign) || r2) > > and the first half of padding-SHA256(innocuous) which is equal to the first 32 bytes of innocuous. > > Imagine the first opcode of innocuous is the push of a value that the attacker claims to be his 33-byte public key. > So long as the attacker doesn't need to prove that they know the discrete log of this pubkey, they can grind r2 until the result of fast-SHA256(double-SHA256(malign) || r2) contains the correct first couple of bytes for the script header and the opcode for a 33-byte push. I believe that is only about 3 or 4 bytes of they need to grind out. > [-- Attachment #2: Type: text/html, Size: 9261 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 20:04 ` Mark Friedenbach @ 2017-09-12 11:44 ` Johnson Lau 0 siblings, 0 replies; 9+ messages in thread From: Johnson Lau @ 2017-09-12 11:44 UTC (permalink / raw) To: Mark Friedenbach, bitcoin-dev > On 8 Sep 2017, at 4:04 AM, Mark Friedenbach via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote: > > If I understand the revised attack description correctly, then there > is a small window in which the attacker can create a script less than > 55 bytes in length, where nearly all of the first 32 bytes are > selected by the attacker, yet nevertheless the script seems safe to > the counter-party. The smallest such script I was able to construct > was the following: > > <fake-pubkey> CHECKSIGVERIFY HASH160 <preimage> EQUAL > > This is 56 bytes and requires only 7 bits of grinding in the fake > pubkey. But 56 bytes is too large. Switching to secp256k1 serialized > 32-byte pubkeys (in a script version upgrade, for example) would > reduce this to the necessary 55 bytes with 0 bits of grinding. A > smaller variant is possible: > > DUP HASH160 <fake-pubkey-hash> EQUALVERIFY CHECKSIGVERIFY HASH160 <preimage> EQUAL > > This is 46 bytes, but requires grinding 96 bits, which is a bit less > plausible. > > Belts and suspenders are not so terrible together, however, and I > think there is enough of a justification here to look into modifying > the scheme to use a different IV for hash tree updates. This would > prevent even the above implausible attacks. > I think you overestimated the difficulty. Consider this MAST branch (an example in BIP114) "Timestamp" CHECKLOCKTIMEVERIFY <fake-pubkey> CHECKSIGVERIFY This requires just a few bytes of collision. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 1:59 [bitcoin-dev] Fast Merkle Trees Russell O'Connor 2017-09-07 2:20 ` Mark Friedenbach @ 2017-09-07 5:55 ` Peter Todd 2017-09-07 15:51 ` Russell O'Connor 1 sibling, 1 reply; 9+ messages in thread From: Peter Todd @ 2017-09-07 5:55 UTC (permalink / raw) To: Russell O'Connor, Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 720 bytes --] On Wed, Sep 06, 2017 at 09:59:54PM -0400, Russell O'Connor via bitcoin-dev wrote: > The fast hash for internal nodes needs to use an IV that is not the > standard SHA-256 IV. Instead needs to use some other fixed value, which > should itself be the SHA-256 hash of some fixed string (e.g. the string > "BIP ???" or "Fash SHA-256"). Note that in general, designs should *not* create new hash functions by using custom IVs, but rather use bog-standard SHA256, and make a fixed first block. That allows unoptimised implementations to just hash a block with the second initialization value, and optimized implementations to start with the fixed midstate. -- https://petertodd.org 'peter'[:-1]@petertodd.org [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 455 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [bitcoin-dev] Fast Merkle Trees 2017-09-07 5:55 ` Peter Todd @ 2017-09-07 15:51 ` Russell O'Connor 0 siblings, 0 replies; 9+ messages in thread From: Russell O'Connor @ 2017-09-07 15:51 UTC (permalink / raw) To: Peter Todd; +Cc: Bitcoin Protocol Discussion [-- Attachment #1: Type: text/plain, Size: 1138 bytes --] On Thu, Sep 7, 2017 at 1:55 AM, Peter Todd <pete@petertodd.org> wrote: > On Wed, Sep 06, 2017 at 09:59:54PM -0400, Russell O'Connor via bitcoin-dev > wrote: > > The fast hash for internal nodes needs to use an IV that is not the > > standard SHA-256 IV. Instead needs to use some other fixed value, which > > should itself be the SHA-256 hash of some fixed string (e.g. the string > > "BIP ???" or "Fash SHA-256"). > > Note that in general, designs should *not* create new hash functions by > using > custom IVs, but rather use bog-standard SHA256, and make a fixed first > block. > That allows unoptimised implementations to just hash a block with the > second > initialization value, and optimized implementations to start with the fixed > midstate. I 100% agree. With SHA256 every final state is also a valid midstate. Therefore, using a custom IV of the SHA256 hash of some fixed string results in a hash of data that is functionally equivalent to prefixing the data with the padded version of the fixed string and using a regular SHA256 hash of the combined data. This is important and I should have explicitly pointed it out. [-- Attachment #2: Type: text/html, Size: 1564 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2017-09-12 11:45 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-09-07 1:59 [bitcoin-dev] Fast Merkle Trees Russell O'Connor 2017-09-07 2:20 ` Mark Friedenbach 2017-09-07 15:43 ` Russell O'Connor 2017-09-07 17:42 ` Mark Friedenbach 2017-09-07 18:55 ` Russell O'Connor 2017-09-07 20:04 ` Mark Friedenbach 2017-09-12 11:44 ` Johnson Lau 2017-09-07 5:55 ` Peter Todd 2017-09-07 15:51 ` Russell O'Connor
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox