diff options
Diffstat (limited to 'src/key.cpp')
-rw-r--r-- | src/key.cpp | 72 |
1 files changed, 51 insertions, 21 deletions
diff --git a/src/key.cpp b/src/key.cpp index b57b7c506c..2199996cf3 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -332,30 +332,60 @@ public: } }; +int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) { + while (c1len > c2len) { + if (*c1) + return 1; + c1++; + c1len--; + } + while (c2len > c1len) { + if (*c2) + return -1; + c2++; + c2len--; + } + while (c1len > 0) { + if (*c1 > *c2) + return 1; + if (*c2 > *c1) + return -1; + c1++; + c2++; + c1len--; + } + return 0; +} + +// Order of secp256k1's generator minus 1. +const unsigned char vchMaxModOrder[32] = { + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, + 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, + 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 +}; + +// Half of the order of secp256k1's generator minus 1. +const unsigned char vchMaxModHalfOrder[32] = { + 0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, + 0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D, + 0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0 +}; + +const unsigned char vchZero[0] = {}; + + }; // end of anonymous namespace bool CKey::Check(const unsigned char *vch) { - // Do not convert to OpenSSL's data structures for range-checking keys, - // it's easy enough to do directly. - static const unsigned char vchMax[32] = { - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, - 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE, - 0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B, - 0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40 - }; - bool fIsZero = true; - for (int i=0; i<32 && fIsZero; i++) - if (vch[i] != 0) - fIsZero = false; - if (fIsZero) - return false; - for (int i=0; i<32; i++) { - if (vch[i] < vchMax[i]) - return true; - if (vch[i] > vchMax[i]) - return false; - } - return true; + return CompareBigEndian(vch, 32, vchZero, 0) > 0 && + CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0; +} + +bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) { + return CompareBigEndian(vch, len, vchZero, 0) > 0 && + CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0; } void CKey::MakeNewKey(bool fCompressedIn) { |