diff --git a/include/fc/crypto/elliptic_r1.hpp b/include/fc/crypto/elliptic_r1.hpp index 1ada2a9d..16dddde8 100644 --- a/include/fc/crypto/elliptic_r1.hpp +++ b/include/fc/crypto/elliptic_r1.hpp @@ -37,6 +37,7 @@ 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/src/crypto/elliptic_r1.cpp b/src/crypto/elliptic_r1.cpp index 84b318f2..496533fc 100644 --- a/src/crypto/elliptic_r1.cpp +++ b/src/crypto/elliptic_r1.cpp @@ -459,6 +459,18 @@ namespace fc { namespace crypto { namespace r1 { */ } + public_key_point_data public_key::serialize_ecc_point()const + { + public_key_point_data dat; + if( !my->_key ) return dat; + auto key = EC_KEY_dup( my->_key ); + EC_KEY_set_conv_form( key, POINT_CONVERSION_UNCOMPRESSED ); + char* front = &dat.data[0]; + i2o_ECPublicKey( key, (unsigned char**)&front ); + EC_KEY_free( key ); + return dat; + } + public_key::public_key() { } diff --git a/src/crypto/elliptic_secp256k1.cpp b/src/crypto/elliptic_secp256k1.cpp index 84eacf44..3f1b53d0 100644 --- a/src/crypto/elliptic_secp256k1.cpp +++ b/src/crypto/elliptic_secp256k1.cpp @@ -119,6 +119,18 @@ namespace fc { namespace ecc { return my->_key; } + public_key_point_data public_key::serialize_ecc_point()const + { + FC_ASSERT( my->_key != empty_pub ); + secp256k1_pubkey secp_pubkey; + FC_ASSERT( secp256k1_ec_pubkey_parse(detail::_get_context(), &secp_pubkey, (unsigned char*)my->_key.begin(), my->_key.size()) ); + public_key_point_data pubkey_point; + size_t pubkey_point_size = pubkey_point.size(); + secp256k1_ec_pubkey_serialize(detail::_get_context(), (unsigned char*)pubkey_point.begin(), &pubkey_point_size, &secp_pubkey, SECP256K1_EC_UNCOMPRESSED); + FC_ASSERT( pubkey_point.size() == pubkey_point_size ); + return pubkey_point; + } + public_key::public_key( const public_key_point_data& dat ) { const char* front = &dat.data[0]; diff --git a/test/crypto/test_cypher_suites.cpp b/test/crypto/test_cypher_suites.cpp index 2a421a82..479b9ca3 100644 --- a/test/crypto/test_cypher_suites.cpp +++ b/test/crypto/test_cypher_suites.cpp @@ -4,8 +4,12 @@ #include #include #include +#include +#include #include +#include + using namespace fc::crypto; using namespace fc; @@ -78,5 +82,33 @@ BOOST_AUTO_TEST_CASE(test_r1_recyle) try { BOOST_CHECK_EQUAL(pub.to_string(), recycled_pub.to_string()); } FC_LOG_AND_RETHROW(); +BOOST_AUTO_TEST_CASE(test_k1_serialize) try { + ecc::public_key_point_data pub_point; + auto pub_point_hex = std::string("04ad90e5b6bc86b3ec7fac2c5fbda7423fc8ef0d58df594c773fa05e2c281b2bfe877677c668bd13603944e34f4818ee03cadd81a88542b8b4d5431264180e2c28"); + from_hex(pub_point_hex, const_cast(&pub_point.data[0]), pub_point.size()); + + ecc::public_key_data pub; + auto pub_hex = std::string("02ad90e5b6bc86b3ec7fac2c5fbda7423fc8ef0d58df594c773fa05e2c281b2bfe"); + from_hex(pub_hex, const_cast(&pub.data[0]), pub.size()); + auto uncompressed = ecc::public_key(pub).serialize_ecc_point(); + + BOOST_CHECK(std::equal(const_cast(pub_point.begin()), const_cast(pub_point.end()), uncompressed.begin())); + +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(test_r1_serialize) try { + r1::public_key_point_data pub_point; + auto pub_point_hex = std::string("04413029cb9a5a4a0b087a9b8a060116d0d32bb22d14aebf7778215744811bb6ce40780d7bb9e2e068879f443e05b21b8fc0b62c9c811008064d988856077e35e7"); + from_hex(pub_point_hex, const_cast(&pub_point.data[0]), pub_point.size()); + + r1::public_key_data pub; + auto pub_hex = std::string("03413029cb9a5a4a0b087a9b8a060116d0d32bb22d14aebf7778215744811bb6ce"); + from_hex(pub_hex, const_cast(&pub.data[0]), pub.size()); + auto uncompressed = r1::public_key(pub).serialize_ecc_point(); + + BOOST_CHECK(std::equal(const_cast(pub_point.begin()), const_cast(pub_point.end()), uncompressed.begin())); + +} FC_LOG_AND_RETHROW(); + -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file +BOOST_AUTO_TEST_SUITE_END()