@@ -191,7 +191,7 @@ namespace hw {
191191
192192 static int device_id = 0 ;
193193
194- #define PROTOCOL_VERSION 2
194+ #define PROTOCOL_VERSION 3
195195
196196 #define INS_NONE 0x00
197197 #define INS_RESET 0x02
@@ -228,6 +228,7 @@ namespace hw {
228228 #define INS_BLIND 0x78
229229 #define INS_UNBLIND 0x7A
230230 #define INS_GEN_TXOUT_KEYS 0x7B
231+ #define INS_PREFIX_HASH 0x7D
231232 #define INS_VALIDATE 0x7C
232233 #define INS_MLSAG 0x7E
233234 #define INS_CLOSE_TX 0x80
@@ -1346,6 +1347,81 @@ namespace hw {
13461347 return true ;
13471348 }
13481349
1350+ void device_ledger::get_transaction_prefix_hash (const cryptonote::transaction_prefix& tx, crypto::hash& h) {
1351+ AUTO_LOCK_CMD ();
1352+
1353+ int pref_length = 0 , pref_offset = 0 , offset = 0 ;
1354+
1355+ #ifdef DEBUG_HWDEVICE
1356+ crypto::hash h_x;
1357+ this ->controle_device ->get_transaction_prefix_hash (tx,h_x);
1358+ MDEBUG (" get_transaction_prefix_hash [[IN]] h_x/1 " <<h_x);
1359+ #endif
1360+
1361+ std::ostringstream s_x;
1362+ binary_archive<true > a_x (s_x);
1363+ CHECK_AND_ASSERT_THROW_MES (::serialization::serialize (a_x, const_cast <cryptonote::transaction_prefix&>(tx)),
1364+ " unable to serialize transaction prefix" );
1365+ pref_length = s_x.str ().size ();
1366+ // auto pref = std::make_unique<unsigned char[]>(pref_length);
1367+ auto uprt_pref = std::unique_ptr<unsigned char []>{ new unsigned char [pref_length] };
1368+ unsigned char * pref = uprt_pref.get ();
1369+ memmove (pref, s_x.str ().data (), pref_length);
1370+
1371+ offset = set_command_header_noopt (INS_PREFIX_HASH ,1 );
1372+ pref_offset = 0 ;
1373+ unsigned char v;
1374+
1375+ // version as varint
1376+ do {
1377+ v = pref[pref_offset];
1378+ this ->buffer_send [offset] = v;
1379+ offset += 1 ;
1380+ pref_offset += 1 ;
1381+ } while (v&0x80 );
1382+
1383+ // locktime as var int
1384+ do {
1385+ v = pref[pref_offset];
1386+ this ->buffer_send [offset] = v;
1387+ offset += 1 ;
1388+ pref_offset += 1 ;
1389+ } while (v&0x80 );
1390+
1391+ this ->buffer_send [4 ] = offset-5 ;
1392+ this ->length_send = offset;
1393+ this ->exchange_wait_on_input ();
1394+
1395+ // hash remains
1396+ int cnt = 0 ;
1397+ while (pref_offset < pref_length) {
1398+ int len;
1399+ cnt++;
1400+ offset = set_command_header (INS_PREFIX_HASH ,2 ,cnt);
1401+ len = pref_length - pref_offset;
1402+ // options
1403+ if (len > (BUFFER_SEND_SIZE -7 )) {
1404+ len = BUFFER_SEND_SIZE -7 ;
1405+ this ->buffer_send [offset] = 0x80 ;
1406+ } else {
1407+ this ->buffer_send [offset] = 0x00 ;
1408+ }
1409+ offset += 1 ;
1410+ // send chunk
1411+ memmove (&this ->buffer_send [offset], pref+pref_offset, len);
1412+ offset += len;
1413+ pref_offset += len;
1414+ this ->buffer_send [4 ] = offset-5 ;
1415+ this ->length_send = offset;
1416+ this ->exchange ();
1417+ }
1418+ memmove (h.data , &this ->buffer_recv [0 ], 32 );
1419+
1420+ #ifdef DEBUG_HWDEVICE
1421+ hw::ledger::check8 (" prefix_hash" , " h" , h_x.data , h.data );
1422+ #endif
1423+ }
1424+
13491425 bool device_ledger::encrypt_payment_id (crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) {
13501426 AUTO_LOCK_CMD ();
13511427
0 commit comments