Skip to content

Deterministic Keypair Generation Method

gz-c edited this page Jul 3, 2019 · 3 revisions

Skycoin has a custom deterministic keypair generation method. Wallets which use this method have the deterministic type. The method is described below:

Initial seed

The initial seed is any arbitrary byte array. By default, skycoin uses the byte array representation of a bip39 mnemonic string. Note: this is NOT a bip39 seed, it is just the mnemomic as bytes. This seed is stored in the wallet file metadata as a string (if using arbitrary bytes, you should hex encode the string, but note that the seed will become the hex-encoded bytes, and not the decoded bytes).

Iterative step

The deterministic iteration step is defined as follows:

Define a function findSecretKey:

  1. Compute k = sha256(b), where b is an sha256 digest
  2. If k is an invalid secret key, compute k = sha256(k)
  3. Repeat the previous step until k is a valid secret key
  4. Return k

Define a function secp256k1Hash:

  1. Compute h = sha256(seed), where seed is a byte array with sufficient entropy
  2. Compute k = findSecretKey(h)
  3. Compute p = pubkeyOf(findSecretKey(sha256(h))). Note that sha256(h) is usually equal to k, but not if sha256(h) is not a valid secret key.
  4. Compute e = ecmult(p, k), where ecmult is the elliptic curve point multiplication operation (i.e. e = p * k mod G)
  5. Compute d = sha256(h || e)
  6. Return d

Using the previous definitions, define the generation method X as:

  1. Compute a = secp256k1Hash(seed), where seed is a byte array with sufficient entropy
  2. Compute b = sha256(seed || a)
  3. Compute k = findSecretKey(b)
  4. Return k as the secret key and a as the seed for the next iteration

Pseudocode to generate a chain of keys from a seed:

# initial seed can be any arbitrary bytes
# use something with at least 128 bits of entropy
seed = sha256("foo bar baz quz qux")  
var secKeys[10]
for i = 0; i < 10; i++ {
  secKeys[i], seed = X(seed)
}
Clone this wiki locally