1
0
mirror of https://github.com/bitcoinbook/bitcoinbook synced 2024-11-21 23:58:09 +00:00

math update

This commit is contained in:
Clare Laylock 2023-10-25 10:20:58 -04:00
parent a59418c69e
commit 48cd7ae0b1
10 changed files with 205 additions and 153 deletions

View File

@ -1171,4 +1171,4 @@ follow every rule in the Bitcoin system without having to trust any
outside authority. In the coming chapters, we'll learn more about the
rules of the system and how your node and your wallet use them to secure
your money, protect your privacy, and make spending and receiving
convenient.
[.keep-together]#convenient.#

View File

@ -117,8 +117,8 @@ use to pick that number does not matter as long as it is not predictable
or repeatable. Bitcoin software uses cryptographically secure random
number generators to produce 256 bits of entropy.
More precisely, the private key can be any number between +0+ and +n -
1+ inclusive, where n is a constant (n = 1.1578 × 10^77^, slightly less
More precisely, the private key can be any number between 0 and n -
1 inclusive, where n is a constant (n = 1.1578 × 10^77^, slightly less
than 2^256^) defined as the order of the elliptic curve used in Bitcoin
(see <<elliptic_curve>>). To create such a key, we randomly pick a
256-bit number and check that it is less than +n+. In programming terms,
@ -167,7 +167,7 @@ curve.
by Bitcoin.
[[ecc-curve]]
[role="smallerthirty"]
[role="width-80"]
.An elliptic curve
image::images/mbc3_0402.png["ecc-curve"]
@ -318,7 +318,7 @@ bitcoin:
[latexmath]
++++
\begin{equation}
{K = k × G}
{K = k \times G}
\end{equation}
++++
@ -341,22 +341,32 @@ Implementing the elliptic curve multiplication, we take the private key
_k_ generated previously and multiply it with the generator point _G_ to
find the public key _K_:
[source, python]
----
K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD * G
----
[latexmath]
++++
\begin{equation}
{K = 1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD \times G}
\end{equation}
++++
Public key _K_ is defined as a point +K = (x,y)+:
Public key _K_ is defined as a point K = (x, y):
----
[latexmath]
++++
\begin{equation}
K = (x, y)
\end{equation}
++++
where,
----
x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
----
To visualize multiplication of a point with an integer, we will use the
simpler elliptic curve over real numbers&#x2014;remember, the math is
the same. Our goal is to find the multiple _kG_ of the generator point
@ -410,6 +420,7 @@ x = F028892BAD7ED57D2FB57BF33081D5CFCF6F9ED3D3D7F159C2E2FFF579DC341A
y = 07CF33DA18BD734C600B96A72BBC4749D5141C90EC8AC328AE52DDFE2E505BDB
----
Instead of direct public key entry, the earliest version of Bitcoin
software allowed a spender to enter the the receiver's IP address, as shown in <<bitcoin_01_send>>. This
feature was later removed--there are many problems

View File

@ -55,6 +55,7 @@ created new key pairs for each transaction, producing wallet databases
that could only reasonably be backed up using digital media.
[[Type0_wallet]]
[role="width-80"]
.Nondeterministic key generation: a collection of independently generated keys stored in a wallet database
image::images/mbc3_0501.png["Non-Deterministic Wallet"]
@ -126,21 +127,29 @@ public key, or to multiply it. Consider the operation we used in
generating a public key (_K_) from a private key (_k_) using the generator
point (_G_):
----
K = k * G
----
[latexmath]
++++
\begin{equation}
{K = k \times G}
\end{equation}
++++
It's possible to create a derived key pair, called a child key pair, by
simply adding the same value to both sides of the equation:
----
K + (123 * G) == (k + 123) * G
----
[latexmath]
++++
\begin{equation}
K + (123 \times G) == (k + 123) \times G
\end{equation}
++++
[TIP]
====
In equations throughout this book, we use a single equals sign for
operations such as +K = k × G+ where the value of a variable is
operations such as K = k × G where the value of a variable is
calculated. We use a double equals sign to show both sides of an
equation are equivalent, or that an operation should return false (not
true) if the two sides aren't equivalent.
@ -1459,7 +1468,7 @@ purpose is identified by index number "i."
Extending that specification, ((("BIP44 HD wallet tree structure", id="bip44")))BIP44 proposes a multiaccount structure
as "purpose" number +44'+ under BIP43. All HD wallets following the
BIP44 structure are identified by the fact that they only used one
branch of the tree: m/44'/.
branch of the tree: m/44++'++/.
BIP44 specifies the structure as consisting of five predefined tree levels:

View File

@ -218,7 +218,7 @@ Wiki's script page].
image::images/mbc3_0702.png["TxScriptSimpleMathExample"]
The following is a slightly more complex script, which calculates
++2 + 7 -- 3 + 1++. Notice that when the script contains several operators in
2 + 7 3 + 1. Notice that when the script contains several operators in
a row, the stack allows the results of one operator to be acted upon by
the next operator:
@ -392,13 +392,13 @@ example:
<Sig B> <Sig C> 2 <Pubkey A> <Pubkey B> <Pubkey C> 3 OP_CHECKMULTISIG
----
First, +OP_CHECKMULTISIG+ pops the top item, which is +k+ (in this example
"3"). Then it pops +k+ items, which are the public keys that can sign;
First, +OP_CHECKMULTISIG+ pops the top item, which is _k_ (in this example
"3"). Then it pops _k_ items, which are the public keys that can sign;
in this example, public keys A, B, and C. Then, it pops one item, which
is +t+, the quorum (how many signatures are needed). Here t = 2. At this
point, +OP_CHECKMULTISIG+ should pop the final +t+ items, which are the
is _t_, the quorum (how many signatures are needed). Here _t_ = 2. At this
point, +OP_CHECKMULTISIG+ should pop the final _t_ items, which are the
signatures, and see if they are valid. However, unfortunately, an oddity in
the implementation causes +OP_CHECKMULTISIG+ to pop one more item (t+1
the implementation causes +OP_CHECKMULTISIG+ to pop one more item (_t_ + 1
total) than it should. The extra item is called((("dummy stack element"))) the _dummy stack
element_, and it is disregarded when checking the
signatures so it has no direct effect on +OP_CHECKMULTISIG+ itself.
@ -444,7 +444,7 @@ the other keys before it is finally compared to its corresponding
performed even though there's only one signature. One way to eliminate
this redundancy would have been to provide +OP_CHECKMULTISIG+ a map
indicating which provided signature corresponds to which public key,
allowing the +OP_CHECKMULTISIG+ operation to only perform exactly +t+
allowing the +OP_CHECKMULTISIG+ operation to only perform exactly _t_
signature-checking operations. It's possible that Bitcoin's original
developer added the extra element (which we now call the dummy stack
element) in the original version of Bitcoin so they could add the

View File

@ -308,11 +308,11 @@ Linearity::
variables and then running a function on that sum will produce the
same value as running the function on each of the variables
independently and then summing together the results, e.g.,
+f(x + y + z) == f(x) + f(y) + f(z)+; this property is((("additivity"))) called
_f(x_ + _y_ + _z)_ == _f(x)_ + _f(y)_ + _f(z)_; this property is((("additivity"))) called
_additivity_. The second property is that multiplying a variable and
then running a function on that product will produce the same value as
running the function on the variable and then multiplying it by the
same amount, e.g., +f(a * x) == a * f(x)+; this property is ((("homogeneity of degree 1")))called
same amount, e.g., _f(a_ × _x)_ == _a_ × _f(x)_; this property is ((("homogeneity of degree 1")))called
_homogeneity of degree 1_.
+
In cryptographic operations, some functions may be private (such
@ -338,67 +338,67 @@ exactly as it's used in Bitcoin, but we're going to start with a
simplified version of it and work our way toward the actual protocol in
stages.
Alice((("digital signatures", "schnorr signature algorithm", "examples of usage")))((("schnorr signature algorithm", "examples of usage"))) starts by choosing a large random number (+x+), which we call her
Alice((("digital signatures", "schnorr signature algorithm", "examples of usage")))((("schnorr signature algorithm", "examples of usage"))) starts by choosing a large random number (_x_), which we call her
_private key_. She also knows a public point on Bitcoin's elliptic
curve called the Generator (+G+) (see <<public_key_derivation>>). Alice uses EC
multiplication to multiply +G+ by her private key +x+, in which case +x+
is called a _scalar_ because it scales up +G+. The result is +xG+,
curve called the Generator (_G_) (see <<public_key_derivation>>). Alice uses EC
multiplication to multiply _G_ by her private key _x_, in which case _x_
is called a _scalar_ because it scales up _G_. The result is _xG_,
which we call Alice's _public key_. Alice gives her public key to Bob.
Even though Bob also knows +G+, the DLP prevents Bob from being able to divide +xG+ by +G+ to derive Alice's
Even though Bob also knows _G_, the DLP prevents Bob from being able to divide _xG_ by _G_ to derive Alice's
private key.
At some later time, Bob wants Alice to identify herself by proving
that she knows the scalar +x+ for the public key (+xG+) that Bob
received earlier. Alice can't give Bob +x+ directly because that would
that she knows the scalar _x_ for the public key (_xG_) that Bob
received earlier. Alice can't give Bob _x_ directly because that would
allow him to identify as her to other people, so she needs to prove
her knowledge of +x+ without revealing +x+ to Bob,((("zero-knowledge proof"))) called a
her knowledge of _x_ without revealing _x_ to Bob,((("zero-knowledge proof"))) called a
_zero-knowledge proof_. For that, we begin the schnorr identity
process:
1. Alice chooses another large random number (+k+), which we call the
_private nonce_. Again she uses it as a scalar, multiplying it by +G+
to produce +kG+, which we call the _public nonce_. She gives the
1. Alice chooses another large random number (_k_), which we call the
_private nonce_. Again she uses it as a scalar, multiplying it by _G_
to produce _kG_, which we call the _public nonce_. She gives the
public nonce to Bob.
2. Bob chooses a large random number of his own, +e+, which we call the
2. Bob chooses a large random number of his own, _e_, which we call the
_challenge scalar_. We say "challenge" because it's used to challenge
Alice to prove that she knows the private key (+x+) for the public key
(+xG+) she previously gave Bob; we say "scalar" because it will later
Alice to prove that she knows the private key (_x_) for the public key
(_xG_) she previously gave Bob; we say "scalar" because it will later
be used to multiply an EC point.
3. Alice now has the numbers (scalars) +x+, +k+, and +e+. She combines
them together to produce a final scalar +s+ using the formula
+s = k + ex+. She gives +s+ to Bob.
3. Alice now has the numbers (scalars) _x_, _k_, and _e_. She combines
them together to produce a final scalar _s_ using the formula
_s_ = _k_ + _ex_. She gives _s_ to Bob.
4. Bob now knows the scalars +s+ and +e+, but not +x+ or +k+. However,
Bob does know +xG+ and +kG+, and he can compute for himself +sG+ and
+exG+. That means he can check the equality of a scaled-up version of
the operation Alice performed: +sG == kG + exG+. If that is equal,
then Bob can be sure that Alice knew +x+ when she generated +s+.
4. Bob now knows the scalars _s_ and _e_, but not _x_ or _k_. However,
Bob does know _xG_ and _kG_, and he can compute for himself _sG_ and
_exG_. That means he can check the equality of a scaled-up version of
the operation Alice performed: _sG_ == _kG_ + _exG_. If that is equal,
then Bob can be sure that Alice knew _x_ when she generated _s_.
.Schnorr Identity Protocol with Integers Instead of Points
****
It might be easier to understand the interactive schnorr identity
protocol if we create an insecure oversimplification by substituting each of the preceding values (including +G+) with simple integers instead of points on an elliptic curve.
protocol if we create an insecure oversimplification by substituting each of the preceding values (including _G_) with simple integers instead of points on an elliptic curve.
For example, we'll use the prime numbers starting with 3:
Setup: Alice chooses +x=3+ as her private key. She multiplies it by the
generator +G=5+ to get her public key +xG=15+. She gives Bob +15+.
Setup: Alice chooses _x_ = 3 as her private key. She multiplies it by the
generator _G_ = 5 to get her public key _xG_ = 15. She gives Bob 15.
1. Alice chooses the private nonce +k=7+ and generates the public nonce
+kG=35+. She gives Bob +35+.
1. Alice chooses the private nonce _k_ = 7 and generates the public nonce
_kG_ = 35. She gives Bob 35.
2. Bob chooses +e=11+ and gives it to Alice.
2. Bob chooses _e_ = 11 and gives it to Alice.
3. Alice generates +s = 40 = 7 + 11 * 3+. She gives Bob +40+.
3. Alice generates _s_ = 40 = 7 + 11 × 3. She gives Bob 40.
4. Bob derives +sG = 200 = 40 * 5+ and +exG = 165 = 11 * 15+. He then
verifies that +200 == 35 + 165+. Note that this is the same operation
that Alice performed, but all of the values have been scaled up by +5+
(the value of +G+).
4. Bob derives _sG_ = 200 = 40 × 5 and _exG_ = 165 = 11 × 15. He then
verifies that 200 == 35 + 165. Note that this is the same operation
that Alice performed, but all of the values have been scaled up by 5
(the value of _G_).
Of course, this is an oversimplified example. When working with simple
integers, we can divide products by the generator +G+ to get the
integers, we can divide products by the generator _G_ to get the
underlying scalar, which isn't secure. This is why a critical property
of the elliptic curve cryptography used in Bitcoin is that
multiplication is easy but division by a point on the curve is impractical. Also, with numbers
@ -409,13 +409,13 @@ brute force is easy; the numbers used in Bitcoin are much larger.
Let's discuss some of the features of the interactive schnorr
identity protocol that make it secure:
The nonce (+k+)::
The nonce ([.plain]#k#)::
In step 1, ((("digital signatures", "schnorr signature algorithm", "security features")))((("schnorr signature algorithm", "security features")))Alice chooses a number that Bob doesn't
know and can't guess and gives him the scaled form of that number,
+kG+. At that point, Bob also already has her public key (+xG+),
which is the scaled form of +x+, her private key. That means when Bob is working on
the final equation (+sG = kG + exG+), there are two independent
variables that Bob doesn't know (+x+ and +k+). It's possible to use
_kG_. At that point, Bob also already has her public key (_xG_),
which is the scaled form of _x_), her private key. That means when Bob is working on
the final equation (_sG_ = _kG_ + _exG_), there are two independent
variables that Bob doesn't know (_x_ and _k_). It's possible to use
simple algebra to solve an equation with one unknown variable but not
two independent unknown variables, so the presence of Alice's nonce
prevents Bob from being able to derive her private key. It's critical
@ -424,24 +424,24 @@ In step 1, ((("digital signatures", "schnorr signature algorithm", "security fea
be able to leverage that into figuring out Alice's private key. See
<<nonce_warning>> for more details.
The challenge scalar (+e+)::
The challenge scalar ([.plain]#e#)::
Bob waits to receive Alice's public nonce
and then proceeds in step 2 to give her a number (the challenge
scalar) that Alice didn't previously know and couldn't have guessed.
It's critical that Bob only give her the challenge scalar after she
commits to her public nonce. Consider what could happen if someone
who didn't know +x+ wanted to impersonate Alice, and Bob accidentally
gave them the challenge scalar +e+ before they told him the public
nonce +kG+. This allows the impersonator to change parameters on both sides of
the equation that Bob will use for verification, +sG == kG + exG+;
specifically, they can change both +sG+ and +kG+. Think about a
simplified form of that expression: +x = y + a+. If you can change both
+x+ and +y+, you can cancel out +a+ using +x' = (x - a) + a+. Any
value you choose for +x+ will now satisfy the equation. For the
actual equation the impersonator simply chooses a random number for +s+, generates
+sG+, and then uses EC subtraction to select a +kG+ that equals +kG =
sG - exG+. They give Bob their calculated +kG+ and later their random
+sG+, and Bob thinks that's valid because +sG == (sG - exG) + exG+.
who didn't know _x_ wanted to impersonate Alice, and Bob accidentally
gave them the challenge scalar _e_ before they told him the public
nonce _kG_. This allows the impersonator to change parameters on both sides of
the equation that Bob will use for verification, _sG_ == _kG_ + _exG_;
specifically, they can change both _sG_ and _kG_. Think about a
simplified form of that expression: _x_ = _y_ + _a_. If you can change both
_x_ and _y_, you can cancel out _a_ using _x_++'++ = (_x_ - _a_) + _a_. Any
value you choose for _x_ will now satisfy the equation. For the
actual equation the impersonator simply chooses a random number for _s_, generates
_sG_, and then uses EC subtraction to select a _kG_ that equals _kG_ =
_sG_ - _exG_. They give Bob their calculated _kG_ and later their random
_sG_, and Bob thinks that's valid because _sG_ == (_sG_ - _exG_) + _exG_.
This explains why the order of operations in the protocol is
essential: Bob must only give Alice the challenge scalar after Alice
has committed to her public nonce.
@ -479,10 +479,10 @@ Alice can't predict the output of the hash function (the challenge), and
because it's always the same for the same input (the nonce), this
ensures that Alice gets a random challenge even though she chooses the nonce
and hashes it herself. We no longer need interaction from Bob. She can
simply publish her public nonce +kG+ and the scalar +s+, and each of the
thousands of full nodes (past and future) can hash +kG+ to produce +e+,
use that to produce +exG+, and then verify +sG == kG + exG+. Written
explicitly, the verification equation becomes +sG == kG + hash(kG) * xG+.
simply publish her public nonce _kG_ and the scalar _s_, and each of the
thousands of full nodes (past and future) can hash _kG_ to produce _e_,
use that to produce _exG_, and then verify _sG_ == _kG_ + _exG_. Written
explicitly, the verification equation becomes _sG_ == _kG_ + hash(_kG_) × _xG_.
We need one other thing to finish converting the interactive schnorr
identity protocol into a digital signature protocol useful for
@ -491,8 +491,8 @@ key; we also want to give her the ability to commit to a message. Specifically,
we want her to commit to the data related to the Bitcoin transaction she
wants to send. With the Fiat-Shamir transform in place, we already
have a commitment, so we can simply have it additionally commit to the
message. Instead of +hash(kG)+, we now also commit to the message
+m+ using +hash(kG || m)+, where +||+ stands for concatenation.
message. Instead of hash(_kG_), we now also commit to the message
_m_ using hash(_kG_ || _m_), where || stands for concatenation.
We've now defined a version of the schnorr signature protocol, but
there's one more thing we need to do to address a Bitcoin-specific
@ -508,7 +508,7 @@ also support several protocols people wanted to build on top of schnorr
signatures, Bitcoin's version of schnorr signatures, called _BIP340
schnorr signatures for secp256k1_, also commits to the public key being
used in addition to the public nonce and the message. That makes the
full commitment +hash(kG || xG || m)+.
full commitment hash(_kG_ || _xG_ || _m_).
Now that we've described each part of the BIP340 schnorr signature
algorithm and explained what it does for us, we can define the protocol.
@ -518,50 +518,50 @@ secp256k1 standard) and the remainder is used. The number _p_ is very
large, but if it was 3 and the result of an operation was 5, the actual
number we would use is 2 (i.e., 5 divided by 3 is 2).
Setup: Alice chooses a large random number (+x+) as her private key
Setup: Alice chooses a large random number (_x_) as her private key
(either directly or by using a protocol like BIP32 to deterministically
generate a private key from a large random seed value). She uses the
parameters defined in secp256k1 (see <<elliptic_curve>>) to multiply the
generator +G+ by her scalar +x+, producing +xG+ (her public key). She
generator _G_ by her scalar _x_, producing _xG_ (her public key). She
gives her public key to everyone who will later authenticate her Bitcoin
transactions (e.g., by having +xG+ included in a transaction output). When
transactions (e.g., by having _xG_ included in a transaction output). When
she's ready to spend, she begins generating her signature:
1. Alice chooses a large random private nonce +k+ and derives the public
nonce +kG+.
1. Alice chooses a large random private nonce _k_ and derives the public
nonce _kG_.
2. She chooses her message +m+ (e.g., transaction data) and generates the
challenge scalar +e = hash(kG || xG || m)+.
2. She chooses her message _m_ (e.g., transaction data) and generates the
challenge scalar _e_ = hash(_kG_ || _xG_ || _m_).
3. She produces the scalar +s = k + ex+. The two values +kG+ and +s+
3. She produces the scalar _s_ = _k_ + _ex_. The two values _kG_ and _s_
are her signature. She gives this signature to everyone who wants to
verify that signature; she also needs to ensure everyone receives her
message +m+. In Bitcoin, this is done by including her signature in
message _m_. In Bitcoin, this is done by including her signature in
the witness structure of her spending transaction and then relaying that
transaction to full nodes.
4. The verifiers (e.g., full nodes) use +s+ to derive +sG+ and then
verify that +sG == kG + hash(kG || xG || m)*xG+. If the equation is
valid, Alice proved that she knows her private key +x+ (without
revealing it) and committed to the message +m+ (containing the
4. The verifiers (e.g., full nodes) use _s_ to derive _sG_ and then
verify that _sG_ == _kG_ + hash(_kG_ || _xG_ || _m_) × _xG_. If the equation is
valid, Alice proved that she knows her private key _x_ (without
revealing it) and committed to the message _m_ (containing the
transaction data).
==== Serialization of Schnorr Signatures
A schnorr signature ((("digital signatures", "schnorr signature algorithm", "serialization")))((("schnorr signature algorithm", "serialization")))((("serialization", "of schnorr signature algorithm", secondary-sortas="schnorr")))consists of two values, +kG+ and +s+. The value
+kG+ is a point on Bitcoin's elliptic curve (called secp256k1) and would normally be represented by two 32-byte coordinates, e.g., +(x,y)+.
A schnorr signature ((("digital signatures", "schnorr signature algorithm", "serialization")))((("schnorr signature algorithm", "serialization")))((("serialization", "of schnorr signature algorithm", secondary-sortas="schnorr")))consists of two values, _kG_ and _s_. The value
_kG_ is a point on Bitcoin's elliptic curve (called secp256k1) and would normally be represented by two 32-byte coordinates, e.g., (_x_, _y_).
However, only the _x_ coordinate is needed, so only that value is
included. When you see +kG+ in schnorr signatures for Bitcoin, note that it's only that point's _x_
included. When you see _kG_ in schnorr signatures for Bitcoin, note that it's only that point's _x_
coordinate.
The value +s+ is a scalar (a number meant to multiply other numbers). For
The value _s_ is a scalar (a number meant to multiply other numbers). For
Bitcoin's secp256k1 curve, it can never be more than 32 bytes long.
Although both +kG+ and +s+ can sometimes be values that can be
Although both _kG_ and _s_ can sometimes be values that can be
represented with fewer than 32 bytes, it's improbable that they'd be
much smaller than 32 bytes, so they're serialized as two 32-byte
values (i.e., values smaller than 32 bytes have leading zeros).
They're serialized in the order of +kG+ and then +s+, producing exactly
They're serialized in the order of _kG_ and then _s_, producing exactly
64 bytes.
The taproot soft fork, also called v1 segwit, introduced schnorr signatures
@ -581,10 +581,10 @@ the serialization used for ECDSA signatures described in
==== Schnorr-based Scriptless Multisignatures
In the((("digital signatures", "schnorr signature algorithm", "scriptless multisignatures", id="digital-sigs-schnorr-multisig")))((("schnorr signature algorithm", "scriptless multisignatures", id="schnorr-multisig")))((("scriptless multisignatures", "in schnorr signature algorithm", secondary-sortas="schnorr", id="scriptless-multi-schnorr")))((("multisignature scripts", "in schnorr signature algorithm", secondary-sortas="schnorr", id="multi-script-schnorr")))((("scripts", "multisignature", "in schnorr signature algorithm", tertiary-sortas="schnorr", id="script-multisignature-schnorr"))) single-signature schnorr protocol described in <<schnorr_signatures>>, Alice
uses a signature (+kG+, +s+) to publicly prove her knowledge of her
private key, which in this case we'll call +y+. Imagine if Bob also has
a private key (+z+) and he's willing to work with Alice to prove that
together they know +x = y + z+ without either of them revealing their
uses a signature (_kG_, _s_) to publicly prove her knowledge of her
private key, which in this case we'll call _y_. Imagine if Bob also has
a private key (_z_) and he's willing to work with Alice to prove that
together they know _x_ = _y_ + _z_ without either of them revealing their
private key to each other or anyone else. Let's go through the BIP340
schnorr signature protocol again.
@ -596,27 +596,27 @@ mechanics of schnorr multisignatures before describing related protocols
that are believed to be secure.
====
Alice and Bob need to derive the public key for +x+, which is +xG+.
Alice and Bob need to derive the public key for _x_, which is _xG_.
Since it's possible to use elliptic curve operations to add two EC
points together, they start by Alice deriving +yG+ and Bob deriving
+zG+. They then add them together to create +xG = yG + zG+. The point
+xG+ is ((("aggregated public keys")))((("public keys", "aggregated")))their _aggregated public key_. To create a signature, they begin the
points together, they start by Alice deriving _yG_ and Bob deriving
_zG_. They then add them together to create _xG_ = _yG_ + _zG_. The point
_xG_ is ((("aggregated public keys")))((("public keys", "aggregated")))their _aggregated public key_. To create a signature, they begin the
simple multisignature protocol:
1. They each individually choose a large random private nonce, +a+ for
Alice and +b+ for Bob. They also individually derive the corresponding
public nonce +aG+ and +bG+. Together, they produce an aggregated
public nonce +kG = aG + bG+.
1. They each individually choose a large random private nonce, _a_ for
Alice and _b_ for Bob. They also individually derive the corresponding
public nonce _aG_ and _bG_. Together, they produce an aggregated
public nonce _kG_ = _aG_ + _bG_.
2. They agree on the message to sign, +m+ (e.g., a transaction), and
each generates a copy of the challenge scalar: +e = hash(kG || xG || m)+.
2. They agree on the message to sign, _m_ (e.g., a transaction), and
each generates a copy of the challenge scalar: _e_ = hash(_kG_ || _xG_ || _m_).
3. Alice produces the scalar +q = a + ey+. Bob produces the scalar
+r = b + ez+. They add the scalars together to produce
+s = q + r+. Their signature is the two values +kG+ and +s+.
3. Alice produces the scalar _q_ = _a_ + _ey_. Bob produces the scalar
_r_ = _b_ + _ez_. They add the scalars together to produce
_s_ = _q_ + _r_. Their signature is the two values _kG_ and _s_.
4. The verifiers check their public key and signature using the normal
equation: +sG == kG + hash(kG || xG || m)*xG+.
equation: _sG_ == _kG_ + hash(_kG_ || _xG_ || _m_) × _xG_.
Alice and Bob have proven that they know the sum of their private keys without
either one of them revealing their private key to the other or anyone
@ -627,10 +627,10 @@ different keys).
The preceding protocol has several security problems. Most notable is that one
party might learn the public keys of the other parties before committing
to their own public key. For example, Alice generates her public key
+yG+ honestly and shares it with Bob. Bob generates his public key
using +zG - yG+. When their two keys are combined (+yG + zG - yG+), the
positive and negative +yG+ terms cancel out so the public key only represents
the private key for +z+ (i.e., Bob's private key). Now Bob can create a
_yG_ honestly and shares it with Bob. Bob generates his public key
using _zG_ - _yG_. When their two keys are combined (_yG_ + _zG_ - _yG_), the
positive and negative _yG_ terms cancel out so the public key only represents
the private key for _z_ (i.e., Bob's private key). Now Bob can create a
valid signature without any assistance from Alice. This is ((("key cancellation attacks")))called a
_key cancellation attack_.
@ -727,7 +727,7 @@ than a nonparticipant who didn't have a share.
A secure secret sharing scheme prevents participants from learning
anything about the secret unless they combine the minimum threshold
number of shares. For example, Alice can choose a threshold of
+2+ if she wants any two of Bob, Carol, and Dan to be able to
2 if she wants any two of Bob, Carol, and Dan to be able to
reconstruct her secret. The best known secure secret sharing algorithm
is _Shamir's Secret Sharing Scheme_, commonly abbreviated SSSS and named
after its discoverer, one of the same discoverers of the Fiat-Shamir
@ -873,7 +873,7 @@ the _R_, _s_ values and the public key to calculate a value _K_, which
is a point on the elliptic curve (the public nonce used in
signature creation):
_K_ = __s__^-1^ * __Hash__(__m__) * _G_ + __s__^-1^ * _R_ * _X_
_K_ = __s__^-1^ × __Hash__(__m__) × _G_ + __s__^-1^ × _R_ × _X_
where:
@ -903,7 +903,7 @@ the following DER-encoded signature:
b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e381301
----
That signature is a serialized byte stream of the +R+ and +S+ values
That signature is a serialized byte stream of the +R+ and _s_ values
produced by the signer to prove control of the private key authorized
to spend an output. The serialization format consists of nine elements
as follows:

View File

@ -35,7 +35,7 @@ previous transaction and is also an exception to several other rules
that apply to other transactions. Coinbase transactions don't pay
transaction fees, don't need to be fee bumped, aren't subject to
transaction pinning, and are largely uninteresting to the following
discussion about fees--so we're going to ignore them in this chapter.
discussion about fees--so we're going to ignore them in this [.keep-together]#chapter.#
====
The criterion that almost all miners use to select which transactions to
@ -587,11 +587,13 @@ and the sum of outputs. Any excess amount that remains after all outputs
have been deducted from all inputs is the fee that is collected by the
miners:
[[tx_fee_equation]]
.Transaction fees are implied, as the excess of inputs minus outputs:
----
Fees = Sum(Inputs) Sum(Outputs)
----
[latexmath]
++++
\begin{equation}
{Fees = Sum(Inputs) Sum(Outputs)}
\end{equation}
++++
This is a somewhat confusing element of transactions and an important
point to understand because if you are constructing your own

View File

@ -915,17 +915,43 @@ If we count the frequency of each difference occurring, we see that the
small differences are much more likely to occur than the large
differences:
[cols="1,1"]
[options="header"]
|===
| Difference | Occurrences
| 0 | 6
| 1 | 10
| 2 | 8
| 3 | 6
| 4 | 4
| 5 | 2
|===
++++
<table>
<thead>
<tr>
<th>Difference</th>
<th>Occurrences</th>
</tr>
</thead>
<tbody>
<tr>
<td><p>0</p></td>
<td><p>6</p></td>
</tr>
<tr>
<td><p>1</p></td>
<td><p>10</p></td>
</tr>
<tr>
<td><p>2</p></td>
<td><p>8</p></td>
</tr>
<tr>
<td><p>3</p></td>
<td><p>6</p></td>
</tr>
<tr>
<td><p>4</p></td>
<td><p>4</p></td>
</tr>
<tr>
<td><p>5</p></td>
<td><p>2</p></td>
</tr>
</tbody>
</table>
++++
If we know that we might need to store large numbers (because large
differences can happen, even if they are rare), but we'll most often need

View File

@ -450,8 +450,8 @@ transactions leading to the same merkle root. For example, the two
trees in <<cve_tree>>:
[[cve_tree]]
[.width-90]
.Two Bitcoin-style merkle tree with the same root but a different number of leaves
[role="width-90"]
.Two Bitcoin-style merkle trees with the same root but a different number of leaves
image::images/mbc3_1104.png["Two Bitcoin-style merkle trees with the same root but a different number of leaves"]
The transaction lists [1,2,3,4,5,6] and [1,2,3,4,5,6,5,6] (where 5 and

View File

@ -382,9 +382,13 @@ To construct((("rewards", id="reward-coinbase")))((("transaction fees", "in coin
coinbase transaction, Jing's node first calculates the total amount of
transaction fees:
----
[latexmath]
++++
\begin{equation}
Total Fees = Sum(Inputs) - Sum(Outputs)
----
\end{equation}
++++
Next, Jing's node calculates the correct reward for the new block. The
reward is calculated based on the block height, starting at 50 bitcoin

View File

@ -1025,7 +1025,7 @@ connect over the internet to Eric's LN node. Eric's LN node creates a
secret +R+ using a random number generator. Eric's node does not reveal
this secret to anyone. Instead, Eric's node calculates a hash +H+ of the
secret +R+ and transmits this hash to Alice's node in the form of an
invoice (see <<ln_payment_process>> step 1).
invoice (see <<ln_payment_process>>, [.keep-together]#step 1).#
Now Alice's LN node constructs a route between Alice's LN node and
Eric's LN node. The pathfinding algorithm used will be examined in more