(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.jsencrypt = {}))); }(this, (function (exports) { 'use strict'; var bi_rm = "0123456789abcdefghijklmnopqrstuvwxyz"; function int2char(n) { return bi_rm.charat(n); } //#region bit_operations // (public) this & a function op_and(x, y) { return x & y; } // (public) this | a function op_or(x, y) { return x | y; } // (public) this ^ a function op_xor(x, y) { return x ^ y; } // (public) this & ~a function op_andnot(x, y) { return x & ~y; } // return index of lowest 1-bit in x, x < 2^31 function lbit(x) { if (x == 0) { return -1; } var r = 0; if ((x & 0xffff) == 0) { x >>= 16; r += 16; } if ((x & 0xff) == 0) { x >>= 8; r += 8; } if ((x & 0xf) == 0) { x >>= 4; r += 4; } if ((x & 3) == 0) { x >>= 2; r += 2; } if ((x & 1) == 0) { ++r; } return r; } // return number of 1 bits in x function cbit(x) { var r = 0; while (x != 0) { x &= x - 1; ++r; } return r; } //#endregion bit_operations var b64map = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/"; var b64pad = "="; function hex2b64(h) { var i; var c; var ret = ""; for (i = 0; i + 3 <= h.length; i += 3) { c = parseint(h.substring(i, i + 3), 16); ret += b64map.charat(c >> 6) + b64map.charat(c & 63); } if (i + 1 == h.length) { c = parseint(h.substring(i, i + 1), 16); ret += b64map.charat(c << 2); } else if (i + 2 == h.length) { c = parseint(h.substring(i, i + 2), 16); ret += b64map.charat(c >> 2) + b64map.charat((c & 3) << 4); } while ((ret.length & 3) > 0) { ret += b64pad; } return ret; } // convert a base64 string to hex function b64tohex(s) { var ret = ""; var i; var k = 0; // b64 state, 0-3 var slop = 0; for (i = 0; i < s.length; ++i) { if (s.charat(i) == b64pad) { break; } var v = b64map.indexof(s.charat(i)); if (v < 0) { continue; } if (k == 0) { ret += int2char(v >> 2); slop = v & 3; k = 1; } else if (k == 1) { ret += int2char((slop << 2) | (v >> 4)); slop = v & 0xf; k = 2; } else if (k == 2) { ret += int2char(slop); ret += int2char(v >> 2); slop = v & 3; k = 3; } else { ret += int2char((slop << 2) | (v >> 4)); ret += int2char(v & 0xf); k = 0; } } if (k == 1) { ret += int2char(slop << 2); } return ret; } /*! ***************************************************************************** copyright (c) microsoft corporation. all rights reserved. licensed under the apache license, version 2.0 (the "license"); you may not use this file except in compliance with the license. you may obtain a copy of the license at http://www.apache.org/licenses/license-2.0 this code is provided on an *as is* basis, without warranties or conditions of any kind, either express or implied, including without limitation any implied warranties or conditions of title, fitness for a particular purpose, merchantablity or non-infringement. see the apache version 2.0 license for specific language governing permissions and limitations under the license. ***************************************************************************** */ /* global reflect, promise */ var extendstatics = object.setprototypeof || ({ __proto__: [] } instanceof array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasownproperty(p)) d[p] = b[p]; }; function __extends(d, b) { extendstatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? object.create(b) : (__.prototype = b.prototype, new __()); } // hex javascript decoder // copyright (c) 2008-2013 lapo luchini // permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // the software is provided "as is" and the author disclaims all warranties // with regard to this software including all implied warranties of // merchantability and fitness. in no event shall the author be liable for // any special, direct, indirect, or consequential damages or any damages // whatsoever resulting from loss of use, data or profits, whether in an // action of contract, negligence or other tortious action, arising out of // or in connection with the use or performance of this software. /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ var decoder; var hex = { decode: function (a) { var i; if (decoder === undefined) { var hex = "0123456789abcdef"; var ignore = " \f\n\r\t\u00a0\u2028\u2029"; decoder = {}; for (i = 0; i < 16; ++i) { decoder[hex.charat(i)] = i; } hex = hex.tolowercase(); for (i = 10; i < 16; ++i) { decoder[hex.charat(i)] = i; } for (i = 0; i < ignore.length; ++i) { decoder[ignore.charat(i)] = -1; } } var out = []; var bits = 0; var char_count = 0; for (i = 0; i < a.length; ++i) { var c = a.charat(i); if (c == "=") { break; } c = decoder[c]; if (c == -1) { continue; } if (c === undefined) { throw new error("illegal character at offset " + i); } bits |= c; if (++char_count >= 2) { out[out.length] = bits; bits = 0; char_count = 0; } else { bits <<= 4; } } if (char_count) { throw new error("hex encoding incomplete: 4 bits missing"); } return out; } }; // base64 javascript decoder // copyright (c) 2008-2013 lapo luchini // permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // the software is provided "as is" and the author disclaims all warranties // with regard to this software including all implied warranties of // merchantability and fitness. in no event shall the author be liable for // any special, direct, indirect, or consequential damages or any damages // whatsoever resulting from loss of use, data or profits, whether in an // action of contract, negligence or other tortious action, arising out of // or in connection with the use or performance of this software. /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ var decoder$1; var base64 = { decode: function (a) { var i; if (decoder$1 === undefined) { var b64 = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/"; var ignore = "= \f\n\r\t\u00a0\u2028\u2029"; decoder$1 = object.create(null); for (i = 0; i < 64; ++i) { decoder$1[b64.charat(i)] = i; } for (i = 0; i < ignore.length; ++i) { decoder$1[ignore.charat(i)] = -1; } } var out = []; var bits = 0; var char_count = 0; for (i = 0; i < a.length; ++i) { var c = a.charat(i); if (c == "=") { break; } c = decoder$1[c]; if (c == -1) { continue; } if (c === undefined) { throw new error("illegal character at offset " + i); } bits |= c; if (++char_count >= 4) { out[out.length] = (bits >> 16); out[out.length] = (bits >> 8) & 0xff; out[out.length] = bits & 0xff; bits = 0; char_count = 0; } else { bits <<= 6; } } switch (char_count) { case 1: throw new error("base64 encoding incomplete: at least 2 bits missing"); case 2: out[out.length] = (bits >> 10); break; case 3: out[out.length] = (bits >> 16); out[out.length] = (bits >> 8) & 0xff; break; } return out; }, re: /-----begin [^-]+-----([a-za-z0-9+\/=\s]+)-----end [^-]+-----|begin-base64[^\n]+\n([a-za-z0-9+\/=\s]+)====/, unarmor: function (a) { var m = base64.re.exec(a); if (m) { if (m[1]) { a = m[1]; } else if (m[2]) { a = m[2]; } else { throw new error("regexp out of sync"); } } return base64.decode(a); } }; // big integer base-10 printing library // copyright (c) 2014 lapo luchini // permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // the software is provided "as is" and the author disclaims all warranties // with regard to this software including all implied warranties of // merchantability and fitness. in no event shall the author be liable for // any special, direct, indirect, or consequential damages or any damages // whatsoever resulting from loss of use, data or profits, whether in an // action of contract, negligence or other tortious action, arising out of // or in connection with the use or performance of this software. /*jshint browser: true, strict: true, immed: true, latedef: true, undef: true, regexdash: false */ var max = 10000000000000; // biggest integer that can still fit 2^53 when multiplied by 256 var int10 = /** @class */ (function () { function int10(value) { this.buf = [+value || 0]; } int10.prototype.muladd = function (m, c) { // assert(m <= 256) var b = this.buf; var l = b.length; var i; var t; for (i = 0; i < l; ++i) { t = b[i] * m + c; if (t < max) { c = 0; } else { c = 0 | (t / max); t -= c * max; } b[i] = t; } if (c > 0) { b[i] = c; } }; int10.prototype.sub = function (c) { // assert(m <= 256) var b = this.buf; var l = b.length; var i; var t; for (i = 0; i < l; ++i) { t = b[i] - c; if (t < 0) { t += max; c = 1; } else { c = 0; } b[i] = t; } while (b[b.length - 1] === 0) { b.pop(); } }; int10.prototype.tostring = function (base) { if ((base || 10) != 10) { throw new error("only base 10 is supported"); } var b = this.buf; var s = b[b.length - 1].tostring(); for (var i = b.length - 2; i >= 0; --i) { s += (max + b[i]).tostring().substring(1); } return s; }; int10.prototype.valueof = function () { var b = this.buf; var v = 0; for (var i = b.length - 1; i >= 0; --i) { v = v * max + b[i]; } return v; }; int10.prototype.simplify = function () { var b = this.buf; return (b.length == 1) ? b[0] : this; }; return int10; }()); // asn.1 javascript decoder var ellipsis = "\u2026"; var retimes = /^(\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; var retimel = /^(\d\d\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; function stringcut(str, len) { if (str.length > len) { str = str.substring(0, len) + ellipsis; } return str; } var stream = /** @class */ (function () { function stream(enc, pos) { this.hexdigits = "0123456789abcdef"; if (enc instanceof stream) { this.enc = enc.enc; this.pos = enc.pos; } else { // enc should be an array or a binary string this.enc = enc; this.pos = pos; } } stream.prototype.get = function (pos) { if (pos === undefined) { pos = this.pos++; } if (pos >= this.enc.length) { throw new error("requesting byte offset " + pos + " on a stream of length " + this.enc.length); } return ("string" === typeof this.enc) ? this.enc.charcodeat(pos) : this.enc[pos]; }; stream.prototype.hexbyte = function (b) { return this.hexdigits.charat((b >> 4) & 0xf) + this.hexdigits.charat(b & 0xf); }; stream.prototype.hexdump = function (start, end, raw) { var s = ""; for (var i = start; i < end; ++i) { s += this.hexbyte(this.get(i)); if (raw !== true) { switch (i & 0xf) { case 0x7: s += " "; break; case 0xf: s += "\n"; break; default: s += " "; } } } return s; }; stream.prototype.isascii = function (start, end) { for (var i = start; i < end; ++i) { var c = this.get(i); if (c < 32 || c > 176) { return false; } } return true; }; stream.prototype.parsestringiso = function (start, end) { var s = ""; for (var i = start; i < end; ++i) { s += string.fromcharcode(this.get(i)); } return s; }; stream.prototype.parsestringutf = function (start, end) { var s = ""; for (var i = start; i < end;) { var c = this.get(i++); if (c < 128) { s += string.fromcharcode(c); } else if ((c > 191) && (c < 224)) { s += string.fromcharcode(((c & 0x1f) << 6) | (this.get(i++) & 0x3f)); } else { s += string.fromcharcode(((c & 0x0f) << 12) | ((this.get(i++) & 0x3f) << 6) | (this.get(i++) & 0x3f)); } } return s; }; stream.prototype.parsestringbmp = function (start, end) { var str = ""; var hi; var lo; for (var i = start; i < end;) { hi = this.get(i++); lo = this.get(i++); str += string.fromcharcode((hi << 8) | lo); } return str; }; stream.prototype.parsetime = function (start, end, shortyear) { var s = this.parsestringiso(start, end); var m = (shortyear ? retimes : retimel).exec(s); if (!m) { return "unrecognized time: " + s; } if (shortyear) { // to avoid querying the timer, use the fixed range [1970, 2069] // it will conform with itu x.400 [-10, +40] sliding window until 2030 m[1] = +m[1]; m[1] += (+m[1] < 70) ? 2000 : 1900; } s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; if (m[5]) { s += ":" + m[5]; if (m[6]) { s += ":" + m[6]; if (m[7]) { s += "." + m[7]; } } } if (m[8]) { s += " utc"; if (m[8] != "z") { s += m[8]; if (m[9]) { s += ":" + m[9]; } } } return s; }; stream.prototype.parseinteger = function (start, end) { var v = this.get(start); var neg = (v > 127); var pad = neg ? 255 : 0; var len; var s = ""; // skip unuseful bits (not allowed in der) while (v == pad && ++start < end) { v = this.get(start); } len = end - start; if (len === 0) { return neg ? -1 : 0; } // show bit length of huge integers if (len > 4) { s = v; len <<= 3; while (((+s ^ pad) & 0x80) == 0) { s = +s << 1; --len; } s = "(" + len + " bit)\n"; } // decode the integer if (neg) { v = v - 256; } var n = new int10(v); for (var i = start + 1; i < end; ++i) { n.muladd(256, this.get(i)); } return s + n.tostring(); }; stream.prototype.parsebitstring = function (start, end, maxlength) { var unusedbit = this.get(start); var lenbit = ((end - start - 1) << 3) - unusedbit; var intro = "(" + lenbit + " bit)\n"; var s = ""; for (var i = start + 1; i < end; ++i) { var b = this.get(i); var skip = (i == end - 1) ? unusedbit : 0; for (var j = 7; j >= skip; --j) { s += (b >> j) & 1 ? "1" : "0"; } if (s.length > maxlength) { return intro + stringcut(s, maxlength); } } return intro + s; }; stream.prototype.parseoctetstring = function (start, end, maxlength) { if (this.isascii(start, end)) { return stringcut(this.parsestringiso(start, end), maxlength); } var len = end - start; var s = "(" + len + " byte)\n"; maxlength /= 2; // we work in bytes if (len > maxlength) { end = start + maxlength; } for (var i = start; i < end; ++i) { s += this.hexbyte(this.get(i)); } if (len > maxlength) { s += ellipsis; } return s; }; stream.prototype.parseoid = function (start, end, maxlength) { var s = ""; var n = new int10(); var bits = 0; for (var i = start; i < end; ++i) { var v = this.get(i); n.muladd(128, v & 0x7f); bits += 7; if (!(v & 0x80)) { if (s === "") { n = n.simplify(); if (n instanceof int10) { n.sub(80); s = "2." + n.tostring(); } else { var m = n < 80 ? n < 40 ? 0 : 1 : 2; s = m + "." + (n - m * 40); } } else { s += "." + n.tostring(); } if (s.length > maxlength) { return stringcut(s, maxlength); } n = new int10(); bits = 0; } } if (bits > 0) { s += ".incomplete"; } return s; }; return stream; }()); var asn1 = /** @class */ (function () { function asn1(stream, header, length, tag, sub) { if (!(tag instanceof asn1tag)) { throw new error("invalid tag value."); } this.stream = stream; this.header = header; this.length = length; this.tag = tag; this.sub = sub; } asn1.prototype.typename = function () { switch (this.tag.tagclass) { case 0:// universal switch (this.tag.tagnumber) { case 0x00: return "eoc"; case 0x01: return "boolean"; case 0x02: return "integer"; case 0x03: return "bit_string"; case 0x04: return "octet_string"; case 0x05: return "null"; case 0x06: return "object_identifier"; case 0x07: return "objectdescriptor"; case 0x08: return "external"; case 0x09: return "real"; case 0x0a: return "enumerated"; case 0x0b: return "embedded_pdv"; case 0x0c: return "utf8string"; case 0x10: return "sequence"; case 0x11: return "set"; case 0x12: return "numericstring"; case 0x13: return "printablestring"; // ascii subset case 0x14: return "teletexstring"; // aka t61string case 0x15: return "videotexstring"; case 0x16: return "ia5string"; // ascii case 0x17: return "utctime"; case 0x18: return "generalizedtime"; case 0x19: return "graphicstring"; case 0x1a: return "visiblestring"; // ascii subset case 0x1b: return "generalstring"; case 0x1c: return "universalstring"; case 0x1e: return "bmpstring"; } return "universal_" + this.tag.tagnumber.tostring(); case 1: return "application_" + this.tag.tagnumber.tostring(); case 2: return "[" + this.tag.tagnumber.tostring() + "]"; // context case 3: return "private_" + this.tag.tagnumber.tostring(); } }; asn1.prototype.content = function (maxlength) { if (this.tag === undefined) { return null; } if (maxlength === undefined) { maxlength = infinity; } var content = this.poscontent(); var len = math.abs(this.length); if (!this.tag.isuniversal()) { if (this.sub !== null) { return "(" + this.sub.length + " elem)"; } return this.stream.parseoctetstring(content, content + len, maxlength); } switch (this.tag.tagnumber) { case 0x01:// boolean return (this.stream.get(content) === 0) ? "false" : "true"; case 0x02:// integer return this.stream.parseinteger(content, content + len); case 0x03:// bit_string return this.sub ? "(" + this.sub.length + " elem)" : this.stream.parsebitstring(content, content + len, maxlength); case 0x04:// octet_string return this.sub ? "(" + this.sub.length + " elem)" : this.stream.parseoctetstring(content, content + len, maxlength); // case 0x05: // null case 0x06:// object_identifier return this.stream.parseoid(content, content + len, maxlength); // case 0x07: // objectdescriptor // case 0x08: // external // case 0x09: // real // case 0x0a: // enumerated // case 0x0b: // embedded_pdv case 0x10: // sequence case 0x11:// set if (this.sub !== null) { return "(" + this.sub.length + " elem)"; } else { return "(no elem)"; } case 0x0c:// utf8string return stringcut(this.stream.parsestringutf(content, content + len), maxlength); case 0x12: // numericstring case 0x13: // printablestring case 0x14: // teletexstring case 0x15: // videotexstring case 0x16: // ia5string // case 0x19: // graphicstring case 0x1a:// visiblestring // case 0x1b: // generalstring // case 0x1c: // universalstring return stringcut(this.stream.parsestringiso(content, content + len), maxlength); case 0x1e:// bmpstring return stringcut(this.stream.parsestringbmp(content, content + len), maxlength); case 0x17: // utctime case 0x18:// generalizedtime return this.stream.parsetime(content, content + len, (this.tag.tagnumber == 0x17)); } return null; }; asn1.prototype.tostring = function () { return this.typename() + "@" + this.stream.pos + "[header:" + this.header + ",length:" + this.length + ",sub:" + ((this.sub === null) ? "null" : this.sub.length) + "]"; }; asn1.prototype.toprettystring = function (indent) { if (indent === undefined) { indent = ""; } var s = indent + this.typename() + " @" + this.stream.pos; if (this.length >= 0) { s += "+"; } s += this.length; if (this.tag.tagconstructed) { s += " (constructed)"; } else if ((this.tag.isuniversal() && ((this.tag.tagnumber == 0x03) || (this.tag.tagnumber == 0x04))) && (this.sub !== null)) { s += " (encapsulates)"; } s += "\n"; if (this.sub !== null) { indent += " "; for (var i = 0, max = this.sub.length; i < max; ++i) { s += this.sub[i].toprettystring(indent); } } return s; }; asn1.prototype.posstart = function () { return this.stream.pos; }; asn1.prototype.poscontent = function () { return this.stream.pos + this.header; }; asn1.prototype.posend = function () { return this.stream.pos + this.header + math.abs(this.length); }; asn1.prototype.tohexstring = function () { return this.stream.hexdump(this.posstart(), this.posend(), true); }; asn1.decodelength = function (stream) { var buf = stream.get(); var len = buf & 0x7f; if (len == buf) { return len; } // no reason to use int10, as it would be a huge buffer anyways if (len > 6) { throw new error("length over 48 bits not supported at position " + (stream.pos - 1)); } if (len === 0) { return null; } // undefined buf = 0; for (var i = 0; i < len; ++i) { buf = (buf * 256) + stream.get(); } return buf; }; /** * retrieve the hexadecimal value (as a string) of the current asn.1 element * @returns {string} * @public */ asn1.prototype.gethexstringvalue = function () { var hexstring = this.tohexstring(); var offset = this.header * 2; var length = this.length * 2; return hexstring.substr(offset, length); }; asn1.decode = function (str) { var stream; if (!(str instanceof stream)) { stream = new stream(str, 0); } else { stream = str; } var streamstart = new stream(stream); var tag = new asn1tag(stream); var len = asn1.decodelength(stream); var start = stream.pos; var header = start - streamstart.pos; var sub = null; var getsub = function () { var ret = []; if (len !== null) { // definite length var end = start + len; while (stream.pos < end) { ret[ret.length] = asn1.decode(stream); } if (stream.pos != end) { throw new error("content size is not correct for container starting at offset " + start); } } else { // undefined length try { for (;;) { var s = asn1.decode(stream); if (s.tag.iseoc()) { break; } ret[ret.length] = s; } len = start - stream.pos; // undefined lengths are represented as negative values } catch (e) { throw new error("exception while decoding undefined length content: " + e); } } return ret; }; if (tag.tagconstructed) { // must have valid content sub = getsub(); } else if (tag.isuniversal() && ((tag.tagnumber == 0x03) || (tag.tagnumber == 0x04))) { // sometimes bitstring and octetstring are used to encapsulate asn.1 try { if (tag.tagnumber == 0x03) { if (stream.get() != 0) { throw new error("bit strings with unused bits cannot encapsulate."); } } sub = getsub(); for (var i = 0; i < sub.length; ++i) { if (sub[i].tag.iseoc()) { throw new error("eoc is not supposed to be actual content."); } } } catch (e) { // but silently ignore when they don't sub = null; } } if (sub === null) { if (len === null) { throw new error("we can't skip over an invalid tag with undefined length at offset " + start); } stream.pos = start + math.abs(len); } return new asn1(streamstart, header, len, tag, sub); }; return asn1; }()); var asn1tag = /** @class */ (function () { function asn1tag(stream) { var buf = stream.get(); this.tagclass = buf >> 6; this.tagconstructed = ((buf & 0x20) !== 0); this.tagnumber = buf & 0x1f; if (this.tagnumber == 0x1f) { var n = new int10(); do { buf = stream.get(); n.muladd(128, buf & 0x7f); } while (buf & 0x80); this.tagnumber = n.simplify(); } } asn1tag.prototype.isuniversal = function () { return this.tagclass === 0x00; }; asn1tag.prototype.iseoc = function () { return this.tagclass === 0x00 && this.tagnumber === 0x00; }; return asn1tag; }()); // copyright (c) 2005 tom wu // bits per digit var dbits; // javascript engine analysis var canary = 0xdeadbeefcafe; var j_lm = ((canary & 0xffffff) == 0xefcafe); //#region var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]; var lplim = (1 << 26) / lowprimes[lowprimes.length - 1]; //#endregion // (public) constructor var biginteger = /** @class */ (function () { function biginteger(a, b, c) { if (a != null) { if ("number" == typeof a) { this.fromnumber(a, b, c); } else if (b == null && "string" != typeof a) { this.fromstring(a, 256); } else { this.fromstring(a, b); } } } //#region public // biginteger.prototype.tostring = bntostring; // (public) return string representation in given radix biginteger.prototype.tostring = function (b) { if (this.s < 0) { return "-" + this.negate().tostring(b); } var k; if (b == 16) { k = 4; } else if (b == 8) { k = 3; } else if (b == 2) { k = 1; } else if (b == 32) { k = 5; } else if (b == 4) { k = 2; } else { return this.toradix(b); } var km = (1 << k) - 1; var d; var m = false; var r = ""; var i = this.t; var p = this.db - (i * this.db) % k; if (i-- > 0) { if (p < this.db && (d = this[i] >> p) > 0) { m = true; r = int2char(d); } while (i >= 0) { if (p < k) { d = (this[i] & ((1 << p) - 1)) << (k - p); d |= this[--i] >> (p += this.db - k); } else { d = (this[i] >> (p -= k)) & km; if (p <= 0) { p += this.db; --i; } } if (d > 0) { m = true; } if (m) { r += int2char(d); } } } return m ? r : "0"; }; // biginteger.prototype.negate = bnnegate; // (public) -this biginteger.prototype.negate = function () { var r = nbi(); biginteger.zero.subto(this, r); return r; }; // biginteger.prototype.abs = bnabs; // (public) |this| biginteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; }; // biginteger.prototype.compareto = bncompareto; // (public) return + if this > a, - if this < a, 0 if equal biginteger.prototype.compareto = function (a) { var r = this.s - a.s; if (r != 0) { return r; } var i = this.t; r = i - a.t; if (r != 0) { return (this.s < 0) ? -r : r; } while (--i >= 0) { if ((r = this[i] - a[i]) != 0) { return r; } } return 0; }; // biginteger.prototype.bitlength = bnbitlength; // (public) return the number of bits in "this" biginteger.prototype.bitlength = function () { if (this.t <= 0) { return 0; } return this.db * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.dm)); }; // biginteger.prototype.mod = bnmod; // (public) this mod a biginteger.prototype.mod = function (a) { var r = nbi(); this.abs().divremto(a, null, r); if (this.s < 0 && r.compareto(biginteger.zero) > 0) { a.subto(r, r); } return r; }; // biginteger.prototype.modpowint = bnmodpowint; // (public) this^e % m, 0 <= e < 2^32 biginteger.prototype.modpowint = function (e, m) { var z; if (e < 256 || m.iseven()) { z = new classic(m); } else { z = new montgomery(m); } return this.exp(e, z); }; // biginteger.prototype.clone = bnclone; // (public) biginteger.prototype.clone = function () { var r = nbi(); this.copyto(r); return r; }; // biginteger.prototype.intvalue = bnintvalue; // (public) return value as integer biginteger.prototype.intvalue = function () { if (this.s < 0) { if (this.t == 1) { return this[0] - this.dv; } else if (this.t == 0) { return -1; } } else if (this.t == 1) { return this[0]; } else if (this.t == 0) { return 0; } // assumes 16 < db < 32 return ((this[1] & ((1 << (32 - this.db)) - 1)) << this.db) | this[0]; }; // biginteger.prototype.bytevalue = bnbytevalue; // (public) return value as byte biginteger.prototype.bytevalue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; }; // biginteger.prototype.shortvalue = bnshortvalue; // (public) return value as short (assumes db>=16) biginteger.prototype.shortvalue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; }; // biginteger.prototype.signum = bnsignum; // (public) 0 if this == 0, 1 if this > 0 biginteger.prototype.signum = function () { if (this.s < 0) { return -1; } else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) { return 0; } else { return 1; } }; // biginteger.prototype.tobytearray = bntobytearray; // (public) convert to bigendian byte array biginteger.prototype.tobytearray = function () { var i = this.t; var r = []; r[0] = this.s; var p = this.db - (i * this.db) % 8; var d; var k = 0; if (i-- > 0) { if (p < this.db && (d = this[i] >> p) != (this.s & this.dm) >> p) { r[k++] = d | (this.s << (this.db - p)); } while (i >= 0) { if (p < 8) { d = (this[i] & ((1 << p) - 1)) << (8 - p); d |= this[--i] >> (p += this.db - 8); } else { d = (this[i] >> (p -= 8)) & 0xff; if (p <= 0) { p += this.db; --i; } } if ((d & 0x80) != 0) { d |= -256; } if (k == 0 && (this.s & 0x80) != (d & 0x80)) { ++k; } if (k > 0 || d != this.s) { r[k++] = d; } } } return r; }; // biginteger.prototype.equals = bnequals; biginteger.prototype.equals = function (a) { return (this.compareto(a) == 0); }; // biginteger.prototype.min = bnmin; biginteger.prototype.min = function (a) { return (this.compareto(a) < 0) ? this : a; }; // biginteger.prototype.max = bnmax; biginteger.prototype.max = function (a) { return (this.compareto(a) > 0) ? this : a; }; // biginteger.prototype.and = bnand; biginteger.prototype.and = function (a) { var r = nbi(); this.bitwiseto(a, op_and, r); return r; }; // biginteger.prototype.or = bnor; biginteger.prototype.or = function (a) { var r = nbi(); this.bitwiseto(a, op_or, r); return r; }; // biginteger.prototype.xor = bnxor; biginteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseto(a, op_xor, r); return r; }; // biginteger.prototype.andnot = bnandnot; biginteger.prototype.andnot = function (a) { var r = nbi(); this.bitwiseto(a, op_andnot, r); return r; }; // biginteger.prototype.not = bnnot; // (public) ~this biginteger.prototype.not = function () { var r = nbi(); for (var i = 0; i < this.t; ++i) { r[i] = this.dm & ~this[i]; } r.t = this.t; r.s = ~this.s; return r; }; // biginteger.prototype.shiftleft = bnshiftleft; // (public) this << n biginteger.prototype.shiftleft = function (n) { var r = nbi(); if (n < 0) { this.rshiftto(-n, r); } else { this.lshiftto(n, r); } return r; }; // biginteger.prototype.shiftright = bnshiftright; // (public) this >> n biginteger.prototype.shiftright = function (n) { var r = nbi(); if (n < 0) { this.lshiftto(-n, r); } else { this.rshiftto(n, r); } return r; }; // biginteger.prototype.getlowestsetbit = bngetlowestsetbit; // (public) returns index of lowest 1-bit (or -1 if none) biginteger.prototype.getlowestsetbit = function () { for (var i = 0; i < this.t; ++i) { if (this[i] != 0) { return i * this.db + lbit(this[i]); } } if (this.s < 0) { return this.t * this.db; } return -1; }; // biginteger.prototype.bitcount = bnbitcount; // (public) return number of set bits biginteger.prototype.bitcount = function () { var r = 0; var x = this.s & this.dm; for (var i = 0; i < this.t; ++i) { r += cbit(this[i] ^ x); } return r; }; // biginteger.prototype.testbit = bntestbit; // (public) true iff nth bit is set biginteger.prototype.testbit = function (n) { var j = math.floor(n / this.db); if (j >= this.t) { return (this.s != 0); } return ((this[j] & (1 << (n % this.db))) != 0); }; // biginteger.prototype.setbit = bnsetbit; // (public) this | (1< 1) { var g2 = nbi(); z.sqrto(g[1], g2); while (n <= km) { g[n] = nbi(); z.multo(g2, g[n - 2], g[n]); n += 2; } } var j = e.t - 1; var w; var is1 = true; var r2 = nbi(); var t; i = nbits(e[j]) - 1; while (j >= 0) { if (i >= k1) { w = (e[j] >> (i - k1)) & km; } else { w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i); if (j > 0) { w |= e[j - 1] >> (this.db + i - k1); } } n = k; while ((w & 1) == 0) { w >>= 1; --n; } if ((i -= n) < 0) { i += this.db; --j; } if (is1) { g[w].copyto(r); is1 = false; } else { while (n > 1) { z.sqrto(r, r2); z.sqrto(r2, r); n -= 2; } if (n > 0) { z.sqrto(r, r2); } else { t = r; r = r2; r2 = t; } z.multo(r2, g[w], r); } while (j >= 0 && (e[j] & (1 << i)) == 0) { z.sqrto(r, r2); t = r; r = r2; r2 = t; if (--i < 0) { i = this.db - 1; --j; } } } return z.revert(r); }; // biginteger.prototype.modinverse = bnmodinverse; // (public) 1/this % m (hac 14.61) biginteger.prototype.modinverse = function (m) { var ac = m.iseven(); if ((this.iseven() && ac) || m.signum() == 0) { return biginteger.zero; } var u = m.clone(); var v = this.clone(); var a = nbv(1); var b = nbv(0); var c = nbv(0); var d = nbv(1); while (u.signum() != 0) { while (u.iseven()) { u.rshiftto(1, u); if (ac) { if (!a.iseven() || !b.iseven()) { a.addto(this, a); b.subto(m, b); } a.rshiftto(1, a); } else if (!b.iseven()) { b.subto(m, b); } b.rshiftto(1, b); } while (v.iseven()) { v.rshiftto(1, v); if (ac) { if (!c.iseven() || !d.iseven()) { c.addto(this, c); d.subto(m, d); } c.rshiftto(1, c); } else if (!d.iseven()) { d.subto(m, d); } d.rshiftto(1, d); } if (u.compareto(v) >= 0) { u.subto(v, u); if (ac) { a.subto(c, a); } b.subto(d, b); } else { v.subto(u, v); if (ac) { c.subto(a, c); } d.subto(b, d); } } if (v.compareto(biginteger.one) != 0) { return biginteger.zero; } if (d.compareto(m) >= 0) { return d.subtract(m); } if (d.signum() < 0) { d.addto(m, d); } else { return d; } if (d.signum() < 0) { return d.add(m); } else { return d; } }; // biginteger.prototype.pow = bnpow; // (public) this^e biginteger.prototype.pow = function (e) { return this.exp(e, new nullexp()); }; // biginteger.prototype.gcd = bngcd; // (public) gcd(this,a) (hac 14.54) biginteger.prototype.gcd = function (a) { var x = (this.s < 0) ? this.negate() : this.clone(); var y = (a.s < 0) ? a.negate() : a.clone(); if (x.compareto(y) < 0) { var t = x; x = y; y = t; } var i = x.getlowestsetbit(); var g = y.getlowestsetbit(); if (g < 0) { return x; } if (i < g) { g = i; } if (g > 0) { x.rshiftto(g, x); y.rshiftto(g, y); } while (x.signum() > 0) { if ((i = x.getlowestsetbit()) > 0) { x.rshiftto(i, x); } if ((i = y.getlowestsetbit()) > 0) { y.rshiftto(i, y); } if (x.compareto(y) >= 0) { x.subto(y, x); x.rshiftto(1, x); } else { y.subto(x, y); y.rshiftto(1, y); } } if (g > 0) { y.lshiftto(g, y); } return y; }; // biginteger.prototype.isprobableprime = bnisprobableprime; // (public) test primality with certainty >= 1-.5^t biginteger.prototype.isprobableprime = function (t) { var i; var x = this.abs(); if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) { for (i = 0; i < lowprimes.length; ++i) { if (x[0] == lowprimes[i]) { return true; } } return false; } if (x.iseven()) { return false; } i = 1; while (i < lowprimes.length) { var m = lowprimes[i]; var j = i + 1; while (j < lowprimes.length && m < lplim) { m *= lowprimes[j++]; } m = x.modint(m); while (i < j) { if (m % lowprimes[i++] == 0) { return false; } } } return x.millerrabin(t); }; //#endregion public //#region protected // biginteger.prototype.copyto = bnpcopyto; // (protected) copy this to r biginteger.prototype.copyto = function (r) { for (var i = this.t - 1; i >= 0; --i) { r[i] = this[i]; } r.t = this.t; r.s = this.s; }; // biginteger.prototype.fromint = bnpfromint; // (protected) set from integer value x, -dv <= x < dv biginteger.prototype.fromint = function (x) { this.t = 1; this.s = (x < 0) ? -1 : 0; if (x > 0) { this[0] = x; } else if (x < -1) { this[0] = x + this.dv; } else { this.t = 0; } }; // biginteger.prototype.fromstring = bnpfromstring; // (protected) set from string and radix biginteger.prototype.fromstring = function (s, b) { var k; if (b == 16) { k = 4; } else if (b == 8) { k = 3; } else if (b == 256) { k = 8; /* byte array */ } else if (b == 2) { k = 1; } else if (b == 32) { k = 5; } else if (b == 4) { k = 2; } else { this.fromradix(s, b); return; } this.t = 0; this.s = 0; var i = s.length; var mi = false; var sh = 0; while (--i >= 0) { var x = (k == 8) ? (+s[i]) & 0xff : intat(s, i); if (x < 0) { if (s.charat(i) == "-") { mi = true; } continue; } mi = false; if (sh == 0) { this[this.t++] = x; } else if (sh + k > this.db) { this[this.t - 1] |= (x & ((1 << (this.db - sh)) - 1)) << sh; this[this.t++] = (x >> (this.db - sh)); } else { this[this.t - 1] |= x << sh; } sh += k; if (sh >= this.db) { sh -= this.db; } } if (k == 8 && ((+s[0]) & 0x80) != 0) { this.s = -1; if (sh > 0) { this[this.t - 1] |= ((1 << (this.db - sh)) - 1) << sh; } } this.clamp(); if (mi) { biginteger.zero.subto(this, this); } }; // biginteger.prototype.clamp = bnpclamp; // (protected) clamp off excess high words biginteger.prototype.clamp = function () { var c = this.s & this.dm; while (this.t > 0 && this[this.t - 1] == c) { --this.t; } }; // biginteger.prototype.dlshiftto = bnpdlshiftto; // (protected) r = this << n*db biginteger.prototype.dlshiftto = function (n, r) { var i; for (i = this.t - 1; i >= 0; --i) { r[i + n] = this[i]; } for (i = n - 1; i >= 0; --i) { r[i] = 0; } r.t = this.t + n; r.s = this.s; }; // biginteger.prototype.drshiftto = bnpdrshiftto; // (protected) r = this >> n*db biginteger.prototype.drshiftto = function (n, r) { for (var i = n; i < this.t; ++i) { r[i - n] = this[i]; } r.t = math.max(this.t - n, 0); r.s = this.s; }; // biginteger.prototype.lshiftto = bnplshiftto; // (protected) r = this << n biginteger.prototype.lshiftto = function (n, r) { var bs = n % this.db; var cbs = this.db - bs; var bm = (1 << cbs) - 1; var ds = math.floor(n / this.db); var c = (this.s << bs) & this.dm; for (var i = this.t - 1; i >= 0; --i) { r[i + ds + 1] = (this[i] >> cbs) | c; c = (this[i] & bm) << bs; } for (var i = ds - 1; i >= 0; --i) { r[i] = 0; } r[ds] = c; r.t = this.t + ds + 1; r.s = this.s; r.clamp(); }; // biginteger.prototype.rshiftto = bnprshiftto; // (protected) r = this >> n biginteger.prototype.rshiftto = function (n, r) { r.s = this.s; var ds = math.floor(n / this.db); if (ds >= this.t) { r.t = 0; return; } var bs = n % this.db; var cbs = this.db - bs; var bm = (1 << bs) - 1; r[0] = this[ds] >> bs; for (var i = ds + 1; i < this.t; ++i) { r[i - ds - 1] |= (this[i] & bm) << cbs; r[i - ds] = this[i] >> bs; } if (bs > 0) { r[this.t - ds - 1] |= (this.s & bm) << cbs; } r.t = this.t - ds; r.clamp(); }; // biginteger.prototype.subto = bnpsubto; // (protected) r = this - a biginteger.prototype.subto = function (a, r) { var i = 0; var c = 0; var m = math.min(a.t, this.t); while (i < m) { c += this[i] - a[i]; r[i++] = c & this.dm; c >>= this.db; } if (a.t < this.t) { c -= a.s; while (i < this.t) { c += this[i]; r[i++] = c & this.dm; c >>= this.db; } c += this.s; } else { c += this.s; while (i < a.t) { c -= a[i]; r[i++] = c & this.dm; c >>= this.db; } c -= a.s; } r.s = (c < 0) ? -1 : 0; if (c < -1) { r[i++] = this.dv + c; } else if (c > 0) { r[i++] = c; } r.t = i; r.clamp(); }; // biginteger.prototype.multiplyto = bnpmultiplyto; // (protected) r = this * a, r != this,a (hac 14.12) // "this" should be the larger one if appropriate. biginteger.prototype.multiplyto = function (a, r) { var x = this.abs(); var y = a.abs(); var i = x.t; r.t = i + y.t; while (--i >= 0) { r[i] = 0; } for (i = 0; i < y.t; ++i) { r[i + x.t] = x.am(0, y[i], r, i, 0, x.t); } r.s = 0; r.clamp(); if (this.s != a.s) { biginteger.zero.subto(r, r); } }; // biginteger.prototype.squareto = bnpsquareto; // (protected) r = this^2, r != this (hac 14.16) biginteger.prototype.squareto = function (r) { var x = this.abs(); var i = r.t = 2 * x.t; while (--i >= 0) { r[i] = 0; } for (i = 0; i < x.t - 1; ++i) { var c = x.am(i, x[i], r, 2 * i, 0, 1); if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.dv) { r[i + x.t] -= x.dv; r[i + x.t + 1] = 1; } } if (r.t > 0) { r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1); } r.s = 0; r.clamp(); }; // biginteger.prototype.divremto = bnpdivremto; // (protected) divide this by m, quotient and remainder to q, r (hac 14.20) // r != q, this != m. q or r may be null. biginteger.prototype.divremto = function (m, q, r) { var pm = m.abs(); if (pm.t <= 0) { return; } var pt = this.abs(); if (pt.t < pm.t) { if (q != null) { q.fromint(0); } if (r != null) { this.copyto(r); } return; } if (r == null) { r = nbi(); } var y = nbi(); var ts = this.s; var ms = m.s; var nsh = this.db - nbits(pm[pm.t - 1]); // normalize modulus if (nsh > 0) { pm.lshiftto(nsh, y); pt.lshiftto(nsh, r); } else { pm.copyto(y); pt.copyto(r); } var ys = y.t; var y0 = y[ys - 1]; if (y0 == 0) { return; } var yt = y0 * (1 << this.f1) + ((ys > 1) ? y[ys - 2] >> this.f2 : 0); var d1 = this.fv / yt; var d2 = (1 << this.f1) / yt; var e = 1 << this.f2; var i = r.t; var j = i - ys; var t = (q == null) ? nbi() : q; y.dlshiftto(j, t); if (r.compareto(t) >= 0) { r[r.t++] = 1; r.subto(t, r); } biginteger.one.dlshiftto(ys, t); t.subto(y, y); // "negative" y so we can replace sub with am later while (y.t < ys) { y[y.t++] = 0; } while (--j >= 0) { // estimate quotient digit var qd = (r[--i] == y0) ? this.dm : math.floor(r[i] * d1 + (r[i - 1] + e) * d2); if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) { y.dlshiftto(j, t); r.subto(t, r); while (r[i] < --qd) { r.subto(t, r); } } } if (q != null) { r.drshiftto(ys, q); if (ts != ms) { biginteger.zero.subto(q, q); } } r.t = ys; r.clamp(); if (nsh > 0) { r.rshiftto(nsh, r); } // denormalize remainder if (ts < 0) { biginteger.zero.subto(r, r); } }; // biginteger.prototype.invdigit = bnpinvdigit; // (protected) return "-1/this % 2^db"; useful for mont. reduction // justification: // xy == 1 (mod m) // xy = 1+km // xy(2-xy) = (1+km)(1-km) // x[y(2-xy)] = 1-k^2m^2 // x[y(2-xy)] == 1 (mod m^2) // if y is 1/x mod m, then y(2-xy) is 1/x mod m^2 // should reduce x and y(2-xy) by m^2 at each step to keep size bounded. // js multiply "overflows" differently from c/c++, so care is needed here. biginteger.prototype.invdigit = function () { if (this.t < 1) { return 0; } var x = this[0]; if ((x & 1) == 0) { return 0; } var y = x & 3; // y == 1/x mod 2^2 y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4 y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8 y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16 // last step - calculate inverse mod dv directly; // assumes 16 < db <= 32 and assumes ability to handle 48-bit ints y = (y * (2 - x * y % this.dv)) % this.dv; // y == 1/x mod 2^dbits // we really want the negative inverse, and -dv < y < dv return (y > 0) ? this.dv - y : -y; }; // biginteger.prototype.iseven = bnpiseven; // (protected) true iff this is even biginteger.prototype.iseven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; }; // biginteger.prototype.exp = bnpexp; // (protected) this^e, e < 2^32, doing sqr and mul with "r" (hac 14.79) biginteger.prototype.exp = function (e, z) { if (e > 0xffffffff || e < 1) { return biginteger.one; } var r = nbi(); var r2 = nbi(); var g = z.convert(this); var i = nbits(e) - 1; g.copyto(r); while (--i >= 0) { z.sqrto(r, r2); if ((e & (1 << i)) > 0) { z.multo(r2, g, r); } else { var t = r; r = r2; r2 = t; } } return z.revert(r); }; // biginteger.prototype.chunksize = bnpchunksize; // (protected) return x s.t. r^x < dv biginteger.prototype.chunksize = function (r) { return math.floor(math.ln2 * this.db / math.log(r)); }; // biginteger.prototype.toradix = bnptoradix; // (protected) convert to radix string biginteger.prototype.toradix = function (b) { if (b == null) { b = 10; } if (this.signum() == 0 || b < 2 || b > 36) { return "0"; } var cs = this.chunksize(b); var a = math.pow(b, cs); var d = nbv(a); var y = nbi(); var z = nbi(); var r = ""; this.divremto(d, y, z); while (y.signum() > 0) { r = (a + z.intvalue()).tostring(b).substr(1) + r; y.divremto(d, y, z); } return z.intvalue().tostring(b) + r; }; // biginteger.prototype.fromradix = bnpfromradix; // (protected) convert from radix string biginteger.prototype.fromradix = function (s, b) { this.fromint(0); if (b == null) { b = 10; } var cs = this.chunksize(b); var d = math.pow(b, cs); var mi = false; var j = 0; var w = 0; for (var i = 0; i < s.length; ++i) { var x = intat(s, i); if (x < 0) { if (s.charat(i) == "-" && this.signum() == 0) { mi = true; } continue; } w = b * w + x; if (++j >= cs) { this.dmultiply(d); this.daddoffset(w, 0); j = 0; w = 0; } } if (j > 0) { this.dmultiply(math.pow(b, j)); this.daddoffset(w, 0); } if (mi) { biginteger.zero.subto(this, this); } }; // biginteger.prototype.fromnumber = bnpfromnumber; // (protected) alternate constructor biginteger.prototype.fromnumber = function (a, b, c) { if ("number" == typeof b) { // new biginteger(int,int,rng) if (a < 2) { this.fromint(1); } else { this.fromnumber(a, c); if (!this.testbit(a - 1)) { // force msb set this.bitwiseto(biginteger.one.shiftleft(a - 1), op_or, this); } if (this.iseven()) { this.daddoffset(1, 0); } // force odd while (!this.isprobableprime(b)) { this.daddoffset(2, 0); if (this.bitlength() > a) { this.subto(biginteger.one.shiftleft(a - 1), this); } } } } else { // new biginteger(int,rng) var x = []; var t = a & 7; x.length = (a >> 3) + 1; b.nextbytes(x); if (t > 0) { x[0] &= ((1 << t) - 1); } else { x[0] = 0; } this.fromstring(x, 256); } }; // biginteger.prototype.bitwiseto = bnpbitwiseto; // (protected) r = this op a (bitwise) biginteger.prototype.bitwiseto = function (a, op, r) { var i; var f; var m = math.min(a.t, this.t); for (i = 0; i < m; ++i) { r[i] = op(this[i], a[i]); } if (a.t < this.t) { f = a.s & this.dm; for (i = m; i < this.t; ++i) { r[i] = op(this[i], f); } r.t = this.t; } else { f = this.s & this.dm; for (i = m; i < a.t; ++i) { r[i] = op(f, a[i]); } r.t = a.t; } r.s = op(this.s, a.s); r.clamp(); }; // biginteger.prototype.changebit = bnpchangebit; // (protected) this op (1<>= this.db; } if (a.t < this.t) { c += a.s; while (i < this.t) { c += this[i]; r[i++] = c & this.dm; c >>= this.db; } c += this.s; } else { c += this.s; while (i < a.t) { c += a[i]; r[i++] = c & this.dm; c >>= this.db; } c += a.s; } r.s = (c < 0) ? -1 : 0; if (c > 0) { r[i++] = c; } else if (c < -1) { r[i++] = this.dv + c; } r.t = i; r.clamp(); }; // biginteger.prototype.dmultiply = bnpdmultiply; // (protected) this *= n, this >= 0, 1 < n < dv biginteger.prototype.dmultiply = function (n) { this[this.t] = this.am(0, n - 1, this, 0, 0, this.t); ++this.t; this.clamp(); }; // biginteger.prototype.daddoffset = bnpdaddoffset; // (protected) this += n << w words, this >= 0 biginteger.prototype.daddoffset = function (n, w) { if (n == 0) { return; } while (this.t <= w) { this[this.t++] = 0; } this[w] += n; while (this[w] >= this.dv) { this[w] -= this.dv; if (++w >= this.t) { this[this.t++] = 0; } ++this[w]; } }; // biginteger.prototype.multiplylowerto = bnpmultiplylowerto; // (protected) r = lower n words of "this * a", a.t <= n // "this" should be the larger one if appropriate. biginteger.prototype.multiplylowerto = function (a, n, r) { var i = math.min(this.t + a.t, n); r.s = 0; // assumes a,this >= 0 r.t = i; while (i > 0) { r[--i] = 0; } for (var j = r.t - this.t; i < j; ++i) { r[i + this.t] = this.am(0, a[i], r, i, 0, this.t); } for (var j = math.min(a.t, n); i < j; ++i) { this.am(0, a[i], r, i, 0, n - i); } r.clamp(); }; // biginteger.prototype.multiplyupperto = bnpmultiplyupperto; // (protected) r = "this * a" without lower n words, n > 0 // "this" should be the larger one if appropriate. biginteger.prototype.multiplyupperto = function (a, n, r) { --n; var i = r.t = this.t + a.t - n; r.s = 0; // assumes a,this >= 0 while (--i >= 0) { r[i] = 0; } for (i = math.max(n - this.t, 0); i < a.t; ++i) { r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n); } r.clamp(); r.drshiftto(1, r); }; // biginteger.prototype.modint = bnpmodint; // (protected) this % n, n < 2^26 biginteger.prototype.modint = function (n) { if (n <= 0) { return 0; } var d = this.dv % n; var r = (this.s < 0) ? n - 1 : 0; if (this.t > 0) { if (d == 0) { r = this[0] % n; } else { for (var i = this.t - 1; i >= 0; --i) { r = (d * r + this[i]) % n; } } } return r; }; // biginteger.prototype.millerrabin = bnpmillerrabin; // (protected) true if probably prime (hac 4.24, miller-rabin) biginteger.prototype.millerrabin = function (t) { var n1 = this.subtract(biginteger.one); var k = n1.getlowestsetbit(); if (k <= 0) { return false; } var r = n1.shiftright(k); t = (t + 1) >> 1; if (t > lowprimes.length) { t = lowprimes.length; } var a = nbi(); for (var i = 0; i < t; ++i) { // pick bases at random, instead of starting at 2 a.fromint(lowprimes[math.floor(math.random() * lowprimes.length)]); var y = a.modpow(r, this); if (y.compareto(biginteger.one) != 0 && y.compareto(n1) != 0) { var j = 1; while (j++ < k && y.compareto(n1) != 0) { y = y.modpowint(2, this); if (y.compareto(biginteger.one) == 0) { return false; } } if (y.compareto(n1) != 0) { return false; } } } return true; }; // biginteger.prototype.square = bnsquare; // (public) this^2 biginteger.prototype.square = function () { var r = nbi(); this.squareto(r); return r; }; //#region async // public api method biginteger.prototype.gcda = function (a, callback) { var x = (this.s < 0) ? this.negate() : this.clone(); var y = (a.s < 0) ? a.negate() : a.clone(); if (x.compareto(y) < 0) { var t = x; x = y; y = t; } var i = x.getlowestsetbit(); var g = y.getlowestsetbit(); if (g < 0) { callback(x); return; } if (i < g) { g = i; } if (g > 0) { x.rshiftto(g, x); y.rshiftto(g, y); } // workhorse of the algorithm, gets called 200 - 800 times per 512 bit keygen. var gcda1 = function () { if ((i = x.getlowestsetbit()) > 0) { x.rshiftto(i, x); } if ((i = y.getlowestsetbit()) > 0) { y.rshiftto(i, y); } if (x.compareto(y) >= 0) { x.subto(y, x); x.rshiftto(1, x); } else { y.subto(x, y); y.rshiftto(1, y); } if (!(x.signum() > 0)) { if (g > 0) { y.lshiftto(g, y); } settimeout(function () { callback(y); }, 0); // escape } else { settimeout(gcda1, 0); } }; settimeout(gcda1, 10); }; // (protected) alternate constructor biginteger.prototype.fromnumberasync = function (a, b, c, callback) { if ("number" == typeof b) { if (a < 2) { this.fromint(1); } else { this.fromnumber(a, c); if (!this.testbit(a - 1)) { this.bitwiseto(biginteger.one.shiftleft(a - 1), op_or, this); } if (this.iseven()) { this.daddoffset(1, 0); } var bnp_1 = this; var bnpfn1_1 = function () { bnp_1.daddoffset(2, 0); if (bnp_1.bitlength() > a) { bnp_1.subto(biginteger.one.shiftleft(a - 1), bnp_1); } if (bnp_1.isprobableprime(b)) { settimeout(function () { callback(); }, 0); // escape } else { settimeout(bnpfn1_1, 0); } }; settimeout(bnpfn1_1, 0); } } else { var x = []; var t = a & 7; x.length = (a >> 3) + 1; b.nextbytes(x); if (t > 0) { x[0] &= ((1 << t) - 1); } else { x[0] = 0; } this.fromstring(x, 256); } }; return biginteger; }()); //#region reducers //#region nullexp var nullexp = /** @class */ (function () { function nullexp() { } // nullexp.prototype.convert = nnop; nullexp.prototype.convert = function (x) { return x; }; // nullexp.prototype.revert = nnop; nullexp.prototype.revert = function (x) { return x; }; // nullexp.prototype.multo = nmulto; nullexp.prototype.multo = function (x, y, r) { x.multiplyto(y, r); }; // nullexp.prototype.sqrto = nsqrto; nullexp.prototype.sqrto = function (x, r) { x.squareto(r); }; return nullexp; }()); // modular reduction using "classic" algorithm var classic = /** @class */ (function () { function classic(m) { this.m = m; } // classic.prototype.convert = cconvert; classic.prototype.convert = function (x) { if (x.s < 0 || x.compareto(this.m) >= 0) { return x.mod(this.m); } else { return x; } }; // classic.prototype.revert = crevert; classic.prototype.revert = function (x) { return x; }; // classic.prototype.reduce = creduce; classic.prototype.reduce = function (x) { x.divremto(this.m, null, x); }; // classic.prototype.multo = cmulto; classic.prototype.multo = function (x, y, r) { x.multiplyto(y, r); this.reduce(r); }; // classic.prototype.sqrto = csqrto; classic.prototype.sqrto = function (x, r) { x.squareto(r); this.reduce(r); }; return classic; }()); //#endregion //#region montgomery // montgomery reduction var montgomery = /** @class */ (function () { function montgomery(m) { this.m = m; this.mp = m.invdigit(); this.mpl = this.mp & 0x7fff; this.mph = this.mp >> 15; this.um = (1 << (m.db - 15)) - 1; this.mt2 = 2 * m.t; } // montgomery.prototype.convert = montconvert; // xr mod m montgomery.prototype.convert = function (x) { var r = nbi(); x.abs().dlshiftto(this.m.t, r); r.divremto(this.m, null, r); if (x.s < 0 && r.compareto(biginteger.zero) > 0) { this.m.subto(r, r); } return r; }; // montgomery.prototype.revert = montrevert; // x/r mod m montgomery.prototype.revert = function (x) { var r = nbi(); x.copyto(r); this.reduce(r); return r; }; // montgomery.prototype.reduce = montreduce; // x = x/r mod m (hac 14.32) montgomery.prototype.reduce = function (x) { while (x.t <= this.mt2) { // pad x so am has enough room later x[x.t++] = 0; } for (var i = 0; i < this.m.t; ++i) { // faster way of calculating u0 = x[i]*mp mod dv var j = x[i] & 0x7fff; var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.dm; // use am to combine the multiply-shift-add into one call j = i + this.m.t; x[j] += this.m.am(0, u0, x, i, 0, this.m.t); // propagate carry while (x[j] >= x.dv) { x[j] -= x.dv; x[++j]++; } } x.clamp(); x.drshiftto(this.m.t, x); if (x.compareto(this.m) >= 0) { x.subto(this.m, x); } }; // montgomery.prototype.multo = montmulto; // r = "xy/r mod m"; x,y != r montgomery.prototype.multo = function (x, y, r) { x.multiplyto(y, r); this.reduce(r); }; // montgomery.prototype.sqrto = montsqrto; // r = "x^2/r mod m"; x != r montgomery.prototype.sqrto = function (x, r) { x.squareto(r); this.reduce(r); }; return montgomery; }()); //#endregion montgomery //#region barrett // barrett modular reduction var barrett = /** @class */ (function () { function barrett(m) { this.m = m; // setup barrett this.r2 = nbi(); this.q3 = nbi(); biginteger.one.dlshiftto(2 * m.t, this.r2); this.mu = this.r2.divide(m); } // barrett.prototype.convert = barrettconvert; barrett.prototype.convert = function (x) { if (x.s < 0 || x.t > 2 * this.m.t) { return x.mod(this.m); } else if (x.compareto(this.m) < 0) { return x; } else { var r = nbi(); x.copyto(r); this.reduce(r); return r; } }; // barrett.prototype.revert = barrettrevert; barrett.prototype.revert = function (x) { return x; }; // barrett.prototype.reduce = barrettreduce; // x = x mod m (hac 14.42) barrett.prototype.reduce = function (x) { x.drshiftto(this.m.t - 1, this.r2); if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); } this.mu.multiplyupperto(this.r2, this.m.t + 1, this.q3); this.m.multiplylowerto(this.q3, this.m.t + 1, this.r2); while (x.compareto(this.r2) < 0) { x.daddoffset(1, this.m.t + 1); } x.subto(this.r2, x); while (x.compareto(this.m) >= 0) { x.subto(this.m, x); } }; // barrett.prototype.multo = barrettmulto; // r = x*y mod m; x,y != r barrett.prototype.multo = function (x, y, r) { x.multiplyto(y, r); this.reduce(r); }; // barrett.prototype.sqrto = barrettsqrto; // r = x^2 mod m; x != r barrett.prototype.sqrto = function (x, r) { x.squareto(r); this.reduce(r); }; return barrett; }()); //#endregion //#endregion reducers // return new, unset biginteger function nbi() { return new biginteger(null); } function parsebigint(str, r) { return new biginteger(str, r); } // am: compute w_j += (x*this_i), propagate carries, // c is initial carry, returns final carry. // c < 3*dvalue, x < 2*dvalue, this_i < dvalue // we need to select the fastest one that works in this environment. // am1: use a single mult and divide to get the high bits, // max digit bits should be 26 because // max internal value = 2*dvalue^2-2*dvalue (< 2^53) function am1(i, x, w, j, c, n) { while (--n >= 0) { var v = x * this[i++] + w[j] + c; c = math.floor(v / 0x4000000); w[j++] = v & 0x3ffffff; } return c; } // am2 avoids a big mult-and-extract completely. // max digit bits should be <= 30 because we do bitwise ops // on values up to 2*hdvalue^2-hdvalue-1 (< 2^31) function am2(i, x, w, j, c, n) { var xl = x & 0x7fff; var xh = x >> 15; while (--n >= 0) { var l = this[i] & 0x7fff; var h = this[i++] >> 15; var m = xh * l + h * xl; l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff); c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30); w[j++] = l & 0x3fffffff; } return c; } // alternately, set max digit bits to 28 since some // browsers slow down when dealing with 32-bit numbers. function am3(i, x, w, j, c, n) { var xl = x & 0x3fff; var xh = x >> 14; while (--n >= 0) { var l = this[i] & 0x3fff; var h = this[i++] >> 14; var m = xh * l + h * xl; l = xl * l + ((m & 0x3fff) << 14) + w[j] + c; c = (l >> 28) + (m >> 14) + xh * h; w[j++] = l & 0xfffffff; } return c; } if (j_lm && (navigator.appname == "microsoft internet explorer")) { biginteger.prototype.am = am2; dbits = 30; } else if (j_lm && (navigator.appname != "netscape")) { biginteger.prototype.am = am1; dbits = 26; } else { biginteger.prototype.am = am3; dbits = 28; } biginteger.prototype.db = dbits; biginteger.prototype.dm = ((1 << dbits) - 1); biginteger.prototype.dv = (1 << dbits); var bi_fp = 52; biginteger.prototype.fv = math.pow(2, bi_fp); biginteger.prototype.f1 = bi_fp - dbits; biginteger.prototype.f2 = 2 * dbits - bi_fp; // digit conversions var bi_rc = []; var rr; var vv; rr = "0".charcodeat(0); for (vv = 0; vv <= 9; ++vv) { bi_rc[rr++] = vv; } rr = "a".charcodeat(0); for (vv = 10; vv < 36; ++vv) { bi_rc[rr++] = vv; } rr = "a".charcodeat(0); for (vv = 10; vv < 36; ++vv) { bi_rc[rr++] = vv; } function intat(s, i) { var c = bi_rc[s.charcodeat(i)]; return (c == null) ? -1 : c; } // return bigint initialized to value function nbv(i) { var r = nbi(); r.fromint(i); return r; } // returns bit length of the integer x function nbits(x) { var r = 1; var t; if ((t = x >>> 16) != 0) { x = t; r += 16; } if ((t = x >> 8) != 0) { x = t; r += 8; } if ((t = x >> 4) != 0) { x = t; r += 4; } if ((t = x >> 2) != 0) { x = t; r += 2; } if ((t = x >> 1) != 0) { x = t; r += 1; } return r; } // "constants" biginteger.zero = nbv(0); biginteger.one = nbv(1); // prng4.js - uses arcfour as a prng var arcfour = /** @class */ (function () { function arcfour() { this.i = 0; this.j = 0; this.s = []; } // arcfour.prototype.init = arc4init; // initialize arcfour context from key, an array of ints, each from [0..255] arcfour.prototype.init = function (key) { var i; var j; var t; for (i = 0; i < 256; ++i) { this.s[i] = i; } j = 0; for (i = 0; i < 256; ++i) { j = (j + this.s[i] + key[i % key.length]) & 255; t = this.s[i]; this.s[i] = this.s[j]; this.s[j] = t; } this.i = 0; this.j = 0; }; // arcfour.prototype.next = arc4next; arcfour.prototype.next = function () { var t; this.i = (this.i + 1) & 255; this.j = (this.j + this.s[this.i]) & 255; t = this.s[this.i]; this.s[this.i] = this.s[this.j]; this.s[this.j] = t; return this.s[(t + this.s[this.i]) & 255]; }; return arcfour; }()); // plug in your rng constructor here function prng_newstate() { return new arcfour(); } // pool size must be a multiple of 4 and greater than 32. // an array of bytes the size of the pool will be passed to init() var rng_psize = 256; // random number generator - requires a prng backend, e.g. prng4.js var rng_state; var rng_pool = null; var rng_pptr; // initialize the pool with junk if needed. if (rng_pool == null) { rng_pool = []; rng_pptr = 0; var t = void 0; if (window.crypto && window.crypto.getrandomvalues) { // extract entropy (2048 bits) from rng if available var z = new uint32array(256); window.crypto.getrandomvalues(z); for (t = 0; t < z.length; ++t) { rng_pool[rng_pptr++] = z[t] & 255; } } // use mouse events for entropy, if we do not have enough entropy by the time // we need it, entropy will be generated by math.random. var onmousemovelistener_1 = function (ev) { this.count = this.count || 0; if (this.count >= 256 || rng_pptr >= rng_psize) { if (window.removeeventlistener) { window.removeeventlistener("mousemove", onmousemovelistener_1, false); } else if (window.detachevent) { window.detachevent("onmousemove", onmousemovelistener_1); } return; } try { var mousecoordinates = ev.x + ev.y; rng_pool[rng_pptr++] = mousecoordinates & 255; this.count += 1; } catch (e) { // sometimes firefox will deny permission to access event properties for some reason. ignore. } }; if (window.addeventlistener) { window.addeventlistener("mousemove", onmousemovelistener_1, false); } else if (window.attachevent) { window.attachevent("onmousemove", onmousemovelistener_1); } } function rng_get_byte() { if (rng_state == null) { rng_state = prng_newstate(); // at this point, we may not have collected enough entropy. if not, fall back to math.random while (rng_pptr < rng_psize) { var random = math.floor(65536 * math.random()); rng_pool[rng_pptr++] = random & 255; } rng_state.init(rng_pool); for (rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr) { rng_pool[rng_pptr] = 0; } rng_pptr = 0; } // todo: allow reseeding after first request return rng_state.next(); } var securerandom = /** @class */ (function () { function securerandom() { } securerandom.prototype.nextbytes = function (ba) { for (var i = 0; i < ba.length; ++i) { ba[i] = rng_get_byte(); } }; return securerandom; }()); // depends on jsbn.js and rng.js // function linebrk(s,n) { // var ret = ""; // var i = 0; // while(i + n < s.length) { // ret += s.substring(i,i+n) + "\n"; // i += n; // } // return ret + s.substring(i,s.length); // } // function byte2hex(b) { // if(b < 0x10) // return "0" + b.tostring(16); // else // return b.tostring(16); // } // pkcs#1 (type 2, random) pad input string s to n bytes, and return a bigint function pkcs1pad2(s, n) { if (n < s.length + 11) { console.error("message too long for rsa"); return null; } var ba = []; var i = s.length - 1; while (i >= 0 && n > 0) { var c = s.charcodeat(i--); if (c < 128) { ba[--n] = c; } else if ((c > 127) && (c < 2048)) { ba[--n] = (c & 63) | 128; ba[--n] = (c >> 6) | 192; } else { ba[--n] = (c & 63) | 128; ba[--n] = ((c >> 6) & 63) | 128; ba[--n] = (c >> 12) | 224; } } ba[--n] = 0; var rng = new securerandom(); var x = []; while (n > 2) { x[0] = 0; while (x[0] == 0) { rng.nextbytes(x); } ba[--n] = x[0]; } ba[--n] = 2; ba[--n] = 0; return new biginteger(ba); } // "empty" rsa key constructor var rsakey = /** @class */ (function () { function rsakey() { this.n = null; this.e = 0; this.d = null; this.p = null; this.q = null; this.dmp1 = null; this.dmq1 = null; this.coeff = null; } //#region protected // protected // rsakey.prototype.dopublic = rsadopublic; // perform raw public operation on "x": return x^e (mod n) rsakey.prototype.dopublic = function (x) { return x.modpowint(this.e, this.n); }; // rsakey.prototype.doprivate = rsadoprivate; // perform raw private operation on "x": return x^d (mod n) rsakey.prototype.doprivate = function (x) { if (this.p == null || this.q == null) { return x.modpow(this.d, this.n); } // todo: re-calculate any missing crt params var xp = x.mod(this.p).modpow(this.dmp1, this.p); var xq = x.mod(this.q).modpow(this.dmq1, this.q); while (xp.compareto(xq) < 0) { xp = xp.add(this.p); } return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq); }; //#endregion protected //#region public // rsakey.prototype.setpublic = rsasetpublic; // set the public key fields n and e from hex strings rsakey.prototype.setpublic = function (n, e) { if (n != null && e != null && n.length > 0 && e.length > 0) { this.n = parsebigint(n, 16); this.e = parseint(e, 16); } else { console.error("invalid rsa public key"); } }; // rsakey.prototype.encrypt = rsaencrypt; // return the pkcs#1 rsa encryption of "text" as an even-length hex string rsakey.prototype.encrypt = function (text) { var m = pkcs1pad2(text, (this.n.bitlength() + 7) >> 3); if (m == null) { return null; } var c = this.dopublic(m); if (c == null) { return null; } var h = c.tostring(16); if ((h.length & 1) == 0) { return h; } else { return "0" + h; } }; // rsakey.prototype.setprivate = rsasetprivate; // set the private key fields n, e, and d from hex strings rsakey.prototype.setprivate = function (n, e, d) { if (n != null && e != null && n.length > 0 && e.length > 0) { this.n = parsebigint(n, 16); this.e = parseint(e, 16); this.d = parsebigint(d, 16); } else { console.error("invalid rsa private key"); } }; // rsakey.prototype.setprivateex = rsasetprivateex; // set the private key fields n, e, d and crt params from hex strings rsakey.prototype.setprivateex = function (n, e, d, p, q, dp, dq, c) { if (n != null && e != null && n.length > 0 && e.length > 0) { this.n = parsebigint(n, 16); this.e = parseint(e, 16); this.d = parsebigint(d, 16); this.p = parsebigint(p, 16); this.q = parsebigint(q, 16); this.dmp1 = parsebigint(dp, 16); this.dmq1 = parsebigint(dq, 16); this.coeff = parsebigint(c, 16); } else { console.error("invalid rsa private key"); } }; // rsakey.prototype.generate = rsagenerate; // generate a new random private key b bits long, using public expt e rsakey.prototype.generate = function (b, e) { var rng = new securerandom(); var qs = b >> 1; this.e = parseint(e, 16); var ee = new biginteger(e, 16); for (;;) { for (;;) { this.p = new biginteger(b - qs, 1, rng); if (this.p.subtract(biginteger.one).gcd(ee).compareto(biginteger.one) == 0 && this.p.isprobableprime(10)) { break; } } for (;;) { this.q = new biginteger(qs, 1, rng); if (this.q.subtract(biginteger.one).gcd(ee).compareto(biginteger.one) == 0 && this.q.isprobableprime(10)) { break; } } if (this.p.compareto(this.q) <= 0) { var t = this.p; this.p = this.q; this.q = t; } var p1 = this.p.subtract(biginteger.one); var q1 = this.q.subtract(biginteger.one); var phi = p1.multiply(q1); if (phi.gcd(ee).compareto(biginteger.one) == 0) { this.n = this.p.multiply(this.q); this.d = ee.modinverse(phi); this.dmp1 = this.d.mod(p1); this.dmq1 = this.d.mod(q1); this.coeff = this.q.modinverse(this.p); break; } } }; // rsakey.prototype.decrypt = rsadecrypt; // return the pkcs#1 rsa decryption of "ctext". // "ctext" is an even-length hex string and the output is a plain string. rsakey.prototype.decrypt = function (ctext) { var c = parsebigint(ctext, 16); var m = this.doprivate(c); if (m == null) { return null; } return pkcs1unpad2(m, (this.n.bitlength() + 7) >> 3); }; // generate a new random private key b bits long, using public expt e rsakey.prototype.generateasync = function (b, e, callback) { var rng = new securerandom(); var qs = b >> 1; this.e = parseint(e, 16); var ee = new biginteger(e, 16); var rsa = this; // these functions have non-descript names because they were originally for(;;) loops. // i don't know about cryptography to give them better names than loop1-4. var loop1 = function () { var loop4 = function () { if (rsa.p.compareto(rsa.q) <= 0) { var t = rsa.p; rsa.p = rsa.q; rsa.q = t; } var p1 = rsa.p.subtract(biginteger.one); var q1 = rsa.q.subtract(biginteger.one); var phi = p1.multiply(q1); if (phi.gcd(ee).compareto(biginteger.one) == 0) { rsa.n = rsa.p.multiply(rsa.q); rsa.d = ee.modinverse(phi); rsa.dmp1 = rsa.d.mod(p1); rsa.dmq1 = rsa.d.mod(q1); rsa.coeff = rsa.q.modinverse(rsa.p); settimeout(function () { callback(); }, 0); // escape } else { settimeout(loop1, 0); } }; var loop3 = function () { rsa.q = nbi(); rsa.q.fromnumberasync(qs, 1, rng, function () { rsa.q.subtract(biginteger.one).gcda(ee, function (r) { if (r.compareto(biginteger.one) == 0 && rsa.q.isprobableprime(10)) { settimeout(loop4, 0); } else { settimeout(loop3, 0); } }); }); }; var loop2 = function () { rsa.p = nbi(); rsa.p.fromnumberasync(b - qs, 1, rng, function () { rsa.p.subtract(biginteger.one).gcda(ee, function (r) { if (r.compareto(biginteger.one) == 0 && rsa.p.isprobableprime(10)) { settimeout(loop3, 0); } else { settimeout(loop2, 0); } }); }); }; settimeout(loop2, 0); }; settimeout(loop1, 0); }; return rsakey; }()); // undo pkcs#1 (type 2, random) padding and, if valid, return the plaintext function pkcs1unpad2(d, n) { var b = d.tobytearray(); var i = 0; while (i < b.length && b[i] == 0) { ++i; } if (b.length - i != n - 1 || b[i] != 2) { return null; } ++i; while (b[i] != 0) { if (++i >= b.length) { return null; } } var ret = ""; while (++i < b.length) { var c = b[i] & 255; if (c < 128) { ret += string.fromcharcode(c); } else if ((c > 191) && (c < 224)) { ret += string.fromcharcode(((c & 31) << 6) | (b[i + 1] & 63)); ++i; } else { ret += string.fromcharcode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63)); i += 2; } } return ret; } // return the pkcs#1 rsa encryption of "text" as a base64-encoded string // function rsaencryptb64(text) { // var h = this.encrypt(text); // if(h) return hex2b64(h); else return null; // } // public // rsakey.prototype.encrypt_b64 = rsaencryptb64; /*! copyright (c) 2011, yahoo! inc. all rights reserved. code licensed under the bsd license: http://developer.yahoo.com/yui/license.html version: 2.9.0 */ var yahoo = {}; yahoo.lang = { /** * utility to set up the prototype, constructor and superclass properties to * support an inheritance strategy that can chain constructors and methods. * static members will not be inherited. * * @method extend * @static * @param {function} subc the object to modify * @param {function} superc the object to inherit * @param {object} overrides additional properties/methods to add to the * subclass prototype. these will override the * matching items obtained from the superclass * if present. */ extend: function(subc, superc, overrides) { if (! superc || ! subc) { throw new error("yahoo.lang.extend failed, please check that " + "all dependencies are included."); } var f = function() {}; f.prototype = superc.prototype; subc.prototype = new f(); subc.prototype.constructor = subc; subc.superclass = superc.prototype; if (superc.prototype.constructor == object.prototype.constructor) { superc.prototype.constructor = superc; } if (overrides) { var i; for (i in overrides) { subc.prototype[i] = overrides[i]; } /* * ie will not enumerate native functions in a derived object even if the * function was overridden. this is a workaround for specific functions * we care about on the object prototype. * @property _ieenumfix * @param {function} r the object to receive the augmentation * @param {function} s the object that supplies the properties to augment * @static * @private */ var _ieenumfix = function() {}, add = ["tostring", "valueof"]; try { if (/msie/.test(navigator.useragent)) { _ieenumfix = function(r, s) { for (i = 0; i < add.length; i = i + 1) { var fname = add[i], f = s[fname]; if (typeof f === 'function' && f != object.prototype[fname]) { r[fname] = f; } } }; } } catch (ex) {} _ieenumfix(subc.prototype, overrides); } } }; /* asn1-1.0.13.js (c) 2013-2017 kenji urushima | kjur.github.com/jsrsasign/license */ /** * @fileoverview * @name asn1-1.0.js * @author kenji urushima kenji.urushima@gmail.com * @version asn1 1.0.13 (2017-jun-02) * @since jsrsasign 2.1 * @license mit license */ /** * kjur's class library name space *

* this name space provides following name spaces: *

    *
  • {@link kjur.asn1} - asn.1 primitive hexadecimal encoder
  • *
  • {@link kjur.asn1.x509} - asn.1 structure for x.509 certificate and crl
  • *
  • {@link kjur.crypto} - java cryptographic extension(jce) style messagedigest/signature * class and utilities
  • *
*

* note: please ignore method summary and document of this namespace. this caused by a bug of jsdoc2. * @name kjur * @namespace kjur's class library name space */ var kjur = {}; /** * kjur's asn.1 class library name space *

* this is itu-t x.690 asn.1 der encoder class library and * class structure and methods is very similar to * org.bouncycastle.asn1 package of * well known bouncycaslte cryptography library. *

providing asn.1 primitives

* here are asn.1 der primitive classes. *
    *
  • 0x01 {@link kjur.asn1.derboolean}
  • *
  • 0x02 {@link kjur.asn1.derinteger}
  • *
  • 0x03 {@link kjur.asn1.derbitstring}
  • *
  • 0x04 {@link kjur.asn1.deroctetstring}
  • *
  • 0x05 {@link kjur.asn1.dernull}
  • *
  • 0x06 {@link kjur.asn1.derobjectidentifier}
  • *
  • 0x0a {@link kjur.asn1.derenumerated}
  • *
  • 0x0c {@link kjur.asn1.derutf8string}
  • *
  • 0x12 {@link kjur.asn1.dernumericstring}
  • *
  • 0x13 {@link kjur.asn1.derprintablestring}
  • *
  • 0x14 {@link kjur.asn1.derteletexstring}
  • *
  • 0x16 {@link kjur.asn1.deria5string}
  • *
  • 0x17 {@link kjur.asn1.derutctime}
  • *
  • 0x18 {@link kjur.asn1.dergeneralizedtime}
  • *
  • 0x30 {@link kjur.asn1.dersequence}
  • *
  • 0x31 {@link kjur.asn1.derset}
  • *
*

other asn.1 classes

*
    *
  • {@link kjur.asn1.asn1object}
  • *
  • {@link kjur.asn1.derabstractstring}
  • *
  • {@link kjur.asn1.derabstracttime}
  • *
  • {@link kjur.asn1.derabstractstructured}
  • *
  • {@link kjur.asn1.dertaggedobject}
  • *
*

sub name spaces

*
    *
  • {@link kjur.asn1.cades} - cades long term signature format
  • *
  • {@link kjur.asn1.cms} - cryptographic message syntax
  • *
  • {@link kjur.asn1.csr} - certificate signing request (csr/pkcs#10)
  • *
  • {@link kjur.asn1.tsp} - rfc 3161 timestamping protocol format
  • *
  • {@link kjur.asn1.x509} - rfc 5280 x.509 certificate and crl
  • *
*

* note: please ignore method summary and document of this namespace. * this caused by a bug of jsdoc2. * @name kjur.asn1 * @namespace */ if (typeof kjur.asn1 == "undefined" || !kjur.asn1) kjur.asn1 = {}; /** * asn1 utilities class * @name kjur.asn1.asn1util * @class asn1 utilities class * @since asn1 1.0.2 */ kjur.asn1.asn1util = new function() { this.integertobytehex = function(i) { var h = i.tostring(16); if ((h.length % 2) == 1) h = '0' + h; return h; }; this.biginttomintwoscomplementshex = function(bigintegervalue) { var h = bigintegervalue.tostring(16); if (h.substr(0, 1) != '-') { if (h.length % 2 == 1) { h = '0' + h; } else { if (! h.match(/^[0-7]/)) { h = '00' + h; } } } else { var hpos = h.substr(1); var xorlen = hpos.length; if (xorlen % 2 == 1) { xorlen += 1; } else { if (! h.match(/^[0-7]/)) { xorlen += 2; } } var hmask = ''; for (var i = 0; i < xorlen; i++) { hmask += 'f'; } var bimask = new biginteger(hmask, 16); var bineg = bimask.xor(bigintegervalue).add(biginteger.one); h = bineg.tostring(16).replace(/^-/, ''); } return h; }; /** * get pem string from hexadecimal data and header string * @name getpemstringfromhex * @memberof kjur.asn1.asn1util * @function * @param {string} datahex hexadecimal string of pem body * @param {string} pemheader pem header string (ex. 'rsa private key') * @return {string} pem formatted string of input data * @description * this method converts a hexadecimal string to a pem string with * a specified header. its line break will be crlf("\r\n"). * @example * var pem = kjur.asn1.asn1util.getpemstringfromhex('616161', 'rsa private key'); * // value of pem will be: * -----begin private key----- * ywfh * -----end private key----- */ this.getpemstringfromhex = function(datahex, pemheader) { return hextopem(datahex, pemheader); }; /** * generate asn1object specifed by json parameters * @name newobject * @memberof kjur.asn1.asn1util * @function * @param {array} param json parameter to generate asn1object * @return {kjur.asn1.asn1object} generated object * @since asn1 1.0.3 * @description * generate any asn1object specified by json param * including asn.1 primitive or structured. * generally 'param' can be described as follows: *
* {type-of-asnobj: asn1obj-parameter} *
* 'type-of-asn1obj' can be one of following symbols: *
    *
  • 'bool' - derboolean
  • *
  • 'int' - derinteger
  • *
  • 'bitstr' - derbitstring
  • *
  • 'octstr' - deroctetstring
  • *
  • 'null' - dernull
  • *
  • 'oid' - derobjectidentifier
  • *
  • 'enum' - derenumerated
  • *
  • 'utf8str' - derutf8string
  • *
  • 'numstr' - dernumericstring
  • *
  • 'prnstr' - derprintablestring
  • *
  • 'telstr' - derteletexstring
  • *
  • 'ia5str' - deria5string
  • *
  • 'utctime' - derutctime
  • *
  • 'gentime' - dergeneralizedtime
  • *
  • 'seq' - dersequence
  • *
  • 'set' - derset
  • *
  • 'tag' - dertaggedobject
  • *
* @example * newobject({'prnstr': 'aaa'}); * newobject({'seq': [{'int': 3}, {'prnstr': 'aaa'}]}) * // asn.1 tagged object * newobject({'tag': {'tag': 'a1', * 'explicit': true, * 'obj': {'seq': [{'int': 3}, {'prnstr': 'aaa'}]}}}); * // more simple representation of asn.1 tagged object * newobject({'tag': ['a1', * true, * {'seq': [ * {'int': 3}, * {'prnstr': 'aaa'}]} * ]}); */ this.newobject = function(param) { var _kjur = kjur, _kjur_asn1 = _kjur.asn1, _derboolean = _kjur_asn1.derboolean, _derinteger = _kjur_asn1.derinteger, _derbitstring = _kjur_asn1.derbitstring, _deroctetstring = _kjur_asn1.deroctetstring, _dernull = _kjur_asn1.dernull, _derobjectidentifier = _kjur_asn1.derobjectidentifier, _derenumerated = _kjur_asn1.derenumerated, _derutf8string = _kjur_asn1.derutf8string, _dernumericstring = _kjur_asn1.dernumericstring, _derprintablestring = _kjur_asn1.derprintablestring, _derteletexstring = _kjur_asn1.derteletexstring, _deria5string = _kjur_asn1.deria5string, _derutctime = _kjur_asn1.derutctime, _dergeneralizedtime = _kjur_asn1.dergeneralizedtime, _dersequence = _kjur_asn1.dersequence, _derset = _kjur_asn1.derset, _dertaggedobject = _kjur_asn1.dertaggedobject, _newobject = _kjur_asn1.asn1util.newobject; var keys = object.keys(param); if (keys.length != 1) throw "key of param shall be only one."; var key = keys[0]; if (":bool:int:bitstr:octstr:null:oid:enum:utf8str:numstr:prnstr:telstr:ia5str:utctime:gentime:seq:set:tag:".indexof(":" + key + ":") == -1) throw "undefined key: " + key; if (key == "bool") return new _derboolean(param[key]); if (key == "int") return new _derinteger(param[key]); if (key == "bitstr") return new _derbitstring(param[key]); if (key == "octstr") return new _deroctetstring(param[key]); if (key == "null") return new _dernull(param[key]); if (key == "oid") return new _derobjectidentifier(param[key]); if (key == "enum") return new _derenumerated(param[key]); if (key == "utf8str") return new _derutf8string(param[key]); if (key == "numstr") return new _dernumericstring(param[key]); if (key == "prnstr") return new _derprintablestring(param[key]); if (key == "telstr") return new _derteletexstring(param[key]); if (key == "ia5str") return new _deria5string(param[key]); if (key == "utctime") return new _derutctime(param[key]); if (key == "gentime") return new _dergeneralizedtime(param[key]); if (key == "seq") { var paramlist = param[key]; var a = []; for (var i = 0; i < paramlist.length; i++) { var asn1obj = _newobject(paramlist[i]); a.push(asn1obj); } return new _dersequence({'array': a}); } if (key == "set") { var paramlist = param[key]; var a = []; for (var i = 0; i < paramlist.length; i++) { var asn1obj = _newobject(paramlist[i]); a.push(asn1obj); } return new _derset({'array': a}); } if (key == "tag") { var tagparam = param[key]; if (object.prototype.tostring.call(tagparam) === '[object array]' && tagparam.length == 3) { var obj = _newobject(tagparam[2]); return new _dertaggedobject({tag: tagparam[0], explicit: tagparam[1], obj: obj}); } else { var newparam = {}; if (tagparam.explicit !== undefined) newparam.explicit = tagparam.explicit; if (tagparam.tag !== undefined) newparam.tag = tagparam.tag; if (tagparam.obj === undefined) throw "obj shall be specified for 'tag'."; newparam.obj = _newobject(tagparam.obj); return new _dertaggedobject(newparam); } } }; /** * get encoded hexadecimal string of asn1object specifed by json parameters * @name jsontoasn1hex * @memberof kjur.asn1.asn1util * @function * @param {array} param json parameter to generate asn1object * @return hexadecimal string of asn1object * @since asn1 1.0.4 * @description * as for asn.1 object representation of json object, * please see {@link newobject}. * @example * jsontoasn1hex({'prnstr': 'aaa'}); */ this.jsontoasn1hex = function(param) { var asn1obj = this.newobject(param); return asn1obj.getencodedhex(); }; }; /** * get dot noted oid number string from hexadecimal value of oid * @name oidhextoint * @memberof kjur.asn1.asn1util * @function * @param {string} hex hexadecimal value of object identifier * @return {string} dot noted string of object identifier * @since jsrsasign 4.8.3 asn1 1.0.7 * @description * this static method converts from hexadecimal string representation of * asn.1 value of object identifier to oid number string. * @example * kjur.asn1.asn1util.oidhextoint('550406') → "2.5.4.6" */ kjur.asn1.asn1util.oidhextoint = function(hex) { var s = ""; var i01 = parseint(hex.substr(0, 2), 16); var i0 = math.floor(i01 / 40); var i1 = i01 % 40; var s = i0 + "." + i1; var binbuf = ""; for (var i = 2; i < hex.length; i += 2) { var value = parseint(hex.substr(i, 2), 16); var bin = ("00000000" + value.tostring(2)).slice(- 8); binbuf = binbuf + bin.substr(1, 7); if (bin.substr(0, 1) == "0") { var bi = new biginteger(binbuf, 2); s = s + "." + bi.tostring(10); binbuf = ""; } } return s; }; /** * get hexadecimal value of object identifier from dot noted oid value * @name oidinttohex * @memberof kjur.asn1.asn1util * @function * @param {string} oidstring dot noted string of object identifier * @return {string} hexadecimal value of object identifier * @since jsrsasign 4.8.3 asn1 1.0.7 * @description * this static method converts from object identifier value string. * to hexadecimal string representation of it. * @example * kjur.asn1.asn1util.oidinttohex("2.5.4.6") → "550406" */ kjur.asn1.asn1util.oidinttohex = function(oidstring) { var itox = function(i) { var h = i.tostring(16); if (h.length == 1) h = '0' + h; return h; }; var roidtox = function(roid) { var h = ''; var bi = new biginteger(roid, 10); var b = bi.tostring(2); var padlen = 7 - b.length % 7; if (padlen == 7) padlen = 0; var bpad = ''; for (var i = 0; i < padlen; i++) bpad += '0'; b = bpad + b; for (var i = 0; i < b.length - 1; i += 7) { var b8 = b.substr(i, 7); if (i != b.length - 7) b8 = '1' + b8; h += itox(parseint(b8, 2)); } return h; }; if (! oidstring.match(/^[0-9.]+$/)) { throw "malformed oid string: " + oidstring; } var h = ''; var a = oidstring.split('.'); var i0 = parseint(a[0]) * 40 + parseint(a[1]); h += itox(i0); a.splice(0, 2); for (var i = 0; i < a.length; i++) { h += roidtox(a[i]); } return h; }; // ******************************************************************** // abstract asn.1 classes // ******************************************************************** // ******************************************************************** /** * base class for asn.1 der encoder object * @name kjur.asn1.asn1object * @class base class for asn.1 der encoder object * @property {boolean} ismodified flag whether internal data was changed * @property {string} htlv hexadecimal string of asn.1 tlv * @property {string} ht hexadecimal string of asn.1 tlv tag(t) * @property {string} hl hexadecimal string of asn.1 tlv length(l) * @property {string} hv hexadecimal string of asn.1 tlv value(v) * @description */ kjur.asn1.asn1object = function() { var hv = ''; /** * get hexadecimal asn.1 tlv length(l) bytes from tlv value(v) * @name getlengthhexfromvalue * @memberof kjur.asn1.asn1object# * @function * @return {string} hexadecimal string of asn.1 tlv length(l) */ this.getlengthhexfromvalue = function() { if (typeof this.hv == "undefined" || this.hv == null) { throw "this.hv is null or undefined."; } if (this.hv.length % 2 == 1) { throw "value hex must be even length: n=" + hv.length + ",v=" + this.hv; } var n = this.hv.length / 2; var hn = n.tostring(16); if (hn.length % 2 == 1) { hn = "0" + hn; } if (n < 128) { return hn; } else { var hnlen = hn.length / 2; if (hnlen > 15) { throw "asn.1 length too long to represent by 8x: n = " + n.tostring(16); } var head = 128 + hnlen; return head.tostring(16) + hn; } }; /** * get hexadecimal string of asn.1 tlv bytes * @name getencodedhex * @memberof kjur.asn1.asn1object# * @function * @return {string} hexadecimal string of asn.1 tlv */ this.getencodedhex = function() { if (this.htlv == null || this.ismodified) { this.hv = this.getfreshvaluehex(); this.hl = this.getlengthhexfromvalue(); this.htlv = this.ht + this.hl + this.hv; this.ismodified = false; //alert("first time: " + this.htlv); } return this.htlv; }; /** * get hexadecimal string of asn.1 tlv value(v) bytes * @name getvaluehex * @memberof kjur.asn1.asn1object# * @function * @return {string} hexadecimal string of asn.1 tlv value(v) bytes */ this.getvaluehex = function() { this.getencodedhex(); return this.hv; }; this.getfreshvaluehex = function() { return ''; }; }; // == begin derabstractstring ================================================ /** * base class for asn.1 der string classes * @name kjur.asn1.derabstractstring * @class base class for asn.1 der string classes * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @property {string} s internal string of value * @extends kjur.asn1.asn1object * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • str - specify initial asn.1 value(v) by a string
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
* note: 'params' can be omitted. */ kjur.asn1.derabstractstring = function(params) { kjur.asn1.derabstractstring.superclass.constructor.call(this); /** * get string value of this string object * @name getstring * @memberof kjur.asn1.derabstractstring# * @function * @return {string} string value of this string object */ this.getstring = function() { return this.s; }; /** * set value by a string * @name setstring * @memberof kjur.asn1.derabstractstring# * @function * @param {string} news value by a string to set */ this.setstring = function(news) { this.htlv = null; this.ismodified = true; this.s = news; this.hv = stohex(this.s); }; /** * set value by a hexadecimal string * @name setstringhex * @memberof kjur.asn1.derabstractstring# * @function * @param {string} newhexstring value by a hexadecimal string to set */ this.setstringhex = function(newhexstring) { this.htlv = null; this.ismodified = true; this.s = null; this.hv = newhexstring; }; this.getfreshvaluehex = function() { return this.hv; }; if (typeof params != "undefined") { if (typeof params == "string") { this.setstring(params); } else if (typeof params['str'] != "undefined") { this.setstring(params['str']); } else if (typeof params['hex'] != "undefined") { this.setstringhex(params['hex']); } } }; yahoo.lang.extend(kjur.asn1.derabstractstring, kjur.asn1.asn1object); // == end derabstractstring ================================================ // == begin derabstracttime ================================================== /** * base class for asn.1 der generalized/utctime class * @name kjur.asn1.derabstracttime * @class base class for asn.1 der generalized/utctime class * @param {array} params associative array of parameters (ex. {'str': '130430235959z'}) * @extends kjur.asn1.asn1object * @description * @see kjur.asn1.asn1object - superclass */ kjur.asn1.derabstracttime = function(params) { kjur.asn1.derabstracttime.superclass.constructor.call(this); // --- private methods -------------------- this.localdatetoutc = function(d) { utc = d.gettime() + (d.gettimezoneoffset() * 60000); var utcdate = new date(utc); return utcdate; }; /* * format date string by data object * @name formatdate * @memberof kjur.asn1.abstracttime; * @param {date} dateobject * @param {string} type 'utc' or 'gen' * @param {boolean} withmillis flag for with millisections or not * @description * 'withmillis' flag is supported from asn1 1.0.6. */ this.formatdate = function(dateobject, type, withmillis) { var pad = this.zeropadding; var d = this.localdatetoutc(dateobject); var year = string(d.getfullyear()); if (type == 'utc') year = year.substr(2, 2); var month = pad(string(d.getmonth() + 1), 2); var day = pad(string(d.getdate()), 2); var hour = pad(string(d.gethours()), 2); var min = pad(string(d.getminutes()), 2); var sec = pad(string(d.getseconds()), 2); var s = year + month + day + hour + min + sec; if (withmillis === true) { var millis = d.getmilliseconds(); if (millis != 0) { var smillis = pad(string(millis), 3); smillis = smillis.replace(/[0]+$/, ""); s = s + "." + smillis; } } return s + "z"; }; this.zeropadding = function(s, len) { if (s.length >= len) return s; return new array(len - s.length + 1).join('0') + s; }; // --- public methods -------------------- /** * get string value of this string object * @name getstring * @memberof kjur.asn1.derabstracttime# * @function * @return {string} string value of this time object */ this.getstring = function() { return this.s; }; /** * set value by a string * @name setstring * @memberof kjur.asn1.derabstracttime# * @function * @param {string} news value by a string to set such like "130430235959z" */ this.setstring = function(news) { this.htlv = null; this.ismodified = true; this.s = news; this.hv = stohex(news); }; /** * set value by a date object * @name setbydatevalue * @memberof kjur.asn1.derabstracttime# * @function * @param {integer} year year of date (ex. 2013) * @param {integer} month month of date between 1 and 12 (ex. 12) * @param {integer} day day of month * @param {integer} hour hours of date * @param {integer} min minutes of date * @param {integer} sec seconds of date */ this.setbydatevalue = function(year, month, day, hour, min, sec) { var dateobject = new date(date.utc(year, month - 1, day, hour, min, sec, 0)); this.setbydate(dateobject); }; this.getfreshvaluehex = function() { return this.hv; }; }; yahoo.lang.extend(kjur.asn1.derabstracttime, kjur.asn1.asn1object); // == end derabstracttime ================================================== // == begin derabstractstructured ============================================ /** * base class for asn.1 der structured class * @name kjur.asn1.derabstractstructured * @class base class for asn.1 der structured class * @property {array} asn1array internal array of asn1object * @extends kjur.asn1.asn1object * @description * @see kjur.asn1.asn1object - superclass */ kjur.asn1.derabstractstructured = function(params) { kjur.asn1.derabstractstring.superclass.constructor.call(this); /** * set value by array of asn1object * @name setbyasn1objectarray * @memberof kjur.asn1.derabstractstructured# * @function * @param {array} asn1objectarray array of asn1object to set */ this.setbyasn1objectarray = function(asn1objectarray) { this.htlv = null; this.ismodified = true; this.asn1array = asn1objectarray; }; /** * append an asn1object to internal array * @name appendasn1object * @memberof kjur.asn1.derabstractstructured# * @function * @param {asn1object} asn1object to add */ this.appendasn1object = function(asn1object) { this.htlv = null; this.ismodified = true; this.asn1array.push(asn1object); }; this.asn1array = new array(); if (typeof params != "undefined") { if (typeof params['array'] != "undefined") { this.asn1array = params['array']; } } }; yahoo.lang.extend(kjur.asn1.derabstractstructured, kjur.asn1.asn1object); // ******************************************************************** // asn.1 object classes // ******************************************************************** // ******************************************************************** /** * class for asn.1 der boolean * @name kjur.asn1.derboolean * @class class for asn.1 der boolean * @extends kjur.asn1.asn1object * @description * @see kjur.asn1.asn1object - superclass */ kjur.asn1.derboolean = function() { kjur.asn1.derboolean.superclass.constructor.call(this); this.ht = "01"; this.htlv = "0101ff"; }; yahoo.lang.extend(kjur.asn1.derboolean, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der integer * @name kjur.asn1.derinteger * @class class for asn.1 der integer * @extends kjur.asn1.asn1object * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • int - specify initial asn.1 value(v) by integer value
  • *
  • bigint - specify initial asn.1 value(v) by biginteger object
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
* note: 'params' can be omitted. */ kjur.asn1.derinteger = function(params) { kjur.asn1.derinteger.superclass.constructor.call(this); this.ht = "02"; /** * set value by tom wu's biginteger object * @name setbybiginteger * @memberof kjur.asn1.derinteger# * @function * @param {biginteger} bigintegervalue to set */ this.setbybiginteger = function(bigintegervalue) { this.htlv = null; this.ismodified = true; this.hv = kjur.asn1.asn1util.biginttomintwoscomplementshex(bigintegervalue); }; /** * set value by integer value * @name setbyinteger * @memberof kjur.asn1.derinteger * @function * @param {integer} integer value to set */ this.setbyinteger = function(intvalue) { var bi = new biginteger(string(intvalue), 10); this.setbybiginteger(bi); }; /** * set value by integer value * @name setvaluehex * @memberof kjur.asn1.derinteger# * @function * @param {string} hexadecimal string of integer value * @description *
* note: value shall be represented by minimum octet length of * two's complement representation. * @example * new kjur.asn1.derinteger(123); * new kjur.asn1.derinteger({'int': 123}); * new kjur.asn1.derinteger({'hex': '1fad'}); */ this.setvaluehex = function(newhexstring) { this.hv = newhexstring; }; this.getfreshvaluehex = function() { return this.hv; }; if (typeof params != "undefined") { if (typeof params['bigint'] != "undefined") { this.setbybiginteger(params['bigint']); } else if (typeof params['int'] != "undefined") { this.setbyinteger(params['int']); } else if (typeof params == "number") { this.setbyinteger(params); } else if (typeof params['hex'] != "undefined") { this.setvaluehex(params['hex']); } } }; yahoo.lang.extend(kjur.asn1.derinteger, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der encoded bitstring primitive * @name kjur.asn1.derbitstring * @class class for asn.1 der encoded bitstring primitive * @extends kjur.asn1.asn1object * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • bin - specify binary string (ex. '10111')
  • *
  • array - specify array of boolean (ex. [true,false,true,true])
  • *
  • hex - specify hexadecimal string of asn.1 value(v) including unused bits
  • *
  • obj - specify {@link kjur.asn1.asn1util.newobject} * argument for "bitstring encapsulates" structure.
  • *
* note1: 'params' can be omitted.
* note2: 'obj' parameter have been supported since * asn1 1.0.11, jsrsasign 6.1.1 (2016-sep-25).
* @example * // default constructor * o = new kjur.asn1.derbitstring(); * // initialize with binary string * o = new kjur.asn1.derbitstring({bin: "1011"}); * // initialize with boolean array * o = new kjur.asn1.derbitstring({array: [true,false,true,true]}); * // initialize with hexadecimal string (04 is unused bits) * o = new kjur.asn1.deroctetstring({hex: "04bac0"}); * // initialize with asn1util.newobject argument for encapsulated * o = new kjur.asn1.derbitstring({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}}); * // above generates a asn.1 data like this: * // bit string, encapsulates { * // sequence { * // integer 3 * // printablestring 'aaa' * // } * // } */ kjur.asn1.derbitstring = function(params) { if (params !== undefined && typeof params.obj !== "undefined") { var o = kjur.asn1.asn1util.newobject(params.obj); params.hex = "00" + o.getencodedhex(); } kjur.asn1.derbitstring.superclass.constructor.call(this); this.ht = "03"; /** * set asn.1 value(v) by a hexadecimal string including unused bits * @name sethexvalueincludingunusedbits * @memberof kjur.asn1.derbitstring# * @function * @param {string} newhexstringincludingunusedbits */ this.sethexvalueincludingunusedbits = function(newhexstringincludingunusedbits) { this.htlv = null; this.ismodified = true; this.hv = newhexstringincludingunusedbits; }; /** * set asn.1 value(v) by unused bit and hexadecimal string of value * @name setunusedbitsandhexvalue * @memberof kjur.asn1.derbitstring# * @function * @param {integer} unusedbits * @param {string} hvalue */ this.setunusedbitsandhexvalue = function(unusedbits, hvalue) { if (unusedbits < 0 || 7 < unusedbits) { throw "unused bits shall be from 0 to 7: u = " + unusedbits; } var hunusedbits = "0" + unusedbits; this.htlv = null; this.ismodified = true; this.hv = hunusedbits + hvalue; }; /** * set asn.1 der bitstring by binary string
* @name setbybinarystring * @memberof kjur.asn1.derbitstring# * @function * @param {string} binarystring binary value string (i.e. '10111') * @description * its unused bits will be calculated automatically by length of * 'binaryvalue'.
* note: trailing zeros '0' will be ignored. * @example * o = new kjur.asn1.derbitstring(); * o.setbybooleanarray("01011"); */ this.setbybinarystring = function(binarystring) { binarystring = binarystring.replace(/0+$/, ''); var unusedbits = 8 - binarystring.length % 8; if (unusedbits == 8) unusedbits = 0; for (var i = 0; i <= unusedbits; i++) { binarystring += '0'; } var h = ''; for (var i = 0; i < binarystring.length - 1; i += 8) { var b = binarystring.substr(i, 8); var x = parseint(b, 2).tostring(16); if (x.length == 1) x = '0' + x; h += x; } this.htlv = null; this.ismodified = true; this.hv = '0' + unusedbits + h; }; /** * set asn.1 tlv value(v) by an array of boolean
* @name setbybooleanarray * @memberof kjur.asn1.derbitstring# * @function * @param {array} booleanarray array of boolean (ex. [true, false, true]) * @description * note: trailing falses will be ignored in the asn.1 der object. * @example * o = new kjur.asn1.derbitstring(); * o.setbybooleanarray([false, true, false, true, true]); */ this.setbybooleanarray = function(booleanarray) { var s = ''; for (var i = 0; i < booleanarray.length; i++) { if (booleanarray[i] == true) { s += '1'; } else { s += '0'; } } this.setbybinarystring(s); }; /** * generate an array of falses with specified length
* @name newfalsearray * @memberof kjur.asn1.derbitstring * @function * @param {integer} nlength length of array to generate * @return {array} array of boolean falses * @description * this static method may be useful to initialize boolean array. * @example * o = new kjur.asn1.derbitstring(); * o.newfalsearray(3) → [false, false, false] */ this.newfalsearray = function(nlength) { var a = new array(nlength); for (var i = 0; i < nlength; i++) { a[i] = false; } return a; }; this.getfreshvaluehex = function() { return this.hv; }; if (typeof params != "undefined") { if (typeof params == "string" && params.tolowercase().match(/^[0-9a-f]+$/)) { this.sethexvalueincludingunusedbits(params); } else if (typeof params['hex'] != "undefined") { this.sethexvalueincludingunusedbits(params['hex']); } else if (typeof params['bin'] != "undefined") { this.setbybinarystring(params['bin']); } else if (typeof params['array'] != "undefined") { this.setbybooleanarray(params['array']); } } }; yahoo.lang.extend(kjur.asn1.derbitstring, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der octetstring
* @name kjur.asn1.deroctetstring * @class class for asn.1 der octetstring * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * this class provides asn.1 octetstring simple type.
* supported "params" attributes are: *
    *
  • str - to set a string as a value
  • *
  • hex - to set a hexadecimal string as a value
  • *
  • obj - to set a encapsulated asn.1 value by json object * which is defined in {@link kjur.asn1.asn1util.newobject}
  • *
* note: a parameter 'obj' have been supported * for "octet string, encapsulates" structure. * since asn1 1.0.11, jsrsasign 6.1.1 (2016-sep-25). * @see kjur.asn1.derabstractstring - superclass * @example * // default constructor * o = new kjur.asn1.deroctetstring(); * // initialize with string * o = new kjur.asn1.deroctetstring({str: "aaa"}); * // initialize with hexadecimal string * o = new kjur.asn1.deroctetstring({hex: "616161"}); * // initialize with asn1util.newobject argument * o = new kjur.asn1.deroctetstring({obj: {seq: [{int: 3}, {prnstr: 'aaa'}]}}); * // above generates a asn.1 data like this: * // octet string, encapsulates { * // sequence { * // integer 3 * // printablestring 'aaa' * // } * // } */ kjur.asn1.deroctetstring = function(params) { if (params !== undefined && typeof params.obj !== "undefined") { var o = kjur.asn1.asn1util.newobject(params.obj); params.hex = o.getencodedhex(); } kjur.asn1.deroctetstring.superclass.constructor.call(this, params); this.ht = "04"; }; yahoo.lang.extend(kjur.asn1.deroctetstring, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der null * @name kjur.asn1.dernull * @class class for asn.1 der null * @extends kjur.asn1.asn1object * @description * @see kjur.asn1.asn1object - superclass */ kjur.asn1.dernull = function() { kjur.asn1.dernull.superclass.constructor.call(this); this.ht = "05"; this.htlv = "0500"; }; yahoo.lang.extend(kjur.asn1.dernull, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der objectidentifier * @name kjur.asn1.derobjectidentifier * @class class for asn.1 der objectidentifier * @param {array} params associative array of parameters (ex. {'oid': '2.5.4.5'}) * @extends kjur.asn1.asn1object * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • oid - specify initial asn.1 value(v) by a oid string (ex. 2.5.4.13)
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
* note: 'params' can be omitted. */ kjur.asn1.derobjectidentifier = function(params) { var itox = function(i) { var h = i.tostring(16); if (h.length == 1) h = '0' + h; return h; }; var roidtox = function(roid) { var h = ''; var bi = new biginteger(roid, 10); var b = bi.tostring(2); var padlen = 7 - b.length % 7; if (padlen == 7) padlen = 0; var bpad = ''; for (var i = 0; i < padlen; i++) bpad += '0'; b = bpad + b; for (var i = 0; i < b.length - 1; i += 7) { var b8 = b.substr(i, 7); if (i != b.length - 7) b8 = '1' + b8; h += itox(parseint(b8, 2)); } return h; }; kjur.asn1.derobjectidentifier.superclass.constructor.call(this); this.ht = "06"; /** * set value by a hexadecimal string * @name setvaluehex * @memberof kjur.asn1.derobjectidentifier# * @function * @param {string} newhexstring hexadecimal value of oid bytes */ this.setvaluehex = function(newhexstring) { this.htlv = null; this.ismodified = true; this.s = null; this.hv = newhexstring; }; /** * set value by a oid string
* @name setvalueoidstring * @memberof kjur.asn1.derobjectidentifier# * @function * @param {string} oidstring oid string (ex. 2.5.4.13) * @example * o = new kjur.asn1.derobjectidentifier(); * o.setvalueoidstring("2.5.4.13"); */ this.setvalueoidstring = function(oidstring) { if (! oidstring.match(/^[0-9.]+$/)) { throw "malformed oid string: " + oidstring; } var h = ''; var a = oidstring.split('.'); var i0 = parseint(a[0]) * 40 + parseint(a[1]); h += itox(i0); a.splice(0, 2); for (var i = 0; i < a.length; i++) { h += roidtox(a[i]); } this.htlv = null; this.ismodified = true; this.s = null; this.hv = h; }; /** * set value by a oid name * @name setvaluename * @memberof kjur.asn1.derobjectidentifier# * @function * @param {string} oidname oid name (ex. 'serverauth') * @since 1.0.1 * @description * oid name shall be defined in 'kjur.asn1.x509.oid.name2oidlist'. * otherwise raise error. * @example * o = new kjur.asn1.derobjectidentifier(); * o.setvaluename("serverauth"); */ this.setvaluename = function(oidname) { var oid = kjur.asn1.x509.oid.name2oid(oidname); if (oid !== '') { this.setvalueoidstring(oid); } else { throw "derobjectidentifier oidname undefined: " + oidname; } }; this.getfreshvaluehex = function() { return this.hv; }; if (params !== undefined) { if (typeof params === "string") { if (params.match(/^[0-2].[0-9.]+$/)) { this.setvalueoidstring(params); } else { this.setvaluename(params); } } else if (params.oid !== undefined) { this.setvalueoidstring(params.oid); } else if (params.hex !== undefined) { this.setvaluehex(params.hex); } else if (params.name !== undefined) { this.setvaluename(params.name); } } }; yahoo.lang.extend(kjur.asn1.derobjectidentifier, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der enumerated * @name kjur.asn1.derenumerated * @class class for asn.1 der enumerated * @extends kjur.asn1.asn1object * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • int - specify initial asn.1 value(v) by integer value
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
* note: 'params' can be omitted. * @example * new kjur.asn1.derenumerated(123); * new kjur.asn1.derenumerated({int: 123}); * new kjur.asn1.derenumerated({hex: '1fad'}); */ kjur.asn1.derenumerated = function(params) { kjur.asn1.derenumerated.superclass.constructor.call(this); this.ht = "0a"; /** * set value by tom wu's biginteger object * @name setbybiginteger * @memberof kjur.asn1.derenumerated# * @function * @param {biginteger} bigintegervalue to set */ this.setbybiginteger = function(bigintegervalue) { this.htlv = null; this.ismodified = true; this.hv = kjur.asn1.asn1util.biginttomintwoscomplementshex(bigintegervalue); }; /** * set value by integer value * @name setbyinteger * @memberof kjur.asn1.derenumerated# * @function * @param {integer} integer value to set */ this.setbyinteger = function(intvalue) { var bi = new biginteger(string(intvalue), 10); this.setbybiginteger(bi); }; /** * set value by integer value * @name setvaluehex * @memberof kjur.asn1.derenumerated# * @function * @param {string} hexadecimal string of integer value * @description *
* note: value shall be represented by minimum octet length of * two's complement representation. */ this.setvaluehex = function(newhexstring) { this.hv = newhexstring; }; this.getfreshvaluehex = function() { return this.hv; }; if (typeof params != "undefined") { if (typeof params['int'] != "undefined") { this.setbyinteger(params['int']); } else if (typeof params == "number") { this.setbyinteger(params); } else if (typeof params['hex'] != "undefined") { this.setvaluehex(params['hex']); } } }; yahoo.lang.extend(kjur.asn1.derenumerated, kjur.asn1.asn1object); // ******************************************************************** /** * class for asn.1 der utf8string * @name kjur.asn1.derutf8string * @class class for asn.1 der utf8string * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * @see kjur.asn1.derabstractstring - superclass */ kjur.asn1.derutf8string = function(params) { kjur.asn1.derutf8string.superclass.constructor.call(this, params); this.ht = "0c"; }; yahoo.lang.extend(kjur.asn1.derutf8string, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der numericstring * @name kjur.asn1.dernumericstring * @class class for asn.1 der numericstring * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * @see kjur.asn1.derabstractstring - superclass */ kjur.asn1.dernumericstring = function(params) { kjur.asn1.dernumericstring.superclass.constructor.call(this, params); this.ht = "12"; }; yahoo.lang.extend(kjur.asn1.dernumericstring, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der printablestring * @name kjur.asn1.derprintablestring * @class class for asn.1 der printablestring * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * @see kjur.asn1.derabstractstring - superclass */ kjur.asn1.derprintablestring = function(params) { kjur.asn1.derprintablestring.superclass.constructor.call(this, params); this.ht = "13"; }; yahoo.lang.extend(kjur.asn1.derprintablestring, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der teletexstring * @name kjur.asn1.derteletexstring * @class class for asn.1 der teletexstring * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * @see kjur.asn1.derabstractstring - superclass */ kjur.asn1.derteletexstring = function(params) { kjur.asn1.derteletexstring.superclass.constructor.call(this, params); this.ht = "14"; }; yahoo.lang.extend(kjur.asn1.derteletexstring, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der ia5string * @name kjur.asn1.deria5string * @class class for asn.1 der ia5string * @param {array} params associative array of parameters (ex. {'str': 'aaa'}) * @extends kjur.asn1.derabstractstring * @description * @see kjur.asn1.derabstractstring - superclass */ kjur.asn1.deria5string = function(params) { kjur.asn1.deria5string.superclass.constructor.call(this, params); this.ht = "16"; }; yahoo.lang.extend(kjur.asn1.deria5string, kjur.asn1.derabstractstring); // ******************************************************************** /** * class for asn.1 der utctime * @name kjur.asn1.derutctime * @class class for asn.1 der utctime * @param {array} params associative array of parameters (ex. {'str': '130430235959z'}) * @extends kjur.asn1.derabstracttime * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • str - specify initial asn.1 value(v) by a string (ex.'130430235959z')
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
  • date - specify date object.
  • *
* note: 'params' can be omitted. *

examples

* @example * d1 = new kjur.asn1.derutctime(); * d1.setstring('130430125959z'); * * d2 = new kjur.asn1.derutctime({'str': '130430125959z'}); * d3 = new kjur.asn1.derutctime({'date': new date(date.utc(2015, 0, 31, 0, 0, 0, 0))}); * d4 = new kjur.asn1.derutctime('130430125959z'); */ kjur.asn1.derutctime = function(params) { kjur.asn1.derutctime.superclass.constructor.call(this, params); this.ht = "17"; /** * set value by a date object
* @name setbydate * @memberof kjur.asn1.derutctime# * @function * @param {date} dateobject date object to set asn.1 value(v) * @example * o = new kjur.asn1.derutctime(); * o.setbydate(new date("2016/12/31")); */ this.setbydate = function(dateobject) { this.htlv = null; this.ismodified = true; this.date = dateobject; this.s = this.formatdate(this.date, 'utc'); this.hv = stohex(this.s); }; this.getfreshvaluehex = function() { if (typeof this.date == "undefined" && typeof this.s == "undefined") { this.date = new date(); this.s = this.formatdate(this.date, 'utc'); this.hv = stohex(this.s); } return this.hv; }; if (params !== undefined) { if (params.str !== undefined) { this.setstring(params.str); } else if (typeof params == "string" && params.match(/^[0-9]{12}z$/)) { this.setstring(params); } else if (params.hex !== undefined) { this.setstringhex(params.hex); } else if (params.date !== undefined) { this.setbydate(params.date); } } }; yahoo.lang.extend(kjur.asn1.derutctime, kjur.asn1.derabstracttime); // ******************************************************************** /** * class for asn.1 der generalizedtime * @name kjur.asn1.dergeneralizedtime * @class class for asn.1 der generalizedtime * @param {array} params associative array of parameters (ex. {'str': '20130430235959z'}) * @property {boolean} withmillis flag to show milliseconds or not * @extends kjur.asn1.derabstracttime * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • str - specify initial asn.1 value(v) by a string (ex.'20130430235959z')
  • *
  • hex - specify initial asn.1 value(v) by a hexadecimal string
  • *
  • date - specify date object.
  • *
  • millis - specify flag to show milliseconds (from 1.0.6)
  • *
* note1: 'params' can be omitted. * note2: 'withmillis' property is supported from asn1 1.0.6. */ kjur.asn1.dergeneralizedtime = function(params) { kjur.asn1.dergeneralizedtime.superclass.constructor.call(this, params); this.ht = "18"; this.withmillis = false; /** * set value by a date object * @name setbydate * @memberof kjur.asn1.dergeneralizedtime# * @function * @param {date} dateobject date object to set asn.1 value(v) * @example * when you specify utc time, use 'date.utc' method like this:
* o1 = new derutctime(); * o1.setbydate(date); * * date = new date(date.utc(2015, 0, 31, 23, 59, 59, 0)); #2015jan31 23:59:59 */ this.setbydate = function(dateobject) { this.htlv = null; this.ismodified = true; this.date = dateobject; this.s = this.formatdate(this.date, 'gen', this.withmillis); this.hv = stohex(this.s); }; this.getfreshvaluehex = function() { if (this.date === undefined && this.s === undefined) { this.date = new date(); this.s = this.formatdate(this.date, 'gen', this.withmillis); this.hv = stohex(this.s); } return this.hv; }; if (params !== undefined) { if (params.str !== undefined) { this.setstring(params.str); } else if (typeof params == "string" && params.match(/^[0-9]{14}z$/)) { this.setstring(params); } else if (params.hex !== undefined) { this.setstringhex(params.hex); } else if (params.date !== undefined) { this.setbydate(params.date); } if (params.millis === true) { this.withmillis = true; } } }; yahoo.lang.extend(kjur.asn1.dergeneralizedtime, kjur.asn1.derabstracttime); // ******************************************************************** /** * class for asn.1 der sequence * @name kjur.asn1.dersequence * @class class for asn.1 der sequence * @extends kjur.asn1.derabstractstructured * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • array - specify array of asn1object to set elements of content
  • *
* note: 'params' can be omitted. */ kjur.asn1.dersequence = function(params) { kjur.asn1.dersequence.superclass.constructor.call(this, params); this.ht = "30"; this.getfreshvaluehex = function() { var h = ''; for (var i = 0; i < this.asn1array.length; i++) { var asn1obj = this.asn1array[i]; h += asn1obj.getencodedhex(); } this.hv = h; return this.hv; }; }; yahoo.lang.extend(kjur.asn1.dersequence, kjur.asn1.derabstractstructured); // ******************************************************************** /** * class for asn.1 der set * @name kjur.asn1.derset * @class class for asn.1 der set * @extends kjur.asn1.derabstractstructured * @description *
* as for argument 'params' for constructor, you can specify one of * following properties: *
    *
  • array - specify array of asn1object to set elements of content
  • *
  • sortflag - flag for sort (default: true). asn.1 ber is not sorted in 'set of'.
  • *
* note1: 'params' can be omitted.
* note2: sortflag is supported since 1.0.5. */ kjur.asn1.derset = function(params) { kjur.asn1.derset.superclass.constructor.call(this, params); this.ht = "31"; this.sortflag = true; // item shall be sorted only in asn.1 der this.getfreshvaluehex = function() { var a = new array(); for (var i = 0; i < this.asn1array.length; i++) { var asn1obj = this.asn1array[i]; a.push(asn1obj.getencodedhex()); } if (this.sortflag == true) a.sort(); this.hv = a.join(''); return this.hv; }; if (typeof params != "undefined") { if (typeof params.sortflag != "undefined" && params.sortflag == false) this.sortflag = false; } }; yahoo.lang.extend(kjur.asn1.derset, kjur.asn1.derabstractstructured); // ******************************************************************** /** * class for asn.1 der taggedobject * @name kjur.asn1.dertaggedobject * @class class for asn.1 der taggedobject * @extends kjur.asn1.asn1object * @description *
* parameter 'tagnonex' is asn.1 tag(t) value for this object. * for example, if you find '[1]' tag in a asn.1 dump, * 'tagnohex' will be 'a1'. *
* as for optional argument 'params' for constructor, you can specify *any* of * following properties: *
    *
  • explicit - specify true if this is explicit tag otherwise false * (default is 'true').
  • *
  • tag - specify tag (default is 'a0' which means [0])
  • *
  • obj - specify asn1object which is tagged
  • *
* @example * d1 = new kjur.asn1.derutf8string({'str':'a'}); * d2 = new kjur.asn1.dertaggedobject({'obj': d1}); * hex = d2.getencodedhex(); */ kjur.asn1.dertaggedobject = function(params) { kjur.asn1.dertaggedobject.superclass.constructor.call(this); this.ht = "a0"; this.hv = ''; this.isexplicit = true; this.asn1object = null; /** * set value by an asn1object * @name setstring * @memberof kjur.asn1.dertaggedobject# * @function * @param {boolean} isexplicitflag flag for explicit/implicit tag * @param {integer} tagnohex hexadecimal string of asn.1 tag * @param {asn1object} asn1object asn.1 to encapsulate */ this.setasn1object = function(isexplicitflag, tagnohex, asn1object) { this.ht = tagnohex; this.isexplicit = isexplicitflag; this.asn1object = asn1object; if (this.isexplicit) { this.hv = this.asn1object.getencodedhex(); this.htlv = null; this.ismodified = true; } else { this.hv = null; this.htlv = asn1object.getencodedhex(); this.htlv = this.htlv.replace(/^../, tagnohex); this.ismodified = false; } }; this.getfreshvaluehex = function() { return this.hv; }; if (typeof params != "undefined") { if (typeof params['tag'] != "undefined") { this.ht = params['tag']; } if (typeof params['explicit'] != "undefined") { this.isexplicit = params['explicit']; } if (typeof params['obj'] != "undefined") { this.asn1object = params['obj']; this.setasn1object(this.isexplicit, this.ht, this.asn1object); } } }; yahoo.lang.extend(kjur.asn1.dertaggedobject, kjur.asn1.asn1object); /** * create a new jsencryptrsakey that extends tom wu's rsa key object. * this object is just a decorator for parsing the key parameter * @param {string|object} key - the key in string format, or an object containing * the parameters needed to build a rsakey object. * @constructor */ var jsencryptrsakey = /** @class */ (function (_super) { __extends(jsencryptrsakey, _super); function jsencryptrsakey(key) { var _this = _super.call(this) || this; // call the super constructor. // rsakey.call(this); // if a key key was provided. if (key) { // if this is a string... if (typeof key === "string") { _this.parsekey(key); } else if (jsencryptrsakey.hasprivatekeyproperty(key) || jsencryptrsakey.haspublickeyproperty(key)) { // set the values for the key. _this.parsepropertiesfrom(key); } } return _this; } /** * method to parse a pem encoded string containing both a public or private key. * the method will translate the pem encoded string in a der encoded string and * will parse private key and public key parameters. this method accepts public key * in the rsaencryption pkcs #1 format (oid: 1.2.840.113549.1.1.1). * * @todo check how many rsa formats use the same format of pkcs #1. * * the format is defined as: * publickeyinfo ::= sequence { * algorithm algorithmidentifier, * publickey bit string * } * where algorithmidentifier is: * algorithmidentifier ::= sequence { * algorithm object identifier, the oid of the enc algorithm * parameters any defined by algorithm optional (null for pkcs #1) * } * and publickey is a sequence encapsulated in a bit string * rsapublickey ::= sequence { * modulus integer, -- n * publicexponent integer -- e * } * it's possible to examine the structure of the keys obtained from openssl using * an asn.1 dumper as the one used here to parse the components: http://lapo.it/asn1js/ * @argument {string} pem the pem encoded string, can include the begin/end header/footer * @private */ jsencryptrsakey.prototype.parsekey = function (pem) { try { var modulus = 0; var public_exponent = 0; var rehex = /^\s*(?:[0-9a-fa-f][0-9a-fa-f]\s*)+$/; var der = rehex.test(pem) ? hex.decode(pem) : base64.unarmor(pem); var asn1 = asn1.decode(der); // fixes a bug with openssl 1.0+ private keys if (asn1.sub.length === 3) { asn1 = asn1.sub[2].sub[0]; } if (asn1.sub.length === 9) { // parse the private key. modulus = asn1.sub[1].gethexstringvalue(); // bigint this.n = parsebigint(modulus, 16); public_exponent = asn1.sub[2].gethexstringvalue(); // int this.e = parseint(public_exponent, 16); var private_exponent = asn1.sub[3].gethexstringvalue(); // bigint this.d = parsebigint(private_exponent, 16); var prime1 = asn1.sub[4].gethexstringvalue(); // bigint this.p = parsebigint(prime1, 16); var prime2 = asn1.sub[5].gethexstringvalue(); // bigint this.q = parsebigint(prime2, 16); var exponent1 = asn1.sub[6].gethexstringvalue(); // bigint this.dmp1 = parsebigint(exponent1, 16); var exponent2 = asn1.sub[7].gethexstringvalue(); // bigint this.dmq1 = parsebigint(exponent2, 16); var coefficient = asn1.sub[8].gethexstringvalue(); // bigint this.coeff = parsebigint(coefficient, 16); } else if (asn1.sub.length === 2) { // parse the public key. var bit_string = asn1.sub[1]; var sequence = bit_string.sub[0]; modulus = sequence.sub[0].gethexstringvalue(); this.n = parsebigint(modulus, 16); public_exponent = sequence.sub[1].gethexstringvalue(); this.e = parseint(public_exponent, 16); } else { return false; } return true; } catch (ex) { return false; } }; /** * translate rsa parameters in a hex encoded string representing the rsa key. * * the translation follow the asn.1 notation : * rsaprivatekey ::= sequence { * version version, * modulus integer, -- n * publicexponent integer, -- e * privateexponent integer, -- d * prime1 integer, -- p * prime2 integer, -- q * exponent1 integer, -- d mod (p1) * exponent2 integer, -- d mod (q-1) * coefficient integer, -- (inverse of q) mod p * } * @returns {string} der encoded string representing the rsa private key * @private */ jsencryptrsakey.prototype.getprivatebasekey = function () { var options = { array: [ new kjur.asn1.derinteger({ int: 0 }), new kjur.asn1.derinteger({ bigint: this.n }), new kjur.asn1.derinteger({ int: this.e }), new kjur.asn1.derinteger({ bigint: this.d }), new kjur.asn1.derinteger({ bigint: this.p }), new kjur.asn1.derinteger({ bigint: this.q }), new kjur.asn1.derinteger({ bigint: this.dmp1 }), new kjur.asn1.derinteger({ bigint: this.dmq1 }), new kjur.asn1.derinteger({ bigint: this.coeff }) ] }; var seq = new kjur.asn1.dersequence(options); return seq.getencodedhex(); }; /** * base64 (pem) encoded version of the der encoded representation * @returns {string} pem encoded representation without header and footer * @public */ jsencryptrsakey.prototype.getprivatebasekeyb64 = function () { return hex2b64(this.getprivatebasekey()); }; /** * translate rsa parameters in a hex encoded string representing the rsa public key. * the representation follow the asn.1 notation : * publickeyinfo ::= sequence { * algorithm algorithmidentifier, * publickey bit string * } * where algorithmidentifier is: * algorithmidentifier ::= sequence { * algorithm object identifier, the oid of the enc algorithm * parameters any defined by algorithm optional (null for pkcs #1) * } * and publickey is a sequence encapsulated in a bit string * rsapublickey ::= sequence { * modulus integer, -- n * publicexponent integer -- e * } * @returns {string} der encoded string representing the rsa public key * @private */ jsencryptrsakey.prototype.getpublicbasekey = function () { var first_sequence = new kjur.asn1.dersequence({ array: [ new kjur.asn1.derobjectidentifier({ oid: "1.2.840.113549.1.1.1" }), new kjur.asn1.dernull() ] }); var second_sequence = new kjur.asn1.dersequence({ array: [ new kjur.asn1.derinteger({ bigint: this.n }), new kjur.asn1.derinteger({ int: this.e }) ] }); var bit_string = new kjur.asn1.derbitstring({ hex: "00" + second_sequence.getencodedhex() }); var seq = new kjur.asn1.dersequence({ array: [ first_sequence, bit_string ] }); return seq.getencodedhex(); }; /** * base64 (pem) encoded version of the der encoded representation * @returns {string} pem encoded representation without header and footer * @public */ jsencryptrsakey.prototype.getpublicbasekeyb64 = function () { return hex2b64(this.getpublicbasekey()); }; /** * wrap the string in block of width chars. the default value for rsa keys is 64 * characters. * @param {string} str the pem encoded string without header and footer * @param {number} [width=64] - the length the string has to be wrapped at * @returns {string} * @private */ jsencryptrsakey.wordwrap = function (str, width) { width = width || 64; if (!str) { return str; } var regex = "(.{1," + width + "})( +|$\n?)|(.{1," + width + "})"; return str.match(regexp(regex, "g")).join("\n"); }; /** * retrieve the pem encoded private key * @returns {string} the pem encoded private key with header/footer * @public */ jsencryptrsakey.prototype.getprivatekey = function () { var key = "-----begin rsa private key-----\n"; key += jsencryptrsakey.wordwrap(this.getprivatebasekeyb64()) + "\n"; key += "-----end rsa private key-----"; return key; }; /** * retrieve the pem encoded public key * @returns {string} the pem encoded public key with header/footer * @public */ jsencryptrsakey.prototype.getpublickey = function () { var key = "-----begin public key-----\n"; key += jsencryptrsakey.wordwrap(this.getpublicbasekeyb64()) + "\n"; key += "-----end public key-----"; return key; }; /** * check if the object contains the necessary parameters to populate the rsa modulus * and public exponent parameters. * @param {object} [obj={}] - an object that may contain the two public key * parameters * @returns {boolean} true if the object contains both the modulus and the public exponent * properties (n and e) * @todo check for types of n and e. n should be a parseable bigint object, e should * be a parseable integer number * @private */ jsencryptrsakey.haspublickeyproperty = function (obj) { obj = obj || {}; return (obj.hasownproperty("n") && obj.hasownproperty("e")); }; /** * check if the object contains all the parameters of an rsa key. * @param {object} [obj={}] - an object that may contain nine rsa key * parameters * @returns {boolean} true if the object contains all the parameters needed * @todo check for types of the parameters all the parameters but the public exponent * should be parseable bigint objects, the public exponent should be a parseable integer number * @private */ jsencryptrsakey.hasprivatekeyproperty = function (obj) { obj = obj || {}; return (obj.hasownproperty("n") && obj.hasownproperty("e") && obj.hasownproperty("d") && obj.hasownproperty("p") && obj.hasownproperty("q") && obj.hasownproperty("dmp1") && obj.hasownproperty("dmq1") && obj.hasownproperty("coeff")); }; /** * parse the properties of obj in the current rsa object. obj should at least * include the modulus and public exponent (n, e) parameters. * @param {object} obj - the object containing rsa parameters * @private */ jsencryptrsakey.prototype.parsepropertiesfrom = function (obj) { this.n = obj.n; this.e = obj.e; if (obj.hasownproperty("d")) { this.d = obj.d; this.p = obj.p; this.q = obj.q; this.dmp1 = obj.dmp1; this.dmq1 = obj.dmq1; this.coeff = obj.coeff; } }; return jsencryptrsakey; }(rsakey)); /** * * @param {object} [options = {}] - an object to customize jsencrypt behaviour * possible parameters are: * - default_key_size {number} default: 1024 the key size in bit * - default_public_exponent {string} default: '010001' the hexadecimal representation of the public exponent * - log {boolean} default: false whether log warn/error or not * @constructor */ var jsencrypt = /** @class */ (function () { function jsencrypt(options) { options = options || {}; this.default_key_size = parseint(options.default_key_size, 10) || 1024; this.default_public_exponent = options.default_public_exponent || "010001"; // 65537 default openssl public exponent for rsa key type this.log = options.log || false; // the private and public key. this.key = null; } /** * method to set the rsa key parameter (one method is enough to set both the public * and the private key, since the private key contains the public key paramenters) * log a warning if logs are enabled * @param {object|string} key the pem encoded string or an object (with or without header/footer) * @public */ jsencrypt.prototype.setkey = function (key) { if (this.log && this.key) { console.warn("a key was already set, overriding existing."); } this.key = new jsencryptrsakey(key); }; /** * proxy method for setkey, for api compatibility * @see setkey * @public */ jsencrypt.prototype.setprivatekey = function (privkey) { // create the key. this.setkey(privkey); }; /** * proxy method for setkey, for api compatibility * @see setkey * @public */ jsencrypt.prototype.setpublickey = function (pubkey) { // sets the public key. this.setkey(pubkey); }; /** * proxy method for rsakey object's decrypt, decrypt the string using the private * components of the rsa key object. note that if the object was not set will be created * on the fly (by the getkey method) using the parameters passed in the jsencrypt constructor * @param {string} str base64 encoded crypted string to decrypt * @return {string} the decrypted string * @public */ jsencrypt.prototype.decrypt = function (str) { // return the decrypted string. try { return this.getkey().decrypt(b64tohex(str)); } catch (ex) { return false; } }; /** * proxy method for rsakey object's encrypt, encrypt the string using the public * components of the rsa key object. note that if the object was not set will be created * on the fly (by the getkey method) using the parameters passed in the jsencrypt constructor * @param {string} str the string to encrypt * @return {string} the encrypted string encoded in base64 * @public */ jsencrypt.prototype.encrypt = function (str) { // return the encrypted string. try { return hex2b64(this.getkey().encrypt(str)); } catch (ex) { return false; } }; /** * getter for the current jsencryptrsakey object. if it doesn't exists a new object * will be created and returned * @param {callback} [cb] the callback to be called if we want the key to be generated * in an async fashion * @returns {jsencryptrsakey} the jsencryptrsakey object * @public */ jsencrypt.prototype.getkey = function (cb) { // only create new if it does not exist. if (!this.key) { // get a new private key. this.key = new jsencryptrsakey(); if (cb && {}.tostring.call(cb) === "[object function]") { this.key.generateasync(this.default_key_size, this.default_public_exponent, cb); return; } // generate the key. this.key.generate(this.default_key_size, this.default_public_exponent); } return this.key; }; /** * returns the pem encoded representation of the private key * if the key doesn't exists a new key will be created * @returns {string} pem encoded representation of the private key with header and footer * @public */ jsencrypt.prototype.getprivatekey = function () { // return the private representation of this key. return this.getkey().getprivatekey(); }; /** * returns the pem encoded representation of the private key * if the key doesn't exists a new key will be created * @returns {string} pem encoded representation of the private key without header and footer * @public */ jsencrypt.prototype.getprivatekeyb64 = function () { // return the private representation of this key. return this.getkey().getprivatebasekeyb64(); }; /** * returns the pem encoded representation of the public key * if the key doesn't exists a new key will be created * @returns {string} pem encoded representation of the public key with header and footer * @public */ jsencrypt.prototype.getpublickey = function () { // return the private representation of this key. return this.getkey().getpublickey(); }; /** * returns the pem encoded representation of the public key * if the key doesn't exists a new key will be created * @returns {string} pem encoded representation of the public key without header and footer * @public */ jsencrypt.prototype.getpublickeyb64 = function () { // return the private representation of this key. return this.getkey().getpublicbasekeyb64(); }; jsencrypt.version = "3.0.0-beta.1"; return jsencrypt; }()); window.jsencrypt = jsencrypt; exports.jsencrypt = jsencrypt; exports.default = jsencrypt; object.defineproperty(exports, '__esmodule', { value: true }); })));