#include
#include
#include
using namespace std;
bool static IsValidSignatureEncoding(const std::vector
// 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)
cout << "at 0..." << endl;
cout << "sig.size() = " << sig.size() << endl;
// Minimum and maximum size constraints.
if (sig.size() < 9) return false;
if (sig.size() > 73) return false;
cout << "at 1..." << endl;
// A signature is of type 0x30 (compound).
if (sig[0] != 0x30) return false;
cout << "at 2..." << endl;
// Make sure the length covers the entire signature.
if (sig[1] != sig.size() - 3) return false;
cout << "at 3..." << endl;
// Extract the length of the R element.
unsigned int lenR = sig[3];
cout << "at 4..." << endl;
// Make sure the length of the S element is still inside the signature.
if (5 + lenR >= sig.size()) return false;
cout << "at 5..." << endl;
// Extract the length of the S element.
unsigned int lenS = sig[5 + lenR];
cout << "lenR = " << lenR << endl;
cout << "lenS = " << lenS << endl;
// 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;
cout << "at 6..." << endl;
// Check whether the R element is an integer.
if (sig[2] != 0x02) return false;
cout << "at 7..." << endl;
// Zero-length integers are not allowed for R.
if (lenR == 0) return false;
cout << "at 8..." << endl;
// Negative numbers are not allowed for R.
if (sig[4] & 0x80) return false;
cout << "at 9..." << endl;
// 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;
cout << "at 10..." << endl;
// Check whether the S element is an integer.
if (sig[lenR + 4] != 0x02) return false;
cout << "at 11..." << endl;
// Zero-length integers are not allowed for S.
if (lenS == 0) return false;
cout << "at 12..." << endl;
// Negative numbers are not allowed for S.
if (sig[lenR + 6] & 0x80) return false;
cout << "at 13..." << endl;
// 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;
cout << "at 14..." << endl;
return true;
}
int main( int argc, char* argv[ ] )
{
if( argc != 2 )
cout << "usage: x
else
{
string sig( argv[ 1 ] );
vector< unsigned char > bytes;
for( size_t i = 0; i < sig.size( ); i += 2 )
{
unsigned char ch = '\0';
if( sig[ i ] == 'a' || sig[ i ] == 'A' )
ch = 0xa0;
else if( sig[ i ] == 'b' || sig[ i ] == 'B' )
ch = 0xb0;
else if( sig[ i ] == 'c' || sig[ i ] == 'C' )
ch = 0xc0;
else if( sig[ i ] == 'd' || sig[ i ] == 'D' )
ch = 0xd0;
else if( sig[ i ] == 'e' || sig[ i ] == 'E' )
ch = 0xe0;
else if( sig[ i ] == 'f' || sig[ i ] == 'F' )
ch = 0xf0;
else if( sig[ i ] >= '0' && sig[ i ] <= '9' )
ch = ( sig[ i ] - '0' ) << 4;
if( sig[ i + 1 ] == 'a' || sig[ i + 1 ] == 'A' )
ch |= 0x0a;
else if( sig[ i + 1 ] == 'b' || sig[ i + 1 ] == 'B' )
ch |= 0x0b;
else if( sig[ i + 1 ] == 'c' || sig[ i + 1 ] == 'C' )
ch |= 0x0c;
else if( sig[ i + 1 ] == 'd' || sig[ i + 1 ] == 'D' )
ch |= 0x0d;
else if( sig[ i + 1 ] == 'e' || sig[ i + 1 ] == 'E' )
ch |= 0x0e;
else if( sig[ i + 1 ] == 'f' || sig[ i + 1 ] == 'F' )
ch |= 0x0f;
else if( sig[ i + 1 ] >= '0' && sig[ i + 1 ] <= '9' )
ch |= ( sig[ i + 1 ] - '0' );
bytes.push_back( ch );
}
cout << IsValidSignatureEncoding( bytes ) << endl;
}
}
And then ran this:
at 0...
sig.size() = 71
at 1...
at 2...
at 3...
at 4...
at 5...
lenR = 32
lenS = 32
at 6...
at 7...
at 8...
at 9...
at 10...
at 11...
at 12...
at 13...
at 14...
1
which tells me that there is nothing wrong with it. I'm guessing I have something else wrong with a script so that the item on the stack is not actually a signature.