diff --git a/Builds/VisualStudio2013/RippleD.vcxproj b/Builds/VisualStudio2013/RippleD.vcxproj index 6a9ff3c92a..af4de2fe2c 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj +++ b/Builds/VisualStudio2013/RippleD.vcxproj @@ -2274,29 +2274,40 @@ + + + + + + + + True True - - True - - - True - - - True - True + + True + True + + True + + + True + + + True + True @@ -2309,6 +2320,9 @@ + + True + True diff --git a/Builds/VisualStudio2013/RippleD.vcxproj.filters b/Builds/VisualStudio2013/RippleD.vcxproj.filters index 31614008ed..e42e4d0403 100644 --- a/Builds/VisualStudio2013/RippleD.vcxproj.filters +++ b/Builds/VisualStudio2013/RippleD.vcxproj.filters @@ -352,6 +352,9 @@ {8EF07519-1C32-2E82-D707-702EB0157733} + + {ACAAFBB2-022D-2EAB-80CD-FBE3D9432F17} + {BEDCC703-A2C8-FF25-7E1E-3471BD39ED98} @@ -3249,30 +3252,45 @@ ripple\crypto + + ripple\crypto + ripple\crypto + + ripple\crypto + + + ripple\crypto + + + ripple\crypto + ripple\crypto\impl ripple\crypto\impl - - ripple\crypto\impl - - - ripple\crypto\impl - - - ripple\crypto\impl - ripple\crypto\impl + + ripple\crypto\impl + ripple\crypto\impl + + ripple\crypto\impl + + + ripple\crypto\impl + + + ripple\crypto\impl + ripple\crypto\impl @@ -3288,6 +3306,9 @@ ripple\crypto + + ripple\crypto\tests + ripple\json\impl diff --git a/src/ripple/crypto/CKey.h b/src/ripple/crypto/CKey.h index c5152230c9..db9ce98636 100644 --- a/src/ripple/crypto/CKey.h +++ b/src/ripple/crypto/CKey.h @@ -25,9 +25,9 @@ #ifndef RIPPLE_CRYPTO_CKEY_H_INCLUDED #define RIPPLE_CRYPTO_CKEY_H_INCLUDED -#include // VFALCO Remove this cyclic dep +#include +#include #include -#include #include #include @@ -42,288 +42,12 @@ namespace ripple { // see www.keylength.com // script supports up to 75 for single byte push -// VFALCO NOTE this is unused -/* -int static inline EC_KEY_regenerate_key(EC_KEY *eckey, BIGNUM *priv_key) -{ - int okay = 0; - BN_CTX *ctx = NULL; - EC_POINT *pub_key = NULL; - - if (!eckey) return 0; - - const EC_GROUP *group = EC_KEY_get0_group(eckey); - - if ((ctx = BN_CTX_new()) == NULL) - goto err; - - pub_key = EC_POINT_new(group); - - if (pub_key == NULL) - goto err; - - if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, ctx)) - goto err; - - EC_KEY_set_conv_form(eckey, POINT_CONVERSION_COMPRESSED); - EC_KEY_set_private_key(eckey, priv_key); - EC_KEY_set_public_key(eckey, pub_key); - - okay = 1; - -err: - - if (pub_key) - EC_POINT_free(pub_key); - if (ctx != NULL) - BN_CTX_free(ctx); - - return (okay); -} -*/ - class key_error : public std::runtime_error { public: explicit key_error (std::string const& str) : std::runtime_error (str) {} }; -class CKey -{ -protected: - EC_KEY* pkey; - bool fSet; - - -public: - typedef std::shared_ptr pointer; - - CKey () - { - pkey = EC_KEY_new_by_curve_name (NID_secp256k1); - - if (pkey == nullptr) - throw key_error ("CKey::CKey() : EC_KEY_new_by_curve_name failed"); - - EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); - - fSet = false; - } - - CKey (const CKey& b) - { - pkey = EC_KEY_dup (b.pkey); - - if (pkey == nullptr) - throw key_error ("CKey::CKey(const CKey&) : EC_KEY_dup failed"); - - EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); - - fSet = b.fSet; - } - - CKey& operator= (const CKey& b) - { - if (!EC_KEY_copy (pkey, b.pkey)) - throw key_error ("CKey::operator=(const CKey&) : EC_KEY_copy failed"); - - fSet = b.fSet; - return (*this); - } - - - ~CKey () - { - EC_KEY_free (pkey); - } - - - static uint128 PassPhraseToKey (std::string const& passPhrase); - static EC_KEY* GenerateRootDeterministicKey (const uint128& passPhrase); - static EC_KEY* GenerateRootPubKey (BIGNUM* pubGenerator); - static EC_KEY* GeneratePublicDeterministicKey (RippleAddress const& generator, int n); - static EC_KEY* GeneratePrivateDeterministicKey (RippleAddress const& family, const BIGNUM* rootPriv, int n); - static EC_KEY* GeneratePrivateDeterministicKey (RippleAddress const& family, uint256 const& rootPriv, int n); - - CKey (const uint128& passPhrase) : fSet (false) - { - pkey = GenerateRootDeterministicKey (passPhrase); - fSet = true; - assert (pkey); - } - - CKey (RippleAddress const& generator, int n) : fSet (false) - { - // public deterministic key - pkey = GeneratePublicDeterministicKey (generator, n); - fSet = true; - assert (pkey); - } - - CKey (RippleAddress const& base, const BIGNUM* rootPrivKey, int n) : fSet (false) - { - // private deterministic key - pkey = GeneratePrivateDeterministicKey (base, rootPrivKey, n); - fSet = true; - assert (pkey); - } - - CKey (uint256 const& privateKey) : pkey (nullptr), fSet (false) - { - // XXX Broken pkey is null. - SetPrivateKeyU (privateKey); - } - -#if 0 - CKey (RippleAddress const& masterKey, int keyNum, bool isPublic) : pkey (nullptr), fSet (false) - { - if (isPublic) - SetPubSeq (masterKey, keyNum); - else - SetPrivSeq (masterKey, keyNum); // broken, need seed - - fSet = true; - } -#endif - - bool IsNull () const - { - return !fSet; - } - - void MakeNewKey () - { - if (!EC_KEY_generate_key (pkey)) - throw key_error ("CKey::MakeNewKey() : EC_KEY_generate_key failed"); - - EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); - fSet = true; - } - - // XXX Still used! - BIGNUM* GetSecretBN () const - { - // DEPRECATED - return BN_dup (EC_KEY_get0_private_key (pkey)); - } - - void GetPrivateKeyU (uint256& privKey) - { - const BIGNUM* bn = EC_KEY_get0_private_key (pkey); - - if (bn == nullptr) - throw key_error ("CKey::GetPrivateKeyU: EC_KEY_get0_private_key failed"); - - privKey.zero (); - BN_bn2bin (bn, privKey.begin () + (privKey.size () - BN_num_bytes (bn))); - } - - bool SetPrivateKeyU (uint256 const& key, bool bThrow = false) - { - // XXX Broken if pkey is not set. - BIGNUM* bn = BN_bin2bn (key.begin (), key.size (), nullptr); - bool bSuccess = EC_KEY_set_private_key (pkey, bn); - - BN_clear_free (bn); - - if (bSuccess) - { - fSet = true; - } - else if (bThrow) - { - throw key_error ("CKey::SetPrivateKeyU: EC_KEY_set_private_key failed"); - } - - return bSuccess; - } - - bool SetPubKey (const void* ptr, size_t len) - { - const unsigned char* pbegin = static_cast (ptr); - - if (!o2i_ECPublicKey (&pkey, &pbegin, len)) - return false; - - EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); - fSet = true; - return true; - } - - bool SetPubKey (Blob const& vchPubKey) - { - return SetPubKey (&vchPubKey[0], vchPubKey.size ()); - } - - bool SetPubKey (std::string const& pubKey) - { - return SetPubKey (pubKey.data (), pubKey.size ()); - } - - Blob GetPubKey () const - { - unsigned int nSize = i2o_ECPublicKey (pkey, nullptr); - assert (nSize <= 33); - - if (!nSize) - throw key_error ("CKey::GetPubKey() : i2o_ECPublicKey failed"); - - Blob vchPubKey (33, 0); - unsigned char* pbegin = &vchPubKey[0]; - - if (i2o_ECPublicKey (pkey, &pbegin) != nSize) - throw key_error ("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size"); - - assert (vchPubKey.size () <= 33); - return vchPubKey; - } - - bool Sign (uint256 const& hash, Blob& vchSig) - { - unsigned char pchSig[128]; - unsigned int nSize = sizeof(pchSig)/sizeof(pchSig[0]) - 1; - - if (!ECDSA_sign (0, (unsigned char*)hash.begin (), hash.size (), pchSig, &nSize, pkey)) - return false; - - size_t len = nSize; - makeCanonicalECDSASig (pchSig, len); - vchSig.resize (len); - memcpy (&vchSig[0], pchSig, len); - - return true; - } - - bool Verify (uint256 const& hash, const void* sig, size_t sigLen) const - { - // -1 = error, 0 = bad sig, 1 = good - if (ECDSA_verify (0, hash.begin (), hash.size (), (const unsigned char*) sig, sigLen, pkey) != 1) - return false; - - return true; - } - - bool Verify (uint256 const& hash, Blob const& vchSig) const - { - return Verify (hash, &vchSig[0], vchSig.size ()); - } - - bool Verify (uint256 const& hash, std::string const& sig) const - { - return Verify (hash, sig.data (), sig.size ()); - } - - // ECIES functions. These throw on failure - - // returns a 32-byte secret unique to these two keys. At least one private key must be known. - void getECIESSecret (CKey& otherKey, uint256& enc_key, uint256& hmac_key); - - // encrypt/decrypt functions with integrity checking. - // Note that the other side must somehow know what keys to use - Blob encryptECIES (CKey& otherKey, Blob const& plaintext); - Blob decryptECIES (CKey& otherKey, Blob const& ciphertext); -}; - } // ripple #endif diff --git a/src/ripple/crypto/ECDSA.h b/src/ripple/crypto/ECDSA.h new file mode 100644 index 0000000000..54a0ecb3c9 --- /dev/null +++ b/src/ripple/crypto/ECDSA.h @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2014 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_ECDSA_H +#define RIPPLE_ECDSA_H + +#include +#include +#include + +namespace ripple { + +openssl::ec_key ECDSAPrivateKey (uint256 const& serialized); +openssl::ec_key ECDSAPublicKey (Blob const& serialized); + +Blob ECDSASign (uint256 const& hash, const openssl::ec_key& key); + +bool ECDSAVerify (uint256 const& hash, Blob const& sig, const openssl::ec_key& key); + +} // ripple + +#endif diff --git a/src/ripple/crypto/ECIES.h b/src/ripple/crypto/ECIES.h new file mode 100644 index 0000000000..f298938b9a --- /dev/null +++ b/src/ripple/crypto/ECIES.h @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2014 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_ECIES_H +#define RIPPLE_ECIES_H + +#include +#include + +namespace ripple { + +// ECIES functions. These throw on failure + +// encrypt/decrypt functions with integrity checking. +// Note that the other side must somehow know what keys to use +Blob encryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& plaintext); +Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext); + +} // ripple + +#endif diff --git a/src/ripple/crypto/GenerateDeterministicKey.h b/src/ripple/crypto/GenerateDeterministicKey.h new file mode 100644 index 0000000000..65424eaaa4 --- /dev/null +++ b/src/ripple/crypto/GenerateDeterministicKey.h @@ -0,0 +1,40 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#ifndef RIPPLE_CKEYDETERMINISTIC_H +#define RIPPLE_CKEYDETERMINISTIC_H + +#include +#include +#include + +namespace ripple { + +openssl::ec_key GenerateRootDeterministicKey (const uint128& passPhrase); +openssl::ec_key GeneratePublicDeterministicKey (Blob const& generator, int n); +openssl::ec_key GeneratePrivateDeterministicKey (Blob const& family, const BIGNUM* rootPriv, int n); + +} // ripple + +#endif diff --git a/src/ripple/crypto/ec_key.h b/src/ripple/crypto/ec_key.h new file mode 100644 index 0000000000..ad1c27fe93 --- /dev/null +++ b/src/ripple/crypto/ec_key.h @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2014 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_ECKEY_H +#define RIPPLE_ECKEY_H + +#include + +namespace ripple { +namespace openssl { + +class ec_key +{ +public: + typedef struct opaque_EC_KEY* pointer_t; + +private: + pointer_t ptr; + + void destroy(); + + ec_key (pointer_t raw) : ptr(raw) + { + } + +public: + static const ec_key invalid; + + static ec_key acquire (pointer_t raw) { return ec_key (raw); } + + //ec_key() : ptr() {} + + ec_key (const ec_key&); + ec_key& operator= (const ec_key&) = delete; + + ~ec_key() + { + destroy(); + } + + pointer_t get() const { return ptr; } + + pointer_t release() + { + pointer_t released = ptr; + + ptr = nullptr; + + return released; + } + + bool valid() const { return ptr != nullptr; } + + uint256 get_private_key() const; + + static std::size_t get_public_key_max_size() { return 33; } + + std::size_t get_public_key_size() const; + + uint8_t get_public_key (uint8* buffer) const; +}; + +} // openssl +} // ripple + +#endif diff --git a/src/ripple/crypto/impl/ECDSA.cpp b/src/ripple/crypto/impl/ECDSA.cpp new file mode 100644 index 0000000000..629434b1e0 --- /dev/null +++ b/src/ripple/crypto/impl/ECDSA.cpp @@ -0,0 +1,124 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include +#include +#include + +namespace ripple { + +using openssl::ec_key; + +static EC_KEY* new_initialized_EC_KEY() +{ + EC_KEY* key = EC_KEY_new_by_curve_name (NID_secp256k1); + + if (key == nullptr) + { + throw std::runtime_error ("new_initialized_EC_KEY() : EC_KEY_new_by_curve_name failed"); + } + + EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED); + + return key; +} + +ec_key ECDSAPrivateKey (uint256 const& serialized) +{ + EC_KEY* key = new_initialized_EC_KEY(); + + BIGNUM* bn = BN_bin2bn (serialized.begin(), serialized.size(), nullptr); + + if (bn == nullptr) + { + // leaks key + throw std::runtime_error ("ec_key::ec_key: BN_bin2bn failed"); + } + + const bool ok = EC_KEY_set_private_key (key, bn); + + BN_clear_free (bn); + + if (! ok) + { + EC_KEY_free (key); + } + + return ec_key::acquire ((ec_key::pointer_t) key); +} + +ec_key ECDSAPublicKey (Blob const& serialized) +{ + EC_KEY* key = new_initialized_EC_KEY(); + + uint8_t const* begin = &serialized[0]; + + if (o2i_ECPublicKey (&key, &begin, serialized.size()) != nullptr) + { + EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED); + } + else + { + EC_KEY_free (key); + } + + return ec_key::acquire ((ec_key::pointer_t) key); +} + +Blob ECDSASign (uint256 const& hash, const openssl::ec_key& key) +{ + Blob result; + + unsigned char sig[128]; + unsigned int siglen = sizeof sig - 1; + + const unsigned char* p = hash.begin(); + + if (ECDSA_sign (0, p, hash.size(), sig, &siglen, (EC_KEY*) key.get())) + { + size_t newlen = siglen; + + makeCanonicalECDSASig (sig, newlen); + + result.resize (newlen); + memcpy (&result[0], sig, newlen); + } + + return result; +} + +static bool ECDSAVerify (uint256 const& hash, uint8 const* sig, size_t sigLen, EC_KEY* key) +{ + // -1 = error, 0 = bad sig, 1 = good + return ECDSA_verify (0, hash.begin(), hash.size(), sig, sigLen, key) > 0; +} + +bool ECDSAVerify (uint256 const& hash, Blob const& sig, const openssl::ec_key& key) +{ + return ECDSAVerify (hash, sig.data(), sig.size(), (EC_KEY*) key.get()); +} + +} // ripple diff --git a/src/ripple/crypto/impl/CKeyECIES.cpp b/src/ripple/crypto/impl/ECIES.cpp similarity index 83% rename from src/ripple/crypto/impl/CKeyECIES.cpp rename to src/ripple/crypto/impl/ECIES.cpp index 83120d7e1d..e11d998c75 100644 --- a/src/ripple/crypto/impl/CKeyECIES.cpp +++ b/src/ripple/crypto/impl/ECIES.cpp @@ -18,8 +18,10 @@ //============================================================================== #include +#include #include #include +#include #include namespace ripple { @@ -63,25 +65,20 @@ namespace ripple { #define ECIES_HMAC_TYPE uint256 // Type used to hold HMAC value #define ECIES_HMAC_SIZE (256/8) // Size of HMAC value -void CKey::getECIESSecret (CKey& otherKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key) +// returns a 32-byte secret unique to these two keys. At least one private key must be known. +static void getECIESSecret (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, ECIES_ENC_KEY_TYPE& enc_key, ECIES_HMAC_KEY_TYPE& hmac_key) { + EC_KEY* privkey = (EC_KEY*) secretKey.get(); + EC_KEY* pubkey = (EC_KEY*) publicKey.get(); + // Retrieve a secret generated from an EC key pair. At least one private key must be known. - if (!pkey || !otherKey.pkey) + if (privkey == nullptr || pubkey == nullptr) throw std::runtime_error ("missing key"); - EC_KEY* pubkey, *privkey; - - if (EC_KEY_get0_private_key (pkey)) + if (! EC_KEY_get0_private_key (privkey)) { - privkey = pkey; - pubkey = otherKey.pkey; + throw std::runtime_error ("not a private key"); } - else if (EC_KEY_get0_private_key (otherKey.pkey)) - { - privkey = otherKey.pkey; - pubkey = pkey; - } - else throw std::runtime_error ("no private key"); unsigned char rawbuf[512]; int buflen = ECDH_compute_key (rawbuf, 512, EC_KEY_get0_public_key (pubkey), privkey, nullptr); @@ -131,7 +128,7 @@ static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const& return ret; } -Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext) +Blob encryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& plaintext) { ECIES_ENC_IV_TYPE iv; @@ -140,7 +137,7 @@ Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext) ECIES_ENC_KEY_TYPE secret; ECIES_HMAC_KEY_TYPE hmacKey; - getECIESSecret (otherKey, secret, hmacKey); + getECIESSecret (secretKey, publicKey, secret, hmacKey); ECIES_HMAC_TYPE hmac = makeHMAC (hmacKey, plaintext); hmacKey.zero (); @@ -206,7 +203,7 @@ Blob CKey::encryptECIES (CKey& otherKey, Blob const& plaintext) return out; } -Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext) +Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext) { // minimum ciphertext = IV + HMAC + 1 block if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) ) @@ -222,7 +219,7 @@ Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext) ECIES_ENC_KEY_TYPE secret; ECIES_HMAC_KEY_TYPE hmacKey; - getECIESSecret (otherKey, secret, hmacKey); + getECIESSecret (secretKey, publicKey, secret, hmacKey); if (EVP_DecryptInit_ex (&ctx, ECIES_ENC_ALGO, nullptr, secret.begin (), iv.begin ()) != 1) { @@ -288,46 +285,4 @@ Blob CKey::decryptECIES (CKey& otherKey, Blob const& ciphertext) return plaintext; } -bool checkECIES (void) -{ - CKey senderPriv, recipientPriv, senderPub, recipientPub; - - for (int i = 0; i < 30000; ++i) - { - if ((i % 100) == 0) - { - // generate new keys every 100 times - senderPriv.MakeNewKey (); - recipientPriv.MakeNewKey (); - - if (!senderPub.SetPubKey (senderPriv.GetPubKey ())) - throw std::runtime_error ("key error"); - - if (!recipientPub.SetPubKey (recipientPriv.GetPubKey ())) - throw std::runtime_error ("key error"); - } - - // generate message - Blob message (4096); - int msglen = i % 3000; - - RandomNumbers::getInstance ().fillBytes (&message.front (), msglen); - message.resize (msglen); - - // encrypt message with sender's private key and recipient's public key - Blob ciphertext = senderPriv.encryptECIES (recipientPub, message); - - // decrypt message with recipient's private key and sender's public key - Blob decrypt = recipientPriv.decryptECIES (senderPub, ciphertext); - - if (decrypt != message) - { - assert (false); - return false; - } - } - - return true; -} - } // ripple diff --git a/src/ripple/crypto/impl/CKeyDeterministic.cpp b/src/ripple/crypto/impl/GenerateDeterministicKey.cpp similarity index 81% rename from src/ripple/crypto/impl/CKeyDeterministic.cpp rename to src/ripple/crypto/impl/GenerateDeterministicKey.cpp index 667b106b34..a85d935020 100644 --- a/src/ripple/crypto/impl/CKeyDeterministic.cpp +++ b/src/ripple/crypto/impl/GenerateDeterministicKey.cpp @@ -17,47 +17,34 @@ */ //============================================================================== +#include + #include -#include #include #include namespace ripple { +using openssl::ec_key; + // #define EC_DEBUG -// Functions to add CKey support for deterministic EC keys - -// <-- seed -uint128 CKey::PassPhraseToKey (std::string const& passPhrase) -{ - // VFALCO NOTE This is a bad dependency, CKey shouldn't need it - Serializer s; - - s.addRaw (passPhrase); - // NIKB TODO this caling sequence is a bit ugly; this should be improved. - uint256 hash256 = s.getSHA512Half (); - uint128 ret (uint128::fromVoid (hash256.data())); - - s.secureErase (); - - return ret; -} +// Functions to add support for deterministic EC keys // --> seed // <-- private root generator + public root generator -EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) +ec_key GenerateRootDeterministicKey (uint128 const& seed) { BN_CTX* ctx = BN_CTX_new (); - if (!ctx) return nullptr; + if (!ctx) return ec_key::invalid; EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1); if (!pkey) { BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); @@ -68,7 +55,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) { BN_CTX_free (ctx); EC_KEY_free (pkey); - return nullptr; + return ec_key::invalid; } if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx)) @@ -77,7 +64,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) BN_free (order); EC_KEY_free (pkey); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } BIGNUM* privKey = nullptr; @@ -98,7 +85,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) EC_KEY_free (pkey); BN_free (order); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } root.zero (); @@ -114,7 +101,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) EC_KEY_free (pkey); BN_clear_free (privKey); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey)); @@ -127,7 +114,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) EC_POINT_free (pubKey); EC_KEY_free (pkey); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } BN_clear_free (privKey); @@ -138,7 +125,7 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) EC_POINT_free (pubKey); EC_KEY_free (pkey); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } EC_POINT_free (pubKey); @@ -148,13 +135,13 @@ EC_KEY* CKey::GenerateRootDeterministicKey (uint128 const& seed) #ifdef EC_DEBUG assert (EC_KEY_check_key (pkey) == 1); // CAUTION: This check is *very* expensive #endif - return pkey; + return ec_key::acquire ((ec_key::pointer_t) pkey); } // Take ripple address. // --> root public generator (consumes) // <-- root public generator in EC format -EC_KEY* CKey::GenerateRootPubKey (BIGNUM* pubGenerator) +static EC_KEY* GenerateRootPubKey (BIGNUM* pubGenerator) { if (pubGenerator == nullptr) { @@ -196,7 +183,7 @@ EC_KEY* CKey::GenerateRootPubKey (BIGNUM* pubGenerator) } // --> public generator -static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* order) +static BIGNUM* makeHash (Blob const& pubGen, int seq, BIGNUM const* order) { int subSeq = 0; BIGNUM* ret = nullptr; @@ -204,7 +191,7 @@ static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* ord do { Serializer s ((33 * 8 + 32 + 32) / 8); - s.addRaw (pubGen.getGenerator ()); + s.addRaw (pubGen); s.add32 (seq); s.add32 (subSeq++); uint256 root = s.getSHA512Half (); @@ -219,18 +206,18 @@ static BIGNUM* makeHash (RippleAddress const& pubGen, int seq, BIGNUM const* ord } // --> public generator -EC_KEY* CKey::GeneratePublicDeterministicKey (RippleAddress const& pubGen, int seq) +ec_key GeneratePublicDeterministicKey (Blob const& pubGen, int seq) { // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point BIGNUM* generator = BN_bin2bn ( - pubGen.getGenerator ().data (), - pubGen.getGenerator ().size (), + pubGen.data(), + pubGen.size(), nullptr); if (generator == nullptr) - return nullptr; + return ec_key::invalid; - EC_KEY* rootKey = CKey::GenerateRootPubKey (generator); + EC_KEY* rootKey = GenerateRootPubKey (generator); const EC_POINT* rootPubKey = EC_KEY_get0_public_key (rootKey); BN_CTX* ctx = BN_CTX_new (); EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1); @@ -289,29 +276,23 @@ EC_KEY* CKey::GeneratePublicDeterministicKey (RippleAddress const& pubGen, int s if (pkey && !success) EC_KEY_free (pkey); - return success ? pkey : nullptr; -} - -EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, uint256 const& u, int seq) -{ - CBigNum bn (u); - return GeneratePrivateDeterministicKey (pubGen, static_cast (&bn), seq); + return success ? ec_key::acquire ((ec_key::pointer_t) pkey) : ec_key::invalid; } // --> root private key -EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, const BIGNUM* rootPrivKey, int seq) +ec_key GeneratePrivateDeterministicKey (Blob const& pubGen, const BIGNUM* rootPrivKey, int seq) { // privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order BN_CTX* ctx = BN_CTX_new (); - if (ctx == nullptr) return nullptr; + if (ctx == nullptr) return ec_key::invalid; EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1); if (pkey == nullptr) { BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED); @@ -322,7 +303,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons { BN_CTX_free (ctx); EC_KEY_free (pkey); - return nullptr; + return ec_key::invalid; } if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx)) @@ -330,7 +311,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons BN_free (order); BN_CTX_free (ctx); EC_KEY_free (pkey); - return nullptr; + return ec_key::invalid; } // calculate the private additional key @@ -341,7 +322,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons BN_free (order); BN_CTX_free (ctx); EC_KEY_free (pkey); - return nullptr; + return ec_key::invalid; } // calculate the final private key @@ -357,7 +338,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons BN_clear_free (privKey); BN_CTX_free (ctx); EC_KEY_free (pkey); - return nullptr; + return ec_key::invalid; } if (EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, nullptr, nullptr, ctx) == 0) @@ -366,7 +347,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons EC_POINT_free (pubKey); EC_KEY_free (pkey); BN_CTX_free (ctx); - return nullptr; + return ec_key::invalid; } BN_clear_free (privKey); @@ -375,7 +356,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey (RippleAddress const& pubGen, cons EC_POINT_free (pubKey); BN_CTX_free (ctx); - return pkey; + return ec_key::acquire ((ec_key::pointer_t) pkey); } } // ripple diff --git a/src/ripple/crypto/impl/ec_key.cpp b/src/ripple/crypto/impl/ec_key.cpp new file mode 100644 index 0000000000..98434df68c --- /dev/null +++ b/src/ripple/crypto/impl/ec_key.cpp @@ -0,0 +1,114 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2012, 2013 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2011 The Bitcoin developers +// Distributed under the MIT/X11 software license, see the accompanying +// file license.txt or http://www.opensource.org/licenses/mit-license.php. + +#include +#include + +namespace ripple { +namespace openssl { + +static inline EC_KEY* get_EC_KEY (const ec_key& that) +{ + return (EC_KEY*) that.get(); +} + +const ec_key ec_key::invalid = ec_key::acquire (nullptr); + +ec_key::ec_key (const ec_key& that) +{ + if (that.ptr == nullptr) + { + ptr = nullptr; + return; + } + + ptr = (pointer_t) EC_KEY_dup (get_EC_KEY (that)); + + if (ptr == nullptr) + { + throw std::runtime_error ("ec_key::ec_key() : EC_KEY_dup failed"); + } + + EC_KEY_set_conv_form (get_EC_KEY (*this), POINT_CONVERSION_COMPRESSED); +} + +void ec_key::destroy() +{ + if (ptr != nullptr) + { + EC_KEY_free (get_EC_KEY (*this)); + ptr = nullptr; + } +} + +uint256 ec_key::get_private_key() const +{ + uint256 result; + result.zero(); + + if (valid()) + { + const BIGNUM* bn = EC_KEY_get0_private_key (get_EC_KEY (*this)); + + if (bn == nullptr) + { + throw std::runtime_error ("ec_key::get_private_key: EC_KEY_get0_private_key failed"); + } + + BN_bn2bin (bn, result.end() - BN_num_bytes (bn)); + } + + return result; +} + +std::size_t ec_key::get_public_key_size() const +{ + int const size = i2o_ECPublicKey (get_EC_KEY (*this), nullptr); + + if (size == 0) + { + throw std::runtime_error ("ec_key::get_public_key_size() : i2o_ECPublicKey failed"); + } + + if (size > get_public_key_max_size()) + { + throw std::runtime_error ("ec_key::get_public_key_size() : i2o_ECPublicKey() result too big"); + } + + return size; +} + +uint8_t ec_key::get_public_key (uint8* buffer) const +{ + uint8_t* begin = buffer; + + int const size = i2o_ECPublicKey (get_EC_KEY (*this), &begin); + + assert (size == get_public_key_size()); + + return uint8_t (size); +} + +} // openssl +} // ripple diff --git a/src/ripple/crypto/impl/CKey.cpp b/src/ripple/crypto/tests/CKey.test.cpp similarity index 87% rename from src/ripple/crypto/impl/CKey.cpp rename to src/ripple/crypto/tests/CKey.test.cpp index c1bd1d4bff..5809685d8b 100644 --- a/src/ripple/crypto/impl/CKey.cpp +++ b/src/ripple/crypto/tests/CKey.test.cpp @@ -17,7 +17,8 @@ */ //============================================================================== -#include +#include +#include #include #include @@ -29,8 +30,6 @@ namespace ripple { // file license.txt or http://www.opensource.org/licenses/mit-license.php. -// VFALCO TODO move inlined stuff from CKey into here - class CKey_test : public beast::unit_test::suite { public: @@ -40,11 +39,12 @@ public: uint128 seed1, seed2; seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26"); seed2.SetHex ("CF0C3BE4485961858C4198515AE5B965"); - CKey root1 (seed1), root2 (seed2); - uint256 priv1, priv2; - root1.GetPrivateKeyU (priv1); - root2.GetPrivateKeyU (priv2); + openssl::ec_key root1 = GenerateRootDeterministicKey (seed1); + openssl::ec_key root2 = GenerateRootDeterministicKey (seed2); + + uint256 const priv1 = root1.get_private_key(); + uint256 const priv2 = root2.get_private_key(); unexpected (to_string (priv1) != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8", "Incorrect private key for generator"); diff --git a/src/ripple/protocol/RippleAddress.h b/src/ripple/protocol/RippleAddress.h index 742b538693..e691feefa8 100644 --- a/src/ripple/protocol/RippleAddress.h +++ b/src/ripple/protocol/RippleAddress.h @@ -67,8 +67,6 @@ public: void clear (); bool isSet () const; - std::string humanAddressType () const; - // // Node Public - Also used for Validators // diff --git a/src/ripple/protocol/impl/RippleAddress.cpp b/src/ripple/protocol/impl/RippleAddress.cpp index 285f3c8521..56e00d427a 100644 --- a/src/ripple/protocol/impl/RippleAddress.cpp +++ b/src/ripple/protocol/impl/RippleAddress.cpp @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -32,6 +34,48 @@ namespace ripple { +static BIGNUM* GetSecretBN (const openssl::ec_key& keypair) +{ + // DEPRECATED + return BN_dup (EC_KEY_get0_private_key ((EC_KEY*) keypair.get())); +} + +// <-- seed +static uint128 PassPhraseToKey (std::string const& passPhrase) +{ + Serializer s; + + s.addRaw (passPhrase); + // NIKB TODO this caling sequence is a bit ugly; this should be improved. + uint256 hash256 = s.getSHA512Half (); + uint128 ret (uint128::fromVoid (hash256.data())); + + s.secureErase (); + + return ret; +} + +static Blob getPublicKey (openssl::ec_key const& key) +{ + Blob result (33); + + key.get_public_key (&result[0]); + + return result; +} + +static bool verifySignature (Blob const& pubkey, uint256 const& hash, Blob const& sig, ECDSA fullyCanonical) +{ + if (! isCanonicalECDSASig (sig, fullyCanonical)) + { + return false; + } + + openssl::ec_key key = ECDSAPublicKey (pubkey); + + return key.valid() && ECDSAVerify (hash, sig, key); +} + RippleAddress::RippleAddress () : mIsValid (false) { @@ -50,43 +94,11 @@ bool RippleAddress::isSet () const return nVersion != VER_NONE; } -std::string RippleAddress::humanAddressType () const -{ - switch (nVersion) - { - case VER_NONE: - return "VER_NONE"; - - case VER_NODE_PUBLIC: - return "VER_NODE_PUBLIC"; - - case VER_NODE_PRIVATE: - return "VER_NODE_PRIVATE"; - - case VER_ACCOUNT_ID: - return "VER_ACCOUNT_ID"; - - case VER_ACCOUNT_PUBLIC: - return "VER_ACCOUNT_PUBLIC"; - - case VER_ACCOUNT_PRIVATE: - return "VER_ACCOUNT_PRIVATE"; - - case VER_FAMILY_GENERATOR: - return "VER_FAMILY_GENERATOR"; - - case VER_FAMILY_SEED: - return "VER_FAMILY_SEED"; - } - - return "unknown"; -} - // // NodePublic // -uint160 Hash160 (Blob const& vch) +static uint160 Hash160 (Blob const& vch) { uint256 hash1; SHA256 (vch.data (), vch.size (), hash1.data ()); @@ -99,11 +111,10 @@ uint160 Hash160 (Blob const& vch) RippleAddress RippleAddress::createNodePublic (RippleAddress const& naSeed) { - CKey ckSeed (naSeed.getSeed ()); RippleAddress naNew; // YYY Should there be a GetPubKey() equiv that returns a uint256? - naNew.setNodePublic (ckSeed.GetPubKey ()); + naNew.setNodePublic (getPublicKey (GenerateRootDeterministicKey (naSeed.getSeed()))); return naNew; } @@ -191,22 +202,7 @@ void RippleAddress::setNodePublic (Blob const& vPublic) bool RippleAddress::verifyNodePublic (uint256 const& hash, Blob const& vchSig, ECDSA fullyCanonical) const { - CKey pubkey = CKey (); - bool bVerified; - - bVerified = isCanonicalECDSASig (vchSig, fullyCanonical); - - if (bVerified && !pubkey.SetPubKey (getNodePublic ())) - { - // Failed to set public key. - bVerified = false; - } - else - { - bVerified = pubkey.Verify (hash, vchSig); - } - - return bVerified; + return verifySignature (getNodePublic(), hash, vchSig, fullyCanonical); } bool RippleAddress::verifyNodePublic (uint256 const& hash, std::string const& strSig, ECDSA fullyCanonical) const @@ -222,13 +218,9 @@ bool RippleAddress::verifyNodePublic (uint256 const& hash, std::string const& st RippleAddress RippleAddress::createNodePrivate (RippleAddress const& naSeed) { - uint256 uPrivKey; RippleAddress naNew; - CKey ckSeed (naSeed.getSeed ()); - ckSeed.GetPrivateKeyU (uPrivKey); - - naNew.setNodePrivate (uPrivKey); + naNew.setNodePrivate (GenerateRootDeterministicKey (naSeed.getSeed()).get_private_key()); return naNew; } @@ -301,11 +293,11 @@ void RippleAddress::setNodePrivate (uint256 hash256) void RippleAddress::signNodePrivate (uint256 const& hash, Blob& vchSig) const { - CKey ckPrivKey; + openssl::ec_key key = ECDSAPrivateKey (getNodePrivate()); + + vchSig = ECDSASign (hash, key); - ckPrivKey.SetPrivateKeyU (getNodePrivate ()); - - if (!ckPrivKey.Sign (hash, vchSig)) + if (vchSig.empty()) throw std::runtime_error ("Signing failed."); } @@ -412,10 +404,9 @@ void RippleAddress::setAccountID (Account const& hash160) RippleAddress RippleAddress::createAccountPublic ( RippleAddress const& generator, int iSeq) { - CKey ckPub (generator, iSeq); RippleAddress naNew; - naNew.setAccountPublic (ckPub.GetPubKey ()); + naNew.setAccountPublic (getPublicKey (GeneratePublicDeterministicKey (generator.getGenerator(), iSeq))); return naNew; } @@ -473,31 +464,13 @@ void RippleAddress::setAccountPublic (Blob const& vPublic) void RippleAddress::setAccountPublic (RippleAddress const& generator, int seq) { - CKey pubkey = CKey (generator, seq); - - setAccountPublic (pubkey.GetPubKey ()); + setAccountPublic (getPublicKey (GeneratePublicDeterministicKey (generator.getGenerator(), seq))); } bool RippleAddress::accountPublicVerify ( uint256 const& uHash, Blob const& vucSig, ECDSA fullyCanonical) const { - CKey ckPublic; - - bool bVerified = isCanonicalECDSASig (vucSig, fullyCanonical); - - if (bVerified && !ckPublic.SetPubKey (getAccountPublic ())) - { - // Bad private key. - WriteLog (lsWARNING, RippleAddress) - << "accountPublicVerify: Bad private key."; - bVerified = false; - } - else - { - bVerified = ckPublic.Verify (uHash, vucSig); - } - - return bVerified; + return verifySignature (getAccountPublic(), uHash, vucSig, fullyCanonical); } RippleAddress RippleAddress::createAccountID (Account const& account) @@ -575,59 +548,58 @@ void RippleAddress::setAccountPrivate (uint256 hash256) void RippleAddress::setAccountPrivate ( RippleAddress const& generator, RippleAddress const& naSeed, int seq) { - CKey ckPubkey = CKey (naSeed.getSeed ()); - CKey ckPrivkey = CKey (generator, ckPubkey.GetSecretBN (), seq); - uint256 uPrivKey; - - ckPrivkey.GetPrivateKeyU (uPrivKey); - - setAccountPrivate (uPrivKey); + openssl::ec_key publicKey = GenerateRootDeterministicKey (naSeed.getSeed()); + openssl::ec_key secretKey = GeneratePrivateDeterministicKey (generator.getGenerator(), GetSecretBN (publicKey), seq); + + setAccountPrivate (secretKey.get_private_key()); } bool RippleAddress::accountPrivateSign (uint256 const& uHash, Blob& vucSig) const { - CKey ckPrivate; - bool bResult; - - if (!ckPrivate.SetPrivateKeyU (getAccountPrivate ())) + openssl::ec_key key = ECDSAPrivateKey (getAccountPrivate()); + + if (!key.valid()) { // Bad private key. WriteLog (lsWARNING, RippleAddress) << "accountPrivateSign: Bad private key."; - bResult = false; - } - else - { - bResult = ckPrivate.Sign (uHash, vucSig); - CondLog (!bResult, lsWARNING, RippleAddress) - << "accountPrivateSign: Signing failed."; + + return false; } + + vucSig = ECDSASign (uHash, key); + const bool ok = !vucSig.empty(); + + CondLog (!ok, lsWARNING, RippleAddress) + << "accountPrivateSign: Signing failed."; - return bResult; + return ok; } Blob RippleAddress::accountPrivateEncrypt ( RippleAddress const& naPublicTo, Blob const& vucPlainText) const { - CKey ckPrivate; - CKey ckPublic; + openssl::ec_key secretKey = ECDSAPrivateKey (getAccountPrivate()); + openssl::ec_key publicKey = ECDSAPublicKey (naPublicTo.getAccountPublic()); + Blob vucCipherText; - if (!ckPublic.SetPubKey (naPublicTo.getAccountPublic ())) + if (! publicKey.valid()) { WriteLog (lsWARNING, RippleAddress) << "accountPrivateEncrypt: Bad public key."; } - else if (!ckPrivate.SetPrivateKeyU (getAccountPrivate ())) + + if (! secretKey.valid()) { WriteLog (lsWARNING, RippleAddress) << "accountPrivateEncrypt: Bad private key."; } - else + { try { - vucCipherText = ckPrivate.encryptECIES (ckPublic, vucPlainText); + vucCipherText = encryptECIES (secretKey, publicKey, vucPlainText); } catch (...) { @@ -640,25 +612,27 @@ Blob RippleAddress::accountPrivateEncrypt ( Blob RippleAddress::accountPrivateDecrypt ( RippleAddress const& naPublicFrom, Blob const& vucCipherText) const { - CKey ckPrivate; - CKey ckPublic; + openssl::ec_key secretKey = ECDSAPrivateKey (getAccountPrivate()); + openssl::ec_key publicKey = ECDSAPublicKey (naPublicFrom.getAccountPublic()); + Blob vucPlainText; - if (!ckPublic.SetPubKey (naPublicFrom.getAccountPublic ())) + if (! publicKey.valid()) { WriteLog (lsWARNING, RippleAddress) << "accountPrivateDecrypt: Bad public key."; } - else if (!ckPrivate.SetPrivateKeyU (getAccountPrivate ())) + + if (! secretKey.valid()) { WriteLog (lsWARNING, RippleAddress) << "accountPrivateDecrypt: Bad private key."; } - else + { try { - vucPlainText = ckPrivate.decryptECIES (ckPublic, vucCipherText); + vucPlainText = decryptECIES (secretKey, publicKey, vucCipherText); } catch (...) { @@ -719,9 +693,8 @@ void RippleAddress::setGenerator (Blob const& vPublic) RippleAddress RippleAddress::createGeneratorPublic (RippleAddress const& naSeed) { - CKey ckSeed (naSeed.getSeed ()); RippleAddress naNew; - naNew.setGenerator (ckSeed.GetPubKey ()); + naNew.setGenerator (getPublicKey (GenerateRootDeterministicKey (naSeed.getSeed()))); return naNew; } @@ -839,7 +812,7 @@ bool RippleAddress::setSeedGeneric (std::string const& strText) } else { - setSeed (CKey::PassPhraseToKey (strText)); + setSeed (PassPhraseToKey (strText)); } return bResult; diff --git a/src/ripple/unity/crypto.cpp b/src/ripple/unity/crypto.cpp index b196eaf788..00c80f19c1 100644 --- a/src/ripple/unity/crypto.cpp +++ b/src/ripple/unity/crypto.cpp @@ -25,10 +25,12 @@ #include #include -#include -#include -#include #include +#include +#include #include +#include +#include #include #include +#include