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.
144 lines (139 loc) • 18.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getCurve = getCurve;
exports.getGenerator = getGenerator;
var _curve = require("../core/curve.js");
var _point = require("../core/point.js");
/**
* Pre-defined elliptic curve parameters, generator points, and a lookup function.
*
* All parameters are from the SEC 2 / NIST standards.
*
* Supported curves:
* secp192k1, secp192r1 — 192-bit (Koblitz & random)
* secp224k1, secp224r1 — 224-bit
* secp256k1, secp256r1 — 256-bit (secp256k1 is used by Bitcoin)
* secp384r1 — 384-bit (NIST P-384)
* secp521r1 — 521-bit (NIST P-521)
*/
// --------------------------------------------------------------------------
// Standard curves (params from SEC 2 / NIST standards)
// --------------------------------------------------------------------------
var _REGISTRY = {
secp192k1: {
p: 0xfffffffffffffffffffffffffffffffffffffffeffffee37n,
a: 0x0n,
b: 0x3n,
Gx: 0xdb4ff10ec057e9ae26b07d0280b7f4341da5d1b1eae06c7dn,
Gy: 0x9b2f2f6d9c5628a7844163d015be86344082aa88d95e2f9dn,
n: 0xfffffffffffffffffffffffe26f2fc170f69466a74defd8dn,
h: 1n
},
secp192r1: {
p: 0xfffffffffffffffffffffffffffffffeffffffffffffffffn,
a: 0xfffffffffffffffffffffffffffffffefffffffffffffffcn,
b: 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1n,
Gx: 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012n,
Gy: 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811n,
n: 0xffffffffffffffffffffffff99def836146bc9b1b4d22831n,
h: 1n
},
secp224k1: {
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffeffffe56dn,
a: 0x0n,
b: 0x5n,
Gx: 0xa1455b334df099df30fc28a169a467e9e47075a90f7e650eb6b7a45cn,
Gy: 0x7e089fed7fba344282cafbd6f7e319f7c0b0bd59e2ca4bdb556d61a5n,
n: 0x10000000000000000000000000001dce8d2ec6184caf0a971769fb1f7n,
h: 1n
},
secp224r1: {
p: 0xffffffffffffffffffffffffffffffff000000000000000000000001n,
a: 0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffen,
b: 0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4n,
Gx: 0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21n,
Gy: 0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34n,
n: 0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3dn,
h: 1n
},
secp256k1: {
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
a: 0x0n,
b: 0x7n,
Gx: 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798n,
Gy: 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8n,
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
h: 1n
},
secp256r1: {
p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,
a: 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffcn,
b: 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn,
Gx: 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n,
Gy: 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n,
n: 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n,
h: 1n
},
secp384r1: {
p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffn,
a: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffcn,
b: 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aefn,
Gx: 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7n,
Gy: 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5fn,
n: 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973n,
h: 1n
},
secp521r1: {
p: 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn,
a: 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffcn,
b: 0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00n,
Gx: 0x0c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66n,
Gy: 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650n,
n: 0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409n,
h: 1n
}
};
/**
* Return a CurveParams by standard name (case-insensitive).
*
* @param {string} name - Curve name (e.g. "secp256k1").
* @returns {CurveParams}
* @throws {Error} If the curve name is not registered.
*/
function getCurve(name) {
var key = name.toLowerCase().trim();
if (!(key in _REGISTRY)) {
var available = Object.keys(_REGISTRY).sort().join(', ');
throw new Error("Unknown curve '".concat(name, "'. Available: ").concat(available));
}
var entry = _REGISTRY[key];
return new _curve.CurveParams({
p: entry.p,
a: entry.a,
b: entry.b,
n: entry.n,
h: entry.h
});
}
/**
* Return the generator Point G for a named curve.
*
* The generator G is a point of order n on the curve, meaning n·G = O.
*
* @param {string} name - Curve name (e.g. "secp256k1").
* @returns {Point}
* @throws {Error} If the curve name is not registered.
*/
function getGenerator(name) {
var key = name.toLowerCase().trim();
if (!(key in _REGISTRY)) {
var available = Object.keys(_REGISTRY).sort().join(', ');
throw new Error("Unknown curve '".concat(name, "'. Available: ").concat(available));
}
var entry = _REGISTRY[key];
var curve = getCurve(name);
return new _point.Point(entry.Gx, entry.Gy, curve);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY3VydmUiLCJyZXF1aXJlIiwiX3BvaW50IiwiX1JFR0lTVFJZIiwic2VjcDE5MmsxIiwicCIsImEiLCJiIiwiR3giLCJHeSIsIm4iLCJoIiwic2VjcDE5MnIxIiwic2VjcDIyNGsxIiwic2VjcDIyNHIxIiwic2VjcDI1NmsxIiwic2VjcDI1NnIxIiwic2VjcDM4NHIxIiwic2VjcDUyMXIxIiwiZ2V0Q3VydmUiLCJuYW1lIiwia2V5IiwidG9Mb3dlckNhc2UiLCJ0cmltIiwiYXZhaWxhYmxlIiwiT2JqZWN0Iiwia2V5cyIsInNvcnQiLCJqb2luIiwiRXJyb3IiLCJjb25jYXQiLCJlbnRyeSIsIkN1cnZlUGFyYW1zIiwiZ2V0R2VuZXJhdG9yIiwiY3VydmUiLCJQb2ludCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9jdXJ2ZXMvcmVnaXN0cnkuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQcmUtZGVmaW5lZCBlbGxpcHRpYyBjdXJ2ZSBwYXJhbWV0ZXJzLCBnZW5lcmF0b3IgcG9pbnRzLCBhbmQgYSBsb29rdXAgZnVuY3Rpb24uXG4gKlxuICogQWxsIHBhcmFtZXRlcnMgYXJlIGZyb20gdGhlIFNFQyAyIC8gTklTVCBzdGFuZGFyZHMuXG4gKlxuICogU3VwcG9ydGVkIGN1cnZlczpcbiAqICAgc2VjcDE5MmsxLCBzZWNwMTkycjEgICAgIOKAlCAxOTItYml0IChLb2JsaXR6ICYgcmFuZG9tKVxuICogICBzZWNwMjI0azEsIHNlY3AyMjRyMSAgICAg4oCUIDIyNC1iaXRcbiAqICAgc2VjcDI1NmsxLCBzZWNwMjU2cjEgICAgIOKAlCAyNTYtYml0IChzZWNwMjU2azEgaXMgdXNlZCBieSBCaXRjb2luKVxuICogICBzZWNwMzg0cjEgICAgICAgICAgICAgICAg4oCUIDM4NC1iaXQgKE5JU1QgUC0zODQpXG4gKiAgIHNlY3A1MjFyMSAgICAgICAgICAgICAgICDigJQgNTIxLWJpdCAoTklTVCBQLTUyMSlcbiAqL1xuXG5pbXBvcnQgeyBDdXJ2ZVBhcmFtcyB9IGZyb20gJy4uL2NvcmUvY3VydmUuanMnXG5pbXBvcnQgeyBQb2ludCB9IGZyb20gJy4uL2NvcmUvcG9pbnQuanMnXG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTdGFuZGFyZCBjdXJ2ZXMgIChwYXJhbXMgZnJvbSBTRUMgMiAvIE5JU1Qgc3RhbmRhcmRzKVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgX1JFR0lTVFJZID0ge1xuICBzZWNwMTkyazE6IHtcbiAgICBwOiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZWUzN24sXG4gICAgYTogMHgwbixcbiAgICBiOiAweDNuLFxuICAgIEd4OiAweGRiNGZmMTBlYzA1N2U5YWUyNmIwN2QwMjgwYjdmNDM0MWRhNWQxYjFlYWUwNmM3ZG4sXG4gICAgR3k6IDB4OWIyZjJmNmQ5YzU2MjhhNzg0NDE2M2QwMTViZTg2MzQ0MDgyYWE4OGQ5NWUyZjlkbixcbiAgICBuOiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZTI2ZjJmYzE3MGY2OTQ2NmE3NGRlZmQ4ZG4sXG4gICAgaDogMW4sXG4gIH0sXG4gIHNlY3AxOTJyMToge1xuICAgIHA6IDB4ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVmZmZmZmZmZmZmZmZmZmZmbixcbiAgICBhOiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmZmZmZmZmZmY24sXG4gICAgYjogMHg2NDIxMDUxOWU1OWM4MGU3MGZhN2U5YWI3MjI0MzA0OWZlYjhkZWVjYzE0NmI5YjFuLFxuICAgIEd4OiAweDE4OGRhODBlYjAzMDkwZjY3Y2JmMjBlYjQzYTE4ODAwZjRmZjBhZmQ4MmZmMTAxMm4sXG4gICAgR3k6IDB4MDcxOTJiOTVmZmM4ZGE3ODYzMTAxMWVkNmIyNGNkZDU3M2Y5NzdhMTFlNzk0ODExbixcbiAgICBuOiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjk5ZGVmODM2MTQ2YmM5YjFiNGQyMjgzMW4sXG4gICAgaDogMW4sXG4gIH0sXG4gIHNlY3AyMjRrMToge1xuICAgIHA6IDB4ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmU1NmRuLFxuICAgIGE6IDB4MG4sXG4gICAgYjogMHg1bixcbiAgICBHeDogMHhhMTQ1NWIzMzRkZjA5OWRmMzBmYzI4YTE2OWE0NjdlOWU0NzA3NWE5MGY3ZTY1MGViNmI3YTQ1Y24sXG4gICAgR3k6IDB4N2UwODlmZWQ3ZmJhMzQ0MjgyY2FmYmQ2ZjdlMzE5ZjdjMGIwYmQ1OWUyY2E0YmRiNTU2ZDYxYTVuLFxuICAgIG46IDB4MTAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDFkY2U4ZDJlYzYxODRjYWYwYTk3MTc2OWZiMWY3bixcbiAgICBoOiAxbixcbiAgfSxcbiAgc2VjcDIyNHIxOiB7XG4gICAgcDogMHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMW4sXG4gICAgYTogMHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZW4sXG4gICAgYjogMHhiNDA1MGE4NTBjMDRiM2FiZjU0MTMyNTY1MDQ0YjBiN2Q3YmZkOGJhMjcwYjM5NDMyMzU1ZmZiNG4sXG4gICAgR3g6IDB4YjcwZTBjYmQ2YmI0YmY3ZjMyMTM5MGI5NGEwM2MxZDM1NmMyMTEyMjM0MzI4MGQ2MTE1YzFkMjFuLFxuICAgIEd5OiAweGJkMzc2Mzg4YjVmNzIzZmI0YzIyZGZlNmNkNDM3NWEwNWEwNzQ3NjQ0NGQ1ODE5OTg1MDA3ZTM0bixcbiAgICBuOiAweGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYxNmEyZTBiOGYwM2UxM2RkMjk0NTVjNWMyYTNkbixcbiAgICBoOiAxbixcbiAgfSxcbiAgc2VjcDI1NmsxOiB7XG4gICAgcDogMHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZmYzJmbixcbiAgICBhOiAweDBuLFxuICAgIGI6IDB4N24sXG4gICAgR3g6IDB4NzliZTY2N2VmOWRjYmJhYzU1YTA2Mjk1Y2U4NzBiMDcwMjliZmNkYjJkY2UyOGQ5NTlmMjgxNWIxNmY4MTc5OG4sXG4gICAgR3k6IDB4NDgzYWRhNzcyNmEzYzQ2NTVkYTRmYmZjMGUxMTA4YThmZDE3YjQ0OGE2ODU1NDE5OWM0N2QwOGZmYjEwZDRiOG4sXG4gICAgbjogMHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWJhYWVkY2U2YWY0OGEwM2JiZmQyNWU4Y2QwMzY0MTQxbixcbiAgICBoOiAxbixcbiAgfSxcbiAgc2VjcDI1NnIxOiB7XG4gICAgcDogMHhmZmZmZmZmZjAwMDAwMDAxMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmbixcbiAgICBhOiAweGZmZmZmZmZmMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNuLFxuICAgIGI6IDB4NWFjNjM1ZDhhYTNhOTNlN2IzZWJiZDU1NzY5ODg2YmM2NTFkMDZiMGNjNTNiMGY2M2JjZTNjM2UyN2QyNjA0Ym4sXG4gICAgR3g6IDB4NmIxN2QxZjJlMTJjNDI0N2Y4YmNlNmU1NjNhNDQwZjI3NzAzN2Q4MTJkZWIzM2EwZjRhMTM5NDVkODk4YzI5Nm4sXG4gICAgR3k6IDB4NGZlMzQyZTJmZTFhN2Y5YjhlZTdlYjRhN2MwZjllMTYyYmNlMzM1NzZiMzE1ZWNlY2JiNjQwNjgzN2JmNTFmNW4sXG4gICAgbjogMHhmZmZmZmZmZjAwMDAwMDAwZmZmZmZmZmZmZmZmZmZmZmJjZTZmYWFkYTcxNzllODRmM2I5Y2FjMmZjNjMyNTUxbixcbiAgICBoOiAxbixcbiAgfSxcbiAgc2VjcDM4NHIxOiB7XG4gICAgcDogMHhmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZlZmZmZmZmZmYwMDAwMDAwMDAwMDAwMDAwZmZmZmZmZmZuLFxuICAgIGE6IDB4ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZWZmZmZmZmZmMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZjbixcbiAgICBiOiAweGIzMzEyZmE3ZTIzZWU3ZTQ5ODhlMDU2YmUzZjgyZDE5MTgxZDljNmVmZTgxNDExMjAzMTQwODhmNTAxMzg3NWFjNjU2Mzk4ZDhhMmVkMTlkMmE4NWM4ZWRkM2VjMmFlZm4sXG4gICAgR3g6IDB4YWE4N2NhMjJiZThiMDUzNzhlYjFjNzFlZjMyMGFkNzQ2ZTFkM2I2MjhiYTc5Yjk4NTlmNzQxZTA4MjU0MmEzODU1MDJmMjVkYmY1NTI5NmMzYTU0NWUzODcyNzYwYWI3bixcbiAgICBHeTogMHgzNjE3ZGU0YTk2MjYyYzZmNWQ5ZTk4YmY5MjkyZGMyOWY4ZjQxZGJkMjg5YTE0N2NlOWRhMzExM2I1ZjBiOGMwMGE2MGIxY2UxZDdlODE5ZDdhNDMxZDdjOTBlYTBlNWZuLFxuICAgIG46IDB4ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYzc2MzRkODFmNDM3MmRkZjU4MWEwZGIyNDhiMGE3N2FlY2VjMTk2YWNjYzUyOTczbixcbiAgICBoOiAxbixcbiAgfSxcbiAgc2VjcDUyMXIxOiB7XG4gICAgcDogMHgxZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm4sXG4gICAgYTogMHgxZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmY24sXG4gICAgYjogMHgwNTE5NTNlYjk2MThlMWM5YTFmOTI5YTIxYTBiNjg1NDBlZWEyZGE3MjViOTliMzE1ZjNiOGI0ODk5MThlZjEwOWUxNTYxOTM5NTFlYzdlOTM3YjE2NTJjMGJkM2JiMWJmMDczNTczZGY4ODNkMmMzNGYxZWY0NTFmZDQ2YjUwM2YwMG4sXG4gICAgR3g6IDB4MGM2ODU4ZTA2YjcwNDA0ZTljZDllM2VjYjY2MjM5NWI0NDI5YzY0ODEzOTA1M2ZiNTIxZjgyOGFmNjA2YjRkM2RiYWExNGI1ZTc3ZWZlNzU5MjhmZTFkYzEyN2EyZmZhOGRlMzM0OGIzYzE4NTZhNDI5YmY5N2U3ZTMxYzJlNWJkNjZuLFxuICAgIEd5OiAweDExODM5Mjk2YTc4OWEzYmMwMDQ1YzhhNWZiNDJjN2QxYmQ5OThmNTQ0NDk1NzliNDQ2ODE3YWZiZDE3MjczZTY2MmM5N2VlNzI5OTVlZjQyNjQwYzU1MGI5MDEzZmFkMDc2MTM1M2M3MDg2YTI3MmMyNDA4OGJlOTQ3NjlmZDE2NjUwbixcbiAgICBuOiAweDFmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmE1MTg2ODc4M2JmMmY5NjZiN2ZjYzAxNDhmNzA5YTVkMDNiYjVjOWI4ODk5YzQ3YWViYjZmYjcxZTkxMzg2NDA5bixcbiAgICBoOiAxbixcbiAgfSxcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBDdXJ2ZVBhcmFtcyBieSBzdGFuZGFyZCBuYW1lIChjYXNlLWluc2Vuc2l0aXZlKS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIEN1cnZlIG5hbWUgKGUuZy4gXCJzZWNwMjU2azFcIikuXG4gKiBAcmV0dXJucyB7Q3VydmVQYXJhbXN9XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGN1cnZlIG5hbWUgaXMgbm90IHJlZ2lzdGVyZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDdXJ2ZShuYW1lKSB7XG4gIGNvbnN0IGtleSA9IG5hbWUudG9Mb3dlckNhc2UoKS50cmltKClcbiAgaWYgKCEoa2V5IGluIF9SRUdJU1RSWSkpIHtcbiAgICBjb25zdCBhdmFpbGFibGUgPSBPYmplY3Qua2V5cyhfUkVHSVNUUlkpLnNvcnQoKS5qb2luKCcsICcpXG4gICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGN1cnZlICcke25hbWV9Jy4gQXZhaWxhYmxlOiAke2F2YWlsYWJsZX1gKVxuICB9XG4gIGNvbnN0IGVudHJ5ID0gX1JFR0lTVFJZW2tleV1cbiAgcmV0dXJuIG5ldyBDdXJ2ZVBhcmFtcyh7XG4gICAgcDogZW50cnkucCxcbiAgICBhOiBlbnRyeS5hLFxuICAgIGI6IGVudHJ5LmIsXG4gICAgbjogZW50cnkubixcbiAgICBoOiBlbnRyeS5oLFxuICB9KVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgZ2VuZXJhdG9yIFBvaW50IEcgZm9yIGEgbmFtZWQgY3VydmUuXG4gKlxuICogVGhlIGdlbmVyYXRvciBHIGlzIGEgcG9pbnQgb2Ygb3JkZXIgbiBvbiB0aGUgY3VydmUsIG1lYW5pbmcgbsK3RyA9IE8uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBDdXJ2ZSBuYW1lIChlLmcuIFwic2VjcDI1NmsxXCIpLlxuICogQHJldHVybnMge1BvaW50fVxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBjdXJ2ZSBuYW1lIGlzIG5vdCByZWdpc3RlcmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0R2VuZXJhdG9yKG5hbWUpIHtcbiAgY29uc3Qga2V5ID0gbmFtZS50b0xvd2VyQ2FzZSgpLnRyaW0oKVxuICBpZiAoIShrZXkgaW4gX1JFR0lTVFJZKSkge1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IE9iamVjdC5rZXlzKF9SRUdJU1RSWSkuc29ydCgpLmpvaW4oJywgJylcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gY3VydmUgJyR7bmFtZX0nLiBBdmFpbGFibGU6ICR7YXZhaWxhYmxlfWApXG4gIH1cbiAgY29uc3QgZW50cnkgPSBfUkVHSVNUUllba2V5XVxuICBjb25zdCBjdXJ2ZSA9IGdldEN1cnZlKG5hbWUpXG4gIHJldHVybiBuZXcgUG9pbnQoZW50cnkuR3gsIGVudHJ5Lkd5LCBjdXJ2ZSlcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQWFBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE1BQUEsR0FBQUQsT0FBQTtBQWRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFLQTtBQUNBO0FBQ0E7O0FBRUEsSUFBTUUsU0FBUyxHQUFHO0VBQ2hCQyxTQUFTLEVBQUU7SUFDVEMsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsRUFBRSxFQUFFLG1EQUFtRDtJQUN2REMsRUFBRSxFQUFFLG1EQUFtRDtJQUN2REMsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNEQyxTQUFTLEVBQUU7SUFDVFAsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsRUFBRSxFQUFFLG1EQUFtRDtJQUN2REMsRUFBRSxFQUFFLG1EQUFtRDtJQUN2REMsQ0FBQyxFQUFFLG1EQUFtRDtJQUN0REMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNERSxTQUFTLEVBQUU7SUFDVFIsQ0FBQyxFQUFFLDJEQUEyRDtJQUM5REMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsRUFBRSxFQUFFLDJEQUEyRDtJQUMvREMsRUFBRSxFQUFFLDJEQUEyRDtJQUMvREMsQ0FBQyxFQUFFLDREQUE0RDtJQUMvREMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNERyxTQUFTLEVBQUU7SUFDVFQsQ0FBQyxFQUFFLDJEQUEyRDtJQUM5REMsQ0FBQyxFQUFFLDJEQUEyRDtJQUM5REMsQ0FBQyxFQUFFLDJEQUEyRDtJQUM5REMsRUFBRSxFQUFFLDJEQUEyRDtJQUMvREMsRUFBRSxFQUFFLDJEQUEyRDtJQUMvREMsQ0FBQyxFQUFFLDJEQUEyRDtJQUM5REMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNESSxTQUFTLEVBQUU7SUFDVFYsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsQ0FBQyxFQUFFLElBQUk7SUFDUEMsRUFBRSxFQUFFLG1FQUFtRTtJQUN2RUMsRUFBRSxFQUFFLG1FQUFtRTtJQUN2RUMsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNESyxTQUFTLEVBQUU7SUFDVFgsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsRUFBRSxFQUFFLG1FQUFtRTtJQUN2RUMsRUFBRSxFQUFFLG1FQUFtRTtJQUN2RUMsQ0FBQyxFQUFFLG1FQUFtRTtJQUN0RUMsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNETSxTQUFTLEVBQUU7SUFDVFosQ0FBQyxFQUFFLG1HQUFtRztJQUN0R0MsQ0FBQyxFQUFFLG1HQUFtRztJQUN0R0MsQ0FBQyxFQUFFLG1HQUFtRztJQUN0R0MsRUFBRSxFQUFFLG1HQUFtRztJQUN2R0MsRUFBRSxFQUFFLG1HQUFtRztJQUN2R0MsQ0FBQyxFQUFFLG1HQUFtRztJQUN0R0MsQ0FBQyxFQUFFO0VBQ0wsQ0FBQztFQUNETyxTQUFTLEVBQUU7SUFDVGIsQ0FBQyxFQUFFLHNJQUFzSTtJQUN6SUMsQ0FBQyxFQUFFLHNJQUFzSTtJQUN6SUMsQ0FBQyxFQUFFLHNJQUFzSTtJQUN6SUMsRUFBRSxFQUFFLHNJQUFzSTtJQUMxSUMsRUFBRSxFQUFFLHNJQUFzSTtJQUMxSUMsQ0FBQyxFQUFFLHNJQUFzSTtJQUN6SUMsQ0FBQyxFQUFFO0VBQ0w7QUFDRixDQUFDOztBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ08sU0FBU1EsUUFBUUEsQ0FBQ0MsSUFBSSxFQUFFO0VBQzdCLElBQU1DLEdBQUcsR0FBR0QsSUFBSSxDQUFDRSxXQUFXLENBQUMsQ0FBQyxDQUFDQyxJQUFJLENBQUMsQ0FBQztFQUNyQyxJQUFJLEVBQUVGLEdBQUcsSUFBSWxCLFNBQVMsQ0FBQyxFQUFFO0lBQ3ZCLElBQU1xQixTQUFTLEdBQUdDLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDdkIsU0FBUyxDQUFDLENBQUN3QixJQUFJLENBQUMsQ0FBQyxDQUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQzFELE1BQU0sSUFBSUMsS0FBSyxtQkFBQUMsTUFBQSxDQUFtQlYsSUFBSSxvQkFBQVUsTUFBQSxDQUFpQk4sU0FBUyxDQUFFLENBQUM7RUFDckU7RUFDQSxJQUFNTyxLQUFLLEdBQUc1QixTQUFTLENBQUNrQixHQUFHLENBQUM7RUFDNUIsT0FBTyxJQUFJVyxrQkFBVyxDQUFDO0lBQ3JCM0IsQ0FBQyxFQUFFMEIsS0FBSyxDQUFDMUIsQ0FBQztJQUNWQyxDQUFDLEVBQUV5QixLQUFLLENBQUN6QixDQUFDO0lBQ1ZDLENBQUMsRUFBRXdCLEtBQUssQ0FBQ3hCLENBQUM7SUFDVkcsQ0FBQyxFQUFFcUIsS0FBSyxDQUFDckIsQ0FBQztJQUNWQyxDQUFDLEVBQUVvQixLQUFLLENBQUNwQjtFQUNYLENBQUMsQ0FBQztBQUNKOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLFNBQVNzQixZQUFZQSxDQUFDYixJQUFJLEVBQUU7RUFDakMsSUFBTUMsR0FBRyxHQUFHRCxJQUFJLENBQUNFLFdBQVcsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxDQUFDO0VBQ3JDLElBQUksRUFBRUYsR0FBRyxJQUFJbEIsU0FBUyxDQUFDLEVBQUU7SUFDdkIsSUFBTXFCLFNBQVMsR0FBR0MsTUFBTSxDQUFDQyxJQUFJLENBQUN2QixTQUFTLENBQUMsQ0FBQ3dCLElBQUksQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDMUQsTUFBTSxJQUFJQyxLQUFLLG1CQUFBQyxNQUFBLENBQW1CVixJQUFJLG9CQUFBVSxNQUFBLENBQWlCTixTQUFTLENBQUUsQ0FBQztFQUNyRTtFQUNBLElBQU1PLEtBQUssR0FBRzVCLFNBQVMsQ0FBQ2tCLEdBQUcsQ0FBQztFQUM1QixJQUFNYSxLQUFLLEdBQUdmLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDO0VBQzVCLE9BQU8sSUFBSWUsWUFBSyxDQUFDSixLQUFLLENBQUN2QixFQUFFLEVBQUV1QixLQUFLLENBQUN0QixFQUFFLEVBQUV5QixLQUFLLENBQUM7QUFDN0MiLCJpZ25vcmVMaXN0IjpbXX0=