Skip to content

Commit 12f3488

Browse files
committed
Merge pull request #6047
a56054b Update key.cpp to use new libsecp256k1 (Pieter Wuille) a591d98 Squashed 'src/secp256k1/' changes from 1897b8e..22f60a6 (Pieter Wuille)
2 parents 00820f9 + a56054b commit 12f3488

31 files changed

+1217
-492
lines changed

src/bitcoin-tx.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,18 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
442442
tx = mergedTx;
443443
}
444444

445+
class Secp256k1Init
446+
{
447+
public:
448+
Secp256k1Init() { ECC_Start(); }
449+
~Secp256k1Init() { ECC_Stop(); }
450+
};
451+
445452
static void MutateTx(CMutableTransaction& tx, const string& command,
446453
const string& commandVal)
447454
{
455+
boost::scoped_ptr<Secp256k1Init> ecc;
456+
448457
if (command == "nversion")
449458
MutateTxVersion(tx, commandVal);
450459
else if (command == "locktime")
@@ -462,8 +471,10 @@ static void MutateTx(CMutableTransaction& tx, const string& command,
462471
else if (command == "outscript")
463472
MutateTxAddOutScript(tx, commandVal);
464473

465-
else if (command == "sign")
474+
else if (command == "sign") {
475+
if (!ecc) { ecc.reset(new Secp256k1Init()); }
466476
MutateTxSign(tx, commandVal);
477+
}
467478

468479
else if (command == "load")
469480
RegisterLoad(commandVal);

src/init.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ void Shutdown()
194194
delete pwalletMain;
195195
pwalletMain = NULL;
196196
#endif
197+
ECC_Stop();
197198
LogPrintf("%s: done\n", __func__);
198199
}
199200

@@ -844,6 +845,9 @@ bool AppInit2(boost::thread_group& threadGroup)
844845

845846
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
846847

848+
// Initialize elliptic curve code
849+
ECC_Start();
850+
847851
// Sanity check
848852
if (!InitSanityCheck())
849853
return InitError(_("Initialization sanity check failed. Bitcoin Core is shutting down."));

src/key.cpp

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,7 @@
1414
#include <secp256k1.h>
1515
#include "ecwrapper.h"
1616

17-
//! anonymous namespace
18-
namespace {
19-
20-
class CSecp256k1Init {
21-
public:
22-
CSecp256k1Init() {
23-
secp256k1_start(SECP256K1_START_SIGN);
24-
}
25-
~CSecp256k1Init() {
26-
secp256k1_stop();
27-
}
28-
};
29-
static CSecp256k1Init instance_of_csecp256k1;
30-
31-
} // anon namespace
17+
static secp256k1_context_t* secp256k1_context = NULL;
3218

3319
bool CKey::Check(const unsigned char *vch) {
3420
return eccrypto::Check(vch);
@@ -44,7 +30,7 @@ void CKey::MakeNewKey(bool fCompressedIn) {
4430
}
4531

4632
bool CKey::SetPrivKey(const CPrivKey &privkey, bool fCompressedIn) {
47-
if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size()))
33+
if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size()))
4834
return false;
4935
fCompressed = fCompressedIn;
5036
fValid = true;
@@ -57,7 +43,7 @@ CPrivKey CKey::GetPrivKey() const {
5743
int privkeylen, ret;
5844
privkey.resize(279);
5945
privkeylen = 279;
60-
ret = secp256k1_ec_privkey_export(begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed);
46+
ret = secp256k1_ec_privkey_export(secp256k1_context, begin(), (unsigned char*)&privkey[0], &privkeylen, fCompressed);
6147
assert(ret);
6248
privkey.resize(privkeylen);
6349
return privkey;
@@ -67,7 +53,7 @@ CPubKey CKey::GetPubKey() const {
6753
assert(fValid);
6854
CPubKey result;
6955
int clen = 65;
70-
int ret = secp256k1_ec_pubkey_create((unsigned char*)result.begin(), &clen, begin(), fCompressed);
56+
int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
7157
assert((int)result.size() == clen);
7258
assert(ret);
7359
assert(result.IsValid());
@@ -81,7 +67,7 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig, uint32_
8167
int nSigLen = 72;
8268
unsigned char extra_entropy[32] = {0};
8369
WriteLE32(extra_entropy, test_case);
84-
int ret = secp256k1_ecdsa_sign(hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL);
70+
int ret = secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), (unsigned char*)&vchSig[0], &nSigLen, begin(), secp256k1_nonce_function_rfc6979, test_case ? extra_entropy : NULL);
8571
assert(ret);
8672
vchSig.resize(nSigLen);
8773
return true;
@@ -106,15 +92,15 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
10692
return false;
10793
vchSig.resize(65);
10894
int rec = -1;
109-
int ret = secp256k1_ecdsa_sign_compact(hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
95+
int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
11096
assert(ret);
11197
assert(rec != -1);
11298
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
11399
return true;
114100
}
115101

116102
bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) {
117-
if (!secp256k1_ec_privkey_import((unsigned char*)begin(), &privkey[0], privkey.size()))
103+
if (!secp256k1_ec_privkey_import(secp256k1_context, (unsigned char*)begin(), &privkey[0], privkey.size()))
118104
return false;
119105
fCompressed = vchPubKey.IsCompressed();
120106
fValid = true;
@@ -140,7 +126,7 @@ bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild
140126
}
141127
memcpy(ccChild, out+32, 32);
142128
memcpy((unsigned char*)keyChild.begin(), begin(), 32);
143-
bool ret = secp256k1_ec_privkey_tweak_add((unsigned char*)keyChild.begin(), out);
129+
bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context, (unsigned char*)keyChild.begin(), out);
144130
UnlockObject(out);
145131
keyChild.fCompressed = true;
146132
keyChild.fValid = ret;
@@ -206,3 +192,32 @@ bool ECC_InitSanityCheck() {
206192
CPubKey pubkey = key.GetPubKey();
207193
return key.VerifyPubKey(pubkey);
208194
}
195+
196+
197+
void ECC_Start() {
198+
assert(secp256k1_context == NULL);
199+
200+
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
201+
assert(ctx != NULL);
202+
203+
{
204+
// Pass in a random blinding seed to the secp256k1 context.
205+
unsigned char seed[32];
206+
LockObject(seed);
207+
GetRandBytes(seed, 32);
208+
bool ret = secp256k1_context_randomize(ctx, seed);
209+
assert(ret);
210+
UnlockObject(seed);
211+
}
212+
213+
secp256k1_context = ctx;
214+
}
215+
216+
void ECC_Stop() {
217+
secp256k1_context_t *ctx = secp256k1_context;
218+
secp256k1_context = NULL;
219+
220+
if (ctx) {
221+
secp256k1_context_destroy(ctx);
222+
}
223+
}

src/key.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,13 @@ struct CExtKey {
173173
void SetMaster(const unsigned char* seed, unsigned int nSeedLen);
174174
};
175175

176-
/** Check that required EC support is available at runtime */
176+
/** Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. */
177+
void ECC_Start(void);
178+
179+
/** Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. */
180+
void ECC_Stop(void);
181+
182+
/** Check that required EC support is available at runtime. */
177183
bool ECC_InitSanityCheck(void);
178184

179185
#endif // BITCOIN_KEY_H

src/secp256k1/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ bench_inv
22
bench_sign
33
bench_verify
44
bench_recover
5+
bench_internal
56
tests
67
*.exe
78
*.so

src/secp256k1/.travis.yml

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
language: c
2+
sudo: false
3+
addons:
4+
apt:
5+
packages: libgmp-dev
26
compiler:
37
- clang
48
- gcc
5-
install:
6-
- sudo apt-get install -qq libssl-dev
7-
- if [ "$BIGNUM" = "gmp" -o "$BIGNUM" = "auto" ]; then sudo apt-get install --no-install-recommends --no-upgrade -qq libgmp-dev; fi
8-
- if [ -n "$EXTRAPACKAGES" ]; then sudo apt-get update && sudo apt-get install --no-install-recommends --no-upgrade $EXTRAPACKAGES; fi
99
env:
1010
global:
11-
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST= EXTRAPACKAGES=
11+
- FIELD=auto BIGNUM=auto SCALAR=auto ENDOMORPHISM=no ASM=no BUILD=check EXTRAFLAGS= HOST=
1212
matrix:
1313
- SCALAR=32bit
1414
- SCALAR=64bit
@@ -22,8 +22,35 @@ env:
2222
- BIGNUM=no ENDOMORPHISM=yes
2323
- BUILD=distcheck
2424
- EXTRAFLAGS=CFLAGS=-DDETERMINISTIC
25-
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib"
26-
- HOST=i686-linux-gnu EXTRAPACKAGES="gcc-multilib" ENDOMORPHISM=yes
25+
matrix:
26+
fast_finish: true
27+
include:
28+
- compiler: clang
29+
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
30+
addons:
31+
apt:
32+
packages:
33+
- gcc-multilib
34+
- libgmp-dev:i386
35+
- compiler: clang
36+
env: HOST=i686-linux-gnu
37+
addons:
38+
apt:
39+
packages:
40+
- gcc-multilib
41+
- compiler: gcc
42+
env: HOST=i686-linux-gnu ENDOMORPHISM=yes
43+
addons:
44+
apt:
45+
packages:
46+
- gcc-multilib
47+
- compiler: gcc
48+
env: HOST=i686-linux-gnu
49+
addons:
50+
apt:
51+
packages:
52+
- gcc-multilib
53+
- libgmp-dev:i386
2754
before_script: ./autogen.sh
2855
script:
2956
- if [ -n "$HOST" ]; then export USE_HOST="--host=$HOST"; fi

0 commit comments

Comments
 (0)