2#include <boost/config.hpp>
8namespace fc {
namespace em {
35 if (pk._key ==
nullptr)
38 }
else if ( _key ==
nullptr ) {
39 _key = EC_KEY_dup( pk._key );
41 EC_KEY_copy( _key, pk._key );
56 void public_key_impl::free_key() BOOST_NOEXCEPT
69 const unsigned char *msg,
70 int msglen,
int recid,
int check)
91 const EC_GROUP *group = EC_KEY_get0_group(eckey);
92 if ((ctx = BN_CTX_new()) == NULL) {
ret = -1;
goto err; }
94 order = BN_CTX_get(ctx);
95 if (!EC_GROUP_get_order(group, order, ctx)) {
ret = -2;
goto err; }
97 if (!BN_copy(x, order)) {
ret=-1;
goto err; }
98 if (!BN_mul_word(x, i)) {
ret=-1;
goto err; }
99 if (!BN_add(x, x, ecsig->r)) {
ret=-1;
goto err; }
100 field = BN_CTX_get(ctx);
101 if (!EC_GROUP_get_curve_GFp(group,
field, NULL, NULL, ctx)) {
ret=-2;
goto err; }
102 if (BN_cmp(x,
field) >= 0) {
ret=0;
goto err; }
103 if ((
R = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
104 if (!EC_POINT_set_compressed_coordinates_GFp(group,
R, x, recid % 2, ctx)) {
ret=0;
goto err; }
107 if ((O = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
108 if (!EC_POINT_mul(group, O, NULL,
R, order, ctx)) {
ret=-2;
goto err; }
109 if (!EC_POINT_is_at_infinity(group, O)) {
ret = 0;
goto err; }
111 if ((Q = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
112 n = EC_GROUP_get_degree(group);
114 if (!BN_bin2bn(msg, msglen, e)) {
ret=-1;
goto err; }
115 if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
116 zero = BN_CTX_get(ctx);
117 if (!BN_zero(zero)) {
ret=-1;
goto err; }
118 if (!BN_mod_sub(e, zero, e, order, ctx)) {
ret=-1;
goto err; }
119 rr = BN_CTX_get(ctx);
120 if (!BN_mod_inverse(rr, ecsig->r, order, ctx)) {
ret=-1;
goto err; }
121 sor = BN_CTX_get(ctx);
122 if (!BN_mod_mul(sor, ecsig->s, rr, order, ctx)) {
ret=-1;
goto err; }
123 eor = BN_CTX_get(ctx);
124 if (!BN_mod_mul(eor, e, rr, order, ctx)) {
ret=-1;
goto err; }
125 if (!EC_POINT_mul(group, Q, eor,
R, sor, ctx)) {
ret=-2;
goto err; }
126 if (!EC_KEY_set_public_key(eckey, Q)) {
ret=-2;
goto err; }
135 if (
R != NULL) EC_POINT_free(
R);
136 if (O != NULL) EC_POINT_free(O);
137 if (Q != NULL) EC_POINT_free(Q);
152 my = std::move(pk.my);
164 return my->_key !=
nullptr;
196 ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
197 bn_ctx ctx(BN_CTX_new());
202 EC_GROUP_get_order(group, order, ctx);
210 const EC_POINT* digest_point = EC_KEY_get0_public_key( digest_key.my->_key );
213 const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key );
222 ec_point result(EC_POINT_new(group));
223 EC_POINT_add(group, result, digest_point, master_pub, ctx);
225 if (EC_POINT_is_at_infinity(group, result))
232 rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
233 EC_KEY_set_public_key(rtn.my->_key,result);
269 if( !my->_key )
return dat;
270 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
273 char* front = &dat.data[0];
274 i2o_ECPublicKey( my->_key, (
unsigned char**)&front );
285 if( !my->_key )
return dat;
286 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_UNCOMPRESSED );
287 char* front = &dat.
data[0];
288 i2o_ECPublicKey( my->_key, (
unsigned char**)&front );
294 const char* front = &dat.
data[0];
298 my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
299 my->_key = o2i_ECPublicKey( &my->_key, (
const unsigned char**)&front,
sizeof(dat) );
308 const char* front = &dat.data[0];
312 my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
313 my->_key = o2i_ECPublicKey( &my->_key, (
const unsigned char**)&front,
sizeof(
public_key_data) );
316 FC_THROW_EXCEPTION( exception,
"error decoding public key", (
"s", ERR_error_string( ERR_get_error(),
nullptr) ) );
332 ECDSA_SIG *sig = ECDSA_SIG_new();
333 BN_bin2bn(&c.data[1],32,sig->r);
334 BN_bin2bn(&c.data[33],32,sig->s);
336 if( check_canonical )
338 FC_ASSERT( is_canonical( c ),
"signature is not canonical" );
341 my->_key = EC_KEY_new_by_curve_name(NID_secp256k1);
345 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
contains only the public point of an elliptic curve key.
public_key_impl & operator=(const public_key_impl &pk) BOOST_NOEXCEPT
static int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
~public_key_impl() BOOST_NOEXCEPT
public_key_impl() BOOST_NOEXCEPT
public_key get_public_key() const
static private_key regenerate(const fc::sha256 &secret)
std::string to_base58() const
Allows to convert current public key object into base58 number.
public_key & operator=(public_key &&pk)
public_key_point_data serialize_ecc_point() const
public_key_data serialize() const
Used to generate a useful error report when an exception is thrown.
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
fc::array< char, 33 > public_key_data
fc::array< unsigned char, 65 > compact_signature
std::string to_base58(const char *d, size_t s, const fc::yield_function_t &yield)
fc::sha256 digest(const T &value)