Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
fc::crypto::r1::public_key Class Reference

contains only the public point of an elliptic curve key. More...

#include <elliptic_r1.hpp>

Public Member Functions

 public_key ()
 
 public_key (const public_key &k)
 
 ~public_key ()
 
bool verify (const fc::sha256 &digest, const signature &sig)
 
public_key_data serialize () const
 
 operator public_key_data () const
 
 public_key (const public_key_data &v)
 
 public_key (const public_key_point_data &v)
 
 public_key (const compact_signature &c, const fc::sha256 &digest, bool check_canonical=true)
 
bool valid () const
 
public_key mult (const fc::sha256 &offset)
 
public_key add (const fc::sha256 &offset) const
 
 public_key (public_key &&pk)
 
public_keyoperator= (public_key &&pk)
 
public_keyoperator= (const public_key &pk)
 
std::string to_base58 () const
 Allows to convert current public key object into base58 number.
 

Static Public Member Functions

static public_key from_base58 (const std::string &b58)
 

Friends

class private_key
 
bool operator== (const public_key &a, const public_key &b)
 
bool operator!= (const public_key &a, const public_key &b)
 
compact_signature signature_from_ecdsa (const EC_KEY *key, const public_key_data &pub_data, fc::ecdsa_sig &sig, const fc::sha256 &d)
 

Detailed Description

Definition at line 32 of file elliptic_r1.hpp.

Constructor & Destructor Documentation

◆ public_key() [1/6]

fc::crypto::r1::public_key::public_key ( )

Definition at line 455 of file elliptic_r1.cpp.

456 {
457 }
Here is the caller graph for this function:

◆ public_key() [2/6]

fc::crypto::r1::public_key::public_key ( const public_key & k)

Definition at line 573 of file elliptic_r1.cpp.

574 :my(pk.my)
575 {
576 }

◆ ~public_key()

fc::crypto::r1::public_key::~public_key ( )

Definition at line 458 of file elliptic_r1.cpp.

459 {
460 }

◆ public_key() [3/6]

fc::crypto::r1::public_key::public_key ( const public_key_data & v)

Definition at line 474 of file elliptic_r1.cpp.

475 {
476 const char* front = &dat.data[0];
477 if( *front == 0 ){}
478 else
479 {
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) );
482 if( !my->_key )
483 {
484 FC_THROW_EXCEPTION( exception, "error decoding public key", ("s", ERR_error_string( ERR_get_error(), nullptr) ) );
485 }
486 }
487 }
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
fc::array< char, 33 > public_key_data

◆ public_key() [4/6]

fc::crypto::r1::public_key::public_key ( const public_key_point_data & v)

Definition at line 461 of file elliptic_r1.cpp.

462 {
463 const char* front = &dat.data[0];
464 if( *front == 0 ){}
465 else
466 {
467 my->_key = o2i_ECPublicKey( &my->_key, (const unsigned char**)&front, sizeof(dat) );
468 if( !my->_key )
469 {
470 FC_THROW_EXCEPTION( exception, "error decoding public key", ("s", ERR_error_string( ERR_get_error(), nullptr) ) );
471 }
472 }
473 }

◆ public_key() [5/6]

fc::crypto::r1::public_key::public_key ( const compact_signature & c,
const fc::sha256 & digest,
bool check_canonical = true )

Definition at line 516 of file elliptic_r1.cpp.

517 {
518 int nV = c.data[0];
519 if (nV<27 || nV>=35)
520 FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
521
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);
526 ECDSA_SIG_set0(sig, r, s);
527
528 my->_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
529
530 const EC_GROUP* group = EC_KEY_get0_group(my->_key);
531 ssl_bignum order, halforder;
532 EC_GROUP_get_order(group, order, nullptr);
533 BN_rshift1(halforder, order);
534 if(BN_cmp(s, halforder) > 0)
535 FC_THROW_EXCEPTION( exception, "invalid high s-value encountered in r1 signature" );
536
537 if (nV >= 31)
538 {
539 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
540 nV -= 4;
541// fprintf( stderr, "compressed\n" );
542 }
543
544 if (ECDSA_SIG_recover_key_GFp(my->_key, sig, (unsigned char*)&digest, sizeof(digest), nV - 27, 0) == 1)
545 return;
546 FC_THROW_EXCEPTION( exception, "unable to reconstruct public key from signature" );
547 }
const mie::Vuint & r
Definition bn.cpp:28
bignum_st BIGNUM
Definition bigint.hpp:7
int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check)
fc::sha256 digest(const T &value)
Definition digest.hpp:9
int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
char * s
Here is the call graph for this function:

◆ public_key() [6/6]

fc::crypto::r1::public_key::public_key ( public_key && pk)

Definition at line 577 of file elliptic_r1.cpp.

578 :my( fc::move( pk.my) )
579 {
580 }

Member Function Documentation

◆ add()

public_key fc::crypto::r1::public_key::add ( const fc::sha256 & offset) const

Definition at line 193 of file elliptic_em_impl_pub.cpp.

194 {
195 try {
196 ec_group group(EC_GROUP_new_by_curve_name(NID_secp256k1));
197 bn_ctx ctx(BN_CTX_new());
198
199 fc::bigint digest_bi( (char*)&digest, sizeof(digest) );
200
201 ssl_bignum order;
202 EC_GROUP_get_order(group, order, ctx);
203 if( digest_bi > fc::bigint(order) )
204 {
205 FC_THROW_EXCEPTION( exception, "digest > group order" );
206 }
207
208
210 const EC_POINT* digest_point = EC_KEY_get0_public_key( digest_key.my->_key );
211
212 // get point from this public key
213 const EC_POINT* master_pub = EC_KEY_get0_public_key( my->_key );
214
215// ssl_bignum z;
216// BN_bin2bn((unsigned char*)&digest, sizeof(digest), z);
217
218 // multiply by digest
219// ssl_bignum one;
220// BN_one(one);
221
222 ec_point result(EC_POINT_new(group));
223 EC_POINT_add(group, result, digest_point, master_pub, ctx);
224
225 if (EC_POINT_is_at_infinity(group, result))
226 {
227 FC_THROW_EXCEPTION( exception, "point at infinity" );
228 }
229
230
231 public_key rtn;
232 rtn.my->_key = EC_KEY_new_by_curve_name( NID_secp256k1 );
233 EC_KEY_set_public_key(rtn.my->_key,result);
234 return rtn;
235 } FC_RETHROW_EXCEPTIONS( debug, "digest: ${digest}", ("digest",digest) );
236 }
public_key get_public_key() const
static private_key regenerate(const fc::sha256 &secret)
bool debug
#define FC_RETHROW_EXCEPTIONS(LOG_LEVEL, FORMAT,...)
Catchs all exception's, std::exceptions, and ... and rethrows them after appending the provided log m...
Here is the call graph for this function:

◆ from_base58()

public_key fc::crypto::r1::public_key::from_base58 ( const std::string & b58)
static

Definition at line 318 of file elliptic_r1.cpp.

319 {
320 array<char, 37> data;
321 size_t s = fc::from_base58(b58, (char*)&data, sizeof(data) );
322 FC_ASSERT( s == sizeof(data) );
323
325 uint32_t check = (uint32_t)sha256::hash(data.data, sizeof(key))._hash[0];
326 FC_ASSERT( memcmp( (char*)&check, data.data + sizeof(key), sizeof(check) ) == 0 );
327 memcpy( (char*)key.data, data.data, sizeof(key) );
328 return public_key(key);
329 }
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
uint64_t _hash[4]
Definition sha256.hpp:100
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
std::vector< char > from_base58(const std::string &base58_str)
Definition base58.cpp:628
unsigned int uint32_t
Definition stdint.h:126
uint8_t key[16]
Definition yubico_otp.c:41
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:

◆ mult()

public_key fc::crypto::r1::public_key::mult ( const fc::sha256 & offset)

Definition at line 235 of file elliptic_r1.cpp.

236 {
237 // get point from this public key
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));
240
241 ssl_bignum z;
242 BN_bin2bn((unsigned char*)&digest, sizeof(digest), z);
243
244 // multiply by digest
245 ssl_bignum one;
246 BN_one(one);
247 bn_ctx ctx(BN_CTX_new());
248
249 ec_point result(EC_POINT_new(group));
250 EC_POINT_mul(group, result, z, master_pub, one, ctx);
251
252 public_key rtn;
253 rtn.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
254 EC_KEY_set_public_key(rtn.my->_key,result);
255
256 return rtn;
257 }
std::string one()
Here is the call graph for this function:

◆ operator public_key_data()

fc::crypto::r1::public_key::operator public_key_data ( ) const
inline

Definition at line 41 of file elliptic_r1.hpp.

41{ return serialize(); }
public_key_data serialize() const
Here is the call graph for this function:

◆ operator=() [1/2]

public_key & fc::crypto::r1::public_key::operator= ( const public_key & pk)

Definition at line 600 of file elliptic_r1.cpp.

601 {
602 if( my->_key )
603 {
604 EC_KEY_free(my->_key);
605 }
606 my->_key = EC_KEY_dup(pk.my->_key);
607 return *this;
608 }

◆ operator=() [2/2]

public_key & fc::crypto::r1::public_key::operator= ( public_key && pk)

Definition at line 590 of file elliptic_r1.cpp.

591 {
592 if( my->_key )
593 {
594 EC_KEY_free(my->_key);
595 }
596 my->_key = pk.my->_key;
597 pk.my->_key = nullptr;
598 return *this;
599 }

◆ serialize()

public_key_data fc::crypto::r1::public_key::serialize ( ) const

Definition at line 438 of file elliptic_r1.cpp.

439 {
440 public_key_data dat;
441 if( !my->_key ) return dat;
442 EC_KEY_set_conv_form( my->_key, POINT_CONVERSION_COMPRESSED );
443 /*size_t nbytes = i2o_ECPublicKey( my->_key, nullptr ); */
444 /*FC_ASSERT( nbytes == 33 )*/
445 char* front = &dat.data[0];
446 i2o_ECPublicKey( my->_key, (unsigned char**)&front );
447 return dat;
448 /*
449 EC_POINT* pub = EC_KEY_get0_public_key( my->_key );
450 EC_GROUP* group = EC_KEY_get0_group( my->_key );
451 EC_POINT_get_affine_coordinates_GFp( group, pub, self.my->_pub_x.get(), self.my->_pub_y.get(), nullptr );
452 */
453 }
Here is the caller graph for this function:

◆ to_base58()

std::string fc::crypto::r1::public_key::to_base58 ( ) const

Definition at line 307 of file elliptic_r1.cpp.

308 {
310 uint32_t check = (uint32_t)sha256::hash(key.data, sizeof(key))._hash[0];
311 static_assert(sizeof(key) + sizeof(check) == 37, ""); // hack around gcc bug: key.size() should be constexpr, but isn't
312 array<char, 37> data;
313 memcpy(data.data, key.begin(), key.size());
314 memcpy(data.begin() + key.size(), (const char*)&check, sizeof(check));
315 return fc::to_base58(data.begin(), data.size(), fc::yield_function_t());
316 }
std::string to_base58(const char *d, size_t s, const fc::yield_function_t &yield)
Definition base58.cpp:618
Here is the call graph for this function:

◆ valid()

bool fc::crypto::r1::public_key::valid ( ) const

Definition at line 258 of file elliptic_r1.cpp.

259 {
260 return my->_key != nullptr;
261 }
Here is the caller graph for this function:

◆ verify()

bool fc::crypto::r1::public_key::verify ( const fc::sha256 & digest,
const signature & sig )

Definition at line 433 of file elliptic_r1.cpp.

434 {
435 return 1 == ECDSA_verify( 0, (unsigned char*)&digest, sizeof(digest), (unsigned char*)&sig, sizeof(sig), my->_key );
436 }
Here is the call graph for this function:

Friends And Related Symbol Documentation

◆ operator!=

bool operator!= ( const public_key & a,
const public_key & b )
friend

Definition at line 60 of file elliptic_r1.hpp.

61 {
62 return a.serialize() != b.serialize();
63 }
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181

◆ operator==

bool operator== ( const public_key & a,
const public_key & b )
friend

Definition at line 56 of file elliptic_r1.hpp.

57 {
58 return a.serialize() == b.serialize();
59 }

◆ private_key

friend class private_key
friend

Definition at line 70 of file elliptic_r1.hpp.

◆ signature_from_ecdsa

compact_signature signature_from_ecdsa ( const EC_KEY * key,
const public_key_data & pub_data,
fc::ecdsa_sig & sig,
const fc::sha256 & d )
friend

Definition at line 136 of file elliptic_r1.cpp.

136 {
137 //We can't use ssl_bignum here; _get0() does not transfer ownership to us; _set0() does transfer ownership to fc::ecdsa_sig
138 const BIGNUM *sig_r, *sig_s;
139 BIGNUM *r = BN_new(), *s = BN_new();
140 ECDSA_SIG_get0(sig, &sig_r, &sig_s);
141 BN_copy(r, sig_r);
142 BN_copy(s, sig_s);
143
144 //want to always use the low S value
145 const EC_GROUP* group = EC_KEY_get0_group(key);
146 ssl_bignum order, halforder;
147 EC_GROUP_get_order(group, order, nullptr);
148 BN_rshift1(halforder, order);
149 if(BN_cmp(s, halforder) > 0)
150 BN_sub(s, order, s);
151
153
154 int nBitsR = BN_num_bits(r);
155 int nBitsS = BN_num_bits(s);
156 if(nBitsR > 256 || nBitsS > 256)
157 FC_THROW_EXCEPTION( exception, "Unable to sign" );
158
159 ECDSA_SIG_set0(sig, r, s);
160
161 int nRecId = -1;
162 for (int i=0; i<4; i++)
163 {
164 public_key keyRec;
165 keyRec.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
166 if (ECDSA_SIG_recover_key_GFp(keyRec.my->_key, sig, (unsigned char*)&d, sizeof(d), i, 1) == 1)
167 {
168 if (keyRec.serialize() == pub_data )
169 {
170 nRecId = i;
171 break;
172 }
173 }
174 }
175 if (nRecId == -1)
176 FC_THROW_EXCEPTION( exception, "unable to construct recoverable key");
177
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]);
181
182 return csig;
183 }
fc::array< unsigned char, 65 > compact_signature
void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)

The documentation for this class was generated from the following files: