Skip to content

Commit 73b82a3

Browse files
committed
Merge pull request #5162
d2e74c5 boost: moveonly: split CPubKey and friends to new files (Cory Fields) 78c228c boost: moveonly: move BIP32Hash to hash.h (Cory Fields) 900078a boost: moveonly: create eccryptoverify.h|cpp and move helper functions there (Cory Fields)
2 parents ff17816 + d2e74c5 commit 73b82a3

21 files changed

+458
-369
lines changed

src/Makefile.am

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ BITCOIN_CORE_H = \
8686
core_io.h \
8787
crypter.h \
8888
db.h \
89+
eccryptoverify.h \
8990
ecwrapper.h \
9091
hash.h \
9192
init.h \
@@ -101,6 +102,7 @@ BITCOIN_CORE_H = \
101102
noui.h \
102103
pow.h \
103104
protocol.h \
105+
pubkey.h \
104106
random.h \
105107
rpcclient.h \
106108
rpcprotocol.h \
@@ -220,12 +222,14 @@ libbitcoin_common_a_SOURCES = \
220222
core/transaction.cpp \
221223
core_read.cpp \
222224
core_write.cpp \
225+
eccryptoverify.cpp \
223226
ecwrapper.cpp \
224227
hash.cpp \
225228
key.cpp \
226229
keystore.cpp \
227230
netbase.cpp \
228231
protocol.cpp \
232+
pubkey.cpp \
229233
script/interpreter.cpp \
230234
script/script.cpp \
231235
script/sigcache.cpp \

src/alert.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "chainparams.h"
99
#include "clientversion.h"
10-
#include "key.h"
10+
#include "pubkey.h"
1111
#include "net.h"
1212
#include "timedata.h"
1313
#include "ui_interface.h"

src/base58.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "chainparams.h"
1818
#include "key.h"
19+
#include "pubkey.h"
1920
#include "script/script.h"
2021
#include "script/standard.h"
2122

src/bloom.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "bloom.h"
66

77
#include "core/transaction.h"
8+
#include "hash.h"
89
#include "script/script.h"
910
#include "script/standard.h"
1011
#include "streams.h"

src/compressor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "compressor.h"
77

88
#include "hash.h"
9-
#include "key.h"
9+
#include "pubkey.h"
1010
#include "script/standard.h"
1111

1212
bool CScriptCompressor::IsToKeyID(CKeyID &hash) const

src/eccryptoverify.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#include "eccryptoverify.h"
2+
3+
namespace {
4+
5+
int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) {
6+
while (c1len > c2len) {
7+
if (*c1)
8+
return 1;
9+
c1++;
10+
c1len--;
11+
}
12+
while (c2len > c1len) {
13+
if (*c2)
14+
return -1;
15+
c2++;
16+
c2len--;
17+
}
18+
while (c1len > 0) {
19+
if (*c1 > *c2)
20+
return 1;
21+
if (*c2 > *c1)
22+
return -1;
23+
c1++;
24+
c2++;
25+
c1len--;
26+
}
27+
return 0;
28+
}
29+
30+
/** Order of secp256k1's generator minus 1. */
31+
const unsigned char vchMaxModOrder[32] = {
32+
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
33+
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
34+
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
35+
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
36+
};
37+
38+
/** Half of the order of secp256k1's generator minus 1. */
39+
const unsigned char vchMaxModHalfOrder[32] = {
40+
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
41+
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
42+
0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D,
43+
0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0
44+
};
45+
46+
const unsigned char vchZero[1] = {0};
47+
} // anon namespace
48+
49+
namespace eccrypto {
50+
51+
bool Check(const unsigned char *vch) {
52+
return vch &&
53+
CompareBigEndian(vch, 32, vchZero, 0) > 0 &&
54+
CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0;
55+
}
56+
57+
bool CheckSignatureElement(const unsigned char *vch, int len, bool half) {
58+
return vch &&
59+
CompareBigEndian(vch, len, vchZero, 0) > 0 &&
60+
CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
61+
}
62+
63+
} // namespace eccrypto

src/eccryptoverify.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2009-2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2013 The Bitcoin developers
3+
// Distributed under the MIT/X11 software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#ifndef BITCOIN_EC_CRYPTO_VERIFY_H
7+
#define BITCOIN_EC_CRYPTO_VERIFY_H
8+
9+
#include <vector>
10+
#include <cstdlib>
11+
class uint256;
12+
13+
namespace eccrypto {
14+
15+
bool Check(const unsigned char *vch);
16+
bool CheckSignatureElement(const unsigned char *vch, int len, bool half);
17+
18+
} // eccrypto namespace
19+
#endif

src/hash.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,16 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
6363

6464
return h1;
6565
}
66+
67+
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64])
68+
{
69+
unsigned char num[4];
70+
num[0] = (nChild >> 24) & 0xFF;
71+
num[1] = (nChild >> 16) & 0xFF;
72+
num[2] = (nChild >> 8) & 0xFF;
73+
num[3] = (nChild >> 0) & 0xFF;
74+
CHMAC_SHA512(chainCode, 32).Write(&header, 1)
75+
.Write(data, 32)
76+
.Write(num, 4)
77+
.Finalize(output);
78+
}

src/hash.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,5 @@ uint256 SerializeHash(const T& obj, int nType=SER_GETHASH, int nVersion=PROTOCOL
159159

160160
unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char>& vDataToHash);
161161

162+
void BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]);
162163
#endif // BITCOIN_HASH_H

src/key.cpp

Lines changed: 3 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include "key.h"
66

77
#include "crypto/sha2.h"
8+
#include "eccryptoverify.h"
9+
#include "pubkey.h"
810
#include "random.h"
911

1012
#ifdef USE_SECP256K1
@@ -30,60 +32,10 @@ class CSecp256k1Init {
3032
static CSecp256k1Init instance_of_csecp256k1;
3133

3234
#endif
33-
34-
int CompareBigEndian(const unsigned char *c1, size_t c1len, const unsigned char *c2, size_t c2len) {
35-
while (c1len > c2len) {
36-
if (*c1)
37-
return 1;
38-
c1++;
39-
c1len--;
40-
}
41-
while (c2len > c1len) {
42-
if (*c2)
43-
return -1;
44-
c2++;
45-
c2len--;
46-
}
47-
while (c1len > 0) {
48-
if (*c1 > *c2)
49-
return 1;
50-
if (*c2 > *c1)
51-
return -1;
52-
c1++;
53-
c2++;
54-
c1len--;
55-
}
56-
return 0;
57-
}
58-
59-
/** Order of secp256k1's generator minus 1. */
60-
const unsigned char vchMaxModOrder[32] = {
61-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
62-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
63-
0xBA,0xAE,0xDC,0xE6,0xAF,0x48,0xA0,0x3B,
64-
0xBF,0xD2,0x5E,0x8C,0xD0,0x36,0x41,0x40
65-
};
66-
67-
/** Half of the order of secp256k1's generator minus 1. */
68-
const unsigned char vchMaxModHalfOrder[32] = {
69-
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
70-
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
71-
0x5D,0x57,0x6E,0x73,0x57,0xA4,0x50,0x1D,
72-
0xDF,0xE9,0x2F,0x46,0x68,0x1B,0x20,0xA0
73-
};
74-
75-
const unsigned char vchZero[1] = {0};
76-
7735
} // anon namespace
7836

7937
bool CKey::Check(const unsigned char *vch) {
80-
return CompareBigEndian(vch, 32, vchZero, 0) > 0 &&
81-
CompareBigEndian(vch, 32, vchMaxModOrder, 32) <= 0;
82-
}
83-
84-
bool CKey::CheckSignatureElement(const unsigned char *vch, int len, bool half) {
85-
return CompareBigEndian(vch, len, vchZero, 0) > 0 &&
86-
CompareBigEndian(vch, len, half ? vchMaxModHalfOrder : vchMaxModOrder, 32) <= 0;
38+
return eccrypto::Check(vch);
8739
}
8840

8941
void CKey::MakeNewKey(bool fCompressedIn) {
@@ -216,88 +168,6 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
216168
return true;
217169
}
218170

219-
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
220-
if (!IsValid())
221-
return false;
222-
#ifdef USE_SECP256K1
223-
if (secp256k1_ecdsa_verify((const unsigned char*)&hash, 32, &vchSig[0], vchSig.size(), begin(), size()) != 1)
224-
return false;
225-
#else
226-
CECKey key;
227-
if (!key.SetPubKey(begin(), size()))
228-
return false;
229-
if (!key.Verify(hash, vchSig))
230-
return false;
231-
#endif
232-
return true;
233-
}
234-
235-
bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned char>& vchSig) {
236-
if (vchSig.size() != 65)
237-
return false;
238-
int recid = (vchSig[0] - 27) & 3;
239-
bool fComp = ((vchSig[0] - 27) & 4) != 0;
240-
#ifdef USE_SECP256K1
241-
int pubkeylen = 65;
242-
if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, 32, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
243-
return false;
244-
assert((int)size() == pubkeylen);
245-
#else
246-
CECKey key;
247-
if (!key.Recover(hash, &vchSig[1], recid))
248-
return false;
249-
std::vector<unsigned char> pubkey;
250-
key.GetPubKey(pubkey, fComp);
251-
Set(pubkey.begin(), pubkey.end());
252-
#endif
253-
return true;
254-
}
255-
256-
bool CPubKey::IsFullyValid() const {
257-
if (!IsValid())
258-
return false;
259-
#ifdef USE_SECP256K1
260-
if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
261-
return false;
262-
#else
263-
CECKey key;
264-
if (!key.SetPubKey(begin(), size()))
265-
return false;
266-
#endif
267-
return true;
268-
}
269-
270-
bool CPubKey::Decompress() {
271-
if (!IsValid())
272-
return false;
273-
#ifdef USE_SECP256K1
274-
int clen = size();
275-
int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen);
276-
assert(ret);
277-
assert(clen == (int)size());
278-
#else
279-
CECKey key;
280-
if (!key.SetPubKey(begin(), size()))
281-
return false;
282-
std::vector<unsigned char> pubkey;
283-
key.GetPubKey(pubkey, false);
284-
Set(pubkey.begin(), pubkey.end());
285-
#endif
286-
return true;
287-
}
288-
289-
void static BIP32Hash(const unsigned char chainCode[32], unsigned int nChild, unsigned char header, const unsigned char data[32], unsigned char output[64]) {
290-
unsigned char num[4];
291-
num[0] = (nChild >> 24) & 0xFF;
292-
num[1] = (nChild >> 16) & 0xFF;
293-
num[2] = (nChild >> 8) & 0xFF;
294-
num[3] = (nChild >> 0) & 0xFF;
295-
CHMAC_SHA512(chainCode, 32).Write(&header, 1)
296-
.Write(data, 32)
297-
.Write(num, 4)
298-
.Finalize(output);
299-
}
300-
301171
bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
302172
assert(IsValid());
303173
assert(IsCompressed());
@@ -324,27 +194,6 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild
324194
return ret;
325195
}
326196

327-
bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const {
328-
assert(IsValid());
329-
assert((nChild >> 31) == 0);
330-
assert(begin() + 33 == end());
331-
unsigned char out[64];
332-
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
333-
memcpy(ccChild, out+32, 32);
334-
#ifdef USE_SECP256K1
335-
pubkeyChild = *this;
336-
bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
337-
#else
338-
CECKey key;
339-
bool ret = key.SetPubKey(begin(), size());
340-
ret &= key.TweakPublic(out);
341-
std::vector<unsigned char> pubkey;
342-
key.GetPubKey(pubkey, true);
343-
pubkeyChild.Set(pubkey.begin(), pubkey.end());
344-
#endif
345-
return ret;
346-
}
347-
348197
bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const {
349198
out.nDepth = nDepth + 1;
350199
CKeyID id = key.GetPubKey().GetID();
@@ -395,32 +244,6 @@ void CExtKey::Decode(const unsigned char code[74]) {
395244
key.Set(code+42, code+74, true);
396245
}
397246

398-
void CExtPubKey::Encode(unsigned char code[74]) const {
399-
code[0] = nDepth;
400-
memcpy(code+1, vchFingerprint, 4);
401-
code[5] = (nChild >> 24) & 0xFF; code[6] = (nChild >> 16) & 0xFF;
402-
code[7] = (nChild >> 8) & 0xFF; code[8] = (nChild >> 0) & 0xFF;
403-
memcpy(code+9, vchChainCode, 32);
404-
assert(pubkey.size() == 33);
405-
memcpy(code+41, pubkey.begin(), 33);
406-
}
407-
408-
void CExtPubKey::Decode(const unsigned char code[74]) {
409-
nDepth = code[0];
410-
memcpy(vchFingerprint, code+1, 4);
411-
nChild = (code[5] << 24) | (code[6] << 16) | (code[7] << 8) | code[8];
412-
memcpy(vchChainCode, code+9, 32);
413-
pubkey.Set(code+41, code+74);
414-
}
415-
416-
bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
417-
out.nDepth = nDepth + 1;
418-
CKeyID id = pubkey.GetID();
419-
memcpy(&out.vchFingerprint[0], &id, 4);
420-
out.nChild = nChild;
421-
return pubkey.Derive(out.pubkey, out.vchChainCode, nChild, vchChainCode);
422-
}
423-
424247
bool ECC_InitSanityCheck() {
425248
#ifdef USE_SECP256K1
426249
return true;

0 commit comments

Comments
 (0)