Offline Transaction Signing (OTS) 0.1.0
Loading...
Searching...
No Matches
account.hpp
Go to the documentation of this file.
1#pragma once
2#include "ots.hpp"
3#include "ots-internal.hpp"
4#include "ots-exceptions.hpp"
5#include "key-store.hpp"
6#include <wipeable_string.h>
7#include <cryptonote_basic/cryptonote_format_utils.h>
8#include <cryptonote_basic/account.h>
9#include <utility>
10#include <unordered_map>
11#include <set>
12
13// transfer_details and exported_transfer_details stuff following
14#include <vector>
15#include <utility>
16#include <crypto/crypto.h> // For crypto::public_key, crypto::hash, crypto::key_image
17#include <crypto/hash.h> // For crypto::hash (if needed separately)
18#include <cryptonote_basic/cryptonote_basic.h> // For cryptonote::transaction_prefix, cryptonote::subaddress_index
19#include <ringct/rctTypes.h> // For rct::key
20#include <serialization/serialization.h> // For serialize support
21#include <serialization/variant.h> // For tools::write_varint
22#include <serialization/tuple.h>
23#include <serialization/pair.h>
24#include <serialization/string.h>
25
39namespace ots {
40 class Account {
41 struct is_out_data;
42 struct tx_scan_info_t;
43 struct exported_transfer_details;
44 struct transfer_details;
45 typedef std::vector<transfer_details> transfer_container;
46
47 public:
53 explicit Account(const std::array<unsigned char, 32>& key, const Network network);
54
60 explicit Account(const crypto::secret_key& key, const Network network);
61
67 explicit Account(const KeyStore& key, const Network network);
68
74 explicit Account(const cryptonote::account_base& account, const Network network);
75
80 explicit Account(const Account& account);
81
86 Address address() const noexcept;
87
92 Address address(uint32_t account, uint32_t index) const noexcept;
93
97 Address address(const cryptonote::subaddress_index index) const noexcept;
98
106 bool hasAddress(
107 const Address& address,
108 uint32_t maxAccountDepth = DEFAULT_MAX_ACCOUNT_DEPTH,
109 uint32_t maxIndexDepth = DEFAULT_MAX_INDEX_DEPTH
110 ) const noexcept;
111
120 std::pair<uint32_t, uint32_t> addressIndex(
121 const Address& address,
122 uint32_t maxAccountDepth = DEFAULT_MAX_ACCOUNT_DEPTH,
123 uint32_t maxIndexDepth = DEFAULT_MAX_INDEX_DEPTH
124 ) const;
125
129 WipeableString secretSpendKey() const noexcept;
130
134 WipeableString publicSpendKey() const noexcept;
135
139 WipeableString secretViewKey() const noexcept;
140
144 WipeableString publicViewKey() const noexcept;
145
149 void clearAddressCache() const noexcept;
150
161 size_t importOutputs(const std::string& outputs);
162
170 size_t importOutputs(const std::tuple<uint64_t, uint64_t, std::vector<exported_transfer_details>> &outputs);
171
179 size_t importOutputs(const std::tuple<uint64_t, uint64_t, std::vector<transfer_details>> &outputs);
180
187 std::string signData(const std::string& data) const;
188
196 std::string signData(const std::string& data, const std::pair<uint32_t, uint32_t>& index) const;
197
208 std::string signData(
209 const std::string& data,
210 const std::string& address,
211 uint32_t maxAccountDepth = DEFAULT_MAX_ACCOUNT_DEPTH,
212 uint32_t maxIndexDepth = DEFAULT_MAX_INDEX_DEPTH
213 ) const;
214
225 std::string signData(const std::string& data, const Address& address, uint32_t maxAccountDepth = DEFAULT_MAX_ACCOUNT_DEPTH, uint32_t maxIndexDepth = DEFAULT_MAX_INDEX_DEPTH) const;
226
236 bool static verifyData(const std::string& data, const Address& address, const std::string& signature);
237
247 bool static verifyData(const std::string& data, const std::string& address, const std::string& signature);
248
258 bool static verifyDataLegacy(const std::string& data, const Address& address, const std::string& signature);
259
269 bool static verifyDataLegacy(const std::string& data, const std::string& address, const std::string& signature);
270
271 private:
280 static crypto::hash hashData(const std::string& data, const crypto::public_key& spendKey, const crypto::public_key& viewKey);
289 std::string decrypt_with_view_secret_key(const std::string& ciphertext, bool authenticated = true) const;
290
298 void authenticate_with_public_view_view_key(const std::string& data, const crypto::signature& signature) const;
299
304 crypto::public_key get_tx_pub_key_from_received_outs(const transfer_details &td) const;
305
306 void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const;
307 void check_acc_out_precomp(const cryptonote::tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, const is_out_data *is_out_data, tx_scan_info_t &tx_scan_info) const;
309 cryptonote::account_base m_account;
310
312 mutable std::unordered_map<std::string, std::pair<uint32_t, uint32_t>> m_addressCache;
313
315 mutable std::map<std::pair<uint32_t, uint32_t>, std::string> m_indexToAddressCache;
316
321 mutable std::set<std::pair<uint32_t, uint32_t>> m_addressIndexCache;
322
329 std::pair<uint32_t, uint32_t> cachedAddressIndex(const Address& address) const;
330
338 void cacheAddress(const Address& address, uint32_t account, uint32_t index) const noexcept;
339
348 void cacheAddress(const Address& address, cryptonote::subaddress_index index) const noexcept;
349
357 void cacheAddress(cryptonote::subaddress_index index) const noexcept;
358
365 bool addressInCache(const Address& address) const noexcept;
366
373 bool addressIndexInCache(const std::pair<uint32_t, uint32_t>& index) const noexcept;
374
383 bool addressIndexInCache(const uint32_t account, const uint32_t index) const noexcept;
384
393 bool addressIndexInCache(const cryptonote::subaddress_index& index) const noexcept;
394
404 Address cachedAddress(const uint32_t account, const uint32_t index) const;
405
416 Address cachedAddress(const cryptonote::subaddress_index index) const;
417 Network m_network;
418
419 struct multisig_info
420 {
421 struct LR
422 {
423 rct::key m_L;
424 rct::key m_R;
425
426 BEGIN_SERIALIZE_OBJECT()
427 FIELD(m_L)
428 FIELD(m_R)
429 END_SERIALIZE()
430 };
431
432 crypto::public_key m_signer;
433 std::vector<LR> m_LR;
434 std::vector<crypto::key_image> m_partial_key_images; // one per key the participant has
435
436 BEGIN_SERIALIZE_OBJECT()
437 FIELD(m_signer)
438 FIELD(m_LR)
439 FIELD(m_partial_key_images)
440 END_SERIALIZE()
441 };
442
443 struct transfer_details
444 {
445 uint64_t m_block_height;
446 cryptonote::transaction_prefix m_tx;
447 crypto::hash m_txid;
448 uint64_t m_internal_output_index;
449 uint64_t m_global_output_index;
450 bool m_spent;
451 bool m_frozen;
452 uint64_t m_spent_height;
453 crypto::key_image m_key_image; //TODO: key_image stored twice :(
454 rct::key m_mask;
455 uint64_t m_amount;
456 bool m_rct;
457 bool m_key_image_known;
458 bool m_key_image_request; // view wallets: we want to request it; cold wallets: it was requested
459 uint64_t m_pk_index;
460 cryptonote::subaddress_index m_subaddr_index;
461 bool m_key_image_partial;
462 std::vector<rct::key> m_multisig_k;
463 std::vector<multisig_info> m_multisig_info; // one per other participant
464 std::vector<std::pair<uint64_t, crypto::hash>> m_uses;
465
466 bool is_rct() const { return m_rct; }
467 uint64_t amount() const { return m_amount; }
468 const crypto::public_key get_public_key() const {
469 crypto::public_key output_public_key;
470 if(m_tx.vout.size() <= m_internal_output_index)
471 throw ots::exception::wallet::InternalError("Too few outputs, outputs may be corrupted");
472 if(!get_output_public_key(m_tx.vout[m_internal_output_index], output_public_key))
473 throw ots::exception::wallet::InternalError("Unable to get output public key from output");
474 return output_public_key;
475 };
476
477 BEGIN_SERIALIZE_OBJECT()
478 FIELD(m_block_height)
479 FIELD(m_tx)
480 FIELD(m_txid)
481 FIELD(m_internal_output_index)
482 FIELD(m_global_output_index)
483 FIELD(m_spent)
484 FIELD(m_frozen)
485 FIELD(m_spent_height)
486 FIELD(m_key_image)
487 FIELD(m_mask)
488 FIELD(m_amount)
489 FIELD(m_rct)
490 FIELD(m_key_image_known)
491 FIELD(m_key_image_request)
492 FIELD(m_pk_index)
493 FIELD(m_subaddr_index)
494 FIELD(m_key_image_partial)
495 FIELD(m_multisig_k)
496 FIELD(m_multisig_info)
497 FIELD(m_uses)
498 END_SERIALIZE()
499 };
500
501 struct exported_transfer_details
502 {
503 crypto::public_key m_pubkey;
504 uint64_t m_internal_output_index;
505 uint64_t m_global_output_index;
506 crypto::public_key m_tx_pubkey;
507 union
508 {
509 struct
510 {
511 uint8_t m_spent: 1;
512 uint8_t m_frozen: 1;
513 uint8_t m_rct: 1;
514 uint8_t m_key_image_known: 1;
515 uint8_t m_key_image_request: 1; // view wallets: we want to request it; cold wallets: it was requested
516 uint8_t m_key_image_partial: 1;
517 };
518 uint8_t flags;
519 } m_flags;
520 uint64_t m_amount;
521 std::vector<crypto::public_key> m_additional_tx_keys;
522 uint32_t m_subaddr_index_major;
523 uint32_t m_subaddr_index_minor;
524
525 BEGIN_SERIALIZE_OBJECT()
526 VERSION_FIELD(1)
527 if (version < 1)
528 return false;
529 FIELD(m_pubkey)
530 VARINT_FIELD(m_internal_output_index)
531 VARINT_FIELD(m_global_output_index)
532 FIELD(m_tx_pubkey)
533 FIELD(m_flags.flags)
534 VARINT_FIELD(m_amount)
535 FIELD(m_additional_tx_keys)
536 VARINT_FIELD(m_subaddr_index_major)
537 VARINT_FIELD(m_subaddr_index_minor)
538 END_SERIALIZE()
539 };
540
541 struct tx_scan_info_t
542 {
543 cryptonote::keypair in_ephemeral;
544 crypto::key_image ki;
545 rct::key mask;
546 uint64_t amount;
547 uint64_t money_transfered;
548 bool error;
549 boost::optional<cryptonote::subaddress_receive_info> received;
550
551 tx_scan_info_t(): amount(0), money_transfered(0), error(true) {}
552 };
553
554 struct is_out_data
555 {
556 crypto::public_key pkey;
557 crypto::key_derivation derivation;
558 std::vector<boost::optional<cryptonote::subaddress_receive_info>> received;
559 };
560
561 transfer_container m_transfers;
562 std::unordered_map<crypto::key_image, size_t> m_key_images;
563 std::unordered_map<crypto::public_key, size_t> m_pub_keys;
564 std::unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
565 std::vector<std::vector<std::string>> m_subaddress_labels;
566 size_t m_subaddress_lookahead_major, m_subaddress_lookahead_minor;
567 };
568}
holds monero internal account and internal functions
Definition account.hpp:40
WipeableString secretSpendKey() const noexcept
secret spend key of the wallet in hex digits
Definition account.cpp:145
std::string signData(const std::string &data) const
sign a message with the wallet
Definition account.cpp:478
Address address() const noexcept
the public address of the wallet/account(0)
Definition account.cpp:35
size_t importOutputs(const std::string &outputs)
import outputs from a string
Definition account.cpp:241
WipeableString secretViewKey() const noexcept
secret view key of the wallet in hex digits
Definition account.cpp:153
void clearAddressCache() const noexcept
clear the address cache
Definition account.cpp:568
bool hasAddress(const Address &address, uint32_t maxAccountDepth=DEFAULT_MAX_ACCOUNT_DEPTH, uint32_t maxIndexDepth=DEFAULT_MAX_INDEX_DEPTH) const noexcept
check if the address is in the wallet, but restricted to the search depth
Definition account.cpp:95
WipeableString publicSpendKey() const noexcept
public spend key of the wallet in hex digits
Definition account.cpp:149
std::pair< uint32_t, uint32_t > addressIndex(const Address &address, uint32_t maxAccountDepth=DEFAULT_MAX_ACCOUNT_DEPTH, uint32_t maxIndexDepth=DEFAULT_MAX_INDEX_DEPTH) const
get the account and subindex of a address in the Wallet
Definition account.cpp:127
WipeableString publicViewKey() const noexcept
public view key of the wallet in hex digits
Definition account.cpp:157
static bool verifyData(const std::string &data, const Address &address, const std::string &signature)
verify a signed message
Definition account.cpp:517
static bool verifyDataLegacy(const std::string &data, const Address &address, const std::string &signature)
verify a signed message
Definition account.cpp:542
Represents a Monero address.
Definition ots.hpp:848
essentialy wraps crypto::secret_key
Definition key-store.hpp:18
String class that wipes its memory on destruction.
Definition ots.hpp:1494
an internal error occurred (monero specific)
Definition ots-exceptions.hpp:642
decoupling of crypto/crypto.h of the monero source
The library exists complete only in this namespace.
Definition account.hpp:39
Network
Represents the monero network.
Definition ots.hpp:63
Header for the C++ library Exceptions.
Internal declarations for library.
Header for the C++ library.
#define DEFAULT_MAX_INDEX_DEPTH
The default maximum index depth, to search for an address in an account of the wallet.
Definition ots.hpp:32
#define DEFAULT_MAX_ACCOUNT_DEPTH
The default maximum account depth, to search for an address in the wallet.
Definition ots.hpp:23
Definition account.hpp:422
rct::key m_R
Definition account.hpp:424
rct::key m_L
Definition account.hpp:423