mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-10 22:18:54 +01:00
Also switch the (unused) verification code to low-s instead of even-s.
a81cd968introduced a malleability breaker for signatures (using an even value for S). Ine0e14e43this was changed to the lower of two potential values, rather than the even one. Only the signing code was changed though, the (for now unused) verification code wasn't adapted.
This commit is contained in:
committed by
Pieter Wuille
parent
a63f8b7b36
commit
6fd7ef2bbf
72
src/key.cpp
72
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) {
|
||||
|
||||
Reference in New Issue
Block a user