Skycoin has a custom deterministic keypair generation method. Wallets which use this method have the deterministic
type. The method is described below:
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).
The deterministic iteration step is defined as follows:
Define a function findSecretKey
:
- Compute
k = sha256(b)
, whereb
is an sha256 digest - If
k
is an invalid secret key, computek = sha256(k)
- Repeat the previous step until
k
is a valid secret key - Return
k
Define a function secp256k1Hash
:
- Compute
h = sha256(seed)
, where seed is a byte array with sufficient entropy - Compute
k = findSecretKey(h)
- Compute
p = pubkeyOf(findSecretKey(sha256(h)))
. Note thatsha256(h)
is usually equal tok
, but not ifsha256(h)
is not a valid secret key. - Compute
e = ecmult(p, k)
, whereecmult
is the elliptic curve point multiplication operation (i.e.e = p * k mod G
) - Compute
d = sha256(h || e)
- Return
d
Using the previous definitions, define the generation method X
as:
- Compute
a = secp256k1Hash(seed)
, where seed is a byte array with sufficient entropy - Compute
b = sha256(seed || a)
- Compute
k = findSecretKey(b)
- Return
k
as the secret key anda
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)
}