1 let cryp = require('crypto-browserify');
2 let scrypt = require('scrypt-js');
3 import {XPrv} from './chainkd';
4 let sha3_256 = require('js-sha3').sha3_256;
5 import _ from 'lodash';
6 import Error from '../error';
8 const scryptDKLen = 32;
11 function encryptKey(key , auth, scryptN, scryptP){
12 let authArray = new Buffer(auth);
13 let salt = cryp.randomBytes(32);
15 let derivedKey = scrypt.syncScrypt(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen);
17 let encryptKey = derivedKey.slice(0, 16);
18 let keyBytes = key.xPrv;
19 let iv = cryp.randomBytes(16);
22 let cipherText = aesCTRXOR(encryptKey, keyBytes, iv);
29 salt:salt.toString('hex')
32 let mac = sha3_256(Buffer.concat([Buffer(derivedKey.slice(16, 32)), cipherText]));
37 xpub:key.xPub.toString('hex'),
41 ciphertext: cipherText.toString('hex'),
43 iv: iv.toString('hex')
45 cipher: 'aes-128-ctr',
48 mac: mac.toString('hex')
54 function aesCTRXOR(key, inText, iv) {
55 let cipher = cryp.createCipheriv('aes-128-ctr', key, iv);
57 var ciphertext = Buffer.from([
58 ...cipher.update(Buffer.from(inText, 'hex')),
66 function decryptKey(v3Keystore, password){
67 if (!_.isString(password)) {
68 throw new Error('No password given.', 'BTM3003');
71 let k = (_.isObject(v3Keystore)) ? v3Keystore : JSON.parse(v3Keystore);
72 const xprv = decrypt(k, password);
73 const _xprv = new XPrv(xprv)
74 const xpub = _xprv.XPub()
84 function decrypt(json, password) {
87 if (json.crypto.kdf === 'scrypt') {
88 kdfparams = json.crypto.kdfparams;
90 // FIXME: support progress reporting callback
91 derivedKey = scrypt.syncScrypt(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen);
92 } else if (json.crypto.kdf === 'pbkdf2') {
93 kdfparams = json.crypto.kdfparams;
95 if (kdfparams.prf !== 'hmac-sha256') {
96 throw new Error('Unsupported parameters to PBKDF2', 'BTM3002');
99 derivedKey = cryp.pbkdf2Sync(Buffer.from(password), Buffer.from(kdfparams.salt, 'hex'), kdfparams.c, kdfparams.dklen, 'sha3256');
101 throw new Error('Unsupported key derivation scheme' , 'BTM3001');
104 var ciphertext = Buffer.from(json.crypto.ciphertext, 'hex');
106 var mac = sha3_256(Buffer.concat([Buffer(derivedKey.slice(16, 32)), ciphertext]));
107 if (mac !== json.crypto.mac) {
108 throw new Error('Key derivation failed - possibly wrong password', 'BTM3000');
111 var decipher = cryp.createDecipheriv(json.crypto.cipher, derivedKey.slice(0, 16), Buffer.from(json.crypto.cipherparams.iv, 'hex'));
112 var privateKey = Buffer.concat([decipher.update(ciphertext), decipher.final()]);