If you wish to test the BitBox for your application, get started quickly using the Electron app demo or the Python command line interface. You can also take a look at a full featured native implementation in our desktop app.
The BitBox is a plug-n-play USB-HID device with a simple JSON interface. It can be accessed using HID API library, a C library that has been ported to many different languages. A web interface using the U2F protocol also exists, but it can only be accessed by whitelisted URLs hardcoded in the firmware.
The BitBox code is open source on GitHub. A native cross-platform desktop app provides a client interface for a fully functioning wallet. Two-factor authentication (2FA) using a mobile app provides a remote screen for added security. The BitBox microcontroller code, written in C, can be compiled and run as a standalone program on a PC for testing purposes. A list of API commands is provided below.
The hierarchical deterministic wallet structure of the BitBox follows the BIP32 and BIP44 standards. Wallets are securely generated onboard the BitBox using a high-quality hardware random number generator to produce entropy. Alternatively, users can load their own wallet from a file on a micro SD card. The micro SD port allows offline backup of the wallet to a file. Random numbers can be requested via the USB interface in order to verify their quality or to use them in other applications.
All USB communication is password encrypted using the AES-256-CBC algorithm with base-64 encoding. USB packets are sent following the ISO 7816-4 standard. A password must be set before any command is accepted. Brute force password attacks are mitigated as the device will reset and erase all private data after 15 incorrect tries. In case a password is forgotten, reset the device and reload your wallet from the backup on the micro SD card.
Method & parameters | Response | Notes |
---|---|---|
Generate a wallet on your BitBox | ||
"seed" :
{ "source" : "source", "U2F_counter" : "counter", "entropy" : "entropy", "key" : "key", "filename" : "filename" } |
"seed" :
"success" |
Source: create , backup , U2F_create , or U2F_load . create securely creates a new wallet on the device. U2F_create securely creates a new U2F master key on the device. In both cases, a backup filename is automatically saved to the micro SD card that contains the wallet seed, the U2F master key, and the device name. backup creates a wallet from a backup filename on the micro SD card. U2F_load sets the U2F master key as that contained in the backup. is the passphrase used when cryptographically generating a wallet. The key is recommended to be strengthened (e.g. PBKDF2) by the client software in order to make brute force attacks on the backup more difficult. entropy is optional if using the create mode. User-supplied entropy can be added to the output of the device's hardware random number generator when creating a wallet.counter sets the U2F counter value. It is a 32-bit number (without quotes) and is optional if using the U2F_create or U2F_load modes. If not specified, the U2F counter value stored inside the device is unchanged. To avoid setting the counter too low, the client code is recommended to set the counter to be the unix_time_seconds * ave_u2f_calls_per_second . A safe choice is 1 call every 10 seconds, giving over 1000 years until the counter is filled. |
Backup the existing wallet to a micro SD card | ||
"backup" :
{ "source" : "U2F/HWW/all", "key" : "key", "filename" : "filename" } |
"backup" :
"success" |
Saves a backup of the wallet to a file filename in a digitalbitbox folder on the micro SD card. source specifies the secret to back up (hardware wallet seed, U2F master key, or both); it is optional for backward compatibility and defaults to all . key is the wallet passphrase and used to verify the integrity of the hardware wallet seed in the backup file; it is ignored is source is U2F . The SD card should be formatted (FAT file system) before use. |
"backup" :
"list" |
"backup" :
"files" |
Lists the files and folders in the digitalbitbox/ folder on the micro SD card. |
"backup" :
{ "source" : "U2F/HWW", "check" : "filename", "key" : "key" } |
"backup" :
"success" |
Check if the backup filename on the micro SD card matches the corresponding secret stored in the BitBox (either main or hidden wallet). source is either the hardware wallet seed (HWW), or the U2F master key; it is optional for backward compatibility and defaults to HWW . key is the (stretched) password for the seeded wallet; it is ignored when checking the U2F master key. |
"backup" :
"erase" |
"backup" :
"success" |
Erase everything in the digitalbitbox/ folder on the micro SD card. |
"backup" :
{ "erase" : "filename" } |
"backup" :
"success" |
Erase filename in the digitalbitbox/ folder on the micro SD card. |
Set a password | ||
"password" :
"password" |
"password" :
"success" |
A password is required that has a length of at least 4 characters. The password needs to be sent only once and is used to encrypt all communication via the AES-256-CBC algorithm. Special symbols (UTF-8) are allowed. |
Access a hidden wallet | ||
"hidden password" :
{ "password" : "hidden_password", "stretched_password" : "hidden_password" } |
"hidden password" :
"success" |
As a plausible deniability security feature, once set, a hidden password can be used to access a hidden wallet. For firmware versions 2.3.0 or higher, if a different hidden password is set, a different hidden wallet is created. Resetting the hidden password for a previous hidden wallet will load the previous hidden wallet (specific to a given wallet seed). Using a hidden password to recover from a backup file will cause the hidden wallet to be loaded as the standard wallet, adding more plausibility. The hidden wallet is erased if the device is factory reset, a new wallet is created onboard, or a wallet is recovered from a backup. |
Sign using a private key | ||
"sign" :
{ "meta" : "metadata", "data" : "hasharray", "checkpub" : "pubkeyarray" } |
"echo" :
{ "meta" : "metadata", "data" : "hasharray", "checkpub" : "pubkeyarray", "pin" : "lock_pin" } |
The sign command produces ECDSA signatures of hashes given in data . Two sign commands must be sent in a row. The first command produces an encrypted verfication message. The second command (see below) returns an array of signatures and corresponding signing pubkeys . Verification messages allow two-factor authentication (2FA) for highest security.Data: hasharray contains a list of hashes and the keypaths used to sign each hash: [{'hash':'hash 1', 'keypath':'keypath 1'}, ... ] . Multiple hashes can be signed in one command. Each hash must be 64-characters long (representing a 32-byte hexadecimal value). Checkpub: pubkeyarray contains a list of compressed pubkeys and associated keypaths. This is used for checking if a pubkey, e.g. for a change output, is part of the wallet: [{'pubkey':'pubkey 1', 'keypath':'keypath 1'}, ... ] . Any number of pubkeys can be checked. The result is added to the encrypted verification message: [{'pubkey':'pubkey 1', 'present':true}, ... ] .Meta: metadata is included 'as is' in the returned encrypted verfication message. This is typically a hash of the unsigned transaction.The JSON value of the echo response is encrypted with the verification key (see verifypass below). For locked devices, the lock_pin is the single-use PIN required to 'unlock', or allow, signatures to be created and returned after sending the second sign command. |
"sign" :
{ "pin" : "lock_pin" } |
"sign" :
{ "recid" : "recid", "sig" : "signature" } |
The second sign command turns on the LED for touch button user confirmation. Its reply contains the signatures. For an unlocked device, pin is ignored, and an empty command can be sent instead: {'sign': ''} . Returned signatures are not post-processed. DER encoding for a standard transaction is to be done in the client software. recid is the recoverable ID that can be used to derive the public key from the signature. ECDSA signing without pre- or post-processing provides compatibility 'out-of-the-box' with multisignature protocols, altcoins, or other custom implementations. |
Set a verification key for two-factor authentication (2FA) | ||
"verifypass" :
"operation" |
"verifypass" :
"reply" |
Operation: export , create , or {'ecdh': 'pubkey A'} . create uses the hardware random number generator to create a random 64 character hexadecimal string as a verification key. {'ecdh': 'pubkey'} implements Diffie-Hellman key exchange using the secp2561 elliptic curve. export saves the key to the micro SD card in a plaintext file named verification.txt . The reply is success for create or export . For ecdh , the reply is {'ecdh': 'pubkey B'} . To avoid MITM from intercepting the shared ECDH secret, LED blinks (to be entered by hand on the 2FA device) are included in key creation. Watch for future tutorial videos for details. 2FA is used to verify that the correct transaction is signed even when using a fully compromised host computer. A verification key is generated during the factory installation and can be updated at any time by an owner. The verification message can be displayed and checked on a separate device (i.e. smartphone app or web service) that knows the verification key. The AES-256-CBC algorithm is used for encryption. |
"device" :
"lock" |
"device" :
{ "lock" : "boolean" } |
Disables backup , verifypass , and seed commands. These can be re-enabled only after a reset command. Be sure to backup your wallet before locking the device! The verifypass command allows a second object to be used for verification. If a thief steals an unlocked BitBox and knows its password, the coins can be taken without the need for the second object. The lock command adds full 2FA protection by requiring the thief to also possess the second object in order to steal coins. After locking the BitBox, a single-use 4-digit PIN is included within the encrypted verification message and is displayed on the second object. This PIN is required to unlock (i.e. decrypt) the signed transaction before it is broadcast to the Bitcoin network. |
Reset | ||
"reset" :
"__ERASE__" |
"reset" :
"success" |
Factory resets the wallet and erases all wallet data. U2F second-factor authentication data is NOT reset. |
"reset" :
"U2F" |
"reset" :
"success" |
DEPRECATED. Use {seed: {source: U2F_create}} to reset the U2F key. |
Name the device | ||
"name" :
"name" |
"name" :
"name" |
Saves a new name . Long names are truncated to 31 characters. Sending an empty string will return the current name. |
Blink the LED | ||
"led" :
"mode" |
"led" :
"success" |
mode is blink or abort . The latter reproduces the LED blinks that occur when a user aborts an operation that requires touch confirmation. |
Get a random number from the device | ||
"random" :
"mode" |
"random" :
"number" |
Mode: true or pseudo .A 16 byte random number is returned as a hexadecimal string. The hardware random number generator (RNG) on a high-security crypto chip is used. The true RNG mode updates a seed value written to the chip's EEPROM, which has a specified minimum lifespan of 100,000 write cycles. The pseudo RNG mode derives numbers using this seed and does not affect lifespan. |
Get an extended public key at the indicated keypath | ||
"xpub" :
"keypath" |
"xpub" :
"xpub" "echo" : "encrypted_xpub" |
Returns the xpub for the given keypath , for example, m/purpose'/coin_type'/account'/change/address_index , following the BIP44 standard. An apostrophe designates a hardened key derivation. A letter p , h , or H can be used instead of an apostrophe. In practice, the BitBox wallet is agnostic of the keypath, i.e., m/index_1/index_2/index_3/...index_N is valid for a varying number of N indices. Each index can be designated as hardened or not.The echo returns the extended public key encrypted using the 2FA verification key. |
Set access to the bootloader | ||
"bootloader" :
"status" |
"bootloader" :
"status" |
status is lock or unlock . When unlocked, the bootloader is entered by pressing the touch button within 3 seconds of plugging in the device. Otherwise, the firmware starts. |
Get device information | ||
"device" :
"info" |
"device" :
{ "seeded" : "boolean", "name" : "name", "U2F" : "boolean", "lock" : "boolean", "sdcard" : "boolean", "new_hidden_wallet" : "boolean", "bootlock" : "boolean", "version" : "version", "U2F_hijack" : "boolean", "serial" : "number", "id" : "sha(xpub)" } |
id is a SHA256 hash of the master extended public key if seeded. |
Feature options | ||
"feature_set" :
{ "U2F" : "boolean", "U2F_hijack" : "boolean", "new_hidden_wallet" : "boolean" } |
"feature_set" :
"success" |
U2F enables or disables the U2F second-factor authentication function. If disabled, any U2F commands will be answered with a device busy error message. Enabled by default on factory reset.U2F_hijack enables or disables browser access to the hardware wallet API. Communication is done by hijacking the 'key handle' data field of the U2F authentication command. This must be enabled to use any web integrations, such as MyEtherWallet. If U2F is disabled, U2F_hijack will also be disabled, even if it is set to be enabled. When disabled, any U2F hijack commands will be answered with a device busy error message. Enabled by default on factory reset. new_hidden_wallet is enabled by default. Disabling it activates the deprecated legacy hidden wallet mode (added to make migration easier).boolean should be true or false and without quotes. A single feature or any combination of features can be sent. |