Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BIPs 340-342 bip-schnorr, bip-taproot, bip-tapscript #876

Merged
merged 163 commits into from Jan 24, 2020

Conversation

sipa
Copy link
Member

@sipa sipa commented Jan 16, 2020

This adds the 3 BIPs that describe the consensus rules and (basic) wallet operation for the Taproot proposal (https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2019-May/016914.html). There have been several discussions on the mailing list on the original idea, and this proposal specifically, including ones that resulting in significant changes being made to the proposal. Furthermore, a structured review session (https://github.com/ajtowns/taproot-review) with many participants was held, resulting in many comments and improvements.

I believe it's time to actually publish them as BIPs.

An (unreviewed) reference implementation is available (https://github.com/sipa/bitcoin/commits/taproot), which I'll open as a (WIP) PR as soon as there are BIP numbers to refer to.

def int_from_bytes(b):
return int.from_bytes(b, byteorder="big")

def hash_sha256(b):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this function is used anywhere in this script.

@coinables
Copy link

Does this suggest there will be a new address type?

"Instead of using ''compressed'' 33-byte encodings of elliptic curve points which are common in Bitcoin today, public keys in this proposal are encoded as 32 bytes."

@pinheadmz
Copy link
Member

pinheadmz commented Jan 17, 2020

@coinables the address type has already been defined by BIP173!

Here's an example of a mainnet SegWit V1 (Taproot) address:

bc1pqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqszqgpqyqs3wf0qm

This encodes a witness version of 1 followed by 32 0x01 bytes.

@julien-boudry
Copy link

@coinables the address type has already been defined by BIP173!

Indeed but BIP84 does not seem to anticipate these successive versions? Or if it does, it does not contain examples or tests.

@pinheadmz
Copy link
Member

@julien-boudry Funny I just asked on IRC about this. Both BIP84 and BIP49 define Extended Key prefixes (xpub, ypub, zpub for mainnet, others for testnet...) that are supposed to inform the importing wallet what type of address to derive. Adoption of those is flimsy and not consistent between wallets. So far I don't think anyone has proposed new prefix values for Taproot addresses. There are different ways to spend from Taproot outputs as well (key-path, MuSig key-path, and script-path) so a single prefix->address type mapping might not be sufficient for BIP44 wallet recovery.

@Relaxo143
Copy link

I propose BIP numbers 200 for schnorr, 201 for taproot and 202 for tapscript

@luke-jr
Copy link
Member

luke-jr commented Jan 19, 2020

@Relaxo143 BIP numbers 200-202 are already assigned. Please don't confuse people.

@luke-jr
Copy link
Member

luke-jr commented Jan 19, 2020

These are:

  • BIP 340: Schnorr Signatures for secp256k1
  • BIP 341: Taproot: SegWit version 1 output spending rules
  • BIP 342: Validation of Taproot Scripts

@luke-jr luke-jr changed the title Add bip-schnorr, bip-taproot, bip-tapscript Add BIPs 340-342 bip-schnorr, bip-taproot, bip-tapscript Jan 19, 2020
@Relaxo143
Copy link

@Relaxo143 BIP numbers 200-202 are already assigned. Please don't confuse people.

According to this page 199 is used and then 300+. That's why I suggested 200's.

@sipa sipa force-pushed the bip-taproot branch 2 times, most recently from ebb95d2 to 4380e26 Compare January 19, 2020 22:31
@sipa
Copy link
Member Author

sipa commented Jan 19, 2020

@luke-jr Any idea what I'm doing wrong? The Travis message seems unrelated to my changes.

@sipa sipa force-pushed the bip-taproot branch 2 times, most recently from 7209c4d to 14273ed Compare January 19, 2020 22:41
sipa and others added 12 commits January 19, 2020 14:47
Includes squashed contributions by GitHub users jonasnick,
real-or-random, AustinWilliams, JustinTArthur, ysangkok,
RCassatta, Sjors, tnakagawa, and guggero.
Though perhaps, the emphasis is warranted given its importance. :-)
If we look at

  def IsPayToTaproot(script):
      return len(script) == 35 and script[0] == OP_1 and script[1] == 33 and script[2] >= 0 and script[2] <= 1

First byte is is checked for OP_1. OP_1 is 0x51

But the example code in this BIP returns  

`bytes([0x01, 0x21, output_pubkey[0] & 1]) + output_pubkey[1:]`

First byte 0x01, but it should be 0x51
Co-Authored-By: Tim Ruffing <tim@timruffing.de>
Co-Authored-By: Tim Ruffing <tim@timruffing.de>
@sipa sipa force-pushed the bip-taproot branch 3 times, most recently from 4e623b9 to a92523e Compare January 19, 2020 22:58
@sipa
Copy link
Member Author

sipa commented Jan 19, 2020

Don't merge yet, somehow not all BIP links are rendered correctly. I don't understand why some work and others don't...

bip-0340.mediawiki Outdated Show resolved Hide resolved
@sipa sipa force-pushed the bip-taproot branch 3 times, most recently from eb5723c to 1ad8242 Compare January 20, 2020 15:33
@sipa
Copy link
Member Author

sipa commented Jan 20, 2020

All links fixed.

=== Design ===

'''Schnorr signature variant''' Elliptic Curve Schnorr signatures for message ''m'' and public key ''P'' generally involve a point ''R'', integers ''e'' and ''s'' picked by the signer, and the base point ''G'' which satisfy ''e = hash(R || m)'' and ''s⋅G = R + e⋅P''. Two formulations exist, depending on whether the signer reveals ''e'' or ''R'':
# Signatures are pairs ''(e, s)'' that satisfy ''e = hash(s⋅G - e⋅P || m)''. This variant avoids minor complexity introduced by the encoding of the point ''R'' in the signature (see paragraphs "Encoding R and public key point P" and "Implicit Y coordinates" further below in this subsection). Moreover, revealing ''e'' instead of ''R'' allows for potentially shorter signatures: Whereas an encoding of ''R'' inherently needs about 32 bytes, the hash ''e'' can be tuned to be shorter than 32 bytes, and [http://www.neven.org/papers/schnorr.pdf a short hash of only 16 bytes suffices to provide SUF-CMA security at the target security level of 128 bits]. However, a major drawback of this optimization is that finding collisions in a short hash function is easy. This complicates the implementation of secure signing protocols in scenarios in which a group of mutually distrusting signers work together to produce a single joint signature (see Applications below). In these scenarios, which are not captured by the SUF-CMA model due its assumption of a single honest signer, a promising attack strategy for malicious co-signers is to find a collision in the hash function in order to obtain a valid signature on a message that an honest co-signer did not intent to sign.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "did not intend to sign"

</ref> and ''has_square_y(P)''<ref>
If ''P := lift_x(x)'' does not fail, then ''y := y(P) = c<sup>(p+1)/4</sup> mod p'' is square. Proof: If ''lift_x'' does not fail, ''y'' is a square root of ''c'' and therefore the [https://en.wikipedia.org/wiki/Legendre_symbol Legendre symbol] ''(c / p)'' is ''c<sup>(p-1)/2</sup> = 1 mod p''. Because the Legendre symbol ''(y / p)'' is ''y<sup>(p-1)/2</sup> mod p = c<sup>((p+1)/4)((p-1)/2)</sup> mod p = 1<sup>((p+1)/4)</sup> mod p = 1 mod p'', ''y'' is square.
</ref>, or fails if no such point exists. The function ''lift_x(x)'' is equivalent to the following pseudocode:
*** Let ''c = x<sup>3</sup> + 7 mod p''.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be ''c = (x<sup>3</sup> + 7) mod p''?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally when a "mod a" is written after an expression it means all operations are mod a.

@luke-jr luke-jr merged commit 9cf4038 into bitcoin:master Jan 24, 2020
@bitcoin bitcoin deleted a comment from Th1983 Jul 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet