diff --git a/decoding/schnorr-signature.mdx b/decoding/schnorr-signature.mdx new file mode 100644 index 0000000..acdcefa --- /dev/null +++ b/decoding/schnorr-signature.mdx @@ -0,0 +1,280 @@ +--- +title: "Schnorr Signature" +date: 2024-01-25T15:32:14Z +lastmod: "2024-07-26" +draft: false +category: Scripts +layout: TopicBanner +order: 2 +icon: "FaUsers" +parent: taproot +images: ["/bitcoin-topics/static/images/topics/taproot/thumbnail-schnorr.jpg"] +--- + + +The code examples in this article are adapted from the [Bitcoin Optech Taproot Workshop](https://github.com/bitcoinops/taproot-workshop). + +Some code here uses Bitcoin Core's functional test framework. + +Working with this will not only help you understand Schnorr signatures but also give you practical experience with tools used in Bitcoin Core development, helping you take your first steps toward contributing to Bitcoin Core. + + + +We have two main characters to help us understand how Schnorr signatures work: + +**Alice (The signer):** wants to sign a message using Schnorr and send it to Bob. +**Bob (The verifier):** wants to verify that the message is truly signed and comes from Alice. + +
+ +
+
+ +
+ +The interaction between Alice and Bob involves two key steps: **Signature Generation** and **Signature Verification**. + +
+ +
+
+ +
+ +Now, let’s follow Alice as she creates a Schnorr signature. + + +## Signature Generation (Alice) + +### Step 1: Generate Key Pair (d, P) + +Alice generates a private key `d`, then calculates her public key `P` by multiplying her private key with the generator point: + +
+ $$\mathbf{P = d \times G}$$ +
+ +
+ +
+
+ +
+ +To see this in action, run the following code to generate Alice's key pair and display the private and public keys. + + +
+ +
+ +### Step 2: Generate Nonce and Nonce Commitment (k, R) + +The nonce, referred to as `k`, is a random value that Alice generates during the signature process. +Its purpose is to introduces randomness into each signature. + +**Why do we need a nonce?** + +**Answer:** The nonce ensures that even if Alice signs the same message multiple times, each signature will be unique. This added randomness prevents attackers from analyzing repeated patterns and attempting to reverse-engineer Alice’s private key. + + + +Alice generates the nonce `k` and computes the **Nonce Commitment** + +
+ $$\mathbf{R = k \times G}$$ +
+ +*`k` is a scalar, `R` is a point on the elliptic curve.* + +
+ +
+
+ +
+ + +Reusing a nonce (k) when creating Schnorr signatures is extremely dangerous! +- Check out my illustrated explanation + + + +**Note:** +In the Taproot context, BIP340 requires that the y-coordinate of the point `R` (computed from `k`) is `even` + +[BitcoinOptech](https://bitcoinops.org) provides a more detailed explanation of this requirement: + + + +BIP340 defines a new way of encoding elliptic curve points. To make the encoding of a point as compact as possible, only the x-coordinate of the point is used (i.e., 32 bytes). + +For a given x-coordinate on the secp256k1 curve, there are two possible curve points: + +$\mathbf{y^2 = x^3 + 7}$ (Two y-coordinate values for a given x-coordinate) + +For x, both (x, y) and (x, -y) are valid curve points (where -y is **SECP256K1_FIELD_SIZE - y** since all arithmetic involving coordinates is modulo **SECP256K1_FIELD_SIZE**). + +One of the y-coordinates is **even**, and the other is **odd** (since SECP256K1_FIELD_SIZE is odd). + +One of the y-coordinates is a quadratic residue (has a square root modulo the field size), and the other is not. + +BIP340 constrains private key points `k` such that the y-value of `R` is **even**. This means that from the x-coordinate, the verifier can unambiguously determine y. + +- k and **SECP256K1_ORDER - k** have nonce points R = (x, y) and R = (x, -y) respectively. +- Only one will have a y-coordinate that is **even**. If a randomly generated nonce k does not yield a valid nonce point R, then the signer can **negate** k to obtain a valid nonce. + +The same goes for private key d and its corresponding public key, P. + + + +Let’s generate a random nonce `k` and calculate its associated point `R`. + +This example shows how to check if `R`'s y-coordinate (and its negative, `-y`) is even or odd, which is crucial for Taproot’s nonce requirements. + + +
+ +
+ +### Step 3: Challenge Computation (h) + +Alice computes the challenge hash `h` using the following formula: + +
+ $$\mathbf{h = H(R \, || \, P \, || \, \text{message})}$$ +
+ +The challenge hash is created by concatenating `R`, `P`, and the message `m`. + +### Step 4: Challenge Response (s) + +Using the challenge hash, Alice calculates the challenge response `s`: + +
+ $$\mathbf{s = k + h \times d}$$ +
+ +### Step 5: Create the Signature + +The final signature for the message is the pair `(R, s)`. +Alice sends both the message `m` and the signature `(R, s)` to Bob. + +
+ +
+
+ +
+ +### Hands-On: Complete the Code to Generate a Schnorr Signature + +Below is a code snippet that generates a Schnorr signature, but some key parts are missing. Follow the instructions in the code to complete it so that it runs successfully and displays a "Success!" message at the end. + +> **Note:** You'll see a method called `tagged_hash` in the code. If you're unfamiliar with tagged hashes and their purpose, refer to our previous topic on Tagged Hashes for a quick refresher. + +
+ +
+ +> **Security Note:** In real Taproot (BIP340) implementations, nonce generation is deterministic to protect the private key. Here, we use a random nonce for simplicity. + +## Verification Process (Bob) + +Bob wants to ensure that the message hasn’t been compromised during transmission and that it’s genuinely signed by Alice. + +To verify this, Bob checks if the following verification equation holds: + +
+ $$\mathbf{s \times G = R + h \times P}$$ +
+ +If the equation is valid, Bob can be confident that the signature was indeed created by Alice. + +All the information needed for verification is already known to Bob: + + +- **s:** Sent by Alice as part of the signature, so Bob has this value. +- **G:** A constant that is well-known within the Bitcoin protocol. +- **h:** Bob computes `h = H(R || P || m)`. Since he has `R`, `P`, and `m`, he can calculate `h`. +- **P:** This is Alice's public key, which Bob knows in advance. + +Once Bob has confirmed that the equation holds, he can be fully assured that the message is authentic, has not been tampered with, and truly originated from Alice. + + +
+ +
+
+ +
diff --git a/decoding/tagged-hashes.mdx b/decoding/tagged-hashes.mdx new file mode 100644 index 0000000..caa495b --- /dev/null +++ b/decoding/tagged-hashes.mdx @@ -0,0 +1,62 @@ +--- +title: "Tagged Hashes" +date: 2024-01-25T15:32:14Z +lastmod: "2024-07-26" +draft: false +category: Scripts +layout: TopicBanner +order: 1 +icon: "FaUsers" +parent: taproot +images: ["/bitcoin-topics/static/images/topics/taproot/thumbnail-tagged-hash.jpg"] +--- + +Tagged hashes are used throughout the Taproot/Schnorr specification. + +## Why Do We Use Tagged Hashes? + +Their purpose is to ensure that hashes used in one context can’t be used in another. +This means that if you hash the same data in a different context, you won’t get the same hash result. + +## How Do Tagged Hashes Work? + +Creating tagged hashes is straightforward and involves two steps: + +1. Prefix the data you want to hash with the tag `tag = sha256(TagName) || sha256(TagName)`. +2. Hash as normal: `tagged_hash("TagName", data) = sha256(tag + data)`. + +--- + +
+ +
+
+ +
+ +--- + +You might wonder why we need to hash the tag twice in step 1. +The BIP 340 specification provides an explanation, which I'll quote here: + +> "This is a 64-byte long context-specific constant, and the SHA256 block size is also 64 bytes, optimized implementations are possible (identical to SHA256 itself, but with a modified initial state). Using SHA256 of the tag name itself is reasonably simple and efficient for implementations that don't choose to use the optimization." + +## Tagged Hashes in Taproot + +Different tag names are used in different contexts. +For example, in Taproot BIP 340, the hash function uses the following tags: + +- `BIP0340/aux` +- `BIP0340/nonce` +- `BIP0340/challenge` +- `TapLeaf` + +Don't worry if you're still confused, we’ll explore where each of these tags is used in the following chapters. \ No newline at end of file diff --git a/decoding/taproot.mdx b/decoding/taproot.mdx new file mode 100644 index 0000000..689d852 --- /dev/null +++ b/decoding/taproot.mdx @@ -0,0 +1,41 @@ +--- +title: "Taproot" +date: 2024-01-25T15:32:14Z +lastmod: "2024-07-26" +draft: false +category: Scripts +layout: TopicBanner +order: 7 +icon: "FaUsers" +children: + - tagged-hashes + - schnorr-signature +--- + +**Time:** ~4 hours + +#### Goals: +1. Understand Taproot's core components and benefits +2. Learn how Taproot improves Bitcoin's privacy and efficiency +3. Explore key technical concepts (MAST, Schnorr, MuSig, Taproot) + +#### Prerequisites: +- Basic understanding of Bitcoin transactions +- Familiarity with public key cryptography + +
+#### Taproot Road Map +
+ +
+
+ +
\ No newline at end of file diff --git a/static/images/topics/taproot/schnorr-sig-1-light.svg b/static/images/topics/taproot/schnorr-sig-1-light.svg new file mode 100644 index 0000000..7945934 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-1-light.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-1.svg b/static/images/topics/taproot/schnorr-sig-1.svg new file mode 100644 index 0000000..9db0bd4 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-1.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-2-light.svg b/static/images/topics/taproot/schnorr-sig-2-light.svg new file mode 100644 index 0000000..9f6b9db --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-2-light.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-2.svg b/static/images/topics/taproot/schnorr-sig-2.svg new file mode 100644 index 0000000..e41d29b --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-2.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-3-light.svg b/static/images/topics/taproot/schnorr-sig-3-light.svg new file mode 100644 index 0000000..6061608 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-3-light.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-3.svg b/static/images/topics/taproot/schnorr-sig-3.svg new file mode 100644 index 0000000..37efec1 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-3.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-4-light.svg b/static/images/topics/taproot/schnorr-sig-4-light.svg new file mode 100644 index 0000000..21683d9 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-4-light.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-4.svg b/static/images/topics/taproot/schnorr-sig-4.svg new file mode 100644 index 0000000..d62878c --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-4.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-5-light.svg b/static/images/topics/taproot/schnorr-sig-5-light.svg new file mode 100644 index 0000000..0f5cd6b --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-5-light.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-5.svg b/static/images/topics/taproot/schnorr-sig-5.svg new file mode 100644 index 0000000..7a1284f --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-5.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-6-light.svg b/static/images/topics/taproot/schnorr-sig-6-light.svg new file mode 100644 index 0000000..6741149 --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-6-light.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/schnorr-sig-6.svg b/static/images/topics/taproot/schnorr-sig-6.svg new file mode 100644 index 0000000..7946acb --- /dev/null +++ b/static/images/topics/taproot/schnorr-sig-6.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/tag-light.svg b/static/images/topics/taproot/tag-light.svg new file mode 100644 index 0000000..bb38e21 --- /dev/null +++ b/static/images/topics/taproot/tag-light.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/tag.svg b/static/images/topics/taproot/tag.svg new file mode 100644 index 0000000..f184fbf --- /dev/null +++ b/static/images/topics/taproot/tag.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/taproot-roadmap-light.svg b/static/images/topics/taproot/taproot-roadmap-light.svg new file mode 100644 index 0000000..1177e5f --- /dev/null +++ b/static/images/topics/taproot/taproot-roadmap-light.svg @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/taproot-roadmap.svg b/static/images/topics/taproot/taproot-roadmap.svg new file mode 100644 index 0000000..911def1 --- /dev/null +++ b/static/images/topics/taproot/taproot-roadmap.svg @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/images/topics/taproot/thumbnail-schnorr.jpg b/static/images/topics/taproot/thumbnail-schnorr.jpg new file mode 100644 index 0000000..db3c854 Binary files /dev/null and b/static/images/topics/taproot/thumbnail-schnorr.jpg differ diff --git a/static/images/topics/taproot/thumbnail-tagged-hash.jpg b/static/images/topics/taproot/thumbnail-tagged-hash.jpg new file mode 100644 index 0000000..25378b4 Binary files /dev/null and b/static/images/topics/taproot/thumbnail-tagged-hash.jpg differ