Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trezor: Enable CLSAG support for Trezor client #6798

Merged
merged 1 commit into from
Sep 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions src/device_trezor/trezor/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,11 +561,6 @@ namespace tx {
assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
}

// TODO: use HF_VERSION_CLSAG after CLSAG is merged
if (tsx_data.hard_fork() >= 13){
throw exc::ProtocolException("CLSAG is not yet implemented");
}

// Rsig decision
auto rsig_data = tsx_data.mutable_rsig_data();
m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size());
Expand Down Expand Up @@ -1017,14 +1012,24 @@ namespace tx {
}
}

// CLSAG support comes here once it is merged to the Monero
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]");
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);
}
m_ct.rv->p.MGs.push_back(mg);
}

m_ct.tx.rct_signatures = *(m_ct.rv);
Expand Down
2 changes: 1 addition & 1 deletion src/wallet/wallet2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10682,7 +10682,7 @@ void wallet2::cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_
hw::wallet_shim wallet_shim;
setup_shim(&wallet_shim, this);
aux_data.tx_recipients = dsts_info;
aux_data.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1;
aux_data.bp_version = (use_fork_rules(HF_VERSION_CLSAG, -10) ? 3 : use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1);
aux_data.hard_fork = get_current_hard_fork();
dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data);
tx_device_aux = aux_data.tx_device_aux;
Expand Down
2 changes: 1 addition & 1 deletion tests/trezor/daemon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ bool mock_daemon::run_main()

if (m_start_zmq)
{
if (!zmq_server.addTCPSocket("127.0.0.1", m_zmq_bind_port))
if (!zmq_server.init_rpc("127.0.0.1", m_zmq_bind_port))
{
MERROR("Failed to add TCP Socket (127.0.0.1:" << m_zmq_bind_port << ") to ZMQ RPC Server");

Expand Down
40 changes: 31 additions & 9 deletions tests/trezor/trezor_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ int main(int argc, char* argv[])

// Bootstrapping common chain & accounts
const uint8_t initial_hf = (uint8_t)get_env_long("TEST_MIN_HF", 12);
const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", 12);
const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", HF_VERSION_CLSAG);
auto sync_test = get_env_long("TEST_KI_SYNC", 1);
MINFO("Test versions " << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")");
MINFO("Testing hardforks [" << (int)initial_hf << ", " << (int)max_hf << "], sync-test: " << sync_test);
Expand Down Expand Up @@ -546,7 +546,7 @@ static void expand_tsx(cryptonote::transaction &tx)
for (size_t n = 0; n < tx.vin.size(); ++n)
rv.p.MGs[0].II[n] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
}
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeCLSAG)
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2)
{
CHECK_AND_ASSERT_THROW_MES(rv.p.MGs.size() == tx.vin.size(), "Bad MGs size");
for (size_t n = 0; n < tx.vin.size(); ++n)
Expand All @@ -555,6 +555,21 @@ static void expand_tsx(cryptonote::transaction &tx)
rv.p.MGs[n].II[0] = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
}
}
else if (rv.type == rct::RCTTypeCLSAG)
{
if (!tx.pruned)
{
CHECK_AND_ASSERT_THROW_MES(rv.p.CLSAGs.size() == tx.vin.size(), "Bad CLSAGs size");
for (size_t n = 0; n < tx.vin.size(); ++n)
{
rv.p.CLSAGs[n].I = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
}
}
}
else
{
CHECK_AND_ASSERT_THROW_MES(false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
}
}

static std::vector<tools::wallet2*> vct_wallets(tools::wallet2* w1=nullptr, tools::wallet2* w2=nullptr, tools::wallet2* w3=nullptr, tools::wallet2* w4=nullptr, tools::wallet2* w5=nullptr)
Expand Down Expand Up @@ -708,7 +723,9 @@ bool gen_trezor_base::generate(std::vector<test_event_entry>& events)
std::vector<size_t> block_weights;
generate_genesis_block(blk_gen, get_config(m_network_type).GENESIS_TX, get_config(m_network_type).GENESIS_NONCE);
events.push_back(blk_gen);
generator.add_block(blk_gen, 0, block_weights, 0);
uint64_t rew = 0;
cryptonote::get_block_reward(0, get_transaction_weight(blk_gen.miner_tx), 0, rew, 1);
generator.add_block(blk_gen, 0, block_weights, 0, rew);

// First event has to be the genesis block
m_bob_account.generate();
Expand Down Expand Up @@ -926,7 +943,7 @@ void gen_trezor_base::fix_hf(std::vector<test_event_entry>& events)
// If current test requires higher hard-fork, move it up
auto current_hf = m_hard_forks.back().first;
CHECK_AND_ASSERT_THROW_MES(current_hf <= m_top_hard_fork, "Generated chain hardfork is higher than desired maximum");
CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version != 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2");
CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version < 2 || m_top_hard_fork >= 10, "Desired maximum is too low for BPv2");

for(;current_hf < m_top_hard_fork; current_hf+=1)
{
Expand Down Expand Up @@ -1014,9 +1031,10 @@ void gen_trezor_base::test_trezor_tx(std::vector<test_event_entry>& events, std:
setup_shim(&wallet_shim);
aux_data.tx_recipients = dsts_info;
aux_data.bp_version = m_rct_config.bp_version;
aux_data.hard_fork = m_top_hard_fork;
dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data);

MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions");
MDEBUG("Signed tx data from hw: " << exported_txs.ptx.size() << " transactions, hf: " << (int)m_top_hard_fork << ", bpv: " << m_rct_config.bp_version);
CHECK_AND_ASSERT_THROW_MES(exported_txs.ptx.size() == ptxs.size(), "Invalid transaction sizes");

for (size_t i = 0; i < exported_txs.ptx.size(); ++i){
Expand Down Expand Up @@ -1245,10 +1263,14 @@ void gen_trezor_base::set_hard_fork(uint8_t hf)
m_top_hard_fork = hf;
if (hf < 9){
throw std::runtime_error("Minimal supported Hardfork is 9");
} else if (hf == 9){
} else if (hf <= 11){
rct_config({rct::RangeProofPaddedBulletproof, 1});
} else {
} else if (hf == 12){
rct_config({rct::RangeProofPaddedBulletproof, 2});
} else if (hf == HF_VERSION_CLSAG){
rct_config({rct::RangeProofPaddedBulletproof, 3});
} else {
throw std::runtime_error("Unsupported HF");
}
}

Expand Down Expand Up @@ -1844,7 +1866,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events)
CHECK_AND_ASSERT_THROW_MES(w->refresh(), "Refresh fail");
uint64_t balance = w->balance(0);
MDEBUG("Balance: " << balance);
CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok");
CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok, " << w->errorString());

auto addr = get_address(m_eve_account);
auto recepient_address = cryptonote::get_account_address_as_str(m_network_type, false, addr);
Expand All @@ -1855,7 +1877,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events)
Monero::PendingTransaction::Priority_Medium,
0,
std::set<uint32_t>{});
CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok");
CHECK_AND_ASSERT_THROW_MES(transaction->status() == Monero::PendingTransaction::Status_Ok, "Status nok: " << transaction->status() << ", msg: " << transaction->errorString());
w->refresh();

CHECK_AND_ASSERT_THROW_MES(w->balance(0) == balance, "Err");
Expand Down