From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from sog-mx-2.v43.ch3.sourceforge.com ([172.29.43.192] helo=mx.sourceforge.net) by sfs-ml-1.v29.ch3.sourceforge.com with esmtp (Exim 4.76) (envelope-from <david.vorick@gmail.com>) id 1YE8CG-00012b-3b for bitcoin-development@lists.sourceforge.net; Thu, 22 Jan 2015 03:12:40 +0000 Received-SPF: pass (sog-mx-2.v43.ch3.sourceforge.com: domain of gmail.com designates 209.85.212.169 as permitted sender) client-ip=209.85.212.169; envelope-from=david.vorick@gmail.com; helo=mail-wi0-f169.google.com; Received: from mail-wi0-f169.google.com ([209.85.212.169]) by sog-mx-2.v43.ch3.sourceforge.com with esmtps (TLSv1:RC4-SHA:128) (Exim 4.76) id 1YE8CD-0003Ua-5L for bitcoin-development@lists.sourceforge.net; Thu, 22 Jan 2015 03:12:40 +0000 Received: by mail-wi0-f169.google.com with SMTP id bs8so37581119wib.0 for <bitcoin-development@lists.sourceforge.net>; Wed, 21 Jan 2015 19:12:31 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.180.8.169 with SMTP id s9mr694361wia.72.1421896351174; Wed, 21 Jan 2015 19:12:31 -0800 (PST) Received: by 10.27.10.12 with HTTP; Wed, 21 Jan 2015 19:12:31 -0800 (PST) In-Reply-To: <87egqnwt7g.fsf@rustcorp.com.au> References: <CAPg+sBhk7F2OHT64i2LNSjv8DR5tD3RJkLJGzPGZW8OPQTCjQw@mail.gmail.com> <87egqnwt7g.fsf@rustcorp.com.au> Date: Wed, 21 Jan 2015 22:12:31 -0500 Message-ID: <CAFVRnyqhU1aLvj_WxFPY2Vu2mEwhm7jiuKrdbnwJWqvCqPVxGQ@mail.gmail.com> From: David Vorick <david.vorick@gmail.com> Cc: Bitcoin Dev <bitcoin-development@lists.sourceforge.net> Content-Type: multipart/alternative; boundary=f46d04430682eb53f0050d350a13 X-Spam-Score: 2.9 (++) X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -1.5 SPF_CHECK_PASS SPF reports sender host as permitted sender for sender-domain 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (david.vorick[at]gmail.com) -0.0 SPF_PASS SPF: sender matches SPF record 1.2 MISSING_HEADERS Missing To: header 1.0 HTML_MESSAGE BODY: HTML included in message -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 2.2 MALFORMED_FREEMAIL Bad headers on message from free email service X-Headers-End: 1YE8CD-0003Ua-5L Subject: Re: [Bitcoin-development] [softfork proposal] Strict DER signatures X-BeenThere: bitcoin-development@lists.sourceforge.net X-Mailman-Version: 2.1.9 Precedence: list List-Id: <bitcoin-development.lists.sourceforge.net> List-Unsubscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>, <mailto:bitcoin-development-request@lists.sourceforge.net?subject=unsubscribe> List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=bitcoin-development> List-Post: <mailto:bitcoin-development@lists.sourceforge.net> List-Help: <mailto:bitcoin-development-request@lists.sourceforge.net?subject=help> List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/bitcoin-development>, <mailto:bitcoin-development-request@lists.sourceforge.net?subject=subscribe> X-List-Received-Date: Thu, 22 Jan 2015 03:12:40 -0000 --f46d04430682eb53f0050d350a13 Content-Type: text/plain; charset=UTF-8 Seems like a good change to me. On Wed, Jan 21, 2015 at 7:32 PM, Rusty Russell <rusty@rustcorp.com.au> wrote: > Pieter Wuille <pieter.wuille@gmail.com> writes: > > Hello everyone, > > > > We've been aware of the risk of depending on OpenSSL for consensus > > rules for a while, and were trying to get rid of this as part of BIP > > 62 (malleability protection), which was however postponed due to > > unforeseen complexities. The recent evens (see the thread titled > > "OpenSSL 1.0.0p / 1.0.1k incompatible, causes blockchain rejection." > > on this mailing list) have made it clear that the problem is very > > real, however, and I would prefer to have a fundamental solution for > > it sooner rather than later. > > OK, I worked up a clearer (but more verbose) version with fewer > magic numbers. More importantly, feel free to steal the test cases. > > One weirdness is the restriction on maximum total length, rather than a > 32 byte (33 with 0-prepad) limit on signatures themselves. > > Apologies for my babytalk C++. Am sure there's a neater way. > > /* Licensed under Creative Commons zero (public domain). */ > #include <vector> > #include <cstdlib> > #include <cassert> > > #ifdef CLARIFY > bool ConsumeByte(const std::vector<unsigned char> &sig, size_t &off, > unsigned int &val) > { > if (off >= sig.size()) return false; > > val = sig[off++]; > return true; > } > > bool ConsumeTypeByte(const std::vector<unsigned char> &sig, size_t &off, > unsigned int t) > { > unsigned int type; > if (!ConsumeByte(sig, off, type)) return false; > > return (type == t); > } > > bool ConsumeNonZeroLength(const std::vector<unsigned char> &sig, size_t > &off, > unsigned int &len) > { > if (!ConsumeByte(sig, off, len)) return false; > > // Zero-length integers are not allowed. > return (len != 0); > } > > bool ConsumeNumber(const std::vector<unsigned char> &sig, size_t &off, > unsigned int len) > { > // Length of number should be within signature. > if (off + len > sig.size()) return false; > > // Negative numbers are not allowed. > if (sig[off] & 0x80) return false; > > // Zero bytes at the start are not allowed, unless it would > // otherwise be interpreted as a negative number. > if (len > 1 && (sig[off] == 0x00) && !(sig[off+1] & 0x80)) return > false; > > // Consume number itself. > off += len; > return true; > } > > // Consume a DER encoded integer, update off if successful. > bool ConsumeDERInteger(const std::vector<unsigned char> &sig, size_t &off) > { > unsigned int len; > > // Type byte must be "integer" > if (!ConsumeTypeByte(sig, off, 0x02)) return false; > if (!ConsumeNonZeroLength(sig, off, len)) return false; > // Now the BE encoded value itself. > if (!ConsumeNumber(sig, off, len)) return false; > > return true; > } > > bool 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 cannot start > with any > // null bytes, unless the first byte that follows is 0x80 or > higher, in which > // case a single null byte is required. > // * 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. > > // Accept empty signature as correctly encoded (but invalid) signature, > // even though it is not strictly DER. > if (sig.size() == 0) return true; > > // Maximum size constraint. > if (sig.size() > 73) return false; > > size_t off = 0; > > // A signature is of type "compound". > if (!ConsumeTypeByte(sig, off, 0x30)) return false; > > unsigned int len; > if (!ConsumeNonZeroLength(sig, off, len)) return false; > > // Make sure the length covers the rest (except sighash). > if (len + 1 != sig.size() - off) return false; > > // Check R value. > if (!ConsumeDERInteger(sig, off)) return false; > > // Check S value. > if (!ConsumeDERInteger(sig, off)) return false; > > // There should exactly one byte left (the sighash). > return off + 1 == sig.size() ? true : false; > } > #else > bool 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) > > // Accept empty signature as correctly encoded (but invalid) signature, > // even though it is not strictly DER. This avoids needing full DER > signatures > // in places where any invalid signature would do. Given that the > empty string is > // always invalid as signature, this is safe. > if (sig.size() == 0) return true; > > // 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; > > // 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 (lenR > 1 && (sig[4] == 0x00) && !(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; > > // 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; > } > #endif > > #define COMPOUND 0x30 > #define NOT_COMPOUND 0x31 > > // Len gets adjusted by check() to be actual length with this offset. > #define LEN_OK 0 > #define LEN_TOO_BIG 1 > #define LEN_TOO_SMALL 0xff > > #define INT 0x02 > #define NOT_INT 0x03 > > #define MINIMAL_SIGLEN 1 > #define MINIMAL_SIGVAL 0x0 > > #define NORMAL_SIGLEN 32 > #define NORMAL_SIGVAL(S) S, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ > 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, \ > 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \ > 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f > > // 33 bytes is possible, with 0 prepended. > #define MAXIMAL_SIGLEN 33 > #define MAXIMAL_SIGVAL(S) NORMAL_SIGVAL(S), 0x20 > > #define OVERSIZE_SIGLEN 34 > #define OVERSIZE_SIGVAL(S) MAXIMAL_SIGVAL(S), 0x21 > > #define ZEROPAD_SIGLEN (1 + NORMAL_SIGLEN) > #define ZEROPAD_SIGVAL(S) 00, NORMAL_SIGVAL(S) > > #define SIGHASH 0xf0 > > static bool check(const std::vector<unsigned char> &sig) > { > std::vector<unsigned char> fixed = sig; > > // Fixup length > if (fixed.size() > 1) > fixed[1] += fixed.size() - 3; > return IsValidSignatureEncoding(fixed); > } > > #define good(arr) assert(check(std::vector<unsigned char>(arr, > arr+sizeof(arr)))) > #define bad(arr) assert(!check(std::vector<unsigned char>(arr, > arr+sizeof(arr)))) > > // The OK cases. > static unsigned char zerolen[] = { }; > static unsigned char normal[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char min_r[] = { COMPOUND, LEN_OK, > INT, MINIMAL_SIGLEN, MINIMAL_SIGVAL, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char min_s[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1), > INT, MINIMAL_SIGLEN, MINIMAL_SIGVAL, > SIGHASH }; > static unsigned char max_r[] = { COMPOUND, LEN_OK, > INT, MAXIMAL_SIGLEN, MAXIMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char max_s[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1), > INT, MAXIMAL_SIGLEN, MAXIMAL_SIGVAL(0x2), > SIGHASH }; > // As long as total size doesn't go over, a single sig is allowed > 33 > bytes > static unsigned char wierd_s_len[] = { COMPOUND, LEN_OK, > INT, OVERSIZE_SIGLEN, > OVERSIZE_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char wierd_r_len[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, OVERSIZE_SIGLEN, > OVERSIZE_SIGVAL(0x2), > SIGHASH }; > static unsigned char zeropad_s[] = { COMPOUND, LEN_OK, > INT, ZEROPAD_SIGLEN, > ZEROPAD_SIGVAL(0x81), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char zeropad_r[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, ZEROPAD_SIGLEN, > ZEROPAD_SIGVAL(0x82), > SIGHASH }; > > > // The fail cases. > static unsigned char not_compound[] = { NOT_COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char short_len[] = { COMPOUND, LEN_TOO_SMALL, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char long_len[] = { COMPOUND, LEN_TOO_BIG, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char r_notint[] = { COMPOUND, LEN_OK, > NOT_INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char s_notint[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1), > NOT_INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char s_oversig[] = { COMPOUND, LEN_OK, > INT, OVERSIZE_SIGLEN, > OVERSIZE_SIGVAL(0x1), > INT, MAXIMAL_SIGLEN, > MAXIMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char r_oversig[] = { COMPOUND, LEN_OK, > INT, MAXIMAL_SIGLEN, > MAXIMAL_SIGVAL(0x1), > INT, OVERSIZE_SIGLEN, > OVERSIZE_SIGVAL(0x2), > SIGHASH }; > static unsigned char s_negative[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x81), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char r_negative[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x82), > SIGHASH }; > static unsigned char zeropad_bad_s[] = { COMPOUND, LEN_OK, > INT, ZEROPAD_SIGLEN, > ZEROPAD_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char zeropad_bad_r[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, ZEROPAD_SIGLEN, > ZEROPAD_SIGVAL(0x2), > SIGHASH }; > static unsigned char missing_sighash[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2) }; > static unsigned char extra_byte[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH, 0 }; > > // Bad signature lengths > static unsigned char zerolen_r[] = { COMPOUND, LEN_OK, > INT, 0, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char zerolen_s[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, 0, > SIGHASH }; > static unsigned char overlen_r_by_1[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN + 1 + 1 + > NORMAL_SIGLEN + 1 + 1, NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char overlen_s_by_1[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN+1+1, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char underlen_r_by_1[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN-1, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x2), > SIGHASH }; > static unsigned char underlen_s_by_1[] = { COMPOUND, LEN_OK, > INT, NORMAL_SIGLEN, > NORMAL_SIGVAL(0x1), > INT, NORMAL_SIGLEN-1, > NORMAL_SIGVAL(0x2), > SIGHASH }; > > int main() > { > good(zerolen); > good(normal); > good(min_r); > good(min_s); > good(max_r); > good(max_s); > good(wierd_s_len); > good(wierd_r_len); > good(zeropad_s); > good(zeropad_r); > > // Try different amounts of truncation. > for (size_t i = 1; i < sizeof(normal)-1; i++) > assert(!check(std::vector<unsigned char>(normal, normal+i))); > > bad(not_compound); > bad(short_len); > bad(long_len); > bad(r_notint); > bad(s_notint); > bad(s_oversig); > bad(r_oversig); > bad(s_negative); > bad(r_negative); > bad(s_negative); > bad(r_negative); > bad(zeropad_bad_s); > bad(zeropad_bad_r); > bad(zerolen_r); > bad(zerolen_s); > bad(overlen_r_by_1); > bad(overlen_s_by_1); > bad(underlen_r_by_1); > bad(underlen_s_by_1); > bad(missing_sighash); > bad(extra_byte); > > return 0; > } > > > > > ------------------------------------------------------------------------------ > New Year. New Location. New Benefits. New Data Center in Ashburn, VA. > GigeNET is offering a free month of service with a new server in Ashburn. > Choose from 2 high performing configs, both with 100TB of bandwidth. > Higher redundancy.Lower latency.Increased capacity.Completely compliant. > http://p.sf.net/sfu/gigenet > _______________________________________________ > Bitcoin-development mailing list > Bitcoin-development@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/bitcoin-development > --f46d04430682eb53f0050d350a13 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Seems like a good change to me.<br></div><div class=3D"gma= il_extra"><br><div class=3D"gmail_quote">On Wed, Jan 21, 2015 at 7:32 PM, R= usty Russell <span dir=3D"ltr"><<a href=3D"mailto:rusty@rustcorp.com.au"= target=3D"_blank">rusty@rustcorp.com.au</a>></span> wrote:<br><blockquo= te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so= lid;padding-left:1ex"><span class=3D"">Pieter Wuille <<a href=3D"mailto:= pieter.wuille@gmail.com">pieter.wuille@gmail.com</a>> writes:<br> > Hello everyone,<br> ><br> > We've been aware of the risk of depending on OpenSSL for consensus= <br> > rules for a while, and were trying to get rid of this as part of BIP<b= r> > 62 (malleability protection), which was however postponed due to<br> > unforeseen complexities. The recent evens (see the thread titled<br> > "OpenSSL 1.0.0p / 1.0.1k incompatible, causes blockchain rejectio= n."<br> > on this mailing list) have made it clear that the problem is very<br> > real, however, and I would prefer to have a fundamental solution for<b= r> > it sooner rather than later.<br> <br> </span>OK, I worked up a clearer (but more verbose) version with fewer<br> magic numbers.=C2=A0 More importantly, feel free to steal the test cases.<b= r> <br> One weirdness is the restriction on maximum total length, rather than a<br> 32 byte (33 with 0-prepad) limit on signatures themselves.<br> <br> Apologies for my babytalk C++.=C2=A0 Am sure there's a neater way.<br> <br> /* Licensed under Creative Commons zero (public domain). */<br> #include <vector><br> #include <cstdlib><br> #include <cassert><br> <br> #ifdef CLARIFY<br> bool ConsumeByte(const std::vector<unsigned char> &sig, size_t &a= mp;off,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int = &val)<br> {<br> =C2=A0 =C2=A0 if (off >=3D sig.size()) return false;<br> <br> =C2=A0 =C2=A0 val =3D sig[off++];<br> =C2=A0 =C2=A0 return true;<br> }<br> <br> bool ConsumeTypeByte(const std::vector<unsigned char> &sig, size_= t &off,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0unsigned int t)<br> {<br> =C2=A0 =C2=A0 unsigned int type;<br> =C2=A0 =C2=A0 if (!ConsumeByte(sig, off, type)) return false;<br> <br> =C2=A0 =C2=A0 return (type =3D=3D t);<br> }<br> <br> bool ConsumeNonZeroLength(const std::vector<unsigned char> &sig, = size_t &off,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 unsigned int &len)<br> {<br> =C2=A0 =C2=A0 if (!ConsumeByte(sig, off, len)) return false;<br> <br> =C2=A0 =C2=A0 // Zero-length integers are not allowed.<br> =C2=A0 =C2=A0 return (len !=3D 0);<br> }<br> <br> bool ConsumeNumber(const std::vector<unsigned char> &sig, size_t = &off,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0unsign= ed int len)<br> {<br> =C2=A0 =C2=A0 // Length of number should be within signature.<br> =C2=A0 =C2=A0 if (off + len > sig.size()) return false;<br> <br> =C2=A0 =C2=A0 // Negative numbers are not allowed.<br> =C2=A0 =C2=A0 if (sig[off] & 0x80) return false;<br> <br> =C2=A0 =C2=A0 // Zero bytes at the start are not allowed, unless it would<b= r> =C2=A0 =C2=A0 // otherwise be interpreted as a negative number.<br> =C2=A0 =C2=A0 if (len > 1 && (sig[off] =3D=3D 0x00) && != (sig[off+1] & 0x80)) return false;<br> <br> =C2=A0 =C2=A0 // Consume number itself.<br> =C2=A0 =C2=A0 off +=3D len;<br> =C2=A0 =C2=A0 return true;<br> }<br> <br> // Consume a DER encoded integer, update off if successful.<br> bool ConsumeDERInteger(const std::vector<unsigned char> &sig, siz= e_t &off) {<br> =C2=A0 =C2=A0 unsigned int len;<br> <br> =C2=A0 =C2=A0 // Type byte must be "integer"<br> =C2=A0 =C2=A0 if (!ConsumeTypeByte(sig, off, 0x02)) return false;<br> =C2=A0 =C2=A0 if (!ConsumeNonZeroLength(sig, off, len)) return false;<br> =C2=A0 =C2=A0 // Now the BE encoded value itself.<br> =C2=A0 =C2=A0 if (!ConsumeNumber(sig, off, len)) return false;<br> <br> =C2=A0 =C2=A0 return true;<br> }<br> <br> bool IsValidSignatureEncoding(const std::vector<unsigned char> &s= ig) {<br> =C2=A0 =C2=A0 // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-le= ngth] [S] [sighash]<br> =C2=A0 =C2=A0 // * total-length: 1-byte length descriptor of everything tha= t follows,<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0excluding the sighash byte.<br> =C2=A0 =C2=A0 // * R-length: 1-byte length descriptor of the R value that f= ollows.<br> =C2=A0 =C2=A0 // * R: arbitrary-length big-endian encoded R value. It canno= t start with any<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0null bytes, unless the first byte that = follows is 0x80 or higher, in which<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0case a single null byte is required.<br= > =C2=A0 =C2=A0 // * S-length: 1-byte length descriptor of the S value that f= ollows.<br> =C2=A0 =C2=A0 // * S: arbitrary-length big-endian encoded S value. The same= rules apply.<br> =C2=A0 =C2=A0 // * sighash: 1-byte value indicating what data is hashed.<br= > <br> =C2=A0 =C2=A0 // Accept empty signature as correctly encoded (but invalid) = signature,<br> =C2=A0 =C2=A0 // even though it is not strictly DER.<br> =C2=A0 =C2=A0 if (sig.size() =3D=3D 0) return true;<br> <br> =C2=A0 =C2=A0 // Maximum size constraint.<br> =C2=A0 =C2=A0 if (sig.size() > 73) return false;<br> <br> =C2=A0 =C2=A0 size_t off =3D 0;<br> <br> =C2=A0 =C2=A0 // A signature is of type "compound".<br> =C2=A0 =C2=A0 if (!ConsumeTypeByte(sig, off, 0x30)) return false;<br> <br> =C2=A0 =C2=A0 unsigned int len;<br> =C2=A0 =C2=A0 if (!ConsumeNonZeroLength(sig, off, len)) return false;<br> <br> =C2=A0 =C2=A0 // Make sure the length covers the rest (except sighash).<br> =C2=A0 =C2=A0 if (len + 1 !=3D sig.size() - off) return false;<br> <br> =C2=A0 =C2=A0 // Check R value.<br> =C2=A0 =C2=A0 if (!ConsumeDERInteger(sig, off)) return false;<br> <br> =C2=A0 =C2=A0 // Check S value.<br> =C2=A0 =C2=A0 if (!ConsumeDERInteger(sig, off)) return false;<br> <br> =C2=A0 =C2=A0 // There should exactly one byte left (the sighash).<br> =C2=A0 =C2=A0 return off + 1 =3D=3D sig.size() ? true : false;<br> }<br> #else<br> bool IsValidSignatureEncoding(const std::vector<unsigned char> &s= ig) {<br> =C2=A0 =C2=A0 // Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-le= ngth] [S] [sighash]<br> =C2=A0 =C2=A0 // * total-length: 1-byte length descriptor of everything tha= t follows,<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0excluding the sighash byte.<br> =C2=A0 =C2=A0 // * R-length: 1-byte length descriptor of the R value that f= ollows.<br> =C2=A0 =C2=A0 // * R: arbitrary-length big-endian encoded R value. It must = use the shortest<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0possible encoding for a positive intege= rs (which means no null bytes at<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0the start, except a single one when the= next byte has its highest bit set).<br> =C2=A0 =C2=A0 // * S-length: 1-byte length descriptor of the S value that f= ollows.<br> =C2=A0 =C2=A0 // * S: arbitrary-length big-endian encoded S value. The same= rules apply.<br> =C2=A0 =C2=A0 // * sighash: 1-byte value indicating what data is hashed (no= t part of the DER<br> =C2=A0 =C2=A0 //=C2=A0 =C2=A0 =C2=A0signature)<br> <br> =C2=A0 =C2=A0 // Accept empty signature as correctly encoded (but invalid) = signature,<br> =C2=A0 =C2=A0 // even though it is not strictly DER. This avoids needing fu= ll DER signatures<br> =C2=A0 =C2=A0 // in places where any invalid signature would do. Given that= the empty string is<br> =C2=A0 =C2=A0 // always invalid as signature, this is safe.<br> =C2=A0 =C2=A0 if (sig.size() =3D=3D 0) return true;<br> <br> =C2=A0 =C2=A0 // Minimum and maximum size constraints.<br> =C2=A0 =C2=A0 if (sig.size() < 9) return false;<br> =C2=A0 =C2=A0 if (sig.size() > 73) return false;<br> <br> =C2=A0 =C2=A0 // A signature is of type 0x30 (compound).<br> =C2=A0 =C2=A0 if (sig[0] !=3D 0x30) return false;<br> <br> =C2=A0 =C2=A0 // Make sure the length covers the entire signature.<br> =C2=A0 =C2=A0 if (sig[1] !=3D sig.size() - 3) return false;<br> <br> =C2=A0 =C2=A0 // Extract the length of the R element.<br> =C2=A0 =C2=A0 unsigned int lenR =3D sig[3];<br> <br> =C2=A0 =C2=A0 // Make sure the length of the S element is still inside the = signature.<br> =C2=A0 =C2=A0 if (5 + lenR >=3D sig.size()) return false;<br> <br> =C2=A0 =C2=A0 // Extract the length of the S element.<br> =C2=A0 =C2=A0 unsigned int lenS =3D sig[5 + lenR];<br> <br> =C2=A0 =C2=A0 // Verify that the length of the signature matches the sum of= the length<br> =C2=A0 =C2=A0 // of the elements.<br> =C2=A0 =C2=A0 if ((size_t)(lenR + lenS + 7) !=3D sig.size()) return false;<= br> <br> =C2=A0 =C2=A0 // Check whether the R element is an integer.<br> =C2=A0 =C2=A0 if (sig[2] !=3D 0x02) return false;<br> <br> =C2=A0 =C2=A0 // Zero-length integers are not allowed for R.<br> =C2=A0 =C2=A0 if (lenR =3D=3D 0) return false;<br> <br> =C2=A0 =C2=A0 // Negative numbers are not allowed for R.<br> =C2=A0 =C2=A0 if (sig[4] & 0x80) return false;<br> <br> =C2=A0 =C2=A0 // Null bytes at the start of R are not allowed, unless R wou= ld<br> =C2=A0 =C2=A0 // otherwise be interpreted as a negative number.<br> =C2=A0 =C2=A0 if (lenR > 1 && (sig[4] =3D=3D 0x00) && !(= sig[5] & 0x80)) return false;<br> <br> =C2=A0 =C2=A0 // Check whether the S element is an integer.<br> =C2=A0 =C2=A0 if (sig[lenR + 4] !=3D 0x02) return false;<br> <br> =C2=A0 =C2=A0 // Zero-length integers are not allowed for S.<br> =C2=A0 =C2=A0 if (lenS =3D=3D 0) return false;<br> <br> =C2=A0 =C2=A0 // Negative numbers are not allowed for S.<br> =C2=A0 =C2=A0 if (sig[lenR + 6] & 0x80) return false;<br> <br> =C2=A0 =C2=A0 // Null bytes at the start of S are not allowed, unless S wou= ld otherwise be<br> <span class=3D"">=C2=A0 =C2=A0 // interpreted as a negative number.<br> =C2=A0 =C2=A0 if (lenS > 1 && (sig[lenR + 6] =3D=3D 0x00) &&= amp; !(sig[lenR + 7] & 0x80)) return false;<br> <br> </span>=C2=A0 =C2=A0 return true;<br> }<br> #endif<br> <br> #define COMPOUND 0x30<br> #define NOT_COMPOUND 0x31<br> <br> // Len gets adjusted by check() to be actual length with this offset.<br> #define LEN_OK 0<br> #define LEN_TOO_BIG 1<br> #define LEN_TOO_SMALL 0xff<br> <br> #define INT 0x02<br> #define NOT_INT 0x03<br> <br> #define MINIMAL_SIGLEN 1<br> #define MINIMAL_SIGVAL 0x0<br> <br> #define NORMAL_SIGLEN 32<br> #define NORMAL_SIGVAL(S) S, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 \<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f<= br> <br> // 33 bytes is possible, with 0 prepended.<br> #define MAXIMAL_SIGLEN 33<br> #define MAXIMAL_SIGVAL(S) NORMAL_SIGVAL(S), 0x20<br> <br> #define OVERSIZE_SIGLEN 34<br> #define OVERSIZE_SIGVAL(S) MAXIMAL_SIGVAL(S), 0x21<br> <br> #define ZEROPAD_SIGLEN (1 + NORMAL_SIGLEN)<br> #define ZEROPAD_SIGVAL(S) 00, NORMAL_SIGVAL(S)<br> <br> #define SIGHASH 0xf0<br> <br> static bool check(const std::vector<unsigned char> &sig)<br> {<br> =C2=A0 =C2=A0 std::vector<unsigned char> fixed =3D sig;<br> <br> =C2=A0 =C2=A0 // Fixup length<br> =C2=A0 =C2=A0 if (fixed.size() > 1)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 fixed[1] +=3D fixed.size() - 3;<br> =C2=A0 =C2=A0 return IsValidSignatureEncoding(fixed);<br> }<br> <br> #define good(arr) assert(check(std::vector<unsigned char>(arr, arr+si= zeof(arr))))<br> #define bad(arr) assert(!check(std::vector<unsigned char>(arr, arr+si= zeof(arr))))<br> <br> // The OK cases.<br> static unsigned char zerolen[] =3D { };<br> static unsigned char normal[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NORMAL_SI= GVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NORMAL_SI= GVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char min_r[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MINIMAL_SIGLEN, MINIMAL_S= IGVAL,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIG= VAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char min_s[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIG= VAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MINIMAL_SIGLEN, MINIMAL_S= IGVAL,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char max_r[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MAXIMAL_SIGLEN, MAXIMAL_S= IGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIG= VAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char max_s[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIG= VAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MAXIMAL_SIGLEN, MAXIMAL_S= IGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> // As long as total size doesn't go over, a single sig is allowed > = 33 bytes<br> static unsigned char wierd_s_len[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, OVER= SIZE_SIGLEN, OVERSIZE_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORM= AL_SIGLEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH }= ;<br> static unsigned char wierd_r_len[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORM= AL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, OVER= SIZE_SIGLEN, OVERSIZE_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH }= ;<br> static unsigned char zeropad_s[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, ZEROPAD_SIG= LEN, ZEROPAD_SIGVAL(0x81),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char zeropad_r[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, ZEROPAD_SIG= LEN, ZEROPAD_SIGVAL(0x82),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> <br> <br> // The fail cases.<br> static unsigned char not_compound[] =3D { NOT_COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NOR= MAL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NOR= MAL_SIGLEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH = };<br> static unsigned char short_len[] =3D { COMPOUND, LEN_TOO_SMALL,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char long_len[] =3D { COMPOUND, LEN_TOO_BIG,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NO= RMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NO= RMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char r_notint[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NOT_INT, NORMAL_SIGLEN= , NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NO= RMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char s_notint[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIGLEN, NO= RMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 NOT_INT, NORMAL_SIGLEN= , NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char s_oversig[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, OVERSIZE_SI= GLEN, OVERSIZE_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MAXIMAL_SIG= LEN, MAXIMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char r_oversig[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, MAXIMAL_SIG= LEN, MAXIMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, OVERSIZE_SI= GLEN, OVERSIZE_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char s_negative[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x81),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char r_negative[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x82),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH };<br> static unsigned char zeropad_bad_s[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IN= T, ZEROPAD_SIGLEN, ZEROPAD_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IN= T, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SI= GHASH };<br> static unsigned char zeropad_bad_r[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IN= T, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0IN= T, ZEROPAD_SIGLEN, ZEROPAD_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SI= GHASH };<br> static unsigned char missing_sighash[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2) };<br> static unsigned char extra_byte[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 INT, NORMAL_SIG= LEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SIGHASH, 0 };<b= r> <br> // Bad signature lengths<br> static unsigned char zerolen_r[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, 0,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char zerolen_s[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, NORMAL_SIGL= EN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INT, 0,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0SIGHASH };<br> static unsigned char overlen_r_by_1[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I= NT, NORMAL_SIGLEN + 1 + 1 + NORMAL_SIGLEN + 1 + 1, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I= NT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 S= IGHASH };<br> static unsigned char overlen_s_by_1[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I= NT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 I= NT, NORMAL_SIGLEN+1+1, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 S= IGHASH };<br> static unsigned char underlen_r_by_1[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN-1, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0SIGHASH };<br> static unsigned char underlen_s_by_1[] =3D { COMPOUND, LEN_OK,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN, NORMAL_SIGVAL(0x1),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0INT, NORMAL_SIGLEN-1, NORMAL_SIGVAL(0x2),<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0SIGHASH };<br> <br> int main()<br> {<br> =C2=A0 =C2=A0 good(zerolen);<br> =C2=A0 =C2=A0 good(normal);<br> =C2=A0 =C2=A0 good(min_r);<br> =C2=A0 =C2=A0 good(min_s);<br> =C2=A0 =C2=A0 good(max_r);<br> =C2=A0 =C2=A0 good(max_s);<br> =C2=A0 =C2=A0 good(wierd_s_len);<br> =C2=A0 =C2=A0 good(wierd_r_len);<br> =C2=A0 =C2=A0 good(zeropad_s);<br> =C2=A0 =C2=A0 good(zeropad_r);<br> <br> =C2=A0 =C2=A0 // Try different amounts of truncation.<br> =C2=A0 =C2=A0 for (size_t i =3D 1; i < sizeof(normal)-1; i++)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 assert(!check(std::vector<unsigned char>(= normal, normal+i)));<br> <br> =C2=A0 =C2=A0 bad(not_compound);<br> =C2=A0 =C2=A0 bad(short_len);<br> =C2=A0 =C2=A0 bad(long_len);<br> =C2=A0 =C2=A0 bad(r_notint);<br> =C2=A0 =C2=A0 bad(s_notint);<br> =C2=A0 =C2=A0 bad(s_oversig);<br> =C2=A0 =C2=A0 bad(r_oversig);<br> =C2=A0 =C2=A0 bad(s_negative);<br> =C2=A0 =C2=A0 bad(r_negative);<br> =C2=A0 =C2=A0 bad(s_negative);<br> =C2=A0 =C2=A0 bad(r_negative);<br> =C2=A0 =C2=A0 bad(zeropad_bad_s);<br> =C2=A0 =C2=A0 bad(zeropad_bad_r);<br> =C2=A0 =C2=A0 bad(zerolen_r);<br> =C2=A0 =C2=A0 bad(zerolen_s);<br> =C2=A0 =C2=A0 bad(overlen_r_by_1);<br> =C2=A0 =C2=A0 bad(overlen_s_by_1);<br> =C2=A0 =C2=A0 bad(underlen_r_by_1);<br> =C2=A0 =C2=A0 bad(underlen_s_by_1);<br> =C2=A0 =C2=A0 bad(missing_sighash);<br> =C2=A0 =C2=A0 bad(extra_byte);<br> <br> =C2=A0 =C2=A0 return 0;<br> <div class=3D"HOEnZb"><div class=3D"h5">}<br> <br> <br> <br> ---------------------------------------------------------------------------= ---<br> New Year. New Location. New Benefits. New Data Center in Ashburn, VA.<br> GigeNET is offering a free month of service with a new server in Ashburn.<b= r> Choose from 2 high performing configs, both with 100TB of bandwidth.<br> Higher redundancy.Lower latency.Increased capacity.Completely compliant.<br= > <a href=3D"http://p.sf.net/sfu/gigenet" target=3D"_blank">http://p.sf.net/s= fu/gigenet</a><br> _______________________________________________<br> Bitcoin-development mailing list<br> <a href=3D"mailto:Bitcoin-development@lists.sourceforge.net">Bitcoin-develo= pment@lists.sourceforge.net</a><br> <a href=3D"https://lists.sourceforge.net/lists/listinfo/bitcoin-development= " target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/bitcoin-de= velopment</a><br> </div></div></blockquote></div><br></div> --f46d04430682eb53f0050d350a13--