diff --git a/.gitmodules b/.gitmodules index 14ad7b178..2ff5eb9c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ -[submodule "secp256k1/upstream"] - path = secp256k1/upstream - url = https://github.com/cryptonomex/secp256k1-zkp.git [submodule "include/fc/crypto/webauthn_json"] path = include/fc/crypto/webauthn_json url = https://github.com/Tencent/rapidjson/ +[submodule "secp256k1/secp256k1"] + path = secp256k1/secp256k1 + url = https://github.com/bitcoin-core/secp256k1 diff --git a/include/fc/crypto/elliptic.hpp b/include/fc/crypto/elliptic.hpp index 26128682b..c16e645a4 100644 --- a/include/fc/crypto/elliptic.hpp +++ b/include/fc/crypto/elliptic.hpp @@ -24,7 +24,6 @@ namespace fc { typedef fc::array public_key_point_data; ///< the full non-compressed version of the ECC point typedef fc::array signature; typedef fc::array compact_signature; - typedef std::vector range_proof_type; typedef fc::array extended_key_data; typedef fc::sha256 blinded_hash; typedef fc::sha256 blind_signature; @@ -53,11 +52,6 @@ namespace fc { public_key child( const fc::sha256& offset )const; bool valid()const; - /** Computes new pubkey = generator * offset + old pubkey ?! */ -// public_key mult( const fc::sha256& offset )const; - /** Computes new pubkey = regenerate(offset).pubkey + old pubkey - * = offset * G + 1 * old pubkey ?! */ - public_key add( const fc::sha256& offset )const; public_key( public_key&& pk ); public_key& operator=( public_key&& pk ); @@ -150,39 +144,6 @@ namespace fc { fc::fwd my; }; - struct range_proof_info - { - int exp; - int mantissa; - uint64_t min_value; - uint64_t max_value; - }; - - commitment_type blind( const blind_factor_type& blind, uint64_t value ); - blind_factor_type blind_sum( const std::vector& blinds, uint32_t non_neg ); - /** verifies taht commnits + neg_commits + excess == 0 */ - bool verify_sum( const std::vector& commits, const std::vector& neg_commits, int64_t excess ); - bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const range_proof_type& proof ); - - range_proof_type range_proof_sign( uint64_t min_value, - const commitment_type& commit, - const blind_factor_type& commit_blind, - const blind_factor_type& nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value - ); - - bool verify_range_proof_rewind( blind_factor_type& blind_out, - uint64_t& value_out, - string& message_out, - const blind_factor_type& nonce, - uint64_t& min_val, - uint64_t& max_val, - commitment_type commit, - const range_proof_type& proof ); - range_proof_info range_get_info( const range_proof_type& proof ); - /** * Shims */ @@ -273,7 +234,6 @@ namespace fc { FC_REFLECT_TYPENAME( fc::ecc::private_key ) FC_REFLECT_TYPENAME( fc::ecc::public_key ) -FC_REFLECT( fc::ecc::range_proof_info, (exp)(mantissa)(min_value)(max_value) ) FC_REFLECT_DERIVED( fc::ecc::public_key_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) FC_REFLECT_DERIVED( fc::ecc::signature_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) FC_REFLECT_DERIVED( fc::ecc::private_key_shim, (fc::crypto::shim), BOOST_PP_SEQ_NIL ) diff --git a/include/fc/crypto/elliptic_r1.hpp b/include/fc/crypto/elliptic_r1.hpp index 16dddde89..1ada2a9d6 100644 --- a/include/fc/crypto/elliptic_r1.hpp +++ b/include/fc/crypto/elliptic_r1.hpp @@ -37,7 +37,6 @@ namespace fc { ~public_key(); bool verify( const fc::sha256& digest, const signature& sig ); public_key_data serialize()const; - public_key_point_data serialize_ecc_point()const; operator public_key_data()const { return serialize(); } diff --git a/secp256k1/CMakeLists.txt b/secp256k1/CMakeLists.txt index 5d2ab0f9e..19056d415 100644 --- a/secp256k1/CMakeLists.txt +++ b/secp256k1/CMakeLists.txt @@ -21,16 +21,16 @@ else() endif() add_library(secp256k1 STATIC - upstream/src/secp256k1.c + secp256k1/src/secp256k1.c ) target_include_directories(secp256k1 PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/ - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/include + secp256k1 + secp256k1/include PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/upstream/src - ${SECP256K1_CONFIG_INC_DIR} + secp256k1/src + "${SECP256K1_CONFIG_INC_DIR}" ${GMP_INCLUDE_DIR} ) diff --git a/secp256k1/config_with_gmp/libsecp256k1-config.h b/secp256k1/config_with_gmp/libsecp256k1-config.h index c1f4762c9..000953f9b 100644 --- a/secp256k1/config_with_gmp/libsecp256k1-config.h +++ b/secp256k1/config_with_gmp/libsecp256k1-config.h @@ -1,9 +1,9 @@ #pragma once -//optimizations that any compiler we target have -#define HAVE_BUILTIN_CLZLL 1 -#define HAVE_BUILTIN_EXPECT 1 -#define HAVE___INT128 1 +#define ENABLE_MODULE_RECOVERY 1 + +#define ECMULT_GEN_PREC_BITS 4 +#define ECMULT_WINDOW_SIZE 15 //use GMP for bignum #define HAVE_LIBGMP 1 @@ -11,10 +11,6 @@ #define USE_FIELD_INV_NUM 1 #define USE_SCALAR_INV_NUM 1 -//use impls best for 64-bit -#define USE_FIELD_5X52 1 -#define USE_SCALAR_4X64 1 - //enable asm #ifdef __x86_64__ #define USE_ASM_X86_64 1 diff --git a/secp256k1/config_without_gmp/libsecp256k1-config.h b/secp256k1/config_without_gmp/libsecp256k1-config.h index 24ed1c987..a81452121 100644 --- a/secp256k1/config_without_gmp/libsecp256k1-config.h +++ b/secp256k1/config_without_gmp/libsecp256k1-config.h @@ -1,19 +1,15 @@ #pragma once -//optimizations that any compiler we target have -#define HAVE_BUILTIN_CLZLL 1 -#define HAVE_BUILTIN_EXPECT 1 -#define HAVE___INT128 1 +#define ENABLE_MODULE_RECOVERY 1 + +#define ECMULT_GEN_PREC_BITS 4 +#define ECMULT_WINDOW_SIZE 15 //use internal field & num impls #define USE_FIELD_INV_BUILTIN 1 #define USE_SCALAR_INV_BUILTIN 1 #define USE_NUM_NONE 1 -//use impls best for 64-bit -#define USE_FIELD_5X52 1 -#define USE_SCALAR_4X64 1 - //enable asm #ifdef __x86_64__ #define USE_ASM_X86_64 1 diff --git a/secp256k1/secp256k1 b/secp256k1/secp256k1 new file mode 160000 index 000000000..b61f9da54 --- /dev/null +++ b/secp256k1/secp256k1 @@ -0,0 +1 @@ +Subproject commit b61f9da54eff6d8137e0681b403b48be62f0460a diff --git a/secp256k1/upstream b/secp256k1/upstream deleted file mode 160000 index bd067945e..000000000 --- a/secp256k1/upstream +++ /dev/null @@ -1 +0,0 @@ -Subproject commit bd067945ead3b514fba884abd0de95fc4b5db9ae diff --git a/src/crypto/_elliptic_impl_priv.hpp b/src/crypto/_elliptic_impl_priv.hpp index 8c2a1abff..45d0ef879 100644 --- a/src/crypto/_elliptic_impl_priv.hpp +++ b/src/crypto/_elliptic_impl_priv.hpp @@ -8,7 +8,7 @@ namespace fc { namespace ecc { namespace detail { -const secp256k1_context_t* _get_context(); +const secp256k1_context* _get_context(); void _init_lib(); class private_key_impl diff --git a/src/crypto/elliptic_common.cpp b/src/crypto/elliptic_common.cpp index 33547f39e..4fa0925b9 100644 --- a/src/crypto/elliptic_common.cpp +++ b/src/crypto/elliptic_common.cpp @@ -110,15 +110,6 @@ namespace fc { namespace ecc { return public_key(data); } - public_key public_key::child( const fc::sha256& offset )const - { - fc::sha256::encoder enc; - fc::raw::pack( enc, *this ); - fc::raw::pack( enc, offset ); - - return add( enc.result() ); - } - private_key private_key::child( const fc::sha256& offset )const { fc::sha256::encoder enc; diff --git a/src/crypto/elliptic_impl_priv.cpp b/src/crypto/elliptic_impl_priv.cpp index 585ffdef1..1134c0b4b 100644 --- a/src/crypto/elliptic_impl_priv.cpp +++ b/src/crypto/elliptic_impl_priv.cpp @@ -1,6 +1,7 @@ #include #include +#include #include "_elliptic_impl_priv.hpp" @@ -71,30 +72,35 @@ namespace fc { namespace ecc { { FC_ASSERT( my->_key != empty_priv ); public_key_data pub; - unsigned int pk_len; - FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), (unsigned char*) pub.begin(), (int*) &pk_len, (unsigned char*) my->_key.data(), 1 ) ); - FC_ASSERT( pk_len == pub.size() ); + size_t pub_len = sizeof(pub); + secp256k1_pubkey secp_pub; + FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), &secp_pub, (unsigned char*) my->_key.data() ) ); + secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char*)&pub, &pub_len, &secp_pub, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( pub_len == pub.size() ); return public_key(pub); } static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32, - const unsigned char *key32, unsigned int attempt, - const void *data ) { + const unsigned char *key32, const unsigned char* algo16, + void* data, unsigned int attempt ) { unsigned int* extra = (unsigned int*) data; (*extra)++; - return secp256k1_nonce_function_default( nonce32, msg32, key32, *extra, nullptr ); + return secp256k1_nonce_function_default( nonce32, msg32, key32, algo16, nullptr, *extra ); } compact_signature private_key::sign_compact( const fc::sha256& digest, bool require_canonical )const { FC_ASSERT( my->_key != empty_priv ); compact_signature result; + secp256k1_ecdsa_recoverable_signature secp_sig; int recid; unsigned int counter = 0; do { - FC_ASSERT( secp256k1_ecdsa_sign_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) result.begin() + 1, (unsigned char*) my->_key.data(), extended_nonce_function, &counter, &recid )); + FC_ASSERT( secp256k1_ecdsa_sign_recoverable( detail::_get_context(), &secp_sig, (unsigned char*) digest.data(), (unsigned char*) my->_key.data(), extended_nonce_function, &counter )); + secp256k1_ecdsa_recoverable_signature_serialize_compact( detail::_get_context(), result.data + 1, &recid, &secp_sig); } while( require_canonical && !public_key::is_canonical( result ) ); + result.begin()[0] = 27 + 4 + recid; return result; } diff --git a/src/crypto/elliptic_r1.cpp b/src/crypto/elliptic_r1.cpp index da8044294..84b318f20 100644 --- a/src/crypto/elliptic_r1.cpp +++ b/src/crypto/elliptic_r1.cpp @@ -458,15 +458,6 @@ namespace fc { namespace crypto { namespace r1 { EC_POINT_get_affine_coordinates_GFp( group, pub, self.my->_pub_x.get(), self.my->_pub_y.get(), nullptr ); */ } - public_key_point_data public_key::serialize_ecc_point()const - { - public_key_point_data dat; - if( !my->_key ) return dat; - EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_UNCOMPRESSED ); - char* front = &dat.data[0]; - i2o_ECPublicKey( my->_key, (unsigned char**)&front ); - return dat; - } public_key::public_key() { diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 826d57358..84eacf44f 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -10,6 +10,7 @@ #include #include +#include #if _WIN32 # include @@ -24,13 +25,13 @@ namespace fc { namespace ecc { namespace detail { - const secp256k1_context_t* _get_context() { - static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_RANGEPROOF | SECP256K1_CONTEXT_COMMIT ); + const secp256k1_context* _get_context() { + static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); return ctx; } void _init_lib() { - static const secp256k1_context_t* ctx = _get_context(); + static const secp256k1_context* ctx = _get_context(); static int init_o = init_openssl(); (void)ctx; (void)init_o; @@ -70,9 +71,14 @@ namespace fc { namespace ecc { static const private_key_secret empty_priv; FC_ASSERT( my->_key != empty_priv ); FC_ASSERT( other.my->_key != empty_pub ); - public_key_data pub(other.my->_key); - FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), (unsigned char*) pub.begin(), pub.size(), (unsigned char*) my->_key.data() ) ); - return fc::sha512::hash( pub.begin() + 1, pub.size() - 1 ); + secp256k1_pubkey secp_pubkey; + FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &secp_pubkey, (unsigned char*)other.serialize().data, other.serialize().size() ) ); + FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), &secp_pubkey, (unsigned char*) my->_key.data() ) ); + public_key_data serialized_result; + size_t serialized_result_sz = sizeof(serialized_result); + secp256k1_ec_pubkey_serialize(detail::_get_context(), (unsigned char*)&serialized_result.data, &serialized_result_sz, &secp_pubkey, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( serialized_result_sz == sizeof(serialized_result) ); + return fc::sha512::hash( serialized_result.begin() + 1, serialized_result.size() - 1 ); } @@ -101,15 +107,6 @@ namespace fc { namespace ecc { return my->_key != empty_pub; } - public_key public_key::add( const fc::sha256& digest )const - { - FC_ASSERT( my->_key != empty_pub ); - public_key_data new_key; - memcpy( new_key.begin(), my->_key.begin(), new_key.size() ); - FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) ); - return public_key( new_key ); - } - std::string public_key::to_base58() const { FC_ASSERT( my->_key != empty_pub ); @@ -122,17 +119,6 @@ namespace fc { namespace ecc { return my->_key; } - public_key_point_data public_key::serialize_ecc_point()const - { - FC_ASSERT( my->_key != empty_pub ); - public_key_point_data dat; - unsigned int pk_len = my->_key.size(); - memcpy( dat.begin(), my->_key.begin(), pk_len ); - FC_ASSERT( secp256k1_ec_pubkey_decompress( detail::_get_context(), (unsigned char *) dat.begin(), (int*) &pk_len ) ); - FC_ASSERT( pk_len == dat.size() ); - return dat; - } - public_key::public_key( const public_key_point_data& dat ) { const char* front = &dat.data[0]; @@ -165,108 +151,15 @@ namespace fc { namespace ecc { FC_ASSERT( is_canonical( c ), "signature is not canonical" ); } - unsigned int pk_len; - FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) ); - FC_ASSERT( pk_len == my->_key.size() ); - } - - - commitment_type blind( const blind_factor_type& blind, uint64_t value ) - { - commitment_type result; - FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), (unsigned char*)&result, (unsigned char*)&blind, value ) ); - return result; - } + secp256k1_pubkey secp_pub; + secp256k1_ecdsa_recoverable_signature secp_sig; - blind_factor_type blind_sum( const std::vector& blinds_in, uint32_t non_neg ) - { - blind_factor_type result; - std::vector blinds(blinds_in.size()); - for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (const unsigned char*)&blinds_in[i]; - FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*)&result, blinds.data(), blinds_in.size(), non_neg ) ); - return result; - } - - /** verifies taht commnits + neg_commits + excess == 0 */ - bool verify_sum( const std::vector& commits_in, const std::vector& neg_commits_in, int64_t excess ) - { - std::vector commits(commits_in.size()); - for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = (const unsigned char*)&commits_in[i]; - std::vector neg_commits(neg_commits_in.size()); - for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = (const unsigned char*)&neg_commits_in[i]; - - return secp256k1_pedersen_verify_tally( detail::_get_context(), commits.data(), commits.size(), neg_commits.data(), neg_commits.size(), excess ); - } - - bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector& proof ) - { - return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, (const unsigned char*)&commit, (const unsigned char*)proof.data(), proof.size() ); - } - - std::vector range_proof_sign( uint64_t min_value, - const commitment_type& commit, - const blind_factor_type& commit_blind, - const blind_factor_type& nonce, - int8_t base10_exp, - uint8_t min_bits, - uint64_t actual_value - ) - { - int proof_len = 5134; - std::vector proof(proof_len); - - FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(), - (unsigned char*)proof.data(), - &proof_len, min_value, - (const unsigned char*)&commit, - (const unsigned char*)&commit_blind, - (const unsigned char*)&nonce, - base10_exp, min_bits, actual_value ) ); - proof.resize(proof_len); - return proof; - } - - - bool verify_range_proof_rewind( blind_factor_type& blind_out, - uint64_t& value_out, - string& message_out, - const blind_factor_type& nonce, - uint64_t& min_val, - uint64_t& max_val, - commitment_type commit, - const std::vector& proof ) - { - char msg[4096]; - int mlen = 0; - FC_ASSERT( secp256k1_rangeproof_rewind( detail::_get_context(), - (unsigned char*)&blind_out, - &value_out, - (unsigned char*)msg, - &mlen, - (const unsigned char*)&nonce, - &min_val, - &max_val, - (const unsigned char*)&commit, - (const unsigned char*)proof.data(), - proof.size() ) ); - - message_out = std::string( msg, mlen ); - return true; - } - - range_proof_info range_get_info( const std::vector& proof ) - { - range_proof_info result; - FC_ASSERT( secp256k1_rangeproof_info( detail::_get_context(), - (int*)&result.exp, - (int*)&result.mantissa, - (uint64_t*)&result.min_value, - (uint64_t*)&result.max_value, - (const unsigned char*)proof.data(), - (int)proof.size() ) ); - - return result; - } + FC_ASSERT( secp256k1_ecdsa_recoverable_signature_parse_compact( detail::_get_context(), &secp_sig, (unsigned char*)c.begin() + 1, (*c.begin() - 27) & 3) ); + FC_ASSERT( secp256k1_ecdsa_recover( detail::_get_context(), &secp_pub, &secp_sig, (unsigned char*) digest.data() ) ); + size_t serialized_result_sz = my->_key.size(); + secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char*)&my->_key.data, &serialized_result_sz, &secp_pub, SECP256K1_EC_COMPRESSED ); + FC_ASSERT( serialized_result_sz == my->_key.size() ); + } } }