Ethereum  PoC-8
The C++ Implementation of Ethereum
Common.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
23 #include <libdevcore/Guards.h> // <boost/thread> conflicts with <thread>
24 #include "Common.h"
25 #include <secp256k1.h>
26 #include <secp256k1_ecdh.h>
27 #include <secp256k1_recovery.h>
28 #include <secp256k1_sha256.h>
29 #include <cryptopp/aes.h>
30 #include <cryptopp/algparam.h>
31 #include <cryptopp/pwdbased.h>
32 #include <cryptopp/sha.h>
33 #include <cryptopp/modes.h>
34 #include <libscrypt.h>
35 #include <libdevcore/SHA3.h>
36 #include <libdevcore/RLP.h>
37 #include "AES.h"
38 #include "CryptoPP.h"
39 #include "Exceptions.h"
40 using namespace std;
41 using namespace dev;
42 using namespace dev::crypto;
43 
44 namespace
45 {
46 
47 secp256k1_context const* getCtx()
48 {
49  static std::unique_ptr<secp256k1_context, decltype(&secp256k1_context_destroy)> s_ctx{
50  secp256k1_context_create(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY),
51  &secp256k1_context_destroy
52  };
53  return s_ctx.get();
54 }
55 
56 }
57 
58 bool dev::SignatureStruct::isValid() const noexcept
59 {
60  static const h256 s_max{"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
61  static const h256 s_zero;
62 
63  return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
64 }
65 
66 Public dev::toPublic(Secret const& _secret)
67 {
68  auto* ctx = getCtx();
69  secp256k1_pubkey rawPubkey;
70  // Creation will fail if the secret key is invalid.
71  if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data()))
72  return {};
73  std::array<byte, 65> serializedPubkey;
74  size_t serializedPubkeySize = serializedPubkey.size();
75  secp256k1_ec_pubkey_serialize(
76  ctx, serializedPubkey.data(), &serializedPubkeySize,
77  &rawPubkey, SECP256K1_EC_UNCOMPRESSED
78  );
79  assert(serializedPubkeySize == serializedPubkey.size());
80  // Expect single byte header of value 0x04 -- uncompressed public key.
81  assert(serializedPubkey[0] == 0x04);
82  // Create the Public skipping the header.
83  return Public{&serializedPubkey[1], Public::ConstructFromPointer};
84 }
85 
86 Address dev::toAddress(Public const& _public)
87 {
88  return right160(sha3(_public.ref()));
89 }
90 
91 Address dev::toAddress(Secret const& _secret)
92 {
93  return toAddress(toPublic(_secret));
94 }
95 
96 Address dev::toAddress(Address const& _from, u256 const& _nonce)
97 {
98  return right160(sha3(rlpList(_from, _nonce)));
99 }
100 
101 void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
102 {
103  bytes io = _plain.toBytes();
104  Secp256k1PP::get()->encrypt(_k, io);
105  o_cipher = std::move(io);
106 }
107 
108 bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
109 {
110  bytes io = _cipher.toBytes();
111  Secp256k1PP::get()->decrypt(_k, io);
112  if (io.empty())
113  return false;
114  o_plaintext = std::move(io);
115  return true;
116 }
117 
118 void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
119 {
120  encryptECIES(_k, bytesConstRef(), _plain, o_cipher);
121 }
122 
123 void dev::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher)
124 {
125  bytes io = _plain.toBytes();
126  Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io);
127  o_cipher = std::move(io);
128 }
129 
130 bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
131 {
132  return decryptECIES(_k, bytesConstRef(), _cipher, o_plaintext);
133 }
134 
135 bool dev::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext)
136 {
137  bytes io = _cipher.toBytes();
138  if (!Secp256k1PP::get()->decryptECIES(_k, _sharedMacData, io))
139  return false;
140  o_plaintext = std::move(io);
141  return true;
142 }
143 
144 void dev::encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher)
145 {
146  // TODO: @alex @subtly do this properly.
147  encrypt(KeyPair(_k).pub(), _plain, o_cipher);
148 }
149 
150 bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain)
151 {
152  // TODO: @alex @subtly do this properly.
153  return decrypt(_k, _cipher, o_plain);
154 }
155 
156 std::pair<bytes, h128> dev::encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain)
157 {
158  h128 iv(Nonce::get().makeInsecure());
159  return make_pair(encryptSymNoAuth(_k, iv, _plain), iv);
160 }
161 
163 {
164  if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32)
165  return bytes();
166  CryptoPP::SecByteBlock key(_k.data(), _k.size());
167  try
168  {
169  CryptoPP::CTR_Mode<CryptoPP::AES>::Encryption e;
170  e.SetKeyWithIV(key, key.size(), _iv.data());
171  bytes ret(_plain.size());
172  e.ProcessData(ret.data(), _plain.data(), _plain.size());
173  return ret;
174  }
175  catch (CryptoPP::Exception& _e)
176  {
177  cerr << _e.what() << endl;
178  return bytes();
179  }
180 }
181 
183 {
184  if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32)
185  return bytesSec();
186  CryptoPP::SecByteBlock key(_k.data(), _k.size());
187  try
188  {
189  CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d;
190  d.SetKeyWithIV(key, key.size(), _iv.data());
191  bytesSec ret(_cipher.size());
192  d.ProcessData(ret.writable().data(), _cipher.data(), _cipher.size());
193  return ret;
194  }
195  catch (CryptoPP::Exception& _e)
196  {
197  cerr << _e.what() << endl;
198  return bytesSec();
199  }
200 }
201 
202 Public dev::recover(Signature const& _sig, h256 const& _message)
203 {
204  int v = _sig[64];
205  if (v > 3)
206  return {};
207 
208  auto* ctx = getCtx();
209  secp256k1_ecdsa_recoverable_signature rawSig;
210  if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, _sig.data(), v))
211  return {};
212 
213  secp256k1_pubkey rawPubkey;
214  if (!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, _message.data()))
215  return {};
216 
217  std::array<byte, 65> serializedPubkey;
218  size_t serializedPubkeySize = serializedPubkey.size();
219  secp256k1_ec_pubkey_serialize(
220  ctx, serializedPubkey.data(), &serializedPubkeySize,
221  &rawPubkey, SECP256K1_EC_UNCOMPRESSED
222  );
223  assert(serializedPubkeySize == serializedPubkey.size());
224  // Expect single byte header of value 0x04 -- uncompressed public key.
225  assert(serializedPubkey[0] == 0x04);
226  // Create the Public skipping the header.
227  return Public{&serializedPubkey[1], Public::ConstructFromPointer};
228 }
229 
230 static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337");
231 
232 Signature dev::sign(Secret const& _k, h256 const& _hash)
233 {
234  auto* ctx = getCtx();
235  secp256k1_ecdsa_recoverable_signature rawSig;
236  if (!secp256k1_ecdsa_sign_recoverable(ctx, &rawSig, _hash.data(), _k.data(), nullptr, nullptr))
237  return {};
238 
239  Signature s;
240  int v = 0;
241  secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, s.data(), &v, &rawSig);
242 
243  SignatureStruct& ss = *reinterpret_cast<SignatureStruct*>(&s);
244  ss.v = static_cast<byte>(v);
245  if (ss.s > c_secp256k1n / 2)
246  {
247  ss.v = static_cast<byte>(ss.v ^ 1);
248  ss.s = h256(c_secp256k1n - u256(ss.s));
249  }
250  assert(ss.s <= c_secp256k1n / 2);
251  return s;
252 }
253 
254 bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
255 {
256  // TODO: Verify w/o recovery (if faster).
257  if (!_p)
258  return false;
259  return _p == recover(_s, _hash);
260 }
261 
262 bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
263 {
264  bytesSec ret(_dkLen);
265  if (CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(
266  ret.writable().data(),
267  _dkLen,
268  0,
269  reinterpret_cast<byte const*>(_pass.data()),
270  _pass.size(),
271  _salt.data(),
272  _salt.size(),
273  _iterations
274  ) != _iterations)
275  BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed."));
276  return ret;
277 }
278 
279 bytesSec dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
280 {
281  bytesSec ret(_dkLen);
282  if (libscrypt_scrypt(
283  reinterpret_cast<uint8_t const*>(_pass.data()),
284  _pass.size(),
285  _salt.data(),
286  _salt.size(),
287  _n,
288  _r,
289  _p,
290  ret.writable().data(),
291  _dkLen
292  ) != 0)
293  BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed."));
294  return ret;
295 }
296 
297 KeyPair::KeyPair(Secret const& _sec):
298  m_secret(_sec),
299  m_public(toPublic(_sec))
300 {
301  // Assign address only if the secret key is valid.
302  if (m_public)
303  m_address = toAddress(m_public);
304 }
305 
307 {
308  while (true)
309  {
310  KeyPair keyPair(Secret::random());
311  if (keyPair.address())
312  return keyPair;
313  }
314 }
315 
316 KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)
317 {
318  return KeyPair(Secret(sha3(aesDecrypt(_seed, _password))));
319 }
320 
321 h256 crypto::kdf(Secret const& _priv, h256 const& _hash)
322 {
323  // H(H(r||k)^h)
324  h256 s;
325  sha3mac(Secret::random().ref(), _priv.ref(), s.ref());
326  s ^= _hash;
327  sha3(s.ref(), s.ref());
328 
329  if (!s || !_hash || !_priv)
330  BOOST_THROW_EXCEPTION(InvalidState());
331  return s;
332 }
333 
334 Secret Nonce::next()
335 {
336  Guard l(x_value);
337  if (!m_value)
338  {
339  m_value = Secret::random();
340  if (!m_value)
341  BOOST_THROW_EXCEPTION(InvalidState());
342  }
343  m_value = sha3Secure(m_value.ref());
344  return sha3(~m_value);
345 }
346 
347 static int secp256k1_ecdh_hash_function_save_compressed(unsigned char* output, const unsigned char* x, const unsigned char* y, void*)
348 {
349  output[0] = 0x02 | (y[31] & 1);
350  std::memcpy(output+1, x, 32);
351  return 1;
352 }
353 
354 bool ecdh::agree(Secret const& _s, Public const& _r, Secret& o_s) noexcept
355 {
356  auto* ctx = getCtx();
357  static_assert(sizeof(Secret) == 32, "Invalid Secret type size");
358  secp256k1_pubkey rawPubkey;
359  std::array<byte, 65> serializedPubKey{{0x04}};
360  std::copy(_r.asArray().begin(), _r.asArray().end(), serializedPubKey.begin() + 1);
361  if (!secp256k1_ec_pubkey_parse(ctx, &rawPubkey, serializedPubKey.data(), serializedPubKey.size()))
362  return false; // Invalid public key.
363  // FIXME: We should verify the public key when constructed, maybe even keep
364  // secp256k1_pubkey as the internal data of Public.
365  std::array<byte, 33> compressedPoint;
366  if (!secp256k1_ecdh(ctx, compressedPoint.data(), &rawPubkey, _s.data(), secp256k1_ecdh_hash_function_save_compressed, nullptr))
367  return false; // Invalid secret key.
368  std::copy(compressedPoint.begin() + 1, compressedPoint.end(), o_s.writable().data());
369  return true;
370 }
371 
372 bytes ecies::kdf(Secret const& _z, bytes const& _s1, unsigned kdByteLen)
373 {
374  auto reps = ((kdByteLen + 7) * 8) / 512;
375  // SEC/ISO/Shoup specify counter size SHOULD be equivalent
376  // to size of hash output, however, it also notes that
377  // the 4 bytes is okay. NIST specifies 4 bytes.
378  std::array<byte, 4> ctr{{0, 0, 0, 1}};
379  bytes k;
380  secp256k1_sha256 ctx;
381  for (unsigned i = 0; i <= reps; i++)
382  {
383  secp256k1_sha256_initialize(&ctx);
384  secp256k1_sha256_write(&ctx, ctr.data(), ctr.size());
385  secp256k1_sha256_write(&ctx, _z.data(), Secret::size);
386  secp256k1_sha256_write(&ctx, _s1.data(), _s1.size());
387  // append hash to k
388  std::array<byte, 32> digest;
389  secp256k1_sha256_finalize(&ctx, digest.data());
390 
391  k.reserve(k.size() + h256::size);
392  move(digest.begin(), digest.end(), back_inserter(k));
393 
394  if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0])
395  continue;
396  }
397 
398  k.resize(kdByteLen);
399  return k;
400 }
bytesConstRef ref() const
Definition: FixedHash.h:300
Definition: Address.cpp:20
bool agree(Secret const &_s, Public const &_r, Secret &o_s) noexcept
Definition: Common.cpp:354
uint8_t byte
Definition: Common.h:57
void encryptSym(Secret const &_k, bytesConstRef _plain, bytes &o_cipher)
Symmetric encryption.
Definition: Common.cpp:144
vector_ref< _T const > ref(_T const &_t)
Definition: vector_ref.h:109
byte * data()
Definition: FixedHash.h:138
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition: FixedHash.h:367
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:43
bytesSec pbkdf2(std::string const &_pass, bytes const &_salt, unsigned _iterations, unsigned _dkLen=32)
Derive key via PBKDF2.
bool decryptECIES(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Decrypt payload using ECIES standard with AES128-CTR.
Definition: Common.cpp:130
bool verify(Public const &_k, Signature const &_s, h256 const &_hash)
Verify signature.
Definition: Common.cpp:254
SecureFixedHash< 32 > sha3Secure(bytesConstRef _input) noexcept
Definition: SHA3.h:50
secure_vector< byte > bytesSec
Definition: Common.h:115
KeyPair(Secret const &_sec)
Definition: Common.cpp:297
std::pair< bytes, h128 > encryptSymNoAuth(SecureFixedHash< 16 > const &_k, bytesConstRef _plain)
Encrypts payload with random IV/ctr using AES128-CTR.
Definition: Common.cpp:156
static KeyPair create()
Create a new, randomly generated object.
Definition: Common.cpp:306
SecureFixedHash< 32 > Secret
Definition: Common.h:36
Definition: FixedHash.h:390
Address toAddress(std::string const &_s)
Convert the given string into an address.
Definition: Common.cpp:56
void encryptECIES(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypt payload using ECIES standard with AES128-CTR.
Definition: Common.cpp:118
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Definition: SHA3.cpp:28
Public toPublic(Secret const &_secret)
Convert a secret key into the public key equivalent.
Definition: Common.cpp:66
bool decryptSym(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Symmetric decryption.
Definition: Common.cpp:150
byte const * data() const
Definition: FixedHash.h:301
static SecureFixedHash< T > random()
Definition: FixedHash.h:303
bytesRef ref()
Definition: FixedHash.h:132
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
Definition: Common.cpp:202
std::vector< byte > bytes
Definition: Common.h:72
vector_ref< byte const > bytesConstRef
Definition: Common.h:74
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const &_password)
Create from an encrypted seed.
Definition: Common.cpp:316
h256 kdf(Secret const &_priv, h256 const &_hash)
Key derivation.
Definition: Common.cpp:321
FixedHash< 32 > h256
Definition: FixedHash.h:354
Address toAddress(Public const &_public)
Convert a public key to address.
Definition: Common.cpp:86
std::vector< T > & writable()
Definition: Common.h:98
bytes rlpList()
Export a list of items in RLP format, returning a byte array.
Definition: RLP.h:456
bytesSec scrypt(std::string const &_pass, bytes const &_salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
Derive key via Scrypt.
Definition: Common.cpp:279
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
Definition: Common.cpp:232
bytesSec decryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _cipher)
Decrypts payload with specified IV/ctr using AES128-CTR.
Definition: Common.cpp:182
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
Definition: Common.h:121
void encrypt(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypts plain text using Public key.
Definition: Common.cpp:101
bytes aesDecrypt(bytesConstRef _cipher, std::string const &_password, unsigned _rounds=2000, bytesConstRef _salt=bytesConstRef())
Definition: AES.cpp:32
bool decrypt(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Decrypts cipher using Secret key.
Definition: Common.cpp:108
Address const & address() const
Retrieve the associated address of the public key.
Definition: Common.h:158
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:69
size_t size() const
Definition: vector_ref.h:53
bytes encryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _plain)
Encrypts payload with specified IV/ctr using AES128-CTR.
Definition: Common.cpp:162
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
Calculate SHA3-256 MAC.
Definition: SHA3.h:129
bool isValid() const noexcept
Definition: Common.cpp:58
_T * data() const
Definition: vector_ref.h:49