Electroneum
crypto.h
Go to the documentation of this file.
1 // Copyrights(c) 2017-2021, The Electroneum Project
2 // Copyrights(c) 2014-2019, The Monero Project
3 //
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without modification, are
7 // permitted provided that the following conditions are met:
8 //
9 // 1. Redistributions of source code must retain the above copyright notice, this list of
10 // conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
13 // of conditions and the following disclaimer in the documentation and/or other
14 // materials provided with the distribution.
15 //
16 // 3. Neither the name of the copyright holder nor the names of its contributors may be
17 // used to endorse or promote products derived from this software without specific
18 // prior written permission.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31 
32 #pragma once
33 
34 #include <cstddef>
35 #include <iostream>
36 #include <boost/optional.hpp>
37 #include <type_traits>
38 #include <boost/thread/mutex.hpp>
39 #include <boost/thread/lock_guard.hpp>
40 #include <boost/archive/iterators/binary_from_base64.hpp>
41 #include <boost/archive/iterators/base64_from_binary.hpp>
42 #include <boost/archive/iterators/transform_width.hpp>
43 #include <boost/algorithm/string.hpp>
44 #include <boost/algorithm/hex.hpp>
45 #include <vector>
46 #include <random>
47 
48 #include "ed25519-donna/ed25519.h"
49 
50 #include "common/pod-class.h"
51 #include "memwipe.h"
52 #include "mlocker.h"
53 #include "generic-ops.h"
54 #include "hex.h"
55 #include "span.h"
56 #include "hash.h"
57 #include "warnings.h"
58 
59 extern "C" {
60 #include "crypto-ops.h"
61 }
62 
63 namespace crypto {
64 
65  extern "C" {
66 #include "random.h"
67  }
68 
69 #pragma pack(push, 1)
71  char data[32];
72  };
73 
75  char data[32];
76  };
77 
79  friend class crypto_ops;
80  };
81 
83 
85  std::vector<public_key> keys;
86  int rows;
87  };
88 
90  std::vector<secret_key> keys;
91  int rows;
92  };
93 
95  int cols;
96  int rows;
97  std::vector<secret_keyV> column_vectors;
98  };
99 
101  friend class crypto_ops;
102  };
103 
105  friend class crypto_ops;
106  };
107 
109  ec_scalar c, r;
110  friend class crypto_ops;
111  };
112 
113 #pragma pack(pop)
114 
115  void hash_to_scalar(const void *data, size_t length, ec_scalar &res);
116  void random32_unbiased(unsigned char *bytes);
117  void random_scalar(ec_scalar &res);
118  size_t rs_comm_size(size_t pubs_count);
120  DISABLE_VS_WARNINGS(4200)
121  struct ec_point_pair {
123  };
124  struct rs_comm {
126  struct ec_point_pair ab[];
127  };
129 
130  void hash_to_ec(const public_key &key, ge_p3 &res);
131  void hash_to_ec(const hash& h, ge_p3 &res);
132 
133  static_assert(sizeof(ec_point) == 32 && sizeof(ec_scalar) == 32 &&
134  sizeof(public_key) == 32 && sizeof(secret_key) == 32 &&
135  sizeof(key_derivation) == 32 && sizeof(key_image) == 32 &&
136  sizeof(signature) == 64, "Invalid structure size");
137 
138  class crypto_ops {
139  crypto_ops();
140  crypto_ops(const crypto_ops &);
141  void operator=(const crypto_ops &);
142  ~crypto_ops();
143 
144  static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false);
145  friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover);
146  static bool check_key(const public_key &);
147  friend bool check_key(const public_key &);
148  static bool secret_key_to_public_key(const secret_key &, public_key &);
149  friend bool secret_key_to_public_key(const secret_key &, public_key &);
150  static bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &);
151  friend bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &);
152  static void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res);
153  friend void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res);
154  static bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &);
155  friend bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &);
156  static void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &);
157  friend void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &);
158  static bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &);
159  friend bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &);
160  static void generate_signature(const hash &, const public_key &, const secret_key &, signature &);
161  friend void generate_signature(const hash &, const public_key &, const secret_key &, signature &);
162  static bool check_signature(const hash &, const public_key &, const signature &);
163  friend bool check_signature(const hash &, const public_key &, const signature &);
164  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 &);
165  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 &);
166  static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &);
167  friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &);
168  static void generate_key_image(const public_key &, const secret_key &, key_image &);
169  friend void generate_key_image(const public_key &, const secret_key &, key_image &);
170  static void generate_input_signature(const hash prefix_hash, const uint32_t input_index, const secret_key sec_view, const secret_key sec_spend, signature &sig);
171  friend void generate_input_signature(const hash prefix_hash, const uint32_t input_index, const secret_key sec_view, const secret_key sec_spend, signature &sig);
172  static bool verify_input_signature(const hash &prefix_hash,const uint32_t input_index, const public_key pub_view, const public_key pub_spend, signature sig);
173  friend bool verify_input_signature(const hash &prefix_hash,const uint32_t input_index, const public_key pub_view, const public_key pub_spend, signature sig);
174  static public_key addKeys(const public_key &A, const public_key &B);
175  friend public_key addKeys(const public_key &A, const public_key &B);
176  static secret_key addSecretKeys(const secret_key &A, const secret_key &B);
177  friend secret_key addSecretKeys(const secret_key &A, const secret_key &B);
178  static void generate_ring_signature(const hash &, const key_image &,
179  const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *);
180  friend void generate_ring_signature(const hash &, const key_image &,
181  const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *);
182  static bool check_ring_signature(const hash &, const key_image &,
183  const public_key *const *, std::size_t, const signature *);
184  friend bool check_ring_signature(const hash &, const key_image &,
185  const public_key *const *, std::size_t, const signature *);
186 
187  static std::string sign_message(const std::string &message, const std::string &privateKey);
188  friend std::string sign_message(const std::string &message, const std::string &privateKey);
189  static bool verify_signature(const std::string &message, const std::string &publicKey, const std::string &signature);
190  friend bool verify_signature(const std::string &message, const std::string &publicKey, const std::string &signature);
191  static bool verify_signature(const std::string &message, std::vector<std::string> publicKey, const std::string &signature);
192  friend bool verify_signature(const std::string &message, std::vector<std::string> publicKey, const std::string &signature);
193 
194  static std::vector<std::string> create_ed25519_keypair();
195  friend std::vector<std::string> create_ed25519_keypair();
196 
197  static std::string base64_decode(std::string val);
199  static std::string base64_encode(std::string val);
201  };
202 
203  void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes);
204 
205  /* Generate N random bytes
206  */
207  inline void rand(size_t N, uint8_t *bytes) {
209  }
210 
211  /* Generate a value filled with random bytes.
212  */
213  template<typename T>
215  typename std::remove_cv<T>::type res;
217  return res;
218  }
219 
220  /* UniformRandomBitGenerator using crypto::rand<uint64_t>()
221  */
223  {
225  static constexpr result_type min() { return 0; }
226  static constexpr result_type max() { return result_type(-1); }
227  result_type operator()() const { return crypto::rand<result_type>(); }
228  };
229 
230  /* Generate a random value between range_min and range_max
231  */
232  template<typename T>
233  typename std::enable_if<std::is_integral<T>::value, T>::type rand_range(T range_min, T range_max) {
235  std::uniform_int_distribution<T> dis(range_min, range_max);
236  return dis(rd);
237  }
238 
239  /* Generate a random index between 0 and sz-1
240  */
241  template<typename T>
243  return crypto::rand_range<T>(0, sz-1);
244  }
245 
246  /* Generate a new key pair
247  */
248  inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
249  return crypto_ops::generate_keys(pub, sec, recovery_key, recover);
250  }
251 
252  /* Check a public key. Returns true if it is valid, false otherwise.
253  */
254  inline bool check_key(const public_key &key) {
255  return crypto_ops::check_key(key);
256  }
257 
258  /* Checks a private key and computes the corresponding public key.
259  */
260  inline bool secret_key_to_public_key(const secret_key &sec, public_key &pub) {
261  return crypto_ops::secret_key_to_public_key(sec, pub);
262  }
263 
264  /* To generate an ephemeral key used to send etn to:
265  * * The sender generates a new key pair, which becomes the transaction key. The public transaction key is included in "extra" field.
266  * * Both the sender and the receiver generate key derivation from the transaction key, the receivers' "view" key and the output index.
267  * * The sender uses key derivation and the receivers' "spend" key to derive an ephemeral public key.
268  * * The receiver can either derive the public key (to check that the transaction is addressed to him) or the private key (to spend the etn).
269  */
270  inline bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation) {
271  return crypto_ops::generate_key_derivation(key1, key2, derivation);
272  }
273  inline bool derive_public_key(const key_derivation &derivation, std::size_t output_index,
274  const public_key &base, public_key &derived_key) {
275  return crypto_ops::derive_public_key(derivation, output_index, base, derived_key);
276  }
277  inline void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res) {
278  return crypto_ops::derivation_to_scalar(derivation, output_index, res);
279  }
280  inline void derive_secret_key(const key_derivation &derivation, std::size_t output_index,
281  const secret_key &base, secret_key &derived_key) {
282  crypto_ops::derive_secret_key(derivation, output_index, base, derived_key);
283  }
284  inline bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &result) {
285  return crypto_ops::derive_subaddress_public_key(out_key, derivation, output_index, result);
286  }
287 
288  /* Generation and checking of a standard signature.
289  */
290  inline void generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig) {
291  crypto_ops::generate_signature(prefix_hash, pub, sec, sig);
292  }
293  inline bool check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) {
294  return crypto_ops::check_signature(prefix_hash, pub, sig);
295  }
296 
297  inline void generate_input_signature(const hash prefix_hash, const uint32_t input_index, const secret_key sec_view, const secret_key sec_spend, signature &sig){
298  return crypto_ops::generate_input_signature(prefix_hash, input_index, sec_view, sec_spend, sig);
299  }
300 
301  inline bool verify_input_signature(const hash &prefix_hash,const uint32_t input_index, const public_key pub_view, const public_key pub_spend, signature sig) {
302  return crypto_ops::verify_input_signature(prefix_hash, input_index, pub_view, pub_spend, sig);
303  }
304 
305  /* Generation and checking of a tx proof; given a tx pubkey R, the recipient's view pubkey A, and the key
306  * derivation D, the signature proves the knowledge of the tx secret key r such that R=r*G and D=r*A
307  * 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
308  */
309  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) {
310  crypto_ops::generate_tx_proof(prefix_hash, R, A, B, D, r, sig);
311  }
312  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) {
313  return crypto_ops::check_tx_proof(prefix_hash, R, A, B, D, sig);
314  }
315 
316  /* To send etn to a key:
317  * * The sender generates an ephemeral key and includes it in transaction output.
318  * * To spend the etn, the receiver generates a key image from it.
319  * * Then he selects a bunch of outputs, including the one he spends, and uses them to generate a ring signature.
320  * 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.
321  */
322  inline void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) {
323  crypto_ops::generate_key_image(pub, sec, image);
324  }
325  inline void generate_ring_signature(const hash &prefix_hash, const key_image &image,
326  const public_key *const *pubs, std::size_t pubs_count,
327  const secret_key &sec, std::size_t sec_index,
328  signature *sig) {
329  crypto_ops::generate_ring_signature(prefix_hash, image, pubs, pubs_count, sec, sec_index, sig);
330  }
331  inline bool check_ring_signature(const hash &prefix_hash, const key_image &image,
332  const public_key *const *pubs, std::size_t pubs_count,
333  const signature *sig) {
334  return crypto_ops::check_ring_signature(prefix_hash, image, pubs, pubs_count, sig);
335  }
336 
337  inline public_key addKeys(const public_key &A, const public_key &B) {
338  return crypto_ops::addKeys(A, B);
339  }
340 
341  /* Variants with vector<const public_key *> parameters.
342  */
343  inline void generate_ring_signature(const hash &prefix_hash, const key_image &image,
344  const std::vector<const public_key *> &pubs,
345  const secret_key &sec, std::size_t sec_index,
346  signature *sig) {
347  generate_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sec, sec_index, sig);
348  }
349  inline bool check_ring_signature(const hash &prefix_hash, const key_image &image,
350  const std::vector<const public_key *> &pubs,
351  const signature *sig) {
352  return check_ring_signature(prefix_hash, image, pubs.data(), pubs.size(), sig);
353  }
354 
355  inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) {
357  }
358  inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) {
360  }
361  inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) {
363  }
364  inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) {
366  }
367  inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) {
369  }
370 
371  const extern crypto::public_key null_pkey;
372  const extern crypto::secret_key null_skey;
373 
375  return crypto_ops::sign_message(message, privateKey);
376  }
377 
379  return crypto_ops::verify_signature(message, publicKey, signature);
380  }
381 
382  inline bool verify_signature(const std::string &message, std::vector<std::string> publicKey, const std::string &signature) {
383  return crypto_ops::verify_signature(message, publicKey, signature);
384  }
385 
386  inline std::vector<std::string> create_ed25519_keypair() {
387  return crypto_ops::create_ed25519_keypair();
388  }
389 
390  inline std::string base64_decode(const std::string &val) {
391  using namespace boost::archive::iterators;
392  using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
393  return boost::algorithm::trim_right_copy_if(std::string(It(std::begin(val)), It(std::end(val))), [](char c) {
394  return c == '\0';
395  });
396  }
397 
398  inline std::string base64_encode(const std::string &val) {
399  using namespace boost::archive::iterators;
400  using It = base64_from_binary<transform_width<std::string::const_iterator, 6, 8>>;
401  auto tmp = std::string(It(std::begin(val)), It(std::end(val)));
402  return tmp.append((3 - val.size() % 3) % 3, '=');
403  }
404 }
405 
friend std::string base64_decode(std::string val)
friend secret_key addSecretKeys(const secret_key &A, const secret_key &B)
friend std::string base64_encode(std::string val)
std::string publicKey
std::string privateKey
std::string message("Message requiring signing")
#define CRYPTO_MAKE_HASHABLE_CONSTANT_TIME(type)
Definition: generic-ops.h:80
#define CRYPTO_MAKE_COMPARABLE(type)
Definition: generic-ops.h:39
#define CRYPTO_MAKE_HASHABLE(type)
Definition: generic-ops.h:76
const uint32_t T[512]
PUSH_WARNINGS
Definition: hash-ops.h:54
const char * res
Definition: hmac_keccak.cpp:41
const char * key
Definition: hmac_keccak.cpp:39
crypto namespace.
Definition: crypto.cpp:58
POD_CLASS secret_keyV
Definition: crypto.h:89
const crypto::public_key null_pkey
Definition: crypto.cpp:72
void generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig)
Definition: crypto.h:290
POD_CLASS public_keyM
Definition: crypto.h:94
bool verify_signature(const std::string &message, const std::string &publicKey, const std::string &signature)
Definition: crypto.h:378
bool check_key(const public_key &key)
Definition: crypto.h:254
bool verify_input_signature(const hash &prefix_hash, const uint32_t input_index, const public_key pub_view, const public_key pub_spend, signature sig)
Definition: crypto.h:301
public_key addKeys(const public_key &A, const public_key &B)
Definition: crypto.h:337
void generate_random_bytes_thread_safe(size_t N, uint8_t *bytes)
Definition: crypto.cpp:91
std::vector< std::string > create_ed25519_keypair()
Definition: crypto.h:386
POD_CLASS ec_point
Definition: crypto.h:70
void hash_to_ec(const public_key &key, ge_p3 &res)
Definition: crypto.cpp:479
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:309
POD_CLASS signature
Definition: crypto.h:108
const crypto::secret_key null_skey
Definition: crypto.cpp:73
void generate_input_signature(const hash prefix_hash, const uint32_t input_index, const secret_key sec_view, const secret_key sec_spend, signature &sig)
Definition: crypto.h:297
POD_CLASS public_keyV
Definition: crypto.h:84
std::enable_if< std::is_integral< T >::value, T >::type rand_range(T range_min, T range_max)
Definition: crypto.h:233
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition: crypto.h:82
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:284
size_t rs_comm_size(size_t pubs_count)
Definition: crypto.cpp:505
POD_CLASS key_derivation
Definition: crypto.h:98
secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key &recovery_key=secret_key(), bool recover=false)
Definition: crypto.h:248
void derive_secret_key(const key_derivation &derivation, std::size_t output_index, const secret_key &base, secret_key &derived_key)
Definition: crypto.h:280
std::vector< secret_keyV > column_vectors
Definition: crypto.h:97
bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation)
Definition: crypto.h:270
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:325
POD_CLASS public_key
Definition: crypto.h:76
void random32_unbiased(unsigned char *bytes)
Definition: crypto.cpp:110
bool derive_public_key(const key_derivation &derivation, std::size_t output_index, const public_key &base, public_key &derived_key)
Definition: crypto.h:273
void rand(size_t N, uint8_t *bytes)
Definition: crypto.h:207
std::string base64_encode(const std::string &val)
Definition: crypto.h:398
POD_CLASS key_image
Definition: crypto.h:102
bool check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig)
Definition: crypto.h:293
POD_CLASS ec_scalar
Definition: crypto.h:74
std::string base64_decode(const std::string &val)
Definition: crypto.h:390
std::ostream & operator<<(std::ostream &o, const crypto::public_key &v)
Definition: crypto.h:355
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
Definition: crypto.h:260
std::enable_if< std::is_unsigned< T >::value, T >::type rand_idx(T sz)
Definition: crypto.h:242
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)
Definition: crypto.h:312
void hash_to_scalar(const void *data, size_t length, ec_scalar &res)
Definition: crypto.cpp:126
int rows
Definition: crypto.h:86
POD_CLASS hash
Definition: hash.h:50
void random_scalar(ec_scalar &res)
Definition: crypto.cpp:122
void generate_key_image(const public_key &pub, const secret_key &sec, key_image &image)
Definition: crypto.h:322
std::string sign_message(const std::string &message, const std::string &privateKey)
Definition: crypto.h:374
void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res)
Definition: crypto.h:277
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:331
span< const std::uint8_t > as_byte_span(const T &src) noexcept
Definition: span.h:153
::std::string string
Definition: gtest-port.h:1097
Matcher< T > A()
#define POD_CLASS
Definition: pod-class.h:44
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
unsigned int uint32_t
Definition: stdint.h:126
unsigned char uint8_t
Definition: stdint.h:124
unsigned __int64 uint64_t
Definition: stdint.h:136
static constexpr result_type min()
Definition: crypto.h:225
result_type operator()() const
Definition: crypto.h:227
uint64_t result_type
Definition: crypto.h:224
static constexpr result_type max()
Definition: crypto.h:226
struct ec_point_pair ab[]
Definition: crypto.h:126
static void formatted(std::ostream &out, const span< const std::uint8_t > src)
Append < + src + > as hex to out.
Definition: hex.cpp:76
DISABLE_VS_WARNINGS(4244 4345 4503) using namespace crypto
#define POP_WARNINGS
Definition: warnings.h:17