Electroneum
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  }
tx_construction_data tx_data
Definition: protocol.hpp:177

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  }
std::shared_ptr< rct::rctSig > rv
Definition: protocol.hpp:207
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  }
std::shared_ptr< ElectroneumRsigData > rsig_param
Definition: protocol.hpp:182
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  {
285  }
RangeProofType range_proof_type
Definition: rctTypes.h:237
tx_construction_data tx_data
Definition: protocol.hpp:177
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  }
std::shared_ptr< rct::rctSig > rv
Definition: protocol.hpp:207
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  }
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
tx_construction_data tx_data
Definition: protocol.hpp:177

◆ 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  }
std::vector< cryptonote::tx_destination_entry > splitted_dsts
Definition: wallet2.h:424
tx_construction_data tx_data
Definition: protocol.hpp:177
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)
Definition: misc_log_ex.h:173
void apply_permutation(std::vector< size_t > permutation, const F &swap)
cryptonote::transaction tx
Definition: protocol.hpp:178
std::vector< std::string > pseudo_outs_hmac
Definition: protocol.hpp:198
std::vector< std::string > tx_in_hmacs
Definition: protocol.hpp:188
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
std::vector< std::string > spend_encs
Definition: protocol.hpp:196
std::vector< size_t > source_permutation
Definition: protocol.hpp:194
std::vector< std::string > alphas
Definition: protocol.hpp:195
crypto::key_image k_image
tx_construction_data tx_data
Definition: protocol.hpp:177
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  }
unsigned client_version() const
Definition: protocol.hpp:271
std::vector< rct::key > rsig_gamma
Definition: protocol.hpp:201
void * memcpy(void *a, const void *b, size_t c)
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  }
std::vector< rct::ecdhTuple > tx_out_ecdh
Definition: protocol.hpp:193
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
int crypto_verify_32(const unsigned char *, const unsigned char *)
cryptonote::transaction tx
Definition: protocol.hpp:178
void string_to_key(::crypto::ec_scalar &key, const std::string &str)
Definition: protocol.cpp:96
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev)
Definition: rctSigs.cpp:403
unsigned char uint8_t
Definition: stdint.h:124
std::vector< uint8_t > extra
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
std::vector< rct::ctkey > tx_out_pk
Definition: protocol.hpp:192
void get_transaction_prefix_hash(const transaction_prefix &tx, crypto::hash &h)
unsigned char bytes[32]
Definition: rctTypes.h:86
POD_CLASS hash
Definition: hash.h:50
std::shared_ptr< rct::rctSig > rv
Definition: protocol.hpp:207
std::string key_to_string(const ::crypto::ec_point &key)
Definition: protocol.cpp:80
tx_construction_data tx_data
Definition: protocol.hpp:177
std::vector< rsig_v > tx_out_rsigs
Definition: protocol.hpp:191
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  }
cryptonote::transaction tx
Definition: protocol.hpp:178
std::shared_ptr< rct::rctSig > rv
Definition: protocol.hpp:207

◆ 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  }
std::vector< std::string > couts
Definition: protocol.hpp:199
std::vector< std::string > couts_dec
Definition: protocol.hpp:200
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  }
boost::optional< unsigned > client_version
Definition: device_cold.hpp:49
cryptonote::transaction tx
Definition: protocol.hpp:178
unsigned client_version() const
Definition: protocol.hpp:271
void assign_to_repeatable(::google::protobuf::RepeatedField< sub_t > *dst, const InputIterator begin, const InputIterator end)
Definition: protocol.hpp:53
void translate_dst_entry(ElectroneumTransactionDestinationEntry *dst, const cryptonote::tx_destination_entry *src)
Definition: protocol.cpp:277
unsigned int uint32_t
Definition: stdint.h:126
std::vector< uint64_t > grouping_vct
Definition: protocol.hpp:181
signed __int64 int64_t
Definition: stdint.h:135
boost::optional< int > bp_version
Definition: device_cold.hpp:48
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  }
std::shared_ptr< ElectroneumRsigData > rsig_param
Definition: protocol.hpp:182
std::vector< std::string > tx_out_entr_hmacs
Definition: protocol.hpp:189
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
Definition: hmac_keccak.cpp:41
void assign_to_repeatable(::google::protobuf::RepeatedField< sub_t > *dst, const InputIterator begin, const InputIterator end)
Definition: protocol.hpp:53
std::vector< size_t > source_permutation
Definition: protocol.hpp:194
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  }
const char * res
Definition: hmac_keccak.cpp:41
std::vector< std::string > tx_out_entr_hmacs
Definition: protocol.hpp:189
unsigned client_version() const
Definition: protocol.hpp:271
void translate_dst_entry(ElectroneumTransactionDestinationEntry *dst, const cryptonote::tx_destination_entry *src)
Definition: protocol.cpp:277
std::vector< cryptonote::tx_destination_entry > splitted_dsts
Definition: wallet2.h:424
tx_construction_data tx_data
Definition: protocol.hpp:177
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  }
const char * res
Definition: hmac_keccak.cpp:41
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
void translate_src_entry(ElectroneumTransactionSourceEntry *dst, const cryptonote::tx_source_entry *src)
Definition: protocol.cpp:285
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
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 
566  cryptonote::txin_v vini;
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  }
cryptonote::transaction tx
Definition: protocol.hpp:178
std::vector< std::string > pseudo_outs_hmac
Definition: protocol.hpp:198
bool cn_deserialize(const void *buff, size_t len, T &dst)
Definition: protocol.hpp:68
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_to_key_public > txin_v
std::vector< std::string > tx_in_hmacs
Definition: protocol.hpp:188
std::vector< std::string > spend_encs
Definition: protocol.hpp:196
std::vector< std::string > alphas
Definition: protocol.hpp:195
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  }
const char * res
Definition: hmac_keccak.cpp:41
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
std::vector< std::string > tx_out_entr_hmacs
Definition: protocol.hpp:189
unsigned client_version() const
Definition: protocol.hpp:271
void translate_dst_entry(ElectroneumTransactionDestinationEntry *dst, const cryptonote::tx_destination_entry *src)
Definition: protocol.cpp:277
std::vector< cryptonote::tx_destination_entry > splitted_dsts
Definition: wallet2.h:424
tx_construction_data tx_data
Definition: protocol.hpp:177
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  }
std::vector< rct::ecdhTuple > tx_out_ecdh
Definition: protocol.hpp:193
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
cryptonote::transaction tx
Definition: protocol.hpp:178
::std::string string
Definition: gtest-port.h:1097
void string_to_key(::crypto::ec_scalar &key, const std::string &str)
Definition: protocol.cpp:96
bool cn_deserialize(const void *buff, size_t len, T &dst)
Definition: protocol.hpp:68
unsigned client_version() const
Definition: protocol.hpp:271
std::vector< rct::ctkey > tx_out_pk
Definition: protocol.hpp:192
std::vector< rct::key > rsig_gamma
Definition: protocol.hpp:201
void * memcpy(void *a, const void *b, size_t c)
std::vector< std::string > tx_out_hmacs
Definition: protocol.hpp:190
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  }
const char * res
Definition: hmac_keccak.cpp:41
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
cryptonote::transaction tx
Definition: protocol.hpp:178
std::vector< std::string > pseudo_outs_hmac
Definition: protocol.hpp:198
unsigned client_version() const
Definition: protocol.hpp:271
void translate_src_entry(ElectroneumTransactionSourceEntry *dst, const cryptonote::tx_source_entry *src)
Definition: protocol.cpp:285
std::vector< std::string > tx_in_hmacs
Definition: protocol.hpp:188
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
tx_construction_data tx_data
Definition: protocol.hpp:177
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  }
const char * res
Definition: hmac_keccak.cpp:41
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
cryptonote::transaction tx
Definition: protocol.hpp:178
std::vector< std::string > pseudo_outs_hmac
Definition: protocol.hpp:198
void translate_src_entry(ElectroneumTransactionSourceEntry *dst, const cryptonote::tx_source_entry *src)
Definition: protocol.cpp:285
std::vector< std::string > tx_in_hmacs
Definition: protocol.hpp:188
std::vector< cryptonote::tx_source_entry > sources
Definition: wallet2.h:422
std::vector< std::string > spend_encs
Definition: protocol.hpp:196
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
std::vector< std::string > alphas
Definition: protocol.hpp:195
tx_construction_data tx_data
Definition: protocol.hpp:177
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  }
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Definition: misc_log_ex.h:173
void string_to_key(::crypto::ec_scalar &key, const std::string &str)
Definition: protocol.cpp:96
bool cn_deserialize(const void *buff, size_t len, T &dst)
Definition: protocol.hpp:68
unsigned client_version() const
Definition: protocol.hpp:271
std::shared_ptr< rct::rctSig > rv
Definition: protocol.hpp:207
std::vector< std::string > pseudo_outs
Definition: protocol.hpp:197
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  {
980  rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
981 
983  json.SetObject();
984 
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
string
Definition: rapidjson.h:626
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
Definition: document.h:2116
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
Definition: document.h:2512
number
Definition: rapidjson.h:627
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
Definition: fwd.h:59
rapidjson::Document json
Definition: transport.cpp:49

◆ 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: