Skip to content

Commit

Permalink
BIP38 encrypt/decrypt WIFs on mainnet/testnet.
Browse files Browse the repository at this point in the history
  • Loading branch information
cloneearth committed Jun 14, 2018
1 parent 7e78f65 commit 17efef2
Show file tree
Hide file tree
Showing 7 changed files with 183 additions and 5 deletions.
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ let cmd = require('node-cmd');
// let ProgressBar = require('progress');

program
.version('1.0.2');
.version('1.0.3');

program
.command('new <name>')
Expand Down
29 changes: 29 additions & 0 deletions lib/BitcoinCash.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ var _coininfo = require('coininfo');

var _coininfo2 = _interopRequireDefault(_coininfo);

var _bip3 = require('bip38');

var _bip4 = _interopRequireDefault(_bip3);

var _wif = require('wif');

var _wif2 = _interopRequireDefault(_wif);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
Expand Down Expand Up @@ -187,6 +195,27 @@ var BitcoinCash = function () {

return Math.ceil(totalWeight / 4);
}
}, {
key: 'encryptBIP38',
value: function encryptBIP38(privKeyWIF, passphrase) {
var decoded = _wif2.default.decode(privKeyWIF);

return _bip4.default.encrypt(decoded.privateKey, decoded.compressed, passphrase);
}
}, {
key: 'decryptBIP38',
value: function decryptBIP38(encryptedKey, passphrase) {
var network = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'mainnet';

var decryptedKey = _bip4.default.decrypt(encryptedKey, passphrase);
var prefix = void 0;
if (network === 'testnet') {
prefix = 0xEF;
} else {
prefix = 0x80;
}
return _wif2.default.encode(prefix, decryptedKey.privateKey, decryptedKey.compressed);
}
}]);

return BitcoinCash;
Expand Down
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"name": "bitbox-cli",
"version": "1.0.2",
"version": "1.0.3",
"description": "A development framework for Bitcoin Cash",
"author": "@bitboxearth",
"main": "index.js",
"scripts": {
"test": "nyc mocha --require babel-core/register",
"test": "nyc mocha --timeout 15000 --require babel-core/register",
"build": "babel src/ -d lib/",
"flow": "flow"
},
Expand All @@ -28,6 +28,7 @@
"bchaddrjs": "^0.2.1",
"bigi": "^1.4.2",
"bip21": "bigearth/bip21",
"bip38": "^2.0.2",
"bip39": "^2.5.0",
"bip68": "^1.0.4",
"bitcoin-ops": "bigearth/bitcoin-ops",
Expand All @@ -54,7 +55,8 @@
"repl.history": "^0.1.4",
"safe-buffer": "^5.1.2",
"satoshi-bitcoin": "^1.0.4",
"touch": "^3.1.0"
"touch": "^3.1.0",
"wif": "^2.0.6"
},
"devDependencies": {
"chai": "^4.1.2",
Expand Down
20 changes: 20 additions & 0 deletions src/BitcoinCash.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import bitcoinMessage from 'bitcoinjs-message';
import bs58 from 'bs58';
import bip21 from 'bip21';
import coininfo from'coininfo';
import bip38 from 'bip38';
import wif from 'wif';

let Buffer = require('safe-buffer').Buffer

class BitcoinCash {
Expand Down Expand Up @@ -117,6 +120,23 @@ class BitcoinCash {

return Math.ceil(totalWeight / 4)
}

encryptBIP38(privKeyWIF, passphrase) {
let decoded = wif.decode(privKeyWIF);

return bip38.encrypt(decoded.privateKey, decoded.compressed, passphrase);
}

decryptBIP38(encryptedKey, passphrase, network = 'mainnet') {
let decryptedKey = bip38.decrypt(encryptedKey, passphrase);
let prefix;
if(network === 'testnet') {
prefix = 0xEF;
} else {
prefix = 0x80;
}
return wif.encode(prefix, decryptedKey.privateKey, decryptedKey.compressed) ;
}
}

export default BitcoinCash;
34 changes: 34 additions & 0 deletions test/BitcoinCash.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,38 @@ describe('#BitcoinCash', () => {
});
});
});

describe('#bip38', () => {
describe('#encryptBIP38', () => {
fixtures.bip38.encrypt.mainnet.forEach((fixture) => {
it(`BIP 38 encrypt wif ${fixture.wif} with password ${fixture.password} on mainnet`, () => {
let encryptedKey = BITBOX.BitcoinCash.encryptBIP38(fixture.wif, fixture.password);
assert.equal(encryptedKey, fixture.encryptedKey);
});
});

fixtures.bip38.encrypt.testnet.forEach((fixture) => {
it(`BIP 38 encrypt wif ${fixture.wif} with password ${fixture.password} on testnet`, () => {
let encryptedKey = BITBOX.BitcoinCash.encryptBIP38(fixture.wif, fixture.password);
assert.equal(encryptedKey, fixture.encryptedKey);
});
});
});

describe('#decryptBIP38', () => {
fixtures.bip38.decrypt.mainnet.forEach((fixture) => {
it(`BIP 38 decrypt encrypted key ${fixture.encryptedKey} on mainnet`, () => {
let wif = BITBOX.BitcoinCash.decryptBIP38(fixture.encryptedKey, fixture.password, 'mainnet');
assert.equal(wif, fixture.wif);
});
});

fixtures.bip38.decrypt.testnet.forEach((fixture) => {
it(`BIP 38 decrypt encrypted key ${fixture.encryptedKey} on testnet`, () => {
let wif = BITBOX.BitcoinCash.decryptBIP38(fixture.encryptedKey, fixture.password, 'testnet');
assert.equal(wif, fixture.wif);
});
});
});
});
});
76 changes: 75 additions & 1 deletion test/fixtures/BitcoinCash.json
Original file line number Diff line number Diff line change
Expand Up @@ -348,5 +348,79 @@
"P2SH":1
}
}
]
],
"bip38": {
"encrypt": {
"mainnet": [
{
"wif": "5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR",
"password": "TestingOneTwoThree",
"encryptedKey": "6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg"
},
{
"wif": "L1XHKhaBAfkr2FJQn3pTfCMxz652WYfmvKj8xDCHCEDV9tWGcbYj",
"password": "1EBPIyj55eR8bVUov9",
"encryptedKey": "6PYWWnBNfNpSqEJZKcfwbrYgTTdb9PNiGjQJ8r9V6cvsZNKLfcZD8YefQc"
},
{
"wif": "L1phBREbhL4vb1uHHHCAse8bdGE5c7ic2PFjRxMawLzQCsiFVbvu",
"password": "9GKVkabAHBMyAf",
"encryptedKey": "6PYU2fDHRVF2194gKDGkbFbeu4mFgkWtVvg2RPd2Sp6KmZx3RCHFpgBB2G"
}
],
"testnet": [
{
"wif": "cRQeGr3Wv91dUF94zy2EEP7rgwVsqNnZa3MtM7Civxdk74gNEPNn",
"password": "TestingOneTwoThree",
"encryptedKey": "6PYXFe1CdGMuVrLCvTo47JUpqcp7sEK7QxE9m4zHHkzUbgqVXVuTUAJh9T"
},
{
"wif": "cSx7KzdH9EcvDEireu2WYpGnXdFYpta7sJUNt5kVCJgA7kcAU8Gm",
"password": "1EBPIyj55eR8bVUov9",
"encryptedKey": "6PYUAPLwLSEjWSAfoe9NTSPkMZXnJA8j8EFJtKaeSnP18RCouutBrS2735"
},
{
"wif": "cRgunCa2z1gCN6nNapTwKLdo58FdgTeAiJSaXx6RZeWSabQHkQKG",
"password": "9GKVkabAHBMyAf",
"encryptedKey": "6PYTNQJ1dYhLg6X1Xqm62ceuyfxCUYvV4LfhFfzzBaTuV4cFhgS5Xe8t1Y"
}
]
},
"decrypt": {
"mainnet": [
{
"wif": "5KN7MzqK5wt2TP1fQCYyHBtDrXdJuXbUzm4A9rKAteGu3Qi5CVR",
"password": "TestingOneTwoThree",
"encryptedKey": "6PRVWUbkzzsbcVac2qwfssoUJAN1Xhrg6bNk8J7Nzm5H7kxEbn2Nh2ZoGg"
},
{
"wif": "L1XHKhaBAfkr2FJQn3pTfCMxz652WYfmvKj8xDCHCEDV9tWGcbYj",
"password": "1EBPIyj55eR8bVUov9",
"encryptedKey": "6PYWWnBNfNpSqEJZKcfwbrYgTTdb9PNiGjQJ8r9V6cvsZNKLfcZD8YefQc"
},
{
"wif": "L1phBREbhL4vb1uHHHCAse8bdGE5c7ic2PFjRxMawLzQCsiFVbvu",
"password": "9GKVkabAHBMyAf",
"encryptedKey": "6PYU2fDHRVF2194gKDGkbFbeu4mFgkWtVvg2RPd2Sp6KmZx3RCHFpgBB2G"
}
],
"testnet": [
{
"wif": "cRQeGr3Wv91dUF94zy2EEP7rgwVsqNnZa3MtM7Civxdk74gNEPNn",
"password": "TestingOneTwoThree",
"encryptedKey": "6PYXFe1CdGMuVrLCvTo47JUpqcp7sEK7QxE9m4zHHkzUbgqVXVuTUAJh9T"
},
{
"wif": "cSx7KzdH9EcvDEireu2WYpGnXdFYpta7sJUNt5kVCJgA7kcAU8Gm",
"password": "1EBPIyj55eR8bVUov9",
"encryptedKey": "6PYUAPLwLSEjWSAfoe9NTSPkMZXnJA8j8EFJtKaeSnP18RCouutBrS2735"
},
{
"wif": "cRgunCa2z1gCN6nNapTwKLdo58FdgTeAiJSaXx6RZeWSabQHkQKG",
"password": "9GKVkabAHBMyAf",
"encryptedKey": "6PYTNQJ1dYhLg6X1Xqm62ceuyfxCUYvV4LfhFfzzBaTuV4cFhgS5Xe8t1Y"
}
]
}
}
}

0 comments on commit 17efef2

Please sign in to comment.