Skip to content
Permalink
Browse files

add get_tx_proof_support

  • Loading branch information...
cslashm committed Mar 21, 2019
1 parent 8039b8d commit 39b595090b664950f8c15812873dda517d65b466
@@ -27,21 +27,6 @@
// 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

#include "crypto/crypto.h"
@@ -180,6 +165,10 @@ namespace hw {
/* 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 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 "ringct/rctOps.h"

#include "log.hpp"
#define ENCRYPTED_PAYMENT_ID_TAIL 0x8d
#define CHACHA8_KEY_TAIL 0x8c

@@ -273,6 +272,11 @@ namespace hw {
/* ======================================================================= */
/* 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) {
cryptonote::keypair txkey = cryptonote::keypair::generate(*this);
@@ -107,6 +107,10 @@ namespace hw {
/* 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 encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
@@ -1,4 +1,4 @@
// Copyright (c) 2017-2018, The Monero Project
// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
@@ -29,7 +29,6 @@

#include "version.h"
#include "device_ledger.hpp"
#include "log.hpp"
#include "ringct/rctOps.h"
#include "cryptonote_basic/account.h"
#include "cryptonote_basic/subaddress_index.h"
@@ -182,6 +181,7 @@ namespace hw {
#define INS_MLSAG 0x7E
#define INS_CLOSE_TX 0x80

#define INS_GET_TX_PROOF 0xA0

#define INS_GET_RESPONSE 0xc0

@@ -274,7 +274,6 @@ namespace hw {

int device_ledger::set_command_header(unsigned char ins, unsigned char p1, unsigned char p2) {
reset_buffer();
int offset = 0;
this->buffer_send[0] = PROTOCOL_VERSION;
this->buffer_send[1] = ins;
this->buffer_send[2] = p1;
@@ -686,7 +685,7 @@ namespace hw {

bool device_ledger::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) {
AUTO_LOCK_CMD();
int offset, sw;
int offset;

offset = set_command_header_noopt(INS_VERIFY_KEY);
//sec
@@ -782,7 +781,11 @@ namespace hw {
const crypto::secret_key a_x = hw::ledger::decrypt(a);
const crypto::secret_key b_x = hw::ledger::decrypt(b);
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);
log_hexbuffer("sc_secret_add: [[OUT]] aG", (char*)r_x.data, 32);
#endif

int offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
@@ -815,10 +818,13 @@ namespace hw {
}

#ifdef DEBUG_HWDEVICE
bool recover_x = recover;
const crypto::secret_key recovery_key_x = recovery_key;
crypto::public_key pub_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

send_simple(INS_GENERATE_KEYPAIR);
@@ -830,6 +836,9 @@ namespace hw {
#ifdef DEBUG_HWDEVICE
crypto::secret_key sec_clear = hw::ledger::decrypt(sec);
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);
hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data);
#endif
@@ -844,7 +853,7 @@ namespace hw {

#ifdef DEBUG_HWDEVICE
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;
log_hexbuffer("generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
log_hexbuffer("generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
@@ -860,7 +869,6 @@ namespace hw {
assert(is_fake_view_key(sec));
r = crypto::generate_key_derivation(pub, this->viewkey, derivation);
} else {

int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
//pub
memmove(this->buffer_send+offset, pub.data, 32);
@@ -879,11 +887,11 @@ namespace hw {
}
#ifdef DEBUG_HWDEVICE
crypto::key_derivation derivation_clear ;
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
derivation_clear = derivation;
}else {
derivation_clear = hw::ledger::decrypt(derivation);
}
if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
derivation_clear = derivation;
} else {
derivation_clear = hw::ledger::decrypt(derivation);
}
hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data);
#endif

@@ -1044,7 +1052,7 @@ namespace hw {
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);
if (!rc){
log_message("secret_key_to_public_key", "secret_key rejected");
log_message("FAIL secret_key_to_public_key", "secret_key rejected");
}
#endif

@@ -1106,6 +1114,77 @@ namespace hw {
/* 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, &this->buffer_recv[64]);
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) {
AUTO_LOCK_CMD();

@@ -1124,7 +1203,11 @@ namespace hw {
this->exchange();

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;
}

@@ -1135,7 +1218,11 @@ namespace hw {
const crypto::public_key public_key_x = public_key;
const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key);
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);
log_hexbuffer("encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data, 32);
#endif

int offset = set_command_header_noopt(INS_STEALTH);
@@ -1172,7 +1259,7 @@ namespace hw {

#ifdef DEBUG_HWDEVICE
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);

const crypto::public_key txkey_pub_x = txkey_pub;
@@ -1190,8 +1277,30 @@ namespace hw {
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;

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,
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


@@ -1589,7 +1698,6 @@ namespace hw {
bool device_ledger::mlsag_prepare(const rct::key &H, const rct::key &xx,
rct::key &a, rct::key &aG, rct::key &aHP, rct::key &II) {
AUTO_LOCK_CMD();
unsigned char options;

#ifdef DEBUG_HWDEVICE
const rct::key H_x = H;
@@ -1633,7 +1741,6 @@ namespace hw {

bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) {
AUTO_LOCK_CMD();
unsigned char options;

#ifdef DEBUG_HWDEVICE
rct::key a_x;
@@ -1656,7 +1763,6 @@ namespace hw {

bool device_ledger::mlsag_hash(const rct::keyV &long_message, rct::key &c) {
AUTO_LOCK_CMD();
unsigned char options;
size_t cnt;

#ifdef DEBUG_HWDEVICE
@@ -33,6 +33,8 @@
#include <cstddef>
#include <string>
#include "device.hpp"
#include "log.hpp"

#include "device_io_hid.hpp"
#include <boost/thread/mutex.hpp>
#include <boost/thread/recursive_mutex.hpp>
@@ -201,7 +203,10 @@ namespace hw {
/* ======================================================================= */
/* 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 encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
@@ -40,6 +40,19 @@

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 log_hexbuffer(const std::string &msg, const char* buff, size_t len);
void log_message(const std::string &msg, const std::string &info );
Oops, something went wrong.

0 comments on commit 39b5950

Please sign in to comment.
You can’t perform that action at this time.