0013_Duniter_Encrypted_Wallet_Import_Format.md 4.34 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# #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).

É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
32
33

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

É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
39
40
This base64 string encodes a sequence of bytes whose structure is defined below.

## dewif bytes structure

É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
44
45
46
47
48
49

## Currencies code

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

Éloïs's avatar
Éloïs committed
52
## version data
53
54
55

### v1

Éloïs's avatar
Éloïs committed
56
57
58
59
60
61
v1 data (encrypted):

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

Éloïs's avatar
Éloïs committed
62
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
63

64
65
Symmetric encryption algorithm : aes256

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

Éloïs's avatar
Éloïs committed
68
69
70
71
password: passphrase  
salt: sha256("dewif" ++ passphrase)  
N : 4096  
r: 16  
72
73
p: 1

Éloïs's avatar
Éloïs committed
74
Example #1:
75

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

Éloïs's avatar
Éloïs committed
78
79
password: "user password"  
salt: "user salt"  
Éloïs's avatar
Éloïs committed
80
81
N : 4096  
r: 16  
82
83
84
85
p: 1

```txt
0x000000001 #v1
Éloïs's avatar
Éloïs committed
86
87
0x100000001 #g1-test
0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # seed
Éloïs's avatar
Éloïs committed
88
0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key
89
90
```

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

Éloïs's avatar
Éloïs committed
93
`AAAAARAAAAGfFDAs+jVZYkfhBlHZZ2fEQIvBqnG16g5+02cY18wSOjW0cUg2JV3SUTJYN2CrbQeRDwGazWnzSFBphchMmiL0`
94
95
96

### v2

Éloïs's avatar
Éloïs committed
97
98
99
100
101
102
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
103
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
104

105
106
Symmetric encryption algorithm : aes256

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

Éloïs's avatar
Éloïs committed
109
110
111
112
password: passphrase  
salt: sha256("dewif" ++ passphrase)  
N : 4096  
r: 16  
113
114
p: 1

Éloïs's avatar
Éloïs committed
115
### v3
116

Éloïs's avatar
Éloïs committed
117
118
119
120
121
122
123
124
125
126
127
v3 data :

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

Encrypted data :

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

Éloïs's avatar
Éloïs committed
129
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

Symmetric encryption algorithm : aes256

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

password: passphrase  
salt: sha256("dewif" ++ passphrase)  
N : `2^(log N)`
r: 16  
p: 1

Example #2:

aes256 key generated from scrypt with the following parameters:  

password: "user password"  
salt: "user salt"  
N : `2^15 = 32768`
r: 16  
p: 1

```txt
0x000000001 #v1
0x100000001 #g1-test
0x0F # log N
0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # seed
0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key
```

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

`AAAAAxAAAAEPdMuBFXF4C6GZPGsJDiPBbacpVKeaLoJwkDsuqLjkwof1c760Z5iVpnZlLt5XEFlEehbdtLllVhccf9OK6Zjn8A==`
Éloïs's avatar
Éloïs committed
162
163

[DUBP]: https://git.duniter.org/nodes/common/doc/blob/master/rfc/0010_Duniter_Blockchain_Protocol_V12.md