Created
July 13, 2018 08:30
-
-
Save XuNeal/9e87e46143f7d5f6ee6fad1fadc528b9 to your computer and use it in GitHub Desktop.
Mnemonic to EOS PrivateKey
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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