Use SecretKey, PublicKey

This commit is contained in:
Vinnie Falco
2015-07-10 19:55:39 -07:00
committed by Nik Bougalis
parent 6fccd07479
commit 163e8eb8fc
34 changed files with 202 additions and 693 deletions

View File

@@ -22,7 +22,7 @@
#include <ripple/protocol/tokens.h>
// VFALCO Uncomment when the header issues are resolved
//#include <ripple/protocol/AnyPublicKey.h>
//#include <ripple/protocol/PublicKey.h>
#include <ripple/basics/base_uint.h>
#include <ripple/basics/UnorderedContainers.h>
#include <ripple/json/json_value.h>
@@ -33,9 +33,6 @@
namespace ripple {
// VFALCO Forward declared due to header issues
class AnyPublicKey;
namespace detail {
class AccountIDTag { };
@@ -96,8 +93,9 @@ parseHexOrBase58 (std::string const& s);
guard bytes included in the base58 representation.
*/
AccountID
calcAccountID (AnyPublicKey const& pk);
// VFALCO In PublicKey.h for now
//AccountID
//calcAccountID (PublicKey const& pk);
/** A special account that's used as the "issuer" for XRP. */
AccountID const&

View File

@@ -1,188 +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.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_ANYPUBLICKEY_H_INCLUDED
#define RIPPLE_PROTOCOL_ANYPUBLICKEY_H_INCLUDED
#include <ripple/basics/Buffer.h>
#include <ripple/crypto/KeyType.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/STExchange.h>
#include <ripple/protocol/STObject.h>
#include <beast/hash/hash_append.h>
#include <beast/utility/noexcept.h>
#include <boost/utility/base_from_member.hpp>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <utility>
namespace ripple {
/** Variant container for all public keys. */
class AnyPublicKeySlice
: public Slice
{
public:
#ifdef _MSC_VER
AnyPublicKeySlice (
void const* data, std::size_t size)
: Slice (data, size)
{
}
#else
using Slice::Slice;
#endif
AnyPublicKeySlice() = delete;
AnyPublicKeySlice (
AnyPublicKeySlice const&) = default;
AnyPublicKeySlice& operator= (
AnyPublicKeySlice const&) = default;
/** Returns the type of key stored. */
KeyType
type() const noexcept;
/** Verify a signature using this public key. */
bool
verify (void const* msg, std::size_t msg_size,
void const* sig, std::size_t sig_size) const;
};
template <>
struct STExchange<STBlob, AnyPublicKeySlice>
{
using value_type = AnyPublicKeySlice;
static
void
get (boost::optional<value_type>& t,
STBlob const& u)
{
t = boost::in_place(u.data(), u.size());
}
static
std::unique_ptr<STBlob>
set (SField const& f, AnyPublicKeySlice const& t)
{
return std::make_unique<STBlob>(
f, t.data(), t.size());
}
};
//------------------------------------------------------------------------------
/** Variant container for all public keys, with ownership. */
class AnyPublicKey
: private boost::base_from_member<Buffer>
, public AnyPublicKeySlice
{
private:
using buffer_type = boost::base_from_member<Buffer>;
public:
AnyPublicKey() = delete;
AnyPublicKey& operator= (AnyPublicKey const&) = delete;
AnyPublicKey (AnyPublicKey const& other)
: buffer_type(other.buffer_type::member.data(),
other.buffer_type::member.size())
, AnyPublicKeySlice (buffer_type::member.data(),
buffer_type::member.size())
{
}
#ifdef _MSC_VER
AnyPublicKey (AnyPublicKey&& other)
: buffer_type(std::move(other.buffer_type::member))
, AnyPublicKeySlice (buffer_type::member.data(),
buffer_type::member.size())
{
}
AnyPublicKey& operator= (AnyPublicKey&& other)
{
buffer_type::member =
std::move (other.buffer_type::member);
AnyPublicKeySlice::operator= (other);
return *this;
}
#else
AnyPublicKey (AnyPublicKey&&) = default;
AnyPublicKey& operator= (AnyPublicKey&&) = default;
#endif
AnyPublicKey (void const* data_, std::size_t size_)
: buffer_type (data_, size_)
, AnyPublicKeySlice (
member.data(), member.size())
{
}
/** Returns ownership of the underlying Buffer.
After calling this function, only the destructor
or the move assignment operator may be called.
*/
Buffer
releaseBuffer() noexcept
{
return std::move(buffer_type::member);
}
};
template <>
struct STExchange<STBlob, AnyPublicKey>
{
using value_type = AnyPublicKey;
static
void
get (boost::optional<value_type>& t,
STBlob const& u)
{
t = boost::in_place(u.data(), u.size());
}
static
std::unique_ptr<STBlob>
set (SField const& f, AnyPublicKey const& t)
{
return std::make_unique<STBlob>(
f, t.data(), t.size());
}
static
std::unique_ptr<STBlob>
set (SField const& f, AnyPublicKey&& t)
{
return std::make_unique<STBlob>(
f, t.releaseBuffer());
}
};
std::string
toString (AnyPublicKey const& pk);
} // ripple
#endif

View File

@@ -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.
*/
//==============================================================================
#ifndef RIPPLE_PROTOCOL_ANYSECRETKEY_H_INCLUDED
#define RIPPLE_PROTOCOL_ANYSECRETKEY_H_INCLUDED
#include <ripple/basics/Buffer.h>
#include <ripple/protocol/AnyPublicKey.h>
#include <ripple/protocol/HashPrefix.h>
#include <boost/utility/base_from_member.hpp>
#include <cstdint>
#include <memory>
#include <utility>
namespace ripple {
/** Variant container for secret key, with ownership. */
class AnySecretKey
{
private:
Buffer p_;
KeyType type_;
public:
AnySecretKey() = delete;
AnySecretKey (AnySecretKey const&) = delete;
AnySecretKey& operator= (AnySecretKey const&) = delete;
/** Destroy the key.
The memory area is secure erased.
*/
~AnySecretKey();
AnySecretKey (AnySecretKey&& other);
AnySecretKey& operator= (AnySecretKey&& other);
AnySecretKey (KeyType type,
void const* data, std::size_t size);
/** Returns the type of secret key. */
KeyType
type() const noexcept
{
return type_;
}
/** Returns the corresponding public key. */
AnyPublicKey
publicKey() const;
/** Create a signature for the given message. */
Buffer
sign (void const* msg, std::size_t msg_len) const;
/** Securely generate a new ed25519 secret key. */
static
AnySecretKey
make_ed25519();
/** Securely generate a new secp256k1 key pair. */
static
std::pair<AnySecretKey, AnyPublicKey>
make_secp256k1_pair();
};
} // ripple
#endif

View File

@@ -20,9 +20,9 @@
#ifndef RIPPLE_PROTOCOL_SIGN_H_INCLUDED
#define RIPPLE_PROTOCOL_SIGN_H_INCLUDED
#include <ripple/protocol/AnyPublicKey.h>
#include <ripple/protocol/AnySecretKey.h>
#include <ripple/protocol/HashPrefix.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/SecretKey.h>
#include <ripple/protocol/STObject.h>
#include <utility>
@@ -35,7 +35,7 @@ namespace ripple {
void
sign (STObject& st,
HashPrefix const& prefix,
AnySecretKey const& sk);
KeyType type, SecretKey const& sk);
/** Verify the signature on a STObject.
The signature must be contained in sfSignature.
@@ -43,7 +43,8 @@ sign (STObject& st,
bool
verify (STObject const& st,
HashPrefix const& prefix,
AnyPublicKeySlice const& pk);
PublicKey const& pk,
bool mustBeFullyCanonical);
} // ripple

View File

@@ -19,7 +19,7 @@
#include <BeastConfig.h>
#include <ripple/protocol/AccountID.h>
#include <ripple/protocol/AnyPublicKey.h>
#include <ripple/protocol/PublicKey.h>
#include <ripple/protocol/digest.h>
#include <ripple/protocol/tokens.h>
#include <cstring>
@@ -139,9 +139,8 @@ parseHexOrBase58 (std::string const& s)
less secure than Bitcoin. So where there was no good reason
to change something, it was not changed."
*/
AccountID
calcAccountID (AnyPublicKey const& pk)
calcAccountID (PublicKey const& pk)
{
ripesha_hasher rsh;
rsh(pk.data(), pk.size());

View File

@@ -1,104 +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/protocol/AnyPublicKey.h>
#include <ripple/protocol/Serializer.h>
#include <ripple/protocol/STExchange.h>
#include <ed25519-donna/ed25519.h>
#include <cassert>
namespace ripple {
/** Verify a secp256k1 signature. */
bool
verify_secp256k1 (void const* pk,
void const* msg, std::size_t msg_size,
void const* sig, std::size_t sig_size)
{
return false;
}
bool
verify_ed25519 (void const* pk,
void const* msg, std::size_t msg_size,
void const* sig, std::size_t sig_size)
{
if (sig_size != 64)
return false;
ed25519_public_key epk;
ed25519_signature es;
std::memcpy(epk, pk, 32);
std::memcpy(es, sig, sig_size);
return ed25519_sign_open(
reinterpret_cast<unsigned char const*>(msg),
msg_size, epk, es) == 0;
}
//------------------------------------------------------------------------------
KeyType
AnyPublicKeySlice::type() const noexcept
{
auto const pk = data();
auto const pk_size = size();
if (pk_size < 1)
return KeyType::unknown;
auto const len = pk_size - 1;
if (len == 32 &&
pk[0] == 0xED)
return KeyType::ed25519;
if (len == 33 &&
(pk[0] == 0x02 || pk[0] == 0x03))
return KeyType::secp256k1;
return KeyType::unknown;
}
bool
AnyPublicKeySlice::verify (
void const* msg, std::size_t msg_size,
void const* sig, std::size_t sig_size) const
{
switch(type())
{
case KeyType::ed25519:
return verify_ed25519(data() + 1,
msg, msg_size, sig, sig_size);
case KeyType::secp256k1:
return verify_secp256k1(data() + 1,
msg, msg_size, sig, sig_size);
default:
break;
}
// throw?
return false;
}
std::string
toString (AnyPublicKey const& pk)
{
Blob buffer;
buffer.reserve (1 + pk.size ());
buffer.push_back (TOKEN_NODE_PUBLIC);
auto const data = pk.data ();
buffer.insert (buffer.end (), data, data + pk.size ());
return Base58::encodeWithCheck (buffer);
}
} // ripple

View File

@@ -1,143 +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/protocol/AnySecretKey.h>
#include <ripple/protocol/RippleAddress.h>
#include <ripple/protocol/Serializer.h>
#include <ripple/crypto/RandomNumbers.h>
#include <ed25519-donna/ed25519.h>
#include <algorithm>
#include <cassert>
#include <cstring>
namespace ripple {
AnySecretKey::~AnySecretKey()
{
// secure erase
std::fill(p_.data(), p_.data() + p_.size(), 0);
}
AnySecretKey::AnySecretKey (AnySecretKey&& other)
: p_ (std::move(other.p_))
, type_ (other.type_)
{
other.type_ = KeyType::unknown;
}
AnySecretKey&
AnySecretKey::operator= (AnySecretKey&& other)
{
p_ = std::move(other.p_);
type_ = other.type_;
other.type_ = KeyType::unknown;
return *this;
}
AnySecretKey::AnySecretKey (KeyType type,
void const* data, std::size_t size)
: p_ (data, size)
, type_ (type)
{
if (type_ == KeyType::unknown)
throw std::runtime_error(
"AnySecretKey: unknown type");
if (type_ == KeyType::ed25519 &&
size != 32)
throw std::runtime_error(
"AnySecretKey: wrong ed25519 size");
if (type_ == KeyType::secp256k1 &&
size != 32)
throw std::runtime_error(
"AnySecretKey: wrong secp256k1 size");
}
AnyPublicKey
AnySecretKey::publicKey() const
{
switch (type())
{
case KeyType::ed25519:
{
unsigned char buf[33];
buf[0] = 0xED;
ed25519_publickey(p_.data(), &buf[1]);
return AnyPublicKey(buf, sizeof(buf));
}
default:
throw std::runtime_error(
"AnySecretKey: unknown type");
};
}
Buffer
AnySecretKey::sign (
void const* msg, std::size_t msg_len) const
{
switch(type_)
{
case KeyType::ed25519:
{
auto const sk = p_.data();
ed25519_public_key pk;
ed25519_publickey(sk, pk);
Buffer b(64);
ed25519_sign(reinterpret_cast<
unsigned char const*>(msg), msg_len,
sk, pk, b.data());
return b;
}
default:
break;
}
throw std::runtime_error(
"AnySecretKey: unknown type");
}
AnySecretKey
AnySecretKey::make_ed25519()
{
std::uint8_t buf[32];
random_fill(&buf[0], sizeof(buf));
AnySecretKey ask(KeyType::ed25519,
buf, sizeof(buf));
// secure erase
std::fill(buf, buf + sizeof(buf), 0);
return ask;
}
std::pair<AnySecretKey, AnyPublicKey>
AnySecretKey::make_secp256k1_pair()
{
// VFALCO What a pile
RippleAddress s;
s.setSeedRandom();
RippleAddress const g =
RippleAddress::createGeneratorPublic(s);
RippleAddress sk;
sk.setAccountPrivate (g, s, 0);
RippleAddress pk;
pk.setAccountPublic (g, 0);
return std::pair<AnySecretKey, AnyPublicKey>(
std::piecewise_construct, std::make_tuple(
KeyType::secp256k1, sk.data(), sk.size()),
std::make_tuple(pk.data(), pk.size()));
}
} // ripple

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/STAccount.h>
#include <ripple/protocol/STAmount.h>
#include <ripple/protocol/STArray.h>

View File

@@ -17,25 +17,27 @@
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/Sign.h>
namespace ripple {
void
sign (STObject& st, HashPrefix const& prefix,
AnySecretKey const& sk)
KeyType type, SecretKey const& sk)
{
Serializer ss;
ss.add32(prefix);
st.addWithoutSigningFields(ss);
set(st, sfSignature,
sk.sign(ss.data(), ss.size()));
sign(type, sk, ss.slice()));
}
bool
verify (STObject const& st,
HashPrefix const& prefix,
AnyPublicKeySlice const& pk)
PublicKey const& pk,
bool mustBeFullyCanonical)
{
auto const sig = get(st, sfSignature);
if (! sig)
@@ -44,8 +46,9 @@ verify (STObject const& st,
ss.add32(prefix);
st.addWithoutSigningFields(ss);
return pk.verify(
ss.data(), ss.size(),
sig->data(), sig->size());
Slice(ss.data(), ss.size()),
Slice(sig->data(), sig->size()),
true);
}
} // ripple

View File

@@ -17,6 +17,7 @@
*/
//==============================================================================
#include <BeastConfig.h>
#include <ripple/protocol/tokens.h>
#include <ripple/protocol/digest.h>
#include <cassert>

View File

@@ -88,7 +88,7 @@ public:
txnSeed.setSeedRandom ();
// VFALCO Generators are no longer supported
RippleAddress txnGenerator = txnSeed.createGeneratorPublic (txnSeed);
// VFALCO Use AnyPublicKey here
// VFALCO Use PublicKey here
RippleAddress txnPublicAcct = txnSeed.createAccountPublic (txnGenerator, 1);
STTx txn (ttACCOUNT_SET);