diff --git a/.babelrc b/.babelrc index 945c87a8..5ccd6b58 100644 --- a/.babelrc +++ b/.babelrc @@ -8,6 +8,13 @@ "moduleName": "babel-runtime" } ], + ["module-resolver", { + "root": ["./common"], + "alias": { + "underscore": "lodash" + }, + "cwd": "babelrc" + }], "react-hot-loader/babel"], "presets": ["es2015", "react", "stage-0", "flow"], "env": { diff --git a/README.md b/README.md index 7d1b37bb..f358d9ab 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,20 @@ It generates app in `dist` folder. npm run test # run tests with Jest ``` +#### Derivation Check: +##### The derivation checker utility assumes that you have: +1. Docker installed/available +2. [dternyak/eth-priv-to-addr](https://hub.docker.com/r/dternyak/eth-priv-to-addr/) pulled from DockerHub + +##### Docker setup instructions: +1. Install docker (on macOS, I suggest [Docker for Mac](https://docs.docker.com/docker-for-mac/)) +2. `docker pull dternyak/eth-priv-to-addr` + +##### Run Derivation Checker +```bash +npm run derivation-checker +``` + ## Folder structure: ``` diff --git a/common/derivation-checker.js b/common/derivation-checker.js new file mode 100644 index 00000000..f42e5348 --- /dev/null +++ b/common/derivation-checker.js @@ -0,0 +1,55 @@ +import PrivKeyWallet from './libs/wallet/privkey'; +import assert from 'assert'; +const { exec } = require('child_process'); +const ProgressBar = require('progress'); + +// FIXME pick a less magic number +const derivationRounds = 100; +const dockerImage = 'dternyak/eth-priv-to-addr'; +const dockerTag = 'latest'; +const bar = new ProgressBar(':percent :bar', { total: derivationRounds }); + +function promiseFromChildProcess(command) { + return new Promise(function(resolve, reject) { + return exec(command, (err, stdout) => { + err ? reject(err) : resolve(stdout); + }); + }); +} + +async function privToAddrViaDocker(privKeyWallet) { + const command = `docker run -e key=${privKeyWallet.getPrivateKey()} ${dockerImage}:${dockerTag}`; + const dockerOutput = await promiseFromChildProcess(command); + const newlineStrippedDockerOutput = dockerOutput.replace( + /(\r\n|\n|\r)/gm, + '' + ); + return newlineStrippedDockerOutput; +} + +async function testDerivation() { + const privKeyWallet = PrivKeyWallet.generate(); + const privKeyWalletAddress = await privKeyWallet.getAddress(); + const dockerAddr = await privToAddrViaDocker(privKeyWallet); + // strip the checksum + const lowerCasedPrivKeyWalletAddress = privKeyWalletAddress.toLowerCase(); + // ensure that pyethereum privToAddr derivation matches our (js based) derivation + assert.strictEqual(dockerAddr, lowerCasedPrivKeyWalletAddress); +} + +async function testDerivationNTimes(n = derivationRounds) { + let totalRounds = 0; + while (totalRounds < n) { + await testDerivation(); + bar.tick(); + totalRounds += 1; + } +} + +console.log('Starting testing...'); +console.time('testDerivationNTimes'); +testDerivationNTimes().then(() => { + console.timeEnd('testDerivationNTimes'); + console.log(`Succeeded testing derivation ${derivationRounds} times :)`); + process.exit(0); +}); diff --git a/common/libs/wallet/privkey.js b/common/libs/wallet/privkey.js index 62404f14..f7fccb8a 100644 --- a/common/libs/wallet/privkey.js +++ b/common/libs/wallet/privkey.js @@ -8,7 +8,6 @@ import { import { randomBytes } from 'crypto'; import { pkeyToKeystore } from 'libs/keystore'; import { signRawTxWithPrivKey, signMessageWithPrivKey } from 'libs/signing'; - import { isValidPrivKey } from 'libs/validators'; import type { RawTransaction } from 'libs/transaction'; import type { UtcKeystore } from 'libs/keystore'; diff --git a/package-lock.json b/package-lock.json index e9a8e282..81cde8a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -760,6 +760,17 @@ "integrity": "sha1-SuKgTqYSpuc2UfP95SwXiZEwS+o=", "dev": true }, + "babel-plugin-module-resolver": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-2.7.1.tgz", + "integrity": "sha1-GL48Qt31n3pFbJ4FEs2ROU9uS+E=", + "dev": true, + "requires": { + "find-babel-config": "1.1.0", + "glob": "7.1.2", + "resolve": "1.3.3" + } + }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", @@ -3667,6 +3678,12 @@ "user-home": "2.0.0" }, "dependencies": { + "progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "dev": true + }, "user-home": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", @@ -4260,6 +4277,16 @@ } } }, + "find-babel-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.1.0.tgz", + "integrity": "sha1-rMAQQ6Z0n+w0Qpvmtk9ULrtdY1U=", + "dev": true, + "requires": { + "json5": "0.5.1", + "path-exists": "3.0.0" + } + }, "find-cache-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", @@ -9878,9 +9905,9 @@ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", "dev": true }, "promise": { diff --git a/package.json b/package.json index 767d62fb..329162cb 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "babel-core": "^6.23.1", "babel-eslint": "^7.1.1", "babel-loader": "^7.1.1", + "babel-plugin-module-resolver": "^2.7.1", "babel-plugin-transform-react-constant-elements": "^6.23.0", "babel-plugin-transform-react-inline-elements": "^6.22.0", "babel-plugin-transform-react-jsx": "^6.23.0", @@ -79,6 +80,7 @@ "nodemon": "^1.11.0", "null-loader": "^0.1.1", "prettier": "^1.5.3", + "progress": "^2.0.0", "react-addons-perf": "^15.4.2", "react-hot-loader": "^3.0.0-beta.6", "redux-devtools-extension": "^2.13.0", @@ -102,6 +104,7 @@ "dev": "node webpack_config/server.js", "predev": "check-node-version --package", "flow": "flow", + "derivation-checker": "babel-node common/derivation-checker.js --presets es2015,stage-0,flow", "start": "npm run dev", "precommit": "lint-staged" },