-
Notifications
You must be signed in to change notification settings - Fork 71
/
ECIES.js
85 lines (63 loc) · 1.96 KB
/
ECIES.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
'use strict';
var bitcore = require('bitcore');
var Hash = bitcore.crypto.Hash;
var Random = bitcore.crypto.Random;
var $ = bitcore.util.preconditions;
var AESCBC = require('./AESCBC');
// http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
var ECIES = function ECIES() {
if (!(this instanceof ECIES)) {
return new ECIES();
}
};
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;
};
ECIES.prototype.encrypt = function(message) {
if (!Buffer.isBuffer(message)) message = new Buffer(message);
var ivbuf = Random.getRandomBuffer(128 / 8);
var r = this._privateKey.bn;
var Rpubkey = this._privateKey.publicKey;
var Rbuf = Rpubkey.toDER(true);
var KB = this._publicKey.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 = AESCBC.encryptCipherkey(message, kE, ivbuf);
var d = Hash.sha256hmac(c, kM);
var encbuf = Buffer.concat([Rbuf, c, d]);
return encbuf;
};
ECIES.prototype.decrypt = function(encbuf) {
$.checkArgument(encbuf);
var kB = this._privateKey.bn;
var frompubkey = this._publicKey;
var R = frompubkey.point;
var P = R.mul(kB);
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 = AESCBC.decryptCipherkey(c, kE);
return messagebuf;
};
module.exports = ECIES;