parent
dcc192e7ef
commit
be632a69e9
@ -0,0 +1,47 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { util as bitcoreUtil } from 'bitcore-lib'; |
||||
var $ = bitcoreUtil.preconditions; |
||||
import aes from 'aes'; |
||||
|
||||
var AES = function AES() {}; |
||||
|
||||
export function encrypt(messagebuf, keybuf) { |
||||
var key = buf2words(keybuf); |
||||
var message = buf2words(messagebuf); |
||||
var a = new aes(key); |
||||
var enc = a.encrypt(message); |
||||
var encbuf = words2buf(enc); |
||||
return encbuf; |
||||
}; |
||||
|
||||
export function decrypt(encbuf, keybuf) { |
||||
var enc = buf2words(encbuf); |
||||
var key = buf2words(keybuf); |
||||
var a = new aes(key); |
||||
var message = a.decrypt(enc); |
||||
var messagebuf = words2buf(message); |
||||
return messagebuf; |
||||
}; |
||||
|
||||
export function buf2words(buf) { |
||||
$.checkArgument(buf); |
||||
$.checkArgument(buf.length % 4 === 0, 'buf length must be a multiple of 4'); |
||||
|
||||
var words = []; |
||||
|
||||
for (var i = 0; i < buf.length / 4; i++) { |
||||
words.push(buf.readUInt32BE(i * 4)); |
||||
}return words; |
||||
}; |
||||
|
||||
export function words2buf(words) { |
||||
var buf = new Buffer(words.length * 4); |
||||
|
||||
for (var i = 0; i < words.length; i++) { |
||||
buf.writeUInt32BE(words[i], i * 4); |
||||
}return buf; |
||||
}; |
@ -0,0 +1,49 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { util as bitcoreUtil, crypto as bitcoreCrypto } from 'bitcore-lib'; |
||||
|
||||
var $ = bitcoreUtil.preconditions; |
||||
var Random = bitcoreCrypto.Random; |
||||
var Hash = bitcoreCrypto.Hash; |
||||
|
||||
import * as AES from './aes'; |
||||
import CBC from './cbc'; |
||||
|
||||
// Symmetric encryption with AES and CBC convenience class
|
||||
var AESCBC = function AESCBC() {}; |
||||
|
||||
export function encrypt(messagebuf, passwordstr) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(passwordstr); |
||||
var cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.encryptCipherkey(messagebuf, cipherkeybuf); |
||||
}; |
||||
|
||||
export function decrypt(encbuf, passwordstr) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(passwordstr); |
||||
var cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.decryptCipherkey(encbuf, cipherkeybuf); |
||||
}; |
||||
|
||||
export function encryptCipherkey(messagebuf, cipherkeybuf, ivbuf) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
$.checkArgument(ivbuf); |
||||
ivbuf = ivbuf || Random.getRandomBuffer(128 / 8); |
||||
var ctbuf = CBC.encrypt(messagebuf, ivbuf, AES, cipherkeybuf); |
||||
var encbuf = Buffer.concat([ivbuf, ctbuf]); |
||||
return encbuf; |
||||
}; |
||||
|
||||
export function decryptCipherkey(encbuf, cipherkeybuf) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
var ivbuf = encbuf.slice(0, 128 / 8); |
||||
var ctbuf = encbuf.slice(128 / 8); |
||||
var messagebuf = CBC.decrypt(ctbuf, ivbuf, AES, cipherkeybuf); |
||||
return messagebuf; |
||||
}; |
@ -0,0 +1,136 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { util as bitcoreUtil } from 'bitcore-lib'; |
||||
var $ = bitcoreUtil.preconditions; |
||||
|
||||
import errors from './errors'; |
||||
|
||||
// Cipher Block Chaining
|
||||
// http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
var CBC = function CBC(blockcipher, cipherkeybuf, ivbuf) { |
||||
if (!(this instanceof CBC)) return new CBC(blockcipher, cipherkeybuf, ivbuf); |
||||
|
||||
this.blockcipher = blockcipher; |
||||
this.cipherkeybuf = cipherkeybuf; |
||||
this.ivbuf = ivbuf; |
||||
}; |
||||
|
||||
CBC.buf2blockbufs = function (buf, blocksize) { |
||||
var bytesize = blocksize / 8; |
||||
var blockbufs = []; |
||||
|
||||
for (var i = 0; i <= buf.length / bytesize; i++) { |
||||
var blockbuf = buf.slice(i * bytesize, i * bytesize + bytesize); |
||||
|
||||
if (blockbuf.length < blocksize) blockbuf = CBC.pkcs7pad(blockbuf, blocksize); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.blockbufs2buf = function (blockbufs) { |
||||
var last = blockbufs[blockbufs.length - 1]; |
||||
last = CBC.pkcs7unpad(last); |
||||
blockbufs[blockbufs.length - 1] = last; |
||||
|
||||
var buf = Buffer.concat(blockbufs); |
||||
|
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encrypt = function (messagebuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blocksize = ivbuf.length * 8; |
||||
var blockbufs = CBC.buf2blockbufs(messagebuf, blocksize); |
||||
var encbufs = CBC.encryptblocks(blockbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
var encbuf = Buffer.concat(encbufs); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decrypt = function (encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blocksize = ivbuf.length * 8; |
||||
var bytesize = ivbuf.length; |
||||
var encbufs = []; |
||||
for (var i = 0; i < encbuf.length / bytesize; i++) { |
||||
encbufs.push(encbuf.slice(i * bytesize, i * bytesize + bytesize)); |
||||
}var blockbufs = CBC.decryptblocks(encbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
var buf = CBC.blockbufs2buf(blockbufs, blocksize); |
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encryptblock = function (blockbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var xorbuf = CBC.xorbufs(blockbuf, ivbuf); |
||||
var encbuf = blockcipher.encrypt(xorbuf, cipherkeybuf); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decryptblock = function (encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var xorbuf = blockcipher.decrypt(encbuf, cipherkeybuf); |
||||
var blockbuf = CBC.xorbufs(xorbuf, ivbuf); |
||||
return blockbuf; |
||||
}; |
||||
|
||||
CBC.encryptblocks = function (blockbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
var encbufs = []; |
||||
|
||||
for (var i = 0; i < blockbufs.length; i++) { |
||||
var blockbuf = blockbufs[i]; |
||||
var encbuf = CBC.encryptblock(blockbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
encbufs.push(encbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return encbufs; |
||||
}; |
||||
|
||||
CBC.decryptblocks = function (encbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blockbufs = []; |
||||
|
||||
for (var i = 0; i < encbufs.length; i++) { |
||||
var encbuf = encbufs[i]; |
||||
var blockbuf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.pkcs7pad = function (buf, blocksize) { |
||||
var bytesize = blocksize / 8; |
||||
var padbytesize = bytesize - buf.length; |
||||
var pad = new Buffer(padbytesize); |
||||
pad.fill(padbytesize); |
||||
var paddedbuf = Buffer.concat([buf, pad]); |
||||
return paddedbuf; |
||||
}; |
||||
|
||||
CBC.pkcs7unpad = function (paddedbuf) { |
||||
var padlength = paddedbuf[paddedbuf.length - 1]; |
||||
var padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length); |
||||
var padbuf2 = new Buffer(padlength); |
||||
padbuf2.fill(padlength); |
||||
if (padbuf.toString('hex') !== padbuf2.toString('hex')) throw new errors.InvalidPadding(padbuf.toString()); |
||||
|
||||
return paddedbuf.slice(0, paddedbuf.length - padlength); |
||||
}; |
||||
|
||||
CBC.xorbufs = function (buf1, buf2) { |
||||
$.checkArgument(buf1.length === buf2.length, 'bufs must have the same length'); |
||||
|
||||
var buf = new Buffer(buf1.length); |
||||
|
||||
for (var i = 0; i < buf1.length; i++) { |
||||
buf[i] = buf1[i] ^ buf2[i]; |
||||
}return buf; |
||||
}; |
||||
|
||||
export default CBC; |
@ -0,0 +1,131 @@ |
||||
import _Object$defineProperty from 'babel-runtime/core-js/object/define-property'; |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { PublicKey, crypto as bitcoreCrypto, util as bitcoreUtil } from 'bitcore-lib'; |
||||
|
||||
var Hash = bitcoreCrypto.Hash; |
||||
var Random = bitcoreCrypto.Random; |
||||
var $ = bitcoreUtil.preconditions; |
||||
|
||||
import { encryptCipherkey, decryptCipherkey } from './aescbc'; |
||||
|
||||
// http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
|
||||
var ECIES = function ECIES(opts) { |
||||
if (!(this instanceof ECIES)) return new ECIES(); |
||||
this.opts = opts || {}; |
||||
}; |
||||
|
||||
ECIES.prototype.privateKey = function (privateKey) { |
||||
$.checkArgument(privateKey, 'no private key provided'); |
||||
|
||||
this._privateKey = privateKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
ECIES.prototype.publicKey = function (publicKey) { |
||||
$.checkArgument(publicKey, 'no public key provided'); |
||||
|
||||
this._publicKey = publicKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
var cachedProperty = function cachedProperty(name, getter) { |
||||
var cachedName = '_' + name; |
||||
_Object$defineProperty(ECIES.prototype, name, { |
||||
configurable: false, |
||||
enumerable: true, |
||||
get: function get() { |
||||
var value = this[cachedName]; |
||||
if (!value) value = this[cachedName] = getter.apply(this); |
||||
return value; |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
cachedProperty('Rbuf', function () { |
||||
return this._privateKey.publicKey.toDER(true); |
||||
}); |
||||
|
||||
cachedProperty('kEkM', function () { |
||||
var r = this._privateKey.bn; |
||||
var KB = this._publicKey.point; |
||||
var P = KB.mul(r); |
||||
var S = P.getX(); |
||||
var Sbuf = S.toBuffer({ |
||||
size: 32 |
||||
}); |
||||
return Hash.sha512(Sbuf); |
||||
}); |
||||
|
||||
cachedProperty('kE', function () { |
||||
return this.kEkM.slice(0, 32); |
||||
}); |
||||
|
||||
cachedProperty('kM', function () { |
||||
return this.kEkM.slice(32, 64); |
||||
}); |
||||
|
||||
// Encrypts the message (String or Buffer).
|
||||
// Optional `ivbuf` contains 16-byte Buffer to be used in AES-CBC.
|
||||
// By default, `ivbuf` is computed deterministically from message and private key using HMAC-SHA256.
|
||||
// Deterministic IV enables end-to-end test vectors for alternative implementations.
|
||||
// Note that identical messages have identical ciphertexts. If your protocol does not include some
|
||||
// kind of a sequence identifier inside the message *and* it is important to not allow attacker to learn
|
||||
// that message is repeated, then you should use custom IV.
|
||||
// For random IV, pass `Random.getRandomBuffer(16)` for the second argument.
|
||||
ECIES.prototype.encrypt = function (message, ivbuf) { |
||||
if (!Buffer.isBuffer(message)) message = new Buffer(message); |
||||
if (ivbuf === undefined) ivbuf = Hash.sha256hmac(message, this._privateKey.toBuffer()).slice(0, 16); |
||||
|
||||
var c = encryptCipherkey(message, this.kE, ivbuf); |
||||
var d = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d = d.slice(0, 4); |
||||
var encbuf = void 0; |
||||
if (this.opts.noKey) encbuf = Buffer.concat([c, d]);else encbuf = Buffer.concat([this.Rbuf, c, d]); |
||||
|
||||
return encbuf; |
||||
}; |
||||
|
||||
ECIES.prototype.decrypt = function (encbuf) { |
||||
$.checkArgument(encbuf); |
||||
var offset = 0; |
||||
var tagLength = 32; |
||||
if (this.opts.shortTag) tagLength = 4; |
||||
|
||||
if (!this.opts.noKey) { |
||||
var pub = void 0; |
||||
switch (encbuf[0]) { |
||||
case 4: |
||||
pub = encbuf.slice(0, 65); |
||||
break; |
||||
case 3: |
||||
case 2: |
||||
pub = encbuf.slice(0, 33); |
||||
break; |
||||
default: |
||||
throw new Error('Invalid type: ' + encbuf[0]); |
||||
} |
||||
this._publicKey = PublicKey.fromDER(pub); |
||||
offset += pub.length; |
||||
} |
||||
|
||||
var c = encbuf.slice(offset, encbuf.length - tagLength); |
||||
var d = encbuf.slice(encbuf.length - tagLength, encbuf.length); |
||||
|
||||
var d2 = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d2 = d2.slice(0, 4); |
||||
|
||||
var equal = true; |
||||
for (var i = 0; i < d.length; i++) { |
||||
equal &= d[i] === d2[i]; |
||||
}if (!equal) throw new Error('Invalid checksum'); |
||||
|
||||
return decryptCipherkey(c, this.kE); |
||||
}; |
||||
|
||||
export default ECIES; |
@ -0,0 +1,17 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { errors as bitcoreErrors } from 'bitcore-lib'; |
||||
|
||||
var spec = { |
||||
name: 'ECIES', |
||||
message: 'Internal Error on bitcore-ecies Module {0}', |
||||
errors: [{ |
||||
name: 'InvalidPadding', |
||||
message: 'Invalid padding: {0}' |
||||
}] |
||||
}; |
||||
|
||||
export default bitcoreErrors.extend(spec); |
@ -0,0 +1,61 @@ |
||||
'use strict'; |
||||
|
||||
Object.defineProperty(exports, "__esModule", { |
||||
value: true |
||||
}); |
||||
exports.encrypt = encrypt; |
||||
exports.decrypt = decrypt; |
||||
exports.buf2words = buf2words; |
||||
exports.words2buf = words2buf; |
||||
|
||||
var _bitcoreLib = require('bitcore-lib'); |
||||
|
||||
var _aes = require('aes'); |
||||
|
||||
var _aes2 = _interopRequireDefault(_aes); |
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } |
||||
|
||||
var $ = _bitcoreLib.util.preconditions; /** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
var AES = function AES() {}; |
||||
|
||||
function encrypt(messagebuf, keybuf) { |
||||
var key = buf2words(keybuf); |
||||
var message = buf2words(messagebuf); |
||||
var a = new _aes2['default'](key); |
||||
var enc = a.encrypt(message); |
||||
var encbuf = words2buf(enc); |
||||
return encbuf; |
||||
}; |
||||
|
||||
function decrypt(encbuf, keybuf) { |
||||
var enc = buf2words(encbuf); |
||||
var key = buf2words(keybuf); |
||||
var a = new _aes2['default'](key); |
||||
var message = a.decrypt(enc); |
||||
var messagebuf = words2buf(message); |
||||
return messagebuf; |
||||
}; |
||||
|
||||
function buf2words(buf) { |
||||
$.checkArgument(buf); |
||||
$.checkArgument(buf.length % 4 === 0, 'buf length must be a multiple of 4'); |
||||
|
||||
var words = []; |
||||
|
||||
for (var i = 0; i < buf.length / 4; i++) { |
||||
words.push(buf.readUInt32BE(i * 4)); |
||||
}return words; |
||||
}; |
||||
|
||||
function words2buf(words) { |
||||
var buf = new Buffer(words.length * 4); |
||||
|
||||
for (var i = 0; i < words.length; i++) { |
||||
buf.writeUInt32BE(words[i], i * 4); |
||||
}return buf; |
||||
}; |
@ -0,0 +1,67 @@ |
||||
'use strict'; |
||||
|
||||
Object.defineProperty(exports, "__esModule", { |
||||
value: true |
||||
}); |
||||
exports.encrypt = encrypt; |
||||
exports.decrypt = decrypt; |
||||
exports.encryptCipherkey = encryptCipherkey; |
||||
exports.decryptCipherkey = decryptCipherkey; |
||||
|
||||
var _bitcoreLib = require('bitcore-lib'); |
||||
|
||||
var _aes = require('./aes'); |
||||
|
||||
var AES = _interopRequireWildcard(_aes); |
||||
|
||||
var _cbc = require('./cbc'); |
||||
|
||||
var _cbc2 = _interopRequireDefault(_cbc); |
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } |
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } |
||||
|
||||
var $ = _bitcoreLib.util.preconditions; /** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
var Random = _bitcoreLib.crypto.Random; |
||||
var Hash = _bitcoreLib.crypto.Hash; |
||||
|
||||
// Symmetric encryption with AES and CBC convenience class
|
||||
var AESCBC = function AESCBC() {}; |
||||
|
||||
function encrypt(messagebuf, passwordstr) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(passwordstr); |
||||
var cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.encryptCipherkey(messagebuf, cipherkeybuf); |
||||
}; |
||||
|
||||
function decrypt(encbuf, passwordstr) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(passwordstr); |
||||
var cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.decryptCipherkey(encbuf, cipherkeybuf); |
||||
}; |
||||
|
||||
function encryptCipherkey(messagebuf, cipherkeybuf, ivbuf) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
$.checkArgument(ivbuf); |
||||
ivbuf = ivbuf || Random.getRandomBuffer(128 / 8); |
||||
var ctbuf = _cbc2['default'].encrypt(messagebuf, ivbuf, AES, cipherkeybuf); |
||||
var encbuf = Buffer.concat([ivbuf, ctbuf]); |
||||
return encbuf; |
||||
}; |
||||
|
||||
function decryptCipherkey(encbuf, cipherkeybuf) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
var ivbuf = encbuf.slice(0, 128 / 8); |
||||
var ctbuf = encbuf.slice(128 / 8); |
||||
var messagebuf = _cbc2['default'].decrypt(ctbuf, ivbuf, AES, cipherkeybuf); |
||||
return messagebuf; |
||||
}; |
@ -0,0 +1,145 @@ |
||||
'use strict'; |
||||
|
||||
Object.defineProperty(exports, "__esModule", { |
||||
value: true |
||||
}); |
||||
|
||||
var _bitcoreLib = require('bitcore-lib'); |
||||
|
||||
var _errors = require('./errors'); |
||||
|
||||
var _errors2 = _interopRequireDefault(_errors); |
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } |
||||
|
||||
var $ = _bitcoreLib.util.preconditions; /** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
// Cipher Block Chaining
|
||||
// http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
var CBC = function CBC(blockcipher, cipherkeybuf, ivbuf) { |
||||
if (!(this instanceof CBC)) return new CBC(blockcipher, cipherkeybuf, ivbuf); |
||||
|
||||
this.blockcipher = blockcipher; |
||||
this.cipherkeybuf = cipherkeybuf; |
||||
this.ivbuf = ivbuf; |
||||
}; |
||||
|
||||
CBC.buf2blockbufs = function (buf, blocksize) { |
||||
var bytesize = blocksize / 8; |
||||
var blockbufs = []; |
||||
|
||||
for (var i = 0; i <= buf.length / bytesize; i++) { |
||||
var blockbuf = buf.slice(i * bytesize, i * bytesize + bytesize); |
||||
|
||||
if (blockbuf.length < blocksize) blockbuf = CBC.pkcs7pad(blockbuf, blocksize); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.blockbufs2buf = function (blockbufs) { |
||||
var last = blockbufs[blockbufs.length - 1]; |
||||
last = CBC.pkcs7unpad(last); |
||||
blockbufs[blockbufs.length - 1] = last; |
||||
|
||||
var buf = Buffer.concat(blockbufs); |
||||
|
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encrypt = function (messagebuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blocksize = ivbuf.length * 8; |
||||
var blockbufs = CBC.buf2blockbufs(messagebuf, blocksize); |
||||
var encbufs = CBC.encryptblocks(blockbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
var encbuf = Buffer.concat(encbufs); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decrypt = function (encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blocksize = ivbuf.length * 8; |
||||
var bytesize = ivbuf.length; |
||||
var encbufs = []; |
||||
for (var i = 0; i < encbuf.length / bytesize; i++) { |
||||
encbufs.push(encbuf.slice(i * bytesize, i * bytesize + bytesize)); |
||||
}var blockbufs = CBC.decryptblocks(encbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
var buf = CBC.blockbufs2buf(blockbufs, blocksize); |
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encryptblock = function (blockbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var xorbuf = CBC.xorbufs(blockbuf, ivbuf); |
||||
var encbuf = blockcipher.encrypt(xorbuf, cipherkeybuf); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decryptblock = function (encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
var xorbuf = blockcipher.decrypt(encbuf, cipherkeybuf); |
||||
var blockbuf = CBC.xorbufs(xorbuf, ivbuf); |
||||
return blockbuf; |
||||
}; |
||||
|
||||
CBC.encryptblocks = function (blockbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
var encbufs = []; |
||||
|
||||
for (var i = 0; i < blockbufs.length; i++) { |
||||
var blockbuf = blockbufs[i]; |
||||
var encbuf = CBC.encryptblock(blockbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
encbufs.push(encbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return encbufs; |
||||
}; |
||||
|
||||
CBC.decryptblocks = function (encbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
var blockbufs = []; |
||||
|
||||
for (var i = 0; i < encbufs.length; i++) { |
||||
var encbuf = encbufs[i]; |
||||
var blockbuf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.pkcs7pad = function (buf, blocksize) { |
||||
var bytesize = blocksize / 8; |
||||
var padbytesize = bytesize - buf.length; |
||||
var pad = new Buffer(padbytesize); |
||||
pad.fill(padbytesize); |
||||
var paddedbuf = Buffer.concat([buf, pad]); |
||||
return paddedbuf; |
||||
}; |
||||
|
||||
CBC.pkcs7unpad = function (paddedbuf) { |
||||
var padlength = paddedbuf[paddedbuf.length - 1]; |
||||
var padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length); |
||||
var padbuf2 = new Buffer(padlength); |
||||
padbuf2.fill(padlength); |
||||
if (padbuf.toString('hex') !== padbuf2.toString('hex')) throw new _errors2['default'].InvalidPadding(padbuf.toString()); |
||||
|
||||
return paddedbuf.slice(0, paddedbuf.length - padlength); |
||||
}; |
||||
|
||||
CBC.xorbufs = function (buf1, buf2) { |
||||
$.checkArgument(buf1.length === buf2.length, 'bufs must have the same length'); |
||||
|
||||
var buf = new Buffer(buf1.length); |
||||
|
||||
for (var i = 0; i < buf1.length; i++) { |
||||
buf[i] = buf1[i] ^ buf2[i]; |
||||
}return buf; |
||||
}; |
||||
|
||||
exports['default'] = CBC; |
@ -0,0 +1,141 @@ |
||||
'use strict'; |
||||
|
||||
Object.defineProperty(exports, "__esModule", { |
||||
value: true |
||||
}); |
||||
|
||||
var _defineProperty = require('babel-runtime/core-js/object/define-property'); |
||||
|
||||
var _defineProperty2 = _interopRequireDefault(_defineProperty); |
||||
|
||||
var _bitcoreLib = require('bitcore-lib'); |
||||
|
||||
var _aescbc = require('./aescbc'); |
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } |
||||
|
||||
var Hash = _bitcoreLib.crypto.Hash; /** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
var Random = _bitcoreLib.crypto.Random; |
||||
var $ = _bitcoreLib.util.preconditions; |
||||
|
||||
// http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
|
||||
var ECIES = function ECIES(opts) { |
||||
if (!(this instanceof ECIES)) return new ECIES(); |
||||
this.opts = opts || {}; |
||||
}; |
||||
|
||||
ECIES.prototype.privateKey = function (privateKey) { |
||||
$.checkArgument(privateKey, 'no private key provided'); |
||||
|
||||
this._privateKey = privateKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
ECIES.prototype.publicKey = function (publicKey) { |
||||
$.checkArgument(publicKey, 'no public key provided'); |
||||
|
||||
this._publicKey = publicKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
var cachedProperty = function cachedProperty(name, getter) { |
||||
var cachedName = '_' + name; |
||||
(0, _defineProperty2['default'])(ECIES.prototype, name, { |
||||
configurable: false, |
||||
enumerable: true, |
||||
get: function get() { |
||||
var value = this[cachedName]; |
||||
if (!value) value = this[cachedName] = getter.apply(this); |
||||
return value; |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
cachedProperty('Rbuf', function () { |
||||
return this._privateKey.publicKey.toDER(true); |
||||
}); |
||||
|
||||
cachedProperty('kEkM', function () { |
||||
var r = this._privateKey.bn; |
||||
var KB = this._publicKey.point; |
||||
var P = KB.mul(r); |
||||
var S = P.getX(); |
||||
var Sbuf = S.toBuffer({ |
||||
size: 32 |
||||
}); |
||||
return Hash.sha512(Sbuf); |
||||
}); |
||||
|
||||
cachedProperty('kE', function () { |
||||
return this.kEkM.slice(0, 32); |
||||
}); |
||||
|
||||
cachedProperty('kM', function () { |
||||
return this.kEkM.slice(32, 64); |
||||
}); |
||||
|
||||
// Encrypts the message (String or Buffer).
|
||||
// Optional `ivbuf` contains 16-byte Buffer to be used in AES-CBC.
|
||||
// By default, `ivbuf` is computed deterministically from message and private key using HMAC-SHA256.
|
||||
// Deterministic IV enables end-to-end test vectors for alternative implementations.
|
||||
// Note that identical messages have identical ciphertexts. If your protocol does not include some
|
||||
// kind of a sequence identifier inside the message *and* it is important to not allow attacker to learn
|
||||
// that message is repeated, then you should use custom IV.
|
||||
// For random IV, pass `Random.getRandomBuffer(16)` for the second argument.
|
||||
ECIES.prototype.encrypt = function (message, ivbuf) { |
||||
if (!Buffer.isBuffer(message)) message = new Buffer(message); |
||||
if (ivbuf === undefined) ivbuf = Hash.sha256hmac(message, this._privateKey.toBuffer()).slice(0, 16); |
||||
|
||||
var c = (0, _aescbc.encryptCipherkey)(message, this.kE, ivbuf); |
||||
var d = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d = d.slice(0, 4); |
||||
var encbuf = void 0; |
||||
if (this.opts.noKey) encbuf = Buffer.concat([c, d]);else encbuf = Buffer.concat([this.Rbuf, c, d]); |
||||
|
||||
return encbuf; |
||||
}; |
||||
|
||||
ECIES.prototype.decrypt = function (encbuf) { |
||||
$.checkArgument(encbuf); |
||||
var offset = 0; |
||||
var tagLength = 32; |
||||
if (this.opts.shortTag) tagLength = 4; |
||||
|
||||
if (!this.opts.noKey) { |
||||
var pub = void 0; |
||||
switch (encbuf[0]) { |
||||
case 4: |
||||
pub = encbuf.slice(0, 65); |
||||
break; |
||||
case 3: |
||||
case 2: |
||||
pub = encbuf.slice(0, 33); |
||||
break; |
||||
default: |
||||
throw new Error('Invalid type: ' + encbuf[0]); |
||||
} |
||||
this._publicKey = _bitcoreLib.PublicKey.fromDER(pub); |
||||
offset += pub.length; |
||||
} |
||||
|
||||
var c = encbuf.slice(offset, encbuf.length - tagLength); |
||||
var d = encbuf.slice(encbuf.length - tagLength, encbuf.length); |
||||
|
||||
var d2 = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d2 = d2.slice(0, 4); |
||||
|
||||
var equal = true; |
||||
for (var i = 0; i < d.length; i++) { |
||||
equal &= d[i] === d2[i]; |
||||
}if (!equal) throw new Error('Invalid checksum'); |
||||
|
||||
return (0, _aescbc.decryptCipherkey)(c, this.kE); |
||||
}; |
||||
|
||||
exports['default'] = ECIES; |
@ -0,0 +1,21 @@ |
||||
'use strict'; |
||||
|
||||
Object.defineProperty(exports, "__esModule", { |
||||
value: true |
||||
}); |
||||
|
||||
var _bitcoreLib = require('bitcore-lib'); |
||||
|
||||
var spec = { |
||||
name: 'ECIES', |
||||
message: 'Internal Error on bitcore-ecies Module {0}', |
||||
errors: [{ |
||||
name: 'InvalidPadding', |
||||
message: 'Invalid padding: {0}' |
||||
}] |
||||
}; /** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
exports['default'] = _bitcoreLib.errors.extend(spec); |
Loading…
Reference in new issue