"use strict"; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard"); var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.deriveSecret = exports.verify = exports.sign = exports.generateKey = void 0; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _params = _interopRequireDefault(require("./params.js")); var asn1enc = _interopRequireWildcard(require("./asn1enc.js")); var _jsCryptoRandom = _interopRequireDefault(require("js-crypto-random")); var _jsCryptoHash = _interopRequireDefault(require("js-crypto-hash")); var _jsCryptoKeyUtils = require("js-crypto-key-utils"); var _jsEncodingUtils = _interopRequireDefault(require("js-encoding-utils")); var _elliptic = _interopRequireDefault(require("elliptic")); /** * purejs.js */ var Ec = _elliptic.default.ec; /** * Generate elliptic curve cryptography public/private key pair. Generated keys are in JWK. * @param {String} namedCurve - Name of curve like 'P-256'. * @return {Promise<{publicKey: JsonWebKey, privateKey: JsonWebKey}>} - The generated keys. * @throws {Error} - Throws if NotPublic/PrivateKeyForECCKeyGenPureJS */ var generateKey = /*#__PURE__*/ function () { var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee(namedCurve) { var curve, ec, ecKey, len, publicOct, privateOct, publicKey, publicJwk, privateKey, privateJwk; return _regenerator.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: curve = _params.default.namedCurves[namedCurve].indutnyName; ec = new Ec(curve); _context.t0 = ec; _context.t1 = _jsEncodingUtils.default.encoder; _context.next = 6; return _jsCryptoRandom.default.getRandomBytes(32); case 6: _context.t2 = _context.sent; _context.t3 = _context.t1.arrayBufferToString.call(_context.t1, _context.t2); _context.t4 = { entropy: _context.t3 }; ecKey = _context.t0.genKeyPair.call(_context.t0, _context.t4); len = _params.default.namedCurves[namedCurve].payloadSize; publicOct = new Uint8Array(ecKey.getPublic('array')); privateOct = new Uint8Array(ecKey.getPrivate().toArray('be', len)); publicKey = new _jsCryptoKeyUtils.Key('oct', publicOct, { namedCurve: namedCurve }); if (!publicKey.isPrivate) { _context.next = 16; break; } throw new Error('NotPublicKeyForECCKeyGenPureJS'); case 16: _context.next = 18; return publicKey.export('jwk', { outputPublic: true }); case 18: publicJwk = _context.sent; privateKey = new _jsCryptoKeyUtils.Key('oct', privateOct, { namedCurve: namedCurve }); if (privateKey.isPrivate) { _context.next = 22; break; } throw new Error('NotPrivateKeyForECCKeyGenPureJS'); case 22: _context.next = 24; return privateKey.export('jwk'); case 24: privateJwk = _context.sent; return _context.abrupt("return", { publicKey: publicJwk, privateKey: privateJwk }); case 26: case "end": return _context.stop(); } } }, _callee); })); return function generateKey(_x) { return _ref.apply(this, arguments); }; }(); /** * Sign message with ECDSA. * @param {Uint8Array} msg - Byte array of message to be signed. * @param {JsonWebKey} privateJwk - Private key object in JWK format. * @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'. * @param {String} signatureFormat - Signature format, 'raw' or 'der' * @return {Promise} - Output signature byte array in raw or der format. * @throws {Error} - Throws if NotPrivateKeyForECCSIgnPureJS */ exports.generateKey = generateKey; var sign = /*#__PURE__*/ function () { var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee2(msg, privateJwk, hash, signatureFormat) { var namedCurve, curve, ec, privateKey, privateOct, ecKey, md, signature, len, arrayR, arrayS, concat; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: namedCurve = privateJwk.crv; curve = _params.default.namedCurves[namedCurve].indutnyName; ec = new Ec(curve); privateKey = new _jsCryptoKeyUtils.Key('jwk', privateJwk); if (privateKey.isPrivate) { _context2.next = 6; break; } throw new Error('NotPrivateKeyForECCSignPureJS'); case 6: _context2.next = 8; return privateKey.export('oct'); case 8: privateOct = _context2.sent; ecKey = ec.keyFromPrivate(privateOct); // get hash _context2.next = 12; return _jsCryptoHash.default.compute(msg, hash); case 12: md = _context2.sent; // generate signature signature = ecKey.sign(md); // formatting len = _params.default.namedCurves[namedCurve].payloadSize; arrayR = new Uint8Array(signature.r.toArray('be', len)); arrayS = new Uint8Array(signature.s.toArray('be', len)); concat = new Uint8Array(arrayR.length + arrayS.length); concat.set(arrayR); concat.set(arrayS, arrayR.length); return _context2.abrupt("return", signatureFormat === 'raw' ? concat : asn1enc.encodeAsn1Signature(concat, namedCurve)); case 21: case "end": return _context2.stop(); } } }, _callee2); })); return function sign(_x2, _x3, _x4, _x5) { return _ref2.apply(this, arguments); }; }(); /** * Verify signature with ECDSA. * @param {Uint8Array} msg - Byte array of message that have been signed. * @param {Uint8Array} signature - Byte array of signature for the given message. * @param {JsonWebKey} publicJwk - Public key object in JWK format. * @param {String} hash - Name of hash algorithm used in singing, like 'SHA-256'. * @param {String} signatureFormat - Signature format,'raw' or 'der'. * @return {Promise} - The result of verification. * @throws {Error} - Throws if NotPublicKeyForEccVerifyPureJS. */ exports.sign = sign; var verify = /*#__PURE__*/ function () { var _ref3 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee3(msg, signature, publicJwk, hash, signatureFormat) { var namedCurve, curve, ec, publicKey, publicOct, ecKey, len, sigR, sigS, md; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: namedCurve = publicJwk.crv; curve = _params.default.namedCurves[namedCurve].indutnyName; ec = new Ec(curve); publicKey = new _jsCryptoKeyUtils.Key('jwk', publicJwk); if (!publicKey.isPrivate) { _context3.next = 6; break; } throw new Error('NotPublicKeyForECCVerifyPureJS'); case 6: _context3.next = 8; return publicKey.export('oct', { compact: false, outputPublic: true }); case 8: publicOct = _context3.sent; ecKey = ec.keyFromPublic(publicOct); // parse signature len = _params.default.namedCurves[namedCurve].payloadSize; if (!(signature instanceof Uint8Array)) signature = new Uint8Array(signature); signature = signatureFormat === 'raw' ? signature : asn1enc.decodeAsn1Signature(signature, namedCurve); sigR = signature.slice(0, len); sigS = signature.slice(len, len + sigR.length); // get hash _context3.next = 17; return _jsCryptoHash.default.compute(msg, hash); case 17: md = _context3.sent; _context3.next = 20; return ecKey.verify(md, { s: sigS, r: sigR }); case 20: return _context3.abrupt("return", _context3.sent); case 21: case "end": return _context3.stop(); } } }, _callee3); })); return function verify(_x6, _x7, _x8, _x9, _x10) { return _ref3.apply(this, arguments); }; }(); /** * Key Derivation for ECDH, Elliptic Curve Diffie-Hellman Key Exchange. * @param {JsonWebKey} publicJwk - Remote public key object in JWK format. * @param {JsonWebKey} privateJwk - Local (my) private key object in JWK format. * @return {Promise} - The derived master secret via ECDH. * @throws {Error} - Throws if NotPublic/PrivateKeyForECCSDeriveKeyPureJS. */ exports.verify = verify; var deriveSecret = /*#__PURE__*/ function () { var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/ _regenerator.default.mark(function _callee4(publicJwk, privateJwk) { var namedCurve, curve, ec, priKeyObj, privateOct, pubKeyObj, publicOct, privateKey, publicKey, len; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: namedCurve = privateJwk.crv; curve = _params.default.namedCurves[namedCurve].indutnyName; ec = new Ec(curve); priKeyObj = new _jsCryptoKeyUtils.Key('jwk', privateJwk); if (priKeyObj.isPrivate) { _context4.next = 6; break; } throw new Error('NotPrivateKeyForECCSDeriveKeyPureJS'); case 6: _context4.next = 8; return priKeyObj.export('oct'); case 8: privateOct = _context4.sent; pubKeyObj = new _jsCryptoKeyUtils.Key('jwk', publicJwk); if (!pubKeyObj.isPrivate) { _context4.next = 12; break; } throw new Error('NotPublicKeyForECCDeriveKeyPureJS'); case 12: _context4.next = 14; return pubKeyObj.export('oct', { compact: false, outputPublic: true }); case 14: publicOct = _context4.sent; privateKey = ec.keyFromPrivate(privateOct); publicKey = ec.keyFromPublic(publicOct); // derive shared key len = _params.default.namedCurves[namedCurve].payloadSize; return _context4.abrupt("return", new Uint8Array(privateKey.derive(publicKey.getPublic()).toArray('be', len))); case 19: case "end": return _context4.stop(); } } }, _callee4); })); return function deriveSecret(_x11, _x12) { return _ref4.apply(this, arguments); }; }(); exports.deriveSecret = deriveSecret;