Skip to content

Commit 77269e0

Browse files
committed
Update to new libsecp256k1
1 parent f02a07f commit 77269e0

File tree

11 files changed

+112
-73
lines changed

11 files changed

+112
-73
lines changed

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
909909
unset PKG_CONFIG_LIBDIR
910910
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"
911911

912-
ac_configure_args="${ac_configure_args} --disable-shared --with-pic"
912+
ac_configure_args="${ac_configure_args} --disable-shared --with-pic --enable-module-schnorr --enable-module-ecdh --enable-module-rangeproof"
913913
AC_CONFIG_SUBDIRS([src/secp256k1])
914914

915915
AC_OUTPUT

src/blind.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,17 @@
66
#include "util.h"
77

88
#include <secp256k1.h>
9+
#include <secp256k1_rangeproof.h>
910

1011
static secp256k1_context_t* secp256k1_context = NULL;
1112

1213
void ECC_Blinding_Start() {
1314
assert(secp256k1_context == NULL);
1415

15-
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_COMMIT | SECP256K1_CONTEXT_RANGEPROOF);
16+
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
1617
assert(ctx != NULL);
18+
secp256k1_pedersen_context_initialize(ctx);
19+
secp256k1_rangeproof_context_initialize(ctx);
1720

1821
secp256k1_context = ctx;
1922
}
@@ -42,14 +45,13 @@ int UnblindOutput(const CKey &key, const CTxOut& txout, CAmount& amount_out, std
4245
if (!ephemeral_key.IsValid()) {
4346
return 0;
4447
}
45-
CPubKey nonce_key = key.ECDH(ephemeral_key);
46-
unsigned char nonce[32];
47-
CHash256().Write(nonce_key.begin(), nonce_key.size()).Finalize(nonce);
48+
uint256 nonce = key.ECDH(ephemeral_key);
49+
CSHA256().Write(nonce.begin(), 32).Finalize(nonce.begin());
4850
unsigned char msg[4096];
4951
int msg_size;
5052
uint64_t min_value, max_value, amount;
5153
blinding_factor_out.resize(32);
52-
int res = secp256k1_rangeproof_rewind(secp256k1_context, &blinding_factor_out[0], &amount, msg, &msg_size, nonce, &min_value, &max_value, &txout.nValue.vchCommitment[0], &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size());
54+
int res = secp256k1_rangeproof_rewind(secp256k1_context, &blinding_factor_out[0], &amount, msg, &msg_size, nonce.begin(), &min_value, &max_value, &txout.nValue.vchCommitment[0], &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size());
5355
if (!res || amount > (uint64_t)MAX_MONEY || !MoneyRange((CAmount)amount)) {
5456
amount_out = 0;
5557
blinding_factor_out.resize(0);
@@ -121,14 +123,13 @@ void BlindOutputs(const std::vector<std::vector<unsigned char> >& input_blinding
121123
value.vchNonceCommitment.resize(33);
122124
memcpy(&value.vchNonceCommitment[0], &ephemeral_pubkey[0], 33);
123125
// Generate nonce
124-
CPubKey nonce_key = ephemeral_key.ECDH(output_pubkeys[nOut]);
125-
unsigned char nonce[32];
126-
CHash256().Write(nonce_key.begin(), nonce_key.size()).Finalize(nonce);
126+
uint256 nonce = ephemeral_key.ECDH(output_pubkeys[nOut]);
127+
CSHA256().Write(nonce.begin(), 32).Finalize(nonce.begin());
127128
// Create range proof
128129
int nRangeProofLen = 5134;
129130
// TODO: smarter min_value selection
130131
value.vchRangeproof.resize(nRangeProofLen);
131-
int res = secp256k1_rangeproof_sign(ECC_Blinding_Context(), &value.vchRangeproof[0], &nRangeProofLen, 0, &value.vchCommitment[0], blindptrs.back(), nonce, std::min(std::max((int)GetArg("-ct_exponent", 0), -1),18), std::min(std::max((int)GetArg("-ct_bits", 32), 1), 51), amount);
132+
int res = secp256k1_rangeproof_sign(ECC_Blinding_Context(), &value.vchRangeproof[0], &nRangeProofLen, 0, &value.vchCommitment[0], blindptrs.back(), nonce.begin(), std::min(std::max((int)GetArg("-ct_exponent", 0), -1),18), std::min(std::max((int)GetArg("-ct_bits", 32), 1), 51), amount);
132133
value.vchRangeproof.resize(nRangeProofLen);
133134
// TODO: do something smarter here
134135
assert(res);

src/coins.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <assert.h>
1010

1111
#include <secp256k1.h>
12+
#include <secp256k1_rangeproof.h>
1213

1314
/**
1415
* calculate number of bytes for the bitmask, and its number of non-zero bytes

src/key.cpp

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#include "random.h"
1313

1414
#include <secp256k1.h>
15+
#include <secp256k1_ecdh.h>
16+
#include <secp256k1_schnorr.h>
1517

1618
static secp256k1_context_t* secp256k1_context = NULL;
1719

@@ -51,21 +53,21 @@ CPubKey CKey::GetPubKey() const {
5153
assert(fValid);
5254
CPubKey result;
5355
int clen = 65;
54-
int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
56+
secp256k1_pubkey_t pubkey;
57+
int ret = secp256k1_ec_pubkey_create(secp256k1_context, &pubkey, begin());
58+
secp256k1_ec_pubkey_serialize(secp256k1_context, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed);
5559
assert((int)result.size() == clen);
5660
assert(ret);
5761
assert(result.IsValid());
5862
return result;
5963
}
6064

61-
CPubKey CKey::ECDH(const CPubKey& pubkey) const {
65+
uint256 CKey::ECDH(const CPubKey& pubkey) const {
6266
assert(fValid);
63-
CPubKey result = pubkey;
64-
int clen = result.size();
65-
int ret = secp256k1_point_multiply((unsigned char*)result.begin(), &clen, begin());
66-
assert((int)result.size() == clen);
67-
assert(ret);
68-
assert(result.IsValid());
67+
uint256 result;
68+
secp256k1_pubkey_t pkey;
69+
assert(secp256k1_ec_pubkey_parse(secp256k1_context, &pkey, pubkey.begin(), pubkey.size()));
70+
assert(secp256k1_ecdh(secp256k1_context, result.begin(), &pkey, begin()));
6971
return result;
7072
}
7173

@@ -101,9 +103,9 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
101103
return false;
102104
vchSig.resize(65);
103105
int rec = -1;
104-
int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
105-
assert(ret);
106-
assert(rec != -1);
106+
secp256k1_ecdsa_signature_t sig;
107+
assert(secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), &sig, begin(), secp256k1_nonce_function_rfc6979, NULL));
108+
assert(secp256k1_ecdsa_signature_serialize_compact(secp256k1_context, &vchSig[1], &rec, &sig));
107109
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
108110
return true;
109111
}

src/key.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class CKey
125125
/**
126126
* Compute the ECDH exchange result using this private key and another public key.
127127
*/
128-
CPubKey ECDH(const CPubKey& pubkey) const;
128+
uint256 ECDH(const CPubKey& pubkey) const;
129129

130130
/**
131131
* Create a DER-serialized signature.

src/pubkey.cpp

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

77
#include <secp256k1.h>
8+
#include <secp256k1_rangeproof.h>
9+
#include <secp256k1_schnorr.h>
810

911
secp256k1_context_t* secp256k1_bitcoin_verify_context = NULL;
1012
static secp256k1_context_t*& secp256k1_context = secp256k1_bitcoin_verify_context;
@@ -14,7 +16,10 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
1416
return false;
1517
if (vchSig.size() != 64)
1618
return false;
17-
if (secp256k1_schnorr_verify(secp256k1_context, (const unsigned char*)&hash, &vchSig[0], begin(), size()) != 1)
19+
secp256k1_pubkey_t pubkey;
20+
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, begin(), size()))
21+
return false;
22+
if (secp256k1_schnorr_verify(secp256k1_context, (const unsigned char*)&hash, &vchSig[0], &pubkey) != 1)
1823
return false;
1924
return true;
2025
}
@@ -24,28 +29,41 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
2429
return false;
2530
int recid = (vchSig[0] - 27) & 3;
2631
bool fComp = ((vchSig[0] - 27) & 4) != 0;
27-
int pubkeylen = 65;
28-
if (!secp256k1_ecdsa_recover_compact(secp256k1_context, (const unsigned char*)&hash, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
32+
secp256k1_pubkey_t pubkey;
33+
secp256k1_ecdsa_signature_t sig;
34+
if (!secp256k1_ecdsa_signature_parse_compact(secp256k1_context, &sig, &vchSig[1], recid)) {
35+
return false;
36+
}
37+
if (!secp256k1_ecdsa_recover(secp256k1_context, hash.begin(), &sig, &pubkey)) {
2938
return false;
30-
assert((int)size() == pubkeylen);
39+
}
40+
unsigned char pub[65];
41+
int publen = 0;
42+
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, fComp);
43+
Set(pub, pub + publen);
3144
return true;
3245
}
3346

3447
bool CPubKey::IsFullyValid() const {
3548
if (!IsValid())
3649
return false;
37-
if (!secp256k1_ec_pubkey_verify(secp256k1_context, begin(), size()))
50+
secp256k1_pubkey_t pubkey;
51+
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, begin(), size()))
3852
return false;
3953
return true;
4054
}
4155

4256
bool CPubKey::Decompress() {
4357
if (!IsValid())
4458
return false;
45-
int clen = size();
46-
int ret = secp256k1_ec_pubkey_decompress(secp256k1_context, (unsigned char*)begin(), &clen);
47-
assert(ret);
48-
assert(clen == (int)size());
59+
secp256k1_pubkey_t pubkey;
60+
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, &(*this)[0], size())) {
61+
return false;
62+
}
63+
unsigned char pub[65];
64+
int publen = 0;
65+
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, false);
66+
Set(pub, pub + publen);
4967
return true;
5068
}
5169

@@ -56,9 +74,18 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i
5674
unsigned char out[64];
5775
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
5876
memcpy(ccChild, out+32, 32);
59-
pubkeyChild = *this;
60-
bool ret = secp256k1_ec_pubkey_tweak_add(secp256k1_context, (unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
61-
return ret;
77+
secp256k1_pubkey_t pubkey;
78+
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, &(*this)[0], size())) {
79+
return false;
80+
}
81+
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context, &pubkey, out)) {
82+
return false;
83+
}
84+
unsigned char pub[33];
85+
int publen = 0;
86+
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, 1);
87+
pubkeyChild.Set(pub, pub + publen);
88+
return true;
6289
}
6390

6491
void CExtPubKey::Encode(unsigned char code[74]) const {
@@ -90,8 +117,10 @@ bool CExtPubKey::Derive(CExtPubKey &out, unsigned int nChild) const {
90117
void ECC_Verify_Start() {
91118
assert(secp256k1_context == NULL);
92119

93-
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_COMMIT | SECP256K1_CONTEXT_RANGEPROOF);
120+
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
94121
assert(ctx != NULL);
122+
secp256k1_pedersen_context_initialize(ctx);
123+
secp256k1_rangeproof_context_initialize(ctx);
95124

96125
secp256k1_context = ctx;
97126
}

src/rpcrawtransaction.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
#include <boost/assign/list_of.hpp>
2727
#include "json/json_spirit_utils.h"
2828
#include "json/json_spirit_value.h"
29-
#include <secp256k1.h>
29+
#include <secp256k1_rangeproof.h>
3030

3131
using namespace boost;
3232
using namespace boost::assign;
3333
using namespace json_spirit;
3434
using namespace std;
3535

36+
extern secp256k1_context_t* secp256k1_bitcoin_verify_context;
37+
3638
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
3739
{
3840
txnouttype type;
@@ -91,7 +93,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
9193
int mantissa;
9294
uint64_t minv;
9395
uint64_t maxv;
94-
if (secp256k1_rangeproof_info(NULL, &exp, &mantissa, &minv, &maxv, &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size())) {
96+
if (secp256k1_rangeproof_info(secp256k1_bitcoin_verify_context, &exp, &mantissa, &minv, &maxv, &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size())) {
9597
if (exp == -1) {
9698
out.push_back(Pair("value", ValueFromAmount((CAmount)minv)));
9799
} else {

src/script/interpreter.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1462,7 +1462,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
14621462
unsigned char *pub_start = &(*(sdpc - 33));
14631463
CHMAC_SHA256(pub_start, 33).Write(&vcontract[0], 40).Finalize(tweak);
14641464
// If someone creates a tweak that makes this fail, they broke SHA256
1465-
assert(secp256k1_ec_pubkey_tweak_add(secp256k1_context, pub_start, 33, tweak) != 0);
1465+
secp256k1_pubkey_t pubkey;
1466+
int pubkeylen = 33;
1467+
assert(secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, pub_start, 33));
1468+
assert(secp256k1_ec_pubkey_tweak_add(secp256k1_context, &pubkey, tweak) != 0);
1469+
assert(secp256k1_ec_pubkey_serialize(secp256k1_context, pub_start, &pubkeylen, &pubkey, 1));
14661470
}
14671471
}
14681472
}

0 commit comments

Comments
 (0)