rippled
SecretKey.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/basics/strHex.h>
21 #include <ripple/protocol/SecretKey.h>
22 #include <ripple/protocol/digest.h>
23 #include <ripple/protocol/impl/secp256k1.h>
24 #include <ripple/basics/contract.h>
25 #include <ripple/crypto/GenerateDeterministicKey.h>
26 #include <ripple/crypto/csprng.h>
27 #include <ripple/beast/crypto/secure_erase.h>
28 #include <ripple/beast/utility/rngfill.h>
29 #include <ed25519-donna/ed25519.h>
30 #include <cstring>
31 
32 namespace ripple {
33 
35 {
36  beast::secure_erase(buf_, sizeof(buf_));
37 }
38 
40 {
41  std::memcpy(buf_, key.data(), key.size());
42 }
43 
45 {
46  if (slice.size() != sizeof(buf_))
47  LogicError("SecretKey::SecretKey: invalid size");
48  std::memcpy(buf_, slice.data(), sizeof(buf_));
49 }
50 
53 {
54  return strHex(*this);
55 }
56 
57 //------------------------------------------------------------------------------
59 class Generator
60 {
61 private:
62  Blob gen_; // VFALCO compile time size?
63 
64 public:
65  explicit
66  Generator (Seed const& seed)
67  {
68  // FIXME: Avoid copying the seed into a uint128 key only to have
69  // generateRootDeterministicPublicKey copy out of it.
70  uint128 ui;
71  std::memcpy(ui.data(),
72  seed.data(), seed.size());
74  }
75 
81  operator()(Seed const& seed, std::size_t ordinal) const
82  {
83  // FIXME: Avoid copying the seed into a uint128 key only to have
84  // generatePrivateDeterministicKey copy out of it.
85  uint128 ui;
86  std::memcpy(ui.data(), seed.data(), seed.size());
87  auto gsk = generatePrivateDeterministicKey(gen_, ui, ordinal);
88  auto gpk = generatePublicDeterministicKey(gen_, ordinal);
89  SecretKey const sk(Slice{ gsk.data(), gsk.size() });
90  PublicKey const pk(Slice{ gpk.data(), gpk.size() });
91  beast::secure_erase(ui.data(), ui.size());
92  beast::secure_erase(gsk.data(), gsk.size());
93  return {pk, sk};
94  }
95 };
96 
97 //------------------------------------------------------------------------------
98 
99 Buffer
100 signDigest (PublicKey const& pk, SecretKey const& sk,
101  uint256 const& digest)
102 {
104  LogicError("sign: secp256k1 required for digest signing");
105 
106  BOOST_ASSERT(sk.size() == 32);
107  secp256k1_ecdsa_signature sig_imp;
108  if(secp256k1_ecdsa_sign(
110  &sig_imp,
111  reinterpret_cast<unsigned char const*>(
112  digest.data()),
113  reinterpret_cast<unsigned char const*>(
114  sk.data()),
115  secp256k1_nonce_function_rfc6979,
116  nullptr) != 1)
117  LogicError("sign: secp256k1_ecdsa_sign failed");
118 
119  unsigned char sig[72];
120  size_t len = sizeof(sig);
121  if(secp256k1_ecdsa_signature_serialize_der(
123  sig,
124  &len,
125  &sig_imp) != 1)
126  LogicError("sign: secp256k1_ecdsa_signature_serialize_der failed");
127 
128  return Buffer{sig, len};
129 }
130 
131 Buffer
132 sign (PublicKey const& pk,
133  SecretKey const& sk, Slice const& m)
134 {
135  auto const type =
136  publicKeyType(pk.slice());
137  if (! type)
138  LogicError("sign: invalid type");
139  switch(*type)
140  {
141  case KeyType::ed25519:
142  {
143  Buffer b(64);
144  ed25519_sign(m.data(), m.size(),
145  sk.data(), pk.data() + 1, b.data());
146  return b;
147  }
148  case KeyType::secp256k1:
149  {
151  h(m.data(), m.size());
152  auto const digest =
154 
155  secp256k1_ecdsa_signature sig_imp;
156  if(secp256k1_ecdsa_sign(
158  &sig_imp,
159  reinterpret_cast<unsigned char const*>(
160  digest.data()),
161  reinterpret_cast<unsigned char const*>(
162  sk.data()),
163  secp256k1_nonce_function_rfc6979,
164  nullptr) != 1)
165  LogicError("sign: secp256k1_ecdsa_sign failed");
166 
167  unsigned char sig[72];
168  size_t len = sizeof(sig);
169  if(secp256k1_ecdsa_signature_serialize_der(
171  sig,
172  &len,
173  &sig_imp) != 1)
174  LogicError("sign: secp256k1_ecdsa_signature_serialize_der failed");
175 
176  return Buffer{sig, len};
177  }
178  default:
179  LogicError("sign: invalid type");
180  }
181 }
182 
183 SecretKey
185 {
186  std::uint8_t buf[32];
188  buf,
189  sizeof(buf),
190  crypto_prng());
191  SecretKey sk(Slice{ buf, sizeof(buf) });
192  beast::secure_erase(buf, sizeof(buf));
193  return sk;
194 }
195 
196 // VFALCO TODO Rewrite all this without using OpenSSL
197 // or calling into GenerateDetermisticKey
198 SecretKey
199 generateSecretKey (KeyType type, Seed const& seed)
200 {
201  if (type == KeyType::ed25519)
202  {
203  auto key = sha512Half_s(Slice(
204  seed.data(), seed.size()));
205  SecretKey sk = Slice{ key.data(), key.size() };
206  beast::secure_erase(key.data(), key.size());
207  return sk;
208  }
209 
210  if (type == KeyType::secp256k1)
211  {
212  // FIXME: Avoid copying the seed into a uint128 key only to have
213  // generateRootDeterministicPrivateKey copy out of it.
214  uint128 ps;
215  std::memcpy(ps.data(),
216  seed.data(), seed.size());
217  auto const upk =
219  SecretKey sk = Slice{ upk.data(), upk.size() };
220  beast::secure_erase(ps.data(), ps.size());
221  return sk;
222  }
223 
224  LogicError ("generateSecretKey: unknown key type");
225 }
226 
227 PublicKey
229 {
230  switch(type)
231  {
232  case KeyType::secp256k1:
233  {
234  secp256k1_pubkey pubkey_imp;
235  if(secp256k1_ec_pubkey_create(
237  &pubkey_imp,
238  reinterpret_cast<unsigned char const*>(
239  sk.data())) != 1)
240  LogicError("derivePublicKey: secp256k1_ec_pubkey_create failed");
241 
242  unsigned char pubkey[33];
243  std::size_t len = sizeof(pubkey);
244  if(secp256k1_ec_pubkey_serialize(
246  pubkey,
247  &len,
248  &pubkey_imp,
249  SECP256K1_EC_COMPRESSED) != 1)
250  LogicError("derivePublicKey: secp256k1_ec_pubkey_serialize failed");
251 
252  return PublicKey{Slice{ pubkey, len }};
253  }
254  case KeyType::ed25519:
255  {
256  unsigned char buf[33];
257  buf[0] = 0xED;
258  ed25519_publickey(sk.data(), &buf[1]);
259  return PublicKey(Slice{ buf, sizeof(buf) });
260  }
261  default:
262  LogicError("derivePublicKey: bad key type");
263  };
264 }
265 
267 generateKeyPair (KeyType type, Seed const& seed)
268 {
269  switch(type)
270  {
271  case KeyType::secp256k1:
272  {
273  Generator g(seed);
274  return g(seed, 0);
275  }
276  default:
277  case KeyType::ed25519:
278  {
279  auto const sk = generateSecretKey(type, seed);
280  return { derivePublicKey(type, sk), sk };
281  }
282  }
283 }
284 
287 {
288  auto const sk = randomSecretKey();
289  return { derivePublicKey(type, sk), sk };
290 }
291 
292 template <>
293 boost::optional<SecretKey>
294 parseBase58 (TokenType type, std::string const& s)
295 {
296  auto const result = decodeBase58Token(s, type);
297  if (result.empty())
298  return boost::none;
299  if (result.size() != 32)
300  return boost::none;
301  return SecretKey(makeSlice(result));
302 }
303 
304 } // ripple
305 
ripple::PublicKey::data
std::uint8_t const * data() const noexcept
Definition: PublicKey.h:81
ripple::Slice::size
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition: Slice.h:77
ripple::Generator::gen_
Blob gen_
Definition: SecretKey.cpp:62
ripple::makeSlice
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition: Slice.h:199
ripple::Generator::operator()
std::pair< PublicKey, SecretKey > operator()(Seed const &seed, std::size_t ordinal) const
Generate the nth key pair.
Definition: SecretKey.cpp:81
std::string
STL class.
cstring
ripple::detail::basic_sha512_half_hasher
Returns the SHA512-Half digest of a message.
Definition: digest.h:192
ripple::publicKeyType
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
ripple::Generator
Produces a sequence of secp256k1 key pairs.
Definition: SecretKey.cpp:59
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:43
std::pair
std::vector< unsigned char >
std::array::size
T size(T... args)
ripple::generateRootDeterministicPrivateKey
uint256 generateRootDeterministicPrivateKey(uint128 const &seed)
Definition: GenerateDeterministicKey.cpp:124
ripple::crypto_prng
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
Definition: csprng.cpp:111
ripple::Slice::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Slice.h:87
ripple::PublicKey::slice
Slice slice() const noexcept
Definition: PublicKey.h:123
ripple::Buffer
Like std::vector<char> but better.
Definition: Buffer.h:35
ripple::sha512Half_s
sha512_half_hasher_s::result_type sha512Half_s(Args const &... args)
Returns the SHA512-Half of a series of objects.
Definition: digest.h:285
ripple::base_uint::data
pointer data()
Definition: base_uint.h:102
ripple::generateKeyPair
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
Definition: SecretKey.cpp:267
ripple::base_uint::size
constexpr static std::size_t size()
Definition: base_uint.h:417
ripple::secp256k1Context
secp256k1_context const * secp256k1Context()
Definition: secp256k1.h:29
ripple::digest
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition: tokens.cpp:44
ripple::KeyType::ed25519
@ ed25519
ripple::SecretKey::buf_
std::uint8_t buf_[32]
Definition: SecretKey.h:39
ripple::base_uint
Definition: base_uint.h:65
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::TokenType
TokenType
Definition: tokens.h:29
ripple::signDigest
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
Definition: SecretKey.cpp:100
ripple::derivePublicKey
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:228
ripple::SecretKey::data
std::uint8_t const * data() const
Definition: SecretKey.h:54
std::array
STL class.
beast::secure_erase
void secure_erase(void *dest, std::size_t bytes)
Guaranteed to fill memory with zeroes.
Definition: secure_erase.h:83
ripple::generateSecretKey
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
Definition: SecretKey.cpp:199
ripple::Buffer::data
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition: Buffer.h:154
std::uint8_t
ripple::SecretKey
A secret key.
Definition: SecretKey.h:36
ripple::KeyType
KeyType
Definition: KeyType.h:28
ripple::generateRootDeterministicPublicKey
Blob generateRootDeterministicPublicKey(uint128 const &seed)
Definition: GenerateDeterministicKey.cpp:110
ripple::KeyType::secp256k1
@ secp256k1
ripple::randomKeyPair
std::pair< PublicKey, SecretKey > randomKeyPair(KeyType type)
Create a key pair using secure random numbers.
Definition: SecretKey.cpp:286
ripple::SecretKey::SecretKey
SecretKey()=default
ripple::Seed::size
std::size_t size() const
Definition: Seed.h:63
ripple::generatePrivateDeterministicKey
uint256 generatePrivateDeterministicKey(Blob const &family, uint128 const &seed, int n)
Definition: GenerateDeterministicKey.cpp:188
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::detail::basic_sha512_half_hasher::result_type
uint256 result_type
Definition: digest.h:201
ripple::Generator::Generator
Generator(Seed const &seed)
Definition: SecretKey.cpp:66
ripple::Seed
Seeds are used to generate deterministic secret keys.
Definition: Seed.h:32
ripple::SecretKey::~SecretKey
~SecretKey()
Definition: SecretKey.cpp:34
ripple::sign
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
Definition: SecretKey.cpp:132
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:32
ripple::decodeBase58Token
static std::string decodeBase58Token(std::string const &s, TokenType type, InverseArray const &inv)
Definition: tokens.cpp:264
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:50
std::size_t
std::memcpy
T memcpy(T... args)
ripple::strHex
std::string strHex(FwdIt begin, FwdIt end)
Definition: strHex.h:70
ripple::generatePublicDeterministicKey
Blob generatePublicDeterministicKey(Blob const &generator, int n)
Definition: GenerateDeterministicKey.cpp:168
ripple::SecretKey::size
std::size_t size() const
Definition: SecretKey.h:60
ripple::parseBase58
boost::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
Definition: AccountID.cpp:36
std::array::data
T data(T... args)
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:184
ripple::SecretKey::to_string
std::string to_string() const
Convert the secret key to a hexadecimal string.
Definition: SecretKey.cpp:52
ripple::Seed::data
std::uint8_t const * data() const
Definition: Seed.h:57