Skip to content

Commit

Permalink
Update to new libsecp256k1
Browse files Browse the repository at this point in the history
  • Loading branch information
sipa committed Aug 6, 2015
1 parent f02a07f commit 77269e0
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 73 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,7 @@ PKGCONFIG_LIBDIR_TEMP="$PKG_CONFIG_LIBDIR"
unset PKG_CONFIG_LIBDIR
PKG_CONFIG_LIBDIR="$PKGCONFIG_LIBDIR_TEMP"

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

AC_OUTPUT
Expand Down
19 changes: 10 additions & 9 deletions src/blind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
#include "util.h"

#include <secp256k1.h>
#include <secp256k1_rangeproof.h>

static secp256k1_context_t* secp256k1_context = NULL;

void ECC_Blinding_Start() {
assert(secp256k1_context == NULL);

secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_COMMIT | SECP256K1_CONTEXT_RANGEPROOF);
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY);
assert(ctx != NULL);
secp256k1_pedersen_context_initialize(ctx);
secp256k1_rangeproof_context_initialize(ctx);

secp256k1_context = ctx;
}
Expand Down Expand Up @@ -42,14 +45,13 @@ int UnblindOutput(const CKey &key, const CTxOut& txout, CAmount& amount_out, std
if (!ephemeral_key.IsValid()) {
return 0;
}
CPubKey nonce_key = key.ECDH(ephemeral_key);
unsigned char nonce[32];
CHash256().Write(nonce_key.begin(), nonce_key.size()).Finalize(nonce);
uint256 nonce = key.ECDH(ephemeral_key);
CSHA256().Write(nonce.begin(), 32).Finalize(nonce.begin());
unsigned char msg[4096];
int msg_size;
uint64_t min_value, max_value, amount;
blinding_factor_out.resize(32);
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());
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());
if (!res || amount > (uint64_t)MAX_MONEY || !MoneyRange((CAmount)amount)) {
amount_out = 0;
blinding_factor_out.resize(0);
Expand Down Expand Up @@ -121,14 +123,13 @@ void BlindOutputs(const std::vector<std::vector<unsigned char> >& input_blinding
value.vchNonceCommitment.resize(33);
memcpy(&value.vchNonceCommitment[0], &ephemeral_pubkey[0], 33);
// Generate nonce
CPubKey nonce_key = ephemeral_key.ECDH(output_pubkeys[nOut]);
unsigned char nonce[32];
CHash256().Write(nonce_key.begin(), nonce_key.size()).Finalize(nonce);
uint256 nonce = ephemeral_key.ECDH(output_pubkeys[nOut]);
CSHA256().Write(nonce.begin(), 32).Finalize(nonce.begin());
// Create range proof
int nRangeProofLen = 5134;
// TODO: smarter min_value selection
value.vchRangeproof.resize(nRangeProofLen);
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);
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);
value.vchRangeproof.resize(nRangeProofLen);
// TODO: do something smarter here
assert(res);
Expand Down
1 change: 1 addition & 0 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <assert.h>

#include <secp256k1.h>
#include <secp256k1_rangeproof.h>

/**
* calculate number of bytes for the bitmask, and its number of non-zero bytes
Expand Down
24 changes: 13 additions & 11 deletions src/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "random.h"

#include <secp256k1.h>
#include <secp256k1_ecdh.h>
#include <secp256k1_schnorr.h>

static secp256k1_context_t* secp256k1_context = NULL;

Expand Down Expand Up @@ -51,21 +53,21 @@ CPubKey CKey::GetPubKey() const {
assert(fValid);
CPubKey result;
int clen = 65;
int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
secp256k1_pubkey_t pubkey;
int ret = secp256k1_ec_pubkey_create(secp256k1_context, &pubkey, begin());
secp256k1_ec_pubkey_serialize(secp256k1_context, (unsigned char*)result.begin(), &clen, &pubkey, fCompressed);
assert((int)result.size() == clen);
assert(ret);
assert(result.IsValid());
return result;
}

CPubKey CKey::ECDH(const CPubKey& pubkey) const {
uint256 CKey::ECDH(const CPubKey& pubkey) const {
assert(fValid);
CPubKey result = pubkey;
int clen = result.size();
int ret = secp256k1_point_multiply((unsigned char*)result.begin(), &clen, begin());
assert((int)result.size() == clen);
assert(ret);
assert(result.IsValid());
uint256 result;
secp256k1_pubkey_t pkey;
assert(secp256k1_ec_pubkey_parse(secp256k1_context, &pkey, pubkey.begin(), pubkey.size()));
assert(secp256k1_ecdh(secp256k1_context, result.begin(), &pkey, begin()));
return result;
}

Expand Down Expand Up @@ -101,9 +103,9 @@ bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig)
return false;
vchSig.resize(65);
int rec = -1;
int ret = secp256k1_ecdsa_sign_compact(secp256k1_context, hash.begin(), &vchSig[1], begin(), secp256k1_nonce_function_rfc6979, NULL, &rec);
assert(ret);
assert(rec != -1);
secp256k1_ecdsa_signature_t sig;
assert(secp256k1_ecdsa_sign(secp256k1_context, hash.begin(), &sig, begin(), secp256k1_nonce_function_rfc6979, NULL));
assert(secp256k1_ecdsa_signature_serialize_compact(secp256k1_context, &vchSig[1], &rec, &sig));
vchSig[0] = 27 + rec + (fCompressed ? 4 : 0);
return true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class CKey
/**
* Compute the ECDH exchange result using this private key and another public key.
*/
CPubKey ECDH(const CPubKey& pubkey) const;
uint256 ECDH(const CPubKey& pubkey) const;

/**
* Create a DER-serialized signature.
Expand Down
55 changes: 42 additions & 13 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "pubkey.h"

#include <secp256k1.h>
#include <secp256k1_rangeproof.h>
#include <secp256k1_schnorr.h>

secp256k1_context_t* secp256k1_bitcoin_verify_context = NULL;
static secp256k1_context_t*& secp256k1_context = secp256k1_bitcoin_verify_context;
Expand All @@ -14,7 +16,10 @@ bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchS
return false;
if (vchSig.size() != 64)
return false;
if (secp256k1_schnorr_verify(secp256k1_context, (const unsigned char*)&hash, &vchSig[0], begin(), size()) != 1)
secp256k1_pubkey_t pubkey;
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, begin(), size()))
return false;
if (secp256k1_schnorr_verify(secp256k1_context, (const unsigned char*)&hash, &vchSig[0], &pubkey) != 1)
return false;
return true;
}
Expand All @@ -24,28 +29,41 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
return false;
int recid = (vchSig[0] - 27) & 3;
bool fComp = ((vchSig[0] - 27) & 4) != 0;
int pubkeylen = 65;
if (!secp256k1_ecdsa_recover_compact(secp256k1_context, (const unsigned char*)&hash, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
secp256k1_pubkey_t pubkey;
secp256k1_ecdsa_signature_t sig;
if (!secp256k1_ecdsa_signature_parse_compact(secp256k1_context, &sig, &vchSig[1], recid)) {
return false;
}
if (!secp256k1_ecdsa_recover(secp256k1_context, hash.begin(), &sig, &pubkey)) {
return false;
assert((int)size() == pubkeylen);
}
unsigned char pub[65];
int publen = 0;
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, fComp);
Set(pub, pub + publen);
return true;
}

bool CPubKey::IsFullyValid() const {
if (!IsValid())
return false;
if (!secp256k1_ec_pubkey_verify(secp256k1_context, begin(), size()))
secp256k1_pubkey_t pubkey;
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, begin(), size()))
return false;
return true;
}

bool CPubKey::Decompress() {
if (!IsValid())
return false;
int clen = size();
int ret = secp256k1_ec_pubkey_decompress(secp256k1_context, (unsigned char*)begin(), &clen);
assert(ret);
assert(clen == (int)size());
secp256k1_pubkey_t pubkey;
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, &(*this)[0], size())) {
return false;
}
unsigned char pub[65];
int publen = 0;
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, false);
Set(pub, pub + publen);
return true;
}

Expand All @@ -56,9 +74,18 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i
unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild, out+32, 32);
pubkeyChild = *this;
bool ret = secp256k1_ec_pubkey_tweak_add(secp256k1_context, (unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
return ret;
secp256k1_pubkey_t pubkey;
if (!secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, &(*this)[0], size())) {
return false;
}
if (!secp256k1_ec_pubkey_tweak_add(secp256k1_context, &pubkey, out)) {
return false;
}
unsigned char pub[33];
int publen = 0;
secp256k1_ec_pubkey_serialize(secp256k1_context, pub, &publen, &pubkey, 1);
pubkeyChild.Set(pub, pub + publen);
return true;
}

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

secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_COMMIT | SECP256K1_CONTEXT_RANGEPROOF);
secp256k1_context_t *ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
assert(ctx != NULL);
secp256k1_pedersen_context_initialize(ctx);
secp256k1_rangeproof_context_initialize(ctx);

secp256k1_context = ctx;
}
Expand Down
6 changes: 4 additions & 2 deletions src/rpcrawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
#include <boost/assign/list_of.hpp>
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
#include <secp256k1.h>
#include <secp256k1_rangeproof.h>

using namespace boost;
using namespace boost::assign;
using namespace json_spirit;
using namespace std;

extern secp256k1_context_t* secp256k1_bitcoin_verify_context;

void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
{
txnouttype type;
Expand Down Expand Up @@ -91,7 +93,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
int mantissa;
uint64_t minv;
uint64_t maxv;
if (secp256k1_rangeproof_info(NULL, &exp, &mantissa, &minv, &maxv, &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size())) {
if (secp256k1_rangeproof_info(secp256k1_bitcoin_verify_context, &exp, &mantissa, &minv, &maxv, &txout.nValue.vchRangeproof[0], txout.nValue.vchRangeproof.size())) {
if (exp == -1) {
out.push_back(Pair("value", ValueFromAmount((CAmount)minv)));
} else {
Expand Down
6 changes: 5 additions & 1 deletion src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un
unsigned char *pub_start = &(*(sdpc - 33));
CHMAC_SHA256(pub_start, 33).Write(&vcontract[0], 40).Finalize(tweak);
// If someone creates a tweak that makes this fail, they broke SHA256
assert(secp256k1_ec_pubkey_tweak_add(secp256k1_context, pub_start, 33, tweak) != 0);
secp256k1_pubkey_t pubkey;
int pubkeylen = 33;
assert(secp256k1_ec_pubkey_parse(secp256k1_context, &pubkey, pub_start, 33));
assert(secp256k1_ec_pubkey_tweak_add(secp256k1_context, &pubkey, tweak) != 0);
assert(secp256k1_ec_pubkey_serialize(secp256k1_context, pub_start, &pubkeylen, &pubkey, 1));
}
}
}
Expand Down
Loading

0 comments on commit 77269e0

Please sign in to comment.