124 lines
2.6 KiB
JavaScript
124 lines
2.6 KiB
JavaScript
var elliptic = require('elliptic')
|
|
var BN = require('bn.js')
|
|
|
|
module.exports = function createECDH (curve) {
|
|
return new ECDH(curve)
|
|
}
|
|
|
|
var aliases = {
|
|
secp256k1: {
|
|
name: 'secp256k1',
|
|
byteLength: 32
|
|
},
|
|
secp224r1: {
|
|
name: 'p224',
|
|
byteLength: 28
|
|
},
|
|
prime256v1: {
|
|
name: 'p256',
|
|
byteLength: 32
|
|
},
|
|
prime192v1: {
|
|
name: 'p192',
|
|
byteLength: 24
|
|
},
|
|
ed25519: {
|
|
name: 'ed25519',
|
|
byteLength: 32
|
|
},
|
|
secp384r1: {
|
|
name: 'p384',
|
|
byteLength: 48
|
|
},
|
|
secp521r1: {
|
|
name: 'p521',
|
|
byteLength: 66
|
|
}
|
|
}
|
|
|
|
aliases.p224 = aliases.secp224r1
|
|
aliases.p256 = aliases.secp256r1 = aliases.prime256v1
|
|
aliases.p192 = aliases.secp192r1 = aliases.prime192v1
|
|
aliases.p384 = aliases.secp384r1
|
|
aliases.p521 = aliases.secp521r1
|
|
|
|
function ECDH (curve) {
|
|
this.curveType = aliases[curve]
|
|
if (!this.curveType) {
|
|
this.curveType = {
|
|
name: curve
|
|
}
|
|
}
|
|
this.curve = new elliptic.ec(this.curveType.name) // eslint-disable-line new-cap
|
|
this.keys = void 0
|
|
}
|
|
|
|
ECDH.prototype.generateKeys = function (enc, format) {
|
|
this.keys = this.curve.genKeyPair()
|
|
return this.getPublicKey(enc, format)
|
|
}
|
|
|
|
ECDH.prototype.computeSecret = function (other, inenc, enc) {
|
|
inenc = inenc || 'utf8'
|
|
if (!Buffer.isBuffer(other)) {
|
|
other = new Buffer(other, inenc)
|
|
}
|
|
var otherPub = this.curve.keyFromPublic(other).getPublic()
|
|
var out = otherPub.mul(this.keys.getPrivate()).getX()
|
|
return formatReturnValue(out, enc, this.curveType.byteLength)
|
|
}
|
|
|
|
ECDH.prototype.getPublicKey = function (enc, format) {
|
|
var key = this.keys.getPublic(format === 'compressed', true)
|
|
if (format === 'hybrid') {
|
|
if (key[key.length - 1] % 2) {
|
|
key[0] = 7
|
|
} else {
|
|
key[0] = 6
|
|
}
|
|
}
|
|
return formatReturnValue(key, enc)
|
|
}
|
|
|
|
ECDH.prototype.getPrivateKey = function (enc) {
|
|
return formatReturnValue(this.keys.getPrivate(), enc)
|
|
}
|
|
|
|
ECDH.prototype.setPublicKey = function (pub, enc) {
|
|
enc = enc || 'utf8'
|
|
if (!Buffer.isBuffer(pub)) {
|
|
pub = new Buffer(pub, enc)
|
|
}
|
|
this.keys._importPublic(pub)
|
|
return this
|
|
}
|
|
|
|
ECDH.prototype.setPrivateKey = function (priv, enc) {
|
|
enc = enc || 'utf8'
|
|
if (!Buffer.isBuffer(priv)) {
|
|
priv = new Buffer(priv, enc)
|
|
}
|
|
|
|
var _priv = new BN(priv)
|
|
_priv = _priv.toString(16)
|
|
this.keys = this.curve.genKeyPair()
|
|
this.keys._importPrivate(_priv)
|
|
return this
|
|
}
|
|
|
|
function formatReturnValue (bn, enc, len) {
|
|
if (!Array.isArray(bn)) {
|
|
bn = bn.toArray()
|
|
}
|
|
var buf = new Buffer(bn)
|
|
if (len && buf.length < len) {
|
|
var zeros = new Buffer(len - buf.length)
|
|
zeros.fill(0)
|
|
buf = Buffer.concat([zeros, buf])
|
|
}
|
|
if (!enc) {
|
|
return buf
|
|
} else {
|
|
return buf.toString(enc)
|
|
}
|
|
}
|