Ryan X. Charles
11 years ago
3 changed files with 94 additions and 0 deletions
@ -0,0 +1,52 @@ |
|||
var SymEnc = require('./symenc'); |
|||
var Key = require('../key'); |
|||
var Point = require('../point'); |
|||
var Hash = require('../hash'); |
|||
var Pubkey = require('../pubkey'); |
|||
|
|||
// http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
|
|||
var ECIES = function ECIES() { |
|||
if (!(this instanceof ECIES)) |
|||
return new ECIES(); |
|||
}; |
|||
|
|||
ECIES.encrypt = function(messagebuf, tokey, fromkey, ivbuf) { |
|||
var r = fromkey.privkey.bn; |
|||
var R = fromkey.pubkey.point; |
|||
var Rpubkey = fromkey.pubkey; |
|||
var Rbuf = Rpubkey.toDER(true); |
|||
var KB = tokey.pubkey.point; |
|||
var P = KB.mul(r); |
|||
var S = P.getX(); |
|||
var Sbuf = S.toBuffer({size: 32}); |
|||
var kEkM = Hash.sha512(Sbuf); |
|||
var kE = kEkM.slice(0, 32); |
|||
var kM = kEkM.slice(32, 64); |
|||
var c = SymEnc.encryptCipherkey(messagebuf, kE, ivbuf); |
|||
var d = Hash.sha256hmac(c, kM); |
|||
var encbuf = Buffer.concat([Rbuf, c, d]); |
|||
return encbuf; |
|||
}; |
|||
|
|||
ECIES.decrypt = function(encbuf, tokey) { |
|||
var kB = tokey.privkey.bn; |
|||
var frompubkey = Pubkey().fromDER(encbuf.slice(0, 33)); |
|||
var R = frompubkey.point; |
|||
var P = R.mul(kB); |
|||
if (P.eq(new Point())) |
|||
throw new Error('P equals 0'); |
|||
var S = P.getX(); |
|||
var Sbuf = S.toBuffer({size: 32}); |
|||
var kEkM = Hash.sha512(Sbuf); |
|||
var kE = kEkM.slice(0, 32); |
|||
var kM = kEkM.slice(32, 64); |
|||
var c = encbuf.slice(33, encbuf.length - 32); |
|||
var d = encbuf.slice(encbuf.length - 32, encbuf.length); |
|||
var d2 = Hash.sha256hmac(c, kM); |
|||
if (d.toString('hex') !== d2.toString('hex')) |
|||
throw new Error('Invalid checksum'); |
|||
var messagebuf = SymEnc.decryptCipherkey(c, kE); |
|||
return messagebuf; |
|||
}; |
|||
|
|||
module.exports = ECIES; |
@ -0,0 +1,41 @@ |
|||
var ECIES = require('../lib/expmt/ecies'); |
|||
var should = require('chai').should(); |
|||
var Key = require('../lib/key'); |
|||
var Hash = require('../lib/hash'); |
|||
|
|||
describe('#ECIES', function() { |
|||
|
|||
it('should make a new ECIES object', function() { |
|||
var ecies = new ECIES(); |
|||
should.exist(ecies); |
|||
}); |
|||
|
|||
it('should make a new ECIES object when called without "new"', function() { |
|||
var ecies = ECIES(); |
|||
should.exist(ecies); |
|||
}); |
|||
|
|||
var fromkey = Key().fromRandom(); |
|||
var tokey = Key().fromRandom(); |
|||
var messagebuf = Hash.sha256(new Buffer('my message is the hash of this string')); |
|||
|
|||
describe('@encrypt', function() { |
|||
|
|||
it('should return a buffer', function() { |
|||
var encbuf = ECIES.encrypt(messagebuf, tokey, fromkey); |
|||
Buffer.isBuffer(encbuf).should.equal(true); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
describe('@decrypt', function() { |
|||
|
|||
it('should decrypt that which was encrypted', function() { |
|||
var encbuf = ECIES.encrypt(messagebuf, tokey, fromkey); |
|||
var messagebuf2 = ECIES.decrypt(encbuf, tokey); |
|||
messagebuf2.toString('hex').should.equal(messagebuf.toString('hex')); |
|||
}); |
|||
|
|||
}); |
|||
|
|||
}); |
Loading…
Reference in new issue