Skip to content

Commit a360280

Browse files
Introduce signature version flags
1 parent 5b669ff commit a360280

File tree

6 files changed

+48
-12
lines changed

6 files changed

+48
-12
lines changed

src/key.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ bool CKey::VerifyPubKey(const CPubKey& pubkey) const {
246246
return pubkey.Verify(hash, vchSig);
247247
}
248248

249-
bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const {
250-
if (!keydata)
249+
bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig, unsigned char header) const {
250+
if (!keydata || header > CPubKey::SigFlag::VERSION_SIG_MASK)
251251
return false;
252252
vchSig.resize(CPubKey::COMPACT_SIGNATURE_SIZE);
253253
int rec = -1;
@@ -257,7 +257,7 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
257257
ret = secp256k1_ecdsa_recoverable_signature_serialize_compact(secp256k1_context_sign, &vchSig[1], &rec, &rsig);
258258
assert(ret);
259259
assert(rec != -1);
260-
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
260+
vchSig[0] = header + rec + (fCompressed ? 4 : 0);
261261
// Additional verification step to prevent using a potentially corrupted signature
262262
secp256k1_pubkey epk, rpk;
263263
ret = secp256k1_ec_pubkey_create(secp256k1_context_sign, &epk, UCharCast(begin()));

src/key.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ class CKey
153153
* 0x1D = second key with even y, 0x1E = second key with odd y,
154154
* add 0x04 for compressed keys.
155155
*/
156-
bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig) const;
156+
bool SignCompact(const uint256& hash, std::vector<unsigned char>& vchSig, unsigned char header = 27) const;
157157

158158
/**
159159
* Create a BIP-340 Schnorr signature, for the xonly-pubkey corresponding to *this,

src/pubkey.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
5353
secp256k1_ecdsa_signature_parse_compact(secp256k1_context_static, sig, tmpsig);
5454

5555
/* Sequence tag byte */
56-
if (pos == inputlen || input[pos] != 0x30) {
56+
if (pos == inputlen || input[pos] != CPubKey::SigFlag::VERSION_SIG_DER) {
5757
return 0;
5858
}
5959
pos++;
@@ -291,11 +291,11 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
291291
return secp256k1_ecdsa_verify(secp256k1_context_static, &sig, hash.begin(), &pubkey);
292292
}
293293

294-
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
295-
if (vchSig.size() != COMPACT_SIGNATURE_SIZE)
294+
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig, unsigned char header) {
295+
if (vchSig.size() != COMPACT_SIGNATURE_SIZE || header > vchSig[0] || header > CPubKey::SigFlag::VERSION_SIG_MASK)
296296
return false;
297-
int recid = (vchSig[0] - 27) & 3;
298-
bool fComp = ((vchSig[0] - 27) & 4) != 0;
297+
int recid = (vchSig[0] - header) & 3;
298+
bool fComp = ((vchSig[0] - header) & 4) != 0;
299299
secp256k1_pubkey pubkey;
300300
secp256k1_ecdsa_recoverable_signature sig;
301301
if (!secp256k1_ecdsa_recoverable_signature_parse_compact(secp256k1_context_static, &sig, &vchSig[1], recid)) {

src/pubkey.h

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,42 @@ class CPubKey
4848
SIZE >= COMPRESSED_SIZE,
4949
"COMPRESSED_SIZE is larger than SIZE");
5050

51+
enum SigType : int {
52+
SIG_COMPACT = 0,
53+
SIG_DER = 1,
54+
SIG_COUNT
55+
};
56+
57+
enum SigFlag : unsigned char {
58+
// must be greater than zero to avoid being interpreted as an uncompressed public key
59+
VERSION_SIG_COMPACT = 1 << 3,
60+
VERSION_SIG_DER = 6 << 3,
61+
VERSION_SIG_MASK = 31 << 3
62+
};
63+
64+
static int GetSigType(unsigned char flag)
65+
{
66+
switch (flag & VERSION_SIG_MASK) {
67+
case VERSION_SIG_COMPACT:
68+
return SIG_COMPACT;
69+
case VERSION_SIG_DER:
70+
return SIG_DER;
71+
default:
72+
return -1;
73+
}
74+
}
75+
76+
static unsigned char GetSigFlag(int type)
77+
{
78+
switch (type) {
79+
case SIG_COMPACT:
80+
return VERSION_SIG_COMPACT;
81+
case SIG_DER:
82+
default:
83+
return VERSION_SIG_DER;
84+
}
85+
}
86+
5187
private:
5288

5389
/**
@@ -218,7 +254,7 @@ class CPubKey
218254
static bool CheckLowS(const std::vector<unsigned char>& vchSig);
219255

220256
//! Recover a public key from a compact signature.
221-
bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig);
257+
bool RecoverCompact(const uint256& hash, const std::vector<unsigned char>& vchSig, unsigned char header = 27);
222258

223259
//! Turn this public key into an uncompressed public key.
224260
bool Decompress();

src/script/interpreter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ bool static IsValidSignatureEncoding(const std::vector<unsigned char> &sig) {
122122
if (sig.size() > 73) return false;
123123

124124
// A signature is of type 0x30 (compound).
125-
if (sig[0] != 0x30) return false;
125+
if (sig[0] != CPubKey::SigFlag::VERSION_SIG_DER) return false;
126126

127127
// Make sure the length covers the entire signature.
128128
if (sig[1] != sig.size() - 3) return false;

src/script/sign.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,7 +721,7 @@ class DummySignatureCreator final : public BaseSignatureCreator {
721721
{
722722
// Create a dummy signature that is a valid DER-encoding
723723
vchSig.assign(m_r_len + m_s_len + 7, '\000');
724-
vchSig[0] = 0x30;
724+
vchSig[0] = CPubKey::SigFlag::VERSION_SIG_DER;
725725
vchSig[1] = m_r_len + m_s_len + 4;
726726
vchSig[2] = 0x02;
727727
vchSig[3] = m_r_len;

0 commit comments

Comments
 (0)