# RFC 13: Duniter Encrypted Wallet Import Format ```txt RFC: 13 Title: Duniter Encrypted Wallet Import Format Type: Format Status: WIP Author: elois 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. ## 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 base64 string. This base64 string encodes a sequence of bytes whose structure is defined below. ## dewif bytes structure | version (4 bytes) | currency code (4 bytes) | version data (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 | ## version data ### v1 v1 data (encrypted): | 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, simply generate an 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: **password:** passphrase **salt:** sha256("dewif" ++ passphrase) **N:** 4096 **r:** 16 **p:** 1 Example #1: aes256 key generated from scrypt with the following parameters: **keypair seed:** 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 **N:** 4096 **r:** 16 **p:** 1 ```txt 0x000000001 #v1 0x100000001 #g1-test 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed 0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key ``` DEWIF base 64 string (with aes key `"toto titi tata"`): `AAAAARAAAAGfFDAs+jVZYkfhBlHZZ2fEQIvBqnG16g5+02cY18wSOjW0cUg2JV3SUTJYN2CrbQeRDwGazWnzSFBphchMmiL0` ### v2 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 | 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. Symmetric encryption algorithm : aes256 aes256 key: scrypt of user passphrase with the following parameters: **password:** passphrase **salt:** sha256("dewif" ++ passphrase) **N:** 4096 **r:** 16 **p:** 1 ### v3 v3 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, simply generate an 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: **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: **keypair seed:** 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 **N:** `2^15 = 32768` **r:** 16 **p:** 1 ```txt 0x000000003 #v3 0x100000001 #g1-test 0x0F # log N 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed 0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key ``` DEWIF base 64 string (with aes key `"toto titi tata"`): `AAAAAxAAAAEPdMuBFXF4C6GZPGsJDiPBbacpVKeaLoJwkDsuqLjkwof1c760Z5iVpnZlLt5XEFlEehbdtLllVhccf9OK6Zjn8A==` ### 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: **password:** passphrase **salt:** sha256("dewif" ++ passphrase) **N:** `2^(log N)` **r:** 16 **p:** 1 Example #3: **keypair seed:** 0xb7d3a54e1c20172cd38e0d803776a3bacf11f895ef8ef846043a0d628431c872 **N:** `2^15 = 32768` **r:** 16 **p:** 1 ```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 [DUBP]: https://git.duniter.org/nodes/common/doc/blob/master/rfc/0010_Duniter_Blockchain_Protocol_V12.md