UNPKG

2.7 kBJavaScriptView Raw
1var elliptic = require('elliptic')
2var BN = require('bn.js')
3
4module.exports = function createECDH (curve) {
5 return new ECDH(curve)
6}
7
8var aliases = {
9 secp256k1: {
10 name: 'secp256k1',
11 byteLength: 32
12 },
13 secp224r1: {
14 name: 'p224',
15 byteLength: 28
16 },
17 prime256v1: {
18 name: 'p256',
19 byteLength: 32
20 },
21 prime192v1: {
22 name: 'p192',
23 byteLength: 24
24 },
25 ed25519: {
26 name: 'ed25519',
27 byteLength: 32
28 },
29 secp384r1: {
30 name: 'p384',
31 byteLength: 48
32 },
33 secp521r1: {
34 name: 'p521',
35 byteLength: 66
36 }
37}
38
39aliases.p224 = aliases.secp224r1
40aliases.p256 = aliases.secp256r1 = aliases.prime256v1
41aliases.p192 = aliases.secp192r1 = aliases.prime192v1
42aliases.p384 = aliases.secp384r1
43aliases.p521 = aliases.secp521r1
44
45function ECDH (curve) {
46 this.curveType = aliases[curve]
47 if (!this.curveType) {
48 this.curveType = {
49 name: curve
50 }
51 }
52 this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap
53 this.keys = void 0
54}
55
56ECDH.prototype.generateKeys = function (enc, format) {
57 this.keys = this.curve.genKeyPair()
58 return this.getPublicKey(enc, format)
59}
60
61ECDH.prototype.computeSecret = function (other, inenc, enc) {
62 inenc = inenc || 'utf8'
63 if (!Buffer.isBuffer(other)) {
64 other = new Buffer(other, inenc)
65 }
66 var otherPub = this.curve.keyFromPublic(other).getPublic()
67 var out = otherPub.mul(this.keys.getPrivate()).getX()
68 return formatReturnValue(out, enc, this.curveType.byteLength)
69}
70
71ECDH.prototype.getPublicKey = function (enc, format) {
72 var key = this.keys.getPublic(format === 'compressed', true)
73 if (format === 'hybrid') {
74 if (key[key.length - 1] % 2) {
75 key[0] = 7
76 } else {
77 key[0] = 6
78 }
79 }
80 return formatReturnValue(key, enc)
81}
82
83ECDH.prototype.getPrivateKey = function (enc) {
84 return formatReturnValue(this.keys.getPrivate(), enc)
85}
86
87ECDH.prototype.setPublicKey = function (pub, enc) {
88 enc = enc || 'utf8'
89 if (!Buffer.isBuffer(pub)) {
90 pub = new Buffer(pub, enc)
91 }
92 this.keys._importPublic(pub)
93 return this
94}
95
96ECDH.prototype.setPrivateKey = function (priv, enc) {
97 enc = enc || 'utf8'
98 if (!Buffer.isBuffer(priv)) {
99 priv = new Buffer(priv, enc)
100 }
101
102 var _priv = new BN(priv)
103 _priv = _priv.toString(16)
104 this.keys = this.curve.genKeyPair()
105 this.keys._importPrivate(_priv)
106 return this
107}
108
109function formatReturnValue (bn, enc, len) {
110 if (!Array.isArray(bn)) {
111 bn = bn.toArray()
112 }
113 var buf = new Buffer(bn)
114 if (len && buf.length < len) {
115 var zeros = new Buffer(len - buf.length)
116 zeros.fill(0)
117 buf = Buffer.concat([zeros, buf])
118 }
119 if (!enc) {
120 return buf
121 } else {
122 return buf.toString(enc)
123 }
124}