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

an elliptic curve private key. More...

#include <elliptic_r1.hpp>

Public Member Functions

 private_key ()
 
 private_key (private_key &&pk)
 
 private_key (const private_key &pk)
 
 ~private_key ()
 
private_keyoperator= (private_key &&pk)
 
private_keyoperator= (const private_key &pk)
 
private_key_secret get_secret () const
 
 operator private_key_secret () const
 
fc::sha512 get_shared_secret (const public_key &pub) const
 
signature sign (const fc::sha256 &digest) const
 
compact_signature sign_compact (const fc::sha256 &digest) const
 
bool verify (const fc::sha256 &digest, const signature &sig)
 
public_key get_public_key () const
 

Static Public Member Functions

static private_key generate ()
 
static private_key regenerate (const fc::sha256 &secret)
 
static private_key generate_from_seed (const fc::sha256 &seed, const fc::sha256 &offset=fc::sha256())
 

Friends

bool operator== (const private_key &a, const private_key &b)
 
bool operator!= (const private_key &a, const private_key &b)
 
bool operator< (const private_key &a, const private_key &b)
 

Detailed Description

Definition at line 79 of file elliptic_r1.hpp.

Constructor & Destructor Documentation

◆ private_key() [1/3]

fc::crypto::r1::private_key::private_key ( )

Definition at line 331 of file elliptic_r1.cpp.

332 {}

◆ private_key() [2/3]

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

Definition at line 585 of file elliptic_r1.cpp.

586 :my( fc::move( pk.my) )
587 {
588 }

◆ private_key() [3/3]

fc::crypto::r1::private_key::private_key ( const private_key & pk)

Definition at line 581 of file elliptic_r1.cpp.

582 :my(pk.my)
583 {
584 }

◆ ~private_key()

fc::crypto::r1::private_key::~private_key ( )

Definition at line 512 of file elliptic_r1.cpp.

513 {
514 }

Member Function Documentation

◆ generate()

private_key fc::crypto::r1::private_key::generate ( )
static

Definition at line 391 of file elliptic_r1.cpp.

392 {
394 EC_KEY* k = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
395 if( !k ) FC_THROW_EXCEPTION( exception, "Unable to generate EC key" );
396 self.my->_key = k;
397 if( !EC_KEY_generate_key( self.my->_key ) )
398 {
399 FC_THROW_EXCEPTION( exception, "ecc key generation error" );
400
401 }
402
403#if 0
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 );
407
408 EC_POINT_get_affine_coordinates_GFp( group, pub, self.my->_pub_x.get(), self.my->_pub_y.get(), nullptr/*ctx*/ );
409
410 EC_KEY_free(k);
411#endif
412
413 return self;
414 }
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
@ self
the connection is to itself
Definition protocol.hpp:48
bool pub
Here is the caller graph for this function:

◆ generate_from_seed()

private_key fc::crypto::r1::private_key::generate_from_seed ( const fc::sha256 & seed,
const fc::sha256 & offset = fc::sha256() )
static

This method of generation enables creating a new private key in a deterministic manner relative to an initial seed. A public_key created from the seed can be multiplied by the offset to calculate the new public key without having to know the private key.

Definition at line 334 of file elliptic_r1.cpp.

335 {
336 ssl_bignum z;
337 BN_bin2bn((unsigned char*)&offset, sizeof(offset), z);
338
339 ec_group group(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
340 bn_ctx ctx(BN_CTX_new());
341 ssl_bignum order;
342 EC_GROUP_get_order(group, order, ctx);
343
344 // secexp = (seed + z) % order
345 ssl_bignum secexp;
346 BN_bin2bn((unsigned char*)&seed, sizeof(seed), secexp);
347 BN_add(secexp, secexp, z);
348 BN_mod(secexp, secexp, order, ctx);
349
350 fc::sha256 secret;
351 FC_ASSERT(BN_num_bytes(secexp) <= int64_t(sizeof(secret)));
352 auto shift = sizeof(secret) - BN_num_bytes(secexp);
353 BN_bn2bin(secexp, ((unsigned char*)&secret)+shift);
354 return regenerate( secret );
355 }
static private_key regenerate(const fc::sha256 &secret)
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
signed __int64 int64_t
Definition stdint.h:135
Here is the call graph for this function:

◆ get_public_key()

public_key fc::crypto::r1::private_key::get_public_key ( ) const

Definition at line 494 of file elliptic_r1.cpp.

495 {
496 public_key pub;
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 ) );
499 return pub;
500 }
Here is the caller graph for this function:

◆ get_secret()

fc::sha256 fc::crypto::r1::private_key::get_secret ( ) const

Definition at line 373 of file elliptic_r1.cpp.

374 {
375 if( !my->_key )
376 {
377 return fc::sha256();
378 }
379
380 fc::sha256 sec;
381 const BIGNUM* bn = EC_KEY_get0_private_key(my->_key);
382 if( bn == NULL )
383 {
384 FC_THROW_EXCEPTION( exception, "get private key failed" );
385 }
386 int nbytes = BN_num_bytes(bn);
387 BN_bn2bin(bn, &((unsigned char*)&sec)[32-nbytes] );
388 return sec;
389 }
bignum_st BIGNUM
Definition bigint.hpp:7
Definition bn.h:56
Here is the caller graph for this function:

◆ get_shared_secret()

fc::sha512 fc::crypto::r1::private_key::get_shared_secret ( const public_key & pub) const

Given a public key, calculatse a 512 bit shared secret between that key and this private key.

Definition at line 503 of file elliptic_r1.cpp.

504 {
505 FC_ASSERT( my->_key != nullptr );
506 FC_ASSERT( other.my->_key != nullptr );
508 ECDH_compute_key( (unsigned char*)&buf, sizeof(buf), EC_KEY_get0_public_key(other.my->_key), my->_key, ecies_key_derivation );
509 return buf;
510 }
uint8_t buf[2048]
Here is the caller graph for this function:

◆ operator private_key_secret()

fc::crypto::r1::private_key::operator private_key_secret ( ) const
inline

Definition at line 102 of file elliptic_r1.hpp.

102{ return get_secret(); }
private_key_secret get_secret() const
Here is the call graph for this function:

◆ operator=() [1/2]

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

Definition at line 609 of file elliptic_r1.cpp.

610 {
611 if( my->_key )
612 {
613 EC_KEY_free(my->_key);
614 }
615 my->_key = EC_KEY_dup(pk.my->_key);
616 return *this;
617 }

◆ operator=() [2/2]

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

Definition at line 563 of file elliptic_r1.cpp.

564 {
565 if( my->_key )
566 {
567 EC_KEY_free(my->_key);
568 }
569 my->_key = pk.my->_key;
570 pk.my->_key = nullptr;
571 return *this;
572 }

◆ regenerate()

private_key fc::crypto::r1::private_key::regenerate ( const fc::sha256 & secret)
static

Definition at line 357 of file elliptic_r1.cpp.

358 {
360 self.my->_key = EC_KEY_new_by_curve_name( NID_X9_62_prime256v1 );
361 if( !self.my->_key ) FC_THROW_EXCEPTION( exception, "Unable to generate EC key" );
362
363 ssl_bignum bn;
364 BN_bin2bn( (const unsigned char*)&secret, 32, bn );
365
366 if( !EC_KEY_regenerate_key(self.my->_key,bn) )
367 {
368 FC_THROW_EXCEPTION( exception, "unable to regenerate key" );
369 }
370 return self;
371 }
Here is the caller graph for this function:

◆ sign()

signature fc::crypto::r1::private_key::sign ( const fc::sha256 & digest) const

Definition at line 416 of file elliptic_r1.cpp.

417 {
418 unsigned int buf_len = ECDSA_size(my->_key);
419// fprintf( stderr, "%d %d\n", buf_len, sizeof(sha256) );
420 signature sig;
421 FC_ASSERT( buf_len == sizeof(sig) );
422
423 if( !ECDSA_sign( 0,
424 (const unsigned char*)&digest, sizeof(digest),
425 (unsigned char*)&sig, &buf_len, my->_key ) )
426 {
427 FC_THROW_EXCEPTION( exception, "signing error" );
428 }
429
430
431 return sig;
432 }
fc::array< char, 72 > signature
fc::sha256 digest(const T &value)
Definition digest.hpp:9
Here is the call graph for this function:

◆ sign_compact()

compact_signature fc::crypto::r1::private_key::sign_compact ( const fc::sha256 & digest) const

Definition at line 178 of file elliptic_openssl.cpp.

179 {
180 try {
181 FC_ASSERT( my->_key != nullptr );
182 auto my_pub_key = get_public_key().serialize(); // just for good measure
183 //ECDSA_SIG *sig = ECDSA_do_sign((unsigned char*)&digest, sizeof(digest), my->_key);
184 public_key_data key_data;
185 while( true )
186 {
187 ecdsa_sig sig = ECDSA_do_sign((unsigned char*)&digest, sizeof(digest), my->_key);
188
189 if (sig==nullptr)
190 FC_THROW_EXCEPTION( exception, "Unable to sign" );
191
193 // memset( csig.data, 0, sizeof(csig) );
194
195 int nBitsR = BN_num_bits(sig->r);
196 int nBitsS = BN_num_bits(sig->s);
197 if (nBitsR <= 256 && nBitsS <= 256)
198 {
199 int nRecId = -1;
200 EC_KEY* key = EC_KEY_new_by_curve_name( NID_secp256k1 );
201 FC_ASSERT( key );
202 EC_KEY_set_conv_form( key, POINT_CONVERSION_COMPRESSED );
203 for (int i=0; i<4; i++)
204 {
205 if (detail::public_key_impl::ECDSA_SIG_recover_key_GFp(key, sig, (unsigned char*)&digest, sizeof(digest), i, 1) == 1)
206 {
207 unsigned char* buffer = (unsigned char*) key_data.begin();
208 i2o_ECPublicKey( key, &buffer ); // FIXME: questionable memory handling
209 if ( key_data == my_pub_key )
210 {
211 nRecId = i;
212 break;
213 }
214 }
215 }
216 EC_KEY_free( key );
217
218 if (nRecId == -1)
219 {
220 FC_THROW_EXCEPTION( exception, "unable to construct recoverable key");
221 }
222 unsigned char* result = nullptr;
223 auto bytes = i2d_ECDSA_SIG( sig, &result );
224 auto lenR = result[3];
225 auto lenS = result[5+lenR];
226 //idump( (result[0])(result[1])(result[2])(result[3])(result[3+lenR])(result[4+lenR])(bytes)(lenR)(lenS) );
227 if( lenR != 32 ) { free(result); continue; }
228 if( lenS != 32 ) { free(result); continue; }
229 //idump( (33-(nBitsR+7)/8) );
230 //idump( (65-(nBitsS+7)/8) );
231 //idump( (sizeof(csig) ) );
232 memcpy( &csig.data[1], &result[4], lenR );
233 memcpy( &csig.data[33], &result[6+lenR], lenS );
234 //idump( (csig.data[33]) );
235 //idump( (csig.data[1]) );
236 free(result);
237 //idump( (nRecId) );
238 csig.data[0] = nRecId+27+4;//(fCompressedPubKey ? 4 : 0);
239 /*
240 idump( (csig) );
241 auto rlen = BN_bn2bin(sig->r,&csig.data[33-(nBitsR+7)/8]);
242 auto slen = BN_bn2bin(sig->s,&csig.data[65-(nBitsS+7)/8]);
243 idump( (rlen)(slen) );
244 */
245 }
246 return csig;
247 } // while true
248 } FC_RETHROW_EXCEPTIONS( warn, "sign ${digest}", ("digest", digest)("private_key",*this) );
249 }
public_key get_public_key() const
public_key_data serialize() const
#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::vector< char > bytes
Definition alt_bn128.hpp:10
memcpy((char *) pInfo->slotDescription, s, l)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ verify()

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

Definition at line 489 of file elliptic_r1.cpp.

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

Friends And Related Symbol Documentation

◆ operator!=

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

Definition at line 120 of file elliptic_r1.hpp.

121 {
122 return a.get_secret() != b.get_secret();
123 }
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181

◆ operator<

bool operator< ( const private_key & a,
const private_key & b )
friend

Definition at line 124 of file elliptic_r1.hpp.

125 {
126 return a.get_secret() < b.get_secret();
127 }

◆ operator==

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

Definition at line 116 of file elliptic_r1.hpp.

117 {
118 return a.get_secret() == b.get_secret();
119 }

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