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
60 static const h256 s_max{
"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"};
61 static const h256 s_zero;
63 return (v <= 1 && r > s_zero && s > s_zero && r < s_max && s < s_max);
69 secp256k1_pubkey rawPubkey;
71 if (!secp256k1_ec_pubkey_create(ctx, &rawPubkey, _secret.
data()))
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
79 assert(serializedPubkeySize == serializedPubkey.size());
81 assert(serializedPubkey[0] == 0x04);
83 return Public{&serializedPubkey[1], Public::ConstructFromPointer};
104 Secp256k1PP::get()->encrypt(_k, io);
105 o_cipher = std::move(io);
111 Secp256k1PP::get()->decrypt(_k, io);
114 o_plaintext = std::move(io);
126 Secp256k1PP::get()->encryptECIES(_k, _sharedMacData, io);
127 o_cipher = std::move(io);
138 if (!Secp256k1PP::get()->
decryptECIES(_k, _sharedMacData, io))
140 o_plaintext = std::move(io);
153 return decrypt(_k, _cipher, o_plain);
158 h128 iv(Nonce::get().makeInsecure());
164 if (_k.
size() != 16 && _k.
size() != 24 && _k.
size() != 32)
166 CryptoPP::SecByteBlock key(_k.
data(), _k.
size());
169 CryptoPP::CTR_Mode<CryptoPP::AES>::Encryption e;
170 e.SetKeyWithIV(key, key.size(), _iv.
data());
172 e.ProcessData(ret.data(), _plain.
data(), _plain.
size());
175 catch (CryptoPP::Exception& _e)
177 cerr << _e.what() << endl;
184 if (_k.
size() != 16 && _k.
size() != 24 && _k.
size() != 32)
186 CryptoPP::SecByteBlock key(_k.
data(), _k.
size());
189 CryptoPP::CTR_Mode<CryptoPP::AES>::Decryption d;
190 d.SetKeyWithIV(key, key.size(), _iv.
data());
192 d.ProcessData(ret.writable().data(), _cipher.
data(), _cipher.
size());
195 catch (CryptoPP::Exception& _e)
197 cerr << _e.what() << endl;
208 auto* ctx = getCtx();
209 secp256k1_ecdsa_recoverable_signature rawSig;
210 if (!secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, &rawSig, _sig.
data(), v))
213 secp256k1_pubkey rawPubkey;
214 if (!secp256k1_ecdsa_recover(ctx, &rawPubkey, &rawSig, _message.
data()))
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
223 assert(serializedPubkeySize == serializedPubkey.size());
225 assert(serializedPubkey[0] == 0x04);
227 return Public{&serializedPubkey[1], Public::ConstructFromPointer};
230 static const u256 c_secp256k1n(
"115792089237316195423570985008687907852837564279074904382605163141518161494337");
234 auto* ctx = getCtx();
235 secp256k1_ecdsa_recoverable_signature rawSig;
236 if (!secp256k1_ecdsa_sign_recoverable(ctx, &rawSig, _hash.
data(), _k.
data(),
nullptr,
nullptr))
241 secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, s.
data(), &v, &rawSig);
244 ss.
v =
static_cast<byte>(v);
245 if (ss.s > c_secp256k1n / 2)
247 ss.v =
static_cast<byte>(ss.v ^ 1);
248 ss.s =
h256(c_secp256k1n -
u256(ss.s));
250 assert(ss.s <= c_secp256k1n / 2);
259 return _p ==
recover(_s, _hash);
265 if (CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(
266 ret.writable().data(),
269 reinterpret_cast<byte const*
>(_pass.data()),
275 BOOST_THROW_EXCEPTION(CryptoException() <<
errinfo_comment(
"Key derivation failed."));
282 if (libscrypt_scrypt(
283 reinterpret_cast<uint8_t const*>(_pass.data()),
293 BOOST_THROW_EXCEPTION(CryptoException() <<
errinfo_comment(
"Key derivation failed."));
327 sha3(s.ref(), s.ref());
329 if (!s || !_hash || !_priv)
330 BOOST_THROW_EXCEPTION(InvalidState());
341 BOOST_THROW_EXCEPTION(InvalidState());
344 return sha3(~m_value);
347 static int secp256k1_ecdh_hash_function_save_compressed(
unsigned char* output,
const unsigned char* x,
const unsigned char* y,
void*)
349 output[0] = 0x02 | (y[31] & 1);
350 std::memcpy(output+1, x, 32);
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()))
365 std::array<byte, 33> compressedPoint;
366 if (!secp256k1_ecdh(ctx, compressedPoint.data(), &rawPubkey, _s.data(), secp256k1_ecdh_hash_function_save_compressed,
nullptr))
368 std::copy(compressedPoint.begin() + 1, compressedPoint.end(), o_s.writable().data());
374 auto reps = ((kdByteLen + 7) * 8) / 512;
378 std::array<byte, 4> ctr{{0, 0, 0, 1}};
380 secp256k1_sha256 ctx;
381 for (
unsigned i = 0; i <= reps; i++)
383 secp256k1_sha256_initialize(&ctx);
384 secp256k1_sha256_write(&ctx, ctr.data(), ctr.size());
386 secp256k1_sha256_write(&ctx, _s1.data(), _s1.size());
388 std::array<byte, 32> digest;
389 secp256k1_sha256_finalize(&ctx, digest.data());
392 move(digest.begin(), digest.end(), back_inserter(k));
394 if (++ctr[3] || ++ctr[2] || ++ctr[1] || ++ctr[0])
bytesConstRef ref() const
bool agree(Secret const &_s, Public const &_r, Secret &o_s) noexcept
void encryptSym(Secret const &_k, bytesConstRef _plain, bytes &o_cipher)
Symmetric encryption.
vector_ref< _T const > ref(_T const &_t)
h160 right160(h256 const &_t)
Convert the given value into h160 (160-bit unsigned integer) using the right 20 bytes.
std::vector< unsigned char > toBytes() const
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.
bool verify(Public const &_k, Signature const &_s, h256 const &_hash)
Verify signature.
SecureFixedHash< 32 > sha3Secure(bytesConstRef _input) noexcept
secure_vector< byte > bytesSec
KeyPair(Secret const &_sec)
std::pair< bytes, h128 > encryptSymNoAuth(SecureFixedHash< 16 > const &_k, bytesConstRef _plain)
Encrypts payload with random IV/ctr using AES128-CTR.
static KeyPair create()
Create a new, randomly generated object.
SecureFixedHash< 32 > Secret
Address toAddress(std::string const &_s)
Convert the given string into an address.
void encryptECIES(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypt payload using ECIES standard with AES128-CTR.
bool sha3(bytesConstRef _input, bytesRef o_output) noexcept
Public toPublic(Secret const &_secret)
Convert a secret key into the public key equivalent.
bool decryptSym(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Symmetric decryption.
byte const * data() const
static SecureFixedHash< T > random()
std::lock_guard< std::mutex > Guard
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
std::vector< byte > bytes
vector_ref< byte const > bytesConstRef
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const &_password)
Create from an encrypted seed.
h256 kdf(Secret const &_priv, h256 const &_hash)
Key derivation.
Address toAddress(Public const &_public)
Convert a public key to address.
std::vector< T > & writable()
bytes rlpList()
Export a list of items in RLP format, returning a byte array.
bytesSec scrypt(std::string const &_pass, bytes const &_salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
Derive key via Scrypt.
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
bytesSec decryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _cipher)
Decrypts payload with specified IV/ctr using AES128-CTR.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void > > u256
void encrypt(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypts plain text using Public key.
bytes aesDecrypt(bytesConstRef _cipher, std::string const &_password, unsigned _rounds=2000, bytesConstRef _salt=bytesConstRef())
bool decrypt(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Decrypts cipher using Secret key.
Address const & address() const
Retrieve the associated address of the public key.
boost::error_info< struct tag_comment, std::string > errinfo_comment
bytes encryptAES128CTR(bytesConstRef _k, h128 const &_iv, bytesConstRef _plain)
Encrypts payload with specified IV/ctr using AES128-CTR.
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
Calculate SHA3-256 MAC.
bool isValid() const noexcept