mirror of
https://github.com/monero-project/monero.git
synced 2024-11-18 00:37:43 +00:00
Merge pull request #5132
2dbc487e
Add support for V10 protocol with BulletProofV2 and short amount. (cslashm)63cc02c0
Fix dummy decryption in debug mode (cslashm)f0e55ceb
fix log namespace (cslashm)460da140
New scheme key destination contrfol (cslashm)
This commit is contained in:
commit
8c53ac2dd1
8 changed files with 314 additions and 121 deletions
|
@ -405,49 +405,12 @@ namespace cryptonote
|
||||||
for(const tx_destination_entry& dst_entr: destinations)
|
for(const tx_destination_entry& dst_entr: destinations)
|
||||||
{
|
{
|
||||||
CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
|
CHECK_AND_ASSERT_MES(dst_entr.amount > 0 || tx.version > 1, false, "Destination with wrong amount: " << dst_entr.amount);
|
||||||
crypto::key_derivation derivation;
|
|
||||||
crypto::public_key out_eph_public_key;
|
crypto::public_key out_eph_public_key;
|
||||||
|
|
||||||
// make additional tx pubkey if necessary
|
hwdev.generate_output_ephemeral_keys(tx.version,sender_account_keys, txkey_pub, tx_key,
|
||||||
keypair additional_txkey;
|
dst_entr, change_addr, output_index,
|
||||||
if (need_additional_txkeys)
|
need_additional_txkeys, additional_tx_keys,
|
||||||
{
|
additional_tx_public_keys, amount_keys, out_eph_public_key);
|
||||||
additional_txkey.sec = additional_tx_keys[output_index];
|
|
||||||
if (dst_entr.is_subaddress)
|
|
||||||
additional_txkey.pub = rct::rct2pk(hwdev.scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec)));
|
|
||||||
else
|
|
||||||
additional_txkey.pub = rct::rct2pk(hwdev.scalarmultBase(rct::sk2rct(additional_txkey.sec)));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool r;
|
|
||||||
if (change_addr && dst_entr.addr == *change_addr)
|
|
||||||
{
|
|
||||||
// sending change to yourself; derivation = a*R
|
|
||||||
r = hwdev.generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation);
|
|
||||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// sending to the recipient; derivation = r*A (or s*C in the subaddress scheme)
|
|
||||||
r = hwdev.generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation);
|
|
||||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (need_additional_txkeys)
|
|
||||||
{
|
|
||||||
additional_tx_public_keys.push_back(additional_txkey.pub);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tx.version > 1)
|
|
||||||
{
|
|
||||||
crypto::secret_key scalar1;
|
|
||||||
hwdev.derivation_to_scalar(derivation, output_index, scalar1);
|
|
||||||
amount_keys.push_back(rct::sk2rct(scalar1));
|
|
||||||
}
|
|
||||||
r = hwdev.derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
|
|
||||||
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
|
|
||||||
|
|
||||||
hwdev.add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, output_index, amount_keys.back(), out_eph_public_key);
|
|
||||||
|
|
||||||
tx_out out;
|
tx_out out;
|
||||||
out.amount = dst_entr.amount;
|
out.amount = dst_entr.amount;
|
||||||
|
|
|
@ -97,6 +97,12 @@ namespace cryptonote
|
||||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
||||||
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
|
bool construct_tx_with_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL, bool shuffle_outs = true);
|
||||||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL);
|
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, bool rct = false, const rct::RCTConfig &rct_config = { rct::RangeProofBorromean, 0 }, rct::multisig_out *msout = NULL);
|
||||||
|
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys,
|
||||||
|
crypto::public_key &out_eph_public_key) ;
|
||||||
|
|
||||||
bool generate_genesis_block(
|
bool generate_genesis_block(
|
||||||
block& bl
|
block& bl
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace cryptonote
|
||||||
struct account_public_address;
|
struct account_public_address;
|
||||||
struct account_keys;
|
struct account_keys;
|
||||||
struct subaddress_index;
|
struct subaddress_index;
|
||||||
|
struct tx_destination_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace hw {
|
namespace hw {
|
||||||
|
@ -211,9 +212,12 @@ namespace hw {
|
||||||
virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) = 0;
|
virtual bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) = 0;
|
||||||
virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) = 0;
|
virtual bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) = 0;
|
||||||
|
|
||||||
virtual bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
virtual bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) = 0;
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys,
|
||||||
|
crypto::public_key &out_eph_public_key) = 0;
|
||||||
|
|
||||||
virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0;
|
virtual bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) = 0;
|
||||||
virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) = 0;
|
virtual bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) = 0;
|
||||||
|
|
|
@ -34,8 +34,10 @@
|
||||||
#include "int-util.h"
|
#include "int-util.h"
|
||||||
#include "cryptonote_basic/account.h"
|
#include "cryptonote_basic/account.h"
|
||||||
#include "cryptonote_basic/subaddress_index.h"
|
#include "cryptonote_basic/subaddress_index.h"
|
||||||
|
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
|
|
||||||
|
#include "log.hpp"
|
||||||
#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d
|
#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d
|
||||||
#define CHACHA8_KEY_TAIL 0x8c
|
#define CHACHA8_KEY_TAIL 0x8c
|
||||||
|
|
||||||
|
@ -278,10 +280,55 @@ namespace hw {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool device_default::generate_output_ephemeral_keys(const size_t tx_version,
|
||||||
|
const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys, crypto::public_key &out_eph_public_key) {
|
||||||
|
|
||||||
bool device_default::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
crypto::key_derivation derivation;
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) {
|
|
||||||
return true;
|
// make additional tx pubkey if necessary
|
||||||
|
cryptonote::keypair additional_txkey;
|
||||||
|
if (need_additional_txkeys)
|
||||||
|
{
|
||||||
|
additional_txkey.sec = additional_tx_keys[output_index];
|
||||||
|
if (dst_entr.is_subaddress)
|
||||||
|
additional_txkey.pub = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(dst_entr.addr.m_spend_public_key), rct::sk2rct(additional_txkey.sec)));
|
||||||
|
else
|
||||||
|
additional_txkey.pub = rct::rct2pk(rct::scalarmultBase(rct::sk2rct(additional_txkey.sec)));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool r;
|
||||||
|
if (change_addr && dst_entr.addr == *change_addr)
|
||||||
|
{
|
||||||
|
// sending change to yourself; derivation = a*R
|
||||||
|
r = generate_key_derivation(txkey_pub, sender_account_keys.m_view_secret_key, derivation);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << txkey_pub << ", " << sender_account_keys.m_view_secret_key << ")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// sending to the recipient; derivation = r*A (or s*C in the subaddress scheme)
|
||||||
|
r = generate_key_derivation(dst_entr.addr.m_view_public_key, dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key, derivation);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to generate_key_derivation(" << dst_entr.addr.m_view_public_key << ", " << (dst_entr.is_subaddress && need_additional_txkeys ? additional_txkey.sec : tx_key) << ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_additional_txkeys)
|
||||||
|
{
|
||||||
|
additional_tx_public_keys.push_back(additional_txkey.pub);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_version > 1)
|
||||||
|
{
|
||||||
|
crypto::secret_key scalar1;
|
||||||
|
derivation_to_scalar(derivation, output_index, scalar1);
|
||||||
|
amount_keys.push_back(rct::sk2rct(scalar1));
|
||||||
|
}
|
||||||
|
r = derive_public_key(derivation, output_index, dst_entr.addr.m_spend_public_key, out_eph_public_key);
|
||||||
|
CHECK_AND_ASSERT_MES(r, false, "at creation outs: failed to derive_public_key(" << derivation << ", " << output_index << ", "<< dst_entr.addr.m_spend_public_key << ")");
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
|
bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
|
||||||
|
|
|
@ -114,9 +114,12 @@ namespace hw {
|
||||||
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) override;
|
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_amount) override;
|
||||||
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) override;
|
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_amount) override;
|
||||||
|
|
||||||
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys,
|
||||||
|
crypto::public_key &out_eph_public_key) override;
|
||||||
|
|
||||||
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
|
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
|
||||||
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
|
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "ringct/rctOps.h"
|
#include "ringct/rctOps.h"
|
||||||
#include "cryptonote_basic/account.h"
|
#include "cryptonote_basic/account.h"
|
||||||
#include "cryptonote_basic/subaddress_index.h"
|
#include "cryptonote_basic/subaddress_index.h"
|
||||||
|
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||||
|
|
||||||
#include <boost/thread/locks.hpp>
|
#include <boost/thread/locks.hpp>
|
||||||
#include <boost/thread/lock_guard.hpp>
|
#include <boost/thread/lock_guard.hpp>
|
||||||
|
@ -67,10 +68,12 @@ namespace hw {
|
||||||
/* === Keymap ==== */
|
/* === Keymap ==== */
|
||||||
/* ===================================================================== */
|
/* ===================================================================== */
|
||||||
|
|
||||||
ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const size_t real_output_index, const rct::key& P, const rct::key& AK) {
|
ABPkeys::ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, const bool is_change, const bool need_additional_txkeys, const size_t real_output_index, const rct::key& P, const rct::key& AK) {
|
||||||
Aout = A;
|
Aout = A;
|
||||||
Bout = B;
|
Bout = B;
|
||||||
is_subaddress = is_subaddr;
|
is_subaddress = is_subaddr;
|
||||||
|
is_change_address = is_change;
|
||||||
|
additional_key = need_additional_txkeys;
|
||||||
index = real_output_index;
|
index = real_output_index;
|
||||||
Pout = P;
|
Pout = P;
|
||||||
AKout = AK;
|
AKout = AK;
|
||||||
|
@ -80,6 +83,8 @@ namespace hw {
|
||||||
Aout = keys.Aout;
|
Aout = keys.Aout;
|
||||||
Bout = keys.Bout;
|
Bout = keys.Bout;
|
||||||
is_subaddress = keys.is_subaddress;
|
is_subaddress = keys.is_subaddress;
|
||||||
|
is_change_address = keys.is_change_address;
|
||||||
|
additional_key = keys.additional_key;
|
||||||
index = keys.index;
|
index = keys.index;
|
||||||
Pout = keys.Pout;
|
Pout = keys.Pout;
|
||||||
AKout = keys.AKout;
|
AKout = keys.AKout;
|
||||||
|
@ -137,6 +142,8 @@ namespace hw {
|
||||||
|
|
||||||
static int device_id = 0;
|
static int device_id = 0;
|
||||||
|
|
||||||
|
#define PROTOCOL_VERSION 2
|
||||||
|
|
||||||
#define INS_NONE 0x00
|
#define INS_NONE 0x00
|
||||||
#define INS_RESET 0x02
|
#define INS_RESET 0x02
|
||||||
|
|
||||||
|
@ -168,6 +175,7 @@ namespace hw {
|
||||||
#define INS_STEALTH 0x76
|
#define INS_STEALTH 0x76
|
||||||
#define INS_BLIND 0x78
|
#define INS_BLIND 0x78
|
||||||
#define INS_UNBLIND 0x7A
|
#define INS_UNBLIND 0x7A
|
||||||
|
#define INS_GEN_TXOUT_KEYS 0x7B
|
||||||
#define INS_VALIDATE 0x7C
|
#define INS_VALIDATE 0x7C
|
||||||
#define INS_MLSAG 0x7E
|
#define INS_MLSAG 0x7E
|
||||||
#define INS_CLOSE_TX 0x80
|
#define INS_CLOSE_TX 0x80
|
||||||
|
@ -268,7 +276,7 @@ namespace hw {
|
||||||
int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) {
|
int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) {
|
||||||
reset_buffer();
|
reset_buffer();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
this->buffer_send[0] = 0x00;
|
this->buffer_send[0] = PROTOCOL_VERSION;
|
||||||
this->buffer_send[1] = ins;
|
this->buffer_send[1] = ins;
|
||||||
this->buffer_send[2] = p1;
|
this->buffer_send[2] = p1;
|
||||||
this->buffer_send[3] = p2;
|
this->buffer_send[3] = p2;
|
||||||
|
@ -508,11 +516,11 @@ namespace hw {
|
||||||
}
|
}
|
||||||
const std::size_t output_index_x = output_index;
|
const std::size_t output_index_x = output_index;
|
||||||
crypto::public_key derived_pub_x;
|
crypto::public_key derived_pub_x;
|
||||||
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32);
|
log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32);
|
||||||
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32);
|
log_hexbuffer("derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32);
|
||||||
hw::ledger::log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x));
|
log_message ("derive_subaddress_public_key: [[IN]] index ", std::to_string((int)output_index_x));
|
||||||
this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x);
|
this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x);
|
||||||
hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32);
|
log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
||||||
|
@ -558,11 +566,11 @@ namespace hw {
|
||||||
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
||||||
const cryptonote::subaddress_index index_x = index;
|
const cryptonote::subaddress_index index_x = index;
|
||||||
crypto::public_key D_x;
|
crypto::public_key D_x;
|
||||||
hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32);
|
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32);
|
log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32);
|
||||||
hw::ledger::log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
|
log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
|
||||||
D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x);
|
D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
|
log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (index.is_zero()) {
|
if (index.is_zero()) {
|
||||||
|
@ -609,14 +617,14 @@ namespace hw {
|
||||||
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys);
|
||||||
const cryptonote::subaddress_index index_x = index;
|
const cryptonote::subaddress_index index_x = index;
|
||||||
cryptonote::account_public_address address_x;
|
cryptonote::account_public_address address_x;
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32);
|
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32);
|
log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32);
|
||||||
hw::ledger::log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
|
log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor));
|
||||||
address_x = this->controle_device->get_subaddress(keys_x, index_x);
|
address_x = this->controle_device->get_subaddress(keys_x, index_x);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32);
|
log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32);
|
log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (index.is_zero()) {
|
if (index.is_zero()) {
|
||||||
|
@ -652,10 +660,10 @@ namespace hw {
|
||||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||||
const cryptonote::subaddress_index index_x = index;
|
const cryptonote::subaddress_index index_x = index;
|
||||||
crypto::secret_key sub_sec_x;
|
crypto::secret_key sub_sec_x;
|
||||||
hw::ledger::log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
|
log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor));
|
||||||
hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32);
|
||||||
sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x);
|
sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x);
|
||||||
hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
|
log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
|
int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
|
||||||
|
@ -717,10 +725,10 @@ namespace hw {
|
||||||
const rct::key P_x = P;
|
const rct::key P_x = P;
|
||||||
const rct::key a_x = hw::ledger::decrypt(a);
|
const rct::key a_x = hw::ledger::decrypt(a);
|
||||||
rct::key aP_x;
|
rct::key aP_x;
|
||||||
hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32);
|
log_hexbuffer("scalarmultKey: [[IN]] P ", (char*)P_x.bytes, 32);
|
||||||
hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
|
log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
|
||||||
this->controle_device->scalarmultKey(aP_x, P_x, a_x);
|
this->controle_device->scalarmultKey(aP_x, P_x, a_x);
|
||||||
hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32);
|
log_hexbuffer("scalarmultKey: [[OUT]] aP", (char*)aP_x.bytes, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_KEY);
|
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_KEY);
|
||||||
|
@ -752,9 +760,9 @@ namespace hw {
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const rct::key a_x = hw::ledger::decrypt(a);
|
const rct::key a_x = hw::ledger::decrypt(a);
|
||||||
rct::key aG_x;
|
rct::key aG_x;
|
||||||
hw::ledger::log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
|
log_hexbuffer("scalarmultKey: [[IN]] a ", (char*)a_x.bytes, 32);
|
||||||
this->controle_device->scalarmultBase(aG_x, a_x);
|
this->controle_device->scalarmultBase(aG_x, a_x);
|
||||||
hw::ledger::log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32);
|
log_hexbuffer("scalarmultKey: [[OUT]] aG", (char*)aG_x.bytes, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
|
int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
|
||||||
|
@ -845,10 +853,10 @@ namespace hw {
|
||||||
const crypto::public_key pub_x = pub;
|
const crypto::public_key pub_x = pub;
|
||||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||||
crypto::key_derivation derivation_x;
|
crypto::key_derivation derivation_x;
|
||||||
hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
|
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
|
||||||
hw::ledger::log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
|
||||||
this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x);
|
this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x);
|
||||||
hw::ledger::log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32);
|
log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
||||||
|
@ -914,10 +922,10 @@ namespace hw {
|
||||||
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
|
const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation);
|
||||||
const size_t output_index_x = output_index;
|
const size_t output_index_x = output_index;
|
||||||
crypto::ec_scalar res_x;
|
crypto::ec_scalar res_x;
|
||||||
hw::ledger::log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32);
|
log_hexbuffer("derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32);
|
||||||
hw::ledger::log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x));
|
log_message ("derivation_to_scalar: [[IN]] output_index ", std::to_string(output_index_x));
|
||||||
this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x);
|
this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x);
|
||||||
hw::ledger::log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32);
|
log_hexbuffer("derivation_to_scalar: [[OUT]] res ", res_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
|
int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
|
||||||
|
@ -954,11 +962,11 @@ namespace hw {
|
||||||
const std::size_t output_index_x = output_index;
|
const std::size_t output_index_x = output_index;
|
||||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||||
crypto::secret_key derived_sec_x;
|
crypto::secret_key derived_sec_x;
|
||||||
hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32);
|
log_hexbuffer("derive_secret_key: [[IN]] derivation ", derivation_x.data, 32);
|
||||||
hw::ledger::log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x));
|
log_message ("derive_secret_key: [[IN]] index ", std::to_string(output_index_x));
|
||||||
hw::ledger::log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("derive_secret_key: [[IN]] sec ", sec_x.data, 32);
|
||||||
this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x);
|
this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x);
|
||||||
hw::ledger::log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32);
|
log_hexbuffer("derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
|
int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
|
||||||
|
@ -998,11 +1006,11 @@ namespace hw {
|
||||||
const std::size_t output_index_x = output_index;
|
const std::size_t output_index_x = output_index;
|
||||||
const crypto::public_key pub_x = pub;
|
const crypto::public_key pub_x = pub;
|
||||||
crypto::public_key derived_pub_x;
|
crypto::public_key derived_pub_x;
|
||||||
hw::ledger::log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32);
|
log_hexbuffer("derive_public_key: [[IN]] derivation ", derivation_x.data, 32);
|
||||||
hw::ledger::log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x));
|
log_message ("derive_public_key: [[IN]] output_index", std::to_string(output_index_x));
|
||||||
hw::ledger::log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32);
|
log_hexbuffer("derive_public_key: [[IN]] pub ", pub_x.data, 32);
|
||||||
this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x);
|
this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x);
|
||||||
hw::ledger::log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32);
|
log_hexbuffer("derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
|
int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
|
||||||
|
@ -1039,11 +1047,11 @@ namespace hw {
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||||
crypto::public_key pub_x;
|
crypto::public_key pub_x;
|
||||||
hw::ledger::log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32);
|
||||||
bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x);
|
bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x);
|
||||||
hw::ledger::log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32);
|
log_hexbuffer("secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32);
|
||||||
if (!rc){
|
if (!rc){
|
||||||
hw::ledger::log_message("secret_key_to_public_key", "secret_key rejected");
|
log_message("secret_key_to_public_key", "secret_key rejected");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1073,10 +1081,10 @@ namespace hw {
|
||||||
const crypto::public_key pub_x = pub;
|
const crypto::public_key pub_x = pub;
|
||||||
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
const crypto::secret_key sec_x = hw::ledger::decrypt(sec);
|
||||||
crypto::key_image image_x;
|
crypto::key_image image_x;
|
||||||
hw::ledger::log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32);
|
log_hexbuffer("generate_key_image: [[IN]] pub ", pub_x.data, 32);
|
||||||
hw::ledger::log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("generate_key_image: [[IN]] sec ", sec_x.data, 32);
|
||||||
this->controle_device->generate_key_image(pub_x, sec_x, image_x);
|
this->controle_device->generate_key_image(pub_x, sec_x, image_x);
|
||||||
hw::ledger::log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32);
|
log_hexbuffer("generate_key_image: [[OUT]] image ", image_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE);
|
int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE);
|
||||||
|
@ -1160,10 +1168,139 @@ namespace hw {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) {
|
bool device_ledger::generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys,
|
||||||
|
crypto::public_key &out_eph_public_key) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, real_output_index, rct::pk2rct(out_eph_public_key), amount_key));
|
|
||||||
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
const size_t &tx_version_x = tx_version;
|
||||||
|
const cryptonote::account_keys sender_account_keys_x = sender_account_keys;
|
||||||
|
memmove((void*)sender_account_keys_x.m_view_secret_key.data, dbg_viewkey.data, 32);
|
||||||
|
|
||||||
|
const crypto::public_key &txkey_pub_x = txkey_pub;
|
||||||
|
const crypto::secret_key &tx_key_x = tx_key;
|
||||||
|
const cryptonote::tx_destination_entry &dst_entr_x = dst_entr;
|
||||||
|
const boost::optional<cryptonote::account_public_address> &change_addr_x = change_addr;
|
||||||
|
const size_t &output_index_x = output_index;
|
||||||
|
const bool &need_additional_txkeys_x = need_additional_txkeys;
|
||||||
|
const std::vector<crypto::secret_key> &additional_tx_keys_x = additional_tx_keys;
|
||||||
|
std::vector<crypto::public_key> additional_tx_public_keys_x;
|
||||||
|
std::vector<rct::key> amount_keys_x;
|
||||||
|
crypto::public_key out_eph_public_key_x;
|
||||||
|
this->controle_device->generate_output_ephemeral_keys(tx_version_x, sender_account_keys_x, txkey_pub_x, tx_key_x, dst_entr_x, change_addr_x, output_index_x, need_additional_txkeys_x, additional_tx_keys_x,
|
||||||
|
additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// make additional tx pubkey if necessary
|
||||||
|
cryptonote::keypair additional_txkey;
|
||||||
|
if (need_additional_txkeys) {
|
||||||
|
additional_txkey.sec = additional_tx_keys[output_index];
|
||||||
|
}
|
||||||
|
|
||||||
|
//compute derivation, out_eph_public_key, and amount key in one shot on device, to ensure checkable link
|
||||||
|
const crypto::secret_key *sec;
|
||||||
|
bool is_change;
|
||||||
|
|
||||||
|
if (change_addr && dst_entr.addr == *change_addr)
|
||||||
|
{
|
||||||
|
// sending change to yourself; derivation = a*R
|
||||||
|
is_change = true;
|
||||||
|
sec = &sender_account_keys.m_view_secret_key;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_change = false;
|
||||||
|
if (dst_entr.is_subaddress && need_additional_txkeys) {
|
||||||
|
sec = &additional_txkey.sec;
|
||||||
|
} else {
|
||||||
|
sec = &tx_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = set_command_header_noopt(INS_GEN_TXOUT_KEYS);
|
||||||
|
//tx_version
|
||||||
|
this->buffer_send[offset+0] = tx_version>>24;
|
||||||
|
this->buffer_send[offset+1] = tx_version>>16;
|
||||||
|
this->buffer_send[offset+2] = tx_version>>8;
|
||||||
|
this->buffer_send[offset+3] = tx_version>>0;
|
||||||
|
offset += 4;
|
||||||
|
//tx_sec
|
||||||
|
memmove(&this->buffer_send[offset], sec->data, 32);
|
||||||
|
offset += 32;
|
||||||
|
//Aout
|
||||||
|
memmove(&this->buffer_send[offset], dst_entr.addr.m_view_public_key.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
//Bout
|
||||||
|
memmove(&this->buffer_send[offset], dst_entr.addr.m_spend_public_key.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
//output index
|
||||||
|
this->buffer_send[offset+0] = output_index>>24;
|
||||||
|
this->buffer_send[offset+1] = output_index>>16;
|
||||||
|
this->buffer_send[offset+2] = output_index>>8;
|
||||||
|
this->buffer_send[offset+3] = output_index>>0;
|
||||||
|
offset += 4;
|
||||||
|
//is_change,
|
||||||
|
this->buffer_send[offset] = is_change;
|
||||||
|
offset++;
|
||||||
|
//is_subaddress
|
||||||
|
this->buffer_send[offset] = dst_entr.is_subaddress;
|
||||||
|
offset++;
|
||||||
|
//need_additional_key
|
||||||
|
this->buffer_send[offset] = need_additional_txkeys;
|
||||||
|
offset++;
|
||||||
|
|
||||||
|
this->buffer_send[4] = offset-5;
|
||||||
|
this->length_send = offset;
|
||||||
|
this->exchange();
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
|
unsigned int recv_len = this->length_recv;
|
||||||
|
if (need_additional_txkeys)
|
||||||
|
{
|
||||||
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
|
memmove(additional_txkey.pub.data, &this->buffer_recv[offset], 32);
|
||||||
|
additional_tx_public_keys.push_back(additional_txkey.pub);
|
||||||
|
offset += 32;
|
||||||
|
recv_len -= 32;
|
||||||
|
}
|
||||||
|
if (tx_version > 1)
|
||||||
|
{
|
||||||
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
|
crypto::secret_key scalar1;
|
||||||
|
memmove(scalar1.data, &this->buffer_recv[offset],32);
|
||||||
|
amount_keys.push_back(rct::sk2rct(scalar1));
|
||||||
|
offset += 32;
|
||||||
|
recv_len -= 32;
|
||||||
|
}
|
||||||
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
|
memmove(out_eph_public_key.data, &this->buffer_recv[offset], 32);
|
||||||
|
recv_len -= 32;
|
||||||
|
|
||||||
|
// add ABPkeys
|
||||||
|
this->add_output_key_mapping(dst_entr.addr.m_view_public_key, dst_entr.addr.m_spend_public_key, dst_entr.is_subaddress, is_change,
|
||||||
|
need_additional_txkeys, output_index,
|
||||||
|
amount_keys.back(), out_eph_public_key);
|
||||||
|
|
||||||
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
hw::ledger::check32("generate_output_ephemeral_keys", "amount_key", (const char*)amount_keys_x.back().bytes, (const char*)hw::ledger::decrypt(amount_keys.back()).bytes);
|
||||||
|
if (need_additional_txkeys) {
|
||||||
|
hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_keys_x.back().data, additional_tx_keys.back().data);
|
||||||
|
}
|
||||||
|
hw::ledger::check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change,
|
||||||
|
const bool need_additional, const size_t real_output_index,
|
||||||
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) {
|
||||||
|
key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, is_change, need_additional, real_output_index, rct::pk2rct(out_eph_public_key), amount_key));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1176,7 +1313,10 @@ namespace hw {
|
||||||
this->controle_device->ecdhEncode(unmasked_x, AKout_x, short_amount);
|
this->controle_device->ecdhEncode(unmasked_x, AKout_x, short_amount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_BLIND);
|
int offset = set_command_header(INS_BLIND);
|
||||||
|
//options
|
||||||
|
this->buffer_send[offset] = short_amount?0x02:0x00;
|
||||||
|
offset += 1;
|
||||||
// AKout
|
// AKout
|
||||||
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1198,7 +1338,7 @@ namespace hw {
|
||||||
hw::ledger::check32("ecdhEncode", "amount", (char*)unmasked_x.amount.bytes, (char*)unmasked.amount.bytes);
|
hw::ledger::check32("ecdhEncode", "amount", (char*)unmasked_x.amount.bytes, (char*)unmasked.amount.bytes);
|
||||||
hw::ledger::check32("ecdhEncode", "mask", (char*)unmasked_x.mask.bytes, (char*)unmasked.mask.bytes);
|
hw::ledger::check32("ecdhEncode", "mask", (char*)unmasked_x.mask.bytes, (char*)unmasked.mask.bytes);
|
||||||
|
|
||||||
hw::ledger::log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32);
|
log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1213,8 +1353,10 @@ namespace hw {
|
||||||
this->controle_device->ecdhDecode(masked_x, AKout_x, short_amount);
|
this->controle_device->ecdhDecode(masked_x, AKout_x, short_amount);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_UNBLIND);
|
int offset = set_command_header(INS_UNBLIND);
|
||||||
|
//options
|
||||||
|
this->buffer_send[offset] = short_amount?0x02:0x00;
|
||||||
|
offset += 1;
|
||||||
// AKout
|
// AKout
|
||||||
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
memmove(this->buffer_send+offset, AKout.bytes, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
@ -1310,7 +1452,11 @@ namespace hw {
|
||||||
|
|
||||||
// ====== Aout, Bout, AKout, C, v, k ======
|
// ====== Aout, Bout, AKout, C, v, k ======
|
||||||
kv_offset = data_offset;
|
kv_offset = data_offset;
|
||||||
C_offset = kv_offset+ (32*2)*outputs_size;
|
if (type==rct::RCTTypeBulletproof2) {
|
||||||
|
C_offset = kv_offset+ (8)*outputs_size;
|
||||||
|
} else {
|
||||||
|
C_offset = kv_offset+ (32+32)*outputs_size;
|
||||||
|
}
|
||||||
for ( i = 0; i < outputs_size; i++) {
|
for ( i = 0; i < outputs_size; i++) {
|
||||||
ABPkeys outKeys;
|
ABPkeys outKeys;
|
||||||
bool found;
|
bool found;
|
||||||
|
@ -1323,11 +1469,15 @@ namespace hw {
|
||||||
offset = set_command_header(INS_VALIDATE, 0x02, i+1);
|
offset = set_command_header(INS_VALIDATE, 0x02, i+1);
|
||||||
//options
|
//options
|
||||||
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
|
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
|
||||||
|
this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00;
|
||||||
offset += 1;
|
offset += 1;
|
||||||
if (found) {
|
if (found) {
|
||||||
//is_subaddress
|
//is_subaddress
|
||||||
this->buffer_send[offset] = outKeys.is_subaddress;
|
this->buffer_send[offset] = outKeys.is_subaddress;
|
||||||
offset++;
|
offset++;
|
||||||
|
//is_change_address
|
||||||
|
this->buffer_send[offset] = outKeys.is_change_address;
|
||||||
|
offset++;
|
||||||
//Aout
|
//Aout
|
||||||
memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32);
|
memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32);
|
||||||
offset+=32;
|
offset+=32;
|
||||||
|
@ -1339,27 +1489,38 @@ namespace hw {
|
||||||
offset+=32;
|
offset+=32;
|
||||||
} else {
|
} else {
|
||||||
// dummy: is_subaddress Aout Bout AKout
|
// dummy: is_subaddress Aout Bout AKout
|
||||||
offset += 1+32*3;
|
offset += 2+32*3;
|
||||||
}
|
}
|
||||||
//C
|
//C
|
||||||
memmove(this->buffer_send+offset, data+C_offset,32);
|
memmove(this->buffer_send+offset, data+C_offset,32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
C_offset += 32;
|
C_offset += 32;
|
||||||
|
if (type==rct::RCTTypeBulletproof2) {
|
||||||
|
//k
|
||||||
|
memset(this->buffer_send+offset, 0, 32);
|
||||||
|
offset += 32;
|
||||||
|
//v
|
||||||
|
memset(this->buffer_send+offset, 0, 32);
|
||||||
|
memmove(this->buffer_send+offset, data+kv_offset,8);
|
||||||
|
offset += 32;
|
||||||
|
kv_offset += 8;
|
||||||
|
} else {
|
||||||
//k
|
//k
|
||||||
memmove(this->buffer_send+offset, data+kv_offset,32);
|
memmove(this->buffer_send+offset, data+kv_offset,32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
//v
|
|
||||||
kv_offset += 32;
|
kv_offset += 32;
|
||||||
|
//v
|
||||||
memmove(this->buffer_send+offset, data+kv_offset,32);
|
memmove(this->buffer_send+offset, data+kv_offset,32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
kv_offset += 32;
|
kv_offset += 32;
|
||||||
|
}
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
// check transaction user input
|
// check transaction user input
|
||||||
CHECK_AND_ASSERT_THROW_MES(this->exchange_wait_on_input() == 0, "Transaction denied on device.");
|
CHECK_AND_ASSERT_THROW_MES(this->exchange_wait_on_input() == 0, "Transaction denied on device.");
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
hw::ledger::log_hexbuffer("Prehash AKV input", (char*)&this->buffer_recv[64], 3*32);
|
log_hexbuffer("Prehash AKV input", (char*)&this->buffer_recv[64], 3*32);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,12 +56,14 @@ namespace hw {
|
||||||
rct::key Aout;
|
rct::key Aout;
|
||||||
rct::key Bout;
|
rct::key Bout;
|
||||||
bool is_subaddress;
|
bool is_subaddress;
|
||||||
|
bool is_change_address;
|
||||||
|
bool additional_key ;
|
||||||
size_t index;
|
size_t index;
|
||||||
rct::key Pout;
|
rct::key Pout;
|
||||||
rct::key AKout;
|
rct::key AKout;
|
||||||
ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, size_t index, const rct::key& P,const rct::key& AK);
|
ABPkeys(const rct::key& A, const rct::key& B, const bool is_subaddr, bool is_subaddress, bool is_change_address, size_t index, const rct::key& P,const rct::key& AK);
|
||||||
ABPkeys(const ABPkeys& keys) ;
|
ABPkeys(const ABPkeys& keys) ;
|
||||||
ABPkeys() {index=0;is_subaddress=false;}
|
ABPkeys() {index=0;is_subaddress=false;is_subaddress=false;is_change_address=false;}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Keymap {
|
class Keymap {
|
||||||
|
@ -105,7 +107,9 @@ namespace hw {
|
||||||
device_mode mode;
|
device_mode mode;
|
||||||
// map public destination key to ephemeral destination key
|
// map public destination key to ephemeral destination key
|
||||||
Keymap key_map;
|
Keymap key_map;
|
||||||
|
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const bool is_change,
|
||||||
|
const bool need_additional, const size_t real_output_index,
|
||||||
|
const rct::key &amount_key, const crypto::public_key &out_eph_public_key);
|
||||||
// To speed up blockchain parsing the view key maybe handle here.
|
// To speed up blockchain parsing the view key maybe handle here.
|
||||||
crypto::secret_key viewkey;
|
crypto::secret_key viewkey;
|
||||||
bool has_view_key;
|
bool has_view_key;
|
||||||
|
@ -194,9 +198,12 @@ namespace hw {
|
||||||
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_format) override;
|
bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec, bool short_format) override;
|
||||||
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_format) override;
|
bool ecdhDecode(rct::ecdhTuple & masked, const rct::key & sharedSec, bool short_format) override;
|
||||||
|
|
||||||
bool add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index,
|
bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
|
||||||
const rct::key &amount_key, const crypto::public_key &out_eph_public_key) override;
|
const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
|
||||||
|
const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
|
||||||
|
std::vector<crypto::public_key> &additional_tx_public_keys,
|
||||||
|
std::vector<rct::key> &amount_keys,
|
||||||
|
crypto::public_key &out_eph_public_key) override;
|
||||||
|
|
||||||
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
|
bool mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) override;
|
||||||
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
|
bool mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &rvII) override;
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace hw {
|
||||||
|
|
||||||
|
|
||||||
void decrypt(char* buf, size_t len) {
|
void decrypt(char* buf, size_t len) {
|
||||||
#ifdef IODUMMYCRYPT_HWDEVICE
|
#if defined(IODUMMYCRYPT_HWDEVICE) || defined(IONOCRYPT_HWDEVICE)
|
||||||
size_t i;
|
size_t i;
|
||||||
if (len == 32) {
|
if (len == 32) {
|
||||||
//view key?
|
//view key?
|
||||||
|
@ -86,11 +86,13 @@ namespace hw {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if defined(IODUMMYCRYPT_HWDEVICE)
|
||||||
//std decrypt: XOR.55h
|
//std decrypt: XOR.55h
|
||||||
for (i = 0; i<len;i++) {
|
for (i = 0; i<len;i++) {
|
||||||
buf[i] ^= 0x55;
|
buf[i] ^= 0x55;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
crypto::key_derivation decrypt(const crypto::key_derivation &derivation) {
|
crypto::key_derivation decrypt(const crypto::key_derivation &derivation) {
|
||||||
|
|
Loading…
Reference in a new issue