mirror of
https://github.com/monero-project/monero.git
synced 2025-08-09 16:22:23 -04:00
Merge pull request #8299
a0df140
feat(trezor): add HF15 support, BP+ (Dusan Klinec)
This commit is contained in:
commit
080fc69435
6 changed files with 232 additions and 181 deletions
|
@ -324,8 +324,8 @@ namespace trezor {
|
|||
|
||||
std::vector<protocol::ki::MoneroTransferDetails> mtds;
|
||||
std::vector<protocol::ki::MoneroExportedKeyImage> kis;
|
||||
protocol::ki::key_image_data(wallet, transfers, mtds, client_version() <= 1);
|
||||
protocol::ki::generate_commitment(mtds, transfers, req, client_version() <= 1);
|
||||
protocol::ki::key_image_data(wallet, transfers, mtds);
|
||||
protocol::ki::generate_commitment(mtds, transfers, req);
|
||||
|
||||
EVENT_PROGRESS(0.);
|
||||
this->set_msg_addr<messages::monero::MoneroKeyImageExportInitRequest>(req.get());
|
||||
|
@ -635,11 +635,7 @@ namespace trezor {
|
|||
}
|
||||
|
||||
// Step: sort
|
||||
auto perm_req = signer->step_permutation();
|
||||
if (perm_req){
|
||||
auto perm_ack = this->client_exchange<messages::monero::MoneroTransactionInputsPermutationAck>(perm_req);
|
||||
signer->step_permutation_ack(perm_ack);
|
||||
}
|
||||
signer->sort_ki();
|
||||
EVENT_PROGRESS(3, 1, 1);
|
||||
|
||||
// Step: input_vini
|
||||
|
@ -697,13 +693,13 @@ namespace trezor {
|
|||
unsigned device_trezor::client_version()
|
||||
{
|
||||
auto trezor_version = get_version();
|
||||
if (trezor_version <= pack_version(2, 0, 10)){
|
||||
throw exc::TrezorException("Trezor firmware 2.0.10 and lower are not supported. Please update.");
|
||||
if (trezor_version < pack_version(2, 4, 3)){
|
||||
throw exc::TrezorException("Minimal Trezor firmware version is 2.4.3. Please update.");
|
||||
}
|
||||
|
||||
unsigned client_version = 1;
|
||||
if (trezor_version >= pack_version(2, 3, 1)){
|
||||
client_version = 3;
|
||||
unsigned client_version = 3;
|
||||
if (trezor_version >= pack_version(2, 5, 2)){
|
||||
client_version = 4;
|
||||
}
|
||||
|
||||
#ifdef WITH_TREZOR_DEBUGGING
|
||||
|
@ -739,14 +735,6 @@ namespace trezor {
|
|||
CHECK_AND_ASSERT_THROW_MES(init_msg, "TransactionInitRequest is empty");
|
||||
CHECK_AND_ASSERT_THROW_MES(init_msg->has_tsx_data(), "TransactionInitRequest has no transaction data");
|
||||
CHECK_AND_ASSERT_THROW_MES(m_features, "Device state not initialized"); // make sure the caller did not reset features
|
||||
const bool nonce_required = init_msg->tsx_data().has_payment_id() && init_msg->tsx_data().payment_id().size() > 0;
|
||||
|
||||
if (nonce_required && init_msg->tsx_data().payment_id().size() == 8){
|
||||
// Versions 2.0.9 and lower do not support payment ID
|
||||
if (get_version() <= pack_version(2, 0, 9)) {
|
||||
throw exc::TrezorException("Trezor firmware 2.0.9 and lower does not support transactions with short payment IDs or integrated addresses. Please update.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void device_trezor::transaction_check(const protocol::tx::TData & tdata, const hw::tx_aux_data & aux_data)
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <crypto/hmac-keccak.h>
|
||||
#include <ringct/rctSigs.h>
|
||||
#include <ringct/bulletproofs.h>
|
||||
#include <ringct/bulletproofs_plus.h>
|
||||
#include "cryptonote_config.h"
|
||||
#include <sodium.h>
|
||||
#include <sodium/crypto_verify_32.h>
|
||||
|
@ -145,8 +146,7 @@ namespace ki {
|
|||
|
||||
bool key_image_data(wallet_shim * wallet,
|
||||
const std::vector<tools::wallet2::transfer_details> & transfers,
|
||||
std::vector<MoneroTransferDetails> & res,
|
||||
bool need_all_additionals)
|
||||
std::vector<MoneroTransferDetails> & res)
|
||||
{
|
||||
for(auto & td : transfers){
|
||||
::crypto::public_key tx_pub_key = wallet->get_tx_pub_key_from_received_outs(td);
|
||||
|
@ -159,11 +159,7 @@ namespace ki {
|
|||
cres.set_internal_output_index(td.m_internal_output_index);
|
||||
cres.set_sub_addr_major(td.m_subaddr_index.major);
|
||||
cres.set_sub_addr_minor(td.m_subaddr_index.minor);
|
||||
if (need_all_additionals) {
|
||||
for (auto &aux : additional_tx_pub_keys) {
|
||||
cres.add_additional_tx_pub_keys(key_to_string(aux));
|
||||
}
|
||||
} else if (!additional_tx_pub_keys.empty() && additional_tx_pub_keys.size() > td.m_internal_output_index) {
|
||||
if (!additional_tx_pub_keys.empty() && additional_tx_pub_keys.size() > td.m_internal_output_index) {
|
||||
cres.add_additional_tx_pub_keys(key_to_string(additional_tx_pub_keys[td.m_internal_output_index]));
|
||||
}
|
||||
}
|
||||
|
@ -194,8 +190,7 @@ namespace ki {
|
|||
|
||||
void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
|
||||
const std::vector<tools::wallet2::transfer_details> & transfers,
|
||||
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
|
||||
bool need_subaddr_indices)
|
||||
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req)
|
||||
{
|
||||
req = std::make_shared<messages::monero::MoneroKeyImageExportInitRequest>();
|
||||
|
||||
|
@ -219,16 +214,6 @@ namespace ki {
|
|||
auto & st = search.first->second;
|
||||
st.insert(cur.m_subaddr_index.minor);
|
||||
}
|
||||
|
||||
if (need_subaddr_indices) {
|
||||
for (auto &x: sub_indices) {
|
||||
auto subs = req->add_subs();
|
||||
subs->set_account(x.first);
|
||||
for (auto minor : x.second) {
|
||||
subs->add_minor_indices(minor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void live_refresh_ack(const ::crypto::secret_key & view_key_priv,
|
||||
|
@ -399,7 +384,7 @@ namespace tx {
|
|||
m_tx_idx = tx_idx;
|
||||
m_ct.tx_data = cur_src_tx();
|
||||
m_multisig = false;
|
||||
m_client_version = 1;
|
||||
m_client_version = 3;
|
||||
}
|
||||
|
||||
void Signer::extract_payment_id(){
|
||||
|
@ -474,25 +459,19 @@ namespace tx {
|
|||
auto & cur = src.outputs[i];
|
||||
auto out = dst->add_outputs();
|
||||
|
||||
if (i == src.real_output || need_ring_indices || client_version() <= 1) {
|
||||
if (i == src.real_output || need_ring_indices) {
|
||||
out->set_idx(cur.first);
|
||||
}
|
||||
if (i == src.real_output || need_ring_keys || client_version() <= 1) {
|
||||
if (i == src.real_output || need_ring_keys) {
|
||||
translate_rct_key(out->mutable_key(), &(cur.second));
|
||||
}
|
||||
}
|
||||
|
||||
dst->set_real_out_tx_key(key_to_string(src.real_out_tx_key));
|
||||
dst->set_real_output_in_tx_index(src.real_output_in_tx_index);
|
||||
|
||||
if (client_version() <= 1) {
|
||||
for (auto &cur : src.real_out_additional_tx_keys) {
|
||||
dst->add_real_out_additional_tx_keys(key_to_string(cur));
|
||||
}
|
||||
} else if (!src.real_out_additional_tx_keys.empty()) {
|
||||
if (!src.real_out_additional_tx_keys.empty()) {
|
||||
dst->add_real_out_additional_tx_keys(key_to_string(src.real_out_additional_tx_keys.at(src.real_output_in_tx_index)));
|
||||
}
|
||||
|
||||
dst->set_amount(src.amount);
|
||||
dst->set_rct(src.rct);
|
||||
dst->set_mask(key_to_string(src.mask));
|
||||
|
@ -532,7 +511,7 @@ namespace tx {
|
|||
|
||||
m_ct.tx.version = 2;
|
||||
m_ct.tx.unlock_time = tx.unlock_time;
|
||||
m_client_version = (m_aux_data->client_version ? m_aux_data->client_version.get() : 1);
|
||||
m_client_version = (m_aux_data->client_version ? m_aux_data->client_version.get() : 3);
|
||||
|
||||
tsx_data.set_version(1);
|
||||
tsx_data.set_client_version(client_version());
|
||||
|
@ -543,18 +522,13 @@ namespace tx {
|
|||
tsx_data.set_monero_version(std::string(MONERO_VERSION) + "|" + MONERO_VERSION_TAG);
|
||||
tsx_data.set_hard_fork(m_aux_data->hard_fork ? m_aux_data->hard_fork.get() : 0);
|
||||
|
||||
if (client_version() <= 1){
|
||||
assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
|
||||
}
|
||||
|
||||
// Rsig decision
|
||||
auto rsig_data = tsx_data.mutable_rsig_data();
|
||||
m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size());
|
||||
rsig_data->set_rsig_type(m_ct.rsig_type);
|
||||
if (tx.rct_config.range_proof_type != rct::RangeProofBorromean){
|
||||
m_ct.bp_version = (m_aux_data->bp_version ? m_aux_data->bp_version.get() : 1);
|
||||
rsig_data->set_bp_version((uint32_t) m_ct.bp_version);
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(tx.rct_config.range_proof_type != rct::RangeProofBorromean, "Borromean rsig not supported");
|
||||
m_ct.bp_version = (m_aux_data->bp_version ? m_aux_data->bp_version.get() : 1);
|
||||
rsig_data->set_bp_version((uint32_t) m_ct.bp_version);
|
||||
|
||||
generate_rsig_batch_sizes(m_ct.grouping_vct, m_ct.rsig_type, tx.splitted_dsts.size());
|
||||
assign_to_repeatable(rsig_data->mutable_grouping(), m_ct.grouping_vct.begin(), m_ct.grouping_vct.end());
|
||||
|
@ -652,22 +626,6 @@ namespace tx {
|
|||
});
|
||||
}
|
||||
|
||||
std::shared_ptr<messages::monero::MoneroTransactionInputsPermutationRequest> Signer::step_permutation(){
|
||||
sort_ki();
|
||||
if (client_version() >= 2){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto res = std::make_shared<messages::monero::MoneroTransactionInputsPermutationRequest>();
|
||||
assign_to_repeatable(res->mutable_perm(), m_ct.source_permutation.begin(), m_ct.source_permutation.end());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void Signer::step_permutation_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputsPermutationAck> ack){
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<messages::monero::MoneroTransactionInputViniRequest> Signer::step_set_vini_input(size_t idx){
|
||||
CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx_data.sources.size(), "Invalid transaction index");
|
||||
CHECK_AND_ASSERT_THROW_MES(idx < m_ct.tx.vin.size(), "Invalid transaction index");
|
||||
|
@ -711,8 +669,10 @@ namespace tx {
|
|||
}
|
||||
|
||||
void Signer::step_set_output_ack(std::shared_ptr<const messages::monero::MoneroTransactionSetOutputAck> ack){
|
||||
CHECK_AND_ASSERT_THROW_MES(is_req_bulletproof(), "Borromean rsig not supported");
|
||||
cryptonote::tx_out tx_out;
|
||||
rct::Bulletproof bproof{};
|
||||
rct::BulletproofPlus bproof_plus{};
|
||||
rct::ctkey out_pk{};
|
||||
rct::ecdhTuple ecdh{};
|
||||
|
||||
|
@ -727,7 +687,7 @@ namespace tx {
|
|||
rsig_buff = rsig_data.rsig();
|
||||
}
|
||||
|
||||
if (client_version() >= 1 && rsig_data.has_mask()){
|
||||
if (rsig_data.has_mask()){
|
||||
rct::key cmask{};
|
||||
string_to_key(cmask, rsig_data.mask());
|
||||
m_ct.rsig_gamma.emplace_back(cmask);
|
||||
|
@ -751,22 +711,32 @@ namespace tx {
|
|||
memcpy(ecdh.amount.bytes, ack->ecdh_info().data(), 8);
|
||||
}
|
||||
|
||||
if (has_rsig && is_req_bulletproof() && !cn_deserialize(rsig_buff, bproof)){
|
||||
throw exc::ProtocolException("Cannot deserialize bulletproof rangesig");
|
||||
}
|
||||
|
||||
m_ct.tx.vout.emplace_back(tx_out);
|
||||
m_ct.tx_out_hmacs.push_back(ack->vouti_hmac());
|
||||
m_ct.tx_out_pk.emplace_back(out_pk);
|
||||
m_ct.tx_out_ecdh.emplace_back(ecdh);
|
||||
|
||||
// ClientV0, if no rsig was generated on Trezor, do not continue.
|
||||
// ClientV1+ generates BP after all masks in the current batch are generated
|
||||
if (!has_rsig || (client_version() >= 1 && is_offloading())){
|
||||
rsig_v bp_obj{};
|
||||
if (has_rsig) {
|
||||
bool deserialize_success;
|
||||
if (is_req_bulletproof_plus()) {
|
||||
deserialize_success = cn_deserialize(rsig_buff, bproof_plus);
|
||||
bp_obj = bproof_plus;
|
||||
} else {
|
||||
deserialize_success = cn_deserialize(rsig_buff, bproof);
|
||||
bp_obj = bproof;
|
||||
}
|
||||
if (!deserialize_success) {
|
||||
throw exc::ProtocolException("Cannot deserialize bulletproof rangesig");
|
||||
}
|
||||
}
|
||||
|
||||
// Generates BP after all masks in the current batch are generated
|
||||
if (!has_rsig || is_offloading()){
|
||||
return;
|
||||
}
|
||||
|
||||
process_bproof(bproof);
|
||||
process_bproof(bp_obj);
|
||||
m_ct.cur_batch_idx += 1;
|
||||
m_ct.cur_output_in_batch_idx = 0;
|
||||
}
|
||||
|
@ -791,13 +761,21 @@ namespace tx {
|
|||
masks.push_back(m_ct.rsig_gamma[bidx]);
|
||||
}
|
||||
|
||||
auto bp = bulletproof_PROVE(amounts, masks);
|
||||
auto serRsig = cn_serialize(bp);
|
||||
m_ct.tx_out_rsigs.emplace_back(bp);
|
||||
std::string serRsig;
|
||||
if (is_req_bulletproof_plus()) {
|
||||
auto bp = bulletproof_plus_PROVE(amounts, masks);
|
||||
serRsig = cn_serialize(bp);
|
||||
m_ct.tx_out_rsigs.emplace_back(bp);
|
||||
} else {
|
||||
auto bp = bulletproof_PROVE(amounts, masks);
|
||||
serRsig = cn_serialize(bp);
|
||||
m_ct.tx_out_rsigs.emplace_back(bp);
|
||||
}
|
||||
|
||||
rsig_data.set_rsig(serRsig);
|
||||
}
|
||||
|
||||
void Signer::process_bproof(rct::Bulletproof & bproof){
|
||||
void Signer::process_bproof(rsig_v & bproof){
|
||||
CHECK_AND_ASSERT_THROW_MES(m_ct.cur_batch_idx < m_ct.grouping_vct.size(), "Invalid batch index");
|
||||
auto batch_size = m_ct.grouping_vct[m_ct.cur_batch_idx];
|
||||
for (size_t i = 0; i < batch_size; ++i){
|
||||
|
@ -806,12 +784,22 @@ namespace tx {
|
|||
|
||||
rct::key commitment = m_ct.tx_out_pk[bidx].mask;
|
||||
commitment = rct::scalarmultKey(commitment, rct::INV_EIGHT);
|
||||
bproof.V.push_back(commitment);
|
||||
if (is_req_bulletproof_plus()) {
|
||||
boost::get<rct::BulletproofPlus>(bproof).V.push_back(commitment);
|
||||
} else {
|
||||
boost::get<rct::Bulletproof>(bproof).V.push_back(commitment);
|
||||
}
|
||||
}
|
||||
|
||||
m_ct.tx_out_rsigs.emplace_back(bproof);
|
||||
if (!rct::bulletproof_VERIFY(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs.back()))) {
|
||||
throw exc::ProtocolException("Returned range signature is invalid");
|
||||
if (is_req_bulletproof_plus()) {
|
||||
if (!rct::bulletproof_plus_VERIFY(boost::get<rct::BulletproofPlus>(m_ct.tx_out_rsigs.back()))) {
|
||||
throw exc::ProtocolException("Returned range signature is invalid");
|
||||
}
|
||||
} else {
|
||||
if (!rct::bulletproof_VERIFY(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs.back()))) {
|
||||
throw exc::ProtocolException("Returned range signature is invalid");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -840,6 +828,7 @@ namespace tx {
|
|||
}
|
||||
|
||||
void Signer::step_all_outs_set_ack(std::shared_ptr<const messages::monero::MoneroTransactionAllOutSetAck> ack, hw::device &hwdev){
|
||||
CHECK_AND_ASSERT_THROW_MES(is_req_bulletproof(), "Borromean rsig not supported");
|
||||
m_ct.rv = std::make_shared<rct::rctSig>();
|
||||
m_ct.rv->txnFee = ack->rv().txn_fee();
|
||||
m_ct.rv->type = static_cast<uint8_t>(ack->rv().rv_type());
|
||||
|
@ -864,24 +853,15 @@ namespace tx {
|
|||
|
||||
// RctSig
|
||||
auto num_sources = m_ct.tx_data.sources.size();
|
||||
if (is_simple() || is_req_bulletproof()){
|
||||
auto dst = &m_ct.rv->pseudoOuts;
|
||||
if (is_bulletproof()){
|
||||
dst = &m_ct.rv->p.pseudoOuts;
|
||||
}
|
||||
|
||||
dst->clear();
|
||||
for (const auto &pseudo_out : m_ct.pseudo_outs) {
|
||||
dst->emplace_back();
|
||||
string_to_key(dst->back(), pseudo_out);
|
||||
}
|
||||
|
||||
m_ct.rv->mixRing.resize(num_sources);
|
||||
} else {
|
||||
m_ct.rv->mixRing.resize(m_ct.tsx_data.mixin());
|
||||
m_ct.rv->mixRing[0].resize(num_sources);
|
||||
auto dst = &m_ct.rv->p.pseudoOuts;
|
||||
dst->clear();
|
||||
for (const auto &pseudo_out : m_ct.pseudo_outs) {
|
||||
dst->emplace_back();
|
||||
string_to_key(dst->back(), pseudo_out);
|
||||
}
|
||||
|
||||
m_ct.rv->mixRing.resize(num_sources);
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(m_ct.tx_out_pk.size() == m_ct.tx_out_ecdh.size(), "Invalid vector sizes");
|
||||
for(size_t i = 0; i < m_ct.tx_out_ecdh.size(); ++i){
|
||||
m_ct.rv->outPk.push_back(m_ct.tx_out_pk[i]);
|
||||
|
@ -889,10 +869,10 @@ namespace tx {
|
|||
}
|
||||
|
||||
for(size_t i = 0; i < m_ct.tx_out_rsigs.size(); ++i){
|
||||
if (is_bulletproof()){
|
||||
m_ct.rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs[i]));
|
||||
if (is_req_bulletproof_plus()) {
|
||||
m_ct.rv->p.bulletproofs_plus.push_back(boost::get<rct::BulletproofPlus>(m_ct.tx_out_rsigs[i]));
|
||||
} else {
|
||||
m_ct.rv->p.rangeSigs.push_back(boost::get<rct::rangeSig>(m_ct.tx_out_rsigs[i]));
|
||||
m_ct.rv->p.bulletproofs.push_back(boost::get<rct::Bulletproof>(m_ct.tx_out_rsigs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -936,8 +916,8 @@ namespace tx {
|
|||
void Signer::step_sign_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionSignInputAck> ack){
|
||||
m_ct.signatures.push_back(ack->signature());
|
||||
|
||||
// Sync updated pseudo_outputs, client_version>=1, HF10+
|
||||
if (client_version() >= 1 && ack->has_pseudo_out()){
|
||||
// Sync updated pseudo_outputs
|
||||
if (ack->has_pseudo_out()){
|
||||
CHECK_AND_ASSERT_THROW_MES(m_ct.cur_input_idx < m_ct.pseudo_outs.size(), "Invalid pseudo-out index");
|
||||
m_ct.pseudo_outs[m_ct.cur_input_idx] = ack->pseudo_out();
|
||||
if (is_bulletproof()){
|
||||
|
@ -955,6 +935,8 @@ namespace tx {
|
|||
}
|
||||
|
||||
void Signer::step_final_ack(std::shared_ptr<const messages::monero::MoneroTransactionFinalAck> ack){
|
||||
CHECK_AND_ASSERT_THROW_MES(is_clsag(), "Only CLSAGs signatures are supported");
|
||||
|
||||
if (m_multisig){
|
||||
auto & cout_key = ack->cout_key();
|
||||
for(auto & cur : m_ct.couts){
|
||||
|
@ -975,47 +957,34 @@ namespace tx {
|
|||
m_ct.enc_keys = ack->tx_enc_keys();
|
||||
|
||||
// Opening the sealed signatures
|
||||
if (client_version() >= 3){
|
||||
if(!ack->has_opening_key()){
|
||||
throw exc::ProtocolException("Client version 3+ requires sealed signatures");
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < m_ct.signatures.size(); ++i){
|
||||
CHECK_AND_ASSERT_THROW_MES(m_ct.signatures[i].size() > crypto::chacha::TAG_SIZE, "Invalid signature size");
|
||||
std::string nonce = compute_sealing_key(ack->opening_key(), i, true);
|
||||
std::string key = compute_sealing_key(ack->opening_key(), i, false);
|
||||
size_t plen = m_ct.signatures[i].size() - crypto::chacha::TAG_SIZE;
|
||||
std::unique_ptr<uint8_t[]> plaintext(new uint8_t[plen]);
|
||||
uint8_t * buff = plaintext.get();
|
||||
|
||||
protocol::crypto::chacha::decrypt(
|
||||
m_ct.signatures[i].data(),
|
||||
m_ct.signatures[i].size(),
|
||||
reinterpret_cast<const uint8_t *>(key.data()),
|
||||
reinterpret_cast<const uint8_t *>(nonce.data()),
|
||||
reinterpret_cast<char *>(buff), &plen);
|
||||
m_ct.signatures[i].assign(reinterpret_cast<const char *>(buff), plen);
|
||||
}
|
||||
if(!ack->has_opening_key()){
|
||||
throw exc::ProtocolException("Client version 3+ requires sealed signatures");
|
||||
}
|
||||
|
||||
if (m_ct.rv->type == rct::RCTTypeCLSAG){
|
||||
m_ct.rv->p.CLSAGs.reserve(m_ct.signatures.size());
|
||||
for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::clsag clsag;
|
||||
if (!cn_deserialize(m_ct.signatures[i], clsag)) {
|
||||
throw exc::ProtocolException("Cannot deserialize clsag[i]");
|
||||
}
|
||||
m_ct.rv->p.CLSAGs.push_back(clsag);
|
||||
}
|
||||
} else {
|
||||
m_ct.rv->p.MGs.reserve(m_ct.signatures.size());
|
||||
for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::mgSig mg;
|
||||
if (!cn_deserialize(m_ct.signatures[i], mg)) {
|
||||
throw exc::ProtocolException("Cannot deserialize mg[i]");
|
||||
}
|
||||
m_ct.rv->p.MGs.push_back(mg);
|
||||
for(size_t i = 0; i < m_ct.signatures.size(); ++i){
|
||||
CHECK_AND_ASSERT_THROW_MES(m_ct.signatures[i].size() > crypto::chacha::TAG_SIZE, "Invalid signature size");
|
||||
std::string nonce = compute_sealing_key(ack->opening_key(), i, true);
|
||||
std::string key = compute_sealing_key(ack->opening_key(), i, false);
|
||||
size_t plen = m_ct.signatures[i].size() - crypto::chacha::TAG_SIZE;
|
||||
std::unique_ptr<uint8_t[]> plaintext(new uint8_t[plen]);
|
||||
uint8_t * buff = plaintext.get();
|
||||
|
||||
protocol::crypto::chacha::decrypt(
|
||||
m_ct.signatures[i].data(),
|
||||
m_ct.signatures[i].size(),
|
||||
reinterpret_cast<const uint8_t *>(key.data()),
|
||||
reinterpret_cast<const uint8_t *>(nonce.data()),
|
||||
reinterpret_cast<char *>(buff), &plen);
|
||||
m_ct.signatures[i].assign(reinterpret_cast<const char *>(buff), plen);
|
||||
}
|
||||
|
||||
m_ct.rv->p.CLSAGs.reserve(m_ct.signatures.size());
|
||||
for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::clsag clsag;
|
||||
if (!cn_deserialize(m_ct.signatures[i], clsag)) {
|
||||
throw exc::ProtocolException("Cannot deserialize clsag[i]");
|
||||
}
|
||||
m_ct.rv->p.CLSAGs.push_back(clsag);
|
||||
}
|
||||
|
||||
m_ct.tx.rct_signatures = *(m_ct.rv);
|
||||
|
|
|
@ -116,8 +116,7 @@ namespace ki {
|
|||
*/
|
||||
bool key_image_data(wallet_shim * wallet,
|
||||
const std::vector<tools::wallet2::transfer_details> & transfers,
|
||||
std::vector<MoneroTransferDetails> & res,
|
||||
bool need_all_additionals=false);
|
||||
std::vector<MoneroTransferDetails> & res);
|
||||
|
||||
/**
|
||||
* Computes a hash over MoneroTransferDetails. Commitment used in the KI sync.
|
||||
|
@ -129,8 +128,7 @@ namespace ki {
|
|||
*/
|
||||
void generate_commitment(std::vector<MoneroTransferDetails> & mtds,
|
||||
const std::vector<tools::wallet2::transfer_details> & transfers,
|
||||
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req,
|
||||
bool need_subaddr_indices=false);
|
||||
std::shared_ptr<messages::monero::MoneroKeyImageExportInitRequest> & req);
|
||||
|
||||
/**
|
||||
* Processes Live refresh step response, parses KI, checks the signature
|
||||
|
@ -166,7 +164,7 @@ namespace tx {
|
|||
::crypto::secret_key compute_enc_key(const ::crypto::secret_key & private_view_key, const std::string & aux, const std::string & salt);
|
||||
std::string compute_sealing_key(const std::string & master_key, size_t idx, bool is_iv=false);
|
||||
|
||||
typedef boost::variant<rct::rangeSig, rct::Bulletproof> rsig_v;
|
||||
typedef boost::variant<rct::Bulletproof, rct::BulletproofPlus> rsig_v;
|
||||
|
||||
/**
|
||||
* Transaction signer state holder.
|
||||
|
@ -247,7 +245,7 @@ namespace tx {
|
|||
void compute_integrated_indices(TsxData * tsx_data);
|
||||
bool should_compute_bp_now() const;
|
||||
void compute_bproof(messages::monero::MoneroTransactionRsigData & rsig_data);
|
||||
void process_bproof(rct::Bulletproof & bproof);
|
||||
void process_bproof(rsig_v & bproof);
|
||||
void set_tx_input(MoneroTransactionSourceEntry * dst, size_t idx, bool need_ring_keys=false, bool need_ring_indices=false);
|
||||
|
||||
public:
|
||||
|
@ -260,8 +258,6 @@ namespace tx {
|
|||
void step_set_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionSetInputAck> ack);
|
||||
|
||||
void sort_ki();
|
||||
std::shared_ptr<messages::monero::MoneroTransactionInputsPermutationRequest> step_permutation();
|
||||
void step_permutation_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputsPermutationAck> ack);
|
||||
|
||||
std::shared_ptr<messages::monero::MoneroTransactionInputViniRequest> step_set_vini_input(size_t idx);
|
||||
void step_set_vini_input_ack(std::shared_ptr<const messages::monero::MoneroTransactionInputViniAck> ack);
|
||||
|
@ -290,11 +286,15 @@ namespace tx {
|
|||
return m_client_version;
|
||||
}
|
||||
|
||||
bool is_simple() const {
|
||||
uint8_t get_rv_type() const {
|
||||
if (!m_ct.rv){
|
||||
throw std::invalid_argument("RV not initialized");
|
||||
}
|
||||
auto tp = m_ct.rv->type;
|
||||
return m_ct.rv->type;
|
||||
}
|
||||
|
||||
bool is_simple() const {
|
||||
auto tp = get_rv_type();
|
||||
return tp == rct::RCTTypeSimple;
|
||||
}
|
||||
|
||||
|
@ -302,12 +302,27 @@ namespace tx {
|
|||
return m_ct.tx_data.rct_config.range_proof_type != rct::RangeProofBorromean;
|
||||
}
|
||||
|
||||
bool is_req_clsag() const {
|
||||
return is_req_bulletproof() && m_ct.tx_data.rct_config.bp_version >= 3;
|
||||
}
|
||||
|
||||
bool is_req_bulletproof_plus() const {
|
||||
return is_req_bulletproof() && m_ct.tx_data.rct_config.bp_version == 4; // rct::genRctSimple
|
||||
}
|
||||
|
||||
bool is_bulletproof() const {
|
||||
if (!m_ct.rv){
|
||||
throw std::invalid_argument("RV not initialized");
|
||||
}
|
||||
auto tp = m_ct.rv->type;
|
||||
return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2 || tp == rct::RCTTypeCLSAG;
|
||||
auto tp = get_rv_type();
|
||||
return rct::is_rct_bulletproof(tp) || rct::is_rct_bulletproof_plus(tp);
|
||||
}
|
||||
|
||||
bool is_bulletproof_plus() const {
|
||||
auto tp = get_rv_type();
|
||||
return rct::is_rct_bulletproof_plus(tp);
|
||||
}
|
||||
|
||||
bool is_clsag() const {
|
||||
auto tp = get_rv_type();
|
||||
return rct::is_rct_clsag(tp);
|
||||
}
|
||||
|
||||
bool is_offloading() const {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue