Scorum
atomicswap_helper.cpp
Go to the documentation of this file.
3 
4 #include <fc/crypto/sha512.hpp>
5 #include <fc/crypto/hex.hpp>
6 #include <fc/crypto/ripemd160.hpp>
7 
8 #include <sstream>
9 
10 namespace scorum {
11 namespace protocol {
12 namespace atomicswap {
13 
14 std::string get_secret_hex(const std::string& secret, const uint8_t secret_length /*= 0*/)
15 {
16  fc::sha512 hash = fc::sha512().hash(secret);
17  FC_ASSERT(secret_length <= hash.data_size(), "Required secret string is too long. Use length less or equal ${1}",
18  ("1", hash.data_size()));
19  std::size_t out_sz = secret_length;
20  if (!out_sz)
21  {
22  static const size_t entropy_percent = (std::size_t)50;
23  FC_ASSERT(entropy_percent > 0);
24  std::size_t entropy = secret.size();
25  // get value in [entropy_percent, 2*entropy_percent - 1]
26  entropy = entropy_percent + entropy % entropy_percent;
27  ++entropy; // increase value for [entropy_percent + 1, 2*entropy_percent]
28  // divide to 2*entropy_percent to get coefficient in (0.5, 1]
29  out_sz = hash.data_size() * entropy / entropy_percent / (std::size_t)2;
30  if (out_sz > SCORUM_ATOMICSWAP_SECRET_MAX_LENGTH / 2)
31  {
32  // Ensure out hex string less then SCORUM_ATOMICSWAP_SECRET_MAX_LENGTH (length in hex view (two symbol per
33  // byte))
35  }
36  }
37  return fc::to_hex(hash.data(), out_sz);
38 }
39 
40 std::string get_secret_hash(const std::string& secret_hex)
41 {
42  fc::ripemd160::encoder e;
43  char ch_out{ '\0' };
44  bool odd = false;
45  for (char ch : secret_hex)
46  {
47  odd = !odd;
48  if (odd)
49  {
50  ch_out = fc::from_hex(ch) << 4;
51  }
52  else
53  {
54  ch_out |= fc::from_hex(ch);
55  e.put(ch_out);
56  }
57  }
58  if (odd)
59  {
60  // if secret_hex is not even 1 byte
61  e.put(ch_out);
62  }
63  fc::ripemd160 encode = e.result();
64  return encode.str();
65 }
66 
67 void validate_secret(const std::string& secret_hex)
68 {
69  FC_ASSERT(!secret_hex.empty(), "Empty secret.");
70  FC_ASSERT(secret_hex.size() < SCORUM_ATOMICSWAP_SECRET_MAX_LENGTH, "Secret string is too long.");
71  for (char ch : secret_hex)
72  {
73  fc::from_hex(ch);
74  }
75 }
76 
77 void validate_secret_hash(const std::string& secret_hash)
78 {
79  fc::ripemd160 fmt;
80  FC_ASSERT(secret_hash.size() == fmt.data_size() * 2, "Invalid hash format. It must be in hex RIPEMD160 format.");
81  try
82  {
83  fmt = fc::ripemd160(secret_hash);
84  }
85  FC_CAPTURE_AND_RETHROW((secret_hash))
86 }
87 
88 void validate_contract_metadata(const std::string& metadata)
89 {
90  FC_ASSERT(metadata.size() < SCORUM_ATOMICSWAP_CONTRACT_METADATA_MAX_LENGTH,
91  "Contract metadata string is too long.");
92 }
93 
94 fc::sha256
95 get_contract_hash_obj(const account_name_type& from, const account_name_type& to, const std::string& secret_hash)
96 {
97  std::stringstream store;
98  store << from << to << secret_hash;
99  return fc::sha256().hash(store.str());
100 }
101 
102 std::string
103 get_contract_hash_hex(const account_name_type& from, const account_name_type& to, const std::string& secret_hash)
104 {
105  return get_contract_hash_obj(from, to, secret_hash).str();
106 }
107 
109 get_contract_hash(const account_name_type& from, const account_name_type& to, const std::string& secret_hash)
110 {
111  fc::sha256 encode = get_contract_hash_obj(from, to, secret_hash);
112 
113  // pack 256-bit binary data to 32-bt fixed string
114  hash_index_type ret;
115  // check if somebody change hash index_type size or sha256 impl
116  FC_ASSERT(encode.data_size() == sizeof(ret.data));
117  memcpy((char*)&ret.data, encode.data(), encode.data_size());
118 
119  ret.data = boost::endian::big_to_native(ret.data);
120 
121  return ret;
122 }
123 }
124 }
125 }
#define SCORUM_ATOMICSWAP_SECRET_MAX_LENGTH
Definition: config.hpp:111
#define SCORUM_ATOMICSWAP_CONTRACT_METADATA_MAX_LENGTH
Definition: config.hpp:110
fc::fixed_string_32 hash_index_type
void validate_contract_metadata(const std::string &metadata)
void validate_secret(const std::string &secret_hex)
hash_index_type get_contract_hash(const account_name_type &from, const account_name_type &to, const std::string &secret_hash)
void validate_secret_hash(const std::string &secret_hash)
fc::sha256 get_contract_hash_obj(const account_name_type &from, const account_name_type &to, const std::string &secret_hash)
std::string get_secret_hash(const std::string &secret_hex)
std::string get_secret_hex(const std::string &secret, const uint8_t secret_length)
std::string get_contract_hash_hex(const account_name_type &from, const account_name_type &to, const std::string &secret_hash)
fc::fixed_string_16 account_name_type
Definition: types.hpp:62
Definition: asset.cpp:15