Skip to content

Instantly share code, notes, and snippets.

@XuNeal
Created July 13, 2018 08:30
Show Gist options
  • Save XuNeal/9e87e46143f7d5f6ee6fad1fadc528b9 to your computer and use it in GitHub Desktop.
Save XuNeal/9e87e46143f7d5f6ee6fad1fadc528b9 to your computer and use it in GitHub Desktop.
Mnemonic to EOS PrivateKey
class EOSKey {
// Generate EOS owner pk and active pk from mnemonic
private static List<byte[]> calcDefaultKeys(List<String> mnemonics, String path) {
// Step 1. Get chaincode at m/44'/194'
// EOS Coin type is defined at SLIP44 ref: https://github.com/satoshilabs/slips/blob/master/slip-0044.md
// We believe that chaincode are more private
MnemonicUtil.validateMnemonics(mnemonics);
DeterministicSeed seed = new DeterministicSeed(mnemonics, null, "", 0L);
DeterministicKeyChain keyChain = DeterministicKeyChain.builder().seed(seed).build();
DeterministicKey parent = keyChain.getKeyByPath(BIP44Util.generatePath(path), true);
byte[] chainCode = parent.getChainCode();
// Step 2. Generate MasterPrivateKey
byte[] chainIDBuffer = NumericUtil.hexToBytes(ChainId.EOS_MAINNET);
byte[] masterPrivateKeyBytes = Hash.hmacSHA256(chainIDBuffer, chainCode);
// Step3. Deriving the subkeys using the MasterPrivateKey
byte[] ownerKey = Hash.sha256(ByteUtil.concat(masterPrivateKeyBytes, "owner".getBytes(Charset.forName("UTF-8"))));
byte[] activeKey = Hash.sha256(ByteUtil.concat(ownerKey, "active".getBytes(Charset.forName("UTF-8"))));
// Why is sha256 hasing instead of BIP44? You can check this: https://github.com/EOSIO/eosjs-ecc/issues/7
// I pasted part of that as follow:
// For BIP44, EOS is different. It does not have change addresses. Change addresses in BIP44 are fine but for
// contract permissions that are not a good fit. Due to the elliptic curve math derived keys on the same
// hierarchical level have a weaker security profile that make them unsafe.
// For example, one private key and a chain code can revile all private keys at that level and lower levels.
// So, this is better suited for flat and redundant change addresses but not suited for more meaningful contract permissions.
//
// Deriving keys are done in binary and use only sha256 hashing that does not involve any elliptic curve math.
// So, while EOS needs something different it is actually easier to implement and understand.
List<byte[]> keys = new ArrayList<>(3);
keys.add(masterPrivateKeyBytes);
keys.add(ownerKey);
keys.add(activeKey);
return keys;
}
private void testCase() {
// Input:
// mnemonic = inject kidney empty canal shadow pact comfort wife crush horse wife sketch
// chainID = aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906
// Output: (test case checks public key not private key)
// ownerPublicKey = "EOS7tpXQ1thFJ69ZXDqqEan7GMmuWdcptKmwgbs7n1cnx3hWPw3jw"
// activePublicKey = "EOS5SxZMjhKiXsmjxac8HBx56wWdZV1sCLZESh3ys1rzbMn4FUumU"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment