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>
47 secp256k1_context
const* getCtx()
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
56 template <std::
size_t KeySize>
57 bool toPublicKey(
Secret const& _secret,
unsigned _flags, array<byte, KeySize>& o_serializedPubkey)
60 secp256k1_pubkey rawPubkey;
62 if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.
data()))
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());
74 static const h256 s_max{
"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
75 static const h256 s_zero;
77 return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
82 std::array<byte, 65> serializedPubkey;
83 if (!toPublicKey(_secret, SECP256K1_EC_UNCOMPRESSED, serializedPubkey))
87 assert(serializedPubkey[0] == 0x04);
90 return Public{&serializedPubkey[1], Public::ConstructFromPointer};
96 if (!toPublicKey(_secret, SECP256K1_EC_COMPRESSED, serializedPubkey.
asArray()))
100 assert(serializedPubkey[0] == 0x02 || serializedPubkey[0] == 0x03);
102 return serializedPubkey;
123 Secp256k1PP::get()->encrypt(_k, io);
124 o_cipher = std::move(io);
130 Secp256k1PP::get()->decrypt(_k, io);
133 o_plaintext = std::move(io);
145 Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io);
146 o_cipher = std::move(io);
157 if (!Secp256k1PP::get()->
decryptECIES(_k, _sharedMacData, io))
159 o_plaintext = std::move(io);
172 return decrypt(_k, _cipher, o_plain);
177 h128 iv(Nonce::get().makeInsecure());
183 if (_k.
size() != 16 && _k.
size() != 24 && _k.
size() != 32)
185 CryptoPP::SecByteBlock key(_k.
data(), _k.
size());
188 CryptoPP::CTR_Mode<CryptoPP::AES>::Encryption e;
189 e.SetKeyWithIV(key, key.size(), _iv.
data());
191 e.ProcessData(ret.data(), _plain.
data(), _plain.
size());
194 catch (CryptoPP::Exception& _e)
196 cerr << _e.what() << endl;
203 if (_k.
size() != 16 && _k.
size() != 24 && _k.
size() != 32)
205 CryptoPP::SecByteBlock key(_k.
data(), _k.
size());
208 CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d;
209 d.SetKeyWithIV(key, key.size(), _iv.
data());
214 catch (CryptoPP::Exception& _e)
216 cerr << _e.what() << endl;
227 auto* ctx = getCtx();
228 secp256k1_ecdsa_recoverable_signature rawSig;
229 if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, _sig.
data(), v))
232 secp256k1_pubkey rawPubkey;
233 if (!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, _message.
data()))
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
242 assert(serializedPubkeySize == serializedPubkey.size());
244 assert(serializedPubkey[0] == 0x04);
246 return Public{&serializedPubkey[1], Public::ConstructFromPointer};
249 static const u256 c_secp256k1n(
"115792089237316195423570985008687907852837564279074904382605163141518161494337");
253 auto* ctx = getCtx();
254 secp256k1_ecdsa_recoverable_signature rawSig;
255 if (!secp256k1_ecdsa_sign_recoverable(ctx, &rawSig, _hash.
data(), _k.
data(),
nullptr,
nullptr))
260 secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, s.
data(), &v, &rawSig);
263 ss.
v =
static_cast<byte>(v);
264 if (ss.
s > c_secp256k1n / 2)
266 ss.
v =
static_cast<byte>(ss.
v ^ 1);
269 assert(ss.
s <= c_secp256k1n / 2);
278 return _p ==
recover(_s, _hash);
283 auto* ctx = getCtx();
285 secp256k1_ecdsa_signature rawSig;
286 if (!secp256k1_ecdsa_signature_parse_compact(ctx, &rawSig, _signature.
data()))
289 secp256k1_pubkey rawPubkey;
290 if (!secp256k1_ec_pubkey_parse(ctx, &rawPubkey, _key.
data(), PublicCompressed::size))
293 return secp256k1_ecdsa_verify(ctx, &rawSig, _hash.
data(), &rawPubkey);
299 if (CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(
300 ret.writable().data(),
303 reinterpret_cast<byte const*
>(_pass.data()),
309 BOOST_THROW_EXCEPTION(CryptoException() <<
errinfo_comment(
"Key derivation failed."));
316 if (libscrypt_scrypt(
317 reinterpret_cast<uint8_t const*
>(_pass.data()),
327 BOOST_THROW_EXCEPTION(CryptoException() <<
errinfo_comment(
"Key derivation failed."));
363 if (!s || !_hash || !_priv)
364 BOOST_THROW_EXCEPTION(InvalidState());
375 BOOST_THROW_EXCEPTION(InvalidState());
378 return sha3(~m_value);
381 static int secp256k1_ecdh_hash_function_save_compressed(
unsigned char* output,
const unsigned char* x,
const unsigned char* y,
void*)
383 output[0] = 0x02 | (y[31] & 1);
384 std::memcpy(output+1, x, 32);
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()))
399 std::array<byte, 33> compressedPoint;
400 if (!secp256k1_ecdh(ctx, compressedPoint.data(), &rawPubkey, _s.data(), secp256k1_ecdh_hash_function_save_compressed,
nullptr))
402 std::copy(compressedPoint.begin() + 1, compressedPoint.end(), o_s.writable().data());
408 auto reps = ((kdByteLen + 7) * 8) / 512;
412 std::array<byte, 4> ctr{{0, 0, 0, 1}};
414 secp256k1_sha256 ctx;
415 for (
unsigned i = 0; i <= reps; i++)
417 secp256k1_sha256_initialize(&ctx);
418 secp256k1_sha256_write(&ctx, ctr.data(), ctr.size());
420 secp256k1_sha256_write(&ctx, _s1.data(), _s1.size());
422 std::array<byte, 32> digest;
423 secp256k1_sha256_finalize(&ctx, digest.data());
426 move(digest.begin(), digest.end(), back_inserter(k));
428 if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0])