Bitcoin ABC  0.24.7
P2P Digital Currency
sigencoding.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Copyright (c) 2017-2019 The Bitcoin developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include <script/sigencoding.h>
8 
9 #include <pubkey.h>
10 #include <script/script_flags.h>
11 
12 #include <boost/range/adaptor/sliced.hpp>
13 
14 typedef boost::sliced_range<const valtype> slicedvaltype;
15 
28  // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
29  // * total-length: 1-byte length descriptor of everything that follows,
30  // excluding the sighash byte.
31  // * R-length: 1-byte length descriptor of the R value that follows.
32  // * R: arbitrary-length big-endian encoded R value. It must use the
33  // shortest possible encoding for a positive integer (which means no null
34  // bytes at the start, except a single one when the next byte has its
35  // highest bit set).
36  // * S-length: 1-byte length descriptor of the S value that follows.
37  // * S: arbitrary-length big-endian encoded S value. The same rules apply.
38 
39  // Minimum and maximum size constraints.
40  if (sig.size() < 8 || sig.size() > 72) {
41  return false;
42  }
43 
44  //
45  // Check that the signature is a compound structure of proper size.
46  //
47 
48  // A signature is of type 0x30 (compound).
49  if (sig[0] != 0x30) {
50  return false;
51  }
52 
53  // Make sure the length covers the entire signature.
54  // Remove:
55  // * 1 byte for the coupound type.
56  // * 1 byte for the length of the signature.
57  if (sig[1] != sig.size() - 2) {
58  return false;
59  }
60 
61  //
62  // Check that R is an positive integer of sensible size.
63  //
64 
65  // Check whether the R element is an integer.
66  if (sig[2] != 0x02) {
67  return false;
68  }
69 
70  // Extract the length of the R element.
71  const uint32_t lenR = sig[3];
72 
73  // Zero-length integers are not allowed for R.
74  if (lenR == 0) {
75  return false;
76  }
77 
78  // Negative numbers are not allowed for R.
79  if (sig[4] & 0x80) {
80  return false;
81  }
82 
83  // Make sure the length of the R element is consistent with the signature
84  // size.
85  // Remove:
86  // * 1 byte for the coumpound type.
87  // * 1 byte for the length of the signature.
88  // * 2 bytes for the integer type of R and S.
89  // * 2 bytes for the size of R and S.
90  // * 1 byte for S itself.
91  if (lenR > (sig.size() - 7)) {
92  return false;
93  }
94 
95  // Null bytes at the start of R are not allowed, unless R would otherwise be
96  // interpreted as a negative number.
97  //
98  // /!\ This check can only be performed after we checked that lenR is
99  // consistent with the size of the signature or we risk to access out of
100  // bound elements.
101  if (lenR > 1 && (sig[4] == 0x00) && !(sig[5] & 0x80)) {
102  return false;
103  }
104 
105  //
106  // Check that S is an positive integer of sensible size.
107  //
108 
109  // S's definition starts after R's definition:
110  // * 1 byte for the coumpound type.
111  // * 1 byte for the length of the signature.
112  // * 1 byte for the size of R.
113  // * lenR bytes for R itself.
114  // * 1 byte to get to S.
115  const uint32_t startS = lenR + 4;
116 
117  // Check whether the S element is an integer.
118  if (sig[startS] != 0x02) {
119  return false;
120  }
121 
122  // Extract the length of the S element.
123  const uint32_t lenS = sig[startS + 1];
124 
125  // Zero-length integers are not allowed for S.
126  if (lenS == 0) {
127  return false;
128  }
129 
130  // Negative numbers are not allowed for S.
131  if (sig[startS + 2] & 0x80) {
132  return false;
133  }
134 
135  // Verify that the length of S is consistent with the size of the signature
136  // including metadatas:
137  // * 1 byte for the integer type of S.
138  // * 1 byte for the size of S.
139  if (size_t(startS + lenS + 2) != sig.size()) {
140  return false;
141  }
142 
143  // Null bytes at the start of S are not allowed, unless S would otherwise be
144  // interpreted as a negative number.
145  //
146  // /!\ This check can only be performed after we checked that lenR and lenS
147  // are consistent with the size of the signature or we risk to access
148  // out of bound elements.
149  if (lenS > 1 && (sig[startS + 2] == 0x00) && !(sig[startS + 3] & 0x80)) {
150  return false;
151  }
152 
153  return true;
154 }
155 
156 static bool IsSchnorrSig(const slicedvaltype &sig) {
157  return sig.size() == 64;
158 }
159 
161  uint32_t flags,
162  ScriptError *serror) {
163  if (IsSchnorrSig(sig)) {
164  // In an ECDSA-only context, 64-byte signatures are forbidden.
165  return set_error(serror, ScriptError::SIG_BADLENGTH);
166  }
167  // https://bitcoin.stackexchange.com/a/12556:
171  return set_error(serror, ScriptError::SIG_DER);
172  }
173  // If the S value is above the order of the curve divided by two, its
174  // complement modulo the order could have been used instead, which is
175  // one byte shorter when encoded correctly.
177  return set_error(serror, ScriptError::SIG_HIGH_S);
178  }
179 
180  return true;
181 }
182 
184  uint32_t flags,
185  ScriptError *serror) {
186  if (IsSchnorrSig(sig)) {
187  return true;
188  }
189  return set_error(serror, ScriptError::SIG_NONSCHNORR);
190 }
191 
192 static bool CheckRawSignatureEncoding(const slicedvaltype &sig, uint32_t flags,
193  ScriptError *serror) {
194  if (IsSchnorrSig(sig)) {
195  // In a generic-signature context, 64-byte signatures are interpreted
196  // as Schnorr signatures (always correctly encoded).
197  return true;
198  }
199  return CheckRawECDSASignatureEncoding(sig, flags, serror);
200 }
201 
202 bool CheckDataSignatureEncoding(const valtype &vchSig, uint32_t flags,
203  ScriptError *serror) {
204  // Empty signature. Not strictly DER encoded, but allowed to provide a
205  // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
206  if (vchSig.size() == 0) {
207  return true;
208  }
209 
211  vchSig | boost::adaptors::sliced(0, vchSig.size()), flags, serror);
212 }
213 
214 static bool CheckSighashEncoding(const valtype &vchSig, uint32_t flags,
215  ScriptError *serror) {
217  if (!GetHashType(vchSig).isDefined()) {
218  return set_error(serror, ScriptError::SIG_HASHTYPE);
219  }
220 
221  bool usesForkId = GetHashType(vchSig).hasForkId();
222  bool forkIdEnabled = flags & SCRIPT_ENABLE_SIGHASH_FORKID;
223  if (!forkIdEnabled && usesForkId) {
224  return set_error(serror, ScriptError::ILLEGAL_FORKID);
225  }
226 
227  if (forkIdEnabled && !usesForkId) {
228  return set_error(serror, ScriptError::MUST_USE_FORKID);
229  }
230  }
231 
232  return true;
233 }
234 
235 template <typename F>
237  uint32_t flags,
238  ScriptError *serror, F fun) {
239  // Empty signature. Not strictly DER encoded, but allowed to provide a
240  // compact way to provide an invalid signature for use with CHECK(MULTI)SIG
241  if (vchSig.size() == 0) {
242  return true;
243  }
244 
245  if (!fun(vchSig | boost::adaptors::sliced(0, vchSig.size() - 1), flags,
246  serror)) {
247  // serror is set
248  return false;
249  }
250 
251  return CheckSighashEncoding(vchSig, flags, serror);
252 }
253 
254 bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags,
255  ScriptError *serror) {
257  vchSig, flags, serror,
258  [](const slicedvaltype &templateSig, uint32_t templateFlags,
259  ScriptError *templateSerror) {
260  return CheckRawSignatureEncoding(templateSig, templateFlags,
261  templateSerror);
262  });
263 }
264 
266  uint32_t flags,
267  ScriptError *serror) {
269  vchSig, flags, serror,
270  [](const slicedvaltype &templateSig, uint32_t templateFlags,
271  ScriptError *templateSerror) {
272  return CheckRawECDSASignatureEncoding(templateSig, templateFlags,
273  templateSerror);
274  });
275 }
276 
278  uint32_t flags,
279  ScriptError *serror) {
281  vchSig, flags, serror,
282  [](const slicedvaltype &templateSig, uint32_t templateFlags,
283  ScriptError *templateSerror) {
284  return CheckRawSchnorrSignatureEncoding(templateSig, templateFlags,
285  templateSerror);
286  });
287 }
288 
289 static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey) {
290  switch (vchPubKey.size()) {
292  // Compressed public key: must start with 0x02 or 0x03.
293  return vchPubKey[0] == 0x02 || vchPubKey[0] == 0x03;
294 
295  case CPubKey::SIZE:
296  // Non-compressed public key: must start with 0x04.
297  return vchPubKey[0] == 0x04;
298 
299  default:
300  // Non-canonical public key: invalid size.
301  return false;
302  }
303 }
304 
305 bool CheckPubKeyEncoding(const valtype &vchPubKey, uint32_t flags,
306  ScriptError *serror) {
307  if ((flags & SCRIPT_VERIFY_STRICTENC) &&
308  !IsCompressedOrUncompressedPubKey(vchPubKey)) {
309  return set_error(serror, ScriptError::PUBKEYTYPE);
310  }
311  return true;
312 }
ScriptError
ScriptError
Definition: script_error.h:11
CheckPubKeyEncoding
bool CheckPubKeyEncoding(const valtype &vchPubKey, uint32_t flags, ScriptError *serror)
Check that a public key is encoded properly.
Definition: sigencoding.cpp:305
ScriptError::ILLEGAL_FORKID
@ ILLEGAL_FORKID
flags
int flags
Definition: bitcoin-tx.cpp:532
CheckRawECDSASignatureEncoding
static bool CheckRawECDSASignatureEncoding(const slicedvaltype &sig, uint32_t flags, ScriptError *serror)
Definition: sigencoding.cpp:160
IsSchnorrSig
static bool IsSchnorrSig(const slicedvaltype &sig)
Definition: sigencoding.cpp:156
ScriptError::SIG_NONSCHNORR
@ SIG_NONSCHNORR
slicedvaltype
boost::sliced_range< const valtype > slicedvaltype
Definition: sigencoding.cpp:14
CPubKey::SIZE
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:36
script_flags.h
IsValidDERSignatureEncoding
static bool IsValidDERSignatureEncoding(const slicedvaltype &sig)
A canonical signature exists of: <30> <total len> <02> <len R> <R> <02> <len S> , where R and S are n...
Definition: sigencoding.cpp:27
pubkey.h
sig
SchnorrSig sig
Definition: processor.cpp:322
CheckDataSignatureEncoding
bool CheckDataSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Check that the signature provided on some data is properly encoded.
Definition: sigencoding.cpp:202
IsCompressedOrUncompressedPubKey
static bool IsCompressedOrUncompressedPubKey(const valtype &vchPubKey)
Definition: sigencoding.cpp:289
CheckRawSchnorrSignatureEncoding
static bool CheckRawSchnorrSignatureEncoding(const slicedvaltype &sig, uint32_t flags, ScriptError *serror)
Definition: sigencoding.cpp:183
CheckTransactionECDSASignatureEncoding
bool CheckTransactionECDSASignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Check that the signature provided to authentify a transaction is properly encoded ECDSA signature.
Definition: sigencoding.cpp:265
ScriptError::PUBKEYTYPE
@ PUBKEYTYPE
CheckTransactionSignatureEncodingImpl
static bool CheckTransactionSignatureEncodingImpl(const valtype &vchSig, uint32_t flags, ScriptError *serror, F fun)
Definition: sigencoding.cpp:236
sigencoding.h
ScriptError::SIG_HASHTYPE
@ SIG_HASHTYPE
SCRIPT_VERIFY_LOW_S
@ SCRIPT_VERIFY_LOW_S
Definition: script_flags.h:31
ScriptError::SIG_HIGH_S
@ SIG_HIGH_S
CPubKey::CheckLowS
static bool CheckLowS(const boost::sliced_range< const std::vector< uint8_t >> &vchSig)
Check whether a DER-serialized ECDSA signature is normalized (lower-S).
Definition: pubkey.cpp:342
CPubKey::COMPRESSED_SIZE
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:37
CheckTransactionSignatureEncoding
bool CheckTransactionSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Check that the signature provided to authentify a transaction is properly encoded.
Definition: sigencoding.cpp:254
valtype
std::vector< uint8_t > valtype
Definition: sigencoding.h:16
CheckRawSignatureEncoding
static bool CheckRawSignatureEncoding(const slicedvaltype &sig, uint32_t flags, ScriptError *serror)
Definition: sigencoding.cpp:192
ScriptError::SIG_DER
@ SIG_DER
SCRIPT_ENABLE_SIGHASH_FORKID
@ SCRIPT_ENABLE_SIGHASH_FORKID
Definition: script_flags.h:85
ScriptError::SIG_BADLENGTH
@ SIG_BADLENGTH
SCRIPT_VERIFY_STRICTENC
@ SCRIPT_VERIFY_STRICTENC
Definition: script_flags.h:22
CheckSighashEncoding
static bool CheckSighashEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Definition: sigencoding.cpp:214
SCRIPT_VERIFY_DERSIG
@ SCRIPT_VERIFY_DERSIG
Definition: script_flags.h:26
CheckTransactionSchnorrSignatureEncoding
bool CheckTransactionSchnorrSignatureEncoding(const valtype &vchSig, uint32_t flags, ScriptError *serror)
Check that the signature provided to authentify a transaction is properly encoded Schnorr signature (...
Definition: sigencoding.cpp:277
ScriptError::MUST_USE_FORKID
@ MUST_USE_FORKID