BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface 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( custom_nonce == 0 )
39  {
40  uint64_t entropy = fc::sha224::hash(fc::ecc::private_key::generate())._hash[0].value();
41  entropy <<= 32;
42  entropy &= 0xff00000000000000;
43  nonce = (fc::time_point::now().time_since_epoch().count() & 0x00ffffffffffffff) | entropy;
44  } else
45  nonce = custom_nonce;
46  auto secret = priv.get_shared_secret(pub);
47  auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());
48  string text = memo_message(digest_type::hash(msg)._hash[0].value(), msg).serialize();
49  message = fc::aes_encrypt( nonce_plus_secret, vector<char>(text.begin(), text.end()) );
50  }
51  else
52  {
53  auto text = memo_message(0, msg).serialize();
54  message = vector<char>(text.begin(), text.end());
55  }
56 }
57 
59  const fc::ecc::public_key& pub)const
60 {
61  if( from != public_key_type() )
62  {
63  auto secret = priv.get_shared_secret(pub);
64  auto nonce_plus_secret = fc::sha512::hash(fc::to_string(nonce) + secret.str());
65  auto plain_text = fc::aes_decrypt( nonce_plus_secret, message );
66  auto result = memo_message::deserialize(string(plain_text.begin(), plain_text.end()));
67  FC_ASSERT( result.checksum == (uint32_t)digest_type::hash(result.text)._hash[0].value() );
68  return result.text;
69  }
70  else
71  {
72  return memo_message::deserialize(string(message.begin(), message.end())).text;
73  }
74 }
75 
77 {
78  auto serial_checksum = string(sizeof(checksum), ' ');
79  (uint32_t&)(*serial_checksum.data()) = boost::endian::native_to_little(checksum);
80  return serial_checksum + text;
81 }
82 
84 {
85  memo_message result;
86  FC_ASSERT( serial.size() >= sizeof(result.checksum) );
87  result.checksum = boost::endian::little_to_native((uint32_t&)(*serial.data()));
88  result.text = serial.substr(sizeof(result.checksum));
89  return result;
90 }
91 
92 } } // graphene::protocol
93 
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
Definition: aes.cpp:181
Definition: api.cpp:56
static sha224 hash(const char *d, uint32_t dlen)
Definition: sha224.cpp:34
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
defines a message and checksum to enable validation of successful decryption
Definition: memo.hpp:75
boost::endian::little_uint32_buf_t _hash[7]
Definition: sha224.hpp:68
public_key get_public_key() const
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
boost::endian::little_uint64_buf_t _hash[4]
Definition: sha256.hpp:71
public_key_type to
Definition: memo.hpp:43
static private_key generate()
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
fc::sha512 get_shared_secret(const public_key &pub) const
int64_t count() const
Definition: time.hpp:28
std::string get_message(const fc::ecc::private_key &priv, const fc::ecc::public_key &pub) const
Definition: memo.cpp:58
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type)
Definition: types.hpp:74
const microseconds & time_since_epoch() const
Definition: time.hpp:54
std::string to_string(double)
Definition: string.cpp:73
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
vector< char > message
Definition: memo.hpp:59
unsigned aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
Definition: aes.cpp:230
static memo_message deserialize(const string &serial)
Definition: memo.cpp:83
public_key_type from
Definition: memo.hpp:42
string serialize() const
Definition: memo.cpp:76
static time_point now()
Definition: time.cpp:13
an elliptic curve private key.
Definition: elliptic.hpp:89
defines the keys used to derive the shared secret
Definition: memo.hpp:40