Bitcoin Forum
May 29, 2024, 06:28:40 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: « 1 2 [3] 4 »
41  Bitcoin / Bitcoin Discussion / Re: [ANN] BitSafe Hardware Wallet Now Shipping on: March 14, 2013, 04:16:11 AM
is the firmware / source code posted somewhere like github or is it not developed yet??

I have been developing the firmware. You can get it from: https://github.com/someone42/hardware-bitcoin-wallet. It's in a state of flux, as the surrounding Bitcoin infrastructure changes. At the moment I'm working on implementing an interface based on protocol buffers, so that I can make it "Trezor compatible" (eg. see https://bitcointalk.org/index.php?topic=125383.0).

Can you explain how it works?  How do you use it?

Advantages over a mass market encrypted USB stick?

Here is an entirely fictitious depiction of what is possible:
  • You open multibit and plug the BitSafe into your computer. One of your greyed-out wallets becomes highlighted.
  • You navigate to bitmit.com, and purchase something for 1.815 BTC. Multibit handles the Bitcoin URI and gives you a payment prompt.
  • After approving multibit's payment prompt, a light flashes on the BitSafe and "Send 1.815 BTC to www.bitmit.net?" appears on the OLED display.
  • You press the "approve" button on the BitSafe and the relevant Bitcoin transaction propagates to the rest of the Bitcoin network.

During this story, there is no opportunity for malware to intercept your private keys. Private key storage and transaction signing is done entirely on the BitSafe. Malware does not even have the opportunity to redirect funds to another address; using a proposed payment protocol (see https://gist.github.com/gavinandresen/4120476), addresses and amounts are signed by the merchant (in this case www.bitmit.net), authenticated by the BitSafe and displayed on its OLED display.

It gets better than this. You could encrypt your wallet so that if you accidentally lose the BitSafe, any finders will have a harder time accessing your wallet. "Deluxe" versions of the BitSafe might include a USB port which will allow you plug in a USB keyboard. You could then enter passphrases without fear of (software) keyloggers. Maybe you could even use this keyboard to enter a brainwallet passphrase; the Deluxe BitSafe generates, uses, and erases the brainwallet independently of the host computer.

This looks like a great product.  I have only 1 question:

What happens to my keys & bitcoins if I loose the device or it stops working because my dog chewed on it?
Currently, the firmware implements a deterministic wallet based on the proposed BIP 0032 standard. So you would be able to do a wallet backup by writing a series of letters/numbers on a piece of paper. You would presumably place this paper in a physically secure location (eg. safe). If you lose the BitSafe or it breaks, you can entirely restore the wallet from this piece of paper.
42  Bitcoin / Project Development / Re: [Dead Project] Physical Bitcoin Wallet on: February 16, 2013, 12:58:19 AM
Submitted for your entertainment, one of my old projects back in May '12:

http://www.youtube.com/watch?v=bhWVv7_ecMY

The project is long since dead, since I got too busy to finish it.  Luckily it looks slush and stick announced a similar project a few months ago (Trezor), so at least the community can finally move past storing private keys on their PCs.

For the curious folks out there, this was built on an STM32F4 Discovery Kit.
Is there any chance you could open-source some of your contributions? For example, it looks like you did some significant work interfacing bitcoind with your wallet; as far as I know, no-one else has done that.

I understand that there may be licensing issues with some of the microcontroller code/libraries, but I think there's value in seeing your approach.
43  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: February 13, 2013, 02:17:48 PM
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.
44  Bitcoin / Project Development / Re: [ANN] BitSafe Hardware Wallet Development - $28.00 (Developers only) on: January 04, 2013, 11:06:00 AM
The different generators have their own advantages and disadvantages.

Could you please elaborate more on this topic? Just to make sure we are on the same page here ...

Here's my current understanding. It's subject to change, since analog circuits can work differently in the "real world" vs. theory.

Atmel CryptoAuthentication chip
Good: Tiny, integrated solution. This means board layout is easy (no touchy analog sections to worry about) and device size is a bit smaller. It is very likely to Just Work.
Bad: As slush has pointed out, Atmel don't say how it works. They say it's "high-quality" but don't justify it. There's no access to the raw samples, meaning that it could fail to produce enough real entropy, though it still outputs seemingly random bits.

Thermal noise source
Good: the existence of thermal noise is guaranteed by fundamental physics. The amplitude can be reasonably well estimated a priori. The particular design used (a differential amplifier) rejects common-mode noise somewhat. Noise characteristics are simple (white, Gaussian).
Bad: requires a lot of gain, which can provoke oscillation. High-valued resistors mean that it's sensitive to parasitic capacitance; this can cause bandwidth, unwanted feedback or (external) noise feedthrough problems. Requires board space for 3 op amps.

Zener noise source from zener diode
Good: components widely available. Requires less op amps than thermal noise source. Noise characteristics are probably distinctive, which makes it easier to distinguish zener noise from everything else.
Bad: noise amplitude is tiny, requiring even more gain than thermal noise source. Noise amplitude probably varies between components, complicating mass production. While zener noise is generally unavoidable, most manufacturers strive to reduce it.

Zener noise source from voltage reference
Good: Louder than zener diode. Probably more consistent than zener diode.
Bad: Once again, noise is usually unwanted by circuit designers, so chip designers try to minimise it. We had to look around for a chip which was noisy enough (the LM385 is used, which is an old chip). Voltage references aren't designed to be used as noise sources: they're designed to be used as voltage references. Slightly more expensive and bigger than zener diode.

Oh, I forgot this one: most microcontrollers have multiple independent oscillators (eg. crystal oscillator and internal RC oscillator). If both oscillators are run simultaneously, they will drift apart randomly. This drift can be measured using a suitable interrupt handler.

Drifting simultaneous oscillators
Good: you get it for "free": no external components required.
Bad: uncertain quality of random bits. Throughput is quite slow - last time I tried, I was only able to get a few hundred bits of (unknown quality) entropy per second.

Some resources:
The zener noise source circuit we borrowed from: https://mywebspace.wisc.edu/lnmaurer/web/minirng/RandomBit.jpg
Comparison of noise sources: http://ciphersbyritter.com/RADELECT/MEASNOIS/NOISMEA1.HTM
45  Bitcoin / Project Development / Re: Yet Another Hardware Wallet Proposal? on: January 03, 2013, 12:23:51 PM
The device should have enough CPU power maybe to do X.509 verification, or at least store public key hashes for existing merchants that are trusted, following the new Payment Protocol standard in development, or Protecting merchants from compromised webservers, or [PROPOSAL] Secure Payment Protocol. This would allow for swipe-style payments for merchants after the first TX.

Fourtunately, X.509 verification is feasible, even with low-end microcontrollers. The overwhelming majority of X.509 certificates use RSA. RSA signing is indeed difficult, but verification is much, much easier. I estimate that verification of a 2048 bit RSA certificate is no more difficult than ECDSA (using secp256k1) signing.

As a very rough estimate, a modern but low-end 32 bit microcontroller should be able to generate a ECDSA signature in < 0.5 s.
46  Bitcoin / Project Development / Re: [ANN] BitSafe Hardware Wallet Development - $28.00 (Developers only) on: January 03, 2013, 12:10:35 PM
2) This price does not include a PicKit 3 which is a must at this early level of development: $45.00 + Shipping
http://www.microchipdirect.com/ProductSearch.aspx?Keywords=PG164130

It is possible to avoid using a PicKit 3. If the dev board is loaded with an appropriate bootloader (eg. http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en554836), it should be possible to program the device using the on-board USB port.

What the PicKit3 is useful for, is if:
  • You want to develop or modify the bootloader itself (if you mess up the bootloader, you could brick the PIC32, in which case you need a PicKit3 to recover).
  • You want good integration with MPLAB.
  • You want to use debugging features like breakpoints, watches etc.

Also, looking at the BOM + schematic, I see the Atmel IC as RNG, so all of the 'Universal Hardware RNG' components would go away, correct? Or would it be an assembly option?

The story is: we had a few ideas for hardware random number generators (the Atmel chip, thermal noise, zener noise from zener, zener noise from voltage reference). Instead of choosing one, all of them were included. There are a bunch of 0 ohm resistors to facilitate switching between circuits. The different generators have their own advantages and disadvantages.
47  Bitcoin / Development & Technical Discussion / Re: Invoices/Payments/Receipts proposal discussion on: December 02, 2012, 08:58:52 AM
It might be worth supporting (or perhaps even demanding) an OCSP stapling-like mechanism for certificate revocation checks. This would place the burden of OCSP querying on the merchant, who is typically better equipped to perform such queries. It also scales better, is potentially more reliable and does not leak information to a 3rd party.
48  Bitcoin / Development & Technical Discussion / Re: Invoices/Payments/Receipts proposal discussion on: December 01, 2012, 06:27:29 AM
How will signed invoices work with offline wallets? I ask this in the context of dedicated hardware wallets, but this issue also applies to cold-storage wallets on computers intentionally disconnected from the Internet.

Theoretically, basic verification of a signature is feasible. As long as an offline device is seeded with a sufficient set of root certificates, it can verify a valid chain of certificates. However, there are problems with certificate revocation. Ideally, certificate verification should be accompanied by revocation checks. For an offline device, checks are very difficult.

I am aware that even with no revocation checking, the security of offline devices is significantly enhanced by signed invoices. But is it possible to do better than this?
49  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 21, 2012, 02:27:02 PM
Etotheipi, someone42, I'd like to know your opinion how to handle change addresses. There are basically two approaches:

a) When transaction is coming to self-address (validity can be verified by the device itself), hide output to change address from the user.
b) Show output to change address as normal output, it can be just displayed in slightly different way on the display.

ad a)
This is how bitcoin software is doing it now, although I don't like it much. User should see full information, otherwise there are some possible attacks. For example, by hiding change address from the UI, malicious (modified) software can send coins literally to /dev/null, by using some very high address vector for change address. Attacker don't take the money, but they're practically lost by the original owner.

ad b)
I see this approach as much safer. User see all outputs and it's only up to the desktop software to explain what's going up here. Change addresses are for example fully visible in Electrum and I don't think that people have any problem with it. Device still must support some kind of scrolling for multiple transaction outputs, so having one more output is not a problem.
I'm not so sure that displaying the change address deals with the "malicious send to /dev/null" attack described above. For example, say the device displays "change of 0.05581992 BTC was sent to 1HoYQQeA3BxWisDK3VtGFNbvnNPcoZTE5n". How do you even know whether that's a "genuine" change address?

Perhaps a better solution is to display the change address index instead. There is an immediately apparent difference between "change was sent to address 18" and "change was sent to address 1156397331". But will users understand this?

Another option is to require change addresses to be explicitly and sequentially generated by the wallet. However, this does require an internal counter that is incremented every time a change address is generated. The malicious change address attack is prevented because the wallet is presumably unable to generate millions of change addresses in any reasonable time.
50  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 21, 2012, 02:17:26 AM
I designed something similar for input transactions, I call it "input streaming". In this way device don't need to store all inputs in the memory so the device can sign transaction with unlimited counts of inputs.

Although very high count of inputs may happen naturally (like when people are consolidating tiny pool payouts), having so many output transactions isn't so common and usually such complex transaction can be split into more smaller txes. However I over-looked the case of multisig transactions, where having very high number of outputs may be required as well. I'll try to propose some solution for this case too. Thank you for pointing to the problem...
You can do this if you re-order the fields* in the protocol buffer messages to match the order of the Bitcoin protocol (inputs before outputs, previous output reference before input script etc.). Then, you send the entire transaction through once per required signature. Each time an output is encountered, you prompt the user about it. This is merely an extension of your "streaming" idea, but applied to the whole transaction.

You can probably see the problem with this: the user will be prompted repeatedly, for each required signature. This makes for an unnecessarily bad user experience. This is how I intend to deal with the problem in my implementation:
1. While processing the transaction, a hash for signing needs to be calculated. In addition to this "signing hash", calculate an "input invariant hash" which is just like the signing hash, except it ignores all input scripts.
2. The input invariant hash will be the same regardless of which input is being signed (that's why it's called the "input invariant hash").
3. If the user fully approves a transaction, save that transaction's input invariant hash.
4. Include a field in the SignTx message which specifies whether the required signature is for a repeat of the previous transaction.
5. If the host specifies that the transaction is repeated, do not prompt the user.
6. In order to stop the host from lying about the status of the repeated transaction, compare the input invariant hash of the current repeated transaction with the saved input invariant hash, returning a Failure message if there is a mismatch.

The host signs a series of inputs like this:
Code:
tx = build_transaction();
is_repeated = 0;
for each input_number_to_sign in inputs:
        SignTx(tx, input_number_to_sign, is_repeated);
        is_repeated = 1;

*This brings me to something which will probably be a non-issue, but we should be aware of: (according to https://developers.google.com/protocol-buffers/docs/encoding) field ordering in a protocol buffer message is not guaranteed. Every serialiser will write out fields in field number order, but certain operations may not preserve this ordering.
51  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 19, 2012, 01:29:32 PM
My only request is that, for all the non-signing messages, there is a maximum message size specified. A reasonable value would be something like 256 bytes. This allows buffers to be statically allocated (i.e. without the use of malloc). The limit cannot apply to signing messages, because transactions can be very large.

Hard-encoding maximum message size into the protocol sounds problematic. It already requires hacks for message signing, so you still need some workaround in the code. Why to limit other messages then?

PB message can be decoded in smaller chunks, i.e. you don't need to allocate receiving buffer to fit whole message into it.
After having a closer look at nanopb's API, I withdraw any request for limited sizes of messages or fields. It is indeed possible to decode smaller chunks of messages. There is even a mechanism to decode smaller chunks of individual fields.
52  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 07:25:30 PM
Forking protocol buffer standard? No way, at least not for me :-).
I'm not aware of any standard saying that protobuf parsers must skip unrecognised fields. In fact, modifying a parser to fail on unrecognised fields would make things more secure: it would protect against client software accidentally using an unsupported feature and then misleadingly reporting success to a user.

I'm affraid of "partial support" of some features. Once you support OTP/PIN messages or not. I'm writing test suite which should cover 100 % of device use cases, so I believe this test suite will help developers to be sure all "features" are well implemented.

It should not report support for some feature which is not fully implemented. As I said, we're handling with valuable information and we should not try to recover from unexpected state by heuristic or some guessing.
I agree that supporting OTP and PIN is a yes or no thing. But sometimes it is not so clear, and we can't anticipate what advanced features might be added to wallets in the future.

The ignore-on-0 convention would not encourage "unexpected state", as long as 0/false/"" is always defined to mean that a feature is disabled. For example, say an "is_hidden" field is added to the LoadDevice message. Wallets which do not support hidden volumes can safely ignore is_hidden = false. If such a wallet ever gets a message with is_hidden = true, it fails with a "feature unsupported" failure message.

Such a convention is safely used in microcontrollers, where reserved bits in peripheral hardware registers are often supposed to be set to 0. Then, if features are added to those registers, the designers will take 0 to mean disabled and 1 to mean enabled.

Edit: Here's a compromise: if a wallet sees an unrecognised field, it always fails with "feature unsupported", no matter what the value of the field. All new fields must be optional. If client software doesn't want to use a new feature, it must not include the corresponding fields.
53  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 06:31:34 PM
I would like to propose the convention that if the wallet sees a field in a protocol buffer that it does not recognise, if that field is 0, false or "" (depending on the type of the field), the wallet can safely ignore the field. On the other hand, if an unrecognised field contains something other than 0, false or "", a wallet must not ignore the field and must return a "feature not supported" failure message. This convention makes it easier to add additional fields in the future.

As it stands, nanopb currently doesn't allow this (it skips all fields it doesn't recognise). But I'm sure it's possible to modify the runtime decoder to follow this convention.

I see the approach slush has taken is to include a "Features" message which enumerates a wallet's features. I think a features list is somewhat open to interpretation. For example, what happens if a wallet only supports a subset of feature X? Does it report that it supports feature X or not? Another advantage of the ignore-on-zero convention is that client software doesn't have to put as many ifs all over the place - "feature not supported" is handled like any other wallet error.
54  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 04:13:01 PM
Checksum and Chunking/ Dechunking
Does the bytestream for USB have guaranteed integrity ?  IE is it necessary to have a checksum for each of the 64 byte message or is that taken care of in the transport protocol ? If required we could simply have 1 checksum byte = XOR(payload bytes) i.e.

1B = payload length
up to 62B = payload
1B = checksum defined as XOR(payload)

Also, you state that the PB message is chunked into 64 byte packets. When they are 'dechunked' how do you know the boundaries of the packets to stitch them back together to recreate the PB messages? Do you need "this protobuf message is chunked over X packets' at the beginning of the PB message.

I am just thinking of how to make the 'chunking' and 'dechunking' as simple and unambigous as possible. Ideally you want it a dumb transport layer that understands nothing of what is in the messages.
USB does have some error checking (one CRC16 per packet), so there's probably no need for us to implement it anywhere.

As for how to determine the packet boundaries, protocol buffers appear to lack a terminator. So length information must be out of band:
1. One option is to include the length of the packet somewhere. For example, the length (eg. as a packed, little-endian 32 bit integer) can be prepended to the protocol buffer.
2. Another option is to rely on the chunk lengths. When you see a chunk with less than 63 bytes of payload, you know it's the end. Note that if the packet length is a multiple of 63, to avoid confusion, an extra 0-payload packet needs to be sent as well.

Lastly, a bit of detail: how is the message type sent? A single byte prepended to the protocol buffer will do; but does anyone have a better solution?
55  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 12:48:35 PM
FTDI don't work in Windows out of the box and the installation is a bit weird. I spent some time to get my BFL Single working on Win7 :-/.

We want to use USB-to-serial for the Raspberry Pi shield (as RPi don't have usable USB port for HID device), too. But from the computer side I think there should be just one supported transport - USB HID.
I was mistaken about FTDI drivers on Windows.

Looks like it is USB HID then.
56  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 12:31:06 PM
I want to use HID protocol just like a transport for higher level protocol, instead of using some custom binary format. No, I'm not going to propose JSON-RPC at this time :-), but I think Protocol Buffers is a good choice. There exists some lightweight implementations for microcontrollers, it is super-easy to use PB from every major programming language and it is well defined high level protocol (in comparsion to some custom-built protocol on top of HID messages).
I was going to come here and whinge about your choice of protocol buffers, but after a bit more research, I'm liking them more. Their encoding is quite lean; I was worried that it would be like XML. Also, there are tiny parser libraries (eg. nanopb) written in C out there.

So now I think it's a good idea to use protocol buffers. My only request is that, for all the non-signing messages, there is a maximum message size specified. A reasonable value would be something like 256 bytes. This allows buffers to be statically allocated (i.e. without the use of malloc). The limit cannot apply to signing messages, because transactions can be very large.
57  Bitcoin / Development & Technical Discussion / Re: Hardware wallet wire protocol on: November 16, 2012, 12:17:20 PM
My current proposal is to use generic class USB HID device, which can be used without installation of drivers across every major operating systems (especially MS Windows). There are some limitations, like 64 bytes of message payload and communication can be initiated only by the computer (polling).
I'm don't mind which USB class device is used. I think the primary criteria is how easy it is to work with the most common combinations of programming languages and operating systems (which unfourtunately is a lot of combinations). The only other appropriate USB classes I can think of are HID and CDC (i.e. a serial port).

There are problems (you appear to be aware of them as well) with USB serial ports in Windows, notably the need to supply a .inf, and the bugginess of usbser.sys. I was going to work around these problems by instead emulating a FTDI USB-to-serial chip. Every major operating system has reliable drivers for the FTDI chips included, and the protocol seems quite simple (from looking at the Linux driver sources).

The advantages of implementing a serial port are:
  • Easy to work with; often OSes allow you to treat them as a non-seekable file.
  • It's possible to use common terminal programs to do debugging or firmware updating.
There's one major disadvantage: device discovery is hard. There's no easy, portable way to "know" what a serial port is connected to without sending something and waiting for the correct response.

I think USB HID is a good choice. Advantages:
  • Allows you to choose a VID/PID (the FTDI emulation solution above requires you to use an FTDI VID/PID).
  • Easy device discovery; just query the product descriptor string.
The only disadvantage I've come across in my research: apparently, in Linux, you need to detach a kernel driver in order to properly communicate with a HID class device. This can be done on most systems, but I worry that it will break on some Linux configurations. Please correct me if the situation is different now.
58  Bitcoin / Bitcoin Technical Support / Re: Estimating Transaction Size (in bytes) on: November 15, 2012, 01:31:03 PM
According to the transaction fee rules, the size of the transaction is used to calculate fees (https://en.bitcoin.it/wiki/Transaction_fees).  From what I've read elsewhere, the size of the tx will be: 180 bytes per input + 34 bytes per output + 10 bytes.

However, while I've found that calculation to hold up most of the time, it doesn't seem to be accurate all of the time.  Is there a more reliable way to know how large a transaction will be so that appropriate fees can be assigned when creating a raw transaction?
As lile has pointed out, the size of signatures can vary.

In particular, for uncompressed public keys, there is:
  • a 25% chance each input is 179 bytes or smaller,
  • a 50% chance each input is 180 bytes,
  • a 25% chance each input is 181 bytes.
However, what makes a bigger difference is that if compressed public keys are used, each input is 32 bytes smaller.

If you want to set a conservative limit, 181 bytes per input + 34 bytes per output + 10 bytes seems like a good bet. This limit only applies to reasonably-sized (< 253 inputs and outputs) and standard (one signature required) transactions.
59  Bitcoin / Hardware wallets / Re: [ANN] Hardware wallet project on: November 13, 2012, 04:02:12 PM
And this is the main problem. You need whole raw transaction in the memory to calculate sha256 for tx_hash. And size of raw tx is growing lineary with number of inputs.
I wasn't very clear on the description of my method, but every hash can be calculated without having any transaction entirely in RAM.

I "found" following algorithm:

1. Client sends SignTx message with the list of outputs to the device.
2. Device displays outputs and amounts on the display, waiting for confirmation by the user.
3. Client start sending TxInput messages. For N inputs, client send N^2+N messages, like in this pseudocode:

Code:
inputs = [] # list of TxInput
for i in inputs:
    for x in inputs:
        send(x) # Sends TxInput to the device
        
    signature = send(SignInput(i)) # Ask for input signature after X inputs

Thanks to this and thanks to streaming capabilities of SHA256, it is possible to check inputs and build tx_hash without a need to store raw transaction in device memory at all. There's some minor overhead in the API and the API don't looks so nice because it resends TxInputs over and over, but memory footprint is extremely low.
You can go even further than this. If you send the entire serialised spending transaction once for each TxInput, you don't even need to store outputs. You can then have essentially unlimited inputs and outputs.
60  Bitcoin / Hardware wallets / Re: [ANN] Hardware wallet project on: November 13, 2012, 11:07:28 AM
This is definitely interesting topic to think about. I think the device will have some known hard limit of inputs and outputs, depending on used chip and amount of available RAM. This information can be provided over the API (message Features?), so desktop client will have a chance to handle it properly (offer to split transaction to more smaller ones, for example).

But maybe we find some algorithm how to do signing in some streaming way so the device won't need to have everything loaded into the memory at a time...

FWIW, here's approximately the method I use:
1. Supporting transactions (i.e. transactions whose outputs are being spent) precede the spending transaction in the data stream.
2. Supporting transactions are serialised as they would be in the blockchain.
3. The spending transaction is serialised as it would be in OP_CHECKSIG (with all inputs removed except for the signing input, which has its script replaced).
4. Before each supporting transaction, the output number of the output being spent is explicitly specified.

This allows the bunch of supporting and spending transactions to be parsed by a streaming parser. Each output in the spending transaction can be displayed and approved as it is parsed.

The supporting transactions are there to calculate the transaction fee. The parser does this to calculate the transaction fee:
1. For each supporting transaction, the hash of the transaction, tx_hash, is calculated.
2. For each supporting transaction, the nominated output (from (4) above) has its amount added to the transaction fee.
3. The list of tx_hash and output numbers is itself hashed into ref_hash_compare.
4. When the parser sees the spending transaction, it takes the list of input reference transaction hashes and input reference numbers and hashes them into ref_hash. ref_hash should == ref_hash_compare. This step is necessary to confirm that the correct supporting transactions are being included.
5. For each output in the spending transaction, the output amount is subtracted from the transaction fee.

BIP 0010 is relevant to this discussion. What do you think of BIP 0010? It might be a good idea to talk to etotheipi about it, if you haven't already.
Pages: « 1 2 [3] 4 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!