Skip to content
Snippets Groups Projects

WIP: RFC 0012 : authentication file format first draft

Open Vincent Texier requested to merge authentication_file_format into master
Files
2
```txt
RFC: 12
Title: RFC Format
Type: Convention
Status: Draft
Author: vit
Created: 2020-02-12
Last edited: 2020-02-12
License: GPL-3
```
# Duniterkey Authentication File Format
This document serves as a reference for the `.duniterkey` authentication file format.
## Limitations
This format is a container format. Its main caveat is that you can have inside a data not be compatible with your application.
This is the same problem as video containers. The video codec inside the container can be unreadable by your application.
## File format extension
The official extension is `.duniterkey`.
## Text File Format
This format is inspired by [the Yaml format](https://yaml.org/spec/1.2/spec.html) for human readability.
The charset is utf-8 and the newline are unix style (\n).
So it is a yaml formatted file containing root fields of the form:
```yaml
Type: string
Version: int
data_field_1: data_value_1
[data_field_n: data_value_n]
```
## Header fields
The first two fields are the header of the file. Their purpose is to know how to treat the following data fields.
### Type field
The first field is the `Type` field. Its value is a string id identifying the type of data in the file.
Recognized values are:
* `PubSec`
* `WIF`
* `EWIF`
### Version field
The second field is the `Version` field. Its value is an integer specifying a version for the following data.
## Data fields
After the header fields come the data fields. This number and the name of the fields depend on the type of data.
### PubSec fields
The PubSec fields are as follow:
```yaml
Type: PubSec
Version: 1
pub: base58(public_key_bytes)
sec: base58(secret_key_bytes)
```
`public_key_bytes` is the public key in bytes.
`secret_key_bytes` is the secret key in bytes.
### WIF fields
The WIF fields are as follow:
```yaml
Type: WIF
Version: 1
Data: base58(data_bytes)
```
Where
```shell script
data_bytes = format_byte + seed_bytes + checksum_bytes
```
Where
```shell script
format_byte = \x01
checksum_bytes = sha256(sha256(format_byte + seed_bytes))[0:2]
```
`format_byte` is one byte with value 1 for the WIF format.
`seed_bytes` is the seed in bytes of the key pair.
`checksum_bytes` are the two first bytes of a two pass sha256 hash of the `format_byte` concatenated to the `seed_bytes`.
### EWIF fields
The EWIF fields are as follow:
```yaml
Type: EWIF
Version: 1
Data: base58(seed_bytes + checksum_bytes)
```
Where
```shell script
checksum_bytes = sha256(sha256(seed_bytes))[0:2]
```
Where
```shell script
seed_bytes = \x02 + salt + encrypted_half_1 + encrypted_half_2
```
Where
```shell script
salt = sha256(sha256(pubkey_bytes))[0:4]
password_bytes = bytes(password_utf8_string)
scrypt_seed = scrypt(password_bytes, salt, n=16384, r=8, p=8, length=64)
derived_half_1 = scrypt_seed[0:32]
derived_half_2 = scrypt_seed[32:64]
seed1_xor_derived_half_1a = bytes(xor_bytes(original_seed_bytes[0:16], derived_half_1[0:16]))
seed2_xor_derived_half_1b = bytes(xor_bytes(original_seed_bytes[16:32], derived_half_1[16:32]))
encrypted_half_1 = aes256.encrypt(seed1_xor_derived_half_1a, key=derived_half_2)
encrypted_half_2 = aes256.encrypt(seed2_xor_derived_half_1b, key=derived_half_2)
seed_bytes = \x02 + salt + encrypted_half_1 + encrypted_half_2
```
`password_utf8_string` is the password string in utf-8 used to encrypt the seed.
`pubkey_bytes` is the public key in bytes used to create the `salt` value.
`original_seed_bytes` is the original seed in bytes of the key pair.
This document can be completed and improved by Tortue document:
https://tmp.tednet.fr/paperwallet/AddressFormat.html
Thanks to him for his work.
End of document
\ No newline at end of file
Loading