BIP 0340
What does a signature verifier actually check?
A BIP 340 verifier receives a public key, a message and 64 bytes of signature. It runs a short list of checks, fixed down to the byte, and any one of them can refuse.
When a wallet shows that a payment was authorized, a program somewhere has run a verifier: a function that takes a public key, a message and a signature, and answers yes or no. It sees no secret key and learns nothing about who pressed a button. It only checks whether the three inputs fit together.12
BIP 340, assigned in 2020 and recorded as deployed, specifies 64-byte Schnorr signatures over secp256k1, the same curve Bitcoin already used for ECDSA. This chapter follows its verifier one check at a time, using the BIP’s own published test vectors, valid and invalid.345
Source details
This chapter is an independent explanation, not the proposals themselves. Preamble fields are shown as recorded in the pinned files, with author e-mail addresses omitted. Status is the proposal’s own field, not an endorsement or a sign of consensus.
BIP 340: Schnorr Signatures for secp256k1
- BIP
- 340
- Title
- Schnorr Signatures for secp256k1
- Authors
- Pieter Wuille
Jonas Nick
Tim Ruffing - Comments-Summary
- No comments yet.
- Comments-URI
- https://github.com/bitcoin/bips/wiki/Comments:BIP-0340
- Status
- Deployed
- Type
- Specification
- Assigned
- 2020-01-19
- License
- BSD-2-Clause
- License-Code
- BSD-2-Clause OR MIT OR CC0-1.0
pkpublic key · 32 bytes
dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659x coordinate of P; its y is taken to be the even oneSame point as the 33-byte compressed key 02 ‖ pk.
mmessage · any length, here 32 bytes
243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89sigsignature · 64 bytes
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341x coordinate of a point R with even y; must be below ps · bytes 32–638906d11ac976abccb20b091292bff4ea897efcb639ea871cfa95f6de339e4b0aa number; must be below nBIP 340 test-vectors.csv line 3 (vector 1). Hex most significant byte first.
Three inputs, one answer
The verifier’s inputs have fixed shapes. The public key is exactly 32 bytes. The signature is exactly 64 bytes. The message is a byte array of any length, including none at all.189
Those sizes were deliberate choices. ECDSA signatures in Bitcoin are DER-encoded, so they vary in size and can reach 72 bytes; BIP 340 uses a simple fixed format instead. Public keys shrink from the usual 33-byte compressed point to 32 bytes, because only the x coordinate is kept.10
The authors also wanted something stricter than most signature standards provide. For use in consensus, they write, the verification algorithm must be completely specified at the byte level, so that nobody can build a signature that some verifiers accept and others reject. They point to the trouble Bitcoin once had with loosely specified DER parsing. Every check below is therefore an exact test, with nothing left to an implementation’s taste.11
The 64 bytes split cleanly in two. The first half, r, is the x coordinate of a curve point R that the signer committed to. The second half, s, is a number. Together they must satisfy one equation, s⋅G = R + e⋅P, where G is the curve’s fixed base point, P is the public key’s point, and e is a hash that binds R, the key and the message together.6
Eight steps, in order
BIP 340 writes Verify as a list. First, turn the key into a point: lift_x takes the 32 bytes as an x coordinate and returns the curve point with that x and an even y, or fails if the number is too large or no such point exists. Next, read r and s from the signature and fail unless r is below the field size p and s is below the curve order n.212
Then compute the challenge e, a tagged hash of r, the key and the message, reduced modulo n. Use it to compute R = s⋅G − e⋅P. Fail if R is the point at infinity, fail if its y coordinate is odd, and fail if its x coordinate is not r. Success means no step failed.2
The figure runs this list on the published vectors. Choose a valid vector and every stage passes. Choose an invalid one and the run stops at the first failure: a key with no curve point fails at the first stage, and an r equal to p fails at the second, before any hashing. Later stages are marked as not reached, because the BIP’s verifier never gets to them.213
A · Interactive
Static view: the first vector checked against its own message, every stage shown. With JavaScript you can choose any of the 12 published vectors, swap in another fixture’s message, and reveal the verifier’s stages one at a time.
- pk 32 bytes
dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659- m 32 bytes
243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89- sig 64 bytes = r ‖ s
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de33418906d11ac976abccb20b091292bff4ea897efcb639ea871cfa95f6de339e4b0a
- 01Lift the keypassesIs pk a valid x coordinate (below p, with a curve point)? Take the point P with even y.y
2ce19b946c4ee58546f5251d441a065ea50735606985e5b228788bec4e582898P has even y. x(P) = pk. - 02Read rpassesr = first 32 bytes of the signature. Is r below the field size p?r
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341r < p - 03Read spassess = last 32 bytes. Is s below the group order n?s
8906d11ac976abccb20b091292bff4ea897efcb639ea871cfa95f6de339e4b0as < n - 04Hash the challengepassese = hash tagged “BIP0340/challenge” of r ‖ P ‖ m, reduced mod n.challenge hash
cfb58e748d9648b71fdc909fb7432fc0c954da5bd75cdc9d4804d32648f9839aecfb58e748d9648b71fdc909fb7432fc0c954da5bd75cdc9d4804d32648f9839aThe hash is already below n, so e equals it. - 05Compute RpassesR = s⋅G − e⋅P, using secp256k1 point arithmetic.x
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341y20bc7663da14be43c22eb2ccb49cd746573b2766b277273fcb20a2f6c1a60c6cy(R) is even. - 06R is not infinitypassesFail if R is the point at infinity.R is an ordinary point.
- 07R has even ypassesFail if the y coordinate of R is odd.y(R) is even.
- 08x(R) equals rpassesFail unless the x coordinate of R equals r.x(R)
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341r6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341x(R) = r: the signature verifies.
✓ success Every check passed. Published result for vector 1: TRUE.
Source: BIP 340 test-vectors.csv line 3. Arithmetic: @noble/curves; every result shown is cross-checked against noble’s own verifier. Hex is shown most significant byte first.
B · Worked example
Published vector 1 from the BIP 340 CSV, checked step by step.
Lift the key to the point P with even y
- pk = x(P)
dff1d77f2a671c5f36183726db2341be58feae1da2deced843240f7b502ba659- y(P)
2ce19b946c4ee58546f5251d441a065ea50735606985e5b228788bec4e582898
Split the signature and check r < p and s < n
- r
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341- s
8906d11ac976abccb20b091292bff4ea897efcb639ea871cfa95f6de339e4b0a
Hash r ‖ P ‖ m with the BIP0340/challenge tag
- m
243f6a8885a308d313198a2e03707344a4093822299f31d0082efa98ec4e6c89- e
cfb58e748d9648b71fdc909fb7432fc0c954da5bd75cdc9d4804d32648f9839a
Compute R = s⋅G − e⋅P
- x(R)
6896bd60eeae296db48a229ff71dfe071bde413e6d43f917dc8dcf8c78de3341- y(R)
20bc7663da14be43c22eb2ccb49cd746573b2766b277273fcb20a2f6c1a60c6c
Checked: R is not the point at infinity, and y(R) is even.
Compare x(R) with r
Equal: the signature verifies, as the CSV says.
Source: BIP 340 test-vectors.csv line 3; arithmetic by @noble/curves.
Each vector in the CSV carries a short comment. These describe how a failing vector was built, not necessarily which check catches it. Vector 7 is labelled “negated message”, yet it never reaches the comparison of x(R) with r: the R it produces has an odd y coordinate, so it fails one step earlier. Vectors 8 and 11 do reach that comparison, and fail there. Reading the BIP’s algorithm and watching it run are two different kinds of evidence, and this page shows both.1315
Try the message control on a valid vector. The key and signature stay the same, but another message changes e, which changes R. For every valid vector in the figure, that is enough to fail, at either the even-y check or the x comparison. Nothing in the verifier knows which message was “meant”; it only checks the one it is given.214
What the challenge binds together
The challenge e is where the message enters. BIP 340 hashes it with a tagged hash: SHA-256 of the tag’s own SHA-256 written twice, followed by the data. Here the tag is the text BIP0340/challenge. The authors use tags so that a hash computed for one purpose cannot be reinterpreted as a hash for another.1718
The data is r, then the public key, then the message. Including the key is called key prefixing, and the authors explain why it matters. Without it, anyone could turn a valid signature for a key P into a valid signature for P + a⋅G, for any tweak a they like. They note this would make signatures insecure for keys made by adding tweaks, as BIP 32’s unhardened derivation and Taproot both do.619
The message is hashed whole, whatever its length. Earlier revisions of BIP 340 required exactly 32 bytes, and the changelog records the lifting of that rule in April 2023. The published vectors include valid signatures over messages of 0, 1, 17 and 100 bytes alongside the usual 32. The BIP still recommends pre-hashing large messages for performance, and BIP 341’s transaction signatures do sign a 32-byte digest.8920
SHA256(“BIP0340/challenge”) = 7bb52d7a9fef58323eb1bf7a407db382d2f3f2d81bb1224f49fe518f6d48d37c
vector 150-byte message · SHA256 of 128 bytes
hash = d3561670cd8b50b077cd4e229a6e1c09a1a663ad08264632a8596194b9e0abc7 → e = hash mod n
vector 161-byte message · SHA256 of 129 bytes
hash = 4535cf052478f0f45f226501cf68dd6898143de5d6905e7f6607a1c6b4323a60 → e = hash mod n
vector 1717-byte message · SHA256 of 145 bytes
hash = 63f0aac9b6b870317dee839c5f5a7f1b584d0cd82c2bba4002cfca02ddef9b74 → e = hash mod n
vector 132-byte message · SHA256 of 160 bytes
hash = cfb58e748d9648b71fdc909fb7432fc0c954da5bd75cdc9d4804d32648f9839a → e = hash mod n
vector 18100-byte message · SHA256 of 228 bytes
hash = 44dd9fe38ba9fefa45d2aca76a95ff66cc535e11fd695b65448374f2016efae3 → e = hash mod n
tag prefix, 64 bytesr, 32 bytespublic key, 32 bytesmessage, any length
BIP 340 test-vectors.csv lines 17, 18, 19, 3, 20. Every one of these signatures verifies.
Details: why the signature carries R and not e
Schnorr signatures come in two forms. One publishes e and s; the other publishes R and s. BIP 340 chose R, which the authors say supports batch verification because no curve operation sits inside a hash. Batch verification checks many signatures together: it always succeeds if every signature is valid, and succeeds with only negligible probability if any is not.2122
Why only x coordinates
Every valid x coordinate on the curve has two possible y values, one even and one odd. BIP 340 removes the ambiguity by rule: the key’s point P and the signature’s point R are always taken to have even y. That is why an x-only key is equivalent to a compressed key beginning with the byte 0x02.67
The figure shows the consequence in two places. The verifier lifts the key to its even-y point before anything else, and it rejects any R whose y turns out odd. The authors argue that, although it halves the set of valid public keys, it is not a reduction in security: breaking an x-only key is at most a small constant faster than breaking a full one. One side effect is stated outright: every public key has two matching secret keys, sk and n − sk.122324
Details: lift_x and the constants
What a passing check does not say
A successful Verify establishes one thing: this signature fits this key and this message under BIP 340’s equation. It does not say what the message means, and BIP 340 asks applications to keep contexts apart, so that a signed message from one application is never accepted as something else, such as a transaction. The authors also note that the security of Schnorr signatures implies they are non-malleable, while ECDSA signatures are inherently malleable.22627
Nor does BIP 340 by itself provide a multisignature protocol. The key may belong to one person or be an aggregate of several. Schemes such as MuSig2, specified separately in BIP 327, let several parties build one key and one signature through an interactive protocol; to a verifier the result looks like any other signature. BIP 340 warns that multisignature schemes are generally insecure with the nonce generation of its default signing algorithm, or with any other deterministic method.2829
Signing is the one part this page leaves alone. The BIP specifies a default signer, but signatures are not unique: other ways of generating its random value produce different, equally valid signatures, and however that value is generated, it must be uniformly random and not even partially predictable to an attacker. Verification is guaranteed to accept what a correct signer produces. The BIP’s own Python code is labelled for demonstration only; the values here come from the audited @noble/curves library, checked against all 19 vectors in the CSV.5133031
Evidence
Each numbered marker in the text points here, and the ↩ links lead back to every place that cites an entry. Quotes are verbatim from the BIP files at commit
3a10b5b, including their wiki markup; links open
the exact lines; the quoted text sits under each entry. Labels say what kind of statement each is: a rule, the author’s rationale, history,
a test vector, or our own inference.
-
↩ a b c Rule Verify takes a 32-byte public key, a message of any length (a byte array), and a 64-byte signature.
Quoted source text (1)
* The public key ''pk'': a 32-byte array * The message ''m'': a byte array * A signature ''sig'': a 64-byte array
-
↩ a b c d e f g Rule Verify lifts pk to a point P, checks r < p and s < n, computes the challenge e, computes R = s⋅G − e⋅P, and fails if R is infinite, has odd y, or has an x coordinate different from r; it succeeds only if no step failed.
Quoted source text (1)
* Let ''P = lift_x(int(pk))''; fail if that fails. * Let ''r = int(sig[0:32])''; fail if ''r ≥ p''. * Let ''s = int(sig[32:64])''; fail if ''s ≥ n''. * Let ''e = int(hash<sub>BIP0340/challenge</sub>(bytes(r) || bytes(P) || m)) mod n''. * Let ''R = s⋅G - e⋅P''. * Fail if ''is_infinite(R)''. * Fail if ''not has_even_y(R)''. * Fail if ''x(R) ≠ r''. * Return success iff no failure occurred before reaching this point.
-
↩ History BIP 340 was assigned in 2020; its preamble records the status Deployed and the type Specification.
BIP 340 L11 BIP 340 L9 BIP 340 L10
Quoted source text (3)
Assigned: 2020-01-19
Status: Deployed
Type: Specification
-
↩ Rule BIP 340 proposes a standard for 64-byte Schnorr signatures over the curve secp256k1. It reuses the curve and hash function Bitcoin already uses for ECDSA.
Quoted source text (2)
This document proposes a standard for 64-byte Schnorr signatures over the elliptic curve ''secp256k1''.
By reusing the same curve and hash function as Bitcoin uses for ECDSA
-
↩ a b Rule The BIP's Python reference implementation is naive, non-constant-time and for demonstration only; the vectors are published as a CSV file.
BIP 340 L289 BIP 340 L292 BIP 340 L288
Quoted source text (3)
a naive, highly inefficient, and non-constant time [[bip-0340/reference.py|pure Python 3.7 reference implementation of the signing and verification algorithm]]
The reference implementation is for demonstration purposes only and not to be used in production environments.
we provide a [[bip-0340/test-vectors.csv|collection of test vectors in CSV format]]
-
↩ a b c d Rule The public key pk is the x coordinate of a point P with even y; a signature is (r, s) where r is the x coordinate of a point R with even y, and s⋅G = R + tagged_hash(r || pk || m)⋅P.
Quoted source text (1)
our final scheme ends up using public key ''pk'' which is the X coordinate of a point ''P'' on the curve whose Y coordinate is even and signatures ''(r,s)'' where ''r'' is the X coordinate of a point ''R'' whose Y coordinate is even. The signature satisfies ''s⋅G = R + tagged_hash(r || pk || m)⋅P''.
-
↩ a b Rule Every valid x coordinate has two possible y coordinates, one even and one odd; BIP 340 implicitly takes the even one for both P and R, so an x-only key is equivalent to a compressed key with the prefix byte 0x02.
BIP 340 L82 BIP 340 L77 BIP 340 L79
Quoted source text (3)
we pick that option for ''P'', and thus our X-only public keys become equivalent to a compressed public key that is the X-only key prefixed by the byte 0x02. For consistency, the same is done for ''R''
(every valid X coordinate has two possible Y coordinates)
This means that for a valid X coordinate, one of the corresponding Y coordinates will be even, and the other will be odd.
-
↩ a b c History BIP 340 accepts messages of arbitrary size; earlier revisions required exactly 32 bytes, and the changelog records the change in 2023-04. Pre-hashing is still recommended for performance with large messages. Implementations may reject messages too large for their environment.
BIP 340 L221 BIP 340 L225 BIP 340 L299 BIP 340 L234 BIP 340 L222
Quoted source text (5)
The signature scheme specified in this BIP accepts byte strings of arbitrary size as input messages.
Earlier revisions of this BIP required messages to be exactly 32 bytes.
2023-04: Allow messages of arbitrary size
We note that pre-hashing is recommended for performance reasons in applications that deal with large messages.
It is understood that implementations may reject messages which are too large in their environment or application context,
-
↩ a b c Test vector The published vectors include valid signatures on messages of 0, 1, 17, 32 and 100 bytes; for each, the challenge hash input is 64 tag bytes, 32 bytes of r, 32 bytes of P and the whole message.
BIP 340 (test-vectors.csv) L17 BIP 340 (test-vectors.csv) L18 BIP 340 (test-vectors.csv) L19 BIP 340 (test-vectors.csv) L20
Quoted source text (4)
message of size 0 (added 2022-12)
message of size 1 (added 2022-12)
message of size 17 (added 2022-12)
message of size 100 (added 2022-12)
-
↩ Author’s rationale BIP 340 uses a fixed 64-byte signature instead of DER encoding (variable size, up to 72 bytes) and 32-byte public keys instead of 33-byte compressed points.
Quoted source text (2)
-encoding for signatures (which are variable size, and up to 72 bytes), we can use a simple fixed 64-byte format.
public keys in this proposal are encoded as 32 bytes.
-
↩ Author’s rationale The authors require the verification algorithm to be completely specified at the byte level, so that nobody can make a signature valid to some verifiers but not others; they cite DER parsing problems with ECDSA.
BIP 340 L46 BIP 340 L46 BIP 340 L46
Quoted source text (3)
To be safe for usage in consensus systems, the verification algorithm must be completely specified at the byte level. This guarantees that nobody can construct a signature that is valid to some verifiers but not all.
the lack of exact specification for the DER parsing of ECDSA signatures has caused problems for Bitcoin
This is traditionally not a requirement for digital signature schemes
-
↩ a b Rule lift_x(x) returns the point with that x coordinate and even y, or fails if x is greater than p − 1 or no such point exists.
Quoted source text (2)
returns the point ''P'' for which ''x(P) = x''
and ''has_even_y(P)'', or fails if ''x'' is greater than ''p-1'' or no such point exists.
-
↩ a b c d Test vector All 19 published vectors (9 valid, 10 invalid) give the published result when run through this site's step-by-step verifier, which uses @noble/curves arithmetic and is cross-checked against noble's own verifier; the eight vectors with secret keys also reproduce their signatures.
Quoted source text (1)
index,secret key,public key,aux_rand,message,signature,verification result,comment
-
↩ a b Test vector Checking each valid hero vector's key and signature against another fixture's message fails, in every such pairing, at the even-y or x(R) step, because the message changes e and therefore R.
Quoted source text (1)
* Let ''e = int(hash<sub>BIP0340/challenge</sub>(bytes(r) || bytes(P) || m)) mod n''. * Let ''R = s⋅G - e⋅P''.
-
↩ a b Test vector The CSV comment says how an invalid vector was made, not necessarily which check rejects it: vector 7 ('negated message') is rejected because the recomputed R has odd y, before any x comparison; vectors 8 and 11 fail at the x(R) comparison.
BIP 340 (test-vectors.csv) L9 BIP 340 L188 BIP 340 (test-vectors.csv) L10
Quoted source text (3)
FALSE,negated message
* Fail if ''not has_even_y(R)''.
FALSE,negated s value
-
↩ a b Rule Points are on the curve y² = x³ + 7 over the integers modulo p; p is the field size and n the curve order, both given as exact constants.
Quoted source text (2)
Uppercase variables refer to points on the curve with equation ''y<sup>2</sup> = x<sup>3</sup> + 7'' over the integers modulo ''p''.
The constant ''p'' refers to the field size, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F''. ** The constant ''n'' refers to the curve order, ''0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141''.
-
↩ a b Rule hash_name(x) is SHA256(SHA256(tag) || SHA256(tag) || x), where tag is the UTF-8 encoding of name.
Quoted source text (1)
returns the 32-byte hash ''SHA256(SHA256(tag) || SHA256(tag) || x)'', where ''tag'' is the UTF-8 encoding of ''name''.
-
↩ Author’s rationale Tags keep a hash computed for one purpose from being reinterpreted in another context.
Quoted source text (1)
To make sure hashes used in one context can't be reinterpreted in another one, hash functions can be tweaked with a context-dependent tag name, in such a way that collisions across contexts can be assumed to be infeasible.
-
↩ Author’s rationale Without the public key in the challenge, a third party could turn a signature for P into one for P + a⋅G for any additive tweak a, which the authors say would make signatures insecure with BIP 32 unhardened derivation and with tweaks such as Taproot's; so the public key is prefixed to the message in the challenge.
BIP 340 L64 BIP 340 L64 BIP 340 L66
Quoted source text (3)
a third party can convert a signature ''(R, s)'' for public key ''P'' into a signature ''(R, s + a⋅hash(R || m))'' for public key ''P + a⋅G'' and the same message ''m'', for any given additive tweak ''a'' to the signing key.
and other methods that rely on additive tweaks to existing keys such as Taproot.
which means that the public key is prefixed to the message in the challenge hash input.
-
↩ Rule BIP 340 gives BIP 341 as an example of pre-hashing to a 32-byte digest; BIP 341's key-path rule verifies a signature over hash_TapSighash(0x00 || SigMsg(...)), a 32-byte tagged hash.
Quoted source text (2)
to create a 32-byte digest which can be passed to signing or verification (as for example done in [[bip-0341.mediawiki|BIP341]].)
return ''Verify(q, hash<sub>TapSighash</sub>(0x00 || SigMsg(0x00, 0)), sig)''
-
↩ Author’s rationale BIP 340 signatures reveal R (as r) rather than e; the authors chose this because it supports batch verification, as no elliptic-curve operations sit inside the hashes.
Quoted source text (2)
This supports batch verification, as there are no elliptic curve operations inside the hashes.
We choose the ''R''-option, which supports batch verification.
-
↩ Rule BIP 340 also specifies batch verification: if every signature is valid it succeeds; if any is invalid it succeeds only with negligible probability.
Quoted source text (1)
If all individual signatures are valid (i.e., ''Verify'' would return success for them), ''BatchVerify'' will always return success. If at least one signature is invalid, ''BatchVerify'' will return success with at most a negligible probability.
-
↩ Author’s rationale The authors argue that implicit y coordinates are not a reduction in security, although they halve the set of valid public keys: breaking an x-only key can be at most a small constant term faster than breaking a full one.
Quoted source text (2)
Despite halving the size of the set of valid public keys, implicit Y coordinates are not a reduction in security.
This shows that breaking an X-only public key can be at most a small constant term faster than breaking a full one.
-
↩ Rule Every BIP 340 public key has two corresponding secret keys, sk and n − sk.
Quoted source text (1)
A side effect is that ''PubKey(sk) = PubKey(bytes(n - int(sk))'', so every public key has two corresponding secret keys.
-
↩ Rule lift_x fails if x ≥ p, computes c = x³ + 7 mod p and y = c^((p+1)/4) mod p, fails if y² ≠ c, and returns the point with the even one of y and p − y.
Quoted source text (1)
*** Fail if ''x ≥ p''. *** Let ''c = x<sup>3</sup> + 7 mod p''. *** Let ''y = c<sup>(p+1)/4</sup> mod p''. *** Fail if ''c ≠ y<sup>2</sup> mod p''. *** Return the unique point ''P'' such that ''x(P) = x'' and ''y(P) = y'' if ''y mod 2 = 0'' or ''y(P) = p-y'' otherwise.
-
↩ Rule BIP 340 says applications should make sure a message signed for one context is never accepted in another, and recommends a tagged pre-hash or a 33-byte context prefix.
Quoted source text (2)
applications should ensure that a signed application message intended for one context is never deemed valid in a different context
we recommend applications to use exactly one of the following methods to pre-process application messages before passing it to the signature scheme:
-
↩ Author’s rationale The authors state that the SUF-CMA security of Schnorr signatures implies they are non-malleable, whereas ECDSA signatures are inherently malleable.
Quoted source text (1)
The SUF-CMA security of Schnorr signatures implies that they are non-malleable. On the other hand, ECDSA signatures are inherently malleable
-
↩ Rule Multiparty signing is left to interactive schemes such as MuSig2 (BIP 327); BIP 340 warns that multisignature schemes are generally insecure with the rand generation of its default signing algorithm or any other deterministic method.
Quoted source text (2)
By means of an interactive scheme such as [https://eprint.iacr.org/2020/1261.pdf MuSig2] ([[bip-0327.mediawiki|BIP327]]), participants can aggregate their public keys into a single public key which they can jointly sign for.
It is important to note that multisignature signing schemes in general are insecure with the ''rand'' generation from the default signing algorithm above (or any other deterministic method).
-
↩ Author’s rationale From a verifier's perspective, an n-of-n MuSig2 signature is no different from an ordinary signature.
Quoted source text (1)
This allows ''n''-of-''n'' multisignatures which, from a verifier's perspective, are no different from ordinary signatures
-
↩ Rule Signing is not unique: other ways of generating the rand value produce different but equally valid signatures; however rand is generated, it must be a fresh uniformly random 32-byte string not even partially predictable to an attacker.
Quoted source text (2)
producing a different but still valid signature (in other words, this is not a ''unique'' signature scheme)
the value must be a fresh uniformly random 32-byte string which is not even partially predictable for the attacker.
-
↩ Rule For every valid secret key and message, verifying the default signer's signature with the matching public key succeeds.
Quoted source text (1)
For every valid secret key ''sk'' and message ''m'', ''Verify(PubKey(sk),m,Sign(sk,m))'' will succeed.