browser.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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);
  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._importPrivate(_priv);
  94. return this;
  95. };
  96. function formatReturnValue(bn, enc, len) {
  97. if (!Array.isArray(bn)) {
  98. bn = bn.toArray();
  99. }
  100. var buf = new Buffer(bn);
  101. if (len && buf.length < len) {
  102. var zeros = new Buffer(len - buf.length);
  103. zeros.fill(0);
  104. buf = Buffer.concat([zeros, buf]);
  105. }
  106. if (!enc) {
  107. return buf;
  108. } else {
  109. return buf.toString(enc);
  110. }
  111. }