38 #include <boost/thread/locks.hpp> 39 #include <boost/thread/lock_guard.hpp> 42 static void local_abort(
const char *msg)
44 fprintf(stderr,
"%s\n", msg);
57 #ifdef WITH_DEVICE_LEDGER 59 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 60 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "device.ledger" 66 void set_apdu_verbose(
bool verbose) {
70 #define TRACKD MTRACE("hw") 71 #define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ; 72 #define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ; 73 #define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg); 91 size_t sz = hmacs.size();
93 for (
size_t i=0; i<sz; i++) {
95 if (memcmp(sec, hmacs[i].sec, 32) == 0) {
96 memcpy(hmac, hmacs[i].hmac, 32);
102 throw std::runtime_error(
"Protocol error: try to send untrusted secret");
105 void HMACmap::add_mac(
const uint8_t sec[32],
const uint8_t hmac[32]) {
108 hmacs.push_back(SecHMAC(sec,hmac));
111 void HMACmap::clear() {
119 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) {
122 is_subaddress = is_subaddr;
123 is_change_address = is_change;
124 additional_key = need_additional_txkeys;
125 index = real_output_index;
132 ABPkeys::ABPkeys(
const ABPkeys& keys) {
135 is_subaddress = keys.is_subaddress;
136 is_change_address = keys.is_change_address;
137 additional_key = keys.additional_key;
148 is_subaddress = keys.is_subaddress;
149 is_change_address = keys.is_change_address;
150 additional_key = keys.additional_key;
157 bool Keymap::find(
const rct::key& P, ABPkeys& keys)
const {
158 size_t sz = ABP.size();
159 for (
size_t i=0; i<sz; i++) {
160 if (ABP[i].Pout == P) {
168 void Keymap::add(
const ABPkeys& keys) {
172 void Keymap::clear() {
176 #ifdef DEBUG_HWDEVICE 179 size_t sz = ABP.size();
180 for (
size_t i=0; i<sz; i++) {
200 return !
crypto_verify_32((
const unsigned char*)&d0, (
const unsigned char*)&d1);
207 static int device_id = 0;
209 #define PROTOCOL_VERSION 2 211 #define INS_NONE 0x00 212 #define INS_RESET 0x02 214 #define INS_GET_KEY 0x20 215 #define INS_PUT_KEY 0x22 216 #define INS_GET_CHACHA8_PREKEY 0x24 217 #define INS_VERIFY_KEY 0x26 219 #define INS_SECRET_KEY_TO_PUBLIC_KEY 0x30 220 #define INS_GEN_KEY_DERIVATION 0x32 221 #define INS_DERIVATION_TO_SCALAR 0x34 222 #define INS_DERIVE_PUBLIC_KEY 0x36 223 #define INS_DERIVE_SECRET_KEY 0x38 224 #define INS_GEN_KEY_IMAGE 0x3A 225 #define INS_SECRET_KEY_ADD 0x3C 226 #define INS_SCALAR_MULSUB 0x3D 227 #define INS_SECRET_KEY_SUB 0x3E 228 #define INS_GENERATE_KEYPAIR 0x40 229 #define INS_SECRET_SCAL_MUL_KEY 0x42 230 #define INS_SECRET_SCAL_MUL_BASE 0x44 232 #define INS_DERIVE_SUBADDRESS_PUBLIC_KEY 0x46 233 #define INS_GET_SUBADDRESS 0x48 234 #define INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY 0x4A 235 #define INS_GET_SUBADDRESS_SECRET_KEY 0x4C 237 #define INS_OPEN_TX 0x70 238 #define INS_SET_SIGNATURE_MODE 0x72 239 #define INS_GET_ADDITIONAL_KEY 0x74 240 #define INS_STEALTH 0x76 241 #define INS_GEN_COMMITMENT_MASK 0x77 242 #define INS_BLIND 0x78 243 #define INS_UNBLIND 0x7A 244 #define INS_GEN_TXOUT_KEYS 0x7B 245 #define INS_VALIDATE 0x7C 246 #define INS_MLSAG 0x7E 247 #define INS_CLOSE_TX 0x80 249 #define INS_GET_TX_PROOF 0xA0 251 #define INS_GET_RESPONSE 0xc0 253 #define INS_TX_PREFIX_START 0xD0 254 #define INS_TX_PREFIX_INPUTS 0xD2 255 #define INS_TX_PREFIX_OUTPUTS 0xD4 256 #define INS_TX_PREFIX_OUTPUTS_SIZE 0xD6 257 #define INS_TX_PREFIX_EXTRA 0xD8 258 #define INS_TX_PROMPT_FEE 0xDA 259 #define INS_TX_PROMPT_AMOUNT 0xDC 261 #define INS_HASH_TO_SCALAR 0xE0 262 #define INS_HASH_TO_SCALAR_BATCH 0xE2 263 #define INS_HASH_TO_SCALAR_INIT 0xE4 265 device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) {
266 this->
id = device_id++;
267 this->reset_buffer();
269 this->has_view_key =
false;
270 this->tx_in_progress =
false;
271 MDEBUG(
"Device "<<this->
id <<
" Created");
274 device_ledger::~device_ledger() {
276 MDEBUG(
"Device "<<this->
id <<
" Destroyed");
284 #define AUTO_LOCK_CMD() \ 286 boost::lock(device_locker, command_locker); \ 288 boost::lock_guard<boost::recursive_mutex> lock1(device_locker, boost::adopt_lock); \ 289 boost::lock_guard<boost::mutex> lock2(command_locker, boost::adopt_lock) 292 void device_ledger::lock(
void) {
293 MDEBUG(
"Ask for LOCKING for device "<<this->
name <<
" in thread ");
294 device_locker.lock();
299 bool device_ledger::try_lock(
void) {
300 MDEBUG(
"Ask for LOCKING(try) for device "<<this->
name <<
" in thread ");
301 bool r = device_locker.try_lock();
303 MDEBUG(
"Device "<<this->
name <<
" LOCKed(try)");
305 MDEBUG(
"Device "<<this->
name <<
" not LOCKed(try)");
311 void device_ledger::unlock(
void) {
313 MDEBUG(
"Ask for UNLOCKING for device "<<this->
name <<
" in thread ");
316 device_locker.unlock();
317 MDEBUG(
"Device "<<this->
name <<
" UNLOCKed");
325 #define IO_SW_DENY 0x6982 326 #define IO_SECRET_KEY 0x02 328 void device_ledger::logCMD() {
330 char strbuffer[1024];
331 snprintf(strbuffer,
sizeof(strbuffer),
"%.02x %.02x %.02x %.02x %.02x ",
332 this->buffer_send[0],
333 this->buffer_send[1],
334 this->buffer_send[2],
335 this->buffer_send[3],
338 const size_t len = strlen(strbuffer);
339 buffer_to_str(strbuffer+len,
sizeof(strbuffer)-len, (
char*)(this->buffer_send+5), this->length_send-5);
340 MDEBUG(
"CMD : " << strbuffer);
344 void device_ledger::logRESP() {
346 char strbuffer[1024];
347 snprintf(strbuffer,
sizeof(strbuffer),
"%.04x ", this->
sw);
348 const size_t len = strlen(strbuffer);
349 buffer_to_str(strbuffer+len,
sizeof(strbuffer)-len, (
char*)(this->buffer_recv), this->length_recv);
350 MDEBUG(
"RESP : " << strbuffer);
355 int device_ledger::set_command_header(
unsigned char ins,
unsigned char p1,
unsigned char p2) {
357 this->buffer_send[0] = PROTOCOL_VERSION;
358 this->buffer_send[1] = ins;
359 this->buffer_send[2] = p1;
360 this->buffer_send[3] = p2;
361 this->buffer_send[4] = 0x00;
365 int device_ledger::set_command_header_noopt(
unsigned char ins,
unsigned char p1,
unsigned char p2) {
366 int offset = set_command_header(ins, p1, p2);
368 this->buffer_send[offset++] = 0;
369 this->buffer_send[4] = offset - 5;
373 void device_ledger::send_simple(
unsigned char ins,
unsigned char p1) {
374 this->length_send = set_command_header_noopt(ins, p1);
375 if (ins == INS_GET_KEY && p1 == IO_SECRET_KEY) {
377 this->exchange_wait_on_input();
383 void device_ledger::send_secret(
const unsigned char sec[32],
int &offset) {
384 MDEBUG(
"send_secret: " << this->tx_in_progress);
385 ASSERT_X(offset + 32 <= BUFFER_SEND_SIZE,
"send_secret: out of bounds write (secret)");
386 memmove(this->buffer_send+offset, sec, 32);
388 if (this->tx_in_progress) {
389 ASSERT_X(offset + 32 <= BUFFER_SEND_SIZE,
"send_secret: out of bounds write (mac)");
390 this->hmac_map.find_mac((
uint8_t*)sec, this->buffer_send+offset);
395 void device_ledger::receive_secret(
unsigned char sec[32],
int &offset) {
396 MDEBUG(
"receive_secret: " << this->tx_in_progress);
397 ASSERT_X(offset + 32 <= BUFFER_RECV_SIZE,
"receive_secret: out of bounds read (secret)");
398 memmove(sec, this->buffer_recv+offset, 32);
400 if (this->tx_in_progress) {
401 ASSERT_X(offset + 32 <= BUFFER_RECV_SIZE,
"receive_secret: out of bounds read (mac)");
402 this->hmac_map.add_mac((
uint8_t*)sec, this->buffer_recv+offset);
407 bool device_ledger::reset() {
409 int offset = set_command_header_noopt(INS_RESET);
411 ASSERT_X(offset + verlen <= BUFFER_SEND_SIZE,
"ELECTRONEUM_VERSION is too long")
414 this->buffer_send[4] = offset-5;
415 this->length_send = offset;
418 ASSERT_X(this->length_recv>=3,
"Communication error, less than three bytes received. Check your application version.");
420 unsigned int device_version = 0;
421 device_version =
VERSION(this->buffer_recv[0], this->buffer_recv[1], this->buffer_recv[2]);
430 unsigned int device_ledger::exchange(
unsigned int ok,
unsigned int mask) {
433 this->length_recv = hw_device.exchange(this->buffer_send, this->length_send, this->buffer_recv, BUFFER_SEND_SIZE,
false);
434 ASSERT_X(this->length_recv>=2,
"Communication error, less than tow bytes received");
436 this->length_recv -= 2;
437 this->
sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1];
439 ASSERT_SW(this->
sw,ok,msk);
444 unsigned int device_ledger::exchange_wait_on_input(
unsigned int ok,
unsigned int mask) {
446 unsigned int deny = 0;
447 this->length_recv = hw_device.exchange(this->buffer_send, this->length_send, this->buffer_recv, BUFFER_SEND_SIZE,
true);
448 ASSERT_X(this->length_recv>=2,
"Communication error, less than two bytes received");
450 this->length_recv -= 2;
451 this->
sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1];
452 if (this->
sw == IO_SW_DENY) {
456 ASSERT_SW(this->
sw,ok,msk);
463 void device_ledger::reset_buffer() {
464 this->length_send = 0;
465 memset(this->buffer_send, 0, BUFFER_SEND_SIZE);
466 this->length_recv = 0;
467 memset(this->buffer_recv, 0, BUFFER_RECV_SIZE);
479 const std::string device_ledger::get_name()
const {
480 if (!this->connected()) {
481 return std::string(
"<disconnected:").append(this->name).append(
">");
487 #ifdef DEBUG_HWDEVICE 492 MDEBUG(
"Device "<<this->
id <<
" HIDUSB inited");
496 static const std::vector<hw::io::hid_conn_params> known_devices {
497 {0x2c97, 0x0001, 0, 0xffa0},
498 {0x2c97, 0x0004, 0, 0xffa0},
501 bool device_ledger::connect(
void) {
503 hw_device.connect(known_devices);
505 #ifdef DEBUG_HWDEVICE 507 this->get_public_address(pubkey);
511 this->get_secret_keys(vkey,skey);
516 bool device_ledger::connected(
void)
const {
517 return hw_device.connected();
520 bool device_ledger::disconnect() {
521 hw_device.disconnect();
525 bool device_ledger::release() {
531 bool device_ledger::set_mode(device_mode mode) {
537 case TRANSACTION_CREATE_REAL:
538 case TRANSACTION_CREATE_FAKE:
539 offset = set_command_header_noopt(INS_SET_SIGNATURE_MODE, 1);
541 this->buffer_send[offset] = mode;
544 this->buffer_send[4] = offset-5;
545 this->length_send = offset;
551 case TRANSACTION_PARSE:
558 MDEBUG(
"Switch to mode: " <<mode);
570 send_simple(INS_GET_KEY, 1);
582 memset(vkey.data, 0x00, 32);
583 memset(skey.data, 0xFF, 32);
586 send_simple(INS_GET_KEY, 0x02);
589 memmove(this->viewkey.data, this->buffer_recv+0, 32);
590 if (is_fake_view_key(this->viewkey)) {
591 MDEBUG(
"Have Not view key");
592 this->has_view_key =
false;
595 this->has_view_key =
true;
598 #ifdef DEBUG_HWDEVICE 599 send_simple(INS_GET_KEY, 0x04);
600 memmove(dbg_viewkey.data, this->buffer_recv+0, 32);
601 memmove(dbg_spendkey.data, this->buffer_recv+32, 32);
610 #ifdef DEBUG_HWDEVICE 611 crypto::chacha_key key_x;
613 this->controle_device->generate_chacha_key(keys_x, key_x, kdf_rounds);
616 send_simple(INS_GET_CHACHA8_PREKEY);
619 memmove(prekey, &this->buffer_recv[0], 200);
620 crypto::generate_chacha_key_prehashed(&prekey[0],
sizeof(prekey),
key, kdf_rounds);
622 #ifdef DEBUG_HWDEVICE 623 hw::ledger::check32(
"generate_chacha_key_prehashed",
"key", (
char*)key_x.data(), (
char*)
key.data());
635 #ifdef DEBUG_HWDEVICE 638 if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
639 derivation_x = derivation;
645 log_hexbuffer(
"derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32);
646 log_hexbuffer(
"derive_subaddress_public_key: [[IN]] derivation", derivation_x.data, 32);
648 this->controle_device->derive_subaddress_public_key(pub_x, derivation_x,output_index_x,derived_pub_x);
649 log_hexbuffer(
"derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32);
652 if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
655 MDEBUG(
"derive_subaddress_public_key : PARSE mode with known viewkey");
659 int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY);
661 memmove(this->buffer_send+offset, pub.data, 32);
664 this->send_secret((
unsigned char*)derivation.data, offset);
672 this->buffer_send[4] = offset-5;
673 this->length_send = offset;
677 memmove(derived_pub.data, &this->buffer_recv[0], 32);
679 #ifdef DEBUG_HWDEVICE 680 hw::ledger::check32(
"derive_subaddress_public_key",
"derived_pub", derived_pub_x.data, derived_pub.data);
690 #ifdef DEBUG_HWDEVICE 697 D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x);
698 log_hexbuffer(
"get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32);
705 int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SPEND_PUBLIC_KEY);
711 this->buffer_send[4] = offset-5;
712 this->length_send = offset;
715 memmove(D.data, &this->buffer_recv[0], 32);
718 #ifdef DEBUG_HWDEVICE 719 hw::ledger::check32(
"get_subaddress_spend_public_key",
"D", D_x.data, D.data);
726 std::vector<crypto::public_key> pkeys;
729 for (
uint32_t idx = begin; idx < end; ++idx) {
731 D = this->get_subaddress_spend_public_key(keys, index);
741 #ifdef DEBUG_HWDEVICE 750 address_x = this->controle_device->get_subaddress(keys_x, index_x);
758 int offset = set_command_header_noopt(INS_GET_SUBADDRESS);
764 this->buffer_send[4] = offset-5;
765 this->length_send = offset;
768 memmove(
address.m_view_public_key.data, &this->buffer_recv[0], 32);
769 memmove(
address.m_spend_public_key.data, &this->buffer_recv[32], 32);
772 #ifdef DEBUG_HWDEVICE 773 hw::ledger::check32(
"get_subaddress",
"address.m_view_public_key.data", address_x.
m_view_public_key.data,
address.m_view_public_key.data);
774 hw::ledger::check32(
"get_subaddress",
"address.m_spend_public_key.data", address_x.
m_spend_public_key.data,
address.m_spend_public_key.data);
784 #ifdef DEBUG_HWDEVICE 789 log_hexbuffer(
"get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32);
790 sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x);
791 log_hexbuffer(
"get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32);
794 int offset = set_command_header_noopt(INS_GET_SUBADDRESS_SECRET_KEY);
796 this->send_secret((
unsigned char*)sec.data, offset);
802 this->buffer_send[4] = offset-5;
803 this->length_send = offset;
807 this->receive_secret((
unsigned char*)sub_sec.data, offset);
809 #ifdef DEBUG_HWDEVICE 811 hw::ledger::check32(
"get_subaddress_secret_key",
"sub_sec", sub_sec_x.data, sub_sec_clear.data);
818 return boost::value_initialized<crypto::secret_key>();
822 return boost::value_initialized<crypto::secret_key>();
833 offset = set_command_header_noopt(INS_VERIFY_KEY);
835 this->send_secret((
unsigned char*)
secret_key.data, offset);
840 this->buffer_send[4] = offset-5;
841 this->length_send = offset;
845 this->buffer_recv[0] << 24 |
846 this->buffer_recv[1] << 16 |
847 this->buffer_recv[2] << 8 |
848 this->buffer_recv[3] << 0 ;
850 return verified == 1;
856 #ifdef DEBUG_HWDEVICE 862 this->controle_device->scalarmultKey(aP_x, P_x, a_x);
866 int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_KEY);
871 this->send_secret(
a.bytes, offset);
873 this->buffer_send[4] = offset-5;
874 this->length_send = offset;
880 #ifdef DEBUG_HWDEVICE 881 hw::ledger::check32(
"scalarmultKey",
"mulkey", (
char*)aP_x.
bytes, (
char*)aP.
bytes);
890 #ifdef DEBUG_HWDEVICE 894 this->controle_device->scalarmultBase(aG_x, a_x);
898 int offset = set_command_header_noopt(INS_SECRET_SCAL_MUL_BASE);
900 this->send_secret(
a.bytes, offset);
902 this->buffer_send[4] = offset-5;
903 this->length_send = offset;
909 #ifdef DEBUG_HWDEVICE 910 hw::ledger::check32(
"scalarmultBase",
"mulkey", (
char*)aG_x.
bytes, (
char*)aG.
bytes);
920 #ifdef DEBUG_HWDEVICE 925 log_hexbuffer(
"sc_secret_add: [[IN]] a ", (
char*)a_x.data, 32);
926 log_hexbuffer(
"sc_secret_add: [[IN]] b ", (
char*)b_x.data, 32);
927 this->controle_device->sc_secret_add(r_x, a_x, b_x);
928 log_hexbuffer(
"sc_secret_add: [[OUT]] aG", (
char*)r_x.data, 32);
931 offset = set_command_header_noopt(INS_SECRET_KEY_ADD);
933 this->send_secret((
unsigned char*)
a.data, offset);
935 this->send_secret((
unsigned char*)b.data, offset);
937 this->buffer_send[4] = offset-5;
938 this->length_send = offset;
943 this->receive_secret((
unsigned char*)r.data, offset);
945 #ifdef DEBUG_HWDEVICE 947 hw::ledger::check32(
"sc_secret_add",
"r", r_x.data, r_clear.data);
958 throw std::runtime_error(
"device generate key does not support recover");
961 #ifdef DEBUG_HWDEVICE 967 log_hexbuffer(
"generate_keys: [[IN]] pub", (
char*)recovery_key_x.data, 32);
971 send_simple(INS_GENERATE_KEYPAIR);
975 memmove(pub.data, &this->buffer_recv[0], 32);
977 this->receive_secret((
unsigned char*)sec.data, offset);
979 #ifdef DEBUG_HWDEVICE 982 log_hexbuffer(
"generate_keys: [[OUT]] pub", (
char*)pub.data, 32);
983 log_hexbuffer(
"generate_keys: [[OUT]] sec", (
char*)sec_clear.data, 32);
986 hw::ledger::check32(
"generate_keys",
"pub", pub_x.data, pub.data);
997 int offset = set_command_header_noopt(INS_SCALAR_MULSUB);
999 memmove(this->buffer_send+offset, c.data, 32);
1002 this->send_secret((
unsigned char*)x.data, offset);
1003 this->send_secret((
unsigned char*)q.data, offset);
1005 this->buffer_send[4] = offset-5;
1006 this->length_send = offset;
1010 memmove(r.data, &this->buffer_recv[0], 32);
1020 #ifdef DEBUG_HWDEVICE 1024 log_hexbuffer(
"generate_key_derivation: [[IN]] pub ", pub_x.data, 32);
1025 log_hexbuffer(
"generate_key_derivation: [[IN]] sec ", sec_x.data, 32);
1026 this->controle_device->generate_key_derivation(pub_x, sec_x, derivation_x);
1027 log_hexbuffer(
"generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32);
1030 if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
1033 MDEBUG(
"generate_key_derivation : PARSE mode with known viewkey");
1035 assert(is_fake_view_key(sec));
1038 int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
1040 memmove(this->buffer_send+offset, pub.data, 32);
1043 this->send_secret((
unsigned char*)sec.data, offset);
1045 this->buffer_send[4] = offset-5;
1046 this->length_send = offset;
1051 this->receive_secret((
unsigned char*)derivation.data, offset);
1055 #ifdef DEBUG_HWDEVICE 1057 if ((this->mode == TRANSACTION_PARSE) && has_view_key) {
1058 derivation_clear = derivation;
1062 hw::ledger::check32(
"generate_key_derivation",
"derivation", derivation_x.data, derivation_clear.data);
1070 if (derivation == main_derivation) {
1072 MDEBUG(
"conceal derivation with main tx pub key");
1074 for(
size_t n=0; n < additional_derivations.size();++n) {
1075 if(derivation == additional_derivations[n]) {
1076 pkey = &additional_tx_pub_keys[n];
1077 MDEBUG(
"conceal derivation with additionnal tx pub key");
1082 ASSERT_X(pkey,
"Mismatched derivation on scan info");
1089 #ifdef DEBUG_HWDEVICE 1093 log_hexbuffer(
"derivation_to_scalar: [[IN]] derivation ", derivation_x.data, 32);
1095 this->controle_device->derivation_to_scalar(derivation_x, output_index_x, res_x);
1096 log_hexbuffer(
"derivation_to_scalar: [[OUT]] res ", res_x.data, 32);
1099 int offset = set_command_header_noopt(INS_DERIVATION_TO_SCALAR);
1101 this->send_secret((
unsigned char*)derivation.data, offset);
1110 this->buffer_send[4] = offset-5;
1111 this->length_send = offset;
1116 this->receive_secret((
unsigned char*)
res.data, offset);
1118 #ifdef DEBUG_HWDEVICE 1120 hw::ledger::check32(
"derivation_to_scalar",
"res", res_x.data, res_clear.data);
1129 #ifdef DEBUG_HWDEVICE 1134 log_hexbuffer(
"derive_secret_key: [[IN]] derivation ", derivation_x.data, 32);
1136 log_hexbuffer(
"derive_secret_key: [[IN]] sec ", sec_x.data, 32);
1137 this->controle_device->derive_secret_key(derivation_x, output_index_x, sec_x, derived_sec_x);
1138 log_hexbuffer(
"derive_secret_key: [[OUT]] derived_sec", derived_sec_x.data, 32);
1141 int offset = set_command_header_noopt(INS_DERIVE_SECRET_KEY);
1143 this->send_secret((
unsigned char*)derivation.data, offset);
1151 this->send_secret((
unsigned char*)sec.data, offset);
1153 this->buffer_send[4] = offset-5;
1154 this->length_send = offset;
1159 this->receive_secret((
unsigned char*)derived_sec.data, offset);
1161 #ifdef DEBUG_HWDEVICE 1163 hw::ledger::check32(
"derive_secret_key",
"derived_sec", derived_sec_x.data, derived_sec_clear.data);
1172 #ifdef DEBUG_HWDEVICE 1177 log_hexbuffer(
"derive_public_key: [[IN]] derivation ", derivation_x.data, 32);
1179 log_hexbuffer(
"derive_public_key: [[IN]] pub ", pub_x.data, 32);
1180 this->controle_device->derive_public_key(derivation_x, output_index_x, pub_x, derived_pub_x);
1181 log_hexbuffer(
"derive_public_key: [[OUT]] derived_pub ", derived_pub_x.data, 32);
1184 int offset = set_command_header_noopt(INS_DERIVE_PUBLIC_KEY);
1186 this->send_secret((
unsigned char*)derivation.data, offset);
1194 memmove(this->buffer_send+offset, pub.data, 32);
1197 this->buffer_send[4] = offset-5;
1198 this->length_send = offset;
1202 memmove(derived_pub.data, &this->buffer_recv[0], 32);
1204 #ifdef DEBUG_HWDEVICE 1205 hw::ledger::check32(
"derive_public_key",
"derived_pub", derived_pub_x.data, derived_pub.data);
1214 #ifdef DEBUG_HWDEVICE 1217 log_hexbuffer(
"secret_key_to_public_key: [[IN]] sec ", sec_x.data, 32);
1218 bool rc = this->controle_device->secret_key_to_public_key(sec_x, pub_x);
1219 log_hexbuffer(
"secret_key_to_public_key: [[OUT]] pub", pub_x.data, 32);
1221 log_message(
"FAIL secret_key_to_public_key",
"secret_key rejected");
1225 int offset = set_command_header_noopt(INS_SECRET_KEY_TO_PUBLIC_KEY);
1227 this->send_secret((
unsigned char*)sec.data, offset);
1229 this->buffer_send[4] = offset-5;
1230 this->length_send = offset;
1234 memmove(pub.data, &this->buffer_recv[0], 32);
1236 #ifdef DEBUG_HWDEVICE 1237 hw::ledger::check32(
"secret_key_to_public_key",
"pub", pub_x.data, pub.data);
1246 #ifdef DEBUG_HWDEVICE 1250 log_hexbuffer(
"generate_key_image: [[IN]] pub ", pub_x.data, 32);
1251 log_hexbuffer(
"generate_key_image: [[IN]] sec ", sec_x.data, 32);
1252 this->controle_device->generate_key_image(pub_x, sec_x, image_x);
1253 log_hexbuffer(
"generate_key_image: [[OUT]] image ", image_x.data, 32);
1256 int offset = set_command_header_noopt(INS_GEN_KEY_IMAGE);
1258 memmove(this->buffer_send+offset, pub.data, 32);
1261 this->send_secret((
unsigned char*)sec.data, offset);
1263 this->buffer_send[4] = offset-5;
1264 this->length_send = offset;
1268 memmove(image.data, &this->buffer_recv[0], 32);
1270 #ifdef DEBUG_HWDEVICE 1271 hw::ledger::check32(
"generate_key_image",
"image", image_x.data, image.data);
1281 return &
reinterpret_cast<unsigned char &
>(point);
1285 return &
reinterpret_cast<const unsigned char &
>(point);
1289 return &
reinterpret_cast<unsigned char &
>(scalar);
1293 return &
reinterpret_cast<const unsigned char &
>(scalar);
1306 #ifdef DEBUG_HWDEVICE 1310 const boost::optional<crypto::public_key> B_x = B;
1314 log_hexbuffer(
"generate_tx_proof: [[IN]] prefix_hash ", prefix_hash_x.data, 32);
1315 log_hexbuffer(
"generate_tx_proof: [[IN]] R ", R_x.data, 32);
1316 log_hexbuffer(
"generate_tx_proof: [[IN]] A ", A_x.data, 32);
1318 log_hexbuffer(
"generate_tx_proof: [[IN]] B ", (*B_x).data, 32);
1320 log_hexbuffer(
"generate_tx_proof: [[IN]] D ", D_x.data, 32);
1321 log_hexbuffer(
"generate_tx_proof: [[IN]] r ", r_x.data, 32);
1325 int offset = set_command_header(INS_GET_TX_PROOF);
1327 this->buffer_send[offset] = B?0x01:0x00;
1330 memmove(&this->buffer_send[offset], prefix_hash.data, 32);
1333 memmove(&this->buffer_send[offset], R.data, 32);
1336 memmove(&this->buffer_send[offset],
A.data, 32);
1340 memmove(&this->buffer_send[offset], (*B).data, 32);
1342 memset(&this->buffer_send[offset], 0, 32);
1346 memmove(&this->buffer_send[offset], D.data, 32);
1349 this->send_secret((
unsigned char*)r.data, offset);
1351 this->buffer_send[4] = offset-5;
1352 this->length_send = offset;
1355 memmove(sig.c.data, &this->buffer_recv[0], 32);
1356 memmove(sig.r.data, &this->buffer_recv[32], 32);
1357 #ifdef DEBUG_HWDEVICE 1358 log_hexbuffer(
"GENERATE_TX_PROOF: **c** ", sig.c.data,
sizeof( sig.c.data));
1359 log_hexbuffer(
"GENERATE_TX_PROOF: **r** ", sig.r.data,
sizeof( sig.r.data));
1361 this->controle_device->generate_tx_proof(prefix_hash_x, R_x, A_x, B_x, D_x, r_x, sig_x);
1362 MDEBUG(
"FAIL is normal if random is not fixed in proof");
1363 hw::ledger::check32(
"generate_tx_proof",
"c", sig_x.c.data, sig.c.data);
1364 hw::ledger::check32(
"generate_tx_proof",
"r", sig_x.r.data, sig.r.data);
1374 this->tx_in_progress =
true;
1375 int offset = set_command_header_noopt(INS_OPEN_TX, 0x01);
1378 this->buffer_send[offset+0] = 0x00;
1379 this->buffer_send[offset+1] = 0x00;
1380 this->buffer_send[offset+2] = 0x00;
1381 this->buffer_send[offset+3] = 0x00;
1384 this->buffer_send[4] = offset-5;
1385 this->length_send = offset;
1389 unsigned char tmp[32];
1391 this->receive_secret((
unsigned char*)tx_key.data, offset);
1392 this->receive_secret(tmp, offset);
1393 this->receive_secret(tmp, offset);
1395 #ifdef DEBUG_HWDEVICE 1397 log_hexbuffer(
"open_tx: [[OUT]] R ", (
char*)&this->buffer_recv[0], 32);
1406 #ifdef DEBUG_HWDEVICE 1410 log_hexbuffer(
"encrypt_payment_id: [[IN]] payment_id ", payment_id_x.data, 32);
1411 log_hexbuffer(
"encrypt_payment_id: [[IN]] public_key ", public_key_x.data, 32);
1412 log_hexbuffer(
"encrypt_payment_id: [[IN]] secret_key ", secret_key_x.data, 32);
1413 this->controle_device->encrypt_payment_id(payment_id_x, public_key_x, secret_key_x);
1414 log_hexbuffer(
"encrypt_payment_id: [[OUT]] payment_id ", payment_id_x.data, 32);
1417 int offset = set_command_header_noopt(INS_STEALTH);
1422 this->send_secret((
unsigned char*)
secret_key.data, offset);
1424 memmove(&this->buffer_send[offset], payment_id.data, 8);
1427 this->buffer_send[4] = offset-5;
1428 this->length_send = offset;
1430 memmove(payment_id.data, &this->buffer_recv[0], 8);
1432 #ifdef DEBUG_HWDEVICE 1433 hw::ledger::check8(
"stealth",
"payment_id", payment_id_x.data, payment_id.data);
1442 const bool &need_additional_txkeys,
const std::vector<crypto::secret_key> &additional_tx_keys,
1443 std::vector<crypto::public_key> &additional_tx_public_keys,
1444 std::vector<rct::key> &amount_keys,
1448 #ifdef DEBUG_HWDEVICE 1449 const size_t &tx_version_x = tx_version;
1456 const boost::optional<cryptonote::account_public_address> change_addr_x = change_addr;
1458 const bool need_additional_txkeys_x = need_additional_txkeys;
1460 std::vector<crypto::secret_key> additional_tx_keys_x;
1461 for (
const auto k: additional_tx_keys) {
1465 std::vector<crypto::public_key> additional_tx_public_keys_x;
1466 std::vector<rct::key> amount_keys_x;
1472 log_hexbuffer(
"generate_output_ephemeral_keys: [[IN]] txkey_pub", txkey_pub_x.data, 32);
1473 log_hexbuffer(
"generate_output_ephemeral_keys: [[IN]] tx_key", tx_key_x.data, 32);
1477 log_hexbuffer(
"generate_output_ephemeral_keys: [[IN]] change_addr.view", (*change_addr_x).m_view_public_key.data, 32);
1478 log_hexbuffer(
"generate_output_ephemeral_keys: [[IN]] change_addr.spend", (*change_addr_x).m_spend_public_key.data, 32);
1481 log_message (
"generate_output_ephemeral_keys: [[IN]] need_additional_txkeys",
std::to_string(need_additional_txkeys_x));
1482 if(need_additional_txkeys_x) {
1483 log_hexbuffer(
"generate_output_ephemeral_keys: [[IN]] additional_tx_keys[oi]", additional_tx_keys_x[
output_index].data, 32);
1485 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,
1486 additional_tx_public_keys_x, amount_keys_x, out_eph_public_key_x);
1487 if(need_additional_txkeys_x) {
1488 log_hexbuffer(
"additional_tx_public_keys_x: [[OUT]] additional_tx_public_keys_x", additional_tx_public_keys_x.back().data, 32);
1490 if(tx_version > 1) {
1491 log_hexbuffer(
"generate_output_ephemeral_keys: [[OUT]] amount_keys ", (
char*)amount_keys_x.back().bytes, 32);
1493 log_hexbuffer(
"generate_output_ephemeral_keys: [[OUT]] out_eph_public_key ", out_eph_public_key_x.data, 32);
1500 if (need_additional_txkeys) {
1504 int offset = set_command_header_noopt(INS_GEN_TXOUT_KEYS);
1506 this->buffer_send[offset+0] = tx_version>>24;
1507 this->buffer_send[offset+1] = tx_version>>16;
1508 this->buffer_send[offset+2] = tx_version>>8;
1509 this->buffer_send[offset+3] = tx_version>>0;
1512 this->send_secret((
unsigned char*)tx_key.data, offset);
1514 memmove(&this->buffer_send[offset], txkey_pub.data, 32);
1529 bool is_change = (change_addr && dst_entr.
addr == *change_addr);
1530 this->buffer_send[offset] = is_change;
1536 this->buffer_send[offset] = need_additional_txkeys;
1539 if (need_additional_txkeys) {
1540 this->send_secret((
unsigned char*)additional_txkey.
sec.data, offset);
1542 memset(&this->buffer_send[offset], 0, 32);
1546 this->buffer_send[4] = offset-5;
1547 this->length_send = offset;
1551 unsigned int recv_len = this->length_recv;
1555 ASSERT_X(recv_len>=32,
"Not enought data from device");
1557 this->receive_secret((
unsigned char*)scalar1.data, offset);
1558 amount_keys.push_back(rct::sk2rct(scalar1));
1561 ASSERT_X(recv_len>=32,
"Not enought data from device");
1562 memmove(out_eph_public_key.data, &this->buffer_recv[offset], 32);
1566 if (need_additional_txkeys)
1568 ASSERT_X(recv_len>=32,
"Not enought data from device");
1569 memmove(additional_txkey.
pub.data, &this->buffer_recv[offset], 32);
1570 additional_tx_public_keys.push_back(additional_txkey.
pub);
1578 amount_keys.back(), out_eph_public_key);
1580 #ifdef DEBUG_HWDEVICE 1581 if(tx_version > 1) {
1583 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);
1585 if (need_additional_txkeys) {
1586 hw::ledger::check32(
"generate_output_ephemeral_keys",
"additional_tx_key", additional_tx_public_keys_x.back().data, additional_tx_public_keys.back().data);
1588 hw::ledger::check32(
"generate_output_ephemeral_keys",
"out_eph_public_key", out_eph_public_key_x.data, out_eph_public_key.data);
1595 const bool need_additional,
const size_t real_output_index,
1597 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));
1602 #ifdef DEBUG_HWDEVICE 1605 mask_x = this->controle_device->genCommitmentMask(AKout_x);
1609 int offset = set_command_header_noopt(INS_GEN_COMMITMENT_MASK);
1611 this->send_secret(AKout.
bytes, offset);
1613 this->buffer_send[4] = offset-5;
1614 this->length_send = offset;
1619 #ifdef DEBUG_HWDEVICE 1620 hw::ledger::check32(
"genCommitmentMask",
"mask", (
const char*)mask_x.
bytes, (
const char*)mask.
bytes);
1629 #ifdef DEBUG_HWDEVICE 1632 this->controle_device->ecdhEncode(unmasked_x, AKout_x, short_amount);
1635 int offset = set_command_header(INS_BLIND);
1637 this->buffer_send[offset] = short_amount?0x02:0x00;
1640 this->send_secret(AKout.
bytes, offset);
1648 this->buffer_send[4] = offset-5;
1649 this->length_send = offset;
1655 #ifdef DEBUG_HWDEVICE 1656 MDEBUG(
"ecdhEncode: Akout: "<<AKout_x);
1657 hw::ledger::check32(
"ecdhEncode",
"amount", (
char*)unmasked_x.
amount.
bytes, (
char*)unmasked.
amount.
bytes);
1658 hw::ledger::check32(
"ecdhEncode",
"mask", (
char*)unmasked_x.
mask.
bytes, (
char*)unmasked.
mask.
bytes);
1660 log_hexbuffer(
"Blind AKV input", (
char*)&this->buffer_recv[64], 3*32);
1669 #ifdef DEBUG_HWDEVICE 1672 this->controle_device->ecdhDecode(masked_x, AKout_x, short_amount);
1675 int offset = set_command_header(INS_UNBLIND);
1677 this->buffer_send[offset] = short_amount?0x02:0x00;
1680 this->send_secret(AKout.
bytes, offset);
1688 this->buffer_send[4] = offset-5;
1689 this->length_send = offset;
1695 #ifdef DEBUG_HWDEVICE 1696 MDEBUG(
"ecdhEncode: Akout: "<<AKout_x);
1698 hw::ledger::check32(
"ecdhDecode",
"mask", (
char*)masked_x.
mask.
bytes,(
char*) masked.
mask.
bytes);
1704 bool device_ledger::mlsag_prehash(
const std::string &blob,
size_t inputs_size,
size_t outputs_size,
1708 unsigned int data_offset, C_offset, kv_offset, i;
1711 #ifdef DEBUG_HWDEVICE 1713 size_t inputs_size_x = inputs_size;
1714 size_t outputs_size_x = outputs_size;
1718 this->controle_device->mlsag_prehash(blob_x, inputs_size_x, outputs_size_x, hashes_x, outPk_x, prehash_x);
1722 this->key_map.log();
1728 int offset = set_command_header(INS_VALIDATE, 0x01, 0x01);
1730 this->buffer_send[offset] = (inputs_size == 0)?0x00:0x80;
1735 this->buffer_send[offset] = data[0];
1740 while (data[data_offset]&0x80) {
1741 this->buffer_send[offset] = data[data_offset];
1745 this->buffer_send[offset] = data[data_offset];
1749 this->buffer_send[4] = offset-5;
1750 this->length_send = offset;
1756 for ( i = 0; i < inputs_size; i++) {
1757 offset = set_command_header(INS_VALIDATE, 0x01, i+2);
1759 this->buffer_send[offset] = (i==inputs_size-1)? 0x00:0x80;
1762 memmove(this->buffer_send+offset, data+data_offset,32);
1766 this->buffer_send[4] = offset-5;
1767 this->length_send = offset;
1773 kv_offset = data_offset;
1775 C_offset = kv_offset+ (8)*outputs_size;
1777 C_offset = kv_offset+ (32+32)*outputs_size;
1779 for ( i = 0; i < outputs_size; i++) {
1783 found = this->key_map.find(outPk[i].
dest, outKeys);
1788 offset = set_command_header(INS_VALIDATE, 0x02, i+1);
1790 this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
1794 this->buffer_send[offset] = outKeys.is_subaddress;
1797 this->buffer_send[offset] = outKeys.is_change_address;
1800 memmove(this->buffer_send+offset, outKeys.Aout.bytes, 32);
1803 memmove(this->buffer_send+offset, outKeys.Bout.bytes, 32);
1806 this->send_secret(outKeys.AKout.bytes, offset);
1809 memmove(this->buffer_send+offset, data+C_offset,32);
1814 memset(this->buffer_send+offset, 0, 32);
1817 memset(this->buffer_send+offset, 0, 32);
1818 memmove(this->buffer_send+offset, data+kv_offset,8);
1823 memmove(this->buffer_send+offset, data+kv_offset,32);
1827 memmove(this->buffer_send+offset, data+kv_offset,32);
1832 this->buffer_send[4] = offset-5;
1833 this->length_send = offset;
1836 #ifdef DEBUG_HWDEVICE 1837 log_hexbuffer(
"Prehash AKV input", (
char*)&this->buffer_recv[64], 3*32);
1842 C_offset = kv_offset;
1843 for (i = 0; i < outputs_size; i++) {
1844 offset = set_command_header(INS_VALIDATE, 0x03, i+1);
1846 this->buffer_send[offset] = 0x80 ;
1849 memmove(this->buffer_send+offset, data+C_offset,32);
1853 this->buffer_send[4] = offset-5;
1854 this->length_send = offset;
1859 offset = set_command_header_noopt(INS_VALIDATE, 0x03, i+1);
1867 this->buffer_send[4] = offset-5;
1868 this->length_send = offset;
1873 #ifdef DEBUG_HWDEVICE 1874 hw::ledger::check32(
"mlsag_prehash",
"prehash", (
char*)prehash_x.
bytes, (
char*)prehash.
bytes);
1885 #ifdef DEBUG_HWDEVICE 1894 int offset = set_command_header_noopt(INS_MLSAG, 0x01);
1899 this->send_secret(xx.
bytes, offset);
1901 this->buffer_send[4] = offset-5;
1902 this->length_send = offset;
1906 this->receive_secret(
a.bytes, offset);
1913 #ifdef DEBUG_HWDEVICE 1919 hw::ledger::check32(
"mlsag_prepare",
"AG", (
char*)aG_x.
bytes, (
char*)aG.
bytes);
1920 hw::ledger::check32(
"mlsag_prepare",
"aHP", (
char*)aHP_x.
bytes, (
char*)aHP.
bytes);
1921 hw::ledger::check32(
"mlsag_prepare",
"II", (
char*)II_x.
bytes, (
char*)II.
bytes);
1931 #ifdef DEBUG_HWDEVICE 1936 send_simple(INS_MLSAG, 0x01);
1939 this->receive_secret(
a.bytes, offset);
1942 #ifdef DEBUG_HWDEVICE 1945 hw::ledger::check32(
"mlsag_prepare",
"AG", (
char*)aG_x.
bytes, (
char*)aG.
bytes);
1955 #ifdef DEBUG_HWDEVICE 1956 const rct::keyV long_message_x = long_message;
1958 this->controle_device->mlsag_hash(long_message_x, c_x);
1961 cnt = long_message.size();
1962 for (
size_t i = 0; i<cnt; i++) {
1963 int offset = set_command_header(INS_MLSAG, 0x02, i+1);
1965 this->buffer_send[offset] =
1966 (i==(cnt-1))?0x00:0x80;
1969 memmove(this->buffer_send+offset, long_message[i].bytes, 32);
1972 this->buffer_send[4] = offset-5;
1973 this->length_send = offset;
1979 #ifdef DEBUG_HWDEVICE 1980 hw::ledger::check32(
"mlsag_hash",
"c", (
char*)c_x.
bytes, (
char*)c.
bytes);
1994 #ifdef DEBUG_HWDEVICE 1998 const int rows_x =
rows;
1999 const int dsRows_x = dsRows;
2001 this->controle_device->mlsag_sign(c_x, xx_x, alpha_x, rows_x, dsRows_x, ss_x);
2004 for (
size_t j = 0; j < dsRows; j++) {
2005 int offset = set_command_header(INS_MLSAG, 0x03, j+1);
2007 this->buffer_send[offset] = 0x00;
2008 if (j==(dsRows-1)) {
2009 this->buffer_send[offset] |= 0x80;
2013 this->send_secret(xx[j].bytes, offset);
2015 this->send_secret(alpha[j].bytes, offset);
2017 this->buffer_send[4] = offset-5;
2018 this->length_send = offset;
2022 memmove(ss[j].bytes, &this->buffer_recv[0], 32);
2025 for (
size_t j = dsRows; j <
rows; j++) {
2029 #ifdef DEBUG_HWDEVICE 2030 for (
size_t j = 0; j <
rows; j++) {
2031 hw::ledger::check32(
"mlsag_sign",
"ss["+
std::to_string(j)+
"]", (
char*)ss_x[j].bytes, (
char*)ss[j].bytes);
2038 bool device_ledger::close_tx() {
2040 send_simple(INS_CLOSE_TX);
2043 this->tx_in_progress =
false;
2053 #ifdef DEBUG_HWDEVICE 2057 int offset = set_command_header_noopt(INS_TX_PREFIX_START);
2059 this->buffer_send[offset+0] = tx.
version>>24;
2060 this->buffer_send[offset+1] = tx.
version>>16;
2061 this->buffer_send[offset+2] = tx.
version>>8;
2062 this->buffer_send[offset+3] = tx.
version>>0;
2071 size = tx.
vin.size();
2072 this->buffer_send[offset+0] = size>>24;
2073 this->buffer_send[offset+1] = size>>16;
2074 this->buffer_send[offset+2] = size>>8;
2075 this->buffer_send[offset+3] = size>>0;
2078 this->buffer_send[4] = offset-5;
2079 this->length_send = offset;
2082 #ifdef DEBUG_HWDEVICE 2083 hex_tx += boost::algorithm::hex(
std::string(reinterpret_cast<char const*>(this->buffer_recv), this->length_recv));
2086 for(
size_t i = 0; i < tx.
vin.size(); ++i) {
2087 offset = set_command_header_noopt(INS_TX_PREFIX_INPUTS);
2089 uint64_t amount = boost::get<cryptonote::txin_to_key>(tx.
vin[i]).amount;
2090 uint64_t key_offset = boost::get<cryptonote::txin_to_key>(tx.
vin[i]).key_offsets[0];
2093 this->buffer_send[offset+0] = amount>>56;
2094 this->buffer_send[offset+1] = amount>>48;
2095 this->buffer_send[offset+2] = amount>>40;
2096 this->buffer_send[offset+3] = amount>>32;
2097 this->buffer_send[offset+4] = amount>>24;
2098 this->buffer_send[offset+5] = amount>>16;
2099 this->buffer_send[offset+6] = amount>>8;
2100 this->buffer_send[offset+7] = amount>>0;
2104 this->buffer_send[offset+0] = key_offset>>24;
2105 this->buffer_send[offset+1] = key_offset>>16;
2106 this->buffer_send[offset+2] = key_offset>>8;
2107 this->buffer_send[offset+3] = key_offset>>0;
2110 memmove(this->buffer_send+offset, k_image.data, 32);
2113 this->buffer_send[4] = offset-5;
2114 this->length_send = offset;
2117 #ifdef DEBUG_HWDEVICE 2118 hex_tx += boost::algorithm::hex(
std::string(reinterpret_cast<char const*>(this->buffer_recv), this->length_recv));
2122 offset = set_command_header_noopt(INS_TX_PREFIX_OUTPUTS_SIZE);
2124 size = tx.
vout.size();
2125 this->buffer_send[offset+0] = size>>24;
2126 this->buffer_send[offset+1] = size>>16;
2127 this->buffer_send[offset+2] = size>>8;
2128 this->buffer_send[offset+3] = size>>0;
2131 this->buffer_send[4] = offset-5;
2132 this->length_send = offset;
2135 #ifdef DEBUG_HWDEVICE 2136 hex_tx += boost::algorithm::hex(
std::string(reinterpret_cast<char const*>(this->buffer_recv), this->length_recv));
2142 for(
size_t i = 0; i < tx.
vout.size(); ++i) {
2143 offset = set_command_header_noopt(INS_TX_PREFIX_OUTPUTS);
2149 this->buffer_send[offset+0] = amount>>56;
2150 this->buffer_send[offset+1] = amount>>48;
2151 this->buffer_send[offset+2] = amount>>40;
2152 this->buffer_send[offset+3] = amount>>32;
2153 this->buffer_send[offset+4] = amount>>24;
2154 this->buffer_send[offset+5] = amount>>16;
2155 this->buffer_send[offset+6] = amount>>8;
2156 this->buffer_send[offset+7] = amount>>0;
2159 memmove(this->buffer_send+offset,
key.data, 32);
2171 this->buffer_send[4] = offset-5;
2172 this->length_send = offset;
2175 #ifdef DEBUG_HWDEVICE 2176 hex_tx += boost::algorithm::hex(
std::string(reinterpret_cast<char const*>(this->buffer_recv), this->length_recv));
2181 offset = set_command_header_noopt(INS_TX_PREFIX_EXTRA);
2184 size = tx.
extra.size();
2185 this->buffer_send[offset+0] = size>>24;
2186 this->buffer_send[offset+1] = size>>16;
2187 this->buffer_send[offset+2] = size>>8;
2188 this->buffer_send[offset+3] = size>>0;
2191 memmove(this->buffer_send+offset, tx.
extra.data(), size);
2194 this->buffer_send[4] = offset-5;
2195 this->length_send = offset;
2198 memmove(&tx_prefix_hash, &this->buffer_recv[0], 32);
2200 #ifdef DEBUG_HWDEVICE 2201 hex_tx += boost::algorithm::hex(
std::string(reinterpret_cast<char const*>(this->buffer_recv), this->length_recv));
2204 offset = set_command_header_noopt(INS_TX_PROMPT_FEE);
2205 this->buffer_send[4] = offset-5;
2206 this->length_send = offset;
2209 offset = set_command_header_noopt(INS_TX_PROMPT_AMOUNT);
2210 this->buffer_send[4] = offset-5;
2211 this->length_send = offset;
2223 int offset = set_command_header_noopt(INS_HASH_TO_SCALAR_INIT);
2224 this->buffer_send[4] = offset-5;
2225 this->length_send = offset;
2228 for(
size_t i = 0; i < pubs_count; ++i) {
2229 offset = set_command_header_noopt(INS_HASH_TO_SCALAR_BATCH);
2231 memmove(this->buffer_send+offset,
buf->ab[i].a.data, 32);
2233 memmove(this->buffer_send+offset,
buf->ab[i].b.data, 32);
2236 this->buffer_send[4] = offset-5;
2237 this->length_send = offset;
2241 offset = set_command_header_noopt(INS_HASH_TO_SCALAR);
2242 this->buffer_send[4] = offset-5;
2243 this->length_send = offset;
2252 const std::vector<const crypto::public_key *> &pubsvector,
2257 size_t pubs_count = pubsvector.size();
2263 boost::shared_ptr<crypto::rs_comm>
buf(reinterpret_cast<crypto::rs_comm *>(malloc(
crypto::rs_comm_size(pubs_count))), free);
2265 local_abort(
"malloc failure");
2266 assert(sec_index < pubs_count);
2267 #if !defined(NDEBUG) 2269 for (i = 0; i < pubs_count; i++) {
2275 local_abort(
"invalid key image");
2279 buf->h = prefix_hash;
2280 for (i = 0; i < pubs_count; i++) {
2284 if (i == sec_index) {
2302 this->generate_key_image(*pubs[i], q_s,R_s);
2314 local_abort(
"invalid pubkey");
2326 sc_add(&sum, &sum, &sig[i].c);
2332 sc_sub(&sig[sec_index].c, &h, &sum);
2336 this->mulsub_eqx(sig[sec_index].r, sig[sec_index].c,
unwrap(sec),
unwrap(q_s));
2347 static device_ledger *legder_device = NULL;
2349 if (!legder_device) {
2350 legder_device =
new device_ledger();
2351 legder_device->set_name(
"Ledger");
2353 registry.insert(std::make_pair(
"Ledger", std::unique_ptr<device>(legder_device)));
2356 #else //WITH_DEVICE_LEDGER 2361 #endif //WITH_DEVICE_LEDGER
void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res)
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
int crypto_verify_32(const unsigned char *, const unsigned char *)
void derive_secret_key(const key_derivation &derivation, std::size_t output_index, const secret_key &base, secret_key &derived_key)
#define MINIMAL_APP_VERSION_MAJOR
#define MINIMAL_APP_VERSION_MINOR
CXA_THROW_INFO_T void(* dest)(void *))
void hash_to_ec(const crypto::public_key &key, crypto::ec_point &res)
void scalarmultKey(key &aP, const key &P, const key &a)
void log_hexbuffer(const std::string &msg, const char *buff, size_t len)
void sc_sub(unsigned char *, const unsigned char *, const unsigned char *)
virtual bool set_mode(device_mode mode)
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
void register_all(std::map< std::string, std::unique_ptr< device >> ®istry)
void generate_input_signature(const hash prefix_hash, const uint32_t input_index, const secret_key sec_view, const secret_key sec_spend, signature &sig)
bool operator==(const some_test_data &a, const some_test_data &b)
void ecdhEncode(ecdhTuple &unmasked, const key &sharedSec, bool v2)
void buffer_to_str(char *to_buff, size_t to_len, const char *buff, size_t len)
struct hash_func hashes[]
key genCommitmentMask(const key &sk)
bool generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation)
std::vector< uint8_t > extra
Archiver & operator &(Archiver &ar, Student &s)
std::vector< tx_out > vout
size_t rs_comm_size(size_t pubs_count)
const crypto::secret_key null_skey
Manages wallet operations. This is the most abstracted wallet class.
std::vector< txin_v > vin
crypto::public_key m_spend_public_key
void generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional< public_key > &B, const public_key &D, const secret_key &r, signature &sig)
crypto::public_key m_view_public_key
cryptonote::simple_wallet sw
bool derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &result)
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp)
void generate_ring_signature(const hash &prefix_hash, const key_image &image, const public_key *const *pubs, std::size_t pubs_count, const secret_key &sec, std::size_t sec_index, signature *sig)
device & get_device(const std::string &device_descriptor)
std::vector< ctkey > ctkeyV
void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *)
#define MINIMAL_APP_VERSION_MICRO
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *)
unsigned __int64 uint64_t
const char *const ELECTRONEUM_VERSION
secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key &recovery_key=secret_key(), bool recover=false)
void sc_0(unsigned char *)
void random_scalar(crypto::ec_scalar &res)
crypto::secret_key m_view_secret_key
void ecdhDecode(ecdhTuple &masked, const key &sharedSec, bool v2)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
account_public_address addr
void scalarmultBase(key &aG, const key &a)
account_public_address m_account_address
void decrypt(const void *ciphertext, size_t length, const uint8_t *key, const uint8_t *iv, char *plaintext, size_t *plaintext_len)
void get_transaction_prefix_hash(const transaction_prefix &tx, crypto::hash &h)
void hash_to_scalar(const void *data, std::size_t length, crypto::ec_scalar &res)
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s)
void * memcpy(void *a, const void *b, size_t c)
crypto::secret_key m_spend_secret_key
bool derive_public_key(const key_derivation &derivation, std::size_t output_index, const public_key &base, public_key &derived_key)
bool check_key(const public_key &key)
T & unwrap(mlocked< T > &src)
#define MINIMAL_APP_VERSION
connection< TProtocol > & operator=(const connection< TProtocol > &obj)
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)
int ge_frombytes_vartime(ge_p3 *, const unsigned char *)
void log_message(const std::string &msg, const std::string &info)
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
std::string to_string(t_connection_type type)
void sc_add(unsigned char *, const unsigned char *, const unsigned char *)
void * memmove(void *a, const void *b, size_t c)
void verbose(enum verbosity_value level, const char *format,...) ATTR_FORMAT(printf