UNPKG

int-cli

Version:

INT is the new generation of bottom-up created system of IoT and blockchain

148 lines (121 loc) 5.25 kB
var _ = require('underscore'); var Hash = require("./hash"); var uuid = require('uuid'); var cryp = (typeof global === 'undefined') ? require('crypto-browserify') : require('crypto'); var scryptsy = require('scrypt.js'); var Address = require('../address'); let isHexStrict = function(hex) { return ((_.isString(hex) || _.isNumber(hex)) && /^(-)?0x[0-9a-f]*$/i.test(hex)); }; let hexToBytes = function(hex) { hex = hex.toString(16); if (!isHexStrict(hex)) { throw new Error('Given value "' + hex + '" is not a valid hex string.'); } hex = hex.replace(/^0x/i, ''); for (var bytes = [], c = 0; c < hex.length; c += 2) bytes.push(parseInt(hex.substr(c, 2), 16)); return bytes; }; let sha3 = function(value) { if (isHexStrict(value) && /^0x/i.test((value).toString())) { value = hexToBytes(value); } var returnValue = Hash.keccak256(value); // jshint ignore:line //if(returnValue === SHA3_NULL_S) { // return null; //} else { return returnValue; //} }; let encrypt = function(privateKey, password, options) { /* jshint maxcomplexity: 20 */ //var account = this.privateKeyToAccount(privateKey); options = options || {}; var salt = options.salt || cryp.randomBytes(32); var iv = options.iv || cryp.randomBytes(16); var derivedKey; var kdf = options.kdf || 'scrypt'; var kdfparams = { dklen: options.dklen || 32, salt: salt.toString('hex') }; if (kdf === 'pbkdf2') { kdfparams.c = options.c || 262144; kdfparams.prf = 'hmac-sha256'; derivedKey = cryp.pbkdf2Sync(new Buffer(password), salt, kdfparams.c, kdfparams.dklen, 'sha256'); } else if (kdf === 'scrypt') { // FIXME: support progress reporting callback kdfparams.n = options.n || 8192; // 2048 4096 8192 16384 kdfparams.r = options.r || 8; kdfparams.p = options.p || 1; derivedKey = scryptsy(new Buffer(password), salt, kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen); } else { throw new Error('Unsupported kdf'); } var cipher = cryp.createCipheriv(options.cipher || 'aes-128-ctr', derivedKey.slice(0, 16), iv); if (!cipher) { throw new Error('Unsupported cipher'); } //var ciphertext = Buffer.concat([ cipher.update(new Buffer(account.privateKey.replace('0x',''), 'hex')), // cipher.final() ]); var ciphertext = Buffer.concat([cipher.update(new Buffer(privateKey, 'hex')), cipher.final()]); //var mac = utils.sha3(Buffer.concat([ derivedKey.slice(16, 32), new Buffer(ciphertext, 'hex') ])).replace('0x',''); var mac = sha3(Buffer.concat([derivedKey.slice(16, 32), new Buffer(ciphertext, 'hex')])).replace('0x', ''); return { version: 3, id: uuid.v4({ random: options.uuid || cryp.randomBytes(16) }), address: '', crypto: { ciphertext: ciphertext.toString('hex'), cipherparams: { iv: iv.toString('hex') }, cipher: options.cipher || 'aes-128-ctr', kdf: kdf, kdfparams: kdfparams, mac: mac.toString('hex') } }; }; let decrypt = function(v3Keystore, password, nonStrict) { /* jshint maxcomplexity: 10 */ if (!_.isString(password)) { throw new Error('No password given.'); } var json = (_.isObject(v3Keystore)) ? v3Keystore : JSON.parse(nonStrict ? v3Keystore.toLowerCase() : v3Keystore); if (json.version !== 3) { throw new Error('Not a valid V3 wallet'); } var derivedKey; var kdfparams; if (json.crypto.kdf === 'scrypt') { kdfparams = json.crypto.kdfparams; // FIXME: support progress reporting callback derivedKey = scryptsy(new Buffer(password), new Buffer(kdfparams.salt, 'hex'), kdfparams.n, kdfparams.r, kdfparams.p, kdfparams.dklen); } else if (json.crypto.kdf === 'pbkdf2') { kdfparams = json.crypto.kdfparams; if (kdfparams.prf !== 'hmac-sha256') { throw new Error('Unsupported parameters to PBKDF2'); } derivedKey = cryp.pbkdf2Sync(new Buffer(password), new Buffer(kdfparams.salt, 'hex'), kdfparams.c, kdfparams.dklen, 'sha256'); } else { throw new Error('Unsupported key derivation scheme'); } var ciphertext = new Buffer(json.crypto.ciphertext, 'hex'); //var mac = utils.sha3(Buffer.concat([ derivedKey.slice(16, 32), ciphertext ])).replace('0x',''); var mac = sha3(Buffer.concat([derivedKey.slice(16, 32), ciphertext])).replace('0x', ''); if (mac !== json.crypto.mac) { throw new Error('Key derivation failed - possibly wrong password'); } var decipher = cryp.createDecipheriv(json.crypto.cipher, derivedKey.slice(0, 16), new Buffer(json.crypto.cipherparams.iv, 'hex')); // var seed = '0x'+ Buffer.concat([ decipher.update(ciphertext), decipher.final() ]).toString('hex'); var seed = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('hex'); //return this.privateKeyToAccount(seed); var address = Address.addressFromSecretKey(seed); return {address: address, privateKey: seed}; }; module.exports = { encrypt, decrypt }