Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
elliptic_common.cpp
Go to the documentation of this file.
3#include <fc/io/raw.hpp>
4#include <fc/crypto/hmac.hpp>
7
8#ifdef _WIN32
9# include <malloc.h>
10#elif defined(__FreeBSD__)
11# include <stdlib.h>
12#else
13# include <alloca.h>
14#endif
15
16/* stuff common to all ecc implementations */
17
18#define BTC_EXT_PUB_MAGIC (0x0488B21E)
19#define BTC_EXT_PRIV_MAGIC (0x0488ADE4)
20
21namespace fc { namespace ecc {
22
23 namespace detail {
25
27 {
28 fc::sha256 result;
29 memcpy( result.data(), v.data(), 32 );
30 return result;
31 }
32
34 {
35 fc::sha256 result;
36 memcpy( result.data(), v.data() + 32, 32 );
37 return result;
38 }
39
40 static void _put( unsigned char** dest, unsigned int i)
41 {
42 *(*dest)++ = (i >> 24) & 0xff;
43 *(*dest)++ = (i >> 16) & 0xff;
44 *(*dest)++ = (i >> 8) & 0xff;
45 *(*dest)++ = i & 0xff;
46 }
47
48
49 static chr37 _derive_message( char first, const char* key32, int i )
50 {
51 chr37 result;
52 unsigned char* dest = (unsigned char*) result.begin();
53 *dest++ = first;
54 memcpy( dest, key32, 32 ); dest += 32;
55 _put( &dest, i );
56 return result;
57 }
58
59 chr37 _derive_message( const public_key_data& key, int i )
60 {
61 return _derive_message( *key.begin(), key.begin() + 1, i );
62 }
63
64
65 const ec_group& get_curve()
66 {
67 static const ec_group secp256k1( EC_GROUP_new_by_curve_name( NID_secp256k1 ) );
68 return secp256k1;
69 }
70
71 static private_key_secret _get_curve_order()
72 {
73 const ec_group& group = get_curve();
74 bn_ctx ctx(BN_CTX_new());
75 ssl_bignum order;
76 FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
78 FC_ASSERT( BN_num_bytes( order ) == static_cast<int>(bin.data_size()) );
79 FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == static_cast<int>(bin.data_size()) );
80 return bin;
81 }
82
84 {
85 static private_key_secret order = _get_curve_order();
86 return order;
87 }
88
89 static private_key_secret _get_half_curve_order()
90 {
91 const ec_group& group = get_curve();
92 bn_ctx ctx(BN_CTX_new());
93 ssl_bignum order;
94 FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
95 BN_rshift1( order, order );
97 FC_ASSERT( BN_num_bytes( order ) == static_cast<int>(bin.data_size()) );
98 FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == static_cast<int>(bin.data_size()) );
99 return bin;
100 }
101
103 {
104 static private_key_secret half_order = _get_half_curve_order();
105 return half_order;
106 }
107 }
108
109 public_key public_key::from_key_data( const public_key_data &data ) {
110 return public_key(data);
111 }
112
114 {
117 fc::raw::pack( enc, offset );
118 return generate_from_seed( get_secret(), enc.result() );
119 }
120
121 std::string public_key::to_base58( const public_key_data &key )
122 {
123 uint32_t check = (uint32_t)sha256::hash(key.data, sizeof(key))._hash[0];
124 static_assert(sizeof(key) + sizeof(check) == 37, ""); // hack around gcc bug: key.size() should be constexpr, but isn't
125 array<char, 37> data;
126 memcpy(data.data, key.begin(), key.size());
127 memcpy(data.begin() + key.size(), (const char*)&check, sizeof(check));
128 return fc::to_base58(data.begin(), data.size(), fc::yield_function_t());
129 }
130
131 public_key public_key::from_base58( const std::string& b58 )
132 {
133 array<char, 37> data;
134 size_t s = fc::from_base58(b58, (char*)&data, sizeof(data) );
135 FC_ASSERT( s == sizeof(data) );
136
138 uint32_t check = (uint32_t)sha256::hash(data.data, sizeof(key))._hash[0];
139 FC_ASSERT( memcmp( (char*)&check, data.data + sizeof(key), sizeof(check) ) == 0 );
140 memcpy( (char*)key.data, data.data, sizeof(key) );
141 return from_key_data(key);
142 }
143
144 unsigned int public_key::fingerprint() const
145 {
147 ripemd160 hash = ripemd160::hash( sha256::hash( key.begin(), key.size() ) );
148 unsigned char* fp = (unsigned char*) hash._hash;
149 return (fp[0] << 24) | (fp[1] << 16) | (fp[2] << 8) | fp[3];
150 }
151
152 bool public_key::is_canonical( const compact_signature& c ) {
153 return !(c.data[1] & 0x80)
154 && !(c.data[1] == 0 && !(c.data[2] & 0x80))
155 && !(c.data[33] & 0x80)
156 && !(c.data[33] == 0 && !(c.data[34] & 0x80));
157 }
158
160 {
161 ssl_bignum z;
162 BN_bin2bn((unsigned char*)&offset, sizeof(offset), z);
163
164 ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
165 bn_ctx ctx(BN_CTX_new());
166 ssl_bignum order;
167 EC_GROUP_get_order(group, order, ctx);
168
169 // secexp = (seed + z) % order
170 ssl_bignum secexp;
171 BN_bin2bn((unsigned char*)&seed, sizeof(seed), secexp);
172 BN_add(secexp, secexp, z);
173 BN_mod(secexp, secexp, order, ctx);
174
175 fc::sha256 secret;
176 FC_ASSERT(BN_num_bytes(secexp) <= int64_t(sizeof(secret)));
177 auto shift = sizeof(secret) - BN_num_bytes(secexp);
178 BN_bn2bin(secexp, ((unsigned char*)&secret)+shift);
179 return regenerate( secret );
180 }
181
182 fc::sha256 private_key::get_secret( const EC_KEY * const k )
183 {
184 if( !k )
185 {
186 return fc::sha256();
187 }
188
189 fc::sha256 sec;
190 const BIGNUM* bn = EC_KEY_get0_private_key(k);
191 if( bn == NULL )
192 {
193 FC_THROW_EXCEPTION( exception, "get private key failed" );
194 }
195 int nbytes = BN_num_bytes(bn);
196 BN_bn2bin(bn, &((unsigned char*)&sec)[32-nbytes] );
197 return sec;
198 }
199
201 {
202 EC_KEY* k = EC_KEY_new_by_curve_name( NID_secp256k1 );
203 if( !k ) FC_THROW_EXCEPTION( exception, "Unable to generate EC key" );
204 if( !EC_KEY_generate_key( k ) )
205 {
206 FC_THROW_EXCEPTION( exception, "ecc key generation error" );
207
208 }
209
210 return private_key( k );
211 }
212
213
214}
215
216void to_variant( const ecc::private_key& var, variant& vo )
217{
218 vo = var.get_secret();
219}
220
221void from_variant( const variant& var, ecc::private_key& vo )
222{
223 fc::sha256 sec;
224 from_variant( var, sec );
226}
227
228void to_variant( const ecc::public_key& var, variant& vo )
229{
230 vo = var.serialize();
231}
232
233void from_variant( const variant& var, ecc::public_key& vo )
234{
236 from_variant( var, dat );
237 vo = ecc::public_key(dat);
238}
239
240}
T data[N]
Definition array.hpp:37
an elliptic curve private key.
Definition elliptic.hpp:88
static private_key generate()
public_key get_public_key() const
private_key_secret get_secret() const
private_key child(const fc::sha256 &offset) const
static private_key generate_from_seed(const fc::sha256 &seed, const fc::sha256 &offset=fc::sha256())
static private_key regenerate(const fc::sha256 &secret)
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.
unsigned int fingerprint() const
static public_key from_base58(const std::string &b58)
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
static ripemd160 hash(const fc::sha512 &h)
Definition ripemd160.cpp:44
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
const char * data() const
Definition sha256.cpp:31
size_t data_size() const
Definition sha256.hpp:23
uint64_t _hash[4]
Definition sha256.hpp:100
char * data()
Definition sha512.cpp:24
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
bignum_st BIGNUM
Definition bigint.hpp:7
Definition bn.h:56
const ec_group & get_curve()
const private_key_secret & get_curve_order()
fc::sha256 _right(const fc::sha512 &v)
fc::sha256 _left(const fc::sha512 &v)
fc::array< char, 37 > chr37
const private_key_secret & get_half_curve_order()
fc::array< char, 33 > public_key_data
Definition elliptic.hpp:22
void pack(Stream &s, const std::deque< T > &value)
Definition raw.hpp:531
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
std::vector< char > from_base58(const std::string &base58_str)
Definition base58.cpp:628
void from_variant(const fc::variant &v, sysio::chain::chain_id_type &cid)
void to_variant(const sysio::chain::shared_public_key &var, fc::variant &vo)
Definition authority.cpp:4
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
uint8_t key[16]
Definition yubico_otp.c:41
char * s
memcpy((char *) pInfo->slotDescription, s, l)