js-ecutils
Version:
JavaScript Library for Elliptic Curve Cryptography: key exchanges (Diffie-Hellman, Massey-Omura), ECDSA signatures, and Koblitz encoding. Suitable for crypto education and secure systems.
160 lines (151 loc) • 7.59 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MasseyOmura = exports.DiffieHellman = void 0;
var _curves = require("./curves");
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var DiffieHellman = exports.DiffieHellman = /*#__PURE__*/function () {
/**
* export class to perform Diffie-Hellman key exchange using elliptic curves.
* @param {number} private_key - The private key of the user.
* @param {string} curve_name - Name of the elliptic curve to be used. Defaults to 'secp192k1'.
*/
function DiffieHellman(private_key) {
var curve_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'secp192k1';
_classCallCheck(this, DiffieHellman);
this.private_key = private_key;
this.curve_name = curve_name;
this._curve = null; // Placeholder for the elliptic curve object
this._public_key = null; // Placeholder for the public key
this._shared_secret_cache = new Map(); // Cache for shared secrets
}
/**
* Retrieves the elliptic curve associated with this `DiffieHellman` instance.
* The `curve_name` attribute is used to fetch the corresponding elliptic curve object.
* @returns {EllipticCurve} The elliptic curve object used for ECDSA operations.
*/
return _createClass(DiffieHellman, [{
key: "curve",
get: function get() {
if (!this._curve) {
this._curve = (0, _curves.get)(this.curve_name);
}
return this._curve;
}
/**
* Computes and returns the public key corresponding to the private key.
* @returns {Point} The public key point on the elliptic curve associated with this instance.
*/
}, {
key: "public_key",
get: function get() {
if (!this._public_key) {
this._public_key = this.curve.multiply_point(this.private_key, this.curve.G);
}
return this._public_key;
}
/**
* Computes the shared secret using the private key and the other party's public key.
* @param {Point} other_public_key - The other party's public key.
* @returns {Point} The resulting shared secret as a point on the elliptic curve.
*/
}, {
key: "compute_shared_secret",
value: function compute_shared_secret(other_public_key) {
var cacheKey = "".concat(other_public_key.x, ",").concat(other_public_key.y);
if (!this._shared_secret_cache.has(cacheKey)) {
var shared_secret = this.curve.multiply_point(this.private_key, other_public_key);
this._shared_secret_cache.set(cacheKey, shared_secret);
}
return this._shared_secret_cache.get(cacheKey);
}
}]);
}();
var MasseyOmura = exports.MasseyOmura = /*#__PURE__*/function () {
/**
* export class to perform Massey-Omura key exchange using elliptic curves.
* @param {number} private_key - The private key of the user.
* @param {string} curve_name - Name of the elliptic curve to be used. Defaults to 'secp192k1'.
*/
function MasseyOmura(private_key) {
var curve_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'secp192k1';
_classCallCheck(this, MasseyOmura);
this.private_key = private_key;
this.curve_name = curve_name;
this._curve = null; // Placeholder for the elliptic curve object
this._public_key = null; // Placeholder for the public key
this._encryption_cache = new Map(); // Cache for encryption steps
this._partial_decryption_cache = new Map(); // Cache for partial decryption steps
}
/**
* Retrieves the elliptic curve associated with this `MasseyOmura` instance.
* The `curve_name` attribute is used to fetch the corresponding elliptic curve object.
* @returns {EllipticCurve} The elliptic curve object used for ECDSA operations.
*/
return _createClass(MasseyOmura, [{
key: "curve",
get: function get() {
if (!this._curve) {
this._curve = (0, _curves.get)(this.curve_name);
}
return this._curve;
}
/**
* Computes and returns the public key corresponding to the private key.
* @returns {Point} The public key point on the elliptic curve associated with this instance.
*/
}, {
key: "public_key",
get: function get() {
if (!this._public_key) {
this._public_key = this.curve.multiply_point(this.private_key, this.curve.G);
}
return this._public_key;
}
/**
* Encrypts the message with the sender's private key.
* @param {Point} message - The message point to encrypt.
* @returns {Point} The encrypted message point.
*/
}, {
key: "first_encryption_step",
value: function first_encryption_step(message) {
if (!this._encryption_cache.has(message)) {
var encrypted_message = this.curve.multiply_point(this.private_key, message);
this._encryption_cache.set(message, encrypted_message);
}
return this._encryption_cache.get(message);
}
/**
* Applies the receiver's private key on the received encrypted message.
* @param {Point} received_encrypted_message - The received encrypted message point.
* @returns {Point} The decrypted message point.
*/
}, {
key: "second_encryption_step",
value: function second_encryption_step(received_encrypted_message) {
return this.first_encryption_step(received_encrypted_message);
}
/**
* Partial decryption using the inverse of the sender's private key.
* @param {Point} encrypted_message - The encrypted message point.
* @returns {Point} The partially decrypted message point.
*/
}, {
key: "partial_decryption_step",
value: function partial_decryption_step(encrypted_message) {
if (!this._partial_decryption_cache.has(encrypted_message)) {
var inverse_key = this.curve.extended_gcd(this.private_key, this.curve.n)[1];
var partially_decrypted_message = this.curve.multiply_point(inverse_key, encrypted_message);
this._partial_decryption_cache.set(encrypted_message, partially_decrypted_message);
}
return this._partial_decryption_cache.get(encrypted_message);
}
}]);
}();