Electroneum
Loading...
Searching...
No Matches
hw::trezor::protocol::tx::Signer Class Reference

#include <protocol.hpp>

Public Member Functions

 Signer (wallet_shim *wallet2, const unsigned_tx_set *unsigned_tx, size_t tx_idx=0, hw::tx_aux_data *aux_data=nullptr)
std::shared_ptr< messages::electroneum::ElectroneumTransactionInitRequest > step_init ()
void step_init_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionInitAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetInputRequest > step_set_input (size_t idx)
void step_set_input_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetInputAck > ack)
void sort_ki ()
std::shared_ptr< messages::electroneum::ElectroneumTransactionInputsPermutationRequest > step_permutation ()
void step_permutation_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputsPermutationAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionInputViniRequest > step_set_vini_input (size_t idx)
void step_set_vini_input_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputViniAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionAllInputsSetRequest > step_all_inputs_set ()
void step_all_inputs_set_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllInputsSetAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetOutputRequest > step_set_output (size_t idx)
void step_set_output_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetOutputRequest > step_rsig (size_t idx)
void step_set_rsig_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionAllOutSetRequest > step_all_outs_set ()
void step_all_outs_set_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllOutSetAck > ack, hw::device &hwdev)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSignInputRequest > step_sign_input (size_t idx)
void step_sign_input_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionSignInputAck > ack)
std::shared_ptr< messages::electroneum::ElectroneumTransactionFinalRequest > step_final ()
void step_final_ack (std::shared_ptr< const messages::electroneum::ElectroneumTransactionFinalAck > ack)
std::string store_tx_aux_info ()
unsigned client_version () const
bool is_simple () const
bool is_req_bulletproof () const
bool is_bulletproof () const
bool is_offloading () const
size_t num_outputs () const
size_t num_inputs () const
const TDatatdata () const

Detailed Description

Definition at line 212 of file protocol.hpp.

Constructor & Destructor Documentation

◆ Signer()

hw::trezor::protocol::tx::Signer::Signer ( wallet_shim * wallet2,
const unsigned_tx_set * unsigned_tx,
size_t tx_idx = 0,
hw::tx_aux_data * aux_data = nullptr )

Definition at line 380 of file protocol.cpp.

380 {
381 m_wallet2 = wallet2;
382 m_unsigned_tx = unsigned_tx;
383 m_aux_data = aux_data;
384 m_tx_idx = tx_idx;
385 m_ct.tx_data = cur_tx();
386 m_multisig = false;
387 m_client_version = 1;
388 }

Member Function Documentation

◆ client_version()

unsigned hw::trezor::protocol::tx::Signer::client_version ( ) const
inline

Definition at line 271 of file protocol.hpp.

271 {
272 return m_client_version;
273 }
Here is the caller graph for this function:

◆ is_bulletproof()

bool hw::trezor::protocol::tx::Signer::is_bulletproof ( ) const
inline

Definition at line 287 of file protocol.hpp.

287 {
288 if (!m_ct.rv){
289 throw std::invalid_argument("RV not initialized");
290 }
291 auto tp = m_ct.rv->type;
293 }
@ RCTTypeBulletproof2
Definition rctTypes.h:233
@ RCTTypeBulletproof
Definition rctTypes.h:232
Here is the caller graph for this function:

◆ is_offloading()

bool hw::trezor::protocol::tx::Signer::is_offloading ( ) const
inline

Definition at line 295 of file protocol.hpp.

295 {
296 return m_ct.rsig_param && m_ct.rsig_param->offload_type() != 0;
297 }
Here is the caller graph for this function:

◆ is_req_bulletproof()

bool hw::trezor::protocol::tx::Signer::is_req_bulletproof ( ) const
inline

Definition at line 283 of file protocol.hpp.

283 {
284 return m_ct.tx_data.rct_config.range_proof_type != rct::RangeProofBorromean;
285 }
@ RangeProofBorromean
Definition rctTypes.h:235
Here is the caller graph for this function:

◆ is_simple()

bool hw::trezor::protocol::tx::Signer::is_simple ( ) const
inline

Definition at line 275 of file protocol.hpp.

275 {
276 if (!m_ct.rv){
277 throw std::invalid_argument("RV not initialized");
278 }
279 auto tp = m_ct.rv->type;
280 return tp == rct::RCTTypeSimple;
281 }
@ RCTTypeSimple
Definition rctTypes.h:231
Here is the caller graph for this function:

◆ num_inputs()

size_t hw::trezor::protocol::tx::Signer::num_inputs ( ) const
inline

Definition at line 303 of file protocol.hpp.

303 {
304 return m_ct.tx_data.sources.size();
305 }

◆ num_outputs()

size_t hw::trezor::protocol::tx::Signer::num_outputs ( ) const
inline

Definition at line 299 of file protocol.hpp.

299 {
300 return m_ct.tx_data.splitted_dsts.size();
301 }
Here is the caller graph for this function:

◆ sort_ki()

void hw::trezor::protocol::tx::Signer::sort_ki ( )

Definition at line 579 of file protocol.cpp.

579 {
580 const size_t input_size = cur_tx().sources.size();
581
582 m_ct.source_permutation.clear();
583 for (size_t n = 0; n < input_size; ++n){
584 m_ct.source_permutation.push_back(n);
585 }
586
587 CHECK_AND_ASSERT_THROW_MES(m_ct.tx.vin.size() == input_size, "Invalid vector size");
588 std::sort(m_ct.source_permutation.begin(), m_ct.source_permutation.end(), [&](const size_t i0, const size_t i1) {
589 const cryptonote::txin_to_key &tk0 = boost::get<cryptonote::txin_to_key>(m_ct.tx.vin[i0]);
590 const cryptonote::txin_to_key &tk1 = boost::get<cryptonote::txin_to_key>(m_ct.tx.vin[i1]);
591 return memcmp(&tk0.k_image, &tk1.k_image, sizeof(tk0.k_image)) > 0;
592 });
593
594 CHECK_AND_ASSERT_THROW_MES(m_ct.tx_in_hmacs.size() == input_size, "Invalid vector size");
595 CHECK_AND_ASSERT_THROW_MES(m_ct.pseudo_outs.size() == input_size, "Invalid vector size");
596 CHECK_AND_ASSERT_THROW_MES(m_ct.pseudo_outs_hmac.size() == input_size, "Invalid vector size");
597 CHECK_AND_ASSERT_THROW_MES(m_ct.alphas.size() == input_size, "Invalid vector size");
598 CHECK_AND_ASSERT_THROW_MES(m_ct.spend_encs.size() == input_size, "Invalid vector size");
599 CHECK_AND_ASSERT_THROW_MES(m_ct.tx_data.sources.size() == input_size, "Invalid vector size");
600
601 tools::apply_permutation(m_ct.source_permutation, [&](size_t i0, size_t i1){
602 std::swap(m_ct.tx.vin[i0], m_ct.tx.vin[i1]);
603 std::swap(m_ct.tx_in_hmacs[i0], m_ct.tx_in_hmacs[i1]);
604 std::swap(m_ct.pseudo_outs[i0], m_ct.pseudo_outs[i1]);
605 std::swap(m_ct.pseudo_outs_hmac[i0], m_ct.pseudo_outs_hmac[i1]);
606 std::swap(m_ct.alphas[i0], m_ct.alphas[i1]);
607 std::swap(m_ct.spend_encs[i0], m_ct.spend_encs[i1]);
608 std::swap(m_ct.tx_data.sources[i0], m_ct.tx_data.sources[i1]);
609 });
610 }
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
void apply_permutation(std::vector< size_t > permutation, const F &swap)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ step_all_inputs_set()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionAllInputsSetRequest > hw::trezor::protocol::tx::Signer::step_all_inputs_set ( )

Definition at line 652 of file protocol.cpp.

652 {
653 return std::make_shared<messages::Electroneum::ElectroneumTransactionAllInputsSetRequest>();
654 }

◆ step_all_inputs_set_ack()

void hw::trezor::protocol::tx::Signer::step_all_inputs_set_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllInputsSetAck > ack)

Definition at line 656 of file protocol.cpp.

656 {
657 if (client_version() > 0 || !is_offloading()){
658 return;
659 }
660
661 // If offloading, expect rsig configuration.
662 if (!ack->has_rsig_data()){
663 throw exc::ProtocolException("Rsig offloading requires rsig param");
664 }
665
666 auto & rsig_data = ack->rsig_data();
667 if (!rsig_data.has_mask()){
668 throw exc::ProtocolException("Gamma masks not present in offloaded version");
669 }
670
671 auto & mask = rsig_data.mask();
672 if (mask.size() != 32 * num_outputs()){
673 throw exc::ProtocolException("Invalid number of gamma masks");
674 }
675
676 m_ct.rsig_gamma.reserve(num_outputs());
677 for(size_t c=0; c < num_outputs(); ++c){
678 rct::key cmask{};
679 memcpy(cmask.bytes, mask.data() + c * 32, 32);
680 m_ct.rsig_gamma.emplace_back(cmask);
681 }
682 }
void * memcpy(void *a, const void *b, size_t c)
unsigned char bytes[32]
Definition rctTypes.h:86
Here is the call graph for this function:

◆ step_all_outs_set()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionAllOutSetRequest > hw::trezor::protocol::tx::Signer::step_all_outs_set ( )

Definition at line 833 of file protocol.cpp.

833 {
834 return std::make_shared<messages::Electroneum::ElectroneumTransactionAllOutSetRequest>();
835 }

◆ step_all_outs_set_ack()

void hw::trezor::protocol::tx::Signer::step_all_outs_set_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllOutSetAck > ack,
hw::device & hwdev )

Definition at line 837 of file protocol.cpp.

837 {
838 m_ct.rv = std::make_shared<rct::rctSig>();
839 m_ct.rv->txnFee = ack->rv().txn_fee();
840 m_ct.rv->type = static_cast<uint8_t>(ack->rv().rv_type());
841 string_to_key(m_ct.rv->message, ack->rv().message());
842
843 // Extra copy
844 m_ct.tx.extra.clear();
845 auto extra = ack->extra();
846 auto extra_data = extra.data();
847 m_ct.tx.extra.reserve(extra.size());
848 for(size_t i = 0; i < extra.size(); ++i){
849 m_ct.tx.extra.push_back(static_cast<uint8_t>(extra_data[i]));
850 }
851
852 ::crypto::hash tx_prefix_hash{};
853 cryptonote::get_transaction_prefix_hash(m_ct.tx, tx_prefix_hash);
854 m_ct.tx_prefix_hash = key_to_string(tx_prefix_hash);
855 if (crypto_verify_32(reinterpret_cast<const unsigned char *>(tx_prefix_hash.data),
856 reinterpret_cast<const unsigned char *>(ack->tx_prefix_hash().data()))){
857 throw exc::proto::SecurityException("Transaction prefix has does not match to the computed value");
858 }
859
860 // RctSig
861 auto num_sources = m_ct.tx_data.sources.size();
862 if (is_simple() || is_req_bulletproof()){
863 auto dst = &m_ct.rv->pseudoOuts;
864 if (is_bulletproof()){
865 dst = &m_ct.rv->p.pseudoOuts;
866 }
867
868 dst->clear();
869 for (const auto &pseudo_out : m_ct.pseudo_outs) {
870 dst->emplace_back();
871 string_to_key(dst->back(), pseudo_out);
872 }
873
874 m_ct.rv->mixRing.resize(num_sources);
875 } else {
876 m_ct.rv->mixRing.resize(m_ct.tsx_data.mixin());
877 m_ct.rv->mixRing[0].resize(num_sources);
878 }
879
880 CHECK_AND_ASSERT_THROW_MES(m_ct.tx_out_pk.size() == m_ct.tx_out_ecdh.size(), "Invalid vector sizes");
881 for(size_t i = 0; i < m_ct.tx_out_ecdh.size(); ++i){
882 m_ct.rv->outPk.push_back(m_ct.tx_out_pk[i]);
883 m_ct.rv->ecdhInfo.push_back(m_ct.tx_out_ecdh[i]);
884 }
885
886 for(size_t i = 0; i < m_ct.tx_out_rsigs.size(); ++i){
887 if (is_bulletproof()){
888 m_ct.rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs[i]));
889 } else {
890 m_ct.rv->p.rangeSigs.push_back(boost::get<rct::rangeSig>(m_ct.tx_out_rsigs[i]));
891 }
892 }
893
894 rct::key hash_computed = rct::get_pre_mlsag_hash(*(m_ct.rv), hwdev);
895 auto & hash = ack->full_message_hash();
896
897 if (hash.size() != 32){
898 throw exc::ProtocolException("Returned mlsag hash has invalid size");
899 }
900
901 if (crypto_verify_32(reinterpret_cast<const unsigned char *>(hash_computed.bytes),
902 reinterpret_cast<const unsigned char *>(hash.data()))){
903 throw exc::proto::SecurityException("Computed MLSAG does not match");
904 }
905 }
int crypto_verify_32(const unsigned char *, const unsigned char *)
POD_CLASS hash
Definition hash.h:50
void get_transaction_prefix_hash(const transaction_prefix &tx, crypto::hash &h)
void string_to_key(::crypto::ec_scalar &key, const std::string &str)
Definition protocol.cpp:96
std::string key_to_string(const ::crypto::ec_point &key)
Definition protocol.cpp:80
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev)
Definition rctSigs.cpp:403
unsigned char uint8_t
Definition stdint.h:124
Here is the call graph for this function:

◆ step_final()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionFinalRequest > hw::trezor::protocol::tx::Signer::step_final ( )

Definition at line 952 of file protocol.cpp.

952 {
953 m_ct.tx.rct_signatures = *(m_ct.rv);
954 return std::make_shared<messages::Electroneum::ElectroneumTransactionFinalRequest>();
955 }

◆ step_final_ack()

void hw::trezor::protocol::tx::Signer::step_final_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionFinalAck > ack)

Definition at line 957 of file protocol.cpp.

957 {
958 if (m_multisig){
959 auto & cout_key = ack->cout_key();
960 for(auto & cur : m_ct.couts){
961 if (cur.size() != crypto::chacha::IV_SIZE + 32){
962 throw std::invalid_argument("Encrypted cout has invalid length");
963 }
964
965 char buff[32];
966 auto data = cur.data();
967
968 crypto::chacha::decrypt(data + crypto::chacha::IV_SIZE, 32, reinterpret_cast<const uint8_t *>(cout_key.data()), reinterpret_cast<const uint8_t *>(data), buff);
969 m_ct.couts_dec.emplace_back(buff, 32);
970 }
971 }
972
973 m_ct.enc_salt1 = ack->salt();
974 m_ct.enc_salt2 = ack->rand_mult();
975 m_ct.enc_keys = ack->tx_enc_keys();
976 }
void decrypt(const void *ciphertext, size_t length, const uint8_t *key, const uint8_t *iv, char *plaintext, size_t *plaintext_len)
Definition protocol.cpp:120
Here is the call graph for this function:

◆ step_init()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionInitRequest > hw::trezor::protocol::tx::Signer::step_init ( )

Definition at line 490 of file protocol.cpp.

490 {
491 // extract payment ID from construction data
492 auto & tsx_data = m_ct.tsx_data;
493 auto & tx = cur_tx();
494
495 m_ct.tx.version = 4;
496 m_ct.tx.unlock_time = tx.unlock_time;
497 m_client_version = (m_aux_data->client_version ? m_aux_data->client_version.get() : 1);
498
499 tsx_data.set_version(1);
500 tsx_data.set_client_version(client_version());
501 tsx_data.set_unlock_time(tx.unlock_time);
502 tsx_data.set_num_inputs(static_cast<google::protobuf::uint32>(tx.sources.size()));
503 tsx_data.set_mixin(static_cast<google::protobuf::uint32>(tx.sources[0].outputs.size() - 1));
504 tsx_data.set_account(tx.subaddr_account);
505 assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
506
507 // Rsig decision
508 auto rsig_data = tsx_data.mutable_rsig_data();
509 m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size());
510 rsig_data->set_rsig_type(m_ct.rsig_type);
511 if (tx.rct_config.range_proof_type != rct::RangeProofBorromean){
512 m_ct.bp_version = (m_aux_data->bp_version ? m_aux_data->bp_version.get() : 1);
513 rsig_data->set_bp_version((uint32_t) m_ct.bp_version);
514 }
515
516 generate_rsig_batch_sizes(m_ct.grouping_vct, m_ct.rsig_type, tx.splitted_dsts.size());
517 assign_to_repeatable(rsig_data->mutable_grouping(), m_ct.grouping_vct.begin(), m_ct.grouping_vct.end());
518
519 translate_dst_entry(tsx_data.mutable_change_dts(), &(tx.change_dts));
520 for(auto & cur : tx.splitted_dsts){
521 auto dst = tsx_data.mutable_outputs()->Add();
522 translate_dst_entry(dst, &cur);
523 }
524
525 compute_integrated_indices(&tsx_data);
526
527 int64_t fee = 0;
528 for(auto & cur_in : tx.sources){
529 fee += cur_in.amount;
530 }
531 for(auto & cur_out : tx.splitted_dsts){
532 fee -= cur_out.amount;
533 }
534 if (fee < 0){
535 throw std::invalid_argument("Fee cannot be negative");
536 }
537
538 tsx_data.set_fee(static_cast<google::protobuf::uint64>(fee));
539 this->extract_payment_id();
540
541 auto init_req = std::make_shared<messages::Electroneum::ElectroneumTransactionInitRequest>();
542 init_req->set_version(0);
543 init_req->mutable_tsx_data()->CopyFrom(tsx_data);
544 return init_req;
545 }
void translate_dst_entry(ElectroneumTransactionDestinationEntry *dst, const cryptonote::tx_destination_entry *src)
Definition protocol.cpp:277
void assign_to_repeatable(::google::protobuf::RepeatedField< sub_t > *dst, const InputIterator begin, const InputIterator end)
Definition protocol.hpp:53
signed __int64 int64_t
Definition stdint.h:135
unsigned int uint32_t
Definition stdint.h:126
Here is the call graph for this function:

◆ step_init_ack()

void hw::trezor::protocol::tx::Signer::step_init_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionInitAck > ack)

Definition at line 547 of file protocol.cpp.

547 {
548 if (ack->has_rsig_data()){
549 m_ct.rsig_param = std::make_shared<ElectroneumRsigData>(ack->rsig_data());
550 }
551
552 assign_from_repeatable(&(m_ct.tx_out_entr_hmacs), ack->hmacs().begin(), ack->hmacs().end());
553 }
void assign_from_repeatable(std::vector< sub_t > *dst, const InputIterator begin, const InputIterator end)
Definition protocol.hpp:61
Here is the call graph for this function:

◆ step_permutation()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionInputsPermutationRequest > hw::trezor::protocol::tx::Signer::step_permutation ( )

Definition at line 612 of file protocol.cpp.

612 {
613 sort_ki();
614
615 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionInputsPermutationRequest>();
616 assign_to_repeatable(res->mutable_perm(), m_ct.source_permutation.begin(), m_ct.source_permutation.end());
617
618 return res;
619 }
const char * res
Here is the call graph for this function:

◆ step_permutation_ack()

void hw::trezor::protocol::tx::Signer::step_permutation_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputsPermutationAck > ack)

Definition at line 621 of file protocol.cpp.

621 {
622
623 }

◆ step_rsig()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionSetOutputRequest > hw::trezor::protocol::tx::Signer::step_rsig ( size_t idx)

Definition at line 813 of file protocol.cpp.

813 {
814 if (client_version() == 0 || !is_offloading() || !should_compute_bp_now()){
815 return nullptr;
816 }
817
818 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetOutputRequest>();
819 auto & cur_dst = m_ct.tx_data.splitted_dsts[idx];
820 translate_dst_entry(res->mutable_dst_entr(), &cur_dst);
821 res->set_dst_entr_hmac(m_ct.tx_out_entr_hmacs[idx]);
822
823 compute_bproof(*(res->mutable_rsig_data()));
824 res->set_is_offloaded_bp(true);
825 return res;
826 }
Here is the call graph for this function:

◆ step_set_input()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionSetInputRequest > hw::trezor::protocol::tx::Signer::step_set_input ( size_t idx)

Definition at line 555 of file protocol.cpp.

555 {
556 CHECK_AND_ASSERT_THROW_MES(idx < cur_tx().sources.size(), "Invalid source index");
557 m_ct.cur_input_idx = idx;
558 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetInputRequest>();
559 translate_src_entry(res->mutable_src_entr(), &(cur_tx().sources[idx]));
560 return res;
561 }
void translate_src_entry(ElectroneumTransactionSourceEntry *dst, const cryptonote::tx_source_entry *src)
Definition protocol.cpp:285
Here is the call graph for this function:

◆ step_set_input_ack()

void hw::trezor::protocol::tx::Signer::step_set_input_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetInputAck > ack)

Definition at line 563 of file protocol.cpp.

563 {
564 auto & vini_str = ack->vini();
565
567 if (!cn_deserialize(vini_str.data(), vini_str.size(), vini)){
568 throw exc::ProtocolException("Cannot deserialize vin[i]");
569 }
570
571 m_ct.tx.vin.emplace_back(vini);
572 m_ct.tx_in_hmacs.push_back(ack->vini_hmac());
573 m_ct.pseudo_outs.push_back(ack->pseudo_out());
574 m_ct.pseudo_outs_hmac.push_back(ack->pseudo_out_hmac());
575 m_ct.alphas.push_back(ack->pseudo_out_alpha());
576 m_ct.spend_encs.push_back(ack->spend_key());
577 }
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_to_key_public > txin_v
bool cn_deserialize(const void *buff, size_t len, T &dst)
Definition protocol.hpp:68
Here is the call graph for this function:

◆ step_set_output()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionSetOutputRequest > hw::trezor::protocol::tx::Signer::step_set_output ( size_t idx)

Definition at line 684 of file protocol.cpp.

684 {
685 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_data.splitted_dsts.size(), "Invalid transaction index");
686 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_out_entr_hmacs.size(), "Invalid transaction index");
687 CHECK_AND_ASSERT_THROW_MES(is_req_bulletproof(), "Borromean rsig not supported");
688
689 m_ct.cur_output_idx = idx;
690 m_ct.cur_output_in_batch_idx += 1; // assumes sequential call to step_set_output()
691
692 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetOutputRequest>();
693 auto & cur_dst = m_ct.tx_data.splitted_dsts[idx];
694 translate_dst_entry(res->mutable_dst_entr(), &cur_dst);
695 res->set_dst_entr_hmac(m_ct.tx_out_entr_hmacs[idx]);
696
697 // Range sig offloading to the host
698 // ClientV0 sends offloaded BP with the last message in the batch.
699 // ClientV1 needs additional message after the last message in the batch as BP uses deterministic masks.
700 if (client_version() == 0 && is_offloading() && should_compute_bp_now()) {
701 auto rsig_data = res->mutable_rsig_data();
702 compute_bproof(*rsig_data);
703 }
704
705 return res;
706 }
Here is the call graph for this function:

◆ step_set_output_ack()

void hw::trezor::protocol::tx::Signer::step_set_output_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)

Definition at line 708 of file protocol.cpp.

708 {
709 cryptonote::tx_out tx_out;
710 rct::Bulletproof bproof{};
711 rct::ctkey out_pk{};
712 rct::ecdhTuple ecdh{};
713
714 bool has_rsig = false;
715 std::string rsig_buff;
716
717 if (ack->has_rsig_data()){
718 auto & rsig_data = ack->rsig_data();
719
720 if (rsig_data.has_rsig() && !rsig_data.rsig().empty()){
721 has_rsig = true;
722 rsig_buff = rsig_data.rsig();
723 }
724
725 if (client_version() >= 1 && rsig_data.has_mask()){
726 rct::key cmask{};
727 string_to_key(cmask, rsig_data.mask());
728 m_ct.rsig_gamma.emplace_back(cmask);
729 }
730 }
731
732 if (!cn_deserialize(ack->tx_out(), tx_out)){
733 throw exc::ProtocolException("Cannot deserialize vout[i]");
734 }
735
736 if (!cn_deserialize(ack->out_pk(), out_pk)){
737 throw exc::ProtocolException("Cannot deserialize out_pk");
738 }
739
740 if (m_ct.bp_version <= 1) {
741 if (!cn_deserialize(ack->ecdh_info(), ecdh)){
742 throw exc::ProtocolException("Cannot deserialize ecdhtuple");
743 }
744 } else {
745 CHECK_AND_ASSERT_THROW_MES(8 == ack->ecdh_info().size(), "Invalid ECDH.amount size");
746 memcpy(ecdh.amount.bytes, ack->ecdh_info().data(), 8);
747 }
748
749 if (has_rsig && is_req_bulletproof() && !cn_deserialize(rsig_buff, bproof)){
750 throw exc::ProtocolException("Cannot deserialize bulletproof rangesig");
751 }
752
753 m_ct.tx.vout.emplace_back(tx_out);
754 m_ct.tx_out_hmacs.push_back(ack->vouti_hmac());
755 m_ct.tx_out_pk.emplace_back(out_pk);
756 m_ct.tx_out_ecdh.emplace_back(ecdh);
757
758 // ClientV0, if no rsig was generated on Trezor, do not continue.
759 // ClientV1+ generates BP after all masks in the current batch are generated
760 if (!has_rsig || (client_version() >= 1 && is_offloading())){
761 return;
762 }
763
764 process_bproof(bproof);
765 m_ct.cur_batch_idx += 1;
766 m_ct.cur_output_in_batch_idx = 0;
767 }
Here is the call graph for this function:

◆ step_set_rsig_ack()

void hw::trezor::protocol::tx::Signer::step_set_rsig_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)

Definition at line 828 of file protocol.cpp.

828 {
829 m_ct.cur_batch_idx += 1;
830 m_ct.cur_output_in_batch_idx = 0;
831 }

◆ step_set_vini_input()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionInputViniRequest > hw::trezor::protocol::tx::Signer::step_set_vini_input ( size_t idx)

Definition at line 625 of file protocol.cpp.

625 {
626 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_data.sources.size(), "Invalid transaction index");
627 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx.vin.size(), "Invalid transaction index");
628 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_in_hmacs.size(), "Invalid transaction index");
629
630 m_ct.cur_input_idx = idx;
631 auto tx = m_ct.tx_data;
632 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionInputViniRequest>();
633 auto & vini = m_ct.tx.vin[idx];
634 translate_src_entry(res->mutable_src_entr(), &(tx.sources[idx]));
636 res->set_vini_hmac(m_ct.tx_in_hmacs[idx]);
637
638 if (client_version() == 0) {
639 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.pseudo_outs.size(), "Invalid transaction index");
640 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.pseudo_outs_hmac.size(), "Invalid transaction index");
641 res->set_pseudo_out(m_ct.pseudo_outs[idx]);
642 res->set_pseudo_out_hmac(m_ct.pseudo_outs_hmac[idx]);
643 }
644
645 return res;
646 }
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
Here is the call graph for this function:

◆ step_set_vini_input_ack()

void hw::trezor::protocol::tx::Signer::step_set_vini_input_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputViniAck > ack)

Definition at line 648 of file protocol.cpp.

648 {
649
650 }

◆ step_sign_input()

std::shared_ptr< messages::Electroneum::ElectroneumTransactionSignInputRequest > hw::trezor::protocol::tx::Signer::step_sign_input ( size_t idx)

Definition at line 907 of file protocol.cpp.

907 {
908 m_ct.cur_input_idx = idx;
909
910 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_data.sources.size(), "Invalid transaction index");
911 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx.vin.size(), "Invalid transaction index");
912 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_in_hmacs.size(), "Invalid transaction index");
913 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.alphas.size(), "Invalid transaction index");
914 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.spend_encs.size(), "Invalid transaction index");
915
916 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSignInputRequest>();
917 translate_src_entry(res->mutable_src_entr(), &(m_ct.tx_data.sources[idx]));
918 res->set_vini(cryptonote::t_serializable_object_to_blob(m_ct.tx.vin[idx]));
919 res->set_vini_hmac(m_ct.tx_in_hmacs[idx]);
920 res->set_pseudo_out_alpha(m_ct.alphas[idx]);
921 res->set_spend_key(m_ct.spend_encs[idx]);
922
923 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.pseudo_outs.size(), "Invalid transaction index");
924 CHECK_AND_ASSERT_THROW_MES(idx < m_ct.pseudo_outs_hmac.size(), "Invalid transaction index");
925 res->set_pseudo_out(m_ct.pseudo_outs[idx]);
926 res->set_pseudo_out_hmac(m_ct.pseudo_outs_hmac[idx]);
927 return res;
928 }
Here is the call graph for this function:

◆ step_sign_input_ack()

void hw::trezor::protocol::tx::Signer::step_sign_input_ack ( std::shared_ptr< const messages::electroneum::ElectroneumTransactionSignInputAck > ack)

Definition at line 930 of file protocol.cpp.

930 {
931 rct::mgSig mg;
932 if (!cn_deserialize(ack->signature(), mg)){
933 throw exc::ProtocolException("Cannot deserialize mg[i]");
934 }
935
936 // Sync updated pseudo_outputs, client_version>=1, HF10+
937 if (client_version() >= 1 && ack->has_pseudo_out()){
938 CHECK_AND_ASSERT_THROW_MES(m_ct.cur_input_idx < m_ct.pseudo_outs.size(), "Invalid pseudo-out index");
939 m_ct.pseudo_outs[m_ct.cur_input_idx] = ack->pseudo_out();
940 if (is_bulletproof()){
941 CHECK_AND_ASSERT_THROW_MES(m_ct.cur_input_idx < m_ct.rv->p.pseudoOuts.size(), "Invalid pseudo-out index");
942 string_to_key(m_ct.rv->p.pseudoOuts[m_ct.cur_input_idx], ack->pseudo_out());
943 } else {
944 CHECK_AND_ASSERT_THROW_MES(m_ct.cur_input_idx < m_ct.rv->pseudoOuts.size(), "Invalid pseudo-out index");
945 string_to_key(m_ct.rv->pseudoOuts[m_ct.cur_input_idx], ack->pseudo_out());
946 }
947 }
948
949 m_ct.rv->p.MGs.push_back(mg);
950 }
Here is the call graph for this function:

◆ store_tx_aux_info()

std::string hw::trezor::protocol::tx::Signer::store_tx_aux_info ( )

Definition at line 978 of file protocol.cpp.

978 {
979 rapidjson::StringBuffer sb;
980 rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
981
982 rapidjson::Document json;
983 json.SetObject();
984
985 rapidjson::Value valueS(rapidjson::kStringType);
986 rapidjson::Value valueI(rapidjson::kNumberType);
987
988 valueI.SetInt(1);
989 json.AddMember("version", valueI, json.GetAllocator());
990
991 valueS.SetString(m_ct.enc_salt1.c_str(), m_ct.enc_salt1.size());
992 json.AddMember("salt1", valueS, json.GetAllocator());
993
994 valueS.SetString(m_ct.enc_salt2.c_str(), m_ct.enc_salt2.size());
995 json.AddMember("salt2", valueS, json.GetAllocator());
996
997 valueS.SetString(m_ct.tx_prefix_hash.c_str(), m_ct.tx_prefix_hash.size());
998 json.AddMember("tx_prefix_hash", valueS, json.GetAllocator());
999
1000 valueS.SetString(m_ct.enc_keys.c_str(), m_ct.enc_keys.size());
1001 json.AddMember("enc_keys", valueS, json.GetAllocator());
1002
1003 json.Accept(writer);
1004 return sb.GetString();
1005 }
rapidjson::Document json
Definition transport.hpp:59

◆ tdata()

const TData & hw::trezor::protocol::tx::Signer::tdata ( ) const
inline

Definition at line 307 of file protocol.hpp.

307 {
308 return m_ct;
309 }

The documentation for this class was generated from the following files:
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/device_trezor/trezor/protocol.hpp
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/device_trezor/trezor/protocol.cpp