Bitcoin Forum
December 14, 2024, 11:01:09 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 2 3 4 [5]  All
  Print  
Author Topic: Hardware wallet wire protocol  (Read 8761 times)
slush (OP)
Legendary
*
Offline Offline

Activity: 1386
Merit: 1097



View Profile WWW
November 22, 2012, 12:12:04 PM
 #81

After quick brainstorming with Stick we've composed following interaction diagram of transaction signing: signtx_workflow.pdf

The purpose of this is to stream everything, to minimize RAM requirements for the device.

Basic description is:
a) Device receives SignTx message, which contains mainly count of inputs and outputs.
b) Device asks for inputs and outputs in separate messages.
c) Every output is confirmed by the user.
d) In first iteration, device computes hash of outputs and blank inputs (without scripts).
e) After first iteration, signature of first input is generated and returned back to computer.
f) In every next iteration, device compare hashed outputs with the hash built during first iteration (which has been confirmed by the user).
g) Every iteration produces exactly one input signature.

slush (OP)
Legendary
*
Offline Offline

Activity: 1386
Merit: 1097



View Profile WWW
November 23, 2012, 01:23:15 PM
 #82

Here's what I'm getting at:  BIP 32 allows for random access to any address, but it also specifies using a separate subchain for change addresses (the "internal" subchain).  This may have been overlooked by you early on for simplicity reasons, but it is part of the spec.

I focused to change addresses in BIP32 proposal and everything I see is that (simplified=) "it is possible to use internal chain for change addresses", however it's not a requirement, so device also should not enforce it. When user wants to use multiple chains for multiple offices to keep their balances separate, he'll probably want to use multiple internal chains for change addresses as well...

etotheipi
Legendary
*
expert
Offline Offline

Activity: 1428
Merit: 1093


Core Armory Developer


View Profile WWW
November 23, 2012, 02:53:06 PM
 #83

Here's what I'm getting at:  BIP 32 allows for random access to any address, but it also specifies using a separate subchain for change addresses (the "internal" subchain).  This may have been overlooked by you early on for simplicity reasons, but it is part of the spec.

I focused to change addresses in BIP32 proposal and everything I see is that (simplified=) "it is possible to use internal chain for change addresses", however it's not a requirement, so device also should not enforce it. When user wants to use multiple chains for multiple offices to keep their balances separate, he'll probably want to use multiple internal chains for change addresses as well...

My point was not that you should use it, for fun, but because using it might make the "what if offline tx uses change address 1e7?" problem a bit easier.  The online computer could hand out millions of addresses on the external chain, but the number of addresses used on the internal chain will be strictly limited.

However, if the private keys are distributed across multiple devices, it's not quite so simple...

Founder and CEO of Armory Technologies, Inc.
Armory Bitcoin Wallet: Bringing cold storage to the average user!
Only use Armory software signed by the Armory Offline Signing Key (0x98832223)

Please donate to the Armory project by clicking here!    (or donate directly via 1QBDLYTDFHHZAABYSKGKPWKLSXZWCCJQBX -- yes, it's a real address!)
thezerg
Legendary
*
Offline Offline

Activity: 1246
Merit: 1010


View Profile
November 24, 2012, 03:59:37 AM
 #84

Seems like we should start really simple targeted for the smallest USB device, like the cypress CY7C64316. 

Define a protocol that could sign a bunch of outputs; and not even keep track of the act balance.

Base it off of a "transport" that consists of 2 APIs:

send(buffer, length)
recv(buffer,length)

because any underlying transport can implement these 2.


Then additional protocol functionality can be layered on top (to support more advanced HW wallets)... and additional transports can be layered below.

In a related note, is there any web service that will just post an arbitrary bitcoin TXN to the network based on some RESTful probably binary-coded API?

someone42
Member
**
Offline Offline

Activity: 78
Merit: 11

Chris Chua


View Profile
February 13, 2013, 02:17:48 PM
 #85

Here are some of my findings regarding USB HID-based communication. Perhaps they will be useful to anyone else working on interfacing with hardware wallets.

  • The maximum throughput I've seen in either direction when using HIDAPI is 31500 bytes/s. This is fast enough to transfer most Bitcoin transactions instantly (from a user's perspective), but it is less than 3% of full-speed USB maximum throughput.
  • There needs to be a way to identify hardware wallets. HIDAPI's hid_enumerate() function gives you a list of HID devices, but it includes things like keyboards and mice. USB device properties which HIDAPI can query include: vendor ID, product ID, manufacturer string, product string and serial number. Identification via. vendor/product ID is probably not a good idea because they're constrained by other factors.
  • The latest version of HIDAPI available on https://github.com/signal11/hidapi/downloads (v0.7.0) is quite outdated. It has issues on Windows relating to report sizes (see https://github.com/signal11/hidapi/pull/28).
  • For the CP2110-based protocol that slush has proposed, a long, repetitive HID report descriptor is required.
  • On the device side, things are complicated by the fact that the HID specification allows reports to be sent/received from both the control endpoint and an interrupt endpoint. Both these methods have their own subtleties.

Some Windows XP-specific things:
  • Windows will refuse to enumerate your HID device unless it provides a valid report descriptor. Windows will refuse to process reports unless that report is correctly described in the report descriptor. This is why that "long, repetitive HID report descriptor" is not just a good idea - it seems to be required for the interface to work at all.
  • Upon success, HIDAPI's hid_read() always returns the size of the largest report, even if a smaller report was received. So its return value should be ignored and the report ID (first byte) should be used to determine the report size.
  • Windows will eat up received reports even if hid_read() isn't being called.

Some Linux-specific things:
  • HIDAPI provides two backends: one based on the hidraw kernel driver, and one based on libusb-1.0. Certain kernel versions have some hidraw bugs.
  • No matter what backend is used, access to a USB HID device requires root permissions. Alternatively, udev rules can be used to whitelist certain devices. Care must be taken to write the whitelist filter so that it includes all hardware wallets.
  • By default, when a USB HID device is plugged in, the hidraw driver will use "get report" control requests, presumably to initialise its view of the state of the device. This can end up eating up the first byte sent from the hardware wallet.
Pages: « 1 2 3 4 [5]  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!