Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • documents/rfcs
  • matograine/rfcs
  • 1000i100/rfcs
  • LukeMarlin/rfcs
  • tuxmain/rfcs
  • pokapow/rfcs
6 results
Select Git revision
Loading items
Show changes
Commits on Source (36)
...@@ -13,6 +13,8 @@ All documents should be implementation agnostic, as specific documentations shou ...@@ -13,6 +13,8 @@ All documents should be implementation agnostic, as specific documentations shou
### Approved RFCs ### Approved RFCs
* RFC_0013: [Duniter Encrypted Wallet Import Format](rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md)
#### DUniter Blockchain Protocol (DUBP) #### DUniter Blockchain Protocol (DUBP)
* V11: [RFC 0009](rfc/0009_Duniter_Blockchain_Protocol_V11.md) * V11: [RFC 0009](rfc/0009_Duniter_Blockchain_Protocol_V11.md)
...@@ -24,17 +26,20 @@ All documents should be implementation agnostic, as specific documentations shou ...@@ -24,17 +26,20 @@ All documents should be implementation agnostic, as specific documentations shou
### Under discussion RFCs ### Under discussion RFCs
* RFC_0007: [Duniter Ascii Armor Messages](https://git.duniter.org/nodes/common/doc/blob/ascii_armor_messages/rfc/0007%20Ascii%20Armor%20Messages.md) * 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/nodes/common/doc/blob/messages_encryption_and_signature/rfc/0008%20Messages%20Encryption%20and%20Signature.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_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)
* RFC_0017: [Encrypt tx commnent](https://git.duniter.org/documents/rfcs/blob/tx_comment_encrypt/rfc/0017_transaction_comment_encryption.md)
### Drafts RFCs ### Drafts RFCs
* RFC_0003: [GraphQL API for Duniter Clients](https://git.duniter.org/nodes/common/doc/blob/graphql_api_rfc/rfc/0003%20RFC%20GraphQL%20API%20for%20Duniter%20Clients.md) * RFC_0003: [GraphQL API for Duniter Clients](https://git.duniter.org/documents/rfcs/blob/graphql_api_rfc/rfc/0003%20RFC%20GraphQL%20API%20for%20Duniter%20Clients.md)
* RFC_0006: [DUniter Network Protocol V2](https://git.duniter.org/nodes/common/doc/blob/ws2p_v2/rfc/0006_ws2p_v2.md) * RFC_0006: [DUniter Network Protocol V2](https://git.duniter.org/documents/rfcs/blob/ws2p_v2/rfc/0006_ws2p_v2.md)
* RFC_0011: [Public Key Secure Transport Layer V1](https://git.duniter.org/nodes/common/doc/blob/ws2p_v2/rfc/0011_pkstl_v1.md) * RFC_0011: [Public Key Secure Transport Layer V1](https://git.duniter.org/documents/rfcs/blob/ws2p_v2/rfc/0011_pkstl_v1.md)
* RFC_0011: [Duniter_Blockchain_Protocol_V13](https://git.duniter.org/nodes/common/doc/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md) * RFC_0011: [Duniter_Blockchain_Protocol_V13](https://git.duniter.org/documents/rfcs/blob/dubp_v13/rfc/0011_Duniter_Blockchain_Protocol_V13.md)
* RFC_0012: [Duniter Key File Format](https://git.duniter.org/nodes/common/doc/blob/authentication_file_format/rfc/0012_duniterkey_authentication_file_format_v1.md) * RFC_0012: [Duniter Key File Format](https://git.duniter.org/documents/rfcs/blob/authentication_file_format/rfc/0012_duniterkey_authentication_file_format_v1.md)
* RFC_0013: [Duniter Encrypted Wallet Import Format](https://git.duniter.org/nodes/common/doc/blob/dewif/rfc/0013_Duniter_Encrypted_Wallet_Import_Format.md) * RFC_0015: [HD wallet](https://git.duniter.org/documents/rfcs/blob/hd_wallet/rfc/0015_Dubp_HD_Wallet.md)
### Discontinued RFCs ### Discontinued RFCs
......
...@@ -249,8 +249,8 @@ Accepted since duniter-ts **v1.6.0** ...@@ -249,8 +249,8 @@ Accepted since duniter-ts **v1.6.0**
#### message field #### message field
API = "WS2P" API = `WS2P`
MESSAGE_TYPE = "HEAD" MESSAGE_TYPE = `HEAD`
PUBKEY := public key of the issuer node of this head PUBKEY := public key of the issuer node of this head
BLOCKSTAMP = `blockNumber-Hash` BLOCKSTAMP = `blockNumber-Hash`
...@@ -263,7 +263,7 @@ sig: ed25519 signature of the message field in base64. ...@@ -263,7 +263,7 @@ sig: ed25519 signature of the message field in base64.
Accepted since duniter-ts **v1.6.9** Accepted since duniter-ts **v1.6.9**
{ {
"message": String("API:MESSAGE_TYPE:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"), "message": String("API:MESSAGE_TYPE:HEAD_VERSION:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"),
"sig": String("MY90zXICfbYhLlz8VrL4HWPkphZEFR+bT2JWsoKdDMadgn0R0ZjsowDsnlfNqX4F4qeWeFoxhvdVgTO9VSghCA==") "sig": String("MY90zXICfbYhLlz8VrL4HWPkphZEFR+bT2JWsoKdDMadgn0R0ZjsowDsnlfNqX4F4qeWeFoxhvdVgTO9VSghCA==")
} }
...@@ -271,6 +271,7 @@ Accepted since duniter-ts **v1.6.9** ...@@ -271,6 +271,7 @@ Accepted since duniter-ts **v1.6.9**
API = `WS2P` API = `WS2P`
MESSAGE_TYPE = `HEAD` MESSAGE_TYPE = `HEAD`
HEAD_VERSION = 1
PUBKEY := public key of the issuer node of this head PUBKEY := public key of the issuer node of this head
BLOCKSTAMP = `blockNumber-Hash` BLOCKSTAMP = `blockNumber-Hash`
WS2PID := unique identifier of the ws2p endpoint WS2PID := unique identifier of the ws2p endpoint
...@@ -288,9 +289,9 @@ Accepted since duniter-ts **v1.6.9**, relayed fully since duniter-ts **v1.6.15** ...@@ -288,9 +289,9 @@ Accepted since duniter-ts **v1.6.9**, relayed fully since duniter-ts **v1.6.15**
_Nodes with versions lower than 1.6.15 bounce a degraded version of the head, only `message` and `sig` fields are relayed._ _Nodes with versions lower than 1.6.15 bounce a degraded version of the head, only `message` and `sig` fields are relayed._
{ {
"message": String("API:HEAD:1:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"), "message": String("API:HEAD:HEAD_VERSION:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX"),
"sig": String("TPh2A3NS8cHj8yrJk1Yeldx2H6bPEp46cFAGZXKfxJcNgXL2sWrlirhIOlp8pkUFSrwDawWY1zO1jlgUqMvlAg=="), "sig": String("TPh2A3NS8cHj8yrJk1Yeldx2H6bPEp46cFAGZXKfxJcNgXL2sWrlirhIOlp8pkUFSrwDawWY1zO1jlgUqMvlAg=="),
"messageV2": String("API:HEAD:2:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX:FREE_MEMBER_ROOM:FREE_MIRROR_ROOM"), "messageV2": String("API:HEAD:HEAD_VERSION:PUBKEY:BLOCKSTAMP:WS2PID:SOFTWARE:SOFT_VERSION:POW_PREFIX:FREE_MEMBER_ROOM:FREE_MIRROR_ROOM"),
"sigV2": String("ta1lRrWsjGcYHcLdS75JgEW5B8ByRetFVUVVpakKNJBirhRe8HcYUHEOM7xj/+gUQGGOit6Gm5Q/lsvfsngWAQ=="), "sigV2": String("ta1lRrWsjGcYHcLdS75JgEW5B8ByRetFVUVVpakKNJBirhRe8HcYUHEOM7xj/+gUQGGOit6Gm5Q/lsvfsngWAQ=="),
"step": Number(0) "step": Number(0)
} }
...@@ -299,11 +300,12 @@ _Nodes with versions lower than 1.6.15 bounce a degraded version of the head, on ...@@ -299,11 +300,12 @@ _Nodes with versions lower than 1.6.15 bounce a degraded version of the head, on
API := field indicating the network layer type and giving some information about the Network configuration. (See section "API field" for details) API := field indicating the network layer type and giving some information about the Network configuration. (See section "API field" for details)
MESSAGE_TYPE = `HEAD` MESSAGE_TYPE = `HEAD`
HEAD_VERSION = 2
PUBKEY := public key of the issuer node of this head PUBKEY := public key of the issuer node of this head
BLOCKSTAMP = `blockNumber-Hash` BLOCKSTAMP = `blockNumber-Hash`
WS2PID := unique identifier of the ws2p endpoint WS2PID := unique identifier of the ws2p endpoint
SOFTWARE = `duniter-ts` SOFTWARE = `duniter-ts`
SOFT_VERSION = `X.Y.Z` (for example `1.6.14`) SOFT_VERSION = `X.Y.Z-suffix` (for example `1.6.14-beta`)
POW_PREFIX := nonce prefix for proof of work (manually fixed by the user) POW_PREFIX := nonce prefix for proof of work (manually fixed by the user)
FREE_MEMBER_ROOM := Number of incoming connection requests that can still be accepted from member nodes (FREE_MIROR_ROOM - Number of incoming connections established by non-priority mirror nodes). FREE_MEMBER_ROOM := Number of incoming connection requests that can still be accepted from member nodes (FREE_MIROR_ROOM - Number of incoming connections established by non-priority mirror nodes).
FREE_MIROR_ROOM := An integer indicating the number of incoming connections that the node can still receive. FREE_MIROR_ROOM := An integer indicating the number of incoming connections that the node can still receive.
......
...@@ -980,6 +980,7 @@ Actives | `IN` memberships (renewal) | Alwa ...@@ -980,6 +980,7 @@ Actives | `IN` memberships (renewal) | Alwa
Leavers | `OUT` memberships | Always Leavers | `OUT` memberships | Always
Revoked | Revocation documents | Always Revoked | Revocation documents | Always
Excluded | Exluded members' public key | Always Excluded | Exluded members' public key | Always
Certifications | Certification documents | Always
Transactions | A list of compact transactions | Always Transactions | A list of compact transactions | Always
InnerHash | The hash value of the block's inner content | Always InnerHash | The hash value of the block's inner content | Always
Nonce | An arbitrary nonce value | Always Nonce | An arbitrary nonce value | Always
......
# 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
# 0016 Checksum for Duniter public keys
```txt
RFC: 0016
Title: Checksum for Duniter public keys
Type: Convention
Status: Proposed Standard
Author: matograine <matograine@zaclys.net>
Created: 2021-03-07
Last edited: 2021-03-07
License: AGPL-3
```
## Sources
This document proposes an enhancement on Tortue's standard for public key checksum:
https://github.com/Tortue95/Duniter_Paper_Wallet/blob/master/Duniter_Auth_Protocol.md
For compatibility, clients MAY accept checksum based on this last standard for user inputs.
## Public key format
A public key is to be understood as an Ed25519 public key.
It is represented as a Base58 string which length ranges {43,44} characters.
Example of a public key:
```
J4c8CARmP9vAFNGtHRuzx14zvxojyRWHW2darguVqjtX
```
Example of two valid public keys referring to the same Ed25519 binary public key:
```
12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx
2BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx
```
When converting a public key to its binary representation, the length of the bytes array MUST be verified.
- If the length of the array is inferior to 32, zero-bytes MUST be prepended.
- If the length of the array is superior to 32, leading zero-bytes MUST be removed.
- If there is one leading non-zero byte and length is superior to 32, then the public key is not valid.
```python
# convert public key string to bytes
pubkey_byte = bytearray(base58.b58decode(pubkey))
# prepend zero-bytes until the public key is 32 bytes long
while len(pubkey_byte) < 32:
pubkey_byte = bytearray(b"\x00") + pubkey_byte
# remove leading zero-bytes if length is superior to 32
while len(pubkey_byte) > 32:
if pubkey_byte[0] == 0:
del pubkey_byte[0]
# raise error if leading byte is not null
else:
raise ValueError("Invalid public key: bytes length is too long")
```
## Checksum display
The checksum aims at verifying the consistency of the public key.
It consists in three (3) base58 characters.
It is displayed after the public key, separated by a colon `:`.
Example of two valid representations of a public key with their checksum:
```
12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8BD
2BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8BD
```
This function is used when a public key is typed manually on the keyboard (or issue on QRcode reader)
to avoid sending coins to the wrong public key. Because no control exist on the Duniter protocol.
This technique is better than adding only some checksum bytes at the end of the key, before the base58.encode because:
- The public key visible for the user is the same.
- If the user miss some characters, the software client can detect it.
- The checksum is not mandatory
### Short form
When displaying a public key on little space, a short form can be used for public keys.
This short form consists in:
* the 4 first characters of the public key
* the ellipsis character `…`
* the 4 last characters of the public key
* a colon `:`
* the checksum
Example of short-form public keys with checksum:
```
12Bj…v2nx:8BD
2Bjy…v2nx:8BD
```
Short form CAN be used for user input, only in research fields.
In that case, users will probably use three points `...` instead of an ellipsis `…`.
Short form MUST NOT be used as a direct input of a public key.
For accessibility, a color CAN be used to display the checksum.
In that case, the same color MUST be used for the separating colon.
## Compute the checksum
To compute the checksum:
0) use the binary representation of the public key :
for simplification we use a pubkey that is 32 bits long once decoded.
`pubkey = bytearray(base58.b58decode("J4c8CARmP9vAFNGtHRuzx14zvxojyRWHW2darguVqjtX"))`
1) `sha256(pubkey)`
`0x47c7aee49dfb9bea99949d04623281d8ad6188be8f6a698b0eb5994fa44d0a67`
2) `Base58.encode(sha256(pubkey))`
`5qCYkJMWgNA54gZz4HMQLbxL5btDmTS3EuHHCTcJaqGi`
3) We only take the 3 first characters of this value to get the checksum
`5qC`