mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Remove RippleAddress:
The RippleAddress class was used to represent a number of fundamentally different types: account public keys, account secret keys, node public keys, node secret keys, seeds and generators. The class is replaced by the following types: * PublicKey for account and node public keys * SecretKey for account and node private keys * Generator for generating secp256k1 accounts * Seed for account, node and generator seeds
This commit is contained in:
@@ -1,84 +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 <BeastConfig.h>
|
||||
#include <ripple/crypto/Base58Data.h>
|
||||
#include <algorithm>
|
||||
|
||||
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.
|
||||
//
|
||||
// Why base-58 instead of standard base-64 encoding?
|
||||
// - Don't want 0OIl characters that look the same in some fonts and
|
||||
// could be used to create visually identical looking account numbers.
|
||||
// - A string with non-alphanumeric characters is not as easily accepted as an account number.
|
||||
// - E-mail usually won't line-break if there's no punctuation to break at.
|
||||
// - Doubleclicking selects the whole number as one word if it's all alphanumeric.
|
||||
//
|
||||
|
||||
CBase58Data::CBase58Data ()
|
||||
: nVersion (1)
|
||||
{
|
||||
}
|
||||
|
||||
CBase58Data::~CBase58Data ()
|
||||
{
|
||||
// Ensures that any potentially sensitive data is cleared from memory
|
||||
std::fill (vchData.begin(), vchData.end(), 0);
|
||||
}
|
||||
|
||||
bool CBase58Data::SetString (
|
||||
std::string const& str,
|
||||
unsigned char version,
|
||||
Base58::Alphabet const& alphabet)
|
||||
{
|
||||
Blob vchTemp;
|
||||
Base58::decodeWithCheck (str.c_str (), vchTemp, alphabet);
|
||||
|
||||
if (vchTemp.empty () || vchTemp[0] != version)
|
||||
{
|
||||
vchData.clear ();
|
||||
nVersion = 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
nVersion = vchTemp[0];
|
||||
|
||||
vchData.assign (vchTemp.begin () + 1, vchTemp.end ());
|
||||
|
||||
// Ensures that any potentially sensitive data is cleared from memory
|
||||
std::fill (vchTemp.begin(), vchTemp.end(), 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string CBase58Data::ToString () const
|
||||
{
|
||||
Blob vch (1, nVersion);
|
||||
|
||||
vch.insert (vch.end (), vchData.begin (), vchData.end ());
|
||||
|
||||
return Base58::encodeWithCheck (vch);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
@@ -1,85 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
// 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/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>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using openssl::ec_key;
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static bool ECDSAVerify (uint256 const& hash, Blob const& sig, const openssl::ec_key& key)
|
||||
{
|
||||
return key.valid() && 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
|
||||
@@ -1,315 +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 <BeastConfig.h>
|
||||
#include <ripple/crypto/ECDSACanonical.h>
|
||||
#include <beast/unit_test/suite.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ecdsa.h>
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace detail {
|
||||
|
||||
// A simple wrapper for a BIGNUM to make it
|
||||
// easier to allocate, construct, and free them
|
||||
struct BigNum
|
||||
{
|
||||
BIGNUM* num;
|
||||
|
||||
BigNum& operator=(BigNum const&) = delete;
|
||||
|
||||
BigNum ()
|
||||
: num (BN_new ())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BigNum (const char *hex)
|
||||
: num (BN_new ())
|
||||
{
|
||||
BN_hex2bn (&num, hex);
|
||||
}
|
||||
|
||||
BigNum (unsigned char const* ptr, std::size_t len)
|
||||
: num (BN_new ())
|
||||
{
|
||||
set (ptr, len);
|
||||
}
|
||||
|
||||
BigNum (BigNum const& other)
|
||||
: num (BN_new ())
|
||||
{
|
||||
if (BN_copy (num, other.num) == nullptr)
|
||||
BN_clear (num);
|
||||
}
|
||||
|
||||
~BigNum ()
|
||||
{
|
||||
BN_free (num);
|
||||
}
|
||||
|
||||
operator BIGNUM* ()
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
operator BIGNUM const* () const
|
||||
{
|
||||
return num;
|
||||
}
|
||||
|
||||
bool set (unsigned char const* ptr, std::size_t len)
|
||||
{
|
||||
if (BN_bin2bn (ptr, len, num) == nullptr)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class SignaturePart
|
||||
{
|
||||
private:
|
||||
std::size_t m_skip;
|
||||
BigNum m_bn;
|
||||
|
||||
public:
|
||||
SignaturePart (unsigned char const* sig, std::size_t size)
|
||||
: m_skip (0)
|
||||
{
|
||||
// The format is: <02> <length of signature> <signature>
|
||||
if ((size < 3) || (sig[0] != 0x02))
|
||||
return;
|
||||
|
||||
std::size_t const len (sig[1]);
|
||||
|
||||
// Claimed length can't be longer than amount of data available
|
||||
if (len > (size - 2))
|
||||
return;
|
||||
|
||||
// Signature must be between 1 and 33 bytes.
|
||||
if ((len < 1) || (len > 33))
|
||||
return;
|
||||
|
||||
// The signature can't be negative
|
||||
if ((sig[2] & 0x80) != 0)
|
||||
return;
|
||||
|
||||
// It can't be zero
|
||||
if ((sig[2] == 0) && (len == 1))
|
||||
return;
|
||||
|
||||
// And it can't be padded
|
||||
if ((sig[2] == 0) && ((sig[3] & 0x80) == 0))
|
||||
return;
|
||||
|
||||
// Load the signature (ignore the marker prefix and length) and if
|
||||
// successful, count the number of bytes we consumed.
|
||||
if (m_bn.set (sig + 2, len))
|
||||
m_skip = len + 2;
|
||||
}
|
||||
|
||||
bool valid () const
|
||||
{
|
||||
return m_skip != 0;
|
||||
}
|
||||
|
||||
// The signature as a BIGNUM
|
||||
BigNum getBigNum () const
|
||||
{
|
||||
return m_bn;
|
||||
}
|
||||
|
||||
// Returns the number of bytes to skip for this signature part
|
||||
std::size_t skip () const
|
||||
{
|
||||
return m_skip;
|
||||
}
|
||||
};
|
||||
|
||||
// The SECp256k1 modulus
|
||||
static BigNum const modulus (
|
||||
"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
|
||||
|
||||
} // detail
|
||||
|
||||
/** Determine whether a signature is canonical.
|
||||
Canonical signatures are important to protect against signature morphing
|
||||
attacks.
|
||||
@param vSig the signature data
|
||||
@param sigLen the length of the signature
|
||||
@param strict_param whether to enforce strictly canonical semantics
|
||||
|
||||
@note For more details please see:
|
||||
https://ripple.com/wiki/Transaction_Malleability
|
||||
https://bitcointalk.org/index.php?topic=8392.msg127623#msg127623
|
||||
https://github.com/sipa/bitcoin/commit/58bc86e37fda1aec270bccb3df6c20fbd2a6591c
|
||||
*/
|
||||
bool isCanonicalECDSASig (void const* vSig, std::size_t sigLen, ECDSA strict_param)
|
||||
{
|
||||
// The format of a signature should be:
|
||||
// <30> <len> [ <02> <lenR> <R> ] [ <02> <lenS> <S> ]
|
||||
|
||||
unsigned char const* sig = reinterpret_cast<unsigned char const*> (vSig);
|
||||
|
||||
if ((sigLen < 8) || (sigLen > 72))
|
||||
return false;
|
||||
|
||||
if ((sig[0] != 0x30) || (sig[1] != (sigLen - 2)))
|
||||
return false;
|
||||
|
||||
// The first two bytes are verified. Eat them.
|
||||
sig += 2;
|
||||
sigLen -= 2;
|
||||
|
||||
// Verify the R signature
|
||||
detail::SignaturePart sigR (sig, sigLen);
|
||||
|
||||
if (!sigR.valid ())
|
||||
return false;
|
||||
|
||||
// Eat the number of bytes we consumed
|
||||
sig += sigR.skip ();
|
||||
sigLen -= sigR.skip ();
|
||||
|
||||
// Verify the S signature
|
||||
detail::SignaturePart sigS (sig, sigLen);
|
||||
|
||||
if (!sigS.valid ())
|
||||
return false;
|
||||
|
||||
// Eat the number of bytes we consumed
|
||||
sig += sigS.skip ();
|
||||
sigLen -= sigS.skip ();
|
||||
|
||||
// Nothing should remain at this point.
|
||||
if (sigLen != 0)
|
||||
return false;
|
||||
|
||||
// Check whether R or S are greater than the modulus.
|
||||
auto bnR (sigR.getBigNum ());
|
||||
auto bnS (sigS.getBigNum ());
|
||||
|
||||
if (BN_cmp (bnR, detail::modulus) != -1)
|
||||
return false;
|
||||
|
||||
if (BN_cmp (bnS, detail::modulus) != -1)
|
||||
return false;
|
||||
|
||||
// For a given signature, (R,S), the signature (R, N-S) is also valid. For
|
||||
// a signature to be fully-canonical, the smaller of these two values must
|
||||
// be specified. If operating in strict mode, check that as well.
|
||||
if (strict_param == ECDSA::strict)
|
||||
{
|
||||
detail::BigNum mS;
|
||||
|
||||
if (BN_sub (mS, detail::modulus, bnS) == 0)
|
||||
return false;
|
||||
|
||||
if (BN_cmp (bnS, mS) == 1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Convert a signature into strictly canonical form.
|
||||
Given the signature (R, S) then (R, G-S) is also valid. For a signature
|
||||
to be canonical, the smaller of { S, G-S } must be specified.
|
||||
@param vSig the signature we wish to convert
|
||||
@param sigLen the length of the signature
|
||||
@returns true if the signature was already canonical, false otherwise
|
||||
*/
|
||||
bool makeCanonicalECDSASig (void* vSig, std::size_t& sigLen)
|
||||
{
|
||||
unsigned char * sig = reinterpret_cast<unsigned char *> (vSig);
|
||||
bool ret = false;
|
||||
|
||||
// Find internals
|
||||
int rLen = sig[3];
|
||||
int sPos = rLen + 6, sLen = sig[rLen + 5];
|
||||
|
||||
detail::BigNum origS, newS;
|
||||
BN_bin2bn (&sig[sPos], sLen, origS);
|
||||
BN_sub (newS, detail::modulus, origS);
|
||||
|
||||
if (BN_cmp (origS, newS) == 1)
|
||||
{ // original signature is not fully canonical
|
||||
unsigned char newSbuf [64];
|
||||
int newSlen = BN_bn2bin (newS, newSbuf);
|
||||
|
||||
if ((newSbuf[0] & 0x80) == 0)
|
||||
{ // no extra padding byte is needed
|
||||
sig[1] = sig[1] - sLen + newSlen;
|
||||
sig[sPos - 1] = newSlen;
|
||||
std::memcpy (&sig[sPos], newSbuf, newSlen);
|
||||
}
|
||||
else
|
||||
{ // an extra padding byte is needed
|
||||
sig[1] = sig[1] - sLen + newSlen + 1;
|
||||
sig[sPos - 1] = newSlen + 1;
|
||||
sig[sPos] = 0;
|
||||
std::memcpy (&sig[sPos + 1], newSbuf, newSlen);
|
||||
}
|
||||
sigLen = sig[1] + 2;
|
||||
}
|
||||
else
|
||||
ret = true;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <class FwdIter, class Container>
|
||||
void hex_to_binary (FwdIter first, FwdIter last, Container& out)
|
||||
{
|
||||
struct Table
|
||||
{
|
||||
int val[256];
|
||||
Table ()
|
||||
{
|
||||
std::fill (val, val+256, 0);
|
||||
for (int i = 0; i < 10; ++i)
|
||||
val ['0'+i] = i;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
val ['A'+i] = 10 + i;
|
||||
val ['a'+i] = 10 + i;
|
||||
}
|
||||
}
|
||||
int operator[] (int i)
|
||||
{
|
||||
return val[i];
|
||||
}
|
||||
};
|
||||
|
||||
static Table lut;
|
||||
out.reserve (std::distance (first, last) / 2);
|
||||
while (first != last)
|
||||
{
|
||||
auto const hi (lut[(*first++)]);
|
||||
auto const lo (lut[(*first++)]);
|
||||
out.push_back ((hi*16)+lo);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user