10namespace fc {
namespace crypto {
namespace r1 {
50 static void * ecies_key_derivation(
const void *input,
size_t ilen,
void *output,
size_t *olen)
52 if (*olen < SHA512_DIGEST_LENGTH) {
55 *olen = SHA512_DIGEST_LENGTH;
56 return (
void*)SHA512((
const unsigned char*)input, ilen, (
unsigned char*)output);
86 const EC_GROUP *group = EC_KEY_get0_group(eckey);
87 if ((ctx = BN_CTX_new()) == NULL) {
ret = -1;
goto err; }
89 order = BN_CTX_get(ctx);
90 if (!EC_GROUP_get_order(group, order, ctx)) {
ret = -2;
goto err; }
92 if (!BN_copy(x, order)) {
ret=-1;
goto err; }
93 if (!BN_mul_word(x, i)) {
ret=-1;
goto err; }
94 if (!BN_add(x, x,
r)) {
ret=-1;
goto err; }
95 field = BN_CTX_get(ctx);
96 if (!EC_GROUP_get_curve_GFp(group,
field, NULL, NULL, ctx)) {
ret=-2;
goto err; }
97 if (BN_cmp(x,
field) >= 0) {
ret=0;
goto err; }
98 if ((
R = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
99 if (!EC_POINT_set_compressed_coordinates_GFp(group,
R, x, recid % 2, ctx)) {
ret=0;
goto err; }
102 if ((O = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
103 if (!EC_POINT_mul(group, O, NULL,
R, order, ctx)) {
ret=-2;
goto err; }
104 if (!EC_POINT_is_at_infinity(group, O)) {
ret = 0;
goto err; }
106 if ((Q = EC_POINT_new(group)) == NULL) {
ret = -2;
goto err; }
107 n = EC_GROUP_get_degree(group);
109 if (!BN_bin2bn(msg, msglen, e)) {
ret=-1;
goto err; }
110 if (8*msglen > n) BN_rshift(e, e, 8-(n & 7));
111 zero = BN_CTX_get(ctx);
113 if (!BN_mod_sub(e, zero, e, order, ctx)) {
ret=-1;
goto err; }
114 rr = BN_CTX_get(ctx);
115 if (!BN_mod_inverse(rr,
r, order, ctx)) {
ret=-1;
goto err; }
116 sor = BN_CTX_get(ctx);
117 if (!BN_mod_mul(sor,
s, rr, order, ctx)) {
ret=-1;
goto err; }
118 eor = BN_CTX_get(ctx);
119 if (!BN_mod_mul(eor, e, rr, order, ctx)) {
ret=-1;
goto err; }
120 if (!EC_POINT_mul(group, Q, eor,
R, sor, ctx)) {
ret=-2;
goto err; }
121 if (!EC_KEY_set_public_key(eckey, Q)) {
ret=-2;
goto err; }
130 if (
R != NULL) EC_POINT_free(
R);
131 if (O != NULL) EC_POINT_free(O);
132 if (Q != NULL) EC_POINT_free(Q);
138 const BIGNUM *sig_r, *sig_s;
139 BIGNUM *
r = BN_new(), *
s = BN_new();
145 const EC_GROUP* group = EC_KEY_get0_group(key);
147 EC_GROUP_get_order(group, order,
nullptr);
148 BN_rshift1(halforder, order);
149 if(BN_cmp(
s, halforder) > 0)
154 int nBitsR = BN_num_bits(
r);
155 int nBitsS = BN_num_bits(
s);
156 if(nBitsR > 256 || nBitsS > 256)
162 for (
int i=0; i<4; i++)
165 keyRec.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
178 csig.
data[0] = nRecId+27+4;
179 BN_bn2bin(
r,&csig.
data[33-(nBitsR+7)/8]);
180 BN_bn2bin(
s,&csig.
data[65-(nBitsS+7)/8]);
185 int static inline EC_KEY_regenerate_key(EC_KEY *eckey,
const BIGNUM *priv_key)
189 EC_POINT *pub_key = NULL;
191 if (!eckey)
return 0;
193 const EC_GROUP *group = EC_KEY_get0_group(eckey);
195 if ((ctx = BN_CTX_new()) == NULL)
198 pub_key = EC_POINT_new(group);
203 if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx))
206 EC_KEY_set_private_key(eckey,priv_key);
207 EC_KEY_set_public_key(eckey,pub_key);
213 if (pub_key) EC_POINT_free(pub_key);
214 if (ctx != NULL) BN_CTX_free(ctx);
238 const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key );
239 ec_group group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
247 bn_ctx ctx(BN_CTX_new());
249 ec_point result(EC_POINT_new(group));
250 EC_POINT_mul(group, result, z, master_pub,
one, ctx);
253 rtn.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
254 EC_KEY_set_public_key(rtn.my->_key,result);
260 return my->_key !=
nullptr;
265 ec_group group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
266 bn_ctx ctx(BN_CTX_new());
271 EC_GROUP_get_order(group, order, ctx);
279 const EC_POINT* digest_point = EC_KEY_get0_public_key( digest_key.my->_key );
282 const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key );
291 ec_point result(EC_POINT_new(group));
292 EC_POINT_add(group, result, digest_point, master_pub, ctx);
294 if (EC_POINT_is_at_infinity(group, result))
301 rtn.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
302 EC_KEY_set_public_key(rtn.my->_key,result);
311 static_assert(
sizeof(
key) +
sizeof(check) == 37,
"");
313 memcpy(data.data, key.begin(), key.size());
314 memcpy(data.begin() + key.size(), (
const char*)&check,
sizeof(check));
326 FC_ASSERT( memcmp( (
char*)&check, data.data +
sizeof(key),
sizeof(check) ) == 0 );
327 memcpy( (
char*)key.data, data.data,
sizeof(key) );
337 BN_bin2bn((
unsigned char*)&offset,
sizeof(offset), z);
339 ec_group group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
340 bn_ctx ctx(BN_CTX_new());
342 EC_GROUP_get_order(group, order, ctx);
346 BN_bin2bn((
unsigned char*)&seed,
sizeof(seed), secexp);
347 BN_add(secexp, secexp, z);
348 BN_mod(secexp, secexp, order, ctx);
352 auto shift =
sizeof(secret) - BN_num_bytes(secexp);
353 BN_bn2bin(secexp, ((
unsigned char*)&secret)+shift);
360 self.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
364 BN_bin2bn( (
const unsigned char*)&secret, 32,
bn );
366 if( !EC_KEY_regenerate_key(self.my->_key,
bn) )
381 const BIGNUM*
bn = EC_KEY_get0_private_key(my->_key);
386 int nbytes = BN_num_bytes(
bn);
387 BN_bn2bin(
bn, &((
unsigned char*)&sec)[32-nbytes] );
394 EC_KEY* k = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
397 if( !EC_KEY_generate_key( self.my->_key ) )
404 =
bigint( EC_KEY_get0_private_key( k );
405 EC_POINT*
pub = EC_KEY_get0_public_key( k );
406 EC_GROUP* group = EC_KEY_get0_group( k );
408 EC_POINT_get_affine_coordinates_GFp( group,
pub, self.my->_pub_x.get(), self.my->_pub_y.get(),
nullptr );
418 unsigned int buf_len = ECDSA_size(my->_key);
425 (
unsigned char*)&sig, &buf_len, my->_key ) )
435 return 1 == ECDSA_verify( 0, (
unsigned char*)&
digest,
sizeof(
digest), (
unsigned char*)&sig,
sizeof(sig), my->_key );
441 if( !my->_key )
return dat;
442 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
445 char* front = &dat.
data[0];
446 i2o_ECPublicKey( my->_key, (
unsigned char**)&front );
463 const char* front = &dat.
data[0];
467 my->_key = o2i_ECPublicKey( &my->_key, (
const unsigned char**)&front,
sizeof(dat) );
470 FC_THROW_EXCEPTION( exception,
"error decoding public key", (
"s", ERR_error_string( ERR_get_error(),
nullptr) ) );
476 const char* front = &dat.
data[0];
480 my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
481 my->_key = o2i_ECPublicKey( &my->_key, (
const unsigned char**)&front,
sizeof(
public_key_data) );
484 FC_THROW_EXCEPTION( exception,
"error decoding public key", (
"s", ERR_error_string( ERR_get_error(),
nullptr) ) );
491 return 1 == ECDSA_verify( 0, (
unsigned char*)&
digest,
sizeof(
digest), (
unsigned char*)&sig,
sizeof(sig), my->_key );
497 pub.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
498 EC_KEY_set_public_key(
pub.my->_key, EC_KEY_get0_public_key( my->_key ) );
508 ECDH_compute_key( (
unsigned char*)&
buf,
sizeof(
buf), EC_KEY_get0_public_key(other.my->_key), my->_key, ecies_key_derivation );
522 ecdsa_sig sig = ECDSA_SIG_new();
523 BIGNUM *
r = BN_new(), *
s = BN_new();
524 BN_bin2bn(&c.
data[1],32,
r);
525 BN_bin2bn(&c.
data[33],32,
s);
528 my->_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
530 const EC_GROUP* group = EC_KEY_get0_group(my->_key);
532 EC_GROUP_get_order(group, order,
nullptr);
533 BN_rshift1(halforder, order);
534 if(BN_cmp(
s, halforder) > 0)
539 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
554 ecdsa_sig sig = ECDSA_do_sign((
unsigned char*)&
digest,
sizeof(
digest), my->_key);
567 EC_KEY_free(my->_key);
569 my->_key = pk.my->_key;
570 pk.my->_key =
nullptr;
578 :my(
fc::move( pk.my) )
586 :my(
fc::move( pk.my) )
594 EC_KEY_free(my->_key);
596 my->_key = pk.my->_key;
597 pk.my->_key =
nullptr;
604 EC_KEY_free(my->_key);
606 my->_key = EC_KEY_dup(pk.my->_key);
613 EC_KEY_free(my->_key);
615 my->_key = EC_KEY_dup(pk.my->_key);
private_key_impl(const private_key_impl &cpy)
public_key_impl(const public_key_impl &cpy)
an elliptic curve private key.
bool verify(const fc::sha256 &digest, const signature &sig)
signature sign(const fc::sha256 &digest) const
static private_key generate_from_seed(const fc::sha256 &seed, const fc::sha256 &offset=fc::sha256())
private_key_secret get_secret() const
public_key get_public_key() const
fc::sha512 get_shared_secret(const public_key &pub) const
compact_signature sign_compact(const fc::sha256 &digest) const
static private_key regenerate(const fc::sha256 &secret)
static private_key generate()
private_key & operator=(private_key &&pk)
contains only the public point of an elliptic curve key.
public_key & operator=(public_key &&pk)
bool verify(const fc::sha256 &digest, const signature &sig)
public_key add(const fc::sha256 &offset) const
static public_key from_base58(const std::string &b58)
public_key_data serialize() const
std::string to_base58() const
Allows to convert current public key object into base58 number.
public_key mult(const fc::sha256 &offset)
static sha256 hash(const char *d, uint32_t dlen)
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
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.
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
compact_signature signature_from_ecdsa(const EC_KEY *key, const public_key_data &pub, fc::ecdsa_sig &sig, const fc::sha256 &d)
std::string to_base58(const char *d, size_t s, const fc::yield_function_t &yield)
fc::sha256 digest(const T &value)
std::vector< char > from_base58(const std::string &base58_str)
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)
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
memcpy((char *) pInfo->slotDescription, s, l)