Title: Strict DER signatures Post by: amaclin on March 16, 2015, 11:03:27 AM Why IsValidSignatureEncoding (const std::vector<unsigned char> &sig) does not check R & S sizes?
My suggestion below in blue color bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) { // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [ S] [sighash] // * total-length: 1-byte length descriptor of everything that follows, // excluding the sighash byte. // * R-length: 1-byte length descriptor of the R value that follows. // * R: arbitrary-length big-endian encoded R value. It must use the shortest // possible encoding for a positive integers (which means no null bytes at // the start, except a single one when the next byte has its highest bit set). // * S-length: 1-byte length descriptor of the S value that follows. // * S: arbitrary-length big-endian encoded S value. The same rules apply. // * sighash: 1-byte value indicating what data is hashed (not part of the DER // signature) // Minimum and maximum size constraints. if (sig.size() < 9) return false; if (sig.size() > 73) return false; // A signature is of type 0x30 (compound). if (sig[0] != 0x30) return false; // Make sure the length covers the entire signature. if (sig[1] != sig.size() - 3) return false; // Extract the length of the R element. unsigned int lenR = sig[3]; // Make sure the length of the S element is still inside the signature. if (5 + lenR >= sig.size()) return false; // Extract the length of the S element. unsigned int lenS = sig[5 + lenR]; // Verify that the length of the signature matches the sum of the length // of the elements. if ((size_t)(lenR + lenS + 7) != sig.size()) return false; // Check whether the R element is an integer. if (sig[2] != 0x02) return false; // Zero-length integers are not allowed for R. if (lenR == 0) return false; // R can not be wider than 32 bytes if (lenR > 33 || (lenR==33 && sig[4] != 0x00)) return false; // Negative numbers are not allowed for R. if (sig[4] & 0x80) return false; // Null bytes at the start of R are not allowed, unless R would // otherwise be interpreted as a negative number. if ((sig[4] == 0x00) && lenR > 1 && !(sig[5] & 0x80)) return false; // Check whether the S element is an integer. if (sig[lenR + 4] != 0x02) return false; // Zero-length integers are not allowed for S. if (lenS == 0) return false; // S can not be wider than 32 bytes if (lenS > 33 || (lenS==33 && sig[lenR + 6] != 0x00)) return false; // Negative numbers are not allowed for S. if (sig[lenR + 6] & 0x80) return false; // Null bytes at the start of S are not allowed, unless S would otherwise be // interpreted as a negative number. if (lenS > 1 && (sig[lenR + 6] == 0x00) && !(sig[lenR + 7] & 0x80)) return false; return true; } Title: Re: Strict DER signatures Post by: ca333 on March 16, 2015, 11:22:42 AM // R can not be wider than 32 bytes if (lenR > 33 || (lenR==33 && sig[4] != 0x00)) return false; // S can not be wider than 32 bytes if (lenS > 33 || (lenS==33 && sig[lenR + 6] != 0x00)) return false; Signature values can be bigger than 32 bytes. For example also 33 bytes is possible when you see header length descriptor in many tx-scripts. see the inputscripts in this tx: (r sig has 33 bytes - you can also see this from header 0x21) https://blockchain.info/tx/f5d289e3b96248208ee21208cb9bba75114ebe0d3082e2afc692086d05a5a95f (https://blockchain.info/tx/f5d289e3b96248208ee21208cb9bba75114ebe0d3082e2afc692086d05a5a95f) Title: Re: Strict DER signatures Post by: amaclin on March 16, 2015, 02:47:27 PM Signature values can be bigger than 32 bytes. For example also 33 bytes is possible when you see header length descriptor in many tx-scripts. No. Value is always 256 bit (32 bytes). The encoding can be 33 bytes (with leading zero byte which is useless, because indicates unsigned integer, not a negative) Title: Re: Strict DER signatures Post by: gmaxwell on March 16, 2015, 04:31:53 PM This specific question was previously discussed on bitcoin-development in the thread there.
Title: Re: Strict DER signatures Post by: doug_armory on March 16, 2015, 04:49:23 PM This specific question was previously discussed on bitcoin-development in the thread there. In particular, this message (http://sourceforge.net/p/bitcoin/mailman/message/33266572/) from sipa explains everything. Title: Re: Strict DER signatures Post by: ca333 on March 16, 2015, 05:11:28 PM Signature values can be bigger than 32 bytes. For example also 33 bytes is possible when you see header length descriptor in many tx-scripts. No. Value is always 256 bit (32 bytes). The encoding can be 33 bytes (with leading zero byte which is useless, because indicates unsigned integer, not a negative) thanks for clarification. will mark this: 33 bytes with leading zero byte. i always thought the 0-prepad is also part of the sig, because the header lenght descriptor tells me how many bytes are used for the sig-value. and in the above example i see 0x21 (33 byte) for lenght descriptor which i have thought means the lenght of the r-sig is 33 bytes. This specific question was previously discussed on bitcoin-development in the thread there. In particular, this message (http://sourceforge.net/p/bitcoin/mailman/message/33266572/) from sipa explains everything. thank you for posting this. makes it all clear. |