diff --git a/README.md b/README.md index d4f2026443275e506c72dca6473a58fbb3ff571a..c73cba5322108dee5cadbd05316aab50d02a5a02 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md b/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md new file mode 100644 index 0000000000000000000000000000000000000000..02c6505ac58e4277e73ad18ba21dc88d477494d7 --- /dev/null +++ b/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md @@ -0,0 +1,207 @@ +# 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