Key derivation clarifications

This commit is contained in:
mDuo13
2019-09-09 18:37:06 -07:00
parent 83710c082a
commit dd2294e7a5
6 changed files with 120 additions and 38 deletions

View File

@@ -5,8 +5,8 @@
<id>UMLObject</id>
<coordinates>
<x>60</x>
<y>60</y>
<w>150</w>
<y>50</y>
<w>110</w>
<h>70</h>
</coordinates>
<panel_attributes>Passphrase
@@ -19,33 +19,34 @@ lt=.</panel_attributes>
<element>
<id>UMLObject</id>
<coordinates>
<x>350</x>
<y>60</y>
<w>180</w>
<x>320</x>
<y>50</y>
<w>130</w>
<h>70</h>
</coordinates>
<panel_attributes>Secret Key
<panel_attributes>Seed
--
</panel_attributes>
(16 bytes)</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>200</x>
<y>80</y>
<w>170</w>
<h>40</h>
<x>160</x>
<y>70</y>
<w>180</w>
<h>50</h>
</coordinates>
<panel_attributes>lt=&lt;.
SHA-512Half</panel_attributes>
<additional_attributes>150.0;20.0;10.0;20.0</additional_attributes>
SHA512, keep
first 16 bytes</panel_attributes>
<additional_attributes>160.0;20.0;10.0;20.0</additional_attributes>
</element>
<element>
<id>UMLObject</id>
<coordinates>
<x>650</x>
<y>60</y>
<x>60</x>
<y>180</y>
<w>220</w>
<h>70</h>
</coordinates>
@@ -58,21 +59,21 @@ SHA-512Half</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>520</x>
<x>160</x>
<y>80</y>
<w>150</w>
<h>50</h>
<w>600</w>
<h>120</h>
</coordinates>
<panel_attributes>lt=&lt;-
Public Key
Derivation</panel_attributes>
<additional_attributes>130.0;20.0;10.0;20.0</additional_attributes>
<additional_attributes>10.0;100.0;10.0;70.0;580.0;70.0;580.0;10.0;550.0;10.0</additional_attributes>
</element>
<element>
<id>UMLObject</id>
<coordinates>
<x>360</x>
<y>190</y>
<y>270</y>
<w>180</w>
<h>80</h>
</coordinates>
@@ -84,25 +85,28 @@ Derivation</panel_attributes>
<element>
<id>Relation</id>
<coordinates>
<x>300</x>
<y>120</y>
<w>440</w>
<h>130</h>
<x>270</x>
<y>180</y>
<w>220</w>
<h>160</h>
</coordinates>
<panel_attributes>lt=&lt;-
SHA-256 of RIPEMD160
RIPEMD160 of SHA-256
</panel_attributes>
<additional_attributes>60.0;90.0;10.0;90.0;10.0;40.0;420.0;40.0;420.0;10.0</additional_attributes>
<additional_attributes>90.0;110.0;40.0;110.0;40.0;40.0;10.0;40.0</additional_attributes>
</element>
<element>
<id>UMLObject</id>
<coordinates>
<x>690</x>
<y>190</y>
<y>270</y>
<w>180</w>
<h>80</h>
</coordinates>
@@ -116,7 +120,7 @@ Checksum (4 bytes)</panel_attributes>
<id>UMLObject</id>
<coordinates>
<x>60</x>
<y>190</y>
<y>270</y>
<w>190</w>
<h>80</h>
</coordinates>
@@ -130,7 +134,7 @@ Checksum (4 bytes)</panel_attributes>
<id>Relation</id>
<coordinates>
<x>240</x>
<y>230</y>
<y>310</y>
<w>140</w>
<h>30</h>
</coordinates>
@@ -141,7 +145,7 @@ Checksum (4 bytes)</panel_attributes>
<id>UMLObject</id>
<coordinates>
<x>400</x>
<y>320</y>
<y>400</y>
<w>100</w>
<h>70</h>
</coordinates>
@@ -154,7 +158,7 @@ Checksum (4 bytes)</panel_attributes>
<id>Relation</id>
<coordinates>
<x>490</x>
<y>230</y>
<y>310</y>
<w>120</w>
<h>140</h>
</coordinates>
@@ -165,7 +169,7 @@ Checksum (4 bytes)</panel_attributes>
<id>Relation</id>
<coordinates>
<x>530</x>
<y>210</y>
<y>290</y>
<w>80</w>
<h>30</h>
</coordinates>
@@ -176,7 +180,7 @@ Checksum (4 bytes)</panel_attributes>
<id>UMLState</id>
<coordinates>
<x>590</x>
<y>210</y>
<y>290</y>
<w>100</w>
<h>40</h>
</coordinates>
@@ -188,7 +192,7 @@ type=sender</panel_attributes>
<id>Relation</id>
<coordinates>
<x>420</x>
<y>260</y>
<y>340</y>
<w>130</w>
<h>80</h>
</coordinates>
@@ -196,4 +200,30 @@ type=sender</panel_attributes>
SHA-256 twice</panel_attributes>
<additional_attributes>10.0;60.0;10.0;10.0</additional_attributes>
</element>
<element>
<id>UMLObject</id>
<coordinates>
<x>600</x>
<y>50</y>
<w>110</w>
<h>70</h>
</coordinates>
<panel_attributes>Private Key
--
(32 bytes)</panel_attributes>
<additional_attributes/>
</element>
<element>
<id>Relation</id>
<coordinates>
<x>440</x>
<y>70</y>
<w>180</w>
<h>50</h>
</coordinates>
<panel_attributes>lt=&lt;-
Private Key
Derivation</panel_attributes>
<additional_attributes>160.0;20.0;10.0;20.0</additional_attributes>
</element>
</diagram>

View File

@@ -93,9 +93,9 @@ XRP Ledger addresses are encoded using [base58](https://en.wikipedia.org/wiki/Ba
The following diagram shows the relationship between keys and addresses:
![Passphrase → Secret Key → Public Key + Type Prefix → Account ID + Checksum → Address](img/key-address-rels.png)
![Passphrase → Seed → Private Key → Public Key + Type Prefix → Account ID + Checksum → Address](img/key-address-rels.png)
The formula for calculating an XRP Ledger address is as follows. For the complete example code, see [`encode_address.js`](https://github.com/ripple/ripple-dev-portal/blob/master/content/_code-samples/address_encoding/encode_address.js).
The formula for calculating an XRP Ledger address from a public key is as follows. For the complete example code, see [`encode_address.js`](https://github.com/ripple/ripple-dev-portal/blob/master/content/_code-samples/address_encoding/encode_address.js). For the process of deriving a public key from a passphrase or seed value, see [Key Derivation](cryptographic-keys.html#key-derivation).
1. Import required algorithms: SHA-256, RIPEMD160, and base58. Set the dictionary for base58.

View File

@@ -116,6 +116,58 @@ The supported types of key pairs can be used interchangeably throughout the XRP
In the future, it is likely that the XRP Ledger will need new cryptographic signing algorithms to keep up with developments in cryptography. For example, if quantum computers using [Shor's algorithm](https://en.wikipedia.org/wiki/Shor's_algorithm) (or something similar) will soon be practical enough to break elliptic curve cryptography, XRP Ledger developers can add a cryptographic signing algorithm that isn't easily broken. As of mid 2019, there's no clear first choice "quantum-resistant" signing algorithm and quantum computers are not yet practical enough to be a threat, so there are no immediate plans to add any specific algorithms. <!-- STYLE_OVERRIDE: will -->
## Key Derivation
The process of deriving a key pair depends on the signing algorithm. In all cases, keys are generated from a _seed_ value that is 16 bytes (128 bits) in length. The seed value can be completely random (recommended) or it can be derived from a specific passphrase by taking the [SHA-512 hash][Hash] and keeping the first 16 bytes (similar to [SHA-512Half][], but keeping only 128 bits instead of 256 bits of the output).
### Ed25519 Key Derivation
[[Source]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/protocol/impl/SecretKey.cpp#L203 "Source")
All 32-byte numbers are valid Ed25519 private keys, so Ed25519 private key derivation is a single step:
- Calculate the [SHA-512Half][] of the seed value. The result is the 32-byte private key.
To calculate an Ed25519 public key, use the standard public key derivation for [Ed25519](https://ed25519.cr.yp.to/software.html) to derive the public key. (As always with cryptographic algorithms, use a standard, well-known, publicly-audited implementation whenever possible. For example, [OpenSSL](https://www.openssl.org/) has implementations of core Ed25519 and secp256k1 functions.)
### secp256k1 Key Derivation
Key derivation for secp256k1 XRP Ledger keys involves more steps than Ed25519 key derivation for a couple reasons:
- Not all 32-byte numbers are valid secp256k1 private keys.
- The XRP Ledger's reference implementation has an unused, incomplete framework for deriving a family of key pairs from a single seed value.
The steps to derive a valid secp256k1 private key from a seed value are as follows:
1. Calculate a "root key pair" from the seed value, as follows:
1. Concatenate the following in order, for a total of 20 bytes:
- The seed value (16 bytes)
- A "root sequence" value (4 bytes), as a big-endian unsigned integer. Use 0 as a starting value for the root sequence.
2. Calculate the [SHA-512Half][] of the concatenated (seed+root sequence) value.
3. If the result is not a valid secp265k1 private key, increment the root sequence by 1 and start over. [[Source]](https://github.com/ripple/rippled/blob/fc7ecd672a3b9748bfea52ce65996e324553c05f/src/ripple/crypto/impl/GenerateDeterministicKey.cpp#L103 "Source")
A valid secp256k1 key must not be zero, and it must be numerically less than the _secp256k1 modulus_ (also called the "group order"). The secp256k1 modulus is the constant value `0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141`.
4. With a valid secp256k1 private key, use the standard ECDSA public key derivation with the secp256k1 curve to derive the root public key. (As always with cryptographic algorithms, use a standard, well-known, publicly-audited implementation whenever possible. For example, [OpenSSL](https://www.openssl.org/) has implementations of core Ed25519 and secp256k1 functions.)
2. Derive an intermediate key pair from the root public key you calculated in step 1, as follows:
1. Concatenate the following in order, for a total of 40 bytes:
- The root public key (32 bytes)
- `0x00000000000000000000000000000000` (4 bytes of zeroes). (This value was intended to be used to derive different members of the same family, but in practice only the value 0 is used.)
- A "key sequence" value (4 bytes), as a big-endian unsigned integer. Use 0 as a starting value for the key sequence.
2. Calculate the [SHA-512Half][] of the concatenated value.
3. If the result is not a valid secp265k1 private key, increment the key sequence by 1 and restart deriving the account's intermediate key pair.
4. With a valid secp256k1 private key, use the standard ECDSA public key derivation with the secp256k1 curve to derive the intermediate public key. (As always with cryptographic algorithms, use a standard, well-known, publicly-audited implementation whenever possible. For example, [OpenSSL](https://www.openssl.org/) has implementations of core Ed25519 and secp256k1 functions.)
3. Calculate the sum of the root public key and the intermediate public key. The result is the master public key. ***TODO: which private key do you use?***
## See Also
- **Concepts:**

View File

@@ -377,7 +377,7 @@ The response follows the [standard format][], with a successful result containin
| `cluster` | Object | Summary of other `rippled` servers in the same cluster, if [configured as a cluster](clustering.html). [New in: rippled 0.30.1][] |
| `peers` | Array | Array of peer objects. |
Each field of the `cluster` object is the public key of that `rippled` server's identifying keypair. (This is the same value that that server returns as `pubkey_node` in the [server_info method][].) The contents of that field are an object with the following fields:
Each field of the `cluster` object is the public key of that `rippled` server's identifying key pair. (This is the same value that that server returns as `pubkey_node` in the [server_info method][].) The contents of that field are an object with the following fields:
| `Field` | Type | Description |
|:--------|:-------|:----------------------------------------------------------|

View File

@@ -42,7 +42,7 @@ The `AccountRoot` object has the following fields:
| `Domain` | String | VariableLength | _(Optional)_ A domain associated with this account. In JSON, this is the hexadecimal for the ASCII representation of the domain. |
| `EmailHash` | String | Hash128 | _(Optional)_ The md5 hash of an email address. Clients can use this to look up an avatar through services such as [Gravatar](https://en.gravatar.com/). |
| `MessageKey` | String | VariableLength | _(Optional)_ A public key that may be used to send encrypted messages to this account. In JSON, uses hexadecimal. No more than 33 bytes. |
| `RegularKey` | String | AccountID | _(Optional)_ The address of a keypair that can be used to sign transactions for this account instead of the master key. Use a [SetRegularKey transaction][] to change this value. |
| `RegularKey` | String | AccountID | _(Optional)_ The address of a [key pair](cryptographic-keys.html) that can be used to sign transactions for this account instead of the master key. Use a [SetRegularKey transaction][] to change this value. |
| `TickSize` | Number | UInt8 | _(Optional)_ How many significant digits to use for exchange rates of Offers involving currencies issued by this address. Valid values are `3` to `15`, inclusive. _(Requires the [TickSize amendment][].)_ |
| `TransferRate` | Number | UInt32 | _(Optional)_ A [transfer fee](https://ripple.com/knowledge_center/transfer-fees/) to charge other users for sending currency issued by this account to each other. |
| `WalletLocator` | String | Hash256 | _(Optional)_ **DEPRECATED**. Do not use. |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 28 KiB