diff --git a/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md b/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md index ecbf966e072bf1c631910435ca32a2d4523f33bd..2a0fc7e9a1215d9cf4182d32844a950e43cb154f 100644 --- a/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md +++ b/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md @@ -19,6 +19,11 @@ The purpose of this RFC is to define a standard, inter-operable and secure forma This RFC does not define a file format, it is agnostic of the way the wallet is stored on the disk. +## conventions + +* `||` means binary concanetanation. +* All string must be encoded in UTF-8 with [NFKD normalization]. + ## DUBP [DUBP] only deals with public keys and signatures. @@ -59,9 +64,9 @@ The 4 bytes of the version field must be interpreted as an unsigned integer enco ### Version 1 -| log N | Algorithm | Encrypted data | -|:---------:|:-----------:|:---------------:| -| 1 byte | 1 byte | Any bytes | +| log N | Algorithm | Nonce | Encrypted data | +|:---------:|:-----------:|:--------:|:----------------:| +| 1 byte | 1 byte | 12 bytes | Any bytes | #### Algorithm @@ -73,6 +78,11 @@ The 4 bytes of the version field must be interpreted as an unsigned integer enco *\* 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] @@ -81,14 +91,14 @@ The 4 bytes of the version field must be interpreted as an unsigned integer enco **XOR key** = scrypt of user passphrase with the following parameters: -| Parameter | Value | -|:--------------:|:-----------------------------:| -|**Password:** | passphrase | -|**Salt** | sha256("dewif" ++ passphrase) | -|**N** | `2^(log N)` | -|**r** | 16 | -|**p** | 1 | -|**dkLen** | Encrypted data length | +| Parameter | Value | +|:--------------:|:--------------------------------------------:| +|**Password:** | passphrase | +|**Salt** | sha256(`"dewif" \|\| nonce \|\| passphrase`) | +|**N** | `2^(log N)` | +|**r** | 16 | +|**p** | 1 | +|**dkLen** | Encrypted data length | ##### Algorithm Ed25519 @@ -102,7 +112,7 @@ The public key serves as a checksum. To check that the DEWIF base64 string is no | Parameter | Value | |:-----------------:|:----------------------------:| -|**Log N** | 15 | +|**Log N** | 12 | |**Algorithm** | Ed25519 | |**Keypair seed** | 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 | @@ -111,6 +121,7 @@ The public key serves as a checksum. To check that the DEWIF base64 string is no 0x100000001 #g1-test 0x0C # log N 0x00 # Algorithm Ed25519 +0x013194f1286512cf094295cb # nonce 0xbfa3f6e322cf21d0e652f79a69df9498fdf5347665e5646d9041f756496a1143 # keypair seed 0x17df9d2b059cdd2825955691e3a783e6da403148ddebb1144d1a9b9e545f2371 # public key ``` @@ -126,7 +137,7 @@ The public key serves as a checksum. To check that the DEWIF base64 string is no DEWIF base 64 string (with xor key `"toto titi tata"`): -`AAAAARAAAAEMALUJm4gAYvodNzw/CPBV4Pckm+pv1taVmMdXpbthi9YyDSu9ioexcFO1YJpKPKATZR5IMBpeOOnZkzhTb3k2SYo=` +`AAAAARAAAAEMAAExlPEoZRLPCUKVy0iKnn1HUSFcmhwJPQETAghFDvH8ZmX59IuvR9hYV1gnVjCpU+TGOdUzyQmj3+auw3vUpFQYBiRlh67/I1xAhZM=` ##### Algorithm Bip32-Ed25519 @@ -151,7 +162,7 @@ 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 `Language code || Entropy length || Mnemonic entropy`. The first eight bytes of the sha256 hash constitute the checksum. +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:** @@ -167,11 +178,12 @@ WARNING: Only the "useful" part of the entropy is used to calculate the checksum 0x100000001 #g1-test 0x0F # log N 0x01 # Algorithm Bip32-Ed25519 +0xc54299ae71fe2a4ecdc7d58a # nonce 0x00 # Language english 0x10 # Entropy length 0x33E46BB13A746EA41CDDE45C90846A79 # Mnemonic entropy -0x 00000000000000000000000000000000 # Mnemonic entropy padding -0xa058ad20f43a5aa2 # checksum (SHA256 of 0x001033E46BB13A746EA41CDDE45C90846A79) +0x00000000000000000000000000000000 # Mnemonic entropy padding +0x8a2bb5a0cb0acfba # checksum (SHA256 of 0xc54299ae71fe2a4ecdc7d58a || 0x00 || 0x10 || 0x33E46BB13A746EA41CDDE45C90846A79) ``` **XOR key generated from scrypt with the following parameters:** @@ -191,4 +203,5 @@ DEWIF base 64 string (with xor key `"toto titi tata"`): [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