#SLIP-0011 : Symmetric encryption of key-value pairs using deterministic hierarchy
#SLIP-0011 : Symmetric encryption of key-value pairs using deterministic hierarchy
```
```
Number: SLIP-0011
Number: SLIP-0011
...
@@ -11,17 +11,17 @@ Authors: Pavol Rusnak <stick@satoshilabs.com>
...
@@ -11,17 +11,17 @@ Authors: Pavol Rusnak <stick@satoshilabs.com>
Created: 2014-06-12
Created: 2014-06-12
```
```
##Abstract
##Abstract
This document is explaining symmetric encryption on hardware devices, using deterministic hierarchy.
This document is explaining symmetric encryption on hardware devices, using deterministic hierarchy.
##Motivation
##Motivation
We want to provide a symmetric encryption in the hardware wallet, where the key doesn't exit the device, and where the user might be forced to confirm the encryption/decryption on the display.
We want to provide a symmetric encryption in the hardware wallet, where the key doesn't exit the device, and where the user might be forced to confirm the encryption/decryption on the display.
##Body
##Body
###Overview
###Overview
The following data are sent to the hardware wallet:
The following data are sent to the hardware wallet:
...
@@ -41,11 +41,11 @@ IV can be either manually set, or it is computed together with the key.
...
@@ -41,11 +41,11 @@ IV can be either manually set, or it is computed together with the key.
The value must be divisible into 16-byte blocks. The application has to pad the blocks itself and ensure safety; for example, by using PKCS7.
The value must be divisible into 16-byte blocks. The application has to pad the blocks itself and ensure safety; for example, by using PKCS7.
###Details
###Details
The details are best explained on a slightly simplified code from TREZOR Python emulator.
The details are best explained on a slightly simplified code from TREZOR Python emulator.
returnFailure(message="Input length must be a multiple of 16")
returnFailure(message="Input length must be a multiple of 16")
````
```
First, the value is checked, if it is divisable into 16-byte blocks, since the symmetric cipher is block cipher. The application has to pad the blocks itself and ensure safety; for example, by using PKCS7.
First, the value is checked, if it is divisable into 16-byte blocks, since the symmetric cipher is block cipher. The application has to pad the blocks itself and ensure safety; for example, by using PKCS7.
The key, displayed on the device, is concatenated with either E1 or E0 and either D1 or D0, depending on whether the confirmation is enabled in a given direction.
The key, displayed on the device, is concatenated with either E1 or E0 and either D1 or D0, depending on whether the confirmation is enabled in a given direction.
The result are the encrypted/decrypted blocks, concatenated together.
The result are the encrypted/decrypted blocks, concatenated together.
##References
##References
The algorithm is implemented in [TREZOR firmware](https://github.com/trezor/trezor-mcu/blob/master/firmware/fsm.c)(function`fsm_msgCipherKeyValue`) and its [emulator](https://github.com/trezor/trezor-emu/blob/master/trezor/machine.py#L781)(function`_cipher_keyvalue`).
The algorithm is implemented in [TREZOR firmware](https://github.com/trezor/trezor-mcu/blob/master/firmware/fsm.c)(function`fsm_msgCipherKeyValue`) and its [emulator](https://github.com/trezor/trezor-emu/blob/master/trezor/machine.py#L781)(function`_cipher_keyvalue`).
[link to blockchain.info](https://blockchain.info/xpub/xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy)
[link to blockchain.info](https://blockchain.info/xpub/xpub6BiVtCpG9fQPxnPmHXG8PhtzQdWC2Su4qWu6XW9tpWFYhxydCLJGrWBJZ5H6qTAHdPQ7pQhtpjiYZVZARo14qHiay2fvrX996oEP42u8wZy)
Then, the result is converted to string using Base58Check encoding, as used in Bitcoin.
Then, the result is converted to string using Base58Check encoding, as used in Bitcoin.
The API key is either 49 or 50 characters long.
The API key is either 49 or 50 characters long.
###Deriving filename and password from account key
###Deriving filename and password from account key
We take the account key, *as a string*, and we use HMAC function to derive filename and password for metadata file. Every account has its own metadata file.
We take the account key, *as a string*, and we use HMAC function to derive filename and password for metadata file. Every account has its own metadata file.
...
@@ -111,7 +110,7 @@ We take the account key, *as a string*, and we use HMAC function to derive filen
...
@@ -111,7 +110,7 @@ We take the account key, *as a string*, and we use HMAC function to derive filen
* the next 16 bytes are the GCM authentication tag
* the next 16 bytes are the GCM authentication tag
* the rest is the ciphertext
* the rest is the ciphertext
###Data format
###Data format
The (decrypted) metadata are in following format:
The (decrypted) metadata are in following format:
...
@@ -130,7 +129,7 @@ All labels can have any unicode letters. Empty string is treated in the software
...
@@ -130,7 +129,7 @@ All labels can have any unicode letters. Empty string is treated in the software
An example object looks like this:
An example object looks like this:
```javascript
```javascript
{
{
"version":"1.0.0",
"version":"1.0.0",
"accountLabel":"Saving account",// one file per account, so only 1 label needed
"accountLabel":"Saving account",// one file per account, so only 1 label needed
...
@@ -152,21 +151,19 @@ An example object looks like this:
...
@@ -152,21 +151,19 @@ An example object looks like this:
(comments are of course not part of a valid JSON and are included here only for clarity)
(comments are of course not part of a valid JSON and are included here only for clarity)
##Example
##Example
All the example code is in Python2.
All the example code is in Python2.
###Deriving master key
### Deriving "master" key
Example code, deriving a master key from a connected TREZOR is in [1_masterkey.py](slip-0015/1_masterkey.py). It requires python-trezor_ installed and TREZOR connencted
Example code, deriving a master key from a connected TREZOR is in [1_masterkey.py](slip-0015/1_masterkey.py). It requires [python-trezor](https://github.com/trezor/python-trezor) installed and TREZOR connencted
For the "stress test" wallet, defined in SLIP-0014, the master key should be (in hex)::
For the "stress test" wallet, defined in SLIP-0014, the master key should be (in hex)::
Example code, deriving an account key for master key, is in [2_accountkey.py](slip-0015/2_accountkey.py). First argument of the script is xpub of the account, the second argument is the master key from previous step (in hexadecimal).
Example code, deriving an account key for master key, is in [2_accountkey.py](slip-0015/2_accountkey.py). First argument of the script is xpub of the account, the second argument is the master key from previous step (in hexadecimal).
...
@@ -174,7 +171,7 @@ For the "stress test" wallet, defined in SLIP-0014, and its first account (with
...
@@ -174,7 +171,7 @@ For the "stress test" wallet, defined in SLIP-0014, and its first account (with
v5kCxSKLTsnwmgPBeaRyFDWeG9zXouF34L72763zjLrS4LWy8
v5kCxSKLTsnwmgPBeaRyFDWeG9zXouF34L72763zjLrS4LWy8
###Deriving filename, decoding
###Deriving filename, decoding
Example code for decryption is in [3_decrypt.py](slip-0015/3_decrypt.py). First and only argument is the account key from previous step. The file has to be in a current working directory (in myTREZOR, we use `~/Dropbox/Apps/TREZOR/` for saving the files).
Example code for decryption is in [3_decrypt.py](slip-0015/3_decrypt.py). First and only argument is the account key from previous step. The file has to be in a current working directory (in myTREZOR, we use `~/Dropbox/Apps/TREZOR/` for saving the files).
- ENC_VALUE: `'2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee'` (in hexadecimal (128 /2), max length is 1024 bytes)
* ENC_VALUE: `'2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee2d650551248d792eabf628f451200d7f51cb63e46aadcbb1038aacb05e8c8aee'` (in hexadecimal (128 /2), max length is 1024 bytes)
- ask_on_encrypt: `true`
* encrypt: `true`
- ask_on_decrypt: `true`
* ask_on_encrypt: `true`
- iv: unset
* ask_on_decrypt: `true`
* iv: unset
JS EXAMPLE:
JS EXAMPLE:
```javascript
```javascript
session.cipherKeyValue(
session.cipherKeyValue(
[(10016|0x80000000)>>>0,0],
[(10016|0x80000000)>>>0,0],
'Unlock encrypted storage?',
'Unlock encrypted storage?',
...
@@ -71,7 +72,7 @@ For encrypt/decrypt we are using `AES-256-GCM` algorithm.
...
@@ -71,7 +72,7 @@ For encrypt/decrypt we are using `AES-256-GCM` algorithm.
- Input Vector (IV) is 12 randomly generated bytes
- Input Vector (IV) is 12 randomly generated bytes
- GCM is used with full 128-bit autentication tag (authTag)
- GCM is used with full 128-bit autentication tag (authTag)
for more: https://nodejs.org/api/crypto.html#crypto_crypto_createcipheriv_algorithm_key_iv
@@ -10,17 +10,17 @@ Authors: Pavol Rusnak <stick@satoshilabs.com>
...
@@ -10,17 +10,17 @@ Authors: Pavol Rusnak <stick@satoshilabs.com>
Created: 2014-07-09
Created: 2014-07-09
```
```
##Abstract
##Abstract
BIP-0044 defines a logical hierarchy for deterministic wallets.
BIP-0044 defines a logical hierarchy for deterministic wallets.
Level 2 of the hierarchy describes a coin type in use.
Level 2 of the hierarchy describes a coin type in use.
##Motivation
##Motivation
BIP repository does not want to deal with assigning the values for various
BIP repository does not want to deal with assigning the values for various
coin types different than Bitcoin so we propose this SLIP to become such body.
coin types different than Bitcoin so we propose this SLIP to become such body.
##Registered coin types
##Registered coin types
These are the registered coin types for usage in level 2 of BIP44 described in chapter "Coin type".
These are the registered coin types for usage in level 2 of BIP44 described in chapter "Coin type".
...
@@ -136,10 +136,10 @@ index | hexa | coin
...
@@ -136,10 +136,10 @@ index | hexa | coin
Coin types will be added only if there is a wallet implementing BIP-0044 for desired coin.
Coin types will be added only if there is a wallet implementing BIP-0044 for desired coin.
##Libraries
##Libraries
*[BIP44-constants](https://www.npmjs.com/package/bip44-constants)([source](http://github.com/bitcoinjs/bip44-constants)) JavaScript package with described coin types
*[BIP44-constants](https://www.npmjs.com/package/bip44-constants)([source](http://github.com/bitcoinjs/bip44-constants)) JavaScript package with described coin types
##References
##References
-[BIP-0044: Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)
*[BIP-0044: Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)