Fabcoin Core  0.16.2
P2P Digital Currency
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 <cryptopp/aes.h>
29 #include <cryptopp/pwdbased.h>
30 #include <cryptopp/sha.h>
31 #include <cryptopp/modes.h>
32 #include <libscrypt/libscrypt.h>
33 #include <libdevcore/SHA3.h>
34 #include <libdevcore/RLP.h>
35 #include "AES.h"
36 #include "CryptoPP.h"
37 #include "Exceptions.h"
38 using namespace std;
39 using namespace dev;
40 using namespace dev::crypto;
41 using namespace CryptoPP;
42 
43 namespace
44 {
45 
46 secp256k1_context const* getCtx()
47 {
48  static std::unique_ptr<secp256k1_context, decltype(&secp256k1_context_destroy)> s_ctx{
51  };
52  return s_ctx.get();
53 }
54 
55 }
56 
57 bool dev::SignatureStruct::isValid() const noexcept
58 {
59  static const h256 s_max{"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
60  static const h256 s_zero;
61 
62  return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
63 }
64 
66 
67 Public dev::toPublic(Secret const& _secret)
68 {
69  auto* ctx = getCtx();
70  secp256k1_pubkey rawPubkey;
71  // Creation will fail if the secret key is invalid.
72  if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.data()))
73  return {};
74  std::array<byte, 65> serializedPubkey;
75  size_t serializedPubkeySize = serializedPubkey.size();
77  ctx, serializedPubkey.data(), &serializedPubkeySize,
78  &rawPubkey, SECP256K1_EC_UNCOMPRESSED
79  );
80  assert(serializedPubkeySize == serializedPubkey.size());
81  // Expect single byte header of value 0x04 -- uncompressed public key.
82  assert(serializedPubkey[0] == 0x04);
83  // Create the Public skipping the header.
84  return Public{&serializedPubkey[1], Public::ConstructFromPointer};
85 }
86 
87 Address dev::toAddress(Public const& _public)
88 {
89  return right160(sha3(_public.ref()));
90 }
91 
92 Address dev::toAddress(Secret const& _secret)
93 {
94  return toAddress(toPublic(_secret));
95 }
96 
97 Address dev::toAddress(Address const& _from, u256 const& _nonce)
98 {
99  return right160(sha3(rlpList(_from, _nonce)));
100 }
101 
102 void dev::encrypt(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
103 {
104  bytes io = _plain.toBytes();
105  Secp256k1PP::get()->encrypt(_k, io);
106  o_cipher = std::move(io);
107 }
108 
109 bool dev::decrypt(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
110 {
111  bytes io = _cipher.toBytes();
112  Secp256k1PP::get()->decrypt(_k, io);
113  if (io.empty())
114  return false;
115  o_plaintext = std::move(io);
116  return true;
117 }
118 
119 void dev::encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher)
120 {
121  encryptECIES(_k, bytesConstRef(), _plain, o_cipher);
122 }
123 
124 void dev::encryptECIES(Public const& _k, bytesConstRef _sharedMacData, bytesConstRef _plain, bytes& o_cipher)
125 {
126  bytes io = _plain.toBytes();
127  Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io);
128  o_cipher = std::move(io);
129 }
130 
131 bool dev::decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext)
132 {
133  return decryptECIES(_k, bytesConstRef(), _cipher, o_plaintext);
134 }
135 
136 bool dev::decryptECIES(Secret const& _k, bytesConstRef _sharedMacData, bytesConstRef _cipher, bytes& o_plaintext)
137 {
138  bytes io = _cipher.toBytes();
139  if (!Secp256k1PP::get()->decryptECIES(_k, _sharedMacData, io))
140  return false;
141  o_plaintext = std::move(io);
142  return true;
143 }
144 
145 void dev::encryptSym(Secret const& _k, bytesConstRef _plain, bytes& o_cipher)
146 {
147  // TODO: @alex @subtly do this properly.
148  encrypt(KeyPair(_k).pub(), _plain, o_cipher);
149 }
150 
151 bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain)
152 {
153  // TODO: @alex @subtly do this properly.
154  return decrypt(_k, _cipher, o_plain);
155 }
156 
157 std::pair<bytes, h128> dev::encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain)
158 {
159  h128 iv(Nonce::get().makeInsecure());
160  return make_pair(encryptSymNoAuth(_k, iv, _plain), iv);
161 }
162 
164 {
165  if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32)
166  return bytes();
167  SecByteBlock key(_k.data(), _k.size());
168  try
169  {
171  e.SetKeyWithIV(key, key.size(), _iv.data());
172  bytes ret(_plain.size());
173  e.ProcessData(ret.data(), _plain.data(), _plain.size());
174  return ret;
175  }
176  catch (CryptoPP::Exception& _e)
177  {
178  cerr << _e.what() << endl;
179  return bytes();
180  }
181 }
182 
184 {
185  if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32)
186  return bytesSec();
187  SecByteBlock key(_k.data(), _k.size());
188  try
189  {
191  d.SetKeyWithIV(key, key.size(), _iv.data());
192  bytesSec ret(_cipher.size());
193  d.ProcessData(ret.writable().data(), _cipher.data(), _cipher.size());
194  return ret;
195  }
196  catch (CryptoPP::Exception& _e)
197  {
198  cerr << _e.what() << endl;
199  return bytesSec();
200  }
201 }
202 
203 Public dev::recover(Signature const& _sig, h256 const& _message)
204 {
205  int v = _sig[64];
206  if (v > 3)
207  return {};
208 
209  auto* ctx = getCtx();
211  if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, _sig.data(), v))
212  return {};
213 
214  secp256k1_pubkey rawPubkey;
215  if (!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, _message.data()))
216  return {};
217 
218  std::array<byte, 65> serializedPubkey;
219  size_t serializedPubkeySize = serializedPubkey.size();
221  ctx, serializedPubkey.data(), &serializedPubkeySize,
222  &rawPubkey, SECP256K1_EC_UNCOMPRESSED
223  );
224  assert(serializedPubkeySize == serializedPubkey.size());
225  // Expect single byte header of value 0x04 -- uncompressed public key.
226  assert(serializedPubkey[0] == 0x04);
227  // Create the Public skipping the header.
228  return Public{&serializedPubkey[1], Public::ConstructFromPointer};
229 }
230 
231 static const u256 c_secp256k1n("115792089237316195423570985008687907852837564279074904382605163141518161494337");
232 
233 Signature dev::sign(Secret const& _k, h256 const& _hash)
234 {
235  auto* ctx = getCtx();
237  if (!secp256k1_ecdsa_sign_recoverable(ctx, &rawSig, _hash.data(), _k.data(), nullptr, nullptr))
238  return {};
239 
240  Signature s;
241  int v = 0;
243 
244  SignatureStruct& ss = *reinterpret_cast<SignatureStruct*>(&s);
245  ss.v = static_cast<byte>(v);
246  if (ss.s > c_secp256k1n / 2)
247  {
248  ss.v = static_cast<byte>(ss.v ^ 1);
249  ss.s = h256(c_secp256k1n - u256(ss.s));
250  }
251  assert(ss.s <= c_secp256k1n / 2);
252  return s;
253 }
254 
255 bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
256 {
257  // TODO: Verify w/o recovery (if faster).
258  if (!_p)
259  return false;
260  return _p == recover(_s, _hash);
261 }
262 
263 bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
264 {
265  bytesSec ret(_dkLen);
266  if (PKCS5_PBKDF2_HMAC<SHA256>().DeriveKey(
267  ret.writable().data(),
268  _dkLen,
269  0,
270  reinterpret_cast<byte const*>(_pass.data()),
271  _pass.size(),
272  _salt.data(),
273  _salt.size(),
274  _iterations
275  ) != _iterations)
276  BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed."));
277  return ret;
278 }
279 
280 bytesSec dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
281 {
282  bytesSec ret(_dkLen);
283  if (libscrypt_scrypt(
284  reinterpret_cast<uint8_t const*>(_pass.data()),
285  _pass.size(),
286  _salt.data(),
287  _salt.size(),
288  _n,
289  _r,
290  _p,
291  ret.writable().data(),
292  _dkLen
293  ) != 0)
294  BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed."));
295  return ret;
296 }
297 
298 KeyPair::KeyPair(Secret const& _sec):
299  m_secret(_sec),
300  m_public(toPublic(_sec))
301 {
302  // Assign address only if the secret key is valid.
303  if (m_public)
305 }
306 
308 {
309  while (true)
310  {
311  KeyPair keyPair(Secret::random());
312  if (keyPair.address())
313  return keyPair;
314  }
315 }
316 
317 KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)
318 {
319  return KeyPair(Secret(sha3(aesDecrypt(_seed, _password))));
320 }
321 
322 h256 crypto::kdf(Secret const& _priv, h256 const& _hash)
323 {
324  // H(H(r||k)^h)
325  h256 s;
326  sha3mac(Secret::random().ref(), _priv.ref(), s.ref());
327  s ^= _hash;
328  sha3(s.ref(), s.ref());
329 
330  if (!s || !_hash || !_priv)
331  BOOST_THROW_EXCEPTION(InvalidState());
332  return s;
333 }
334 
335 Secret Nonce::next()
336 {
337  Guard l(x_value);
338  if (!m_value)
339  {
340  m_value = Secret::random();
341  if (!m_value)
342  BOOST_THROW_EXCEPTION(InvalidState());
343  }
344  m_value = sha3Secure(m_value.ref());
345  return sha3(~m_value);
346 }
347 
348 void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, Secret& o_s)
349 {
350  auto* ctx = getCtx();
351  static_assert(sizeof(Secret) == 32, "Invalid Secret type size");
352  secp256k1_pubkey rawPubkey;
353  std::array<byte, 65> serializedPubKey{{0x04}};
354  std::copy(_r.asArray().begin(), _r.asArray().end(), serializedPubKey.begin() + 1);
355  auto r = secp256k1_ec_pubkey_parse(ctx, &rawPubkey, serializedPubKey.data(), serializedPubKey.size());
356  assert(r == 1);
357  std::array<byte, 33> compressedPoint;
358 #ifdef FASC_BUILD
359  r = secp256k1_ecdh(ctx, compressedPoint.data(), &rawPubkey, _s.data());
360 #else
361  r = secp256k1_ecdh_raw(ctx, compressedPoint.data(), &rawPubkey, _s.data());
362 #endif
363  assert(r == 1); // TODO: This should be "invalid secret key" exception.
364  std::copy(compressedPoint.begin() + 1, compressedPoint.end(), o_s.writable().data());
365 }
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *input64, int recid) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a compact ECDSA signature (64 bytes + recovery id).
Definition: main_impl.h:38
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
uint8_t byte
Definition: Common.h:57
void encryptSym(Secret const &_k, bytesConstRef _plain, bytes &o_cipher)
Symmetric encryption.
Definition: Common.cpp:145
vector_ref< _T const > ref(_T const &_t)
Definition: vector_ref.h:115
byte * data()
Definition: FixedHash.h:139
byte const * data() const
Definition: FixedHash.h:293
Class file for modes of operation.
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
Definition: FixedHash.h:353
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:131
bool verify(Public const &_k, Signature const &_s, h256 const &_hash)
Verify signature.
Definition: Common.cpp:255
Simple class that represents a "key pair".
Definition: Common.h:150
Opaque data structured that holds a parsed ECDSA signature, supporting pubkey recovery.
secure_vector< byte > bytesSec
Definition: Common.h:118
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
SecureFixedHash< 32 > sha3Secure(bytesConstRef _input)
Definition: SHA3.h:41
std::pair< bytes, h128 > encryptSymNoAuth(SecureFixedHash< 16 > const &_k, bytesConstRef _plain)
Encrypts payload with random IV/ctr using AES128-CTR.
Definition: Common.cpp:157
static KeyPair create()
Create a new, randomly generated object.
Definition: Common.cpp:307
Address m_address
Definition: Common.h:181
SecureFixedHash< 32 > Secret
Definition: Common.h:35
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
void encryptECIES(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypt payload using ECIES standard with AES128-CTR.
Definition: Common.cpp:119
SECP256K1_API int secp256k1_ec_pubkey_serialize(const secp256k1_context *ctx, unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize a pubkey object into a serialized byte sequence.
Definition: secp256k1.c:165
#define SECP256K1_CONTEXT_SIGN
Definition: secp256k1.h:155
PBKDF2 from PKCS #5.
Definition: pwdbased.h:62
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object.
Definition: secp256k1.c:92
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_create(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Compute the public key for a secret key.
Definition: secp256k1.c:404
Public toPublic(Secret const &_secret)
Convert a secret key into the public key equivalent.
Definition: Common.cpp:67
#define SECP256K1_EC_UNCOMPRESSED
Definition: secp256k1.h:160
bytesConstRef ref() const
Definition: FixedHash.h:292
int libscrypt_scrypt(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t *buf, size_t buflen)
crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): Compute scrypt(passwd[0 ...
bool decryptSym(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Symmetric decryption.
Definition: Common.cpp:151
static SecureFixedHash< T > random()
Definition: FixedHash.h:295
bytesRef ref()
Definition: FixedHash.h:133
Block cipher mode of operation aggregate.
Definition: modes.h:285
std::lock_guard< std::mutex > Guard
Definition: Guards.h:41
KeyPair()=default
Null constructor.
Class file for the AES cipher (Rijndael)
Address ZeroAddress
The zero address.
Definition: Common.cpp:65
Public m_public
Definition: Common.h:180
SECP256K1_API int secp256k1_ecdsa_sign_recoverable(const secp256k1_context *ctx, secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32, const unsigned char *seckey, secp256k1_nonce_function noncefp, const void *ndata) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Create a recoverable ECDSA signature.
Definition: main_impl.h:123
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
Definition: Common.cpp:203
std::vector< byte > bytes
Definition: Common.h:75
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:45
vector_ref< byte const > bytesConstRef
Definition: Common.h:77
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const &_password)
Create from an encrypted seed.
Definition: Common.cpp:317
h256 kdf(Secret const &_priv, h256 const &_hash)
Key derivation.
Definition: Common.cpp:322
FixedHash< T > & writable()
Definition: FixedHash.h:254
FixedHash< 32 > h256
Definition: FixedHash.h:340
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_pubkey_parse(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3)
Parse a variable-length public key into the pubkey object.
Definition: secp256k1.c:150
Address toAddress(std::string const &_s)
Convert the given string into an address.
Definition: Common.cpp:56
SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact(const secp256k1_context *ctx, unsigned char *output64, int *recid, const secp256k1_ecdsa_recoverable_signature *sig) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Serialize an ECDSA signature in compact format (64 bytes + recovery id).
Definition: main_impl.h:60
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
Address toAddress(Public const &_public)
Convert a public key to address.
Definition: Common.cpp:87
std::vector< T > & writable()
Definition: Common.h:101
size_t size() const
Definition: vector_ref.h:55
bytes rlpList()
Export a list of items in RLP format, returning a byte array.
Definition: RLP.h:470
Address const & address() const
Retrieve the associated address of the public key.
Definition: Common.h:173
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:280
Classes for SHA-1 and SHA-2 family of message digests.
#define SECP256K1_CONTEXT_VERIFY
Flags to pass to secp256k1_context_create.
Definition: secp256k1.h:154
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
Definition: Common.cpp:233
unsigned char data[64]
Definition: secp256k1.h:54
bytesSec decryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _cipher)
Decrypts payload with specified IV/ctr using AES128-CTR.
Definition: Common.cpp:183
Password based key derivation functions.
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover(const secp256k1_context *ctx, secp256k1_pubkey *pubkey, const secp256k1_ecdsa_recoverable_signature *sig, const unsigned char *msg32) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Recover an ECDSA public key from a signature.
Definition: main_impl.h:170
_T * data() const
Definition: vector_ref.h:51
void encrypt(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypts plain text using Public key.
Definition: Common.cpp:102
bytes aesDecrypt(bytesConstRef _cipher, std::string const &_password, unsigned _rounds=2000, bytesConstRef _salt=bytesConstRef())
Definition: AES.cpp:34
bool decrypt(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Decrypts cipher using Secret key.
Definition: Common.cpp:109
boost::error_info< struct tag_comment, std::string > errinfo_comment
Definition: Assertions.h:78
void agree(Secret const &_s, Public const &_r, Secret &o_s)
Definition: Common.cpp:348
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
bytes encryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _plain)
Encrypts payload with specified IV/ctr using AES128-CTR.
Definition: Common.cpp:163
#define e(i)
Definition: sha.cpp:733
#define d(i)
Definition: sha.cpp:732
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh(const secp256k1_context *ctx, unsigned char *result, const secp256k1_pubkey *pubkey, const unsigned char *privkey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4)
Compute an EC Diffie-Hellman secret in constant time Returns: 1: exponentiation was successful 0: sca...
Definition: main_impl.h:13
std::array< byte, N > & asArray()
Definition: FixedHash.h:148
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
Calculate SHA3-256 MAC.
Definition: SHA3.h:65
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object.
Definition: secp256k1.c:58
bool isValid() const noexcept
Definition: Common.cpp:57
Opaque data structure that holds a parsed and valid public key.
Definition: secp256k1.h:53