Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
elliptic_secp256k1.cpp
Go to the documentation of this file.
2
4#include <fc/crypto/hmac.hpp>
7
8#include <fc/fwd_impl.hpp>
10#include <fc/log/logger.hpp>
11
12#include <secp256k1.h>
13#include <secp256k1_recovery.h>
14
15#if _WIN32
16# include <malloc.h>
17#elif defined(__FreeBSD__)
18# include <stdlib.h>
19#else
20# include <alloca.h>
21#endif
22
24
25namespace fc { namespace ecc {
26 namespace detail
27 {
30 return ctx;
31 }
32
33 void _init_lib() {
34 static const secp256k1_context* ctx = _get_context();
35 (void)ctx;
36 }
37
39 {
40 public:
41 public_key_impl() BOOST_NOEXCEPT
42 {
43 _init_lib();
44 }
45
46 public_key_impl( const public_key_impl& cpy ) BOOST_NOEXCEPT
47 : _key( cpy._key )
48 {
49 _init_lib();
50 }
51
53 };
54
56 chr37 _derive_message( const public_key_data& key, int i );
57 fc::sha256 _left( const fc::sha512& v );
58 fc::sha256 _right( const fc::sha512& v );
59 const ec_group& get_curve();
62 }
63
64 static const public_key_data empty_pub;
65
66
68 {
69 static const private_key_secret empty_priv;
70 FC_ASSERT( my->_key != empty_priv );
71 FC_ASSERT( other.my->_key != empty_pub );
72 secp256k1_pubkey secp_pubkey;
73 FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &secp_pubkey, (unsigned char*)other.serialize().data, other.serialize().size() ) );
74 FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), &secp_pubkey, (unsigned char*) my->_key.data() ) );
75 public_key_data serialized_result;
76 size_t serialized_result_sz = sizeof(serialized_result);
77 secp256k1_ec_pubkey_serialize(detail::_get_context(), (unsigned char*)&serialized_result.data, &serialized_result_sz, &secp_pubkey, SECP256K1_EC_COMPRESSED );
78 FC_ASSERT( serialized_result_sz == sizeof(serialized_result) );
79 return fc::sha512::hash( serialized_result.begin() + 1, serialized_result.size() - 1 );
80 }
81
82
84
85 public_key::public_key( const public_key &pk ) : my( pk.my ) {}
86
87 public_key::public_key( public_key &&pk ) : my( std::move( pk.my ) ) {}
88
90
91 public_key& public_key::operator=( const public_key& pk )
92 {
93 my = pk.my;
94 return *this;
95 }
96
97 public_key& public_key::operator=( public_key&& pk )
98 {
99 my = pk.my;
100 return *this;
101 }
102
103 bool public_key::valid()const
104 {
105 return my->_key != empty_pub;
106 }
107
108 std::string public_key::to_base58() const
109 {
110 FC_ASSERT( my->_key != empty_pub );
111 return to_base58( my->_key );
112 }
113
115 {
116 FC_ASSERT( my->_key != empty_pub );
117 return my->_key;
118 }
119
121 {
122 const char* front = &dat.data[0];
123 if( *front == 0 ){}
124 else
125 {
126 EC_KEY *key = EC_KEY_new_by_curve_name( NID_secp256k1 );
127 key = o2i_ECPublicKey( &key, (const unsigned char**)&front, sizeof(dat) );
128 FC_ASSERT( key );
129 EC_KEY_set_conv_form( key, POINT_CONVERSION_COMPRESSED );
130 unsigned char* buffer = (unsigned char*) my->_key.begin();
131 i2o_ECPublicKey( key, &buffer ); // FIXME: questionable memory handling
132 EC_KEY_free( key );
133 }
134 }
135
137 {
138 my->_key = dat;
139 }
140
141 public_key::public_key( const compact_signature& c, const fc::sha256& digest, bool check_canonical )
142 {
143 int nV = c.data[0];
144 if (nV<27 || nV>=35)
145 FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
146
147 if( check_canonical )
148 {
149 FC_ASSERT( is_canonical( c ), "signature is not canonical" );
150 }
151
152 secp256k1_pubkey secp_pub;
154
155 FC_ASSERT( secp256k1_ecdsa_recoverable_signature_parse_compact( detail::_get_context(), &secp_sig, (unsigned char*)c.begin() + 1, (*c.begin() - 27) & 3) );
156 FC_ASSERT( secp256k1_ecdsa_recover( detail::_get_context(), &secp_pub, &secp_sig, (unsigned char*) digest.data() ) );
157
158 size_t serialized_result_sz = my->_key.size();
159 secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char*)&my->_key.data, &serialized_result_sz, &secp_pub, SECP256K1_EC_COMPRESSED );
160 FC_ASSERT( serialized_result_sz == my->_key.size() );
161 }
162
163} }
size_t size() const
Definition array.hpp:35
const T * begin() const
Definition array.hpp:29
T data[N]
Definition array.hpp:37
public_key_impl(const public_key_impl &cpy) BOOST_NOEXCEPT
fc::sha512 get_shared_secret(const public_key &pub) const
contains only the public point of an elliptic curve key.
Definition elliptic.hpp:36
public_key_data serialize() const
std::string to_base58() const
Allows to convert current public key object into base58 number.
public_key & operator=(public_key &&pk)
const char * data() const
Definition sha256.cpp:31
static sha512 hash(const char *d, uint32_t dlen)
Definition sha512.cpp:37
Defines exception's used by fc.
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
const ec_group & get_curve()
chr37 _derive_message(const public_key_data &key, int i)
const private_key_secret & get_curve_order()
fc::sha256 _right(const fc::sha512 &v)
const secp256k1_context * _get_context()
fc::sha256 _left(const fc::sha512 &v)
fc::array< char, 37 > chr37
const private_key_secret & get_half_curve_order()
fc::array< char, 65 > public_key_point_data
the full non-compressed version of the ECC point
Definition elliptic.hpp:24
fc::array< unsigned char, 65 > compact_signature
Definition elliptic.hpp:26
fc::array< char, 33 > public_key_data
Definition elliptic.hpp:22
namespace sysio::chain
Definition authority.cpp:3
std::string to_base58(const char *d, size_t s, const fc::yield_function_t &yield)
Definition base58.cpp:618
fc::sha256 digest(const T &value)
Definition digest.hpp:9
Definition name.hpp:106
#define SECP256K1_CONTEXT_SIGN
Definition secp256k1.h:196
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Definition secp256k1.c:246
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Definition secp256k1.c:107
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Definition secp256k1.c:228
#define SECP256K1_EC_COMPRESSED
Definition secp256k1.h:201
#define SECP256K1_CONTEXT_VERIFY
Definition secp256k1.h:195
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_tweak_mul(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *tweak32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Definition secp256k1.c:683
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Definition main_impl.h:38
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msghash32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Definition main_impl.h:137