|
|
|
@ -332,30 +332,60 @@ public:
@@ -332,30 +332,60 @@ public:
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
}; // end of anonymous namespace
|
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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] = { |
|
|
|
|
// 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 |
|
|
|
|
}; |
|
|
|
|
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; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// 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) { |
|
|
|
|
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) { |
|
|
|
|