0013_Duniter_Encrypted_Wallet_Import_Format.md 5.95 KB
Newer Older
Éloïs's avatar
Éloïs committed
1
# RFC 13: Duniter Encrypted Wallet Import Format
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

```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).

Éloïs's avatar
Éloïs committed
18
The purpose of this RFC is to define a standard, inter-operable and secure format for any [DUBP] wallet.
19

Éloïs's avatar
Éloïs committed
20
21
22
23
24
This RFC does not define a file format, it is agnostic of the way the wallet is stored on the disk.

## DUBP

[DUBP] only deals with public keys and signatures.
25
26
27
28
29
30
31

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.

Éloïs's avatar
Éloïs committed
32
## DEWIF format
33

Éloïs's avatar
Éloïs committed
34
DEWIF is an inter-operable and secure format for any DUBP wallet.
35

Éloïs's avatar
Éloïs committed
36
DEWIF format is a base64 string.  
37
38
This base64 string encodes a sequence of bytes whose structure is defined below.

Éloïs's avatar
Éloïs committed
39
## dewif bytes structure
40

Éloïs's avatar
Éloïs committed
41
42
| version (4 bytes) | currency code (4 bytes) | version data (any bytes) |
|:-----------------:|:-----------------------:|:------------------------:|
Éloïs's avatar
Éloïs committed
43

Éloïs's avatar
Éloïs committed
44
45
46
47
## Version

The 4 bytes of the version field must be interpreted as an unsigned integer encoded in big endian.

Éloïs's avatar
Éloïs committed
48
## Currencies code
Éloïs's avatar
Éloïs committed
49
50
51
52
53

| Currency | code       |
|:---------|:-----------|
| None     | 0x00000000 |
| Ğ1       | 0x00000001 |
Éloïs's avatar
Éloïs committed
54
| Ğ1-Test  | 0x10000001 |
55

Éloïs's avatar
Éloïs committed
56
## version data
57
58
59

### v1

Éloïs's avatar
Éloïs committed
60
61
62
63
64
65
v1 data (encrypted):

| seed(32 bytes) | public key(32bytes) |
|:--------------:|:-------------------:|
| seed bytes     | public key bytes    |

Éloïs's avatar
Éloïs committed
66
The public key serves as a checksum. To check that the DEWIF base64 string is not corrupted, simply generate an ed25519 keypair with the seed and check that the obtained public key matches.
Éloïs's avatar
Éloïs committed
67

68
69
Symmetric encryption algorithm : aes256

Éloïs's avatar
Éloïs committed
70
71
aes256 key: scrypt of user passphrase with the following parameters:  

Éloïs's avatar
Éloïs committed
72
73
74
75
76
**password:** passphrase  
**salt:** sha256("dewif" ++ passphrase)  
**N:** 4096  
**r:** 16  
**p:** 1
77

Éloïs's avatar
Éloïs committed
78
Example #1:
79

Éloïs's avatar
Éloïs committed
80
aes256 key generated from scrypt with the following parameters:  
81

Éloïs's avatar
Éloïs committed
82
83
84
85
**keypair seed:** 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143  
**N:** 4096  
**r:** 16  
**p:** 1
86
87
88

```txt
0x000000001 #v1
Éloïs's avatar
Éloïs committed
89
0x100000001 #g1-test
Éloïs's avatar
Éloïs committed
90
0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed
Éloïs's avatar
Éloïs committed
91
0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key
92
93
```

Éloïs's avatar
Éloïs committed
94
DEWIF base 64 string (with aes key `"toto titi tata"`):
95

Éloïs's avatar
Éloïs committed
96
`AAAAARAAAAGfFDAs+jVZYkfhBlHZZ2fEQIvBqnG16g5+02cY18wSOjW0cUg2JV3SUTJYN2CrbQeRDwGazWnzSFBphchMmiL0`
97
98
99

### v2

Éloïs's avatar
Éloïs committed
100
101
102
103
104
105
v2 data (encrypted):

| seed1(32 bytes) | public key1(32bytes) | seed2(32 bytes) | public key2(32bytes) |
|:---------------:|:--------------------:|:---------------:|:--------------------:|
| seed bytes      | public key bytes     | seed bytes      | public key bytes     |

Éloïs's avatar
Éloïs committed
106
The public key serves as a checksum. To check that the DEWIF base64 string is not corrupted, simply generate an ed25519 keypair with the seed and check that the obtained public key matches.
Éloïs's avatar
Éloïs committed
107

108
109
Symmetric encryption algorithm : aes256

Éloïs's avatar
Éloïs committed
110
111
aes256 key: scrypt of user passphrase with the following parameters:  

Éloïs's avatar
Éloïs committed
112
113
114
115
116
**password:** passphrase  
**salt:** sha256("dewif" ++ passphrase)  
**N:** 4096  
**r:** 16  
**p:** 1
117

Éloïs's avatar
Éloïs committed
118
### v3
119

Éloïs's avatar
Éloïs committed
120
121
122
123
124
125
126
127
128
129
130
v3 data :

| `log N` | Encrypted data |
|:-------:|:--------------:|
| 1 byte  | 64 bytes       |

Encrypted data :

| seed(32 bytes) | public key(32bytes) |
|:--------------:|:-------------------:|
| seed bytes     | public key bytes    |
131

Éloïs's avatar
Éloïs committed
132
The public key serves as a checksum. To check that the DEWIF base64 string is not corrupted, simply generate an ed25519 keypair with the seed and check that the obtained public key matches.
Éloïs's avatar
Éloïs committed
133
134
135
136
137

Symmetric encryption algorithm : aes256

aes256 key: scrypt of user passphrase with the following parameters:  

Éloïs's avatar
Éloïs committed
138
139
140
141
142
**password:** passphrase  
**salt:** sha256("dewif" ++ passphrase)  
**N:** `2^(log N)`  
**r:** 16  
**p:** 1
Éloïs's avatar
Éloïs committed
143
144
145
146
147

Example #2:

aes256 key generated from scrypt with the following parameters:  

Éloïs's avatar
Éloïs committed
148
149
150
151
**keypair seed:** 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143  
**N:** `2^15 = 32768`  
**r:** 16  
**p:** 1
Éloïs's avatar
Éloïs committed
152
153

```txt
Éloïs's avatar
Éloïs committed
154
0x000000003 #v3
Éloïs's avatar
Éloïs committed
155
156
0x100000001 #g1-test
0x0F # log N
Éloïs's avatar
Éloïs committed
157
0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed
Éloïs's avatar
Éloïs committed
158
159
160
161
162
163
0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key
```

DEWIF base 64 string (with aes key `"toto titi tata"`):

`AAAAAxAAAAEPdMuBFXF4C6GZPGsJDiPBbacpVKeaLoJwkDsuqLjkwof1c760Z5iVpnZlLt5XEFlEehbdtLllVhccf9OK6Zjn8A==`
Éloïs's avatar
Éloïs committed
164

Éloïs's avatar
Éloïs committed
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
### v4

Version 4 stores an HD wallet according to the [BIP32-Ed25519] specifications.

v4 data :

| `log N` | Encrypted data |
|:-------:|:--------------:|
| 1 byte  | 64 bytes       |

Encrypted data :

| seed(32 bytes) | public key(32bytes) |
|:--------------:|:-------------------:|
| seed bytes     | public key bytes    |

The public key serves as a checksum. To check that the DEWIF base64 string is not corrupted, generate a [BIP32-Ed25519] keypair with the seed and check that the obtained public key matches.

Symmetric encryption algorithm : aes256

aes256 key: scrypt of user passphrase with the following parameters:  

Éloïs's avatar
Éloïs committed
187
188
189
190
191
**password:** passphrase  
**salt:** sha256("dewif" ++ passphrase)  
**N:** `2^(log N)`  
**r:** 16  
**p:** 1
Éloïs's avatar
Éloïs committed
192
193
194

Example #3:

Éloïs's avatar
Éloïs committed
195
196
197
198
**keypair seed:** 0xb7d3a54e1c20172cd38e0d803776a3bacf11f895ef8ef846043a0d628431c872  
**N:** `2^15 = 32768`  
**r:** 16  
**p:** 1
Éloïs's avatar
Éloïs committed
199
200
201
202
203
204
205
206
207
208
209
210
211
212

```txt
0x000000004 #v4
0x100000001 #g1-test
0x0F # log N
0xb7d3a54e1c20172cd38e0d803776a3bacf11f895ef8ef846043a0d628431c872 # keypair seed
0xd1fec6ddf6e887e40bd77d459131ee5a6bec1194341b9393ead606363bb7b060 # public key
```

DEWIF base 64 string (with aes key `"toto titi tata"`):

`AAAABBAAAAEPcE3yXhA0T0iElXR/vDbZTRSmdec26lWu42mWKuaczzxZ22bIGVfLmlhfVW9NWmWY7m/P/j0W6Su4QZEiERe8vA==`

[BIP32-Ed25519]: https://drive.google.com/file/d/0ByMtMw2hul0EMFJuNnZORDR2NDA/view
Éloïs's avatar
Éloïs committed
213
[DUBP]: https://git.duniter.org/nodes/common/doc/blob/master/rfc/0010_Duniter_Blockchain_Protocol_V12.md