mirror of
https://codeberg.org/anoncontributorxmr/monero.git
synced 2024-11-30 06:43:28 +01:00
Add get_tx_proof support, needed for new sanity check
Enhance debug info
This commit is contained in:
parent
98fdcb2aa5
commit
7c44091541
@ -27,21 +27,6 @@
|
|||||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
/* Note about debug:
|
|
||||||
* To debug Device you can def the following :
|
|
||||||
* #define DEBUG_HWDEVICE
|
|
||||||
* Activate debug mechanism:
|
|
||||||
* - Add more trace
|
|
||||||
* - All computation done by device are checked by default device.
|
|
||||||
* Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working
|
|
||||||
* #define IODUMMYCRYPT_HWDEVICE 1
|
|
||||||
* - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value
|
|
||||||
* #define IONOCRYPT_HWDEVICE 1
|
|
||||||
* - It assumes sensitive data encryption is off on device side.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "crypto/crypto.h"
|
#include "crypto/crypto.h"
|
||||||
@ -211,6 +196,10 @@ namespace hw {
|
|||||||
/* TRANSACTION */
|
/* TRANSACTION */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
virtual void generate_tx_proof(const crypto::hash &prefix_hash,
|
||||||
|
const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||||
|
crypto::signature &sig) = 0;
|
||||||
|
|
||||||
virtual bool open_tx(crypto::secret_key &tx_key) = 0;
|
virtual bool open_tx(crypto::secret_key &tx_key) = 0;
|
||||||
|
|
||||||
virtual bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) = 0;
|
virtual bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) = 0;
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include "cryptonote_core/cryptonote_tx_utils.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
|
||||||
|
|
||||||
@ -273,6 +272,11 @@ namespace hw {
|
|||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* TRANSACTION */
|
/* TRANSACTION */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
void device_default::generate_tx_proof(const crypto::hash &prefix_hash,
|
||||||
|
const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||||
|
crypto::signature &sig) {
|
||||||
|
crypto::generate_tx_proof(prefix_hash, R, A, B, D, r, sig);
|
||||||
|
}
|
||||||
|
|
||||||
bool device_default::open_tx(crypto::secret_key &tx_key) {
|
bool device_default::open_tx(crypto::secret_key &tx_key) {
|
||||||
cryptonote::keypair txkey = cryptonote::keypair::generate(*this);
|
cryptonote::keypair txkey = cryptonote::keypair::generate(*this);
|
||||||
|
@ -107,6 +107,10 @@ namespace hw {
|
|||||||
/* TRANSACTION */
|
/* TRANSACTION */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
void generate_tx_proof(const crypto::hash &prefix_hash,
|
||||||
|
const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||||
|
crypto::signature &sig) override;
|
||||||
|
|
||||||
bool open_tx(crypto::secret_key &tx_key) override;
|
bool open_tx(crypto::secret_key &tx_key) override;
|
||||||
|
|
||||||
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
|
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "device_ledger.hpp"
|
#include "device_ledger.hpp"
|
||||||
#include "log.hpp"
|
|
||||||
#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"
|
||||||
@ -182,6 +181,7 @@ namespace hw {
|
|||||||
#define INS_MLSAG 0x7E
|
#define INS_MLSAG 0x7E
|
||||||
#define INS_CLOSE_TX 0x80
|
#define INS_CLOSE_TX 0x80
|
||||||
|
|
||||||
|
#define INS_GET_TX_PROOF 0xA0
|
||||||
|
|
||||||
#define INS_GET_RESPONSE 0xc0
|
#define INS_GET_RESPONSE 0xc0
|
||||||
|
|
||||||
@ -808,7 +808,11 @@ namespace hw {
|
|||||||
const crypto::secret_key a_x = hw::ledger::decrypt(a);
|
const crypto::secret_key a_x = hw::ledger::decrypt(a);
|
||||||
const crypto::secret_key b_x = hw::ledger::decrypt(b);
|
const crypto::secret_key b_x = hw::ledger::decrypt(b);
|
||||||
crypto::secret_key r_x;
|
crypto::secret_key r_x;
|
||||||
|
rct::key aG_x;
|
||||||
|
log_hexbuffer("sc_secret_add: [[IN]] a ", (char*)a_x.data, 32);
|
||||||
|
log_hexbuffer("sc_secret_add: [[IN]] b ", (char*)b_x.data, 32);
|
||||||
this->controle_device->sc_secret_add(r_x, a_x, b_x);
|
this->controle_device->sc_secret_add(r_x, a_x, b_x);
|
||||||
|
log_hexbuffer("sc_secret_add: [[OUT]] aG", (char*)r_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
|
int offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
|
||||||
@ -843,6 +847,11 @@ namespace hw {
|
|||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::public_key pub_x;
|
crypto::public_key pub_x;
|
||||||
crypto::secret_key sec_x;
|
crypto::secret_key sec_x;
|
||||||
|
crypto::secret_key recovery_key_x;
|
||||||
|
if (recover) {
|
||||||
|
recovery_key_x = hw::ledger::decrypt(recovery_key);
|
||||||
|
log_hexbuffer("generate_keys: [[IN]] pub", (char*)recovery_key_x.data, 32);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send_simple(INS_GENERATE_KEYPAIR);
|
send_simple(INS_GENERATE_KEYPAIR);
|
||||||
@ -854,6 +863,9 @@ namespace hw {
|
|||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::secret_key sec_clear = hw::ledger::decrypt(sec);
|
crypto::secret_key sec_clear = hw::ledger::decrypt(sec);
|
||||||
sec_x = sec_clear;
|
sec_x = sec_clear;
|
||||||
|
log_hexbuffer("generate_keys: [[OUT]] pub", (char*)pub.data, 32);
|
||||||
|
log_hexbuffer("generate_keys: [[OUT]] sec", (char*)sec_clear.data, 32);
|
||||||
|
|
||||||
crypto::secret_key_to_public_key(sec_x,pub_x);
|
crypto::secret_key_to_public_key(sec_x,pub_x);
|
||||||
hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data);
|
hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data);
|
||||||
#endif
|
#endif
|
||||||
@ -868,7 +880,7 @@ namespace hw {
|
|||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
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 = (sec == rct::rct2sk(rct::I)) ? sec: hw::ledger::decrypt(sec);
|
||||||
crypto::key_derivation derivation_x;
|
crypto::key_derivation derivation_x;
|
||||||
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
|
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
|
||||||
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
|
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
|
||||||
@ -884,7 +896,6 @@ namespace hw {
|
|||||||
assert(is_fake_view_key(sec));
|
assert(is_fake_view_key(sec));
|
||||||
r = crypto::generate_key_derivation(pub, this->viewkey, derivation);
|
r = crypto::generate_key_derivation(pub, this->viewkey, derivation);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
|
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
|
||||||
//pub
|
//pub
|
||||||
memmove(this->buffer_send+offset, pub.data, 32);
|
memmove(this->buffer_send+offset, pub.data, 32);
|
||||||
@ -903,11 +914,11 @@ namespace hw {
|
|||||||
}
|
}
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
crypto::key_derivation derivation_clear ;
|
crypto::key_derivation derivation_clear ;
|
||||||
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
|
||||||
derivation_clear = derivation;
|
derivation_clear = derivation;
|
||||||
}else {
|
} else {
|
||||||
derivation_clear = hw::ledger::decrypt(derivation);
|
derivation_clear = hw::ledger::decrypt(derivation);
|
||||||
}
|
}
|
||||||
hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data);
|
hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1068,7 +1079,7 @@ namespace hw {
|
|||||||
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);
|
||||||
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){
|
||||||
log_message("secret_key_to_public_key", "secret_key rejected");
|
log_message("FAIL secret_key_to_public_key", "secret_key rejected");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1130,6 +1141,75 @@ namespace hw {
|
|||||||
/* TRANSACTION */
|
/* TRANSACTION */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
|
||||||
|
void device_ledger::generate_tx_proof(const crypto::hash &prefix_hash,
|
||||||
|
const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||||
|
crypto::signature &sig) {
|
||||||
|
|
||||||
|
AUTO_LOCK_CMD();
|
||||||
|
|
||||||
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
const crypto::hash prefix_hash_x = prefix_hash;
|
||||||
|
const crypto::public_key R_x = R;
|
||||||
|
const crypto::public_key A_x = A;
|
||||||
|
const boost::optional<crypto::public_key> B_x = B;
|
||||||
|
const crypto::public_key D_x = D;
|
||||||
|
const crypto::secret_key r_x = hw::ledger::decrypt(r);
|
||||||
|
crypto::signature sig_x;
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] prefix_hash ", prefix_hash_x.data, 32);
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] R ", R_x.data, 32);
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] A ", A_x.data, 32);
|
||||||
|
if (B_x) {
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] B ", (*B_x).data, 32);
|
||||||
|
}
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] D ", D_x.data, 32);
|
||||||
|
log_hexbuffer("generate_tx_proof: [[IN]] r ", r_x.data, 32);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int offset = set_command_header(INS_GET_TX_PROOF);
|
||||||
|
//options
|
||||||
|
this->buffer_send[offset] = B?0x01:0x00;
|
||||||
|
offset += 1;
|
||||||
|
//prefix_hash
|
||||||
|
memmove(&this->buffer_send[offset], prefix_hash.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
// R
|
||||||
|
memmove(&this->buffer_send[offset], R.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
// A
|
||||||
|
memmove(&this->buffer_send[offset], A.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
// B
|
||||||
|
if (B) {
|
||||||
|
memmove(&this->buffer_send[offset], (*B).data, 32);
|
||||||
|
} else {
|
||||||
|
memset(&this->buffer_send[offset], 0, 32);
|
||||||
|
}
|
||||||
|
offset += 32;
|
||||||
|
// D
|
||||||
|
memmove(&this->buffer_send[offset], D.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
// r
|
||||||
|
memmove(&this->buffer_send[offset], r.data, 32);
|
||||||
|
offset += 32;
|
||||||
|
|
||||||
|
this->buffer_send[4] = offset-5;
|
||||||
|
this->length_send = offset;
|
||||||
|
this->exchange();
|
||||||
|
|
||||||
|
memmove(sig.c.data, &this->buffer_recv[0], 32);
|
||||||
|
memmove(sig.r.data, &this->buffer_recv[32], 32);
|
||||||
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
log_hexbuffer("GENERATE_TX_PROOF: **c** ", sig.c.data, sizeof( sig.c.data));
|
||||||
|
log_hexbuffer("GENERATE_TX_PROOF: **r** ", sig.r.data, sizeof( sig.r.data));
|
||||||
|
|
||||||
|
this->controle_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
|
||||||
|
hw::ledger::check32("generate_tx_proof", "c", sig_x.c.data, sig.c.data);
|
||||||
|
hw::ledger::check32("generate_tx_proof", "r", sig_x.r.data, sig.r.data);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
||||||
AUTO_LOCK_CMD();
|
AUTO_LOCK_CMD();
|
||||||
|
|
||||||
@ -1148,7 +1228,11 @@ namespace hw {
|
|||||||
this->exchange();
|
this->exchange();
|
||||||
|
|
||||||
memmove(tx_key.data, &this->buffer_recv[32], 32);
|
memmove(tx_key.data, &this->buffer_recv[32], 32);
|
||||||
|
#ifdef DEBUG_HWDEVICE
|
||||||
|
const crypto::secret_key r_x = hw::ledger::decrypt(tx_key);
|
||||||
|
log_hexbuffer("open_tx: [[OUT]] R ", (char*)&this->buffer_recv[0], 32);
|
||||||
|
log_hexbuffer("open_tx: [[OUT]] r ", r_x.data, 32);
|
||||||
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1159,7 +1243,11 @@ namespace hw {
|
|||||||
const crypto::public_key public_key_x = public_key;
|
const crypto::public_key public_key_x = public_key;
|
||||||
const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key);
|
const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key);
|
||||||
crypto::hash8 payment_id_x = payment_id;
|
crypto::hash8 payment_id_x = payment_id;
|
||||||
|
log_hexbuffer("encrypt_payment_id: [[IN]] payment_id ", payment_id_x.data, 32);
|
||||||
|
log_hexbuffer("encrypt_payment_id: [[IN]] public_key ", public_key_x.data, 32);
|
||||||
|
log_hexbuffer("encrypt_payment_id: [[IN]] secret_key ", secret_key_x.data, 32);
|
||||||
this->controle_device->encrypt_payment_id(payment_id_x, public_key_x, secret_key_x);
|
this->controle_device->encrypt_payment_id(payment_id_x, public_key_x, secret_key_x);
|
||||||
|
log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int offset = set_command_header_noopt(INS_STEALTH);
|
int offset = set_command_header_noopt(INS_STEALTH);
|
||||||
@ -1196,10 +1284,9 @@ namespace hw {
|
|||||||
|
|
||||||
#ifdef DEBUG_HWDEVICE
|
#ifdef DEBUG_HWDEVICE
|
||||||
const size_t &tx_version_x = tx_version;
|
const size_t &tx_version_x = tx_version;
|
||||||
const cryptonote::account_keys sender_account_keys_x = sender_account_keys;
|
const cryptonote::account_keys sender_account_keys_x = hw::ledger::decrypt(sender_account_keys);
|
||||||
memmove((void*)sender_account_keys_x.m_view_secret_key.data, dbg_viewkey.data, 32);
|
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::public_key txkey_pub_x = txkey_pub;
|
||||||
const crypto::secret_key tx_key_x = hw::ledger::decrypt(tx_key);
|
const crypto::secret_key tx_key_x = hw::ledger::decrypt(tx_key);
|
||||||
const cryptonote::tx_destination_entry dst_entr_x = dst_entr;
|
const cryptonote::tx_destination_entry dst_entr_x = dst_entr;
|
||||||
@ -1215,12 +1302,32 @@ namespace hw {
|
|||||||
std::vector<crypto::public_key> additional_tx_public_keys_x;
|
std::vector<crypto::public_key> additional_tx_public_keys_x;
|
||||||
std::vector<rct::key> amount_keys_x;
|
std::vector<rct::key> amount_keys_x;
|
||||||
crypto::public_key out_eph_public_key_x;
|
crypto::public_key out_eph_public_key_x;
|
||||||
|
|
||||||
|
log_message ("generate_output_ephemeral_keys: [[IN]] tx_version", std::to_string(tx_version_x));
|
||||||
|
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.view", sender_account_keys.m_sview_secret_key.data, 32);
|
||||||
|
//log_hexbuffer("generate_output_ephemeral_keys: [[IN]] sender_account_keys.spend", sender_account_keys.m_spend_secret_key.data, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] txkey_pub", txkey_pub_x.data, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] tx_key", tx_key_x.data, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.view", dst_entr_x.addr.m_view_public_key.data, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] dst_entr.spend", dst_entr_x.addr.m_spend_public_key.data, 32);
|
||||||
|
if (change_addr) {
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.view", (*change_addr_x).m_view_public_key.data, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] change_addr.spend", (*change_addr_x).m_spend_public_key.data, 32);
|
||||||
|
}
|
||||||
|
log_message ("generate_output_ephemeral_keys: [[IN]] output_index", std::to_string(output_index_x));
|
||||||
|
log_message ("generate_output_ephemeral_keys: [[IN]] need_additional_txkeys", std::to_string(need_additional_txkeys_x));
|
||||||
|
if(need_additional_txkeys_x) {
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[output_index].data, 32);
|
||||||
|
}
|
||||||
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,
|
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);
|
additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x);
|
||||||
|
if(need_additional_txkeys_x) {
|
||||||
|
log_hexbuffer("additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data, 32);
|
||||||
|
}
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] amount_keys ", (char*)amount_keys_x.back().bytes, 32);
|
||||||
|
log_hexbuffer("generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data, 32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ASSERT_X(tx_version > 1, "TX version not supported"<<tx_version);
|
ASSERT_X(tx_version > 1, "TX version not supported"<<tx_version);
|
||||||
|
|
||||||
// make additional tx pubkey if necessary
|
// make additional tx pubkey if necessary
|
||||||
@ -1236,7 +1343,6 @@ namespace hw {
|
|||||||
this->buffer_send[offset+2] = tx_version>>8;
|
this->buffer_send[offset+2] = tx_version>>8;
|
||||||
this->buffer_send[offset+3] = tx_version>>0;
|
this->buffer_send[offset+3] = tx_version>>0;
|
||||||
offset += 4;
|
offset += 4;
|
||||||
|
|
||||||
//tx_key
|
//tx_key
|
||||||
memmove(&this->buffer_send[offset], tx_key.data, 32);
|
memmove(&this->buffer_send[offset], tx_key.data, 32);
|
||||||
offset += 32;
|
offset += 32;
|
||||||
@ -1256,7 +1362,7 @@ namespace hw {
|
|||||||
this->buffer_send[offset+3] = output_index>>0;
|
this->buffer_send[offset+3] = output_index>>0;
|
||||||
offset += 4;
|
offset += 4;
|
||||||
//is_change,
|
//is_change,
|
||||||
bool is_change = (change_addr && dst_entr.addr == *change_addr);
|
bool is_change = (change_addr && dst_entr.addr == *change_addr);
|
||||||
this->buffer_send[offset] = is_change;
|
this->buffer_send[offset] = is_change;
|
||||||
offset++;
|
offset++;
|
||||||
//is_subaddress
|
//is_subaddress
|
||||||
@ -1265,13 +1371,14 @@ namespace hw {
|
|||||||
//need_additional_key
|
//need_additional_key
|
||||||
this->buffer_send[offset] = need_additional_txkeys;
|
this->buffer_send[offset] = need_additional_txkeys;
|
||||||
offset++;
|
offset++;
|
||||||
//additional_tx_key
|
//additional_tx_key
|
||||||
if (need_additional_txkeys) {
|
if (need_additional_txkeys) {
|
||||||
memmove(&this->buffer_send[offset], additional_txkey.sec.data, 32);
|
memmove(&this->buffer_send[offset], additional_txkey.sec.data, 32);
|
||||||
} else {
|
} else {
|
||||||
memset(&this->buffer_send[offset], 0, 32);
|
memset(&this->buffer_send[offset], 0, 32);
|
||||||
}
|
}
|
||||||
offset += 32;
|
offset += 32;
|
||||||
|
|
||||||
this->buffer_send[4] = offset-5;
|
this->buffer_send[4] = offset-5;
|
||||||
this->length_send = offset;
|
this->length_send = offset;
|
||||||
this->exchange();
|
this->exchange();
|
||||||
@ -1280,7 +1387,7 @@ namespace hw {
|
|||||||
unsigned int recv_len = this->length_recv;
|
unsigned int recv_len = this->length_recv;
|
||||||
|
|
||||||
//if (tx_version > 1)
|
//if (tx_version > 1)
|
||||||
{
|
{
|
||||||
ASSERT_X(recv_len>=32, "Not enought data from device");
|
ASSERT_X(recv_len>=32, "Not enought data from device");
|
||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
memmove(scalar1.data, &this->buffer_recv[offset],32);
|
memmove(scalar1.data, &this->buffer_recv[offset],32);
|
||||||
@ -1312,7 +1419,7 @@ namespace hw {
|
|||||||
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);
|
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) {
|
if (need_additional_txkeys) {
|
||||||
hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data, additional_tx_public_keys.back().data);
|
hw::ledger::check32("generate_output_ephemeral_keys", "additional_tx_key", additional_tx_public_keys_x.back().data, additional_tx_public_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);
|
hw::ledger::check32("generate_output_ephemeral_keys", "out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "device.hpp"
|
#include "device.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
#include "device_io_hid.hpp"
|
#include "device_io_hid.hpp"
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <boost/thread/recursive_mutex.hpp>
|
#include <boost/thread/recursive_mutex.hpp>
|
||||||
@ -202,6 +203,9 @@ namespace hw {
|
|||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
/* TRANSACTION */
|
/* TRANSACTION */
|
||||||
/* ======================================================================= */
|
/* ======================================================================= */
|
||||||
|
void generate_tx_proof(const crypto::hash &prefix_hash,
|
||||||
|
const crypto::public_key &R, const crypto::public_key &A, const boost::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||||
|
crypto::signature &sig) override;
|
||||||
|
|
||||||
bool open_tx(crypto::secret_key &tx_key) override;
|
bool open_tx(crypto::secret_key &tx_key) override;
|
||||||
|
|
||||||
|
@ -40,6 +40,19 @@
|
|||||||
|
|
||||||
namespace hw {
|
namespace hw {
|
||||||
|
|
||||||
|
/* Note about debug:
|
||||||
|
* To debug Device you can def the following :
|
||||||
|
* #define DEBUG_HWDEVICE
|
||||||
|
* Activate debug mechanism:
|
||||||
|
* - Add more trace
|
||||||
|
* - All computation done by device are checked by default device.
|
||||||
|
* Required IODUMMYCRYPT_HWDEVICE or IONOCRYPT_HWDEVICE for fully working
|
||||||
|
* #define IODUMMYCRYPT_HWDEVICE 1
|
||||||
|
* - It assumes sensitive data encryption is is off on device side. a XOR with 0x55. This allow Ledger Class to make check on clear value
|
||||||
|
* #define IONOCRYPT_HWDEVICE 1
|
||||||
|
* - It assumes sensitive data encryption is off on device side.
|
||||||
|
*/
|
||||||
|
|
||||||
void buffer_to_str(char *to_buff, size_t to_len, const char *buff, size_t len) ;
|
void buffer_to_str(char *to_buff, size_t to_len, const char *buff, size_t len) ;
|
||||||
void log_hexbuffer(const std::string &msg, const char* buff, size_t len);
|
void log_hexbuffer(const std::string &msg, const char* buff, size_t len);
|
||||||
void log_message(const std::string &msg, const std::string &info );
|
void log_message(const std::string &msg, const std::string &info );
|
||||||
|
@ -6871,11 +6871,6 @@ bool simple_wallet::set_tx_key(const std::vector<std::string> &args_)
|
|||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
bool simple_wallet::get_tx_proof(const std::vector<std::string> &args)
|
bool simple_wallet::get_tx_proof(const std::vector<std::string> &args)
|
||||||
{
|
{
|
||||||
if (m_wallet->key_on_device() && m_wallet->get_account().get_device().get_type() != hw::device::TREZOR)
|
|
||||||
{
|
|
||||||
fail_msg_writer() << tr("command not supported by HW wallet");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (args.size() != 2 && args.size() != 3)
|
if (args.size() != 2 && args.size() != 3)
|
||||||
{
|
{
|
||||||
PRINT_USAGE(USAGE_GET_TX_PROOF);
|
PRINT_USAGE(USAGE_GET_TX_PROOF);
|
||||||
|
@ -10411,7 +10411,7 @@ void wallet2::check_tx_key(const crypto::hash &txid, const crypto::secret_key &t
|
|||||||
void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received) const
|
void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received) const
|
||||||
{
|
{
|
||||||
received = 0;
|
received = 0;
|
||||||
hw::device &hwdev = m_account.get_device();
|
|
||||||
for (size_t n = 0; n < tx.vout.size(); ++n)
|
for (size_t n = 0; n < tx.vout.size(); ++n)
|
||||||
{
|
{
|
||||||
const cryptonote::txout_to_key* const out_key = boost::get<cryptonote::txout_to_key>(std::addressof(tx.vout[n].target));
|
const cryptonote::txout_to_key* const out_key = boost::get<cryptonote::txout_to_key>(std::addressof(tx.vout[n].target));
|
||||||
@ -10419,13 +10419,13 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
crypto::public_key derived_out_key;
|
crypto::public_key derived_out_key;
|
||||||
bool r = hwdev.derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key);
|
bool r = crypto::derive_public_key(derivation, n, address.m_spend_public_key, derived_out_key);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
|
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
|
||||||
bool found = out_key->key == derived_out_key;
|
bool found = out_key->key == derived_out_key;
|
||||||
crypto::key_derivation found_derivation = derivation;
|
crypto::key_derivation found_derivation = derivation;
|
||||||
if (!found && !additional_derivations.empty())
|
if (!found && !additional_derivations.empty())
|
||||||
{
|
{
|
||||||
r = hwdev.derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key);
|
r = crypto::derive_public_key(additional_derivations[n], n, address.m_spend_public_key, derived_out_key);
|
||||||
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
|
THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, "Failed to derive public key");
|
||||||
found = out_key->key == derived_out_key;
|
found = out_key->key == derived_out_key;
|
||||||
found_derivation = additional_derivations[n];
|
found_derivation = additional_derivations[n];
|
||||||
@ -10441,9 +10441,9 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto::secret_key scalar1;
|
crypto::secret_key scalar1;
|
||||||
hwdev.derivation_to_scalar(found_derivation, n, scalar1);
|
crypto::derivation_to_scalar(found_derivation, n, scalar1);
|
||||||
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
rct::ecdhTuple ecdh_info = tx.rct_signatures.ecdhInfo[n];
|
||||||
hwdev.ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
rct::ecdhDecode(ecdh_info, rct::sk2rct(scalar1), tx.rct_signatures.type == rct::RCTTypeBulletproof2);
|
||||||
const rct::key C = tx.rct_signatures.outPk[n].mask;
|
const rct::key C = tx.rct_signatures.outPk[n].mask;
|
||||||
rct::key Ctmp;
|
rct::key Ctmp;
|
||||||
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask");
|
THROW_WALLET_EXCEPTION_IF(sc_check(ecdh_info.mask.bytes) != 0, error::wallet_internal_error, "Bad ECDH input mask");
|
||||||
@ -10554,6 +10554,8 @@ std::string wallet2::get_tx_proof(const crypto::hash &txid, const cryptonote::ac
|
|||||||
|
|
||||||
std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message) const
|
std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypto::secret_key &tx_key, const std::vector<crypto::secret_key> &additional_tx_keys, const cryptonote::account_public_address &address, bool is_subaddress, const std::string &message) const
|
||||||
{
|
{
|
||||||
|
hw::device &hwdev = m_account.get_device();
|
||||||
|
rct::key aP;
|
||||||
// determine if the address is found in the subaddress hash table (i.e. whether the proof is outbound or inbound)
|
// determine if the address is found in the subaddress hash table (i.e. whether the proof is outbound or inbound)
|
||||||
const bool is_out = m_subaddresses.count(address.m_spend_public_key) == 0;
|
const bool is_out = m_subaddresses.count(address.m_spend_public_key) == 0;
|
||||||
|
|
||||||
@ -10572,30 +10574,34 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
|
|||||||
shared_secret.resize(num_sigs);
|
shared_secret.resize(num_sigs);
|
||||||
sig.resize(num_sigs);
|
sig.resize(num_sigs);
|
||||||
|
|
||||||
shared_secret[0] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_view_public_key), rct::sk2rct(tx_key)));
|
hwdev.scalarmultKey(aP, rct::pk2rct(address.m_view_public_key), rct::sk2rct(tx_key));
|
||||||
|
shared_secret[0] = rct::rct2pk(aP);
|
||||||
crypto::public_key tx_pub_key;
|
crypto::public_key tx_pub_key;
|
||||||
if (is_subaddress)
|
if (is_subaddress)
|
||||||
{
|
{
|
||||||
tx_pub_key = rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_spend_public_key), rct::sk2rct(tx_key)));
|
hwdev.scalarmultKey(aP, rct::pk2rct(address.m_spend_public_key), rct::sk2rct(tx_key));
|
||||||
crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], tx_key, sig[0]);
|
tx_pub_key = rct2pk(aP);
|
||||||
|
hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[0], tx_key, sig[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto::secret_key_to_public_key(tx_key, tx_pub_key);
|
hwdev.secret_key_to_public_key(tx_key, tx_pub_key);
|
||||||
crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], tx_key, sig[0]);
|
hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[0], tx_key, sig[0]);
|
||||||
}
|
}
|
||||||
for (size_t i = 1; i < num_sigs; ++i)
|
for (size_t i = 1; i < num_sigs; ++i)
|
||||||
{
|
{
|
||||||
shared_secret[i] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_view_public_key), rct::sk2rct(additional_tx_keys[i - 1])));
|
hwdev.scalarmultKey(aP, rct::pk2rct(address.m_view_public_key), rct::sk2rct(additional_tx_keys[i - 1]));
|
||||||
|
shared_secret[i] = rct::rct2pk(aP);
|
||||||
if (is_subaddress)
|
if (is_subaddress)
|
||||||
{
|
{
|
||||||
tx_pub_key = rct2pk(rct::scalarmultKey(rct::pk2rct(address.m_spend_public_key), rct::sk2rct(additional_tx_keys[i - 1])));
|
hwdev.scalarmultKey(aP, rct::pk2rct(address.m_spend_public_key), rct::sk2rct(additional_tx_keys[i - 1]));
|
||||||
crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[i], additional_tx_keys[i - 1], sig[i]);
|
tx_pub_key = rct2pk(aP);
|
||||||
|
hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, address.m_spend_public_key, shared_secret[i], additional_tx_keys[i - 1], sig[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto::secret_key_to_public_key(additional_tx_keys[i - 1], tx_pub_key);
|
hwdev.secret_key_to_public_key(additional_tx_keys[i - 1], tx_pub_key);
|
||||||
crypto::generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[i], additional_tx_keys[i - 1], sig[i]);
|
hwdev.generate_tx_proof(prefix_hash, tx_pub_key, address.m_view_public_key, boost::none, shared_secret[i], additional_tx_keys[i - 1], sig[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sig_str = std::string("OutProofV1");
|
sig_str = std::string("OutProofV1");
|
||||||
@ -10611,25 +10617,27 @@ std::string wallet2::get_tx_proof(const cryptonote::transaction &tx, const crypt
|
|||||||
sig.resize(num_sigs);
|
sig.resize(num_sigs);
|
||||||
|
|
||||||
const crypto::secret_key& a = m_account.get_keys().m_view_secret_key;
|
const crypto::secret_key& a = m_account.get_keys().m_view_secret_key;
|
||||||
shared_secret[0] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(tx_pub_key), rct::sk2rct(a)));
|
hwdev.scalarmultKey(aP, rct::pk2rct(tx_pub_key), rct::sk2rct(a));
|
||||||
|
shared_secret[0] = rct2pk(aP);
|
||||||
if (is_subaddress)
|
if (is_subaddress)
|
||||||
{
|
{
|
||||||
crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], a, sig[0]);
|
hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, address.m_spend_public_key, shared_secret[0], a, sig[0]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], a, sig[0]);
|
hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, tx_pub_key, boost::none, shared_secret[0], a, sig[0]);
|
||||||
}
|
}
|
||||||
for (size_t i = 1; i < num_sigs; ++i)
|
for (size_t i = 1; i < num_sigs; ++i)
|
||||||
{
|
{
|
||||||
shared_secret[i] = rct::rct2pk(rct::scalarmultKey(rct::pk2rct(additional_tx_pub_keys[i - 1]), rct::sk2rct(a)));
|
hwdev.scalarmultKey(aP,rct::pk2rct(additional_tx_pub_keys[i - 1]), rct::sk2rct(a));
|
||||||
|
shared_secret[i] = rct2pk(aP);
|
||||||
if (is_subaddress)
|
if (is_subaddress)
|
||||||
{
|
{
|
||||||
crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], address.m_spend_public_key, shared_secret[i], a, sig[i]);
|
hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], address.m_spend_public_key, shared_secret[i], a, sig[i]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
crypto::generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], boost::none, shared_secret[i], a, sig[i]);
|
hwdev.generate_tx_proof(prefix_hash, address.m_view_public_key, additional_tx_pub_keys[i - 1], boost::none, shared_secret[i], a, sig[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sig_str = std::string("InProofV1");
|
sig_str = std::string("InProofV1");
|
||||||
|
Loading…
Reference in New Issue
Block a user