About three months ago I first heard about IOTA and I really liked it. However, it is still in a very early beta stage, and lots of improvements still need to be built. One of the missing features at the moment is an offline wallet.
Another project I started with my brother a little over four months ago was to built our very own trezors. We discovered that trezor makes all their software and hardware open source. It seemed like a cool idea to order some PCB’s and components and construct our very own trezors for lower cost. Also, the device is built around an STM32, which I’ve covered many times before on my website. It did not seem to difficult to make modifications to the firmware.
The schematics and board layout for a trezor are available on Github. However, R6 on this schematic shoud not be placed! Initially we had this resistor on the board, but that gives a lot of trouble with the USB discovery, especially on Windows. The standard board layout provides a breakout for the ST-Link programmer:
For this development board, I did want to have some flexibility with the bootloader. By default, the trezor bootloader makes sure that the bootloader cannot be erased by enabling write protection. I disabled this for my development board. Also, it checks the signature of the firmware which I am skipping at the moment.
IOTA Seed generation from 24 words mnemonic
By default, the trezor uses a 24 words mnemonic which deterministically generates addresses for various crypto’s. The trezor internally generates a 64-byte long ‘seed’ according to the BIP-0039 standard. IOTA seeds consist of 81 trytes. Deterministic conversions can done between 81 trytes and 48 bytes. Kerl actually does this exactly. But 48 bytes is not 64 bytes, but 3/4 of 64 bytes. I implemented a simple algorithm that chops the 64 bytes from the mnemonic into 4 48-byte arrays. These are then absorbed by kerl and in the end the deterministic seed is squeezed out.
 I got some useful feedback on this. I will change the method to implement BIP-0032 and BIP-0044.
Interaction with IOTA functions on the trezor
At the moment, I only implemented function calls using trezorctl, which is a python script. The basic functions at the moment are:
trezorctl iota_get_address [-i <seed_index>] trezorctl iota_show_seed trezorctl iota_sign_transaction -a <receiving_address> -b <balance> -v <transfer_value>
Address generation and transaction signing
The generation of public addresses is probably the slowest. Each address takes about 12 seconds to generate. Therefore, once the public address is generated, it is stored in the trezors flash memory.
Transaction signing is very basic at the moment. It makes the following assumptions:
- The current address is the address holding the value.
- The next address is the remainder address.
- The security level is always 2.
- The bundle always consist of 4 transactions, of which the first one sends value to a receiving address.
The trezor will respond to iota_sign_transaction with the bundle hash (which can be used for verification) and two signatures.
Attaching the transaction to the tangle
bundle.addEntry(1, to_addr, 10, tag, timestamp) bundle.addEntry(1, from_addr, -16000000, tag, timestamp) bundle.addEntry(1, from_addr, 0, tag, timestamp) bundle.addEntry(1, remainder_addr, 15999990, tag, timestamp) bundle.finalize() bundle.addTrytes()
After that, I overwrote the signature/message field with the signatures received from the trezor. Attaching to tangle was done with api.sendTrytes(). Proof of work is not done on the trezor. The seed never left the trezor! The very first trezor-signed transaction ever in the tangle can be found here on thetangle.org. Thanks to the organizers of the first dutch IOTA meetup for providing me with initial funds on my trezor.
I have no contact with the trezor development team (yet). It would be cool to have a more mature version of this being merged into the official trezor firmware. Before that I’ll probably already publish some binary which can be flashed onto an official trezor. However you’ll have to deal with the “unofficial firmware detected” warning.
It would also be good to have the source code tripple-checked for possible implementation errors. I tried to prevent bugs in the core protocol by applying the test-driven-development method, but I cannot (yet) guarantee that your IOTAs are 100% safe on the trezor.
Please note that I do all of this development as a hobby project in my spare time. Don’t ask me when something is ready or when it will be released. If you’re a programmer and you really want to have this, feel free to browse to the source code on github and compile the stuff for yourself. Otherwise, remain patient and be excited 😉
If you really love this, feel free to donate IOTA to the following address:
This is the same address as the one I transferred some IOTA to with my trezor.