mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Clean up CKey and RippleAddress (RIPD-672)
* Remove CKey dependency on RippleAddress * Create RAII ec_key wrapper that hides EC_KEY and other OpenSSL details * Move CKey member logic into free functions * Delete CKey class * Rename units that are no longer CKey-related * Delete code that was unused
This commit is contained in:
@@ -1,69 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/crypto/CKey.h>
|
||||
#include <ripple/types/base_uint.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// 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.
|
||||
|
||||
|
||||
// VFALCO TODO move inlined stuff from CKey into here
|
||||
|
||||
class CKey_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
run ()
|
||||
{
|
||||
uint128 seed1, seed2;
|
||||
seed1.SetHex ("71ED064155FFADFA38782C5E0158CB26");
|
||||
seed2.SetHex ("CF0C3BE4485961858C4198515AE5B965");
|
||||
CKey root1 (seed1), root2 (seed2);
|
||||
|
||||
uint256 priv1, priv2;
|
||||
root1.GetPrivateKeyU (priv1);
|
||||
root2.GetPrivateKeyU (priv2);
|
||||
|
||||
unexpected (to_string (priv1) != "7CFBA64F771E93E817E15039215430B53F7401C34931D111EAB3510B22DBB0D8",
|
||||
"Incorrect private key for generator");
|
||||
|
||||
unexpected (to_string (priv2) != "98BC2EACB26EB021D1A6293C044D88BA2F0B6729A2772DEEBF2E21A263C1740B",
|
||||
"Incorrect private key for generator");
|
||||
|
||||
RippleAddress nSeed;
|
||||
nSeed.setSeed (seed1);
|
||||
|
||||
unexpected (nSeed.humanSeed () != "shHM53KPZ87Gwdqarm1bAmPeXg8Tn",
|
||||
"Incorrect human seed");
|
||||
|
||||
unexpected (nSeed.humanSeed1751 () != "MAD BODY ACE MINT OKAY HUB WHAT DATA SACK FLAT DANA MATH",
|
||||
"Incorrect 1751 seed");
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(CKey,ripple_data,ripple);
|
||||
|
||||
} // ripple
|
||||
|
||||
124
src/ripple/crypto/impl/ECDSA.cpp
Normal file
124
src/ripple/crypto/impl/ECDSA.cpp
Normal file
@@ -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 <ripple/crypto/ECDSA.h>
|
||||
#include <ripple/crypto/ECDSACanonical.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
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
|
||||
@@ -18,8 +18,10 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/crypto/CKey.h>
|
||||
#include <ripple/crypto/ECIES.h>
|
||||
#include <ripple/crypto/RandomNumbers.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
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
|
||||
@@ -17,47 +17,34 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/crypto/GenerateDeterministicKey.h>
|
||||
|
||||
#include <ripple/crypto/CBigNum.h>
|
||||
#include <ripple/crypto/CKey.h>
|
||||
#include <ripple/protocol/Serializer.h>
|
||||
#include <string>
|
||||
|
||||
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<BIGNUM*> (&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
|
||||
114
src/ripple/crypto/impl/ec_key.cpp
Normal file
114
src/ripple/crypto/impl/ec_key.cpp
Normal file
@@ -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 <ripple/crypto/ec_key.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user