browser.js 2.6 KB

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