31 #include <unordered_map> 34 #include <boost/endian/conversion.hpp> 43 #include <sodium/crypto_aead_chacha20poly1305.h> 45 #define GET_FIELD_STRING(name, type, jtype) field_##name = std::string(json[#name].GetString(), json[#name].GetStringLength()) 46 #define GET_FIELD_OTHER(name, type, jtype) field_##name = static_cast<type>(json[#name].Get##jtype()) 48 #define GET_STRING_FROM_JSON(json, name, type, mandatory, def) \ 49 GET_FIELD_FROM_JSON_EX(json, name, type, String, mandatory, def, GET_FIELD_STRING) 51 #define GET_FIELD_FROM_JSON(json, name, type, jtype, mandatory, def) \ 52 GET_FIELD_FROM_JSON_EX(json, name, type, jtype, mandatory, def, GET_FIELD_OTHER) 54 #define GET_FIELD_FROM_JSON_EX(json, name, type, jtype, mandatory, def, VAL) \ 55 type field_##name = static_cast<type>(def); \ 56 bool field_##name##_found = false; \ 57 (void)field_##name##_found; \ 58 do if (json.HasMember(#name)) \ 60 if (json[#name].Is##jtype()) \ 62 VAL(name, type, jtype); \ 63 field_##name##_found = true; \ 67 throw std::invalid_argument("Field " #name " found in JSON, but not " #jtype); \ 72 throw std::invalid_argument("Field " #name " not found in JSON");\ 97 if (str.size() !=
sizeof(
key.data)){
104 if (str.size() !=
sizeof(
key.data)){
111 if (str.size() !=
sizeof(
key.bytes)){
120 void decrypt(
const void* ciphertext,
size_t length,
const uint8_t*
key,
const uint8_t* iv,
char* plaintext,
size_t *plaintext_len){
124 unsigned long long int res_len = plaintext_len ? *plaintext_len : length;
125 auto r = crypto_aead_chacha20poly1305_ietf_decrypt(
126 reinterpret_cast<unsigned char *>(plaintext), &res_len,
nullptr,
127 static_cast<const unsigned char *>(ciphertext), length,
nullptr, 0, iv,
key);
134 *plaintext_len = (size_t) res_len;
146 const std::vector<tools::wallet2::transfer_details> & transfers,
147 std::vector<ElectroneumTransferDetails> &
res)
149 for(
auto & td : transfers){
154 auto & cres =
res.back();
156 cres.set_out_key(
key_to_string(boost::get<cryptonote::txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key));
158 cres.set_internal_output_index(td.m_internal_output_index);
159 for(
auto & aux : additional_tx_pub_keys){
175 keccak_update(&kck, reinterpret_cast<const uint8_t *>(rr.out_key().data()), 32);
176 keccak_update(&kck, reinterpret_cast<const uint8_t *>(rr.tx_pub_key().data()), 32);
177 for (
const auto &aux : rr.additional_tx_pub_keys()){
179 keccak_update(&kck, reinterpret_cast<const uint8_t *>(aux.data()), 32);
183 keccak_update(&kck, reinterpret_cast<const uint8_t *>(index_serialized.data()), index_serialized.size());
185 return std::string(reinterpret_cast<const char*>(md),
sizeof(md));
189 const std::vector<tools::wallet2::transfer_details> & transfers,
190 std::shared_ptr<messages::Electroneum::ElectroneumKeyImageExportInitRequest> & req)
192 req = std::make_shared<messages::Electroneum::ElectroneumKeyImageExportInitRequest>();
198 for(
auto &cur : mtds){
204 req = std::make_shared<messages::Electroneum::ElectroneumKeyImageExportInitRequest>();
205 req->set_hash(
std::string(reinterpret_cast<const char*>(final_hash), 32));
206 req->set_num(transfers.size());
208 std::unordered_map<uint32_t, std::set<uint32_t>> sub_indices;
209 for (
auto &cur : transfers){
210 auto search = sub_indices.emplace(cur.m_subaddr_index.major, std::set<uint32_t>());
211 auto & st = search.first->second;
212 st.insert(cur.m_subaddr_index.minor);
215 for (
auto& x: sub_indices){
216 auto subs = req->add_subs();
217 subs->set_account(x.first);
218 for(
auto minor : x.second){
219 subs->add_minor_indices(minor);
226 const std::shared_ptr<messages::Electroneum::ElectroneumLiveRefreshStepAck> & ack,
230 std::string str_out_key(out_key.data,
sizeof(out_key.data));
233 const size_t len_ciphertext = ack->key_image().size();
237 std::unique_ptr<uint8_t[]> plaintext(
new uint8_t[ki_len]);
238 uint8_t * buff = plaintext.get();
243 reinterpret_cast<const uint8_t *
>(enc_key.data),
244 reinterpret_cast<const uint8_t *>(ack->key_image().data()),
245 reinterpret_cast<char *>(buff), &ki_len);
249 memcpy(ki.data, buff, 32);
250 memcpy(sig.c.data, buff + 32, 32);
251 memcpy(sig.r.data, buff + 64, 32);
252 in_ephemeral.
pub = out_key;
256 std::vector<const ::crypto::public_key*> pkeys;
257 pkeys.push_back(&out_key);
278 dst->set_amount(src->
amount);
286 for(
auto & cur : src->
outputs){
287 auto out = dst->add_outputs();
288 out->set_idx(cur.first);
299 dst->set_amount(src->
amount);
300 dst->set_rct(src->
rct);
318 return hash_addr(addr->spend_public_key(), addr->view_public_key(), amount, is_subaddr);
323 if (spend_key.size() != 32 || view_key.size() != 32){
324 throw std::invalid_argument(
"Public keys have invalid sizes");
327 memcpy(spend.data, spend_key.data(), 32);
336 memcpy(buff + offset, spend_key->data, 32); offset += 32;
337 memcpy(buff + offset, view_key->data, 32); offset += 32;
340 memcpy(buff + offset, (
uint8_t*) &(amount.get()),
sizeof(amount.get())); offset +=
sizeof(amount.get());
344 buff[offset] = is_subaddr.get();
382 m_unsigned_tx = unsigned_tx;
383 m_aux_data = aux_data;
387 m_client_version = 1;
390 void Signer::extract_payment_id(){
391 const std::vector<uint8_t>& tx_extra = cur_tx().
extra;
394 std::vector<cryptonote::tx_extra_field> tx_extra_fields;
413 static unsigned get_rsig_type(
const rct::RCTConfig &rct_config,
size_t num_outputs){
423 static void generate_rsig_batch_sizes(std::vector<uint64_t> &batches,
unsigned rsig_type,
size_t num_outputs){
424 size_t amount_batched = 0;
426 while(amount_batched < num_outputs){
428 batches.push_back(1);
433 throw std::invalid_argument(
"BP padded can support only BULLETPROOF_MAX_OUTPUTS statements");
435 batches.push_back(num_outputs);
436 amount_batched += num_outputs;
439 size_t batch_size = 1;
443 batch_size = std::min(batch_size, num_outputs - amount_batched);
444 batches.push_back(batch_size);
445 amount_batched += batch_size;
448 throw std::invalid_argument(
"Unknown rsig type");
453 void Signer::compute_integrated_indices(
TsxData * tsx_data){
454 if (m_aux_data ==
nullptr || m_aux_data->
tx_recipients.empty()){
458 auto & chg = tsx_data->change_dts();
461 std::vector<uint32_t> integrated_indices;
462 std::set<std::string> integrated_hashes;
464 if (!cur.has_payment_id){
467 integrated_hashes.emplace(
hash_addr(&cur.address.m_spend_public_key, &cur.address.m_view_public_key));
471 for (
auto & cur : tsx_data->outputs()){
475 if (c_hash == change_hash || cur.is_subaddress()){
480 if (integrated_hashes.find(c_hash) != integrated_hashes.end()){
481 integrated_indices.push_back((
uint32_t)idx);
485 if (!integrated_indices.empty()){
486 assign_to_repeatable(tsx_data->mutable_integrated_indices(), integrated_indices.begin(), integrated_indices.end());
493 auto & tx = cur_tx();
499 tsx_data.set_version(1);
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());
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);
520 for(
auto & cur : tx.splitted_dsts){
521 auto dst = tsx_data.mutable_outputs()->Add();
525 compute_integrated_indices(&tsx_data);
528 for(
auto & cur_in : tx.sources){
529 fee += cur_in.amount;
531 for(
auto & cur_out : tx.splitted_dsts){
532 fee -= cur_out.amount;
535 throw std::invalid_argument(
"Fee cannot be negative");
538 tsx_data.set_fee(static_cast<google::protobuf::uint64>(fee));
539 this->extract_payment_id();
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);
548 if (ack->has_rsig_data()){
549 m_ct.
rsig_param = std::make_shared<ElectroneumRsigData>(ack->rsig_data());
558 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetInputRequest>();
564 auto & vini_str = ack->vini();
571 m_ct.
tx.
vin.emplace_back(vini);
575 m_ct.
alphas.push_back(ack->pseudo_out_alpha());
580 const size_t input_size = cur_tx().
sources.size();
583 for (
size_t n = 0; n < input_size; ++n){
591 return memcmp(&tk0.
k_image, &tk1.k_image,
sizeof(tk0.
k_image)) > 0;
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]);
615 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionInputsPermutationRequest>();
632 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionInputViniRequest>();
633 auto & vini = m_ct.
tx.
vin[idx];
653 return std::make_shared<messages::Electroneum::ElectroneumTransactionAllInputsSetRequest>();
662 if (!ack->has_rsig_data()){
666 auto & rsig_data = ack->rsig_data();
667 if (!rsig_data.has_mask()){
671 auto & mask = rsig_data.mask();
679 memcpy(cmask.bytes, mask.data() + c * 32, 32);
692 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetOutputRequest>();
701 auto rsig_data =
res->mutable_rsig_data();
702 compute_bproof(*rsig_data);
714 bool has_rsig =
false;
717 if (ack->has_rsig_data()){
718 auto & rsig_data = ack->rsig_data();
720 if (rsig_data.has_rsig() && !rsig_data.rsig().empty()){
722 rsig_buff = rsig_data.rsig();
746 memcpy(ecdh.amount.bytes, ack->ecdh_info().data(), 8);
753 m_ct.
tx.
vout.emplace_back(tx_out);
764 process_bproof(bproof);
769 bool Signer::should_compute_bp_now()
const {
774 void Signer::compute_bproof(messages::Electroneum::ElectroneumTransactionRsigData & rsig_data){
776 std::vector<uint64_t> amounts;
780 for(
size_t i = 0; i < batch_size; ++i){
792 rsig_data.set_rsig(serRsig);
798 for (
size_t i = 0; i < batch_size; ++i){
804 bproof.
V.push_back(commitment);
809 throw exc::ProtocolException(
"Returned range signature is invalid");
813 std::shared_ptr<messages::Electroneum::ElectroneumTransactionSetOutputRequest>
Signer::step_rsig(
size_t idx){
818 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSetOutputRequest>();
823 compute_bproof(*(
res->mutable_rsig_data()));
824 res->set_is_offloaded_bp(
true);
834 return std::make_shared<messages::Electroneum::ElectroneumTransactionAllOutSetRequest>();
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());
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]));
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()))){
863 auto dst = &m_ct.
rv->pseudoOuts;
865 dst = &m_ct.
rv->p.pseudoOuts;
874 m_ct.
rv->mixRing.resize(num_sources);
876 m_ct.
rv->mixRing.resize(m_ct.
tsx_data.mixin());
877 m_ct.
rv->mixRing[0].resize(num_sources);
881 for(
size_t i = 0; i < m_ct.
tx_out_ecdh.size(); ++i){
888 m_ct.
rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.
tx_out_rsigs[i]));
890 m_ct.
rv->p.rangeSigs.push_back(boost::get<rct::rangeSig>(m_ct.
tx_out_rsigs[i]));
895 auto &
hash = ack->full_message_hash();
897 if (
hash.size() != 32){
902 reinterpret_cast<const unsigned char *>(
hash.data()))){
916 auto res = std::make_shared<messages::Electroneum::ElectroneumTransactionSignInputRequest>();
920 res->set_pseudo_out_alpha(m_ct.
alphas[idx]);
949 m_ct.
rv->p.MGs.push_back(mg);
954 return std::make_shared<messages::Electroneum::ElectroneumTransactionFinalRequest>();
959 auto & cout_key = ack->cout_key();
960 for(
auto & cur : m_ct.
couts){
962 throw std::invalid_argument(
"Encrypted cout has invalid length");
966 auto data = cur.data();
980 rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
989 json.AddMember(
"version", valueI,
json.GetAllocator());
992 json.AddMember(
"salt1", valueS,
json.GetAllocator());
995 json.AddMember(
"salt2", valueS,
json.GetAllocator());
998 json.AddMember(
"tx_prefix_hash", valueS,
json.GetAllocator());
1001 json.AddMember(
"enc_keys", valueS,
json.GetAllocator());
1003 json.Accept(writer);
1004 return sb.GetString();
1012 if (
json.Parse(data.c_str()).HasParseError())
1014 throw std::invalid_argument(
"Data parsing error");
1016 else if(!
json.IsObject())
1018 throw std::invalid_argument(
"Data parsing error - not an object");
1027 if (field_version != 1)
1029 throw std::invalid_argument(
"Unknown version");
1032 res.salt1 = field_salt1;
1033 res.salt2 = field_salt2;
1034 res.tx_enc_keys = field_enc_keys;
1035 res.tx_prefix_hash = field_tx_prefix_hash;
1038 std::shared_ptr<messages::Electroneum::ElectroneumGetTxKeyRequest>
get_tx_key(
1041 auto req = std::make_shared<messages::Electroneum::ElectroneumGetTxKeyRequest>();
1042 req->set_salt1(tx_data.
salt1);
1043 req->set_salt2(tx_data.
salt2);
1052 std::vector<::crypto::secret_key> & tx_keys,
1055 std::shared_ptr<const messages::Electroneum::ElectroneumGetTxKeyAck> ack
1059 auto & encrypted_keys = ack->has_tx_derivations() ? ack->tx_derivations() : ack->tx_keys();
1061 const size_t len_ciphertext = encrypted_keys.size();
1065 std::unique_ptr<uint8_t[]> plaintext(
new uint8_t[keys_len]);
1070 reinterpret_cast<const uint8_t *
>(enc_key.data),
1071 reinterpret_cast<const uint8_t *>(encrypted_keys.data()),
1072 reinterpret_cast<char *>(plaintext.get()), &keys_len);
1075 tx_keys.resize(keys_len / 32);
1077 for(
unsigned i = 0; i < keys_len / 32; ++i)
1079 memcpy(tx_keys[i].data, plaintext.get() + 32 * i, 32);
1081 memwipe(plaintext.get(), keys_len);
boost::optional< unsigned > client_version
std::vector< rct::ecdhTuple > tx_out_ecdh
void generate_commitment(std::vector< ElectroneumTransferDetails > &mtds, const std::vector< tools::wallet2::transfer_details > &transfers, std::shared_ptr< messages::Electroneum::ElectroneumKeyImageExportInitRequest > &req)
bool parse_tx_extra(const std::vector< uint8_t > &tx_extra, std::vector< tx_extra_field > &tx_extra_fields)
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
Signer(wallet_shim *wallet2, const unsigned_tx_set *unsigned_tx, size_t tx_idx=0, hw::tx_aux_data *aux_data=nullptr)
messages::electroneum::ElectroneumKeyImageSyncStepRequest_ElectroneumTransferDetails ElectroneumTransferDetails
void step_set_rsig_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)
crypto::public_key real_out_tx_key
int crypto_verify_32(const unsigned char *, const unsigned char *)
boost::function< crypto::public_key(const tools::wallet2::transfer_details &td)> get_tx_pub_key_from_received_outs
std::string store_tx_aux_info()
void step_init_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionInitAck > ack)
void get_tx_key_ack(std::vector<::crypto::secret_key > &tx_keys, const std::string &tx_prefix_hash, const ::crypto::secret_key &view_key_priv, std::shared_ptr< const messages::Electroneum::ElectroneumGetTxKeyAck > ack)
#define GET_FIELD_FROM_JSON(json, name, type, jtype, mandatory, def)
cryptonote::transaction tx
std::vector< std::string > pseudo_outs_hmac
void step_permutation_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputsPermutationAck > ack)
#define GET_STRING_FROM_JSON(json, name, type, mandatory, def)
std::shared_ptr< messages::electroneum::ElectroneumTransactionInputViniRequest > step_set_vini_input(size_t idx)
bool is_bulletproof() const
size_t num_outputs() const
void scalarmultKey(key &aP, const key &P, const key &a)
void string_to_key(::crypto::ec_scalar &key, const std::string &str)
void step_sign_input_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionSignInputAck > ack)
bool bulletproof_VERIFY(const Bulletproof &proof)
key get_pre_mlsag_hash(const rctSig &rv, hw::device &hwdev)
bool cn_deserialize(const void *buff, size_t len, T &dst)
boost::variant< txin_gen, txin_to_script, txin_to_scripthash, txin_to_key, txin_to_key_public > txin_v
std::string cn_serialize(T &obj)
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)
void translate_klrki(ElectroneumMultisigKLRki *dst, const rct::multisig_kLRki *src)
std::shared_ptr< ElectroneumRsigData > rsig_param
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
#define BULLETPROOF_MAX_OUTPUTS
bool find_tx_extra_field_by_type(const std::vector< tx_extra_field > &tx_extra_fields, T &field, size_t index=0)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSignInputRequest > step_sign_input(size_t idx)
std::string tx_prefix_hash
void step_all_outs_set_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllOutSetAck > ack, hw::device &hwdev)
void keccak_finish(KECCAK_CTX *ctx, uint8_t *md)
std::vector< std::string > tx_out_entr_hmacs
bool is_offloading() const
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetOutputRequest > step_set_output(size_t idx)
std::shared_ptr< messages::Electroneum::ElectroneumGetTxKeyRequest > get_tx_key(const hw::device_cold::tx_key_data_t &tx_data)
unsigned client_version() const
void translate_src_entry(ElectroneumTransactionSourceEntry *dst, const cryptonote::tx_source_entry *src)
void step_final_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionFinalAck > ack)
void translate_address(ElectroneumAccountPublicAddress *dst, const cryptonote::account_public_address *src)
std::shared_ptr< messages::electroneum::ElectroneumTransactionAllOutSetRequest > step_all_outs_set()
std::vector< uint8_t > extra
void assign_to_repeatable(::google::protobuf::RepeatedField< sub_t > *dst, const InputIterator begin, const InputIterator end)
std::vector< std::string > tx_in_hmacs
void step_set_vini_input_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionInputViniAck > ack)
std::string compute_hash(const ElectroneumTransferDetails &rr)
std::vector< std::string > spend_encs
std::vector< tx_out > vout
std::vector< std::string > couts
void translate_dst_entry(ElectroneumTransactionDestinationEntry *dst, const cryptonote::tx_destination_entry *src)
const crypto::secret_key null_skey
void translate_rct_key(ElectroneumRctKey *dst, const rct::ctkey *src)
messages::electroneum::ElectroneumTransactionSourceEntry_ElectroneumOutputEntry_ElectroneumRctKeyPublic ElectroneumRctKey
messages::electroneum::ElectroneumTransactionSourceEntry_ElectroneumMultisigKLRki ElectroneumMultisigKLRki
void load_tx_key_data(hw::device_cold::tx_key_data_t &res, const std::string &data)
std::vector< txin_v > vin
crypto::public_key m_spend_public_key
size_t cur_output_in_batch_idx
void step_set_input_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetInputAck > ack)
bool is_req_bulletproof() const
crypto::public_key m_view_public_key
std::shared_ptr< messages::electroneum::ElectroneumTransactionFinalRequest > step_final()
GenericValue< UTF8<> > Value
GenericValue with UTF8 encoding.
rct::rctSig rct_signatures
std::vector< rct::ctkey > tx_out_pk
::crypto::secret_key compute_enc_key(const ::crypto::secret_key &private_view_key, const std::string &aux, const std::string &salt)
std::vector< size_t > source_permutation
std::vector< uint64_t > grouping_vct
GenericDocument< UTF8<> > Document
GenericDocument with UTF8 encoding.
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
void keccak_init(KECCAK_CTX *ctx)
bool get_payment_id_from_tx_extra_nonce(const blobdata &extra_nonce, crypto::hash &payment_id)
std::string tx_prefix_hash
GenericStringBuffer< UTF8< char >, CrtAllocator > StringBuffer
std::vector< std::string > couts_dec
std::vector< std::string > alphas
version
Supported socks variants.
bool get_encrypted_payment_id_from_tx_extra_nonce(const blobdata &extra_nonce, crypto::hash8 &payment_id)
rct::multisig_kLRki multisig_kLRki
messages::electroneum::ElectroneumTransactionDestinationEntry_ElectroneumAccountPublicAddress ElectroneumAccountPublicAddress
std::vector< rct::key > rsig_gamma
std::shared_ptr< messages::electroneum::ElectroneumTransactionInitRequest > step_init()
account_public_address addr
messages::electroneum::ElectroneumTransactionInitRequest_ElectroneumTransactionData TsxData
void decrypt(const void *ciphertext, size_t length, const uint8_t *key, const uint8_t *iv, char *plaintext, size_t *plaintext_len)
std::shared_ptr< messages::electroneum::ElectroneumTransactionInputsPermutationRequest > step_permutation()
void get_transaction_prefix_hash(const transaction_prefix &tx, crypto::hash &h)
std::shared_ptr< messages::electroneum::ElectroneumTransactionAllInputsSetRequest > step_all_inputs_set()
std::vector< crypto::public_key > real_out_additional_tx_keys
void live_refresh_ack(const ::crypto::secret_key &view_key_priv, const ::crypto::public_key &out_key, const std::shared_ptr< messages::Electroneum::ElectroneumLiveRefreshStepAck > &ack, ::cryptonote::keypair &in_ephemeral, ::crypto::key_image &ki)
void * memcpy(void *a, const void *b, size_t c)
size_t real_output_in_tx_index
crypto::key_image k_image
void step_set_output_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionSetOutputAck > ack)
void keccak_update(KECCAK_CTX *ctx, const uint8_t *in, size_t inlen)
std::vector< output_entry > outputs
void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen)
void assign_from_repeatable(std::vector< sub_t > *dst, const InputIterator begin, const InputIterator end)
RangeProofType range_proof_type
boost::optional< int > bp_version
messages::electroneum::ElectroneumTransactionSourceEntry ElectroneumTransactionSourceEntry
bool key_image_data(wallet_shim *wallet, const std::vector< tools::wallet2::transfer_details > &transfers, std::vector< ElectroneumTransferDetails > &res)
std::vector< cryptonote::address_parse_info > tx_recipients
std::string to_string(t_connection_type type)
messages::electroneum::ElectroneumTransactionDestinationEntry ElectroneumTransactionDestinationEntry
std::string hash_addr(const ElectroneumAccountPublicAddress *addr, boost::optional< uint64_t > amount, boost::optional< bool > is_subaddr)
std::vector< crypto::public_key > get_additional_tx_pub_keys_from_extra(const std::vector< uint8_t > &tx_extra)
void * memwipe(void *src, size_t n)
std::shared_ptr< rct::rctSig > rv
std::vector< std::string > tx_out_hmacs
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetInputRequest > step_set_input(size_t idx)
std::string key_to_string(const ::crypto::ec_point &key)
std::shared_ptr< messages::electroneum::ElectroneumTransactionSetOutputRequest > step_rsig(size_t idx)
tx_construction_data tx_data
std::vector< rsig_v > tx_out_rsigs
void hmac_keccak_hash(uint8_t *out, const uint8_t *key, size_t keylen, const uint8_t *in, size_t inlen)
void step_all_inputs_set_ack(std::shared_ptr< const messages::electroneum::ElectroneumTransactionAllInputsSetAck > ack)
Bulletproof bulletproof_PROVE(const rct::key &v, const rct::key &gamma)
std::vector< std::string > pseudo_outs