Monero
crypto.h
Go to the documentation of this file.
1 // Copyright (c) 2014-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30 
31 #pragma once
32 
33 #include <cstddef>
34 #include <iostream>
35 #include <boost/optional.hpp>
36 #include <type_traits>
37 #include <vector>
38 #include <random>
39 
40 #include "common/pod-class.h"
41 #include "memwipe.h"
42 #include "mlocker.h"
43 #include "generic-ops.h"
44 #include "hex.h"
45 #include "span.h"
46 #include "hash.h"
47 
48 namespace crypto {
49 
50  extern "C" {
51 #include "random.h"
52  }
53 
54 #pragma pack(push, 1)
56  char data[32];
57  };
58 
60  char data[32];
61  };
62 
64  friend class crypto_ops;
65  };
66 
68  public_key_memsafe() = default;
69  public_key_memsafe(const public_key &original) { memcpy(this->data, original.data, 32); }
70  };
71 
73 
75  std::vector<public_key> keys;
76  int rows;
77  };
78 
80  std::vector<secret_key> keys;
81  int rows;
82  };
83 
85  int cols;
86  int rows;
87  std::vector<secret_keyV> column_vectors;
88  };
89 
91  friend class crypto_ops;
92  };
93 
95  friend class crypto_ops;
96  };
97 
99  ec_scalar c, r;
100  friend class crypto_ops;
101  };
102 
104  char data;
105  };
106 #pragma pack(pop)
107 
108  void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
109  void random32_unbiased(unsigned char *bytes);
110 
111  static_assert(sizeof(ec_point) == 32 && sizeof(ec_scalar) == 32 &&
112  sizeof(public_key) == 32 && sizeof(public_key_memsafe) == 32 && sizeof(secret_key) == 32 &&
113  sizeof(key_derivation) == 32 && sizeof(key_image) == 32 &&
114  sizeof(signature) == 64 && sizeof(view_tag) == 1, "Invalid structure size");
115 
116  class crypto_ops {
117  crypto_ops();
118  crypto_ops(const crypto_ops &);
119  void operator=(const crypto_ops &);
120  ~crypto_ops();
121 
122  static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false);
123  friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover);
124  static bool check_key(const public_key &);
125  friend bool check_key(const public_key &);
126  static bool secret_key_to_public_key(const secret_key &, public_key &);
127  friend bool secret_key_to_public_key(const secret_key &, public_key &);
128  static bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &);
129  friend bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &);
130  static void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res);
131  friend void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res);
132  static bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &);
133  friend bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &);
134  static void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &);
135  friend void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &);
136  static bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &);
137  friend bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &);
138  static void generate_signature(const hash &, const public_key &, const secret_key &, signature &);
139  friend void generate_signature(const hash &, const public_key &, const secret_key &, signature &);
140  static bool check_signature(const hash &, const public_key &, const signature &);
141  friend bool check_signature(const hash &, const public_key &, const signature &);
142  static void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
143  friend void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
144  static void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
145  friend void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
146  static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
147  friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
148  static void generate_key_image(const public_key &, const secret_key &, key_image &);
149  friend void generate_key_image(const public_key &, const secret_key &, key_image &);
150  static void generate_ring_signature(const hash &, const key_image &,
151  const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *);
152  friend void generate_ring_signature(const hash &, const key_image &,
153  const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *);
154  static bool check_ring_signature(const hash &, const key_image &,
155  const public_key *const *, std::size_t, const signature *);
156  friend bool check_ring_signature(const hash &, const key_image &,
157  const public_key *const *, std::size_t, const signature *);
158  static void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
159  friend void derive_view_tag(const key_derivation &, std::size_t, view_tag &);
160  };
161 
162  void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes);
163  void add_extra_entropy_thread_safe(const void *ptr, size_t bytes);
164 
165  /* Generate N random bytes
166  */
167  inline void rand(size_t N, uint8_t *bytes) {
169  }
170 
171  /* Generate a value filled with random bytes.
172  */
173  template<typename T>
174  T rand() {
175  static_assert(std::is_standard_layout<T>(), "cannot write random bytes into non-standard layout type");
176  static_assert(std::is_trivially_copyable<T>(), "cannot write random bytes into non-trivially copyable type");
177  typename std::remove_cv<T>::type res;
179  return res;
180  }
181 
182  /* UniformRandomBitGenerator using crypto::rand<uint64_t>()
183  */
185  {
187  static constexpr result_type min() { return 0; }
188  static constexpr result_type max() { return result_type(-1); }
189  result_type operator()() const { return crypto::rand<result_type>(); }
190  };
191 
192  /* Generate a random value between range_min and range_max
193  */
194  template<typename T>
197  std::uniform_int_distribution<T> dis(range_min, range_max);
198  return dis(rd);
199  }
200 
201  /* Generate a random index between 0 and sz-1
202  */
203  template<typename T>
205  return crypto::rand_range<T>(0, sz-1);
206  }
207 
208  /* Generate a new key pair
209  */
210  inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
211  return crypto_ops::generate_keys(pub, sec, recovery_key, recover);
212  }
213 
214  /* Check a public key. Returns true if it is valid, false otherwise.
215  */
216  inline bool check_key(const public_key &key) {
217  return crypto_ops::check_key(key);
218  }
219 
220  /* Checks a private key and computes the corresponding public key.
221  */
222  inline bool secret_key_to_public_key(const secret_key &sec, public_key &pub) {
223  return crypto_ops::secret_key_to_public_key(sec, pub);
224  }
225 
226  /* To generate an ephemeral key used to send money to:
227  * * The sender generates a new key pair, which becomes the transaction key. The public transaction key is included in "extra" field.
228  * * Both the sender and the receiver generate key derivation from the transaction key, the receivers' "view" key and the output index.
229  * * The sender uses key derivation and the receivers' "spend" key to derive an ephemeral public key.
230  * * The receiver can either derive the public key (to check that the transaction is addressed to him) or the private key (to spend the money).
231  */
232  inline bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation) {
233  return crypto_ops::generate_key_derivation(key1, key2, derivation);
234  }
235  inline bool derive_public_key(const key_derivation &derivation, std::size_t output_index,
236  const public_key &base, public_key &derived_key) {
237  return crypto_ops::derive_public_key(derivation, output_index, base, derived_key);
238  }
239  inline void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res) {
241  }
242  inline void derive_secret_key(const key_derivation &derivation, std::size_t output_index,
243  const secret_key &base, secret_key &derived_key) {
244  crypto_ops::derive_secret_key(derivation, output_index, base, derived_key);
245  }
246  inline bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &result) {
247  return crypto_ops::derive_subaddress_public_key(out_key, derivation, output_index, result);
248  }
249 
250  /* Generation and checking of a standard signature.
251  */
252  inline void generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig) {
253  crypto_ops::generate_signature(prefix_hash, pub, sec, sig);
254  }
255  inline bool check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) {
256  return crypto_ops::check_signature(prefix_hash, pub, sig);
257  }
258 
259  /* Generation and checking of a tx proof; given a tx pubkey R, the recipient's view pubkey A, and the key
260  * derivation D, the signature proves the knowledge of the tx secret key r such that R=r*G and D=r*A
261  * When the recipient's address is a subaddress, the tx pubkey R is defined as R=r*B where B is the recipient's spend pubkey
262  */
263  inline void generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
264  crypto_ops::generate_tx_proof(prefix_hash, R, A, B, D, r, sig);
265  }
266  inline void generate_tx_proof_v1(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
267  crypto_ops::generate_tx_proof_v1(prefix_hash, R, A, B, D, r, sig);
268  }
269  inline bool check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig, const int version) {
270  return crypto_ops::check_tx_proof(prefix_hash, R, A, B, D, sig, version);
271  }
272 
273  /* To send money to a key:
274  * * The sender generates an ephemeral key and includes it in transaction output.
275  * * To spend the money, the receiver generates a key image from it.
276  * * Then he selects a bunch of outputs, including the one he spends, and uses them to generate a ring signature.
277  * To check the signature, it is necessary to collect all the keys that were used to generate it. To detect double spends, it is necessary to check that each key image is used at most once.
278  */
279  inline void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) {
280  crypto_ops::generate_key_image(pub, sec, image);
281  }
282  inline void generate_ring_signature(const hash &prefix_hash, const key_image &image,
283  const public_key *const *pubs, std::size_t pubs_count,
284  const secret_key &sec, std::size_t sec_index,
285  signature *sig) {
286  crypto_ops::generate_ring_signature(prefix_hash, image, pubs, pubs_count, sec, sec_index, sig);
287  }
288  inline bool check_ring_signature(const hash &prefix_hash, const key_image &image,
289  const public_key *const *pubs, std::size_t pubs_count,
290  const signature *sig) {
291  return crypto_ops::check_ring_signature(prefix_hash, image, pubs, pubs_count, sig);
292  }
293 
294  /* Variants with vector<const public_key *> parameters.
295  */
296  inline void generate_ring_signature(const hash &prefix_hash, const key_image &image,
297  const std::vector<const public_key *> &pubs,
298  const secret_key &sec, std::size_t sec_index,
299  signature *sig) {
300  generate_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sec, sec_index, sig);
301  }
302  inline bool check_ring_signature(const hash &prefix_hash, const key_image &image,
303  const std::vector<const public_key *> &pubs,
304  const signature *sig) {
305  return check_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sig);
306  }
307 
308  /* Derive a 1-byte view tag from the sender-receiver shared secret to reduce scanning time.
309  * When scanning outputs that were not sent to the user, checking the view tag for a match removes the need to proceed with expensive EC operations
310  * for an expected 99.6% of outputs (expected false positive rate = 1/2^8 = 1/256 = 0.4% = 100% - 99.6%).
311  */
312  inline void derive_view_tag(const key_derivation &derivation, std::size_t output_index, view_tag &vt) {
313  crypto_ops::derive_view_tag(derivation, output_index, vt);
314  }
315 
316  inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
318  }
319  /* Do NOT overload the << operator for crypto::secret_key here. Use secret_key_explicit_print_ref
320  * instead to prevent accidental implicit dumping of secret key material to the logs (which has
321  * happened before). For the same reason, do not overload it for crypto::ec_scalar either since
322  * crypto::secret_key is a subclass. I'm not sorry that it's obtuse; that's the point, bozo.
323  */
325  inline std::ostream &operator <<(std::ostream &o, const secret_key_explicit_print_ref v) {
327  }
328  inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) {
330  }
331  inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) {
333  }
334  inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) {
336  }
337  inline std::ostream &operator <<(std::ostream &o, const crypto::view_tag &v) {
339  }
340 
341  const extern crypto::public_key null_pkey;
342  const extern crypto::secret_key null_skey;
343 
344  inline bool operator<(const public_key &p1, const public_key &p2) { return memcmp(&p1, &p2, sizeof(public_key)) < 0; }
345  inline bool operator>(const public_key &p1, const public_key &p2) { return p2 < p1; }
346 }
347 
const char * res
Definition: hmac_keccak.cpp:42
void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res)
Definition: crypto.h:239
POD_CLASS ec_point
Definition: crypto.h:55
const uint32_t T[512]
Definition: groestl_tables.h:36
#define CRYPTO_MAKE_COMPARABLE(type)
Definition: generic-ops.h:39
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition: span.h:161
static bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &)
bool operator>(const public_key &p1, const public_key &p2)
Definition: crypto.h:345
void derive_secret_key(const key_derivation &derivation, std::size_t output_index, const secret_key &base, secret_key &derived_key)
Definition: crypto.h:242
const crypto::secret_key & sk
Definition: crypto.h:324
Definition: crypto.h:116
static bool secret_key_to_public_key(const secret_key &, public_key &)
Definition: crypto.cpp:180
static bool check_signature(const hash &, const public_key &, const signature &)
Definition: crypto.cpp:319
static void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional< public_key > &, const public_key &, const secret_key &, signature &)
Definition: crypto.cpp:347
static void generate_key_image(const public_key &, const secret_key &, key_image &)
Definition: crypto.cpp:621
POD_CLASS key_derivation
Definition: crypto.h:88
static bool check_key(const public_key &)
Definition: crypto.cpp:175
static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional< public_key > &, const public_key &, const signature &, const int)
Definition: crypto.cpp:508
bool check_ring_signature(const hash &prefix_hash, const key_image &image, const public_key *const *pubs, std::size_t pubs_count, const signature *sig)
Definition: crypto.h:288
void generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig)
Definition: crypto.h:252
std::string data
Definition: base58.cpp:37
const char * key
Definition: hmac_keccak.cpp:40
int type
Definition: superscalar.cpp:50
crypto namespace.
Definition: crypto.cpp:60
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition: crypto.h:72
POD_CLASS view_tag
Definition: crypto.h:103
#define CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(type)
Definition: generic-ops.h:84
tools::wallet2::message_signature_result_t result
Definition: signature.cpp:62
unsigned char uint8_t
Definition: stdint.h:124
POD_CLASS secret_keyV
Definition: crypto.h:79
#define POD_CLASS
Definition: pod-class.h:43
bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation)
Definition: crypto.h:232
Definition: crypto.h:184
void random32_unbiased(unsigned char *bytes)
Definition: crypto.cpp:123
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition: crypto.h:204
static bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &)
Definition: crypto.cpp:245
POD_CLASS public_key_memsafe
Definition: crypto.h:65
const crypto::secret_key null_skey
Definition: crypto.cpp:75
std::enable_if< std::is_integral< T >::value, T >::type rand_range(T range_min, T range_max)
Definition: crypto.h:195
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes)
Definition: crypto.cpp:99
void generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional< public_key > &B, const public_key &D, const secret_key &r, signature &sig)
Definition: crypto.h:263
void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image)
Definition: crypto.h:279
void rand(size_t N, uint8_t *bytes)
Definition: crypto.h:167
constexpr uint32_t B
Definition: jit_compiler_a64.cpp:38
Definition: chaingen.h:294
const crypto::public_key null_pkey
Definition: crypto.cpp:74
static constexpr result_type max()
Definition: crypto.h:188
POD_CLASS public_keyM
Definition: crypto.h:84
POD_CLASS ec_scalar
Definition: crypto.h:59
bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &result)
Definition: crypto.h:246
static void derive_view_tag(const key_derivation &, std::size_t, view_tag &)
static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key &recovery_key=secret_key(), bool recover=false)
Definition: crypto.cpp:153
void derive_view_tag(const key_derivation &derivation, std::size_t output_index, view_tag &vt)
Definition: crypto.h:312
void generate_ring_signature(const hash &prefix_hash, const key_image &image, const public_key *const *pubs, std::size_t pubs_count, const secret_key &sec, std::size_t sec_index, signature *sig)
Definition: crypto.h:282
friend class crypto_ops
Definition: crypto.h:100
static void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional< public_key > &, const public_key &, const secret_key &, signature &)
Definition: crypto.cpp:423
unsigned __int64 uint64_t
Definition: stdint.h:136
static void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &)
secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key &recovery_key=secret_key(), bool recover=false)
Definition: crypto.h:210
POD_CLASS public_key
Definition: crypto.h:61
version
Supported socks variants.
Definition: socks.h:57
r
Definition: testupnpigd.py:61
static bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &)
Definition: crypto.cpp:190
Definition: base.py:1
bool operator<(const public_key &p1, const public_key &p2)
Definition: crypto.h:344
POD_CLASS signature
Definition: crypto.h:98
static constexpr result_type min()
Definition: crypto.h:187
POD_CLASS key_image
Definition: crypto.h:92
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:16
Matcher< T > A()
Definition: gmock-matchers.h:3732
void operator=(const crypto_ops &)
bool derive_public_key(const key_derivation &derivation, std::size_t output_index, const public_key &base, public_key &derived_key)
Definition: crypto.h:235
bool check_key(const public_key &key)
Definition: crypto.h:216
Definition: mlocker.h:68
void hash_to_scalar(const void *data, size_t length, ec_scalar &res)
Definition: crypto.cpp:143
T & unwrap(mlocked< T > &src)
Definition: mlocker.h:81
static bool check_ring_signature(const hash &, const key_image &, const public_key *const *, std::size_t, const signature *)
POD_CLASS hash
Definition: hash.h:49
static void generate_ring_signature(const hash &, const key_image &, const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *)
std::vector< secret_keyV > column_vectors
Definition: crypto.h:87
std::ostream & operator<<(std::ostream &o, const crypto::public_key &v)
Definition: crypto.h:316
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
Definition: crypto.h:222
POD_CLASS public_keyV
Definition: crypto.h:74
void generate_tx_proof_v1(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional< public_key > &B, const public_key &D, const secret_key &r, signature &sig)
Definition: crypto.h:266
public_key_memsafe(const public_key &original)
Definition: crypto.h:69
result_type operator()() const
Definition: crypto.h:189
static void generate_signature(const hash &, const public_key &, const secret_key &, signature &)
Definition: crypto.cpp:290
void add_extra_entropy_thread_safe(const void *ptr, size_t bytes)
Definition: crypto.cpp:105
#define CRYPTO_MAKE_HASHABLE(type)
Definition: generic-ops.h:80
bool check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional< public_key > &B, const public_key &D, const signature &sig, const int version)
Definition: crypto.h:269
uint64_t result_type
Definition: crypto.h:186
static void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res)
Definition: crypto.cpp:205
static void formatted(std::ostream &out, const span< const std::uint8_t > src)
Append < + src + > as hex to out.
Definition: hex.cpp:77
c
Definition: pymoduletest.py:79
bool check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig)
Definition: crypto.h:255
int rows
Definition: crypto.h:76