SIP: 32
Title: Hierarchically Deterministic Node IDs
Author: Lily Anne Hall
Braydon Fuller
Shawn Wilkinson
Status: Active
Type: Standard
Created: 2016-10-17
This document describes hierarchically deterministic node IDs for the purposes of running a cluster of renter nodes that can all share the same contracts with farmers.
The specification extends bitcoin ECDSA derivation standard BIP32 and BIP43, and extends both contacts and contracts with new fields and message and contract verification.
To more evenly distribute shards in the network when running a cluster of renter nodes. By using a hierarchically determined key, contracts can reference the renter_hd_key
such that a renter node can use a derived key renter_hd_index
and act an behalf of the renter_hd_key
. The nodeID
will use the derived key for more evenly distributed Kademlia routing.
Key derivation must match the specification of Bitcoin Hierarchical Deterministic Wallets (BIP32) with the purpose field described in Bitcoin Purpose Field for Deterministic Wallets (BIP43).
We define the following levels in BIP32 path:
m / purpose' / group_index' / node_index
Apostrophe in the path indicates that BIP32 hardened derivation is used.
Purpose is a constant set to 3000, so as to not collide with any bitcoin related proposals which recommends to use the BIP number.
m / 3000' / group_index' / node_index
The group_index
for most purposes will be 0. However is reserved for a future use to be able to increment in the case that the contracts should be updated with a new key.
The node_index
can be a number from 0 through 2 ^ 31 - 1, so that it’s using a non-hardened paths and it’s always possible to derive the public key for a node using the m / 3000' / group_index'
derived extended public key. This gives a total of 2.147 billion possible nodes to run in a group cluster.
Security Note: As noted in BIP32, a compromised private key at the node_index
level in combination with the extended public key at the group_index
level will compromise all descending private keys derived from the group_index
level, this is the rationale for a hardened path for the group_index
.
This specification extends the message format for a contact to include hdKey
and hdIndex
.
{
"contact": {
"address": "10.0.0.2",
"port": 1337,
"nodeID": "89cc3ddb4209c6e7e301c10c0257adf4fd85f253",
"hdKey": "xpub...",
"hdIndex": 12,
"protocol": "0.7.2"
}
}
The hdKey
is the extended public key derived from m / 3000' / group_index'
and uses the same serialization format described in BIP32, and as recommended in BIP43, a base58 encoded string.
If the hdKey
is present, nodes must validate that a message is signed by the key derived from the hdKey
at the index hdIndex
, and that the hash160 (sha256 and ripemd160) of that derived public key matches the nodeID
.
Two new fields are added to a contract renter_hd_key
and renter_hd_index
. The serialization will be identical to the serialization for the contacts.
A contract with a renter_hd_key
can be authenticated for any contact that has a matching hdKey
and with any hdIndex
. The contract itself must be signed by the corresponding renter_hd_key
and renter_hd_index
. The contract renter_id
is the sha256 and then ripemd hash of the serialized public key of the derived key, and this renter will receive the offer for the contract from the farmer, while any of the sibling renters should be able to act on behalf of the contract.
Because there are new fields being added to both contact and contract, new renters will require that farmers have also been upgraded to use the functionality.
https://github.com/braydonf/storj-lib/tree/hdkeys