# SLIP-0017 : ECDH using deterministic hierarchy ``` Number: SLIP-0017 Title: ECDH using deterministic hierarchy Type: Standard Status: Final Authors: Roman Zeyde Created: 2016-05-29 ``` ## Abstract This document describes a method for implementing Elliptic Curve Diffie-Hellman algorithm, using a determinstic hierarchy. ## Motivation Using Deterministic Hierarchy for encryption and decryption is ideal, because the same concepts of easy backup that relate to backing up deterministic wallets can be applied to backing up private keys. ## Service Identity Let's introduce the service identity. It consists of two elements: a) RFC 3986 URI `proto://[user@]host[:port][/path]` Examples: * `https://example.com` * `ftp://public@example.com/pub` * `ssh://root@example.com:2222` b) index (32-bit unsigned integer) The index is used so one can generate more keys corresponding to the same URI. ## HD Structure 1. First concatenate `index` with the URI (`uri`). Use little endian for `index`. 2. Compute the SHA256 hash of the result (`hash`). 3. Truncate `hash` to 128 bits (`hash128`) 4. Split `hash128` into four 32-bit integers `A`, `B`, `C`, `D`. Use little endian for each. 5. Set highest bits of numbers `A`, `B`, `C`, `D` to 1 (e.g. logical OR with 0x80000000) to harden 6. Derive the HD node `m/17'/A'/B'/C'/D'` according to SLIP-0010. ## Shared secret generation Suppose that Alice and Bob need to agree on a shared secret. First, they agree on a specific elliptic curve and generate two public keys: `P1 = k1*G` for Alice and `P2 = k2*G` for Bob. In order to derive a shared secret, Alice retrieves Bob's public key (P2). Then, she calls `Q = GetECDHSessionKey(P2)` API on her TREZOR, to compute `Q = k1*P2`, by multiplying Bob's public key `P2` (as an elliptic curve point) by her private key `k1` (as a 256-bit scalar). The result is the elliptic curve point `Q = k1*k2*P`, which can be computed in a similar way by Bob (since `Q = k2*P1`), is used to derive a shared secret. ## Worked example 1. `index + uri`=`42` + `https://nvsaberhagen@getmonero.org/login` 2. `sha256(index + uri)` = `f8be2155d1323418dc94a20c74bfdb7ab418eb7b061b38729193870405dd3875` 3. `hash128` = `f8be2155d1323418dc94a20c74bfdb7a` 4. `A` = 1428274936 (0x5521bef8), `B` = 406074065 (0x0x183432d1), `C` = 211981532 (0x0ca294dc), `D` = 2061221748 (0x7adbbf74) 5. `A'` = 3575758584, `B'` = 2553557713, `C'` = 2359465180, `D'` = 4208705396 6. `HD node path` = `m/2147483665/3575758584/2553557713/2359465180/4208705396` ## References * [BIP-0043: Purpose Field for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki) * [RFC 3986: Uniform Resource Identifier (URI): Generic Syntax](https://tools.ietf.org/html/rfc3986) * [SLIP-0010: Universal private key derivation from master private key](https://github.com/satoshilabs/slips/blob/master/slip-0010.md)