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
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
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.