mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Refactor GenerateDeterministicKey and its call sites:
Remove the use of ec_key parameters and return values from ECDSA crypto
prototypes. Don't store key data into an ec_key variable only to fetch
it back into the original type again. Use uint256 and Blob explicitly.
Pass private keys as uint256, and pass public keys as either pointer and
length or Blob in calls to ECDSA{Sign,Verify}() and {en,de}cryptECIES().
Replace GenerateRootDeterministicKey() with separate functions returning
either the public or private key, since no caller needs both at once.
Simplify the use of GenerateDeterministicKey within RippleAddress. Call
a single routine rather than pass the result of one as input to another.
Add openssl unit with RAII classes for bignum, bn_ctx, and ec_point plus
free utility functions.
Rewrite the functions in GenerateDeterministicKey.cpp to use RAII rather
than explicit cleanup code:
* factor out secp256k1_group and secp256k1_order for reuse rather than
computing them each time
* replace getPublicKey() with serialize_ec_point(), which makes, sets,
and destroys an ec_key internally (sparing the caller those details)
and calls i2o_ECPublicKey() directly
* return bignum rather than ec_key from GenerateRootDeterministicKey()
* return ec_point rather than EC_KEY* from GenerateRootPubKey()
Move ECDSA{Private,Public}Key() to a new ECDSAKey unit.
Move ec_key.h into impl/ since it's no longer used outside crypto/.
Remove now-unused member functions from ec_key.
Change tabs to spaces; trim trailing whitespace (including blank lines).
This commit is contained in:
committed by
Tom Ritchford
parent
be44f75d2d
commit
7a6d533014
@@ -25,6 +25,8 @@
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/crypto/ECDSA.h>
|
||||
#include <ripple/crypto/ECDSACanonical.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
#include <ripple/crypto/impl/ECDSAKey.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <openssl/hmac.h>
|
||||
@@ -34,63 +36,7 @@ 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();
|
||||
|
||||
std::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)
|
||||
static Blob ECDSASign (uint256 const& hash, const openssl::ec_key& key)
|
||||
{
|
||||
Blob result;
|
||||
|
||||
@@ -112,15 +58,28 @@ Blob ECDSASign (uint256 const& hash, const openssl::ec_key& key)
|
||||
return result;
|
||||
}
|
||||
|
||||
Blob ECDSASign (uint256 const& hash, uint256 const& key)
|
||||
{
|
||||
return ECDSASign (hash, ECDSAPrivateKey (key));
|
||||
}
|
||||
|
||||
static bool ECDSAVerify (uint256 const& hash, std::uint8_t 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)
|
||||
static bool ECDSAVerify (uint256 const& hash, Blob const& sig, const openssl::ec_key& key)
|
||||
{
|
||||
return ECDSAVerify (hash, sig.data(), sig.size(), (EC_KEY*) key.get());
|
||||
}
|
||||
|
||||
bool ECDSAVerify (uint256 const& hash,
|
||||
Blob const& sig,
|
||||
std::uint8_t const* key_data,
|
||||
std::size_t key_size)
|
||||
{
|
||||
return ECDSAVerify (hash, sig, ECDSAPublicKey (key_data, key_size));
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
92
src/ripple/crypto/impl/ECDSAKey.cpp
Normal file
92
src/ripple/crypto/impl/ECDSAKey.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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 <BeastConfig.h>
|
||||
#include <ripple/crypto/impl/ECDSAKey.h>
|
||||
#include <openssl/ec.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)
|
||||
{
|
||||
BIGNUM* bn = BN_bin2bn (serialized.begin(), serialized.size(), nullptr);
|
||||
|
||||
if (bn == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("ec_key::ec_key: BN_bin2bn failed");
|
||||
}
|
||||
|
||||
EC_KEY* key = new_initialized_EC_KEY();
|
||||
|
||||
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 (std::uint8_t const* data, std::size_t size)
|
||||
{
|
||||
EC_KEY* key = new_initialized_EC_KEY();
|
||||
|
||||
if (o2i_ECPublicKey (&key, &data, 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);
|
||||
}
|
||||
|
||||
ec_key ECDSAPublicKey (Blob const& serialized)
|
||||
{
|
||||
return ECDSAPublicKey (&serialized[0], serialized.size());
|
||||
}
|
||||
|
||||
} // ripple
|
||||
36
src/ripple/crypto/impl/ECDSAKey.h
Normal file
36
src/ripple/crypto/impl/ECDSAKey.h
Normal file
@@ -0,0 +1,36 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_ECDSAKEY_H
|
||||
#define RIPPLE_ECDSAKEY_H
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/basics/Blob.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
openssl::ec_key ECDSAPrivateKey (uint256 const& serialized);
|
||||
openssl::ec_key ECDSAPublicKey (Blob const& serialized);
|
||||
|
||||
openssl::ec_key ECDSAPublicKey (std::uint8_t const* data, std::size_t size);
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/crypto/ECIES.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
#include <ripple/crypto/impl/ECDSAKey.h>
|
||||
#include <ripple/crypto/RandomNumbers.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
@@ -97,6 +99,14 @@ static void getECIESSecret (const openssl::ec_key& secretKey, const openssl::ec_
|
||||
memset (hbuf, 0, ECIES_KEY_LENGTH);
|
||||
}
|
||||
|
||||
static void getECIESSecret (uint256 const& secretKey,
|
||||
Blob const& publicKey,
|
||||
ECIES_ENC_KEY_TYPE& enc_key,
|
||||
ECIES_HMAC_KEY_TYPE& hmac_key)
|
||||
{
|
||||
getECIESSecret (ECDSAPrivateKey (secretKey), ECDSAPublicKey (publicKey), enc_key, hmac_key);
|
||||
}
|
||||
|
||||
static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const& data)
|
||||
{
|
||||
HMAC_CTX ctx;
|
||||
@@ -129,7 +139,7 @@ static ECIES_HMAC_TYPE makeHMAC (const ECIES_HMAC_KEY_TYPE& secret, Blob const&
|
||||
return ret;
|
||||
}
|
||||
|
||||
Blob encryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& plaintext)
|
||||
Blob encryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& plaintext)
|
||||
{
|
||||
|
||||
ECIES_ENC_IV_TYPE iv;
|
||||
@@ -204,7 +214,7 @@ Blob encryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publ
|
||||
return out;
|
||||
}
|
||||
|
||||
Blob decryptECIES (const openssl::ec_key& secretKey, const openssl::ec_key& publicKey, Blob const& ciphertext)
|
||||
Blob decryptECIES (uint256 const& secretKey, Blob const& publicKey, Blob const& ciphertext)
|
||||
{
|
||||
// minimum ciphertext = IV + HMAC + 1 block
|
||||
if (ciphertext.size () < ((2 * ECIES_ENC_BLK_SIZE) + ECIES_HMAC_SIZE) )
|
||||
|
||||
@@ -19,23 +19,38 @@
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/crypto/GenerateDeterministicKey.h>
|
||||
#include <ripple/crypto/Base58.h>
|
||||
#include <ripple/crypto/CBigNum.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
#include <ripple/crypto/impl/openssl.h>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using openssl::ec_key;
|
||||
namespace openssl {
|
||||
|
||||
static EC_GROUP const* const secp256k1_group = EC_GROUP_new_by_curve_name (NID_secp256k1);
|
||||
static bignum const secp256k1_order = get_order (secp256k1_group);
|
||||
|
||||
} // namespace openssl
|
||||
|
||||
using namespace openssl;
|
||||
|
||||
static Blob serialize_ec_point (ec_point const& point)
|
||||
{
|
||||
Blob result (33);
|
||||
|
||||
serialize_ec_point (point, &result[0]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint256
|
||||
getSHA512Half (void const* data, std::size_t bytes)
|
||||
{
|
||||
uint256 j[2];
|
||||
SHA512 (reinterpret_cast<unsigned char const*>(data), bytes,
|
||||
SHA512 (reinterpret_cast<unsigned char const*>(data), bytes,
|
||||
reinterpret_cast<unsigned char*> (j));
|
||||
return j[0];
|
||||
}
|
||||
@@ -56,43 +71,12 @@ copy_uint32 (FwdIt out, std::uint32_t v)
|
||||
|
||||
// --> seed
|
||||
// <-- private root generator + public root generator
|
||||
ec_key GenerateRootDeterministicKey (uint128 const& seed)
|
||||
static bignum GenerateRootDeterministicKey (uint128 const& seed)
|
||||
{
|
||||
BN_CTX* ctx = BN_CTX_new ();
|
||||
|
||||
if (!ctx) return ec_key::invalid;
|
||||
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
if (!pkey)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
BIGNUM* order = BN_new ();
|
||||
|
||||
if (!order)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
{
|
||||
assert (false);
|
||||
BN_free (order);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
// find non-zero private key less than the curve's order
|
||||
BIGNUM* privKey = nullptr;
|
||||
bignum privKey;
|
||||
std::uint32_t seq = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// buf: 0 seed 16 seq 20
|
||||
@@ -102,114 +86,54 @@ ec_key GenerateRootDeterministicKey (uint128 const& seed)
|
||||
copy_uint32 (buf.begin() + 16, seq++);
|
||||
uint256 root = getSHA512Half (buf.data(), buf.size());
|
||||
std::fill (buf.begin(), buf.end(), 0); // security erase
|
||||
privKey = BN_bin2bn ((const unsigned char*) &root, sizeof (root), privKey);
|
||||
if (privKey == nullptr)
|
||||
{
|
||||
EC_KEY_free (pkey);
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
privKey.assign ((unsigned char const*) &root, sizeof (root));
|
||||
|
||||
root.zero(); // security erase
|
||||
}
|
||||
while (BN_is_zero (privKey) || (BN_cmp (privKey, order) >= 0));
|
||||
while (privKey.is_zero() || privKey >= secp256k1_order);
|
||||
|
||||
BN_free (order);
|
||||
return privKey;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_private_key (pkey, privKey))
|
||||
{
|
||||
// set the random point as the private key
|
||||
assert (false);
|
||||
EC_KEY_free (pkey);
|
||||
BN_clear_free (privKey);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
// --> seed
|
||||
// <-- private root generator + public root generator
|
||||
Blob GenerateRootDeterministicPublicKey (uint128 const& seed)
|
||||
{
|
||||
bn_ctx ctx;
|
||||
|
||||
EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
bignum privKey = GenerateRootDeterministicKey (seed);
|
||||
|
||||
if (!EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, nullptr, nullptr, ctx))
|
||||
{
|
||||
// compute the corresponding public key point
|
||||
assert (false);
|
||||
BN_clear_free (privKey);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
// compute the corresponding public key point
|
||||
ec_point pubKey = multiply (secp256k1_group, privKey, ctx);
|
||||
|
||||
BN_clear_free (privKey);
|
||||
privKey.clear(); // security erase
|
||||
|
||||
if (!EC_KEY_set_public_key (pkey, pubKey))
|
||||
{
|
||||
assert (false);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
return serialize_ec_point (pubKey);
|
||||
}
|
||||
|
||||
EC_POINT_free (pubKey);
|
||||
uint256 GenerateRootDeterministicPrivateKey (uint128 const& seed)
|
||||
{
|
||||
bignum key = GenerateRootDeterministicKey (seed);
|
||||
|
||||
BN_CTX_free (ctx);
|
||||
|
||||
#ifdef EC_DEBUG
|
||||
assert (EC_KEY_check_key (pkey) == 1); // CAUTION: This check is *very* expensive
|
||||
#endif
|
||||
return ec_key::acquire ((ec_key::pointer_t) pkey);
|
||||
return uint256_from_bignum_clear (key);
|
||||
}
|
||||
|
||||
// Take ripple address.
|
||||
// --> root public generator (consumes)
|
||||
// <-- root public generator in EC format
|
||||
static EC_KEY* GenerateRootPubKey (BIGNUM* pubGenerator)
|
||||
static ec_point GenerateRootPubKey (bignum&& pubGenerator)
|
||||
{
|
||||
if (pubGenerator == nullptr)
|
||||
{
|
||||
assert (false);
|
||||
return nullptr;
|
||||
}
|
||||
ec_point pubPoint = bn2point (secp256k1_group, pubGenerator.get());
|
||||
|
||||
EC_KEY* pkey = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
if (!pkey)
|
||||
{
|
||||
BN_free (pubGenerator);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
EC_POINT* pubPoint = EC_POINT_bn2point (EC_KEY_get0_group (pkey), pubGenerator, nullptr, nullptr);
|
||||
BN_free (pubGenerator);
|
||||
|
||||
if (!pubPoint)
|
||||
{
|
||||
assert (false);
|
||||
EC_KEY_free (pkey);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!EC_KEY_set_public_key (pkey, pubPoint))
|
||||
{
|
||||
assert (false);
|
||||
EC_POINT_free (pubPoint);
|
||||
EC_KEY_free (pkey);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EC_POINT_free (pubPoint);
|
||||
|
||||
return pkey;
|
||||
return pubPoint;
|
||||
}
|
||||
|
||||
// --> public generator
|
||||
static BIGNUM* makeHash (Blob const& pubGen, int seq, BIGNUM const* order)
|
||||
static bignum makeHash (Blob const& pubGen, int seq, bignum const& order)
|
||||
{
|
||||
int subSeq = 0;
|
||||
BIGNUM* ret = nullptr;
|
||||
|
||||
bignum result;
|
||||
|
||||
assert(pubGen.size() == 33);
|
||||
do
|
||||
@@ -222,167 +146,51 @@ static BIGNUM* makeHash (Blob const& pubGen, int seq, BIGNUM const* order)
|
||||
copy_uint32 (buf.begin() + 37, subSeq++);
|
||||
uint256 root = getSHA512Half (buf.data(), buf.size());
|
||||
std::fill(buf.begin(), buf.end(), 0); // security erase
|
||||
ret = BN_bin2bn ((const unsigned char*) &root, sizeof (root), ret);
|
||||
if (!ret) return nullptr;
|
||||
result.assign ((unsigned char const*) &root, sizeof (root));
|
||||
root.zero(); // security erase
|
||||
}
|
||||
while (BN_is_zero (ret) || (BN_cmp (ret, order) >= 0));
|
||||
while (result.is_zero() || result >= order);
|
||||
|
||||
return ret;
|
||||
return result;
|
||||
}
|
||||
|
||||
// --> public generator
|
||||
ec_key GeneratePublicDeterministicKey (Blob const& pubGen, int seq)
|
||||
Blob GeneratePublicDeterministicKey (Blob const& pubGen, int seq)
|
||||
{
|
||||
// publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
|
||||
BIGNUM* generator = BN_bin2bn (
|
||||
pubGen.data(),
|
||||
pubGen.size(),
|
||||
nullptr);
|
||||
ec_point rootPubKey = GenerateRootPubKey (bignum (pubGen));
|
||||
|
||||
if (generator == nullptr)
|
||||
return ec_key::invalid;
|
||||
|
||||
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);
|
||||
EC_POINT* newPoint = 0;
|
||||
BIGNUM* order = 0;
|
||||
BIGNUM* hash = 0;
|
||||
bool success = true;
|
||||
|
||||
if (!ctx || !pkey) success = false;
|
||||
|
||||
if (success)
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
if (success)
|
||||
{
|
||||
newPoint = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
|
||||
if (!newPoint) success = false;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
order = BN_new ();
|
||||
|
||||
if (!order || !EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
success = false;
|
||||
}
|
||||
bn_ctx ctx;
|
||||
|
||||
// Calculate the private additional key.
|
||||
if (success)
|
||||
{
|
||||
hash = makeHash (pubGen, seq, order);
|
||||
bignum hash = makeHash (pubGen, seq, secp256k1_order);
|
||||
|
||||
if (!hash) success = false;
|
||||
}
|
||||
// Calculate the corresponding public key.
|
||||
ec_point newPoint = multiply (secp256k1_group, hash, ctx);
|
||||
|
||||
if (success)
|
||||
{
|
||||
// Calculate the corresponding public key.
|
||||
EC_POINT_mul (EC_KEY_get0_group (pkey), newPoint, hash, nullptr, nullptr, ctx);
|
||||
// Add the master public key and set.
|
||||
add_to (secp256k1_group, rootPubKey, newPoint, ctx);
|
||||
|
||||
// Add the master public key and set.
|
||||
EC_POINT_add (EC_KEY_get0_group (pkey), newPoint, newPoint, rootPubKey, ctx);
|
||||
EC_KEY_set_public_key (pkey, newPoint);
|
||||
}
|
||||
|
||||
if (order) BN_free (order);
|
||||
|
||||
if (hash) BN_free (hash);
|
||||
|
||||
if (newPoint) EC_POINT_free (newPoint);
|
||||
|
||||
if (ctx) BN_CTX_free (ctx);
|
||||
|
||||
if (rootKey) EC_KEY_free (rootKey);
|
||||
|
||||
if (pkey && !success) EC_KEY_free (pkey);
|
||||
|
||||
return success ? ec_key::acquire ((ec_key::pointer_t) pkey) : ec_key::invalid;
|
||||
return serialize_ec_point (newPoint);
|
||||
}
|
||||
|
||||
// --> root private key
|
||||
ec_key GeneratePrivateDeterministicKey (Blob const& pubGen, const BIGNUM* rootPrivKey, int seq)
|
||||
uint256 GeneratePrivateDeterministicKey (Blob const& pubGen, uint128 const& seed, int seq)
|
||||
{
|
||||
// privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
|
||||
BN_CTX* ctx = BN_CTX_new ();
|
||||
bignum rootPrivKey = GenerateRootDeterministicKey (seed);
|
||||
|
||||
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 ec_key::invalid;
|
||||
}
|
||||
|
||||
EC_KEY_set_conv_form (pkey, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
BIGNUM* order = BN_new ();
|
||||
|
||||
if (order == nullptr)
|
||||
{
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
if (!EC_GROUP_get_order (EC_KEY_get0_group (pkey), order, ctx))
|
||||
{
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
bn_ctx ctx;
|
||||
|
||||
// calculate the private additional key
|
||||
BIGNUM* privKey = makeHash (pubGen, seq, order);
|
||||
|
||||
if (privKey == nullptr)
|
||||
{
|
||||
BN_free (order);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
bignum privKey = makeHash (pubGen, seq, secp256k1_order);
|
||||
|
||||
// calculate the final private key
|
||||
BN_mod_add (privKey, privKey, rootPrivKey, order, ctx);
|
||||
BN_free (order);
|
||||
EC_KEY_set_private_key (pkey, privKey);
|
||||
add_to (rootPrivKey, privKey, secp256k1_order, ctx);
|
||||
|
||||
// compute the corresponding public key
|
||||
EC_POINT* pubKey = EC_POINT_new (EC_KEY_get0_group (pkey));
|
||||
rootPrivKey.clear(); // security erase
|
||||
|
||||
if (!pubKey)
|
||||
{
|
||||
BN_clear_free (privKey);
|
||||
BN_CTX_free (ctx);
|
||||
EC_KEY_free (pkey);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
if (EC_POINT_mul (EC_KEY_get0_group (pkey), pubKey, privKey, nullptr, nullptr, ctx) == 0)
|
||||
{
|
||||
BN_clear_free (privKey);
|
||||
EC_POINT_free (pubKey);
|
||||
EC_KEY_free (pkey);
|
||||
BN_CTX_free (ctx);
|
||||
return ec_key::invalid;
|
||||
}
|
||||
|
||||
BN_clear_free (privKey);
|
||||
EC_KEY_set_public_key (pkey, pubKey);
|
||||
|
||||
EC_POINT_free (pubKey);
|
||||
BN_CTX_free (ctx);
|
||||
|
||||
return ec_key::acquire ((ec_key::pointer_t) pkey);
|
||||
return uint256_from_bignum_clear (privKey);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/crypto/ec_key.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
namespace ripple {
|
||||
@@ -63,53 +63,5 @@ void ec_key::destroy()
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::uint8_t ec_key::get_public_key (std::uint8_t* buffer) const
|
||||
{
|
||||
std::uint8_t* begin = buffer;
|
||||
|
||||
int const size = i2o_ECPublicKey (get_EC_KEY (*this), &begin);
|
||||
|
||||
assert (size == get_public_key_size());
|
||||
|
||||
return std::uint8_t (size);
|
||||
}
|
||||
|
||||
} // openssl
|
||||
} // ripple
|
||||
|
||||
75
src/ripple/crypto/impl/ec_key.h
Normal file
75
src/ripple/crypto/impl/ec_key.h
Normal file
@@ -0,0 +1,75 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_CRYPTO_EC_KEY_H_INCLUDED
|
||||
#define RIPPLE_CRYPTO_EC_KEY_H_INCLUDED
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <cstdint>
|
||||
|
||||
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; }
|
||||
};
|
||||
|
||||
} // openssl
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
154
src/ripple/crypto/impl/openssl.cpp
Normal file
154
src/ripple/crypto/impl/openssl.cpp
Normal file
@@ -0,0 +1,154 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/crypto/impl/openssl.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace openssl {
|
||||
|
||||
bignum::bignum()
|
||||
{
|
||||
ptr = BN_new();
|
||||
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("BN_new() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void bignum::assign (uint8_t const* data, size_t size)
|
||||
{
|
||||
// This reuses and assigns ptr
|
||||
BIGNUM* bn = BN_bin2bn (data, size, ptr);
|
||||
|
||||
if (bn == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("BN_bin2bn() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void bignum::assign_new (uint8_t const* data, size_t size)
|
||||
{
|
||||
// ptr must not be allocated
|
||||
|
||||
ptr = BN_bin2bn (data, size, nullptr);
|
||||
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("BN_bin2bn() failed");
|
||||
}
|
||||
}
|
||||
|
||||
bn_ctx::bn_ctx()
|
||||
{
|
||||
ptr = BN_CTX_new();
|
||||
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("BN_CTX_new() failed");
|
||||
}
|
||||
}
|
||||
|
||||
bignum get_order (EC_GROUP const* group, bn_ctx& ctx)
|
||||
{
|
||||
bignum result;
|
||||
|
||||
if (!EC_GROUP_get_order (group, result.get(), ctx.get()))
|
||||
{
|
||||
throw std::runtime_error ("EC_GROUP_get_order() failed");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ec_point::ec_point (EC_GROUP const* group)
|
||||
{
|
||||
ptr = EC_POINT_new (group);
|
||||
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("EC_POINT_new() failed");
|
||||
}
|
||||
}
|
||||
|
||||
void add_to (EC_GROUP const* group,
|
||||
ec_point const& a,
|
||||
ec_point& b,
|
||||
bn_ctx& ctx)
|
||||
{
|
||||
if (!EC_POINT_add (group, b.get(), a.get(), b.get(), ctx.get()))
|
||||
{
|
||||
throw std::runtime_error ("EC_POINT_add() failed");
|
||||
}
|
||||
}
|
||||
|
||||
ec_point multiply (EC_GROUP const* group,
|
||||
bignum const& n,
|
||||
bn_ctx& ctx)
|
||||
{
|
||||
ec_point result (group);
|
||||
|
||||
if (!EC_POINT_mul (group, result.get(), n.get(), nullptr, nullptr, ctx.get()))
|
||||
{
|
||||
throw std::runtime_error ("EC_POINT_mul() failed");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ec_point bn2point (EC_GROUP const* group, BIGNUM const* number)
|
||||
{
|
||||
EC_POINT* result = EC_POINT_bn2point (group, number, nullptr, nullptr);
|
||||
|
||||
if (result == nullptr)
|
||||
{
|
||||
throw std::runtime_error ("EC_POINT_bn2point() failed");
|
||||
}
|
||||
|
||||
return ec_point::acquire (result);
|
||||
}
|
||||
|
||||
static ec_key ec_key_new_secp256k1_compressed()
|
||||
{
|
||||
EC_KEY* key = EC_KEY_new_by_curve_name (NID_secp256k1);
|
||||
|
||||
if (key == nullptr) throw std::runtime_error ("EC_KEY_new_by_curve_name() failed");
|
||||
|
||||
EC_KEY_set_conv_form (key, POINT_CONVERSION_COMPRESSED);
|
||||
|
||||
return ec_key::acquire ((ec_key::pointer_t) key);
|
||||
}
|
||||
|
||||
void serialize_ec_point (ec_point const& point, std::uint8_t* ptr)
|
||||
{
|
||||
ec_key key = ec_key_new_secp256k1_compressed();
|
||||
|
||||
if (EC_KEY_set_public_key((EC_KEY*) key.get(), point.get()) <= 0)
|
||||
{
|
||||
throw std::runtime_error ("EC_KEY_set_public_key() failed");
|
||||
}
|
||||
|
||||
int const size = i2o_ECPublicKey ((EC_KEY*) key.get(), &ptr);
|
||||
|
||||
assert (size <= 33);
|
||||
}
|
||||
|
||||
} // openssl
|
||||
} // ripple
|
||||
200
src/ripple/crypto/impl/openssl.h
Normal file
200
src/ripple/crypto/impl/openssl.h
Normal file
@@ -0,0 +1,200 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_OPENSSL_H
|
||||
#define RIPPLE_OPENSSL_H
|
||||
|
||||
#include <ripple/basics/base_uint.h>
|
||||
#include <ripple/crypto/impl/ec_key.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace openssl {
|
||||
|
||||
class bignum
|
||||
{
|
||||
private:
|
||||
BIGNUM* ptr;
|
||||
|
||||
// non-copyable
|
||||
bignum (bignum const&) = delete;
|
||||
bignum& operator=(bignum const&) = delete;
|
||||
|
||||
void assign_new (uint8_t const* data, size_t size);
|
||||
|
||||
public:
|
||||
bignum();
|
||||
|
||||
~bignum()
|
||||
{
|
||||
if ( ptr != nullptr)
|
||||
{
|
||||
BN_free (ptr);
|
||||
}
|
||||
}
|
||||
|
||||
bignum (uint8_t const* data, size_t size)
|
||||
{
|
||||
assign_new (data, size);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
explicit bignum (T const& thing)
|
||||
{
|
||||
assign_new (thing.data(), thing.size());
|
||||
}
|
||||
|
||||
bignum(bignum&& that) : ptr( that.ptr )
|
||||
{
|
||||
that.ptr = nullptr;
|
||||
}
|
||||
|
||||
bignum& operator= (bignum&& that)
|
||||
{
|
||||
using std::swap;
|
||||
|
||||
swap( ptr, that.ptr );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BIGNUM * get() { return ptr; }
|
||||
BIGNUM const* get() const { return ptr; }
|
||||
|
||||
bool is_zero() const { return BN_is_zero (ptr); }
|
||||
|
||||
void clear() { BN_clear (ptr); }
|
||||
|
||||
void assign (uint8_t const* data, size_t size);
|
||||
};
|
||||
|
||||
inline bool operator< (bignum const& a, bignum const& b)
|
||||
{
|
||||
return BN_cmp (a.get(), b.get()) < 0;
|
||||
}
|
||||
|
||||
inline bool operator>= (bignum const& a, bignum const& b)
|
||||
{
|
||||
return !(a < b);
|
||||
}
|
||||
|
||||
inline uint256 uint256_from_bignum_clear (bignum& number)
|
||||
{
|
||||
uint256 result;
|
||||
result.zero();
|
||||
|
||||
BN_bn2bin (number.get(), result.end() - BN_num_bytes (number.get()));
|
||||
|
||||
number.clear();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
class bn_ctx
|
||||
{
|
||||
private:
|
||||
BN_CTX* ptr;
|
||||
|
||||
// non-copyable
|
||||
bn_ctx (bn_ctx const&);
|
||||
bn_ctx& operator=(bn_ctx const&);
|
||||
|
||||
public:
|
||||
bn_ctx();
|
||||
|
||||
~bn_ctx()
|
||||
{
|
||||
BN_CTX_free (ptr);
|
||||
}
|
||||
|
||||
BN_CTX * get() { return ptr; }
|
||||
BN_CTX const* get() const { return ptr; }
|
||||
};
|
||||
|
||||
bignum get_order (EC_GROUP const* group, bn_ctx& ctx);
|
||||
|
||||
inline bignum get_order (EC_GROUP const* group)
|
||||
{
|
||||
bn_ctx ctx;
|
||||
|
||||
return get_order (group, ctx);
|
||||
}
|
||||
|
||||
inline void add_to (bignum const& a,
|
||||
bignum& b,
|
||||
bignum const& modulus,
|
||||
bn_ctx& ctx)
|
||||
{
|
||||
BN_mod_add (b.get(), a.get(), b.get(), modulus.get(), ctx.get());
|
||||
}
|
||||
|
||||
class ec_point
|
||||
{
|
||||
public:
|
||||
typedef EC_POINT* pointer_t;
|
||||
|
||||
private:
|
||||
pointer_t ptr;
|
||||
|
||||
ec_point (pointer_t raw) : ptr(raw)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static ec_point acquire (pointer_t raw)
|
||||
{
|
||||
return ec_point (raw);
|
||||
}
|
||||
|
||||
ec_point (EC_GROUP const* group);
|
||||
|
||||
~ec_point() { EC_POINT_free (ptr); }
|
||||
|
||||
ec_point (ec_point const&) = delete;
|
||||
ec_point& operator=(ec_point const&) = delete;
|
||||
|
||||
ec_point(ec_point&& that)
|
||||
{
|
||||
ptr = that.ptr;
|
||||
that.ptr = nullptr;
|
||||
}
|
||||
|
||||
EC_POINT * get() { return ptr; }
|
||||
EC_POINT const* get() const { return ptr; }
|
||||
};
|
||||
|
||||
void add_to (EC_GROUP const* group,
|
||||
ec_point const& a,
|
||||
ec_point& b,
|
||||
bn_ctx& ctx);
|
||||
|
||||
ec_point multiply (EC_GROUP const* group,
|
||||
bignum const& n,
|
||||
bn_ctx& ctx);
|
||||
|
||||
ec_point bn2point (EC_GROUP const* group, BIGNUM const* number);
|
||||
|
||||
// output buffer must hold 33 bytes
|
||||
void serialize_ec_point (ec_point const& point, std::uint8_t* ptr);
|
||||
|
||||
} // openssl
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user