forked from daren.hsu/line_push
351 lines
11 KiB
JavaScript
351 lines
11 KiB
JavaScript
"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<Uint8Array>} - 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<boolean>} - 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<Uint8Array>} - 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; |