According to this github issue page it turns out the answer is the private key is not generated as part of the node structure but instead the result of HMACing the first 32 bytes of the the entropy. An example below
import hdkey from 'ethereumjs-wallet/hdkey';
import ethwallet from 'ethereumjs-wallet';
import ethtx from 'ethereumjs-tx';
import bip39 from 'bip39';
const mnemonic = bip39.generateMnemonic();
console.log(`Mnemonic: ${mnemonic}`);
const root = hdkey.fromMasterSeed(bip39.mnemonicToSeed(mnemonic));
const derivedNode = root.derivePath("m/44'/60'/0'/0");
const address = this.generateAddress(derivedNode);
console.log(`Private Key: ${root._hdkey.privateKey.toString('hex')}`);
The actual private key generation occurs in hdkey
(1) I could use keccack256 online tool to transform a word to a private key. Would this be a valid key ?
Any 256-bit number is a valid private key, so yes, it would be a valid key. But this isn't enough entropy to generate a secure private key. I could just run every word in the dictionary through keccak256()
(and every other widely used hash function that generates 256-bit numbers) and check whether there are any funds associated with each private key until I find yours.
The whole idea behind using 12-24 dictionary words as the seed is to make the entropy sufficient to make it secure.
https://xkcd.com/936/
You can't have both the seed and the hash function known or easy-to-guess. (keccak256()
is known, dictionary words are easy to guess.)
So how is it possible to generate a private key from a single word.
You have 2 choices:
- Use a difficult-to-guess seed with a known hash function, or
- Use a difficult-to-guess hash function with an easy-to-guess seed
For the first option, you could use a password manager to generate a secure password, then run that through keccak256()
or any other hash function that can give you a 256-bit number. However, your secure password (high entropy) doesn't come under your definition of "mnemonic".
For the second option, you would need to run your chosen dictionary word (low entropy) through a hash function you had written yourself (or, alternatively, a series of known hash functions in an order only you know).
Best Answer
A private key in both bitcoin and ethereum is simply a random 256 bit number (actually a number between 0 and the order of the secp256k1 curve, but that's not really important).
If you can get your raw bitcoin public key, i.e.something like a random hex string of length 64, then it can be used directly as a raw ETH private key in any library or client.
For example, to import it into geth just use
for parity see How to import a plain private key into Parity?
To simply derive an address from the key in JS, you can use the keythereum library or ethereumjs-util
You can even use openssl, see https://kobl.one/blog/create-full-ethereum-keypair-and-address/