diff --git a/rfc/0016_public_key_checksum.md b/rfc/0016_public_key_checksum.md index 9cd96ed9aa9a267d4f8899b3072b15ed2f8b8c0f..6478615e85c02588d6efb7e7967c2bde1c85d238 100644 --- a/rfc/0016_public_key_checksum.md +++ b/rfc/0016_public_key_checksum.md @@ -15,6 +15,7 @@ License: AGPL-3 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 @@ -33,14 +34,25 @@ Example of two valid public keys referring to the same Ed25519 binary public ke ``` 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 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 @@ -51,8 +63,8 @@ It is displayed after the public key, separated by a colon `:`. Example of two valid representations of a public key with their checksum: ``` -12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8pQ -2BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8pQ +12BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8BD +2BjyvjoAf5qik7R8TKDJAHJugsX23YgJGi2LmBUv2nx:8BD ``` This function is used when a public key is typed manually on the keyboard (or issue on QRcode reader) @@ -76,8 +88,8 @@ This short form consists in: Example of short-form public keys with checksum: ``` -12Bj…v2nx:8pQ -2Bjy…v2nx:8pQ +12Bj…v2nx:8BD +2Bjy…v2nx:8BD ``` Short form CAN be used for user input, only in research fields. @@ -91,18 +103,15 @@ In that case, the same color MUST be used for the separating colon. To compute the checksum: -0) use the binary representation of the public key : +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)` +1) `sha256(pubkey)` `0x47c7aee49dfb9bea99949d04623281d8ad6188be8f6a698b0eb5994fa44d0a67` -2) `sha256(sha256(pubkey))` -`0x04a7ad22fbe357fbf5f58b2996fe5840fa2f977b9f6aa4c62575e68f75882672` - -3) `Base58.encode(sha256(sha256(pubkey))` -`KAvdGW7rpV68WDQPVN2TCrCoyvAHqMK1nSTS8y68bmB` - -4) We only take the 3 first characters of this value to get the checksum -`KAv` +2) `Base58.encode(sha256(pubkey))` +`5qCYkJMWgNA54gZz4HMQLbxL5btDmTS3EuHHCTcJaqGi` +3) We only take the 3 first characters of this value to get the checksum +`5qC`