BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
memo.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
25 #include <boost/endian/conversion.hpp>
26 #include <fc/crypto/aes.hpp>
27 #include <fc/io/raw.hpp>
28 
29 namespace graphene { namespace protocol {
30 
32  const string& msg, uint64_t custom_nonce)
33 {
34  if( priv != fc::ecc::private_key() && public_key_type(pub) != public_key_type() )
35  {
36  from = priv.get_public_key();
37  to = pub;
38  if( 0 == custom_nonce )
39  {
40  uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0].value();
41  constexpr uint64_t half_size = 32;
42  constexpr uint64_t high_bits = 0xff00000000000000ULL;
43  constexpr uint64_t low_bits = 0x00ffffffffffffffULL;
44  entropy <<= half_size;
45  entropy &= high_bits;
46  nonce = ((uint64_t)(fc::time_point::now().time_since_epoch().count()) & low_bits) | entropy;
47  } else
48  nonce = custom_nonce;
49  auto secret = priv.get_shared_secret(pub);
50  auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());
51  string text = memo_message((uint32_t)digest_type::hash(msg)._hash[0].value(), msg).serialize();
52  message = fc::aes_encrypt( nonce_plus_secret, vector<char>(text.begin(), text.end()) );
53  }
54  else
55  {
56  auto text = memo_message(0, msg).serialize();
57  message = vector<char>(text.begin(), text.end());
58  }
59 }
60 
62  const fc::ecc::public_key& pub)const
63 {
64  if( from != public_key_type() )
65  {
66  auto secret = priv.get_shared_secret(pub);
67  auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());
68  auto plain_text = fc::aes_decrypt( nonce_plus_secret, message );
69  auto result = memo_message::deserialize(string(plain_text.begin(), plain_text.end()));
70  FC_ASSERT( result.checksum == (uint32_t)digest_type::hash(result.text)._hash[0].value() );
71  return result.text;
72  }
73  else
74  {
75  return memo_message::deserialize(string(message.begin(), message.end())).text;
76  }
77 }
78 
80 {
81  auto serial_checksum = string(sizeof(checksum), ' ');
82  (uint32_t&)(*serial_checksum.data()) = boost::endian::native_to_little(checksum);
83  return serial_checksum + text;
84 }
85 
87 {
88  memo_message result;
89  FC_ASSERT( serial.size() >= sizeof(result.checksum) );
90  result.checksum = boost::endian::little_to_native((uint32_t&)(*serial.data()));
91  result.text = serial.substr(sizeof(result.checksum));
92  return result;
93 }
94 
95 } } // graphene::protocol
96 
fc::to_string
std::string to_string(double)
Definition: string.cpp:73
graphene::protocol::memo_data::get_message
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
Definition: memo.cpp:61
fc::ecc::private_key::get_shared_secret
fc::sha512 get_shared_secret(const public_key &pub) const
Definition: elliptic_secp256k1.cpp:66
graphene::protocol::memo_data::nonce
uint64_t nonce
Definition: memo.hpp:55
fc::ecc::public_key
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION
#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type)
Definition: types.hpp:86
graphene::protocol::public_key_type
Definition: types.hpp:312
graphene::protocol::memo_data::to
public_key_type to
Definition: memo.hpp:43
graphene::protocol::memo_message::serialize
string serialize() const
Definition: memo.cpp:79
fc::time_point::time_since_epoch
const microseconds & time_since_epoch() const
Definition: time.hpp:54
fc::ecc::private_key
an elliptic curve private key.
Definition: elliptic.hpp:89
graphene::protocol::memo_message::checksum
uint32_t checksum
Definition: memo.hpp:81
fc::ecc::private_key::generate
static private_key generate()
Definition: elliptic_common.cpp:217
memo.hpp
graphene::protocol::memo_message::deserialize
static memo_message deserialize(const string &serial)
Definition: memo.cpp:86
fc::sha512::hash
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
fc::sha256::_hash
boost::endian::little_uint64_buf_t _hash[4]
Definition: sha256.hpp:71
fc::ecc::private_key::get_public_key
public_key get_public_key() const
Definition: elliptic_impl_priv.cpp:70
fc::time_point::now
static time_point now()
Definition: time.cpp:13
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::protocol::memo_data::set_message
void set_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub, const string &msg, uint64_t custom_nonce=0)
Definition: memo.cpp:31
graphene::protocol::memo_data::message
vector< char > message
Definition: memo.hpp:59
fc::microseconds::count
int64_t count() const
Definition: time.hpp:28
graphene::protocol::memo_message
defines a message and checksum to enable validation of successful decryption
Definition: memo.hpp:75
graphene::protocol::memo_data
defines the keys used to derive the shared secret
Definition: memo.hpp:40
aes.hpp
fc::sha224::_hash
boost::endian::little_uint32_buf_t _hash[7]
Definition: sha224.hpp:68
fc::sha224::hash
static sha224 hash(const char *d, uint32_t dlen)
Definition: sha224.cpp:34
graphene::protocol::memo_message::text
std::string text
Definition: memo.hpp:82
graphene::protocol::memo_data::from
public_key_type from
Definition: memo.hpp:42
fc::aes_decrypt
unsigned aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
Definition: aes.cpp:230
fc::sha256::hash
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
graphene
Definition: api.cpp:48
fc::aes_encrypt
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
Definition: aes.cpp:181
raw.hpp