Commit 411bccc0 authored by Éloïs's avatar Éloïs
Browse files

Merge branch 'dewif'

parents 701df156 cd0bf729
......@@ -13,6 +13,8 @@ All documents should be implementation agnostic, as specific documentations shou
### Approved RFCs
* RFC_0013: [Duniter Encrypted Wallet Import Format](https://git.duniter.org/documents/rfcs/blob/dewif/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md)
#### DUniter Blockchain Protocol (DUBP)
* V11: [RFC 0009](rfc/0009_Duniter_Blockchain_Protocol_V11.md)
......@@ -26,7 +28,6 @@ All documents should be implementation agnostic, as specific documentations shou
* RFC_0007: [Duniter Ascii Armor Messages](https://git.duniter.org/documents/rfcs/blob/ascii_armor_messages/rfc/0007%20Ascii%20Armor%20Messages.md)
* RFC_0008: [Duniter Messages Encryption and Signature](https://git.duniter.org/documents/rfcs/blob/messages_encryption_and_signature/rfc/0008%20Messages%20Encryption%20and%20Signature.md)
* RFC_0013: [Duniter Encrypted Wallet Import Format](https://git.duniter.org/documents/rfcs/blob/dewif/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md)
* RFC_0014: [DUBP Mnemonic](https://git.duniter.org/documents/rfcs/blob/dubp-mnemonic/rfc/0014_Dubp_Mnemonic.md)
* RFC_0016: [Checksum for Duniter public keys](rfc/0016_public_key_checksum.md)
......
# RFC 13: Duniter Encrypted Wallet Import Format
```txt
RFC: 13
Title: Duniter Encrypted Wallet Import Format
Type: Format
Status: WIP
Author: elois <c@elo.tf>
Created: 2020-02-13
Last edited: 2020-02-13
License: CC-SA
```
## Introduction
A wallet is a pair of asymmetric keys (a public key + a private key).
The purpose of this RFC is to define a standard, inter-operable and secure format for any [DUBP] wallet.
This RFC does not define a file format, it is agnostic of the way the wallet is stored on the disk.
## conventions
* `||` means binary concatenation.
* All string must be encoded in UTF-8 with [NFKD normalization].
## DUBP
[DUBP] only deals with public keys and signatures.
A public key is always paired with a private key, which DUBP will never deal with.
Today DUBP manage only the algorithm ED25519, but in the future DUBP can evolve to manage multiples digital signature algorithms.
So currently a public key for DUBP is to be understood as an Ed25519 public key.
## DEWIF format
DEWIF is an inter-operable and secure format for any DUBP wallet.
DEWIF format is a sequence of bytes whose structure is defined below. It can be used as raw binary data where suitable.
To use the binary data in a text context (email, ftp text transfer, json, html, etc) it is recommended to encode the binary data in a Base64 string. The Base64 string is used here to check the binary data validity.
## Dewif bytes structure
| Version | Currency code | Data expected for this specific version |
|:-------:|:-------------:|:---------------------------------------:|
| 4 bytes | 4 bytes | Any bytes |
## Version
The 4 bytes of the version field must be interpreted as an unsigned integer encoded in big endian.
## Currencies code
| Currency | Code |
|:---------|:-----------|
| None | 0x00000000 |
| Ğ1 | 0x00000001 |
| Ğ1-Test | 0x10000001 |
## Data expected for this specific version
### Version 1
| log N | Algorithm | Nonce | Encrypted data |
|:---------:|:-----------:|:--------:|:----------------:|
| 1 byte | 1 byte | 12 bytes | Any bytes |
#### Algorithm
| Algorithm | Code |
|:----------------|:-----|
| [Ed25519] | 0x00 |
| [BIP32-Ed25519] | 0x01 |
| Unknown* | 0x02 |
*\* Future algorithms can be added to DEWIF v1.*
#### Nonce
The nonce is used to vary the encryption key (see next section).
It must be randomly generated at the creation of the DEWIF.
#### Encrypted data
**Symmetric encryption algorithm:** [XOR cipher]
[XOR cipher] is the fastest symmetric encryption algorithm in the world, the only limitation is that the encryption key must be at least as long as the encrypted data.
**XOR key** = scrypt of user passphrase with the following parameters:
| Parameter | Value |
|:--------------:|:--------------------------------------------:|
|**Password:** | passphrase |
|**Salt** | sha256(`"dewif" \|\| nonce \|\| passphrase`) |
|**N** | `2^(log N)` |
|**r** | 16 |
|**p** | 1 |
|**dkLen** | Encrypted data length |
##### Algorithm Ed25519
| Seed | Public key |
|:-------------:|:-------------:|
| 32 bytes | 32 bytes |
The public key serves as a checksum. To check that the DEWIF base64 string is not corrupted, simply generate a keypair with the seed and check that the obtained public key matches.
**Example 1:**
| Parameter | Value |
|:-----------------:|:----------------------------:|
|**Log N** | 12 |
|**Algorithm** | Ed25519 |
|**Keypair seed** | 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 |
```txt
0x000000001 #v1
0x100000001 #g1-test
0x0C # log N
0x00 # Algorithm Ed25519
0x013194f1286512cf094295cb # nonce
0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed
0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key
```
**XOR key generated from scrypt with the following parameters:**
| Parameter | Value |
|:-----------------:|:-------------:|
| **N** | `2^12 = 4096` |
| **r** | 16 |
| **p** | 1 |
| **dkLen** | 64 |
DEWIF base 64 string (with xor key `"toto titi tata"`):
`AAAAARAAAAEMAAExlPEoZRLPCUKVy0iKnn1HUSFcmhwJPQETAghFDvH8ZmX59IuvR9hYV1gnVjCpU+TGOdUzyQmj3+auw3vUpFQYBiRlh67/I1xAhZM=`
##### Algorithm Bip32-Ed25519
| Language code | Entropy length | Mnemonic entropy | Checksum |
|:--------------:|:--------------:|:----------------:|:--------:|
| Uint8 (1 byte) | Uint8 (1 byte) | 32 bytes | 8 bytes |
Language code:
| Language code | Language |
|:--------------:|:-------------------:|
| 0 | English |
| 1 | Chinese simplified |
| 2 | Chinese traditional |
| 3 | French |
| 4 | Italian |
| 5 | Japanese |
| 6 | Korean |
| 7 | Spanish |
Mnemonic entropy is defined on [BIP39].
The entropy is stored in 32 bytes to avoid revealing the size of the stored mnemonic.
If the entropy of the mnemonic is less than 32 bytes, the extra bytes are ignored (they can have any value).
To check that the DEWIF base64 string is not corrupted, compute the hash sha256 of `Nonce || Language code || Entropy length || Mnemonic entropy`. The first eight bytes of the sha256 hash constitute the checksum.
WARNING: Only the "useful" part of the entropy is used to calculate the checksum, the extra bytes are ignored.
**Example 2:**
| parameter | value |
|:-----------------:|:----------------------------:|
| **Log N** | 14 |
| **Algorithm** | Bip32-Ed25519 |
| **mnemonic** | `"crop cash unable insane eight faith inflict route frame loud box vibrant"` |
```txt
0x000000001 #v1
0x100000001 #g1-test
0x0F # log N
0x01 # Algorithm Bip32-Ed25519
0xc54299ae71fe2a4ecdc7d58a # nonce
0x00 # Language english
0x10 # Entropy length
0x33E46BB13A746EA41CDDE45C90846A79 # Mnemonic entropy
0xaa083bd16c8317121d34b5aed1c1420a # Mnemonic entropy padding (random bytes)
0x8a2bb5a0cb0acfba # checksum (SHA256 of 0xc54299ae71fe2a4ecdc7d58a || 0x00 || 0x10 || 0x33E46BB13A746EA41CDDE45C90846A79)
```
**XOR key generated from scrypt with the following parameters:**
| Parameter | Value |
|:--------------:|:--------------:|
| **N** | `2^14 = 16384` |
| **r** | 16 |
| **p** | 1 |
| **dkLen** | 42 |
DEWIF base 64 string (with xor key `"toto titi tata"`):
`AAAAARAAAAEOAcVCma5x/ipOzcfViufNdfj5k4Sl5zdrHLf9PPGDkH1Pz3y8tFrx/jZZcJd92LIk+EWIrjxiSw==`
[BIP32-Ed25519]: https://drive.google.com/file/d/0ByMtMw2hul0EMFJuNnZORDR2NDA/view
[BIP39]: https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki#generating-the-mnemonic
[DUBP]: https://git.duniter.org/nodes/common/doc/blob/master/rfc/0010_Duniter_Blockchain_Protocol_V12.md
[Ed25519]: https://tools.ietf.org/html/rfc8032
[NFKD normalization]: https://unicode.org/reports/tr15/#Norm_Forms
[XOR cipher]: https://en.wikipedia.org/wiki/XOR_cipher
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment