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