UNPKG

1.46 MBJavaScriptView Raw
1/*! OpenPGP.js v5.5.0 - 2022-08-31 - this is LGPL licensed code, see LICENSE/our website https://openpgpjs.org/ for more information. */
2const globalThis = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3
4import buffer from 'buffer';
5import stream$1 from 'stream';
6import crypto$3 from 'crypto';
7import zlib from 'zlib';
8import os from 'os';
9import util$1 from 'util';
10import asn1$2 from 'asn1.js';
11
12const doneWritingPromise = Symbol('doneWritingPromise');
13const doneWritingResolve = Symbol('doneWritingResolve');
14const doneWritingReject = Symbol('doneWritingReject');
15
16const readingIndex = Symbol('readingIndex');
17
18class ArrayStream extends Array {
19 constructor() {
20 super();
21 this[doneWritingPromise] = new Promise((resolve, reject) => {
22 this[doneWritingResolve] = resolve;
23 this[doneWritingReject] = reject;
24 });
25 this[doneWritingPromise].catch(() => {});
26 }
27}
28
29ArrayStream.prototype.getReader = function() {
30 if (this[readingIndex] === undefined) {
31 this[readingIndex] = 0;
32 }
33 return {
34 read: async () => {
35 await this[doneWritingPromise];
36 if (this[readingIndex] === this.length) {
37 return { value: undefined, done: true };
38 }
39 return { value: this[this[readingIndex]++], done: false };
40 }
41 };
42};
43
44ArrayStream.prototype.readToEnd = async function(join) {
45 await this[doneWritingPromise];
46 const result = join(this.slice(this[readingIndex]));
47 this.length = 0;
48 return result;
49};
50
51ArrayStream.prototype.clone = function() {
52 const clone = new ArrayStream();
53 clone[doneWritingPromise] = this[doneWritingPromise].then(() => {
54 clone.push(...this);
55 });
56 return clone;
57};
58
59/**
60 * Check whether data is an ArrayStream
61 * @param {Any} input data to check
62 * @returns {boolean}
63 */
64function isArrayStream(input) {
65 return input && input.getReader && Array.isArray(input);
66}
67
68/**
69 * A wrapper class over the native WritableStreamDefaultWriter.
70 * It also lets you "write data to" array streams instead of streams.
71 * @class
72 */
73function Writer(input) {
74 if (!isArrayStream(input)) {
75 const writer = input.getWriter();
76 const releaseLock = writer.releaseLock;
77 writer.releaseLock = () => {
78 writer.closed.catch(function() {});
79 releaseLock.call(writer);
80 };
81 return writer;
82 }
83 this.stream = input;
84}
85
86/**
87 * Write a chunk of data.
88 * @returns {Promise<undefined>}
89 * @async
90 */
91Writer.prototype.write = async function(chunk) {
92 this.stream.push(chunk);
93};
94
95/**
96 * Close the stream.
97 * @returns {Promise<undefined>}
98 * @async
99 */
100Writer.prototype.close = async function() {
101 this.stream[doneWritingResolve]();
102};
103
104/**
105 * Error the stream.
106 * @returns {Promise<Object>}
107 * @async
108 */
109Writer.prototype.abort = async function(reason) {
110 this.stream[doneWritingReject](reason);
111 return reason;
112};
113
114/**
115 * Release the writer's lock.
116 * @returns {undefined}
117 * @async
118 */
119Writer.prototype.releaseLock = function() {};
120
121const isNode = typeof globalThis.process === 'object' &&
122 typeof globalThis.process.versions === 'object';
123
124const NodeReadableStream = isNode && stream$1.Readable;
125
126/**
127 * Check whether data is a Stream, and if so of which type
128 * @param {Any} input data to check
129 * @returns {'web'|'ponyfill'|'node'|'array'|'web-like'|false}
130 */
131function isStream(input) {
132 if (isArrayStream(input)) {
133 return 'array';
134 }
135 if (globalThis.ReadableStream && globalThis.ReadableStream.prototype.isPrototypeOf(input)) {
136 return 'web';
137 }
138 if (ReadableStream && ReadableStream.prototype.isPrototypeOf(input)) {
139 return 'ponyfill';
140 }
141 if (NodeReadableStream && NodeReadableStream.prototype.isPrototypeOf(input)) {
142 return 'node';
143 }
144 if (input && input.getReader) {
145 return 'web-like';
146 }
147 return false;
148}
149
150/**
151 * Check whether data is a Uint8Array
152 * @param {Any} input data to check
153 * @returns {Boolean}
154 */
155function isUint8Array(input) {
156 return Uint8Array.prototype.isPrototypeOf(input);
157}
158
159/**
160 * Concat Uint8Arrays
161 * @param {Array<Uint8array>} Array of Uint8Arrays to concatenate
162 * @returns {Uint8array} Concatenated array
163 */
164function concatUint8Array(arrays) {
165 if (arrays.length === 1) return arrays[0];
166
167 let totalLength = 0;
168 for (let i = 0; i < arrays.length; i++) {
169 if (!isUint8Array(arrays[i])) {
170 throw new Error('concatUint8Array: Data must be in the form of a Uint8Array');
171 }
172
173 totalLength += arrays[i].length;
174 }
175
176 const result = new Uint8Array(totalLength);
177 let pos = 0;
178 arrays.forEach(function (element) {
179 result.set(element, pos);
180 pos += element.length;
181 });
182
183 return result;
184}
185
186const NodeBuffer = isNode && buffer.Buffer;
187const NodeReadableStream$1 = isNode && stream$1.Readable;
188
189/**
190 * Web / node stream conversion functions
191 * From https://github.com/gwicke/node-web-streams
192 */
193
194let nodeToWeb;
195let webToNode;
196
197if (NodeReadableStream$1) {
198
199 /**
200 * Convert a Node Readable Stream to a Web ReadableStream
201 * @param {Readable} nodeStream
202 * @returns {ReadableStream}
203 */
204 nodeToWeb = function(nodeStream) {
205 let canceled = false;
206 return new ReadableStream({
207 start(controller) {
208 nodeStream.pause();
209 nodeStream.on('data', chunk => {
210 if (canceled) {
211 return;
212 }
213 if (NodeBuffer.isBuffer(chunk)) {
214 chunk = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
215 }
216 controller.enqueue(chunk);
217 nodeStream.pause();
218 });
219 nodeStream.on('end', () => {
220 if (canceled) {
221 return;
222 }
223 controller.close();
224 });
225 nodeStream.on('error', e => controller.error(e));
226 },
227 pull() {
228 nodeStream.resume();
229 },
230 cancel(reason) {
231 canceled = true;
232 nodeStream.destroy(reason);
233 }
234 });
235 };
236
237
238 class NodeReadable extends NodeReadableStream$1 {
239 constructor(webStream, options) {
240 super(options);
241 this._reader = getReader(webStream);
242 }
243
244 async _read(size) {
245 try {
246 while (true) {
247 const { done, value } = await this._reader.read();
248 if (done) {
249 this.push(null);
250 break;
251 }
252 if (!this.push(value) || this._cancelling) {
253 this._reading = false;
254 break;
255 }
256 }
257 } catch(e) {
258 this.emit('error', e);
259 }
260 }
261
262 _destroy(reason) {
263 this._reader.cancel(reason);
264 }
265 }
266
267 /**
268 * Convert a Web ReadableStream to a Node Readable Stream
269 * @param {ReadableStream} webStream
270 * @param {Object} options
271 * @returns {Readable}
272 */
273 webToNode = function(webStream, options) {
274 return new NodeReadable(webStream, options);
275 };
276
277}
278
279const doneReadingSet = new WeakSet();
280const externalBuffer = Symbol('externalBuffer');
281
282/**
283 * A wrapper class over the native ReadableStreamDefaultReader.
284 * This additionally implements pushing back data on the stream, which
285 * lets us implement peeking and a host of convenience functions.
286 * It also lets you read data other than streams, such as a Uint8Array.
287 * @class
288 */
289function Reader(input) {
290 this.stream = input;
291 if (input[externalBuffer]) {
292 this[externalBuffer] = input[externalBuffer].slice();
293 }
294 if (isArrayStream(input)) {
295 const reader = input.getReader();
296 this._read = reader.read.bind(reader);
297 this._releaseLock = () => {};
298 this._cancel = () => {};
299 return;
300 }
301 let streamType = isStream(input);
302 if (streamType === 'node') {
303 input = nodeToWeb(input);
304 }
305 if (streamType) {
306 const reader = input.getReader();
307 this._read = reader.read.bind(reader);
308 this._releaseLock = () => {
309 reader.closed.catch(function() {});
310 reader.releaseLock();
311 };
312 this._cancel = reader.cancel.bind(reader);
313 return;
314 }
315 let doneReading = false;
316 this._read = async () => {
317 if (doneReading || doneReadingSet.has(input)) {
318 return { value: undefined, done: true };
319 }
320 doneReading = true;
321 return { value: input, done: false };
322 };
323 this._releaseLock = () => {
324 if (doneReading) {
325 try {
326 doneReadingSet.add(input);
327 } catch(e) {}
328 }
329 };
330}
331
332/**
333 * Read a chunk of data.
334 * @returns {Promise<Object>} Either { done: false, value: Uint8Array | String } or { done: true, value: undefined }
335 * @async
336 */
337Reader.prototype.read = async function() {
338 if (this[externalBuffer] && this[externalBuffer].length) {
339 const value = this[externalBuffer].shift();
340 return { done: false, value };
341 }
342 return this._read();
343};
344
345/**
346 * Allow others to read the stream.
347 */
348Reader.prototype.releaseLock = function() {
349 if (this[externalBuffer]) {
350 this.stream[externalBuffer] = this[externalBuffer];
351 }
352 this._releaseLock();
353};
354
355/**
356 * Cancel the stream.
357 */
358Reader.prototype.cancel = function(reason) {
359 return this._cancel(reason);
360};
361
362/**
363 * Read up to and including the first \n character.
364 * @returns {Promise<String|Undefined>}
365 * @async
366 */
367Reader.prototype.readLine = async function() {
368 let buffer = [];
369 let returnVal;
370 while (!returnVal) {
371 let { done, value } = await this.read();
372 value += '';
373 if (done) {
374 if (buffer.length) return concat(buffer);
375 return;
376 }
377 const lineEndIndex = value.indexOf('\n') + 1;
378 if (lineEndIndex) {
379 returnVal = concat(buffer.concat(value.substr(0, lineEndIndex)));
380 buffer = [];
381 }
382 if (lineEndIndex !== value.length) {
383 buffer.push(value.substr(lineEndIndex));
384 }
385 }
386 this.unshift(...buffer);
387 return returnVal;
388};
389
390/**
391 * Read a single byte/character.
392 * @returns {Promise<Number|String|Undefined>}
393 * @async
394 */
395Reader.prototype.readByte = async function() {
396 const { done, value } = await this.read();
397 if (done) return;
398 const byte = value[0];
399 this.unshift(slice(value, 1));
400 return byte;
401};
402
403/**
404 * Read a specific amount of bytes/characters, unless the stream ends before that amount.
405 * @returns {Promise<Uint8Array|String|Undefined>}
406 * @async
407 */
408Reader.prototype.readBytes = async function(length) {
409 const buffer = [];
410 let bufferLength = 0;
411 while (true) {
412 const { done, value } = await this.read();
413 if (done) {
414 if (buffer.length) return concat(buffer);
415 return;
416 }
417 buffer.push(value);
418 bufferLength += value.length;
419 if (bufferLength >= length) {
420 const bufferConcat = concat(buffer);
421 this.unshift(slice(bufferConcat, length));
422 return slice(bufferConcat, 0, length);
423 }
424 }
425};
426
427/**
428 * Peek (look ahead) a specific amount of bytes/characters, unless the stream ends before that amount.
429 * @returns {Promise<Uint8Array|String|Undefined>}
430 * @async
431 */
432Reader.prototype.peekBytes = async function(length) {
433 const bytes = await this.readBytes(length);
434 this.unshift(bytes);
435 return bytes;
436};
437
438/**
439 * Push data to the front of the stream.
440 * Data must have been read in the last call to read*.
441 * @param {...(Uint8Array|String|Undefined)} values
442 */
443Reader.prototype.unshift = function(...values) {
444 if (!this[externalBuffer]) {
445 this[externalBuffer] = [];
446 }
447 if (
448 values.length === 1 && isUint8Array(values[0]) &&
449 this[externalBuffer].length && values[0].length &&
450 this[externalBuffer][0].byteOffset >= values[0].length
451 ) {
452 this[externalBuffer][0] = new Uint8Array(
453 this[externalBuffer][0].buffer,
454 this[externalBuffer][0].byteOffset - values[0].length,
455 this[externalBuffer][0].byteLength + values[0].length
456 );
457 return;
458 }
459 this[externalBuffer].unshift(...values.filter(value => value && value.length));
460};
461
462/**
463 * Read the stream to the end and return its contents, concatenated by the join function (defaults to streams.concat).
464 * @param {Function} join
465 * @returns {Promise<Uint8array|String|Any>} the return value of join()
466 * @async
467 */
468Reader.prototype.readToEnd = async function(join=concat) {
469 const result = [];
470 while (true) {
471 const { done, value } = await this.read();
472 if (done) break;
473 result.push(value);
474 }
475 return join(result);
476};
477
478let { ReadableStream, WritableStream, TransformStream } = globalThis;
479
480let toPonyfillReadable, toNativeReadable;
481
482async function loadStreamsPonyfill() {
483 if (TransformStream) {
484 return;
485 }
486
487 const [ponyfill, adapter] = await Promise.all([
488 Promise.resolve().then(function () { return ponyfill_es6; }),
489 Promise.resolve().then(function () { return webStreamsAdapter; })
490 ]);
491
492 ({ ReadableStream, WritableStream, TransformStream } = ponyfill);
493
494 const { createReadableStreamWrapper } = adapter;
495
496 if (globalThis.ReadableStream && ReadableStream !== globalThis.ReadableStream) {
497 toPonyfillReadable = createReadableStreamWrapper(ReadableStream);
498 toNativeReadable = createReadableStreamWrapper(globalThis.ReadableStream);
499 }
500}
501
502const NodeBuffer$1 = isNode && buffer.Buffer;
503
504/**
505 * Convert data to Stream
506 * @param {ReadableStream|Uint8array|String} input data to convert
507 * @returns {ReadableStream} Converted data
508 */
509function toStream(input) {
510 let streamType = isStream(input);
511 if (streamType === 'node') {
512 return nodeToWeb(input);
513 }
514 if (streamType === 'web' && toPonyfillReadable) {
515 return toPonyfillReadable(input);
516 }
517 if (streamType) {
518 return input;
519 }
520 return new ReadableStream({
521 start(controller) {
522 controller.enqueue(input);
523 controller.close();
524 }
525 });
526}
527
528/**
529 * Convert data to ArrayStream
530 * @param {Object} input data to convert
531 * @returns {ArrayStream} Converted data
532 */
533function toArrayStream(input) {
534 if (isStream(input)) {
535 return input;
536 }
537 const stream = new ArrayStream();
538 (async () => {
539 const writer = getWriter(stream);
540 await writer.write(input);
541 await writer.close();
542 })();
543 return stream;
544}
545
546/**
547 * Concat a list of Uint8Arrays, Strings or Streams
548 * The caller should not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
549 * @param {Array<Uint8array|String|ReadableStream>} Array of Uint8Arrays/Strings/Streams to concatenate
550 * @returns {Uint8array|String|ReadableStream} Concatenated array
551 */
552function concat(list) {
553 if (list.some(stream => isStream(stream) && !isArrayStream(stream))) {
554 return concatStream(list);
555 }
556 if (list.some(stream => isArrayStream(stream))) {
557 return concatArrayStream(list);
558 }
559 if (typeof list[0] === 'string') {
560 return list.join('');
561 }
562 if (NodeBuffer$1 && NodeBuffer$1.isBuffer(list[0])) {
563 return NodeBuffer$1.concat(list);
564 }
565 return concatUint8Array(list);
566}
567
568/**
569 * Concat a list of Streams
570 * @param {Array<ReadableStream|Uint8array|String>} list Array of Uint8Arrays/Strings/Streams to concatenate
571 * @returns {ReadableStream} Concatenated list
572 */
573function concatStream(list) {
574 list = list.map(toStream);
575 const transform = transformWithCancel(async function(reason) {
576 await Promise.all(transforms.map(stream => cancel(stream, reason)));
577 });
578 let prev = Promise.resolve();
579 const transforms = list.map((stream, i) => transformPair(stream, (readable, writable) => {
580 prev = prev.then(() => pipe(readable, transform.writable, {
581 preventClose: i !== list.length - 1
582 }));
583 return prev;
584 }));
585 return transform.readable;
586}
587
588/**
589 * Concat a list of ArrayStreams
590 * @param {Array<ArrayStream|Uint8array|String>} list Array of Uint8Arrays/Strings/ArrayStreams to concatenate
591 * @returns {ArrayStream} Concatenated streams
592 */
593function concatArrayStream(list) {
594 const result = new ArrayStream();
595 let prev = Promise.resolve();
596 list.forEach((stream, i) => {
597 prev = prev.then(() => pipe(stream, result, {
598 preventClose: i !== list.length - 1
599 }));
600 return prev;
601 });
602 return result;
603}
604
605/**
606 * Get a Reader
607 * @param {ReadableStream|Uint8array|String} input
608 * @returns {Reader}
609 */
610function getReader(input) {
611 return new Reader(input);
612}
613
614/**
615 * Get a Writer
616 * @param {WritableStream} input
617 * @returns {Writer}
618 */
619function getWriter(input) {
620 return new Writer(input);
621}
622
623/**
624 * Pipe a readable stream to a writable stream. Don't throw on input stream errors, but forward them to the output stream.
625 * @param {ReadableStream|Uint8array|String} input
626 * @param {WritableStream} target
627 * @param {Object} (optional) options
628 * @returns {Promise<undefined>} Promise indicating when piping has finished (input stream closed or errored)
629 * @async
630 */
631async function pipe(input, target, {
632 preventClose = false,
633 preventAbort = false,
634 preventCancel = false
635} = {}) {
636 if (isStream(input) && !isArrayStream(input)) {
637 input = toStream(input);
638 try {
639 if (input[externalBuffer]) {
640 const writer = getWriter(target);
641 for (let i = 0; i < input[externalBuffer].length; i++) {
642 await writer.ready;
643 await writer.write(input[externalBuffer][i]);
644 }
645 writer.releaseLock();
646 }
647 await input.pipeTo(target, {
648 preventClose,
649 preventAbort,
650 preventCancel
651 });
652 } catch(e) {}
653 return;
654 }
655 input = toArrayStream(input);
656 const reader = getReader(input);
657 const writer = getWriter(target);
658 try {
659 while (true) {
660 await writer.ready;
661 const { done, value } = await reader.read();
662 if (done) {
663 if (!preventClose) await writer.close();
664 break;
665 }
666 await writer.write(value);
667 }
668 } catch (e) {
669 if (!preventAbort) await writer.abort(e);
670 } finally {
671 reader.releaseLock();
672 writer.releaseLock();
673 }
674}
675
676/**
677 * Pipe a readable stream through a transform stream.
678 * @param {ReadableStream|Uint8array|String} input
679 * @param {Object} (optional) options
680 * @returns {ReadableStream} transformed stream
681 */
682function transformRaw(input, options) {
683 const transformStream = new TransformStream(options);
684 pipe(input, transformStream.writable);
685 return transformStream.readable;
686}
687
688/**
689 * Create a cancelable TransformStream.
690 * @param {Function} cancel
691 * @returns {TransformStream}
692 */
693function transformWithCancel(cancel) {
694 let pulled = false;
695 let backpressureChangePromiseResolve;
696 let outputController;
697 return {
698 readable: new ReadableStream({
699 start(controller) {
700 outputController = controller;
701 },
702 pull() {
703 if (backpressureChangePromiseResolve) {
704 backpressureChangePromiseResolve();
705 } else {
706 pulled = true;
707 }
708 },
709 cancel
710 }, {highWaterMark: 0}),
711 writable: new WritableStream({
712 write: async function(chunk) {
713 outputController.enqueue(chunk);
714 if (!pulled) {
715 await new Promise(resolve => {
716 backpressureChangePromiseResolve = resolve;
717 });
718 backpressureChangePromiseResolve = null;
719 } else {
720 pulled = false;
721 }
722 },
723 close: outputController.close.bind(outputController),
724 abort: outputController.error.bind(outputController)
725 })
726 };
727}
728
729/**
730 * Transform a stream using helper functions which are called on each chunk, and on stream close, respectively.
731 * @param {ReadableStream|Uint8array|String} input
732 * @param {Function} process
733 * @param {Function} finish
734 * @returns {ReadableStream|Uint8array|String}
735 */
736function transform(input, process = () => undefined, finish = () => undefined) {
737 if (isArrayStream(input)) {
738 const output = new ArrayStream();
739 (async () => {
740 const writer = getWriter(output);
741 try {
742 const data = await readToEnd(input);
743 const result1 = process(data);
744 const result2 = finish();
745 let result;
746 if (result1 !== undefined && result2 !== undefined) result = concat([result1, result2]);
747 else result = result1 !== undefined ? result1 : result2;
748 await writer.write(result);
749 await writer.close();
750 } catch (e) {
751 await writer.abort(e);
752 }
753 })();
754 return output;
755 }
756 if (isStream(input)) {
757 return transformRaw(input, {
758 async transform(value, controller) {
759 try {
760 const result = await process(value);
761 if (result !== undefined) controller.enqueue(result);
762 } catch(e) {
763 controller.error(e);
764 }
765 },
766 async flush(controller) {
767 try {
768 const result = await finish();
769 if (result !== undefined) controller.enqueue(result);
770 } catch(e) {
771 controller.error(e);
772 }
773 }
774 });
775 }
776 const result1 = process(input);
777 const result2 = finish();
778 if (result1 !== undefined && result2 !== undefined) return concat([result1, result2]);
779 return result1 !== undefined ? result1 : result2;
780}
781
782/**
783 * Transform a stream using a helper function which is passed a readable and a writable stream.
784 * This function also maintains the possibility to cancel the input stream,
785 * and does so on cancelation of the output stream, despite cancelation
786 * normally being impossible when the input stream is being read from.
787 * @param {ReadableStream|Uint8array|String} input
788 * @param {Function} fn
789 * @returns {ReadableStream}
790 */
791function transformPair(input, fn) {
792 if (isStream(input) && !isArrayStream(input)) {
793 let incomingTransformController;
794 const incoming = new TransformStream({
795 start(controller) {
796 incomingTransformController = controller;
797 }
798 });
799
800 const pipeDonePromise = pipe(input, incoming.writable);
801
802 const outgoing = transformWithCancel(async function(reason) {
803 incomingTransformController.error(reason);
804 await pipeDonePromise;
805 await new Promise(setTimeout);
806 });
807 fn(incoming.readable, outgoing.writable);
808 return outgoing.readable;
809 }
810 input = toArrayStream(input);
811 const output = new ArrayStream();
812 fn(input, output);
813 return output;
814}
815
816/**
817 * Parse a stream using a helper function which is passed a Reader.
818 * The reader additionally has a remainder() method which returns a
819 * stream pointing to the remainder of input, and is linked to input
820 * for cancelation.
821 * @param {ReadableStream|Uint8array|String} input
822 * @param {Function} fn
823 * @returns {Any} the return value of fn()
824 */
825function parse(input, fn) {
826 let returnValue;
827 const transformed = transformPair(input, (readable, writable) => {
828 const reader = getReader(readable);
829 reader.remainder = () => {
830 reader.releaseLock();
831 pipe(readable, writable);
832 return transformed;
833 };
834 returnValue = fn(reader);
835 });
836 return returnValue;
837}
838
839/**
840 * Tee a Stream for reading it twice. The input stream can no longer be read after tee()ing.
841 * Reading either of the two returned streams will pull from the input stream.
842 * The input stream will only be canceled if both of the returned streams are canceled.
843 * @param {ReadableStream|Uint8array|String} input
844 * @returns {Array<ReadableStream|Uint8array|String>} array containing two copies of input
845 */
846function tee(input) {
847 if (isArrayStream(input)) {
848 throw new Error('ArrayStream cannot be tee()d, use clone() instead');
849 }
850 if (isStream(input)) {
851 const teed = toStream(input).tee();
852 teed[0][externalBuffer] = teed[1][externalBuffer] = input[externalBuffer];
853 return teed;
854 }
855 return [slice(input), slice(input)];
856}
857
858/**
859 * Clone a Stream for reading it twice. The input stream can still be read after clone()ing.
860 * Reading from the clone will pull from the input stream.
861 * The input stream will only be canceled if both the clone and the input stream are canceled.
862 * @param {ReadableStream|Uint8array|String} input
863 * @returns {ReadableStream|Uint8array|String} cloned input
864 */
865function clone(input) {
866 if (isArrayStream(input)) {
867 return input.clone();
868 }
869 if (isStream(input)) {
870 const teed = tee(input);
871 overwrite(input, teed[0]);
872 return teed[1];
873 }
874 return slice(input);
875}
876
877/**
878 * Clone a Stream for reading it twice. Data will arrive at the same rate as the input stream is being read.
879 * Reading from the clone will NOT pull from the input stream. Data only arrives when reading the input stream.
880 * The input stream will NOT be canceled if the clone is canceled, only if the input stream are canceled.
881 * If the input stream is canceled, the clone will be errored.
882 * @param {ReadableStream|Uint8array|String} input
883 * @returns {ReadableStream|Uint8array|String} cloned input
884 */
885function passiveClone(input) {
886 if (isArrayStream(input)) {
887 return clone(input);
888 }
889 if (isStream(input)) {
890 return new ReadableStream({
891 start(controller) {
892 const transformed = transformPair(input, async (readable, writable) => {
893 const reader = getReader(readable);
894 const writer = getWriter(writable);
895 try {
896 while (true) {
897 await writer.ready;
898 const { done, value } = await reader.read();
899 if (done) {
900 try { controller.close(); } catch(e) {}
901 await writer.close();
902 return;
903 }
904 try { controller.enqueue(value); } catch(e) {}
905 await writer.write(value);
906 }
907 } catch(e) {
908 controller.error(e);
909 await writer.abort(e);
910 }
911 });
912 overwrite(input, transformed);
913 }
914 });
915 }
916 return slice(input);
917}
918
919/**
920 * Modify a stream object to point to a different stream object.
921 * This is used internally by clone() and passiveClone() to provide an abstraction over tee().
922 * @param {ReadableStream} input
923 * @param {ReadableStream} clone
924 */
925function overwrite(input, clone) {
926 // Overwrite input.getReader, input.locked, etc to point to clone
927 Object.entries(Object.getOwnPropertyDescriptors(input.constructor.prototype)).forEach(([name, descriptor]) => {
928 if (name === 'constructor') {
929 return;
930 }
931 if (descriptor.value) {
932 descriptor.value = descriptor.value.bind(clone);
933 } else {
934 descriptor.get = descriptor.get.bind(clone);
935 }
936 Object.defineProperty(input, name, descriptor);
937 });
938}
939
940/**
941 * Return a stream pointing to a part of the input stream.
942 * @param {ReadableStream|Uint8array|String} input
943 * @returns {ReadableStream|Uint8array|String} clone
944 */
945function slice(input, begin=0, end=Infinity) {
946 if (isArrayStream(input)) {
947 throw new Error('Not implemented');
948 }
949 if (isStream(input)) {
950 if (begin >= 0 && end >= 0) {
951 let bytesRead = 0;
952 return transformRaw(input, {
953 transform(value, controller) {
954 if (bytesRead < end) {
955 if (bytesRead + value.length >= begin) {
956 controller.enqueue(slice(value, Math.max(begin - bytesRead, 0), end - bytesRead));
957 }
958 bytesRead += value.length;
959 } else {
960 controller.terminate();
961 }
962 }
963 });
964 }
965 if (begin < 0 && (end < 0 || end === Infinity)) {
966 let lastBytes = [];
967 return transform(input, value => {
968 if (value.length >= -begin) lastBytes = [value];
969 else lastBytes.push(value);
970 }, () => slice(concat(lastBytes), begin, end));
971 }
972 if (begin === 0 && end < 0) {
973 let lastBytes;
974 return transform(input, value => {
975 const returnValue = lastBytes ? concat([lastBytes, value]) : value;
976 if (returnValue.length >= -end) {
977 lastBytes = slice(returnValue, end);
978 return slice(returnValue, begin, end);
979 } else {
980 lastBytes = returnValue;
981 }
982 });
983 }
984 console.warn(`stream.slice(input, ${begin}, ${end}) not implemented efficiently.`);
985 return fromAsync(async () => slice(await readToEnd(input), begin, end));
986 }
987 if (input[externalBuffer]) {
988 input = concat(input[externalBuffer].concat([input]));
989 }
990 if (isUint8Array(input) && !(NodeBuffer$1 && NodeBuffer$1.isBuffer(input))) {
991 if (end === Infinity) end = input.length;
992 return input.subarray(begin, end);
993 }
994 return input.slice(begin, end);
995}
996
997/**
998 * Read a stream to the end and return its contents, concatenated by the join function (defaults to concat).
999 * @param {ReadableStream|Uint8array|String} input
1000 * @param {Function} join
1001 * @returns {Promise<Uint8array|String|Any>} the return value of join()
1002 * @async
1003 */
1004async function readToEnd(input, join=concat) {
1005 if (isArrayStream(input)) {
1006 return input.readToEnd(join);
1007 }
1008 if (isStream(input)) {
1009 return getReader(input).readToEnd(join);
1010 }
1011 return input;
1012}
1013
1014/**
1015 * Cancel a stream.
1016 * @param {ReadableStream|Uint8array|String} input
1017 * @param {Any} reason
1018 * @returns {Promise<Any>} indicates when the stream has been canceled
1019 * @async
1020 */
1021async function cancel(input, reason) {
1022 if (isStream(input)) {
1023 if (input.cancel) {
1024 return input.cancel(reason);
1025 }
1026 if (input.destroy) {
1027 input.destroy(reason);
1028 await new Promise(setTimeout);
1029 return reason;
1030 }
1031 }
1032}
1033
1034/**
1035 * Convert an async function to an ArrayStream. When the function returns, its return value is written to the stream.
1036 * @param {Function} fn
1037 * @returns {ArrayStream}
1038 */
1039function fromAsync(fn) {
1040 const arrayStream = new ArrayStream();
1041 (async () => {
1042 const writer = getWriter(arrayStream);
1043 try {
1044 await writer.write(await fn());
1045 await writer.close();
1046 } catch (e) {
1047 await writer.abort(e);
1048 }
1049 })();
1050 return arrayStream;
1051}
1052
1053/* eslint-disable new-cap */
1054
1055/**
1056 * @fileoverview
1057 * BigInteger implementation of basic operations
1058 * that wraps the native BigInt library.
1059 * Operations are not constant time,
1060 * but we try and limit timing leakage where we can
1061 * @module biginteger/native
1062 * @private
1063 */
1064
1065/**
1066 * @private
1067 */
1068class BigInteger {
1069 /**
1070 * Get a BigInteger (input must be big endian for strings and arrays)
1071 * @param {Number|String|Uint8Array} n - Value to convert
1072 * @throws {Error} on null or undefined input
1073 */
1074 constructor(n) {
1075 if (n === undefined) {
1076 throw new Error('Invalid BigInteger input');
1077 }
1078
1079 if (n instanceof Uint8Array) {
1080 const bytes = n;
1081 const hex = new Array(bytes.length);
1082 for (let i = 0; i < bytes.length; i++) {
1083 const hexByte = bytes[i].toString(16);
1084 hex[i] = (bytes[i] <= 0xF) ? ('0' + hexByte) : hexByte;
1085 }
1086 this.value = BigInt('0x0' + hex.join(''));
1087 } else {
1088 this.value = BigInt(n);
1089 }
1090 }
1091
1092 clone() {
1093 return new BigInteger(this.value);
1094 }
1095
1096 /**
1097 * BigInteger increment in place
1098 */
1099 iinc() {
1100 this.value++;
1101 return this;
1102 }
1103
1104 /**
1105 * BigInteger increment
1106 * @returns {BigInteger} this + 1.
1107 */
1108 inc() {
1109 return this.clone().iinc();
1110 }
1111
1112 /**
1113 * BigInteger decrement in place
1114 */
1115 idec() {
1116 this.value--;
1117 return this;
1118 }
1119
1120 /**
1121 * BigInteger decrement
1122 * @returns {BigInteger} this - 1.
1123 */
1124 dec() {
1125 return this.clone().idec();
1126 }
1127
1128 /**
1129 * BigInteger addition in place
1130 * @param {BigInteger} x - Value to add
1131 */
1132 iadd(x) {
1133 this.value += x.value;
1134 return this;
1135 }
1136
1137 /**
1138 * BigInteger addition
1139 * @param {BigInteger} x - Value to add
1140 * @returns {BigInteger} this + x.
1141 */
1142 add(x) {
1143 return this.clone().iadd(x);
1144 }
1145
1146 /**
1147 * BigInteger subtraction in place
1148 * @param {BigInteger} x - Value to subtract
1149 */
1150 isub(x) {
1151 this.value -= x.value;
1152 return this;
1153 }
1154
1155 /**
1156 * BigInteger subtraction
1157 * @param {BigInteger} x - Value to subtract
1158 * @returns {BigInteger} this - x.
1159 */
1160 sub(x) {
1161 return this.clone().isub(x);
1162 }
1163
1164 /**
1165 * BigInteger multiplication in place
1166 * @param {BigInteger} x - Value to multiply
1167 */
1168 imul(x) {
1169 this.value *= x.value;
1170 return this;
1171 }
1172
1173 /**
1174 * BigInteger multiplication
1175 * @param {BigInteger} x - Value to multiply
1176 * @returns {BigInteger} this * x.
1177 */
1178 mul(x) {
1179 return this.clone().imul(x);
1180 }
1181
1182 /**
1183 * Compute value modulo m, in place
1184 * @param {BigInteger} m - Modulo
1185 */
1186 imod(m) {
1187 this.value %= m.value;
1188 if (this.isNegative()) {
1189 this.iadd(m);
1190 }
1191 return this;
1192 }
1193
1194 /**
1195 * Compute value modulo m
1196 * @param {BigInteger} m - Modulo
1197 * @returns {BigInteger} this mod m.
1198 */
1199 mod(m) {
1200 return this.clone().imod(m);
1201 }
1202
1203 /**
1204 * Compute modular exponentiation using square and multiply
1205 * @param {BigInteger} e - Exponent
1206 * @param {BigInteger} n - Modulo
1207 * @returns {BigInteger} this ** e mod n.
1208 */
1209 modExp(e, n) {
1210 if (n.isZero()) throw Error('Modulo cannot be zero');
1211 if (n.isOne()) return new BigInteger(0);
1212 if (e.isNegative()) throw Error('Unsopported negative exponent');
1213
1214 let exp = e.value;
1215 let x = this.value;
1216
1217 x %= n.value;
1218 let r = BigInt(1);
1219 while (exp > BigInt(0)) {
1220 const lsb = exp & BigInt(1);
1221 exp >>= BigInt(1); // e / 2
1222 // Always compute multiplication step, to reduce timing leakage
1223 const rx = (r * x) % n.value;
1224 // Update r only if lsb is 1 (odd exponent)
1225 r = lsb ? rx : r;
1226 x = (x * x) % n.value; // Square
1227 }
1228 return new BigInteger(r);
1229 }
1230
1231
1232 /**
1233 * Compute the inverse of this value modulo n
1234 * Note: this and and n must be relatively prime
1235 * @param {BigInteger} n - Modulo
1236 * @returns {BigInteger} x such that this*x = 1 mod n
1237 * @throws {Error} if the inverse does not exist
1238 */
1239 modInv(n) {
1240 const { gcd, x } = this._egcd(n);
1241 if (!gcd.isOne()) {
1242 throw new Error('Inverse does not exist');
1243 }
1244 return x.add(n).mod(n);
1245 }
1246
1247 /**
1248 * Extended Eucleadian algorithm (http://anh.cs.luc.edu/331/notes/xgcd.pdf)
1249 * Given a = this and b, compute (x, y) such that ax + by = gdc(a, b)
1250 * @param {BigInteger} b - Second operand
1251 * @returns {{ gcd, x, y: BigInteger }}
1252 */
1253 _egcd(b) {
1254 let x = BigInt(0);
1255 let y = BigInt(1);
1256 let xPrev = BigInt(1);
1257 let yPrev = BigInt(0);
1258
1259 let a = this.value;
1260 b = b.value;
1261
1262 while (b !== BigInt(0)) {
1263 const q = a / b;
1264 let tmp = x;
1265 x = xPrev - q * x;
1266 xPrev = tmp;
1267
1268 tmp = y;
1269 y = yPrev - q * y;
1270 yPrev = tmp;
1271
1272 tmp = b;
1273 b = a % b;
1274 a = tmp;
1275 }
1276
1277 return {
1278 x: new BigInteger(xPrev),
1279 y: new BigInteger(yPrev),
1280 gcd: new BigInteger(a)
1281 };
1282 }
1283
1284 /**
1285 * Compute greatest common divisor between this and n
1286 * @param {BigInteger} b - Operand
1287 * @returns {BigInteger} gcd
1288 */
1289 gcd(b) {
1290 let a = this.value;
1291 b = b.value;
1292 while (b !== BigInt(0)) {
1293 const tmp = b;
1294 b = a % b;
1295 a = tmp;
1296 }
1297 return new BigInteger(a);
1298 }
1299
1300 /**
1301 * Shift this to the left by x, in place
1302 * @param {BigInteger} x - Shift value
1303 */
1304 ileftShift(x) {
1305 this.value <<= x.value;
1306 return this;
1307 }
1308
1309 /**
1310 * Shift this to the left by x
1311 * @param {BigInteger} x - Shift value
1312 * @returns {BigInteger} this << x.
1313 */
1314 leftShift(x) {
1315 return this.clone().ileftShift(x);
1316 }
1317
1318 /**
1319 * Shift this to the right by x, in place
1320 * @param {BigInteger} x - Shift value
1321 */
1322 irightShift(x) {
1323 this.value >>= x.value;
1324 return this;
1325 }
1326
1327 /**
1328 * Shift this to the right by x
1329 * @param {BigInteger} x - Shift value
1330 * @returns {BigInteger} this >> x.
1331 */
1332 rightShift(x) {
1333 return this.clone().irightShift(x);
1334 }
1335
1336 /**
1337 * Whether this value is equal to x
1338 * @param {BigInteger} x
1339 * @returns {Boolean}
1340 */
1341 equal(x) {
1342 return this.value === x.value;
1343 }
1344
1345 /**
1346 * Whether this value is less than x
1347 * @param {BigInteger} x
1348 * @returns {Boolean}
1349 */
1350 lt(x) {
1351 return this.value < x.value;
1352 }
1353
1354 /**
1355 * Whether this value is less than or equal to x
1356 * @param {BigInteger} x
1357 * @returns {Boolean}
1358 */
1359 lte(x) {
1360 return this.value <= x.value;
1361 }
1362
1363 /**
1364 * Whether this value is greater than x
1365 * @param {BigInteger} x
1366 * @returns {Boolean}
1367 */
1368 gt(x) {
1369 return this.value > x.value;
1370 }
1371
1372 /**
1373 * Whether this value is greater than or equal to x
1374 * @param {BigInteger} x
1375 * @returns {Boolean}
1376 */
1377 gte(x) {
1378 return this.value >= x.value;
1379 }
1380
1381 isZero() {
1382 return this.value === BigInt(0);
1383 }
1384
1385 isOne() {
1386 return this.value === BigInt(1);
1387 }
1388
1389 isNegative() {
1390 return this.value < BigInt(0);
1391 }
1392
1393 isEven() {
1394 return !(this.value & BigInt(1));
1395 }
1396
1397 abs() {
1398 const res = this.clone();
1399 if (this.isNegative()) {
1400 res.value = -res.value;
1401 }
1402 return res;
1403 }
1404
1405 /**
1406 * Get this value as a string
1407 * @returns {String} this value.
1408 */
1409 toString() {
1410 return this.value.toString();
1411 }
1412
1413 /**
1414 * Get this value as an exact Number (max 53 bits)
1415 * Fails if this value is too large
1416 * @returns {Number}
1417 */
1418 toNumber() {
1419 const number = Number(this.value);
1420 if (number > Number.MAX_SAFE_INTEGER) {
1421 // We throw and error to conform with the bn.js implementation
1422 throw new Error('Number can only safely store up to 53 bits');
1423 }
1424 return number;
1425 }
1426
1427 /**
1428 * Get value of i-th bit
1429 * @param {Number} i - Bit index
1430 * @returns {Number} Bit value.
1431 */
1432 getBit(i) {
1433 const bit = (this.value >> BigInt(i)) & BigInt(1);
1434 return (bit === BigInt(0)) ? 0 : 1;
1435 }
1436
1437 /**
1438 * Compute bit length
1439 * @returns {Number} Bit length.
1440 */
1441 bitLength() {
1442 const zero = new BigInteger(0);
1443 const one = new BigInteger(1);
1444 const negOne = new BigInteger(-1);
1445
1446 // -1n >> -1n is -1n
1447 // 1n >> 1n is 0n
1448 const target = this.isNegative() ? negOne : zero;
1449 let bitlen = 1;
1450 const tmp = this.clone();
1451 while (!tmp.irightShift(one).equal(target)) {
1452 bitlen++;
1453 }
1454 return bitlen;
1455 }
1456
1457 /**
1458 * Compute byte length
1459 * @returns {Number} Byte length.
1460 */
1461 byteLength() {
1462 const zero = new BigInteger(0);
1463 const negOne = new BigInteger(-1);
1464
1465 const target = this.isNegative() ? negOne : zero;
1466 const eight = new BigInteger(8);
1467 let len = 1;
1468 const tmp = this.clone();
1469 while (!tmp.irightShift(eight).equal(target)) {
1470 len++;
1471 }
1472 return len;
1473 }
1474
1475 /**
1476 * Get Uint8Array representation of this number
1477 * @param {String} endian - Endianess of output array (defaults to 'be')
1478 * @param {Number} length - Of output array
1479 * @returns {Uint8Array}
1480 */
1481 toUint8Array(endian = 'be', length) {
1482 // we get and parse the hex string (https://coolaj86.com/articles/convert-js-bigints-to-typedarrays/)
1483 // this is faster than shift+mod iterations
1484 let hex = this.value.toString(16);
1485 if (hex.length % 2 === 1) {
1486 hex = '0' + hex;
1487 }
1488
1489 const rawLength = hex.length / 2;
1490 const bytes = new Uint8Array(length || rawLength);
1491 // parse hex
1492 const offset = length ? (length - rawLength) : 0;
1493 let i = 0;
1494 while (i < rawLength) {
1495 bytes[i + offset] = parseInt(hex.slice(2 * i, 2 * i + 2), 16);
1496 i++;
1497 }
1498
1499 if (endian !== 'be') {
1500 bytes.reverse();
1501 }
1502
1503 return bytes;
1504 }
1505}
1506
1507async function getBigInteger() {
1508 if (util.detectBigInt()) {
1509 return BigInteger;
1510 } else {
1511 const { default: BigInteger } = await Promise.resolve().then(function () { return bn_interface; });
1512 return BigInteger;
1513 }
1514}
1515
1516const debugMode = (() => {
1517 try {
1518 return process.env.NODE_ENV === 'development'; // eslint-disable-line no-process-env
1519 } catch (e) {}
1520 return false;
1521})();
1522
1523const util = {
1524 isString: function(data) {
1525 return typeof data === 'string' || String.prototype.isPrototypeOf(data);
1526 },
1527
1528 isArray: function(data) {
1529 return Array.prototype.isPrototypeOf(data);
1530 },
1531
1532 isUint8Array: isUint8Array,
1533
1534 isStream: isStream,
1535
1536 readNumber: function (bytes) {
1537 let n = 0;
1538 for (let i = 0; i < bytes.length; i++) {
1539 n += (256 ** i) * bytes[bytes.length - 1 - i];
1540 }
1541 return n;
1542 },
1543
1544 writeNumber: function (n, bytes) {
1545 const b = new Uint8Array(bytes);
1546 for (let i = 0; i < bytes; i++) {
1547 b[i] = (n >> (8 * (bytes - i - 1))) & 0xFF;
1548 }
1549
1550 return b;
1551 },
1552
1553 readDate: function (bytes) {
1554 const n = util.readNumber(bytes);
1555 const d = new Date(n * 1000);
1556 return d;
1557 },
1558
1559 writeDate: function (time) {
1560 const numeric = Math.floor(time.getTime() / 1000);
1561
1562 return util.writeNumber(numeric, 4);
1563 },
1564
1565 normalizeDate: function (time = Date.now()) {
1566 return time === null || time === Infinity ? time : new Date(Math.floor(+time / 1000) * 1000);
1567 },
1568
1569 /**
1570 * Read one MPI from bytes in input
1571 * @param {Uint8Array} bytes - Input data to parse
1572 * @returns {Uint8Array} Parsed MPI.
1573 */
1574 readMPI: function (bytes) {
1575 const bits = (bytes[0] << 8) | bytes[1];
1576 const bytelen = (bits + 7) >>> 3;
1577 return bytes.subarray(2, 2 + bytelen);
1578 },
1579
1580 /**
1581 * Left-pad Uint8Array to length by adding 0x0 bytes
1582 * @param {Uint8Array} bytes - Data to pad
1583 * @param {Number} length - Padded length
1584 * @returns {Uint8Array} Padded bytes.
1585 */
1586 leftPad(bytes, length) {
1587 const padded = new Uint8Array(length);
1588 const offset = length - bytes.length;
1589 padded.set(bytes, offset);
1590 return padded;
1591 },
1592
1593 /**
1594 * Convert a Uint8Array to an MPI-formatted Uint8Array.
1595 * @param {Uint8Array} bin - An array of 8-bit integers to convert
1596 * @returns {Uint8Array} MPI-formatted Uint8Array.
1597 */
1598 uint8ArrayToMPI: function (bin) {
1599 const bitSize = util.uint8ArrayBitLength(bin);
1600 if (bitSize === 0) {
1601 throw new Error('Zero MPI');
1602 }
1603 const stripped = bin.subarray(bin.length - Math.ceil(bitSize / 8));
1604 const prefix = new Uint8Array([(bitSize & 0xFF00) >> 8, bitSize & 0xFF]);
1605 return util.concatUint8Array([prefix, stripped]);
1606 },
1607
1608 /**
1609 * Return bit length of the input data
1610 * @param {Uint8Array} bin input data (big endian)
1611 * @returns bit length
1612 */
1613 uint8ArrayBitLength: function (bin) {
1614 let i; // index of leading non-zero byte
1615 for (i = 0; i < bin.length; i++) if (bin[i] !== 0) break;
1616 if (i === bin.length) {
1617 return 0;
1618 }
1619 const stripped = bin.subarray(i);
1620 return (stripped.length - 1) * 8 + util.nbits(stripped[0]);
1621 },
1622
1623 /**
1624 * Convert a hex string to an array of 8-bit integers
1625 * @param {String} hex - A hex string to convert
1626 * @returns {Uint8Array} An array of 8-bit integers.
1627 */
1628 hexToUint8Array: function (hex) {
1629 const result = new Uint8Array(hex.length >> 1);
1630 for (let k = 0; k < hex.length >> 1; k++) {
1631 result[k] = parseInt(hex.substr(k << 1, 2), 16);
1632 }
1633 return result;
1634 },
1635
1636 /**
1637 * Convert an array of 8-bit integers to a hex string
1638 * @param {Uint8Array} bytes - Array of 8-bit integers to convert
1639 * @returns {String} Hexadecimal representation of the array.
1640 */
1641 uint8ArrayToHex: function (bytes) {
1642 const r = [];
1643 const e = bytes.length;
1644 let c = 0;
1645 let h;
1646 while (c < e) {
1647 h = bytes[c++].toString(16);
1648 while (h.length < 2) {
1649 h = '0' + h;
1650 }
1651 r.push('' + h);
1652 }
1653 return r.join('');
1654 },
1655
1656 /**
1657 * Convert a string to an array of 8-bit integers
1658 * @param {String} str - String to convert
1659 * @returns {Uint8Array} An array of 8-bit integers.
1660 */
1661 stringToUint8Array: function (str) {
1662 return transform(str, str => {
1663 if (!util.isString(str)) {
1664 throw new Error('stringToUint8Array: Data must be in the form of a string');
1665 }
1666
1667 const result = new Uint8Array(str.length);
1668 for (let i = 0; i < str.length; i++) {
1669 result[i] = str.charCodeAt(i);
1670 }
1671 return result;
1672 });
1673 },
1674
1675 /**
1676 * Convert an array of 8-bit integers to a string
1677 * @param {Uint8Array} bytes - An array of 8-bit integers to convert
1678 * @returns {String} String representation of the array.
1679 */
1680 uint8ArrayToString: function (bytes) {
1681 bytes = new Uint8Array(bytes);
1682 const result = [];
1683 const bs = 1 << 14;
1684 const j = bytes.length;
1685
1686 for (let i = 0; i < j; i += bs) {
1687 result.push(String.fromCharCode.apply(String, bytes.subarray(i, i + bs < j ? i + bs : j)));
1688 }
1689 return result.join('');
1690 },
1691
1692 /**
1693 * Convert a native javascript string to a Uint8Array of utf8 bytes
1694 * @param {String|ReadableStream} str - The string to convert
1695 * @returns {Uint8Array|ReadableStream} A valid squence of utf8 bytes.
1696 */
1697 encodeUTF8: function (str) {
1698 const encoder = new TextEncoder('utf-8');
1699 // eslint-disable-next-line no-inner-declarations
1700 function process(value, lastChunk = false) {
1701 return encoder.encode(value, { stream: !lastChunk });
1702 }
1703 return transform(str, process, () => process('', true));
1704 },
1705
1706 /**
1707 * Convert a Uint8Array of utf8 bytes to a native javascript string
1708 * @param {Uint8Array|ReadableStream} utf8 - A valid squence of utf8 bytes
1709 * @returns {String|ReadableStream} A native javascript string.
1710 */
1711 decodeUTF8: function (utf8) {
1712 const decoder = new TextDecoder('utf-8');
1713 // eslint-disable-next-line no-inner-declarations
1714 function process(value, lastChunk = false) {
1715 return decoder.decode(value, { stream: !lastChunk });
1716 }
1717 return transform(utf8, process, () => process(new Uint8Array(), true));
1718 },
1719
1720 /**
1721 * Concat a list of Uint8Arrays, Strings or Streams
1722 * The caller must not mix Uint8Arrays with Strings, but may mix Streams with non-Streams.
1723 * @param {Array<Uint8Array|String|ReadableStream>} Array - Of Uint8Arrays/Strings/Streams to concatenate
1724 * @returns {Uint8Array|String|ReadableStream} Concatenated array.
1725 */
1726 concat: concat,
1727
1728 /**
1729 * Concat Uint8Arrays
1730 * @param {Array<Uint8Array>} Array - Of Uint8Arrays to concatenate
1731 * @returns {Uint8Array} Concatenated array.
1732 */
1733 concatUint8Array: concatUint8Array,
1734
1735 /**
1736 * Check Uint8Array equality
1737 * @param {Uint8Array} array1 - First array
1738 * @param {Uint8Array} array2 - Second array
1739 * @returns {Boolean} Equality.
1740 */
1741 equalsUint8Array: function (array1, array2) {
1742 if (!util.isUint8Array(array1) || !util.isUint8Array(array2)) {
1743 throw new Error('Data must be in the form of a Uint8Array');
1744 }
1745
1746 if (array1.length !== array2.length) {
1747 return false;
1748 }
1749
1750 for (let i = 0; i < array1.length; i++) {
1751 if (array1[i] !== array2[i]) {
1752 return false;
1753 }
1754 }
1755 return true;
1756 },
1757
1758 /**
1759 * Calculates a 16bit sum of a Uint8Array by adding each character
1760 * codes modulus 65535
1761 * @param {Uint8Array} Uint8Array - To create a sum of
1762 * @returns {Uint8Array} 2 bytes containing the sum of all charcodes % 65535.
1763 */
1764 writeChecksum: function (text) {
1765 let s = 0;
1766 for (let i = 0; i < text.length; i++) {
1767 s = (s + text[i]) & 0xFFFF;
1768 }
1769 return util.writeNumber(s, 2);
1770 },
1771
1772 /**
1773 * Helper function to print a debug message. Debug
1774 * messages are only printed if
1775 * @param {String} str - String of the debug message
1776 */
1777 printDebug: function (str) {
1778 if (debugMode) {
1779 console.log('[OpenPGP.js debug]', str);
1780 }
1781 },
1782
1783 /**
1784 * Helper function to print a debug error. Debug
1785 * messages are only printed if
1786 * @param {String} str - String of the debug message
1787 */
1788 printDebugError: function (error) {
1789 if (debugMode) {
1790 console.error('[OpenPGP.js debug]', error);
1791 }
1792 },
1793
1794 // returns bit length of the integer x
1795 nbits: function (x) {
1796 let r = 1;
1797 let t = x >>> 16;
1798 if (t !== 0) {
1799 x = t;
1800 r += 16;
1801 }
1802 t = x >> 8;
1803 if (t !== 0) {
1804 x = t;
1805 r += 8;
1806 }
1807 t = x >> 4;
1808 if (t !== 0) {
1809 x = t;
1810 r += 4;
1811 }
1812 t = x >> 2;
1813 if (t !== 0) {
1814 x = t;
1815 r += 2;
1816 }
1817 t = x >> 1;
1818 if (t !== 0) {
1819 x = t;
1820 r += 1;
1821 }
1822 return r;
1823 },
1824
1825 /**
1826 * If S[1] == 0, then double(S) == (S[2..128] || 0);
1827 * otherwise, double(S) == (S[2..128] || 0) xor
1828 * (zeros(120) || 10000111).
1829 *
1830 * Both OCB and EAX (through CMAC) require this function to be constant-time.
1831 *
1832 * @param {Uint8Array} data
1833 */
1834 double: function(data) {
1835 const doubleVar = new Uint8Array(data.length);
1836 const last = data.length - 1;
1837 for (let i = 0; i < last; i++) {
1838 doubleVar[i] = (data[i] << 1) ^ (data[i + 1] >> 7);
1839 }
1840 doubleVar[last] = (data[last] << 1) ^ ((data[0] >> 7) * 0x87);
1841 return doubleVar;
1842 },
1843
1844 /**
1845 * Shift a Uint8Array to the right by n bits
1846 * @param {Uint8Array} array - The array to shift
1847 * @param {Integer} bits - Amount of bits to shift (MUST be smaller
1848 * than 8)
1849 * @returns {String} Resulting array.
1850 */
1851 shiftRight: function (array, bits) {
1852 if (bits) {
1853 for (let i = array.length - 1; i >= 0; i--) {
1854 array[i] >>= bits;
1855 if (i > 0) {
1856 array[i] |= (array[i - 1] << (8 - bits));
1857 }
1858 }
1859 }
1860 return array;
1861 },
1862
1863 /**
1864 * Get native Web Cryptography api, only the current version of the spec.
1865 * @returns {Object} The SubtleCrypto api or 'undefined'.
1866 */
1867 getWebCrypto: function() {
1868 return typeof globalThis !== 'undefined' && globalThis.crypto && globalThis.crypto.subtle;
1869 },
1870
1871 /**
1872 * Detect native BigInt support
1873 */
1874 detectBigInt: () => typeof BigInt !== 'undefined',
1875
1876 /**
1877 * Get BigInteger class
1878 * It wraps the native BigInt type if it's available
1879 * Otherwise it relies on bn.js
1880 * @returns {BigInteger}
1881 * @async
1882 */
1883 getBigInteger,
1884
1885 /**
1886 * Get native Node.js crypto api.
1887 * @returns {Object} The crypto module or 'undefined'.
1888 */
1889 getNodeCrypto: function() {
1890 return crypto$3;
1891 },
1892
1893 getNodeZlib: function() {
1894 return zlib;
1895 },
1896
1897 /**
1898 * Get native Node.js Buffer constructor. This should be used since
1899 * Buffer is not available under browserify.
1900 * @returns {Function} The Buffer constructor or 'undefined'.
1901 */
1902 getNodeBuffer: function() {
1903 return (buffer || {}).Buffer;
1904 },
1905
1906 getHardwareConcurrency: function() {
1907 if (typeof navigator !== 'undefined') {
1908 return navigator.hardwareConcurrency || 1;
1909 }
1910
1911 const os$1 = os; // Assume we're on Node.js.
1912 return os$1.cpus().length;
1913 },
1914
1915 isEmailAddress: function(data) {
1916 if (!util.isString(data)) {
1917 return false;
1918 }
1919 const re = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+([a-zA-Z]{2,}|xn--[a-zA-Z\-0-9]+)))$/;
1920 return re.test(data);
1921 },
1922
1923 /**
1924 * Normalize line endings to <CR><LF>
1925 * Support any encoding where CR=0x0D, LF=0x0A
1926 */
1927 canonicalizeEOL: function(data) {
1928 const CR = 13;
1929 const LF = 10;
1930 let carryOverCR = false;
1931
1932 return transform(data, bytes => {
1933 if (carryOverCR) {
1934 bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
1935 }
1936
1937 if (bytes[bytes.length - 1] === CR) {
1938 carryOverCR = true;
1939 bytes = bytes.subarray(0, -1);
1940 } else {
1941 carryOverCR = false;
1942 }
1943
1944 let index;
1945 const indices = [];
1946 for (let i = 0; ; i = index) {
1947 index = bytes.indexOf(LF, i) + 1;
1948 if (index) {
1949 if (bytes[index - 2] !== CR) indices.push(index);
1950 } else {
1951 break;
1952 }
1953 }
1954 if (!indices.length) {
1955 return bytes;
1956 }
1957
1958 const normalized = new Uint8Array(bytes.length + indices.length);
1959 let j = 0;
1960 for (let i = 0; i < indices.length; i++) {
1961 const sub = bytes.subarray(indices[i - 1] || 0, indices[i]);
1962 normalized.set(sub, j);
1963 j += sub.length;
1964 normalized[j - 1] = CR;
1965 normalized[j] = LF;
1966 j++;
1967 }
1968 normalized.set(bytes.subarray(indices[indices.length - 1] || 0), j);
1969 return normalized;
1970 }, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
1971 },
1972
1973 /**
1974 * Convert line endings from canonicalized <CR><LF> to native <LF>
1975 * Support any encoding where CR=0x0D, LF=0x0A
1976 */
1977 nativeEOL: function(data) {
1978 const CR = 13;
1979 const LF = 10;
1980 let carryOverCR = false;
1981
1982 return transform(data, bytes => {
1983 if (carryOverCR && bytes[0] !== LF) {
1984 bytes = util.concatUint8Array([new Uint8Array([CR]), bytes]);
1985 } else {
1986 bytes = new Uint8Array(bytes); // Don't mutate passed bytes
1987 }
1988
1989 if (bytes[bytes.length - 1] === CR) {
1990 carryOverCR = true;
1991 bytes = bytes.subarray(0, -1);
1992 } else {
1993 carryOverCR = false;
1994 }
1995
1996 let index;
1997 let j = 0;
1998 for (let i = 0; i !== bytes.length; i = index) {
1999 index = bytes.indexOf(CR, i) + 1;
2000 if (!index) index = bytes.length;
2001 const last = index - (bytes[index] === LF ? 1 : 0);
2002 if (i) bytes.copyWithin(j, i, last);
2003 j += last - i;
2004 }
2005 return bytes.subarray(0, j);
2006 }, () => (carryOverCR ? new Uint8Array([CR]) : undefined));
2007 },
2008
2009 /**
2010 * Remove trailing spaces, carriage returns and tabs from each line
2011 */
2012 removeTrailingSpaces: function(text) {
2013 return text.split('\n').map(line => {
2014 let i = line.length - 1;
2015 for (; i >= 0 && (line[i] === ' ' || line[i] === '\t' || line[i] === '\r'); i--);
2016 return line.substr(0, i + 1);
2017 }).join('\n');
2018 },
2019
2020 wrapError: function(message, error) {
2021 if (!error) {
2022 return new Error(message);
2023 }
2024
2025 // update error message
2026 try {
2027 error.message = message + ': ' + error.message;
2028 } catch (e) {}
2029
2030 return error;
2031 },
2032
2033 /**
2034 * Map allowed packet tags to corresponding classes
2035 * Meant to be used to format `allowedPacket` for Packetlist.read
2036 * @param {Array<Object>} allowedClasses
2037 * @returns {Object} map from enum.packet to corresponding *Packet class
2038 */
2039 constructAllowedPackets: function(allowedClasses) {
2040 const map = {};
2041 allowedClasses.forEach(PacketClass => {
2042 if (!PacketClass.tag) {
2043 throw new Error('Invalid input: expected a packet class');
2044 }
2045 map[PacketClass.tag] = PacketClass;
2046 });
2047 return map;
2048 },
2049
2050 /**
2051 * Return a Promise that will resolve as soon as one of the promises in input resolves
2052 * or will reject if all input promises all rejected
2053 * (similar to Promise.any, but with slightly different error handling)
2054 * @param {Array<Promise>} promises
2055 * @return {Promise<Any>} Promise resolving to the result of the fastest fulfilled promise
2056 * or rejected with the Error of the last resolved Promise (if all promises are rejected)
2057 */
2058 anyPromise: function(promises) {
2059 return new Promise(async (resolve, reject) => {
2060 let exception;
2061 await Promise.all(promises.map(async promise => {
2062 try {
2063 resolve(await promise);
2064 } catch (e) {
2065 exception = e;
2066 }
2067 }));
2068 reject(exception);
2069 });
2070 },
2071
2072 /**
2073 * Return either `a` or `b` based on `cond`, in algorithmic constant time.
2074 * @param {Boolean} cond
2075 * @param {Uint8Array} a
2076 * @param {Uint8Array} b
2077 * @returns `a` if `cond` is true, `b` otherwise
2078 */
2079 selectUint8Array: function(cond, a, b) {
2080 const length = Math.max(a.length, b.length);
2081 const result = new Uint8Array(length);
2082 let end = 0;
2083 for (let i = 0; i < result.length; i++) {
2084 result[i] = (a[i] & (256 - cond)) | (b[i] & (255 + cond));
2085 end += (cond & i < a.length) | ((1 - cond) & i < b.length);
2086 }
2087 return result.subarray(0, end);
2088 },
2089 /**
2090 * Return either `a` or `b` based on `cond`, in algorithmic constant time.
2091 * NB: it only supports `a, b` with values between 0-255.
2092 * @param {Boolean} cond
2093 * @param {Uint8} a
2094 * @param {Uint8} b
2095 * @returns `a` if `cond` is true, `b` otherwise
2096 */
2097 selectUint8: function(cond, a, b) {
2098 return (a & (256 - cond)) | (b & (255 + cond));
2099 }
2100};
2101
2102/* OpenPGP radix-64/base64 string encoding/decoding
2103 * Copyright 2005 Herbert Hanewinkel, www.haneWIN.de
2104 * version 1.0, check www.haneWIN.de for the latest version
2105 *
2106 * This software is provided as-is, without express or implied warranty.
2107 * Permission to use, copy, modify, distribute or sell this software, with or
2108 * without fee, for any purpose and by any individual or organization, is hereby
2109 * granted, provided that the above copyright notice and this paragraph appear
2110 * in all copies. Distribution as a part of an application or binary must
2111 * include the above copyright notice in the documentation and/or other materials
2112 * provided with the application or distribution.
2113 */
2114
2115const Buffer = util.getNodeBuffer();
2116
2117let encodeChunk;
2118let decodeChunk;
2119if (Buffer) {
2120 encodeChunk = buf => Buffer.from(buf).toString('base64');
2121 decodeChunk = str => {
2122 const b = Buffer.from(str, 'base64');
2123 return new Uint8Array(b.buffer, b.byteOffset, b.byteLength);
2124 };
2125} else {
2126 encodeChunk = buf => btoa(util.uint8ArrayToString(buf));
2127 decodeChunk = str => util.stringToUint8Array(atob(str));
2128}
2129
2130/**
2131 * Convert binary array to radix-64
2132 * @param {Uint8Array | ReadableStream<Uint8Array>} data - Uint8Array to convert
2133 * @returns {String | ReadableStream<String>} Radix-64 version of input string.
2134 * @static
2135 */
2136function encode(data) {
2137 let buf = new Uint8Array();
2138 return transform(data, value => {
2139 buf = util.concatUint8Array([buf, value]);
2140 const r = [];
2141 const bytesPerLine = 45; // 60 chars per line * (3 bytes / 4 chars of base64).
2142 const lines = Math.floor(buf.length / bytesPerLine);
2143 const bytes = lines * bytesPerLine;
2144 const encoded = encodeChunk(buf.subarray(0, bytes));
2145 for (let i = 0; i < lines; i++) {
2146 r.push(encoded.substr(i * 60, 60));
2147 r.push('\n');
2148 }
2149 buf = buf.subarray(bytes);
2150 return r.join('');
2151 }, () => (buf.length ? encodeChunk(buf) + '\n' : ''));
2152}
2153
2154/**
2155 * Convert radix-64 to binary array
2156 * @param {String | ReadableStream<String>} data - Radix-64 string to convert
2157 * @returns {Uint8Array | ReadableStream<Uint8Array>} Binary array version of input string.
2158 * @static
2159 */
2160function decode(data) {
2161 let buf = '';
2162 return transform(data, value => {
2163 buf += value;
2164
2165 // Count how many whitespace characters there are in buf
2166 let spaces = 0;
2167 const spacechars = [' ', '\t', '\r', '\n'];
2168 for (let i = 0; i < spacechars.length; i++) {
2169 const spacechar = spacechars[i];
2170 for (let pos = buf.indexOf(spacechar); pos !== -1; pos = buf.indexOf(spacechar, pos + 1)) {
2171 spaces++;
2172 }
2173 }
2174
2175 // Backtrack until we have 4n non-whitespace characters
2176 // that we can safely base64-decode
2177 let length = buf.length;
2178 for (; length > 0 && (length - spaces) % 4 !== 0; length--) {
2179 if (spacechars.includes(buf[length])) spaces--;
2180 }
2181
2182 const decoded = decodeChunk(buf.substr(0, length));
2183 buf = buf.substr(length);
2184 return decoded;
2185 }, () => decodeChunk(buf));
2186}
2187
2188/**
2189 * Convert a Base-64 encoded string an array of 8-bit integer
2190 *
2191 * Note: accepts both Radix-64 and URL-safe strings
2192 * @param {String} base64 - Base-64 encoded string to convert
2193 * @returns {Uint8Array} An array of 8-bit integers.
2194 */
2195function b64ToUint8Array(base64) {
2196 return decode(base64.replace(/-/g, '+').replace(/_/g, '/'));
2197}
2198
2199/**
2200 * Convert an array of 8-bit integer to a Base-64 encoded string
2201 * @param {Uint8Array} bytes - An array of 8-bit integers to convert
2202 * @param {bool} url - If true, output is URL-safe
2203 * @returns {String} Base-64 encoded string.
2204 */
2205function uint8ArrayToB64(bytes, url) {
2206 let encoded = encode(bytes).replace(/[\r\n]/g, '');
2207 if (url) {
2208 encoded = encoded.replace(/[+]/g, '-').replace(/[/]/g, '_').replace(/[=]/g, '');
2209 }
2210 return encoded;
2211}
2212
2213/**
2214 * @module enums
2215 */
2216
2217const byValue = Symbol('byValue');
2218
2219var enums = {
2220
2221 /** Maps curve names under various standards to one
2222 * @see {@link https://wiki.gnupg.org/ECC|ECC - GnuPG wiki}
2223 * @enum {String}
2224 * @readonly
2225 */
2226 curve: {
2227 /** NIST P-256 Curve */
2228 'p256': 'p256',
2229 'P-256': 'p256',
2230 'secp256r1': 'p256',
2231 'prime256v1': 'p256',
2232 '1.2.840.10045.3.1.7': 'p256',
2233 '2a8648ce3d030107': 'p256',
2234 '2A8648CE3D030107': 'p256',
2235
2236 /** NIST P-384 Curve */
2237 'p384': 'p384',
2238 'P-384': 'p384',
2239 'secp384r1': 'p384',
2240 '1.3.132.0.34': 'p384',
2241 '2b81040022': 'p384',
2242 '2B81040022': 'p384',
2243
2244 /** NIST P-521 Curve */
2245 'p521': 'p521',
2246 'P-521': 'p521',
2247 'secp521r1': 'p521',
2248 '1.3.132.0.35': 'p521',
2249 '2b81040023': 'p521',
2250 '2B81040023': 'p521',
2251
2252 /** SECG SECP256k1 Curve */
2253 'secp256k1': 'secp256k1',
2254 '1.3.132.0.10': 'secp256k1',
2255 '2b8104000a': 'secp256k1',
2256 '2B8104000A': 'secp256k1',
2257
2258 /** Ed25519 */
2259 'ED25519': 'ed25519',
2260 'ed25519': 'ed25519',
2261 'Ed25519': 'ed25519',
2262 '1.3.6.1.4.1.11591.15.1': 'ed25519',
2263 '2b06010401da470f01': 'ed25519',
2264 '2B06010401DA470F01': 'ed25519',
2265
2266 /** Curve25519 */
2267 'X25519': 'curve25519',
2268 'cv25519': 'curve25519',
2269 'curve25519': 'curve25519',
2270 'Curve25519': 'curve25519',
2271 '1.3.6.1.4.1.3029.1.5.1': 'curve25519',
2272 '2b060104019755010501': 'curve25519',
2273 '2B060104019755010501': 'curve25519',
2274
2275 /** BrainpoolP256r1 Curve */
2276 'brainpoolP256r1': 'brainpoolP256r1',
2277 '1.3.36.3.3.2.8.1.1.7': 'brainpoolP256r1',
2278 '2b2403030208010107': 'brainpoolP256r1',
2279 '2B2403030208010107': 'brainpoolP256r1',
2280
2281 /** BrainpoolP384r1 Curve */
2282 'brainpoolP384r1': 'brainpoolP384r1',
2283 '1.3.36.3.3.2.8.1.1.11': 'brainpoolP384r1',
2284 '2b240303020801010b': 'brainpoolP384r1',
2285 '2B240303020801010B': 'brainpoolP384r1',
2286
2287 /** BrainpoolP512r1 Curve */
2288 'brainpoolP512r1': 'brainpoolP512r1',
2289 '1.3.36.3.3.2.8.1.1.13': 'brainpoolP512r1',
2290 '2b240303020801010d': 'brainpoolP512r1',
2291 '2B240303020801010D': 'brainpoolP512r1'
2292 },
2293
2294 /** A string to key specifier type
2295 * @enum {Integer}
2296 * @readonly
2297 */
2298 s2k: {
2299 simple: 0,
2300 salted: 1,
2301 iterated: 3,
2302 gnu: 101
2303 },
2304
2305 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.1|RFC4880bis-04, section 9.1}
2306 * @enum {Integer}
2307 * @readonly
2308 */
2309 publicKey: {
2310 /** RSA (Encrypt or Sign) [HAC] */
2311 rsaEncryptSign: 1,
2312 /** RSA (Encrypt only) [HAC] */
2313 rsaEncrypt: 2,
2314 /** RSA (Sign only) [HAC] */
2315 rsaSign: 3,
2316 /** Elgamal (Encrypt only) [ELGAMAL] [HAC] */
2317 elgamal: 16,
2318 /** DSA (Sign only) [FIPS186] [HAC] */
2319 dsa: 17,
2320 /** ECDH (Encrypt only) [RFC6637] */
2321 ecdh: 18,
2322 /** ECDSA (Sign only) [RFC6637] */
2323 ecdsa: 19,
2324 /** EdDSA (Sign only)
2325 * [{@link https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04|Draft RFC}] */
2326 eddsa: 22,
2327 /** Reserved for AEDH */
2328 aedh: 23,
2329 /** Reserved for AEDSA */
2330 aedsa: 24
2331 },
2332
2333 /** {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC4880, section 9.2}
2334 * @enum {Integer}
2335 * @readonly
2336 */
2337 symmetric: {
2338 plaintext: 0,
2339 /** Not implemented! */
2340 idea: 1,
2341 tripledes: 2,
2342 cast5: 3,
2343 blowfish: 4,
2344 aes128: 7,
2345 aes192: 8,
2346 aes256: 9,
2347 twofish: 10
2348 },
2349
2350 /** {@link https://tools.ietf.org/html/rfc4880#section-9.3|RFC4880, section 9.3}
2351 * @enum {Integer}
2352 * @readonly
2353 */
2354 compression: {
2355 uncompressed: 0,
2356 /** RFC1951 */
2357 zip: 1,
2358 /** RFC1950 */
2359 zlib: 2,
2360 bzip2: 3
2361 },
2362
2363 /** {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880, section 9.4}
2364 * @enum {Integer}
2365 * @readonly
2366 */
2367 hash: {
2368 md5: 1,
2369 sha1: 2,
2370 ripemd: 3,
2371 sha256: 8,
2372 sha384: 9,
2373 sha512: 10,
2374 sha224: 11
2375 },
2376
2377 /** A list of hash names as accepted by webCrypto functions.
2378 * {@link https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest|Parameters, algo}
2379 * @enum {String}
2380 */
2381 webHash: {
2382 'SHA-1': 2,
2383 'SHA-256': 8,
2384 'SHA-384': 9,
2385 'SHA-512': 10
2386 },
2387
2388 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-9.6|RFC4880bis-04, section 9.6}
2389 * @enum {Integer}
2390 * @readonly
2391 */
2392 aead: {
2393 eax: 1,
2394 ocb: 2,
2395 experimentalGCM: 100 // Private algorithm
2396 },
2397
2398 /** A list of packet types and numeric tags associated with them.
2399 * @enum {Integer}
2400 * @readonly
2401 */
2402 packet: {
2403 publicKeyEncryptedSessionKey: 1,
2404 signature: 2,
2405 symEncryptedSessionKey: 3,
2406 onePassSignature: 4,
2407 secretKey: 5,
2408 publicKey: 6,
2409 secretSubkey: 7,
2410 compressedData: 8,
2411 symmetricallyEncryptedData: 9,
2412 marker: 10,
2413 literalData: 11,
2414 trust: 12,
2415 userID: 13,
2416 publicSubkey: 14,
2417 userAttribute: 17,
2418 symEncryptedIntegrityProtectedData: 18,
2419 modificationDetectionCode: 19,
2420 aeadEncryptedData: 20 // see IETF draft: https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1
2421 },
2422
2423 /** Data types in the literal packet
2424 * @enum {Integer}
2425 * @readonly
2426 */
2427 literal: {
2428 /** Binary data 'b' */
2429 binary: 'b'.charCodeAt(),
2430 /** Text data 't' */
2431 text: 't'.charCodeAt(),
2432 /** Utf8 data 'u' */
2433 utf8: 'u'.charCodeAt(),
2434 /** MIME message body part 'm' */
2435 mime: 'm'.charCodeAt()
2436 },
2437
2438
2439 /** One pass signature packet type
2440 * @enum {Integer}
2441 * @readonly
2442 */
2443 signature: {
2444 /** 0x00: Signature of a binary document. */
2445 binary: 0,
2446 /** 0x01: Signature of a canonical text document.
2447 *
2448 * Canonicalyzing the document by converting line endings. */
2449 text: 1,
2450 /** 0x02: Standalone signature.
2451 *
2452 * This signature is a signature of only its own subpacket contents.
2453 * It is calculated identically to a signature over a zero-lengh
2454 * binary document. Note that it doesn't make sense to have a V3
2455 * standalone signature. */
2456 standalone: 2,
2457 /** 0x10: Generic certification of a User ID and Public-Key packet.
2458 *
2459 * The issuer of this certification does not make any particular
2460 * assertion as to how well the certifier has checked that the owner
2461 * of the key is in fact the person described by the User ID. */
2462 certGeneric: 16,
2463 /** 0x11: Persona certification of a User ID and Public-Key packet.
2464 *
2465 * The issuer of this certification has not done any verification of
2466 * the claim that the owner of this key is the User ID specified. */
2467 certPersona: 17,
2468 /** 0x12: Casual certification of a User ID and Public-Key packet.
2469 *
2470 * The issuer of this certification has done some casual
2471 * verification of the claim of identity. */
2472 certCasual: 18,
2473 /** 0x13: Positive certification of a User ID and Public-Key packet.
2474 *
2475 * The issuer of this certification has done substantial
2476 * verification of the claim of identity.
2477 *
2478 * Most OpenPGP implementations make their "key signatures" as 0x10
2479 * certifications. Some implementations can issue 0x11-0x13
2480 * certifications, but few differentiate between the types. */
2481 certPositive: 19,
2482 /** 0x30: Certification revocation signature
2483 *
2484 * This signature revokes an earlier User ID certification signature
2485 * (signature class 0x10 through 0x13) or direct-key signature
2486 * (0x1F). It should be issued by the same key that issued the
2487 * revoked signature or an authorized revocation key. The signature
2488 * is computed over the same data as the certificate that it
2489 * revokes, and should have a later creation date than that
2490 * certificate. */
2491 certRevocation: 48,
2492 /** 0x18: Subkey Binding Signature
2493 *
2494 * This signature is a statement by the top-level signing key that
2495 * indicates that it owns the subkey. This signature is calculated
2496 * directly on the primary key and subkey, and not on any User ID or
2497 * other packets. A signature that binds a signing subkey MUST have
2498 * an Embedded Signature subpacket in this binding signature that
2499 * contains a 0x19 signature made by the signing subkey on the
2500 * primary key and subkey. */
2501 subkeyBinding: 24,
2502 /** 0x19: Primary Key Binding Signature
2503 *
2504 * This signature is a statement by a signing subkey, indicating
2505 * that it is owned by the primary key and subkey. This signature
2506 * is calculated the same way as a 0x18 signature: directly on the
2507 * primary key and subkey, and not on any User ID or other packets.
2508 *
2509 * When a signature is made over a key, the hash data starts with the
2510 * octet 0x99, followed by a two-octet length of the key, and then body
2511 * of the key packet. (Note that this is an old-style packet header for
2512 * a key packet with two-octet length.) A subkey binding signature
2513 * (type 0x18) or primary key binding signature (type 0x19) then hashes
2514 * the subkey using the same format as the main key (also using 0x99 as
2515 * the first octet). */
2516 keyBinding: 25,
2517 /** 0x1F: Signature directly on a key
2518 *
2519 * This signature is calculated directly on a key. It binds the
2520 * information in the Signature subpackets to the key, and is
2521 * appropriate to be used for subpackets that provide information
2522 * about the key, such as the Revocation Key subpacket. It is also
2523 * appropriate for statements that non-self certifiers want to make
2524 * about the key itself, rather than the binding between a key and a
2525 * name. */
2526 key: 31,
2527 /** 0x20: Key revocation signature
2528 *
2529 * The signature is calculated directly on the key being revoked. A
2530 * revoked key is not to be used. Only revocation signatures by the
2531 * key being revoked, or by an authorized revocation key, should be
2532 * considered valid revocation signatures.a */
2533 keyRevocation: 32,
2534 /** 0x28: Subkey revocation signature
2535 *
2536 * The signature is calculated directly on the subkey being revoked.
2537 * A revoked subkey is not to be used. Only revocation signatures
2538 * by the top-level signature key that is bound to this subkey, or
2539 * by an authorized revocation key, should be considered valid
2540 * revocation signatures.
2541 *
2542 * Key revocation signatures (types 0x20 and 0x28)
2543 * hash only the key being revoked. */
2544 subkeyRevocation: 40,
2545 /** 0x40: Timestamp signature.
2546 * This signature is only meaningful for the timestamp contained in
2547 * it. */
2548 timestamp: 64,
2549 /** 0x50: Third-Party Confirmation signature.
2550 *
2551 * This signature is a signature over some other OpenPGP Signature
2552 * packet(s). It is analogous to a notary seal on the signed data.
2553 * A third-party signature SHOULD include Signature Target
2554 * subpacket(s) to give easy identification. Note that we really do
2555 * mean SHOULD. There are plausible uses for this (such as a blind
2556 * party that only sees the signature, not the key or source
2557 * document) that cannot include a target subpacket. */
2558 thirdParty: 80
2559 },
2560
2561 /** Signature subpacket type
2562 * @enum {Integer}
2563 * @readonly
2564 */
2565 signatureSubpacket: {
2566 signatureCreationTime: 2,
2567 signatureExpirationTime: 3,
2568 exportableCertification: 4,
2569 trustSignature: 5,
2570 regularExpression: 6,
2571 revocable: 7,
2572 keyExpirationTime: 9,
2573 placeholderBackwardsCompatibility: 10,
2574 preferredSymmetricAlgorithms: 11,
2575 revocationKey: 12,
2576 issuer: 16,
2577 notationData: 20,
2578 preferredHashAlgorithms: 21,
2579 preferredCompressionAlgorithms: 22,
2580 keyServerPreferences: 23,
2581 preferredKeyServer: 24,
2582 primaryUserID: 25,
2583 policyURI: 26,
2584 keyFlags: 27,
2585 signersUserID: 28,
2586 reasonForRevocation: 29,
2587 features: 30,
2588 signatureTarget: 31,
2589 embeddedSignature: 32,
2590 issuerFingerprint: 33,
2591 preferredAEADAlgorithms: 34
2592 },
2593
2594 /** Key flags
2595 * @enum {Integer}
2596 * @readonly
2597 */
2598 keyFlags: {
2599 /** 0x01 - This key may be used to certify other keys. */
2600 certifyKeys: 1,
2601 /** 0x02 - This key may be used to sign data. */
2602 signData: 2,
2603 /** 0x04 - This key may be used to encrypt communications. */
2604 encryptCommunication: 4,
2605 /** 0x08 - This key may be used to encrypt storage. */
2606 encryptStorage: 8,
2607 /** 0x10 - The private component of this key may have been split
2608 * by a secret-sharing mechanism. */
2609 splitPrivateKey: 16,
2610 /** 0x20 - This key may be used for authentication. */
2611 authentication: 32,
2612 /** 0x80 - The private component of this key may be in the
2613 * possession of more than one person. */
2614 sharedPrivateKey: 128
2615 },
2616
2617 /** Armor type
2618 * @enum {Integer}
2619 * @readonly
2620 */
2621 armor: {
2622 multipartSection: 0,
2623 multipartLast: 1,
2624 signed: 2,
2625 message: 3,
2626 publicKey: 4,
2627 privateKey: 5,
2628 signature: 6
2629 },
2630
2631 /** {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.23|RFC4880, section 5.2.3.23}
2632 * @enum {Integer}
2633 * @readonly
2634 */
2635 reasonForRevocation: {
2636 /** No reason specified (key revocations or cert revocations) */
2637 noReason: 0,
2638 /** Key is superseded (key revocations) */
2639 keySuperseded: 1,
2640 /** Key material has been compromised (key revocations) */
2641 keyCompromised: 2,
2642 /** Key is retired and no longer used (key revocations) */
2643 keyRetired: 3,
2644 /** User ID information is no longer valid (cert revocations) */
2645 userIDInvalid: 32
2646 },
2647
2648 /** {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.2.3.25|RFC4880bis-04, section 5.2.3.25}
2649 * @enum {Integer}
2650 * @readonly
2651 */
2652 features: {
2653 /** 0x01 - Modification Detection (packets 18 and 19) */
2654 modificationDetection: 1,
2655 /** 0x02 - AEAD Encrypted Data Packet (packet 20) and version 5
2656 * Symmetric-Key Encrypted Session Key Packets (packet 3) */
2657 aead: 2,
2658 /** 0x04 - Version 5 Public-Key Packet format and corresponding new
2659 * fingerprint format */
2660 v5Keys: 4
2661 },
2662
2663 /**
2664 * Asserts validity of given value and converts from string/integer to integer.
2665 * @param {Object} type target enum type
2666 * @param {String|Integer} e value to check and/or convert
2667 * @returns {Integer} enum value if it exists
2668 * @throws {Error} if the value is invalid
2669 */
2670 write: function(type, e) {
2671 if (typeof e === 'number') {
2672 e = this.read(type, e);
2673 }
2674
2675 if (type[e] !== undefined) {
2676 return type[e];
2677 }
2678
2679 throw new Error('Invalid enum value.');
2680 },
2681
2682 /**
2683 * Converts enum integer value to the corresponding string, if it exists.
2684 * @param {Object} type target enum type
2685 * @param {Integer} e value to convert
2686 * @returns {String} name of enum value if it exists
2687 * @throws {Error} if the value is invalid
2688 */
2689 read: function(type, e) {
2690 if (!type[byValue]) {
2691 type[byValue] = [];
2692 Object.entries(type).forEach(([key, value]) => {
2693 type[byValue][value] = key;
2694 });
2695 }
2696
2697 if (type[byValue][e] !== undefined) {
2698 return type[byValue][e];
2699 }
2700
2701 throw new Error('Invalid enum value.');
2702 }
2703};
2704
2705// GPG4Browsers - An OpenPGP implementation in javascript
2706
2707var defaultConfig = {
2708 /**
2709 * @memberof module:config
2710 * @property {Integer} preferredHashAlgorithm Default hash algorithm {@link module:enums.hash}
2711 */
2712 preferredHashAlgorithm: enums.hash.sha256,
2713 /**
2714 * @memberof module:config
2715 * @property {Integer} preferredSymmetricAlgorithm Default encryption cipher {@link module:enums.symmetric}
2716 */
2717 preferredSymmetricAlgorithm: enums.symmetric.aes256,
2718 /**
2719 * @memberof module:config
2720 * @property {Integer} compression Default compression algorithm {@link module:enums.compression}
2721 */
2722 preferredCompressionAlgorithm: enums.compression.uncompressed,
2723 /**
2724 * @memberof module:config
2725 * @property {Integer} deflateLevel Default zip/zlib compression level, between 1 and 9
2726 */
2727 deflateLevel: 6,
2728
2729 /**
2730 * Use Authenticated Encryption with Additional Data (AEAD) protection for symmetric encryption.
2731 * Note: not all OpenPGP implementations are compatible with this option.
2732 * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION**
2733 * @see {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-07|RFC4880bis-07}
2734 * @memberof module:config
2735 * @property {Boolean} aeadProtect
2736 */
2737 aeadProtect: false,
2738 /**
2739 * Default Authenticated Encryption with Additional Data (AEAD) encryption mode
2740 * Only has an effect when aeadProtect is set to true.
2741 * @memberof module:config
2742 * @property {Integer} preferredAEADAlgorithm Default AEAD mode {@link module:enums.aead}
2743 */
2744 preferredAEADAlgorithm: enums.aead.eax,
2745 /**
2746 * Chunk Size Byte for Authenticated Encryption with Additional Data (AEAD) mode
2747 * Only has an effect when aeadProtect is set to true.
2748 * Must be an integer value from 0 to 56.
2749 * @memberof module:config
2750 * @property {Integer} aeadChunkSizeByte
2751 */
2752 aeadChunkSizeByte: 12,
2753 /**
2754 * Use V5 keys.
2755 * Note: not all OpenPGP implementations are compatible with this option.
2756 * **FUTURE OPENPGP.JS VERSIONS MAY BREAK COMPATIBILITY WHEN USING THIS OPTION**
2757 * @memberof module:config
2758 * @property {Boolean} v5Keys
2759 */
2760 v5Keys: false,
2761 /**
2762 * {@link https://tools.ietf.org/html/rfc4880#section-3.7.1.3|RFC4880 3.7.1.3}:
2763 * Iteration Count Byte for S2K (String to Key)
2764 * @memberof module:config
2765 * @property {Integer} s2kIterationCountByte
2766 */
2767 s2kIterationCountByte: 224,
2768 /**
2769 * Allow decryption of messages without integrity protection.
2770 * This is an **insecure** setting:
2771 * - message modifications cannot be detected, thus processing the decrypted data is potentially unsafe.
2772 * - it enables downgrade attacks against integrity-protected messages.
2773 * @memberof module:config
2774 * @property {Boolean} allowUnauthenticatedMessages
2775 */
2776 allowUnauthenticatedMessages: false,
2777 /**
2778 * Allow streaming unauthenticated data before its integrity has been checked. This would allow the application to
2779 * process large streams while limiting memory usage by releasing the decrypted chunks as soon as possible
2780 * and deferring checking their integrity until the decrypted stream has been read in full.
2781 *
2782 * This setting is **insecure** if the partially decrypted message is processed further or displayed to the user.
2783 * @memberof module:config
2784 * @property {Boolean} allowUnauthenticatedStream
2785 */
2786 allowUnauthenticatedStream: false,
2787 /**
2788 * @memberof module:config
2789 * @property {Boolean} checksumRequired Do not throw error when armor is missing a checksum
2790 */
2791 checksumRequired: false,
2792 /**
2793 * Minimum RSA key size allowed for key generation and message signing, verification and encryption.
2794 * The default is 2047 since due to a bug, previous versions of OpenPGP.js could generate 2047-bit keys instead of 2048-bit ones.
2795 * @memberof module:config
2796 * @property {Number} minRSABits
2797 */
2798 minRSABits: 2047,
2799 /**
2800 * Work-around for rare GPG decryption bug when encrypting with multiple passwords.
2801 * **Slower and slightly less secure**
2802 * @memberof module:config
2803 * @property {Boolean} passwordCollisionCheck
2804 */
2805 passwordCollisionCheck: false,
2806 /**
2807 * @memberof module:config
2808 * @property {Boolean} revocationsExpire If true, expired revocation signatures are ignored
2809 */
2810 revocationsExpire: false,
2811 /**
2812 * Allow decryption using RSA keys without `encrypt` flag.
2813 * This setting is potentially insecure, but it is needed to get around an old openpgpjs bug
2814 * where key flags were ignored when selecting a key for encryption.
2815 * @memberof module:config
2816 * @property {Boolean} allowInsecureDecryptionWithSigningKeys
2817 */
2818 allowInsecureDecryptionWithSigningKeys: false,
2819 /**
2820 * Allow verification of message signatures with keys whose validity at the time of signing cannot be determined.
2821 * Instead, a verification key will also be consider valid as long as it is valid at the current time.
2822 * This setting is potentially insecure, but it is needed to verify messages signed with keys that were later reformatted,
2823 * and have self-signature's creation date that does not match the primary key creation date.
2824 * @memberof module:config
2825 * @property {Boolean} allowInsecureDecryptionWithSigningKeys
2826 */
2827 allowInsecureVerificationWithReformattedKeys: false,
2828
2829 /**
2830 * Enable constant-time decryption of RSA- and ElGamal-encrypted session keys, to hinder Bleichenbacher-like attacks (https://link.springer.com/chapter/10.1007/BFb0055716).
2831 * This setting has measurable performance impact and it is only helpful in application scenarios where both of the following conditions apply:
2832 * - new/incoming messages are automatically decrypted (without user interaction);
2833 * - an attacker can determine how long it takes to decrypt each message (e.g. due to decryption errors being logged remotely).
2834 * See also `constantTimePKCS1DecryptionSupportedSymmetricAlgorithms`.
2835 * @memberof module:config
2836 * @property {Boolean} constantTimePKCS1Decryption
2837 */
2838 constantTimePKCS1Decryption: false,
2839 /**
2840 * This setting is only meaningful if `constantTimePKCS1Decryption` is enabled.
2841 * Decryption of RSA- and ElGamal-encrypted session keys of symmetric algorithms different from the ones specified here will fail.
2842 * However, the more algorithms are added, the slower the decryption procedure becomes.
2843 * @memberof module:config
2844 * @property {Set<Integer>} constantTimePKCS1DecryptionSupportedSymmetricAlgorithms {@link module:enums.symmetric}
2845 */
2846 constantTimePKCS1DecryptionSupportedSymmetricAlgorithms: new Set([enums.symmetric.aes128, enums.symmetric.aes192, enums.symmetric.aes256]),
2847
2848 /**
2849 * @memberof module:config
2850 * @property {Integer} minBytesForWebCrypto The minimum amount of bytes for which to use native WebCrypto APIs when available
2851 */
2852 minBytesForWebCrypto: 1000,
2853 /**
2854 * @memberof module:config
2855 * @property {Boolean} ignoreUnsupportedPackets Ignore unsupported/unrecognizable packets on parsing instead of throwing an error
2856 */
2857 ignoreUnsupportedPackets: true,
2858 /**
2859 * @memberof module:config
2860 * @property {Boolean} ignoreMalformedPackets Ignore malformed packets on parsing instead of throwing an error
2861 */
2862 ignoreMalformedPackets: false,
2863 /**
2864 * @memberof module:config
2865 * @property {Boolean} showVersion Whether to include {@link module:config/config.versionString} in armored messages
2866 */
2867 showVersion: false,
2868 /**
2869 * @memberof module:config
2870 * @property {Boolean} showComment Whether to include {@link module:config/config.commentString} in armored messages
2871 */
2872 showComment: false,
2873 /**
2874 * @memberof module:config
2875 * @property {String} versionString A version string to be included in armored messages
2876 */
2877 versionString: 'OpenPGP.js 5.5.0',
2878 /**
2879 * @memberof module:config
2880 * @property {String} commentString A comment string to be included in armored messages
2881 */
2882 commentString: 'https://openpgpjs.org',
2883
2884 /**
2885 * Max userID string length (used for parsing)
2886 * @memberof module:config
2887 * @property {Integer} maxUserIDLength
2888 */
2889 maxUserIDLength: 1024 * 5,
2890 /**
2891 * Contains notatations that are considered "known". Known notations do not trigger
2892 * validation error when the notation is marked as critical.
2893 * @memberof module:config
2894 * @property {Array} knownNotations
2895 */
2896 knownNotations: ['preferred-email-encoding@pgp.com', 'pka-address@gnupg.org'],
2897 /**
2898 * Whether to use the indutny/elliptic library for curves (other than Curve25519) that are not supported by the available native crypto API.
2899 * When false, certain standard curves will not be supported (depending on the platform).
2900 * Note: the indutny/elliptic curve library is not designed to be constant time.
2901 * @memberof module:config
2902 * @property {Boolean} useIndutnyElliptic
2903 */
2904 useIndutnyElliptic: true,
2905 /**
2906 * Reject insecure hash algorithms
2907 * @memberof module:config
2908 * @property {Set<Integer>} rejectHashAlgorithms {@link module:enums.hash}
2909 */
2910 rejectHashAlgorithms: new Set([enums.hash.md5, enums.hash.ripemd]),
2911 /**
2912 * Reject insecure message hash algorithms
2913 * @memberof module:config
2914 * @property {Set<Integer>} rejectMessageHashAlgorithms {@link module:enums.hash}
2915 */
2916 rejectMessageHashAlgorithms: new Set([enums.hash.md5, enums.hash.ripemd, enums.hash.sha1]),
2917 /**
2918 * Reject insecure public key algorithms for key generation and message encryption, signing or verification
2919 * @memberof module:config
2920 * @property {Set<Integer>} rejectPublicKeyAlgorithms {@link module:enums.publicKey}
2921 */
2922 rejectPublicKeyAlgorithms: new Set([enums.publicKey.elgamal, enums.publicKey.dsa]),
2923 /**
2924 * Reject non-standard curves for key generation, message encryption, signing or verification
2925 * @memberof module:config
2926 * @property {Set<String>} rejectCurves {@link module:enums.curve}
2927 */
2928 rejectCurves: new Set([enums.curve.brainpoolP256r1, enums.curve.brainpoolP384r1, enums.curve.brainpoolP512r1, enums.curve.secp256k1])
2929};
2930
2931// GPG4Browsers - An OpenPGP implementation in javascript
2932
2933/**
2934 * Finds out which Ascii Armoring type is used. Throws error if unknown type.
2935 * @param {String} text - ascii armored text
2936 * @returns {Integer} 0 = MESSAGE PART n of m.
2937 * 1 = MESSAGE PART n
2938 * 2 = SIGNED MESSAGE
2939 * 3 = PGP MESSAGE
2940 * 4 = PUBLIC KEY BLOCK
2941 * 5 = PRIVATE KEY BLOCK
2942 * 6 = SIGNATURE
2943 * @private
2944 */
2945function getType(text) {
2946 const reHeader = /^-----BEGIN PGP (MESSAGE, PART \d+\/\d+|MESSAGE, PART \d+|SIGNED MESSAGE|MESSAGE|PUBLIC KEY BLOCK|PRIVATE KEY BLOCK|SIGNATURE)-----$/m;
2947
2948 const header = text.match(reHeader);
2949
2950 if (!header) {
2951 throw new Error('Unknown ASCII armor type');
2952 }
2953
2954 // BEGIN PGP MESSAGE, PART X/Y
2955 // Used for multi-part messages, where the armor is split amongst Y
2956 // parts, and this is the Xth part out of Y.
2957 if (/MESSAGE, PART \d+\/\d+/.test(header[1])) {
2958 return enums.armor.multipartSection;
2959 } else
2960 // BEGIN PGP MESSAGE, PART X
2961 // Used for multi-part messages, where this is the Xth part of an
2962 // unspecified number of parts. Requires the MESSAGE-ID Armor
2963 // Header to be used.
2964 if (/MESSAGE, PART \d+/.test(header[1])) {
2965 return enums.armor.multipartLast;
2966 } else
2967 // BEGIN PGP SIGNED MESSAGE
2968 if (/SIGNED MESSAGE/.test(header[1])) {
2969 return enums.armor.signed;
2970 } else
2971 // BEGIN PGP MESSAGE
2972 // Used for signed, encrypted, or compressed files.
2973 if (/MESSAGE/.test(header[1])) {
2974 return enums.armor.message;
2975 } else
2976 // BEGIN PGP PUBLIC KEY BLOCK
2977 // Used for armoring public keys.
2978 if (/PUBLIC KEY BLOCK/.test(header[1])) {
2979 return enums.armor.publicKey;
2980 } else
2981 // BEGIN PGP PRIVATE KEY BLOCK
2982 // Used for armoring private keys.
2983 if (/PRIVATE KEY BLOCK/.test(header[1])) {
2984 return enums.armor.privateKey;
2985 } else
2986 // BEGIN PGP SIGNATURE
2987 // Used for detached signatures, OpenPGP/MIME signatures, and
2988 // cleartext signatures. Note that PGP 2.x uses BEGIN PGP MESSAGE
2989 // for detached signatures.
2990 if (/SIGNATURE/.test(header[1])) {
2991 return enums.armor.signature;
2992 }
2993}
2994
2995/**
2996 * Add additional information to the armor version of an OpenPGP binary
2997 * packet block.
2998 * @author Alex
2999 * @version 2011-12-16
3000 * @param {String} [customComment] - Additional comment to add to the armored string
3001 * @returns {String} The header information.
3002 * @private
3003 */
3004function addheader(customComment, config) {
3005 let result = '';
3006 if (config.showVersion) {
3007 result += 'Version: ' + config.versionString + '\n';
3008 }
3009 if (config.showComment) {
3010 result += 'Comment: ' + config.commentString + '\n';
3011 }
3012 if (customComment) {
3013 result += 'Comment: ' + customComment + '\n';
3014 }
3015 result += '\n';
3016 return result;
3017}
3018
3019
3020/**
3021 * Calculates a checksum over the given data and returns it base64 encoded
3022 * @param {String | ReadableStream<String>} data - Data to create a CRC-24 checksum for
3023 * @returns {String | ReadableStream<String>} Base64 encoded checksum.
3024 * @private
3025 */
3026function getCheckSum(data) {
3027 const crc = createcrc24(data);
3028 return encode(crc);
3029}
3030
3031// https://create.stephan-brumme.com/crc32/#slicing-by-8-overview
3032
3033const crc_table = [
3034 new Array(0xFF),
3035 new Array(0xFF),
3036 new Array(0xFF),
3037 new Array(0xFF)
3038];
3039
3040for (let i = 0; i <= 0xFF; i++) {
3041 let crc = i << 16;
3042 for (let j = 0; j < 8; j++) {
3043 crc = (crc << 1) ^ ((crc & 0x800000) !== 0 ? 0x864CFB : 0);
3044 }
3045 crc_table[0][i] =
3046 ((crc & 0xFF0000) >> 16) |
3047 (crc & 0x00FF00) |
3048 ((crc & 0x0000FF) << 16);
3049}
3050for (let i = 0; i <= 0xFF; i++) {
3051 crc_table[1][i] = (crc_table[0][i] >> 8) ^ crc_table[0][crc_table[0][i] & 0xFF];
3052}
3053for (let i = 0; i <= 0xFF; i++) {
3054 crc_table[2][i] = (crc_table[1][i] >> 8) ^ crc_table[0][crc_table[1][i] & 0xFF];
3055}
3056for (let i = 0; i <= 0xFF; i++) {
3057 crc_table[3][i] = (crc_table[2][i] >> 8) ^ crc_table[0][crc_table[2][i] & 0xFF];
3058}
3059
3060// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness
3061const isLittleEndian = (function() {
3062 const buffer = new ArrayBuffer(2);
3063 new DataView(buffer).setInt16(0, 0xFF, true /* littleEndian */);
3064 // Int16Array uses the platform's endianness.
3065 return new Int16Array(buffer)[0] === 0xFF;
3066}());
3067
3068/**
3069 * Internal function to calculate a CRC-24 checksum over a given string (data)
3070 * @param {String | ReadableStream<String>} input - Data to create a CRC-24 checksum for
3071 * @returns {Uint8Array | ReadableStream<Uint8Array>} The CRC-24 checksum.
3072 * @private
3073 */
3074function createcrc24(input) {
3075 let crc = 0xCE04B7;
3076 return transform(input, value => {
3077 const len32 = isLittleEndian ? Math.floor(value.length / 4) : 0;
3078 const arr32 = new Uint32Array(value.buffer, value.byteOffset, len32);
3079 for (let i = 0; i < len32; i++) {
3080 crc ^= arr32[i];
3081 crc =
3082 crc_table[0][(crc >> 24) & 0xFF] ^
3083 crc_table[1][(crc >> 16) & 0xFF] ^
3084 crc_table[2][(crc >> 8) & 0xFF] ^
3085 crc_table[3][(crc >> 0) & 0xFF];
3086 }
3087 for (let i = len32 * 4; i < value.length; i++) {
3088 crc = (crc >> 8) ^ crc_table[0][(crc & 0xFF) ^ value[i]];
3089 }
3090 }, () => new Uint8Array([crc, crc >> 8, crc >> 16]));
3091}
3092
3093/**
3094 * Verify armored headers. crypto-refresh-06, section 6.2:
3095 * "An OpenPGP implementation may consider improperly formatted Armor
3096 * Headers to be corruption of the ASCII Armor, but SHOULD make an
3097 * effort to recover."
3098 * @private
3099 * @param {Array<String>} headers - Armor headers
3100 */
3101function verifyHeaders(headers) {
3102 for (let i = 0; i < headers.length; i++) {
3103 if (!/^([^\s:]|[^\s:][^:]*[^\s:]): .+$/.test(headers[i])) {
3104 util.printDebugError(new Error('Improperly formatted armor header: ' + headers[i]));
3105 }
3106 if (!/^(Version|Comment|MessageID|Hash|Charset): .+$/.test(headers[i])) {
3107 util.printDebugError(new Error('Unknown header: ' + headers[i]));
3108 }
3109 }
3110}
3111
3112/**
3113 * Splits a message into two parts, the body and the checksum. This is an internal function
3114 * @param {String} text - OpenPGP armored message part
3115 * @returns {Object} An object with attribute "body" containing the body.
3116 * and an attribute "checksum" containing the checksum.
3117 * @private
3118 */
3119function splitChecksum(text) {
3120 let body = text;
3121 let checksum = '';
3122
3123 const lastEquals = text.lastIndexOf('=');
3124
3125 if (lastEquals >= 0 && lastEquals !== text.length - 1) { // '=' as the last char means no checksum
3126 body = text.slice(0, lastEquals);
3127 checksum = text.slice(lastEquals + 1).substr(0, 4);
3128 }
3129
3130 return { body: body, checksum: checksum };
3131}
3132
3133/**
3134 * Dearmor an OpenPGP armored message; verify the checksum and return
3135 * the encoded bytes
3136 * @param {String} input - OpenPGP armored message
3137 * @returns {Promise<Object>} An object with attribute "text" containing the message text,
3138 * an attribute "data" containing a stream of bytes and "type" for the ASCII armor type
3139 * @async
3140 * @static
3141 */
3142function unarmor(input, config = defaultConfig) {
3143 return new Promise(async (resolve, reject) => {
3144 try {
3145 const reSplit = /^-----[^-]+-----$/m;
3146 const reEmptyLine = /^[ \f\r\t\u00a0\u2000-\u200a\u202f\u205f\u3000]*$/;
3147
3148 let type;
3149 const headers = [];
3150 let lastHeaders = headers;
3151 let headersDone;
3152 let text = [];
3153 let textDone;
3154 let checksum;
3155 let data = decode(transformPair(input, async (readable, writable) => {
3156 const reader = getReader(readable);
3157 try {
3158 while (true) {
3159 let line = await reader.readLine();
3160 if (line === undefined) {
3161 throw new Error('Misformed armored text');
3162 }
3163 // remove trailing whitespace at end of lines
3164 line = util.removeTrailingSpaces(line.replace(/[\r\n]/g, ''));
3165 if (!type) {
3166 if (reSplit.test(line)) {
3167 type = getType(line);
3168 }
3169 } else if (!headersDone) {
3170 if (reSplit.test(line)) {
3171 reject(new Error('Mandatory blank line missing between armor headers and armor data'));
3172 }
3173 if (!reEmptyLine.test(line)) {
3174 lastHeaders.push(line);
3175 } else {
3176 verifyHeaders(lastHeaders);
3177 headersDone = true;
3178 if (textDone || type !== 2) {
3179 resolve({ text, data, headers, type });
3180 break;
3181 }
3182 }
3183 } else if (!textDone && type === 2) {
3184 if (!reSplit.test(line)) {
3185 // Reverse dash-escaping for msg
3186 text.push(line.replace(/^- /, ''));
3187 } else {
3188 text = text.join('\r\n');
3189 textDone = true;
3190 verifyHeaders(lastHeaders);
3191 lastHeaders = [];
3192 headersDone = false;
3193 }
3194 }
3195 }
3196 } catch (e) {
3197 reject(e);
3198 return;
3199 }
3200 const writer = getWriter(writable);
3201 try {
3202 while (true) {
3203 await writer.ready;
3204 const { done, value } = await reader.read();
3205 if (done) {
3206 throw new Error('Misformed armored text');
3207 }
3208 const line = value + '';
3209 if (line.indexOf('=') === -1 && line.indexOf('-') === -1) {
3210 await writer.write(line);
3211 } else {
3212 let remainder = await reader.readToEnd();
3213 if (!remainder.length) remainder = '';
3214 remainder = line + remainder;
3215 remainder = util.removeTrailingSpaces(remainder.replace(/\r/g, ''));
3216 const parts = remainder.split(reSplit);
3217 if (parts.length === 1) {
3218 throw new Error('Misformed armored text');
3219 }
3220 const split = splitChecksum(parts[0].slice(0, -1));
3221 checksum = split.checksum;
3222 await writer.write(split.body);
3223 break;
3224 }
3225 }
3226 await writer.ready;
3227 await writer.close();
3228 } catch (e) {
3229 await writer.abort(e);
3230 }
3231 }));
3232 data = transformPair(data, async (readable, writable) => {
3233 const checksumVerified = readToEnd(getCheckSum(passiveClone(readable)));
3234 checksumVerified.catch(() => {});
3235 await pipe(readable, writable, {
3236 preventClose: true
3237 });
3238 const writer = getWriter(writable);
3239 try {
3240 const checksumVerifiedString = (await checksumVerified).replace('\n', '');
3241 if (checksum !== checksumVerifiedString && (checksum || config.checksumRequired)) {
3242 throw new Error('Ascii armor integrity check failed');
3243 }
3244 await writer.ready;
3245 await writer.close();
3246 } catch (e) {
3247 await writer.abort(e);
3248 }
3249 });
3250 } catch (e) {
3251 reject(e);
3252 }
3253 }).then(async result => {
3254 if (isArrayStream(result.data)) {
3255 result.data = await readToEnd(result.data);
3256 }
3257 return result;
3258 });
3259}
3260
3261
3262/**
3263 * Armor an OpenPGP binary packet block
3264 * @param {module:enums.armor} messageType - Type of the message
3265 * @param {Uint8Array | ReadableStream<Uint8Array>} body - The message body to armor
3266 * @param {Integer} [partIndex]
3267 * @param {Integer} [partTotal]
3268 * @param {String} [customComment] - Additional comment to add to the armored string
3269 * @returns {String | ReadableStream<String>} Armored text.
3270 * @static
3271 */
3272function armor(messageType, body, partIndex, partTotal, customComment, config = defaultConfig) {
3273 let text;
3274 let hash;
3275 if (messageType === enums.armor.signed) {
3276 text = body.text;
3277 hash = body.hash;
3278 body = body.data;
3279 }
3280 const bodyClone = passiveClone(body);
3281 const result = [];
3282 switch (messageType) {
3283 case enums.armor.multipartSection:
3284 result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
3285 result.push(addheader(customComment, config));
3286 result.push(encode(body));
3287 result.push('=', getCheckSum(bodyClone));
3288 result.push('-----END PGP MESSAGE, PART ' + partIndex + '/' + partTotal + '-----\n');
3289 break;
3290 case enums.armor.multipartLast:
3291 result.push('-----BEGIN PGP MESSAGE, PART ' + partIndex + '-----\n');
3292 result.push(addheader(customComment, config));
3293 result.push(encode(body));
3294 result.push('=', getCheckSum(bodyClone));
3295 result.push('-----END PGP MESSAGE, PART ' + partIndex + '-----\n');
3296 break;
3297 case enums.armor.signed:
3298 result.push('-----BEGIN PGP SIGNED MESSAGE-----\n');
3299 result.push('Hash: ' + hash + '\n\n');
3300 result.push(text.replace(/^-/mg, '- -'));
3301 result.push('\n-----BEGIN PGP SIGNATURE-----\n');
3302 result.push(addheader(customComment, config));
3303 result.push(encode(body));
3304 result.push('=', getCheckSum(bodyClone));
3305 result.push('-----END PGP SIGNATURE-----\n');
3306 break;
3307 case enums.armor.message:
3308 result.push('-----BEGIN PGP MESSAGE-----\n');
3309 result.push(addheader(customComment, config));
3310 result.push(encode(body));
3311 result.push('=', getCheckSum(bodyClone));
3312 result.push('-----END PGP MESSAGE-----\n');
3313 break;
3314 case enums.armor.publicKey:
3315 result.push('-----BEGIN PGP PUBLIC KEY BLOCK-----\n');
3316 result.push(addheader(customComment, config));
3317 result.push(encode(body));
3318 result.push('=', getCheckSum(bodyClone));
3319 result.push('-----END PGP PUBLIC KEY BLOCK-----\n');
3320 break;
3321 case enums.armor.privateKey:
3322 result.push('-----BEGIN PGP PRIVATE KEY BLOCK-----\n');
3323 result.push(addheader(customComment, config));
3324 result.push(encode(body));
3325 result.push('=', getCheckSum(bodyClone));
3326 result.push('-----END PGP PRIVATE KEY BLOCK-----\n');
3327 break;
3328 case enums.armor.signature:
3329 result.push('-----BEGIN PGP SIGNATURE-----\n');
3330 result.push(addheader(customComment, config));
3331 result.push(encode(body));
3332 result.push('=', getCheckSum(bodyClone));
3333 result.push('-----END PGP SIGNATURE-----\n');
3334 break;
3335 }
3336
3337 return util.concat(result);
3338}
3339
3340// GPG4Browsers - An OpenPGP implementation in javascript
3341
3342/**
3343 * Implementation of type key id
3344 *
3345 * {@link https://tools.ietf.org/html/rfc4880#section-3.3|RFC4880 3.3}:
3346 * A Key ID is an eight-octet scalar that identifies a key.
3347 * Implementations SHOULD NOT assume that Key IDs are unique. The
3348 * section "Enhanced Key Formats" below describes how Key IDs are
3349 * formed.
3350 */
3351class KeyID {
3352 constructor() {
3353 this.bytes = '';
3354 }
3355
3356 /**
3357 * Parsing method for a key id
3358 * @param {Uint8Array} bytes - Input to read the key id from
3359 */
3360 read(bytes) {
3361 this.bytes = util.uint8ArrayToString(bytes.subarray(0, 8));
3362 }
3363
3364 /**
3365 * Serializes the Key ID
3366 * @returns {Uint8Array} Key ID as a Uint8Array.
3367 */
3368 write() {
3369 return util.stringToUint8Array(this.bytes);
3370 }
3371
3372 /**
3373 * Returns the Key ID represented as a hexadecimal string
3374 * @returns {String} Key ID as a hexadecimal string.
3375 */
3376 toHex() {
3377 return util.uint8ArrayToHex(util.stringToUint8Array(this.bytes));
3378 }
3379
3380 /**
3381 * Checks equality of Key ID's
3382 * @param {KeyID} keyID
3383 * @param {Boolean} matchWildcard - Indicates whether to check if either keyID is a wildcard
3384 */
3385 equals(keyID, matchWildcard = false) {
3386 return (matchWildcard && (keyID.isWildcard() || this.isWildcard())) || this.bytes === keyID.bytes;
3387 }
3388
3389 /**
3390 * Checks to see if the Key ID is unset
3391 * @returns {Boolean} True if the Key ID is null.
3392 */
3393 isNull() {
3394 return this.bytes === '';
3395 }
3396
3397 /**
3398 * Checks to see if the Key ID is a "wildcard" Key ID (all zeros)
3399 * @returns {Boolean} True if this is a wildcard Key ID.
3400 */
3401 isWildcard() {
3402 return /^0+$/.test(this.toHex());
3403 }
3404
3405 static mapToHex(keyID) {
3406 return keyID.toHex();
3407 }
3408
3409 static fromID(hex) {
3410 const keyID = new KeyID();
3411 keyID.read(util.hexToUint8Array(hex));
3412 return keyID;
3413 }
3414
3415 static wildcard() {
3416 const keyID = new KeyID();
3417 keyID.read(new Uint8Array(8));
3418 return keyID;
3419 }
3420}
3421
3422/**
3423 * @file {@link http://asmjs.org Asm.js} implementation of the {@link https://en.wikipedia.org/wiki/Advanced_Encryption_Standard Advanced Encryption Standard}.
3424 * @author Artem S Vybornov <vybornov@gmail.com>
3425 * @license MIT
3426 */
3427var AES_asm = function () {
3428
3429 /**
3430 * Galois Field stuff init flag
3431 */
3432 var ginit_done = false;
3433
3434 /**
3435 * Galois Field exponentiation and logarithm tables for 3 (the generator)
3436 */
3437 var gexp3, glog3;
3438
3439 /**
3440 * Init Galois Field tables
3441 */
3442 function ginit() {
3443 gexp3 = [],
3444 glog3 = [];
3445
3446 var a = 1, c, d;
3447 for (c = 0; c < 255; c++) {
3448 gexp3[c] = a;
3449
3450 // Multiply by three
3451 d = a & 0x80, a <<= 1, a &= 255;
3452 if (d === 0x80) a ^= 0x1b;
3453 a ^= gexp3[c];
3454
3455 // Set the log table value
3456 glog3[gexp3[c]] = c;
3457 }
3458 gexp3[255] = gexp3[0];
3459 glog3[0] = 0;
3460
3461 ginit_done = true;
3462 }
3463
3464 /**
3465 * Galois Field multiplication
3466 * @param {number} a
3467 * @param {number} b
3468 * @return {number}
3469 */
3470 function gmul(a, b) {
3471 var c = gexp3[(glog3[a] + glog3[b]) % 255];
3472 if (a === 0 || b === 0) c = 0;
3473 return c;
3474 }
3475
3476 /**
3477 * Galois Field reciprocal
3478 * @param {number} a
3479 * @return {number}
3480 */
3481 function ginv(a) {
3482 var i = gexp3[255 - glog3[a]];
3483 if (a === 0) i = 0;
3484 return i;
3485 }
3486
3487 /**
3488 * AES stuff init flag
3489 */
3490 var aes_init_done = false;
3491
3492 /**
3493 * Encryption, Decryption, S-Box and KeyTransform tables
3494 *
3495 * @type {number[]}
3496 */
3497 var aes_sbox;
3498
3499 /**
3500 * @type {number[]}
3501 */
3502 var aes_sinv;
3503
3504 /**
3505 * @type {number[][]}
3506 */
3507 var aes_enc;
3508
3509 /**
3510 * @type {number[][]}
3511 */
3512 var aes_dec;
3513
3514 /**
3515 * Init AES tables
3516 */
3517 function aes_init() {
3518 if (!ginit_done) ginit();
3519
3520 // Calculates AES S-Box value
3521 function _s(a) {
3522 var c, s, x;
3523 s = x = ginv(a);
3524 for (c = 0; c < 4; c++) {
3525 s = ((s << 1) | (s >>> 7)) & 255;
3526 x ^= s;
3527 }
3528 x ^= 99;
3529 return x;
3530 }
3531
3532 // Tables
3533 aes_sbox = [],
3534 aes_sinv = [],
3535 aes_enc = [[], [], [], []],
3536 aes_dec = [[], [], [], []];
3537
3538 for (var i = 0; i < 256; i++) {
3539 var s = _s(i);
3540
3541 // S-Box and its inverse
3542 aes_sbox[i] = s;
3543 aes_sinv[s] = i;
3544
3545 // Ecryption and Decryption tables
3546 aes_enc[0][i] = (gmul(2, s) << 24) | (s << 16) | (s << 8) | gmul(3, s);
3547 aes_dec[0][s] = (gmul(14, i) << 24) | (gmul(9, i) << 16) | (gmul(13, i) << 8) | gmul(11, i);
3548 // Rotate tables
3549 for (var t = 1; t < 4; t++) {
3550 aes_enc[t][i] = (aes_enc[t - 1][i] >>> 8) | (aes_enc[t - 1][i] << 24);
3551 aes_dec[t][s] = (aes_dec[t - 1][s] >>> 8) | (aes_dec[t - 1][s] << 24);
3552 }
3553 }
3554
3555 aes_init_done = true;
3556 }
3557
3558 /**
3559 * Asm.js module constructor.
3560 *
3561 * <p>
3562 * Heap buffer layout by offset:
3563 * <pre>
3564 * 0x0000 encryption key schedule
3565 * 0x0400 decryption key schedule
3566 * 0x0800 sbox
3567 * 0x0c00 inv sbox
3568 * 0x1000 encryption tables
3569 * 0x2000 decryption tables
3570 * 0x3000 reserved (future GCM multiplication lookup table)
3571 * 0x4000 data
3572 * </pre>
3573 * Don't touch anything before <code>0x400</code>.
3574 * </p>
3575 *
3576 * @alias AES_asm
3577 * @class
3578 * @param foreign - <i>ignored</i>
3579 * @param buffer - heap buffer to link with
3580 */
3581 var wrapper = function (foreign, buffer) {
3582 // Init AES stuff for the first time
3583 if (!aes_init_done) aes_init();
3584
3585 // Fill up AES tables
3586 var heap = new Uint32Array(buffer);
3587 heap.set(aes_sbox, 0x0800 >> 2);
3588 heap.set(aes_sinv, 0x0c00 >> 2);
3589 for (var i = 0; i < 4; i++) {
3590 heap.set(aes_enc[i], (0x1000 + 0x400 * i) >> 2);
3591 heap.set(aes_dec[i], (0x2000 + 0x400 * i) >> 2);
3592 }
3593
3594 /**
3595 * Calculate AES key schedules.
3596 * @instance
3597 * @memberof AES_asm
3598 * @param {number} ks - key size, 4/6/8 (for 128/192/256-bit key correspondingly)
3599 * @param {number} k0 - key vector components
3600 * @param {number} k1 - key vector components
3601 * @param {number} k2 - key vector components
3602 * @param {number} k3 - key vector components
3603 * @param {number} k4 - key vector components
3604 * @param {number} k5 - key vector components
3605 * @param {number} k6 - key vector components
3606 * @param {number} k7 - key vector components
3607 */
3608 function set_key(ks, k0, k1, k2, k3, k4, k5, k6, k7) {
3609 var ekeys = heap.subarray(0x000, 60),
3610 dkeys = heap.subarray(0x100, 0x100 + 60);
3611
3612 // Encryption key schedule
3613 ekeys.set([k0, k1, k2, k3, k4, k5, k6, k7]);
3614 for (var i = ks, rcon = 1; i < 4 * ks + 28; i++) {
3615 var k = ekeys[i - 1];
3616 if ((i % ks === 0) || (ks === 8 && i % ks === 4)) {
3617 k = aes_sbox[k >>> 24] << 24 ^ aes_sbox[k >>> 16 & 255] << 16 ^ aes_sbox[k >>> 8 & 255] << 8 ^ aes_sbox[k & 255];
3618 }
3619 if (i % ks === 0) {
3620 k = (k << 8) ^ (k >>> 24) ^ (rcon << 24);
3621 rcon = (rcon << 1) ^ ((rcon & 0x80) ? 0x1b : 0);
3622 }
3623 ekeys[i] = ekeys[i - ks] ^ k;
3624 }
3625
3626 // Decryption key schedule
3627 for (var j = 0; j < i; j += 4) {
3628 for (var jj = 0; jj < 4; jj++) {
3629 var k = ekeys[i - (4 + j) + (4 - jj) % 4];
3630 if (j < 4 || j >= i - 4) {
3631 dkeys[j + jj] = k;
3632 } else {
3633 dkeys[j + jj] = aes_dec[0][aes_sbox[k >>> 24]]
3634 ^ aes_dec[1][aes_sbox[k >>> 16 & 255]]
3635 ^ aes_dec[2][aes_sbox[k >>> 8 & 255]]
3636 ^ aes_dec[3][aes_sbox[k & 255]];
3637 }
3638 }
3639 }
3640
3641 // Set rounds number
3642 asm.set_rounds(ks + 5);
3643 }
3644
3645 // create library object with necessary properties
3646 var stdlib = {Uint8Array: Uint8Array, Uint32Array: Uint32Array};
3647
3648 var asm = function (stdlib, foreign, buffer) {
3649 "use asm";
3650
3651 var S0 = 0, S1 = 0, S2 = 0, S3 = 0,
3652 I0 = 0, I1 = 0, I2 = 0, I3 = 0,
3653 N0 = 0, N1 = 0, N2 = 0, N3 = 0,
3654 M0 = 0, M1 = 0, M2 = 0, M3 = 0,
3655 H0 = 0, H1 = 0, H2 = 0, H3 = 0,
3656 R = 0;
3657
3658 var HEAP = new stdlib.Uint32Array(buffer),
3659 DATA = new stdlib.Uint8Array(buffer);
3660
3661 /**
3662 * AES core
3663 * @param {number} k - precomputed key schedule offset
3664 * @param {number} s - precomputed sbox table offset
3665 * @param {number} t - precomputed round table offset
3666 * @param {number} r - number of inner rounds to perform
3667 * @param {number} x0 - 128-bit input block vector
3668 * @param {number} x1 - 128-bit input block vector
3669 * @param {number} x2 - 128-bit input block vector
3670 * @param {number} x3 - 128-bit input block vector
3671 */
3672 function _core(k, s, t, r, x0, x1, x2, x3) {
3673 k = k | 0;
3674 s = s | 0;
3675 t = t | 0;
3676 r = r | 0;
3677 x0 = x0 | 0;
3678 x1 = x1 | 0;
3679 x2 = x2 | 0;
3680 x3 = x3 | 0;
3681
3682 var t1 = 0, t2 = 0, t3 = 0,
3683 y0 = 0, y1 = 0, y2 = 0, y3 = 0,
3684 i = 0;
3685
3686 t1 = t | 0x400, t2 = t | 0x800, t3 = t | 0xc00;
3687
3688 // round 0
3689 x0 = x0 ^ HEAP[(k | 0) >> 2],
3690 x1 = x1 ^ HEAP[(k | 4) >> 2],
3691 x2 = x2 ^ HEAP[(k | 8) >> 2],
3692 x3 = x3 ^ HEAP[(k | 12) >> 2];
3693
3694 // round 1..r
3695 for (i = 16; (i | 0) <= (r << 4); i = (i + 16) | 0) {
3696 y0 = HEAP[(t | x0 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x1 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x2 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x3 << 2 & 1020) >> 2] ^ HEAP[(k | i | 0) >> 2],
3697 y1 = HEAP[(t | x1 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x2 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x3 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x0 << 2 & 1020) >> 2] ^ HEAP[(k | i | 4) >> 2],
3698 y2 = HEAP[(t | x2 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x3 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x0 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x1 << 2 & 1020) >> 2] ^ HEAP[(k | i | 8) >> 2],
3699 y3 = HEAP[(t | x3 >> 22 & 1020) >> 2] ^ HEAP[(t1 | x0 >> 14 & 1020) >> 2] ^ HEAP[(t2 | x1 >> 6 & 1020) >> 2] ^ HEAP[(t3 | x2 << 2 & 1020) >> 2] ^ HEAP[(k | i | 12) >> 2];
3700 x0 = y0, x1 = y1, x2 = y2, x3 = y3;
3701 }
3702
3703 // final round
3704 S0 = HEAP[(s | x0 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x1 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x2 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x3 << 2 & 1020) >> 2] ^ HEAP[(k | i | 0) >> 2],
3705 S1 = HEAP[(s | x1 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x2 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x3 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x0 << 2 & 1020) >> 2] ^ HEAP[(k | i | 4) >> 2],
3706 S2 = HEAP[(s | x2 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x3 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x0 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x1 << 2 & 1020) >> 2] ^ HEAP[(k | i | 8) >> 2],
3707 S3 = HEAP[(s | x3 >> 22 & 1020) >> 2] << 24 ^ HEAP[(s | x0 >> 14 & 1020) >> 2] << 16 ^ HEAP[(s | x1 >> 6 & 1020) >> 2] << 8 ^ HEAP[(s | x2 << 2 & 1020) >> 2] ^ HEAP[(k | i | 12) >> 2];
3708 }
3709
3710 /**
3711 * ECB mode encryption
3712 * @param {number} x0 - 128-bit input block vector
3713 * @param {number} x1 - 128-bit input block vector
3714 * @param {number} x2 - 128-bit input block vector
3715 * @param {number} x3 - 128-bit input block vector
3716 */
3717 function _ecb_enc(x0, x1, x2, x3) {
3718 x0 = x0 | 0;
3719 x1 = x1 | 0;
3720 x2 = x2 | 0;
3721 x3 = x3 | 0;
3722
3723 _core(
3724 0x0000, 0x0800, 0x1000,
3725 R,
3726 x0,
3727 x1,
3728 x2,
3729 x3
3730 );
3731 }
3732
3733 /**
3734 * ECB mode decryption
3735 * @param {number} x0 - 128-bit input block vector
3736 * @param {number} x1 - 128-bit input block vector
3737 * @param {number} x2 - 128-bit input block vector
3738 * @param {number} x3 - 128-bit input block vector
3739 */
3740 function _ecb_dec(x0, x1, x2, x3) {
3741 x0 = x0 | 0;
3742 x1 = x1 | 0;
3743 x2 = x2 | 0;
3744 x3 = x3 | 0;
3745
3746 var t = 0;
3747
3748 _core(
3749 0x0400, 0x0c00, 0x2000,
3750 R,
3751 x0,
3752 x3,
3753 x2,
3754 x1
3755 );
3756
3757 t = S1, S1 = S3, S3 = t;
3758 }
3759
3760
3761 /**
3762 * CBC mode encryption
3763 * @param {number} x0 - 128-bit input block vector
3764 * @param {number} x1 - 128-bit input block vector
3765 * @param {number} x2 - 128-bit input block vector
3766 * @param {number} x3 - 128-bit input block vector
3767 */
3768 function _cbc_enc(x0, x1, x2, x3) {
3769 x0 = x0 | 0;
3770 x1 = x1 | 0;
3771 x2 = x2 | 0;
3772 x3 = x3 | 0;
3773
3774 _core(
3775 0x0000, 0x0800, 0x1000,
3776 R,
3777 I0 ^ x0,
3778 I1 ^ x1,
3779 I2 ^ x2,
3780 I3 ^ x3
3781 );
3782
3783 I0 = S0,
3784 I1 = S1,
3785 I2 = S2,
3786 I3 = S3;
3787 }
3788
3789 /**
3790 * CBC mode decryption
3791 * @param {number} x0 - 128-bit input block vector
3792 * @param {number} x1 - 128-bit input block vector
3793 * @param {number} x2 - 128-bit input block vector
3794 * @param {number} x3 - 128-bit input block vector
3795 */
3796 function _cbc_dec(x0, x1, x2, x3) {
3797 x0 = x0 | 0;
3798 x1 = x1 | 0;
3799 x2 = x2 | 0;
3800 x3 = x3 | 0;
3801
3802 var t = 0;
3803
3804 _core(
3805 0x0400, 0x0c00, 0x2000,
3806 R,
3807 x0,
3808 x3,
3809 x2,
3810 x1
3811 );
3812
3813 t = S1, S1 = S3, S3 = t;
3814
3815 S0 = S0 ^ I0,
3816 S1 = S1 ^ I1,
3817 S2 = S2 ^ I2,
3818 S3 = S3 ^ I3;
3819
3820 I0 = x0,
3821 I1 = x1,
3822 I2 = x2,
3823 I3 = x3;
3824 }
3825
3826 /**
3827 * CFB mode encryption
3828 * @param {number} x0 - 128-bit input block vector
3829 * @param {number} x1 - 128-bit input block vector
3830 * @param {number} x2 - 128-bit input block vector
3831 * @param {number} x3 - 128-bit input block vector
3832 */
3833 function _cfb_enc(x0, x1, x2, x3) {
3834 x0 = x0 | 0;
3835 x1 = x1 | 0;
3836 x2 = x2 | 0;
3837 x3 = x3 | 0;
3838
3839 _core(
3840 0x0000, 0x0800, 0x1000,
3841 R,
3842 I0,
3843 I1,
3844 I2,
3845 I3
3846 );
3847
3848 I0 = S0 = S0 ^ x0,
3849 I1 = S1 = S1 ^ x1,
3850 I2 = S2 = S2 ^ x2,
3851 I3 = S3 = S3 ^ x3;
3852 }
3853
3854
3855 /**
3856 * CFB mode decryption
3857 * @param {number} x0 - 128-bit input block vector
3858 * @param {number} x1 - 128-bit input block vector
3859 * @param {number} x2 - 128-bit input block vector
3860 * @param {number} x3 - 128-bit input block vector
3861 */
3862 function _cfb_dec(x0, x1, x2, x3) {
3863 x0 = x0 | 0;
3864 x1 = x1 | 0;
3865 x2 = x2 | 0;
3866 x3 = x3 | 0;
3867
3868 _core(
3869 0x0000, 0x0800, 0x1000,
3870 R,
3871 I0,
3872 I1,
3873 I2,
3874 I3
3875 );
3876
3877 S0 = S0 ^ x0,
3878 S1 = S1 ^ x1,
3879 S2 = S2 ^ x2,
3880 S3 = S3 ^ x3;
3881
3882 I0 = x0,
3883 I1 = x1,
3884 I2 = x2,
3885 I3 = x3;
3886 }
3887
3888 /**
3889 * OFB mode encryption / decryption
3890 * @param {number} x0 - 128-bit input block vector
3891 * @param {number} x1 - 128-bit input block vector
3892 * @param {number} x2 - 128-bit input block vector
3893 * @param {number} x3 - 128-bit input block vector
3894 */
3895 function _ofb(x0, x1, x2, x3) {
3896 x0 = x0 | 0;
3897 x1 = x1 | 0;
3898 x2 = x2 | 0;
3899 x3 = x3 | 0;
3900
3901 _core(
3902 0x0000, 0x0800, 0x1000,
3903 R,
3904 I0,
3905 I1,
3906 I2,
3907 I3
3908 );
3909
3910 I0 = S0,
3911 I1 = S1,
3912 I2 = S2,
3913 I3 = S3;
3914
3915 S0 = S0 ^ x0,
3916 S1 = S1 ^ x1,
3917 S2 = S2 ^ x2,
3918 S3 = S3 ^ x3;
3919 }
3920
3921 /**
3922 * CTR mode encryption / decryption
3923 * @param {number} x0 - 128-bit input block vector
3924 * @param {number} x1 - 128-bit input block vector
3925 * @param {number} x2 - 128-bit input block vector
3926 * @param {number} x3 - 128-bit input block vector
3927 */
3928 function _ctr(x0, x1, x2, x3) {
3929 x0 = x0 | 0;
3930 x1 = x1 | 0;
3931 x2 = x2 | 0;
3932 x3 = x3 | 0;
3933
3934 _core(
3935 0x0000, 0x0800, 0x1000,
3936 R,
3937 N0,
3938 N1,
3939 N2,
3940 N3
3941 );
3942
3943 N3 = (~M3 & N3) | M3 & (N3 + 1);
3944 N2 = (~M2 & N2) | M2 & (N2 + ((N3 | 0) == 0));
3945 N1 = (~M1 & N1) | M1 & (N1 + ((N2 | 0) == 0));
3946 N0 = (~M0 & N0) | M0 & (N0 + ((N1 | 0) == 0));
3947
3948 S0 = S0 ^ x0;
3949 S1 = S1 ^ x1;
3950 S2 = S2 ^ x2;
3951 S3 = S3 ^ x3;
3952 }
3953
3954 /**
3955 * GCM mode MAC calculation
3956 * @param {number} x0 - 128-bit input block vector
3957 * @param {number} x1 - 128-bit input block vector
3958 * @param {number} x2 - 128-bit input block vector
3959 * @param {number} x3 - 128-bit input block vector
3960 */
3961 function _gcm_mac(x0, x1, x2, x3) {
3962 x0 = x0 | 0;
3963 x1 = x1 | 0;
3964 x2 = x2 | 0;
3965 x3 = x3 | 0;
3966
3967 var y0 = 0, y1 = 0, y2 = 0, y3 = 0,
3968 z0 = 0, z1 = 0, z2 = 0, z3 = 0,
3969 i = 0, c = 0;
3970
3971 x0 = x0 ^ I0,
3972 x1 = x1 ^ I1,
3973 x2 = x2 ^ I2,
3974 x3 = x3 ^ I3;
3975
3976 y0 = H0 | 0,
3977 y1 = H1 | 0,
3978 y2 = H2 | 0,
3979 y3 = H3 | 0;
3980
3981 for (; (i | 0) < 128; i = (i + 1) | 0) {
3982 if (y0 >>> 31) {
3983 z0 = z0 ^ x0,
3984 z1 = z1 ^ x1,
3985 z2 = z2 ^ x2,
3986 z3 = z3 ^ x3;
3987 }
3988
3989 y0 = (y0 << 1) | (y1 >>> 31),
3990 y1 = (y1 << 1) | (y2 >>> 31),
3991 y2 = (y2 << 1) | (y3 >>> 31),
3992 y3 = (y3 << 1);
3993
3994 c = x3 & 1;
3995
3996 x3 = (x3 >>> 1) | (x2 << 31),
3997 x2 = (x2 >>> 1) | (x1 << 31),
3998 x1 = (x1 >>> 1) | (x0 << 31),
3999 x0 = (x0 >>> 1);
4000
4001 if (c) x0 = x0 ^ 0xe1000000;
4002 }
4003
4004 I0 = z0,
4005 I1 = z1,
4006 I2 = z2,
4007 I3 = z3;
4008 }
4009
4010 /**
4011 * Set the internal rounds number.
4012 * @instance
4013 * @memberof AES_asm
4014 * @param {number} r - number if inner AES rounds
4015 */
4016 function set_rounds(r) {
4017 r = r | 0;
4018 R = r;
4019 }
4020
4021 /**
4022 * Populate the internal state of the module.
4023 * @instance
4024 * @memberof AES_asm
4025 * @param {number} s0 - state vector
4026 * @param {number} s1 - state vector
4027 * @param {number} s2 - state vector
4028 * @param {number} s3 - state vector
4029 */
4030 function set_state(s0, s1, s2, s3) {
4031 s0 = s0 | 0;
4032 s1 = s1 | 0;
4033 s2 = s2 | 0;
4034 s3 = s3 | 0;
4035
4036 S0 = s0,
4037 S1 = s1,
4038 S2 = s2,
4039 S3 = s3;
4040 }
4041
4042 /**
4043 * Populate the internal iv of the module.
4044 * @instance
4045 * @memberof AES_asm
4046 * @param {number} i0 - iv vector
4047 * @param {number} i1 - iv vector
4048 * @param {number} i2 - iv vector
4049 * @param {number} i3 - iv vector
4050 */
4051 function set_iv(i0, i1, i2, i3) {
4052 i0 = i0 | 0;
4053 i1 = i1 | 0;
4054 i2 = i2 | 0;
4055 i3 = i3 | 0;
4056
4057 I0 = i0,
4058 I1 = i1,
4059 I2 = i2,
4060 I3 = i3;
4061 }
4062
4063 /**
4064 * Set nonce for CTR-family modes.
4065 * @instance
4066 * @memberof AES_asm
4067 * @param {number} n0 - nonce vector
4068 * @param {number} n1 - nonce vector
4069 * @param {number} n2 - nonce vector
4070 * @param {number} n3 - nonce vector
4071 */
4072 function set_nonce(n0, n1, n2, n3) {
4073 n0 = n0 | 0;
4074 n1 = n1 | 0;
4075 n2 = n2 | 0;
4076 n3 = n3 | 0;
4077
4078 N0 = n0,
4079 N1 = n1,
4080 N2 = n2,
4081 N3 = n3;
4082 }
4083
4084 /**
4085 * Set counter mask for CTR-family modes.
4086 * @instance
4087 * @memberof AES_asm
4088 * @param {number} m0 - counter mask vector
4089 * @param {number} m1 - counter mask vector
4090 * @param {number} m2 - counter mask vector
4091 * @param {number} m3 - counter mask vector
4092 */
4093 function set_mask(m0, m1, m2, m3) {
4094 m0 = m0 | 0;
4095 m1 = m1 | 0;
4096 m2 = m2 | 0;
4097 m3 = m3 | 0;
4098
4099 M0 = m0,
4100 M1 = m1,
4101 M2 = m2,
4102 M3 = m3;
4103 }
4104
4105 /**
4106 * Set counter for CTR-family modes.
4107 * @instance
4108 * @memberof AES_asm
4109 * @param {number} c0 - counter vector
4110 * @param {number} c1 - counter vector
4111 * @param {number} c2 - counter vector
4112 * @param {number} c3 - counter vector
4113 */
4114 function set_counter(c0, c1, c2, c3) {
4115 c0 = c0 | 0;
4116 c1 = c1 | 0;
4117 c2 = c2 | 0;
4118 c3 = c3 | 0;
4119
4120 N3 = (~M3 & N3) | M3 & c3,
4121 N2 = (~M2 & N2) | M2 & c2,
4122 N1 = (~M1 & N1) | M1 & c1,
4123 N0 = (~M0 & N0) | M0 & c0;
4124 }
4125
4126 /**
4127 * Store the internal state vector into the heap.
4128 * @instance
4129 * @memberof AES_asm
4130 * @param {number} pos - offset where to put the data
4131 * @return {number} The number of bytes have been written into the heap, always 16.
4132 */
4133 function get_state(pos) {
4134 pos = pos | 0;
4135
4136 if (pos & 15) return -1;
4137
4138 DATA[pos | 0] = S0 >>> 24,
4139 DATA[pos | 1] = S0 >>> 16 & 255,
4140 DATA[pos | 2] = S0 >>> 8 & 255,
4141 DATA[pos | 3] = S0 & 255,
4142 DATA[pos | 4] = S1 >>> 24,
4143 DATA[pos | 5] = S1 >>> 16 & 255,
4144 DATA[pos | 6] = S1 >>> 8 & 255,
4145 DATA[pos | 7] = S1 & 255,
4146 DATA[pos | 8] = S2 >>> 24,
4147 DATA[pos | 9] = S2 >>> 16 & 255,
4148 DATA[pos | 10] = S2 >>> 8 & 255,
4149 DATA[pos | 11] = S2 & 255,
4150 DATA[pos | 12] = S3 >>> 24,
4151 DATA[pos | 13] = S3 >>> 16 & 255,
4152 DATA[pos | 14] = S3 >>> 8 & 255,
4153 DATA[pos | 15] = S3 & 255;
4154
4155 return 16;
4156 }
4157
4158 /**
4159 * Store the internal iv vector into the heap.
4160 * @instance
4161 * @memberof AES_asm
4162 * @param {number} pos - offset where to put the data
4163 * @return {number} The number of bytes have been written into the heap, always 16.
4164 */
4165 function get_iv(pos) {
4166 pos = pos | 0;
4167
4168 if (pos & 15) return -1;
4169
4170 DATA[pos | 0] = I0 >>> 24,
4171 DATA[pos | 1] = I0 >>> 16 & 255,
4172 DATA[pos | 2] = I0 >>> 8 & 255,
4173 DATA[pos | 3] = I0 & 255,
4174 DATA[pos | 4] = I1 >>> 24,
4175 DATA[pos | 5] = I1 >>> 16 & 255,
4176 DATA[pos | 6] = I1 >>> 8 & 255,
4177 DATA[pos | 7] = I1 & 255,
4178 DATA[pos | 8] = I2 >>> 24,
4179 DATA[pos | 9] = I2 >>> 16 & 255,
4180 DATA[pos | 10] = I2 >>> 8 & 255,
4181 DATA[pos | 11] = I2 & 255,
4182 DATA[pos | 12] = I3 >>> 24,
4183 DATA[pos | 13] = I3 >>> 16 & 255,
4184 DATA[pos | 14] = I3 >>> 8 & 255,
4185 DATA[pos | 15] = I3 & 255;
4186
4187 return 16;
4188 }
4189
4190 /**
4191 * GCM initialization.
4192 * @instance
4193 * @memberof AES_asm
4194 */
4195 function gcm_init() {
4196 _ecb_enc(0, 0, 0, 0);
4197 H0 = S0,
4198 H1 = S1,
4199 H2 = S2,
4200 H3 = S3;
4201 }
4202
4203 /**
4204 * Perform ciphering operation on the supplied data.
4205 * @instance
4206 * @memberof AES_asm
4207 * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
4208 * @param {number} pos - offset of the data being processed
4209 * @param {number} len - length of the data being processed
4210 * @return {number} Actual amount of data have been processed.
4211 */
4212 function cipher(mode, pos, len) {
4213 mode = mode | 0;
4214 pos = pos | 0;
4215 len = len | 0;
4216
4217 var ret = 0;
4218
4219 if (pos & 15) return -1;
4220
4221 while ((len | 0) >= 16) {
4222 _cipher_modes[mode & 7](
4223 DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3],
4224 DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7],
4225 DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11],
4226 DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]
4227 );
4228
4229 DATA[pos | 0] = S0 >>> 24,
4230 DATA[pos | 1] = S0 >>> 16 & 255,
4231 DATA[pos | 2] = S0 >>> 8 & 255,
4232 DATA[pos | 3] = S0 & 255,
4233 DATA[pos | 4] = S1 >>> 24,
4234 DATA[pos | 5] = S1 >>> 16 & 255,
4235 DATA[pos | 6] = S1 >>> 8 & 255,
4236 DATA[pos | 7] = S1 & 255,
4237 DATA[pos | 8] = S2 >>> 24,
4238 DATA[pos | 9] = S2 >>> 16 & 255,
4239 DATA[pos | 10] = S2 >>> 8 & 255,
4240 DATA[pos | 11] = S2 & 255,
4241 DATA[pos | 12] = S3 >>> 24,
4242 DATA[pos | 13] = S3 >>> 16 & 255,
4243 DATA[pos | 14] = S3 >>> 8 & 255,
4244 DATA[pos | 15] = S3 & 255;
4245
4246 ret = (ret + 16) | 0,
4247 pos = (pos + 16) | 0,
4248 len = (len - 16) | 0;
4249 }
4250
4251 return ret | 0;
4252 }
4253
4254 /**
4255 * Calculates MAC of the supplied data.
4256 * @instance
4257 * @memberof AES_asm
4258 * @param {number} mode - block cipher mode (see {@link AES_asm} mode constants)
4259 * @param {number} pos - offset of the data being processed
4260 * @param {number} len - length of the data being processed
4261 * @return {number} Actual amount of data have been processed.
4262 */
4263 function mac(mode, pos, len) {
4264 mode = mode | 0;
4265 pos = pos | 0;
4266 len = len | 0;
4267
4268 var ret = 0;
4269
4270 if (pos & 15) return -1;
4271
4272 while ((len | 0) >= 16) {
4273 _mac_modes[mode & 1](
4274 DATA[pos | 0] << 24 | DATA[pos | 1] << 16 | DATA[pos | 2] << 8 | DATA[pos | 3],
4275 DATA[pos | 4] << 24 | DATA[pos | 5] << 16 | DATA[pos | 6] << 8 | DATA[pos | 7],
4276 DATA[pos | 8] << 24 | DATA[pos | 9] << 16 | DATA[pos | 10] << 8 | DATA[pos | 11],
4277 DATA[pos | 12] << 24 | DATA[pos | 13] << 16 | DATA[pos | 14] << 8 | DATA[pos | 15]
4278 );
4279
4280 ret = (ret + 16) | 0,
4281 pos = (pos + 16) | 0,
4282 len = (len - 16) | 0;
4283 }
4284
4285 return ret | 0;
4286 }
4287
4288 /**
4289 * AES cipher modes table (virual methods)
4290 */
4291 var _cipher_modes = [_ecb_enc, _ecb_dec, _cbc_enc, _cbc_dec, _cfb_enc, _cfb_dec, _ofb, _ctr];
4292
4293 /**
4294 * AES MAC modes table (virual methods)
4295 */
4296 var _mac_modes = [_cbc_enc, _gcm_mac];
4297
4298 /**
4299 * Asm.js module exports
4300 */
4301 return {
4302 set_rounds: set_rounds,
4303 set_state: set_state,
4304 set_iv: set_iv,
4305 set_nonce: set_nonce,
4306 set_mask: set_mask,
4307 set_counter: set_counter,
4308 get_state: get_state,
4309 get_iv: get_iv,
4310 gcm_init: gcm_init,
4311 cipher: cipher,
4312 mac: mac,
4313 };
4314 }(stdlib, foreign, buffer);
4315
4316 asm.set_key = set_key;
4317
4318 return asm;
4319 };
4320
4321 /**
4322 * AES enciphering mode constants
4323 * @enum {number}
4324 * @const
4325 */
4326 wrapper.ENC = {
4327 ECB: 0,
4328 CBC: 2,
4329 CFB: 4,
4330 OFB: 6,
4331 CTR: 7,
4332 },
4333
4334 /**
4335 * AES deciphering mode constants
4336 * @enum {number}
4337 * @const
4338 */
4339 wrapper.DEC = {
4340 ECB: 1,
4341 CBC: 3,
4342 CFB: 5,
4343 OFB: 6,
4344 CTR: 7,
4345 },
4346
4347 /**
4348 * AES MAC mode constants
4349 * @enum {number}
4350 * @const
4351 */
4352 wrapper.MAC = {
4353 CBC: 0,
4354 GCM: 1,
4355 };
4356
4357 /**
4358 * Heap data offset
4359 * @type {number}
4360 * @const
4361 */
4362 wrapper.HEAP_DATA = 0x4000;
4363
4364 return wrapper;
4365}();
4366
4367function is_bytes(a) {
4368 return a instanceof Uint8Array;
4369}
4370function _heap_init(heap, heapSize) {
4371 const size = heap ? heap.byteLength : heapSize || 65536;
4372 if (size & 0xfff || size <= 0)
4373 throw new Error('heap size must be a positive integer and a multiple of 4096');
4374 heap = heap || new Uint8Array(new ArrayBuffer(size));
4375 return heap;
4376}
4377function _heap_write(heap, hpos, data, dpos, dlen) {
4378 const hlen = heap.length - hpos;
4379 const wlen = hlen < dlen ? hlen : dlen;
4380 heap.set(data.subarray(dpos, dpos + wlen), hpos);
4381 return wlen;
4382}
4383function joinBytes(...arg) {
4384 const totalLenght = arg.reduce((sum, curr) => sum + curr.length, 0);
4385 const ret = new Uint8Array(totalLenght);
4386 let cursor = 0;
4387 for (let i = 0; i < arg.length; i++) {
4388 ret.set(arg[i], cursor);
4389 cursor += arg[i].length;
4390 }
4391 return ret;
4392}
4393
4394class IllegalStateError extends Error {
4395 constructor(...args) {
4396 super(...args);
4397 }
4398}
4399class IllegalArgumentError extends Error {
4400 constructor(...args) {
4401 super(...args);
4402 }
4403}
4404class SecurityError extends Error {
4405 constructor(...args) {
4406 super(...args);
4407 }
4408}
4409
4410const heap_pool = [];
4411const asm_pool = [];
4412class AES {
4413 constructor(key, iv, padding = true, mode, heap, asm) {
4414 this.pos = 0;
4415 this.len = 0;
4416 this.mode = mode;
4417 // The AES object state
4418 this.pos = 0;
4419 this.len = 0;
4420 this.key = key;
4421 this.iv = iv;
4422 this.padding = padding;
4423 // The AES "worker"
4424 this.acquire_asm(heap, asm);
4425 }
4426 acquire_asm(heap, asm) {
4427 if (this.heap === undefined || this.asm === undefined) {
4428 this.heap = heap || heap_pool.pop() || _heap_init().subarray(AES_asm.HEAP_DATA);
4429 this.asm = asm || asm_pool.pop() || new AES_asm(null, this.heap.buffer);
4430 this.reset(this.key, this.iv);
4431 }
4432 return { heap: this.heap, asm: this.asm };
4433 }
4434 release_asm() {
4435 if (this.heap !== undefined && this.asm !== undefined) {
4436 heap_pool.push(this.heap);
4437 asm_pool.push(this.asm);
4438 }
4439 this.heap = undefined;
4440 this.asm = undefined;
4441 }
4442 reset(key, iv) {
4443 const { asm } = this.acquire_asm();
4444 // Key
4445 const keylen = key.length;
4446 if (keylen !== 16 && keylen !== 24 && keylen !== 32)
4447 throw new IllegalArgumentError('illegal key size');
4448 const keyview = new DataView(key.buffer, key.byteOffset, key.byteLength);
4449 asm.set_key(keylen >> 2, keyview.getUint32(0), keyview.getUint32(4), keyview.getUint32(8), keyview.getUint32(12), keylen > 16 ? keyview.getUint32(16) : 0, keylen > 16 ? keyview.getUint32(20) : 0, keylen > 24 ? keyview.getUint32(24) : 0, keylen > 24 ? keyview.getUint32(28) : 0);
4450 // IV
4451 if (iv !== undefined) {
4452 if (iv.length !== 16)
4453 throw new IllegalArgumentError('illegal iv size');
4454 let ivview = new DataView(iv.buffer, iv.byteOffset, iv.byteLength);
4455 asm.set_iv(ivview.getUint32(0), ivview.getUint32(4), ivview.getUint32(8), ivview.getUint32(12));
4456 }
4457 else {
4458 asm.set_iv(0, 0, 0, 0);
4459 }
4460 }
4461 AES_Encrypt_process(data) {
4462 if (!is_bytes(data))
4463 throw new TypeError("data isn't of expected type");
4464 let { heap, asm } = this.acquire_asm();
4465 let amode = AES_asm.ENC[this.mode];
4466 let hpos = AES_asm.HEAP_DATA;
4467 let pos = this.pos;
4468 let len = this.len;
4469 let dpos = 0;
4470 let dlen = data.length || 0;
4471 let rpos = 0;
4472 let rlen = (len + dlen) & -16;
4473 let wlen = 0;
4474 let result = new Uint8Array(rlen);
4475 while (dlen > 0) {
4476 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
4477 len += wlen;
4478 dpos += wlen;
4479 dlen -= wlen;
4480 wlen = asm.cipher(amode, hpos + pos, len);
4481 if (wlen)
4482 result.set(heap.subarray(pos, pos + wlen), rpos);
4483 rpos += wlen;
4484 if (wlen < len) {
4485 pos += wlen;
4486 len -= wlen;
4487 }
4488 else {
4489 pos = 0;
4490 len = 0;
4491 }
4492 }
4493 this.pos = pos;
4494 this.len = len;
4495 return result;
4496 }
4497 AES_Encrypt_finish() {
4498 let { heap, asm } = this.acquire_asm();
4499 let amode = AES_asm.ENC[this.mode];
4500 let hpos = AES_asm.HEAP_DATA;
4501 let pos = this.pos;
4502 let len = this.len;
4503 let plen = 16 - (len % 16);
4504 let rlen = len;
4505 if (this.hasOwnProperty('padding')) {
4506 if (this.padding) {
4507 for (let p = 0; p < plen; ++p) {
4508 heap[pos + len + p] = plen;
4509 }
4510 len += plen;
4511 rlen = len;
4512 }
4513 else if (len % 16) {
4514 throw new IllegalArgumentError('data length must be a multiple of the block size');
4515 }
4516 }
4517 else {
4518 len += plen;
4519 }
4520 const result = new Uint8Array(rlen);
4521 if (len)
4522 asm.cipher(amode, hpos + pos, len);
4523 if (rlen)
4524 result.set(heap.subarray(pos, pos + rlen));
4525 this.pos = 0;
4526 this.len = 0;
4527 this.release_asm();
4528 return result;
4529 }
4530 AES_Decrypt_process(data) {
4531 if (!is_bytes(data))
4532 throw new TypeError("data isn't of expected type");
4533 let { heap, asm } = this.acquire_asm();
4534 let amode = AES_asm.DEC[this.mode];
4535 let hpos = AES_asm.HEAP_DATA;
4536 let pos = this.pos;
4537 let len = this.len;
4538 let dpos = 0;
4539 let dlen = data.length || 0;
4540 let rpos = 0;
4541 let rlen = (len + dlen) & -16;
4542 let plen = 0;
4543 let wlen = 0;
4544 if (this.padding) {
4545 plen = len + dlen - rlen || 16;
4546 rlen -= plen;
4547 }
4548 const result = new Uint8Array(rlen);
4549 while (dlen > 0) {
4550 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
4551 len += wlen;
4552 dpos += wlen;
4553 dlen -= wlen;
4554 wlen = asm.cipher(amode, hpos + pos, len - (!dlen ? plen : 0));
4555 if (wlen)
4556 result.set(heap.subarray(pos, pos + wlen), rpos);
4557 rpos += wlen;
4558 if (wlen < len) {
4559 pos += wlen;
4560 len -= wlen;
4561 }
4562 else {
4563 pos = 0;
4564 len = 0;
4565 }
4566 }
4567 this.pos = pos;
4568 this.len = len;
4569 return result;
4570 }
4571 AES_Decrypt_finish() {
4572 let { heap, asm } = this.acquire_asm();
4573 let amode = AES_asm.DEC[this.mode];
4574 let hpos = AES_asm.HEAP_DATA;
4575 let pos = this.pos;
4576 let len = this.len;
4577 let rlen = len;
4578 if (len > 0) {
4579 if (len % 16) {
4580 if (this.hasOwnProperty('padding')) {
4581 throw new IllegalArgumentError('data length must be a multiple of the block size');
4582 }
4583 else {
4584 len += 16 - (len % 16);
4585 }
4586 }
4587 asm.cipher(amode, hpos + pos, len);
4588 if (this.hasOwnProperty('padding') && this.padding) {
4589 let pad = heap[pos + rlen - 1];
4590 if (pad < 1 || pad > 16 || pad > rlen)
4591 throw new SecurityError('bad padding');
4592 let pcheck = 0;
4593 for (let i = pad; i > 1; i--)
4594 pcheck |= pad ^ heap[pos + rlen - i];
4595 if (pcheck)
4596 throw new SecurityError('bad padding');
4597 rlen -= pad;
4598 }
4599 }
4600 const result = new Uint8Array(rlen);
4601 if (rlen > 0) {
4602 result.set(heap.subarray(pos, pos + rlen));
4603 }
4604 this.pos = 0;
4605 this.len = 0;
4606 this.release_asm();
4607 return result;
4608 }
4609}
4610
4611class AES_ECB {
4612 static encrypt(data, key, padding = false) {
4613 return new AES_ECB(key, padding).encrypt(data);
4614 }
4615 static decrypt(data, key, padding = false) {
4616 return new AES_ECB(key, padding).decrypt(data);
4617 }
4618 constructor(key, padding = false, aes) {
4619 this.aes = aes ? aes : new AES(key, undefined, padding, 'ECB');
4620 }
4621 encrypt(data) {
4622 const r1 = this.aes.AES_Encrypt_process(data);
4623 const r2 = this.aes.AES_Encrypt_finish();
4624 return joinBytes(r1, r2);
4625 }
4626 decrypt(data) {
4627 const r1 = this.aes.AES_Decrypt_process(data);
4628 const r2 = this.aes.AES_Decrypt_finish();
4629 return joinBytes(r1, r2);
4630 }
4631}
4632
4633/**
4634 * Javascript AES implementation.
4635 * This is used as fallback if the native Crypto APIs are not available.
4636 */
4637function aes(length) {
4638 const C = function(key) {
4639 const aesECB = new AES_ECB(key);
4640
4641 this.encrypt = function(block) {
4642 return aesECB.encrypt(block);
4643 };
4644
4645 this.decrypt = function(block) {
4646 return aesECB.decrypt(block);
4647 };
4648 };
4649
4650 C.blockSize = C.prototype.blockSize = 16;
4651 C.keySize = C.prototype.keySize = length / 8;
4652
4653 return C;
4654}
4655
4656//Paul Tero, July 2001
4657//http://www.tero.co.uk/des/
4658//
4659//Optimised for performance with large blocks by Michael Hayworth, November 2001
4660//http://www.netdealing.com
4661//
4662// Modified by Recurity Labs GmbH
4663
4664//THIS SOFTWARE IS PROVIDED "AS IS" AND
4665//ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4666//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4667//ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4668//FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4669//DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4670//OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4671//HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4672//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
4673//OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
4674//SUCH DAMAGE.
4675
4676//des
4677//this takes the key, the message, and whether to encrypt or decrypt
4678
4679function des(keys, message, encrypt, mode, iv, padding) {
4680 //declaring this locally speeds things up a bit
4681 const spfunction1 = [
4682 0x1010400, 0, 0x10000, 0x1010404, 0x1010004, 0x10404, 0x4, 0x10000, 0x400, 0x1010400,
4683 0x1010404, 0x400, 0x1000404, 0x1010004, 0x1000000, 0x4, 0x404, 0x1000400, 0x1000400, 0x10400, 0x10400, 0x1010000,
4684 0x1010000, 0x1000404, 0x10004, 0x1000004, 0x1000004, 0x10004, 0, 0x404, 0x10404, 0x1000000, 0x10000, 0x1010404, 0x4,
4685 0x1010000, 0x1010400, 0x1000000, 0x1000000, 0x400, 0x1010004, 0x10000, 0x10400, 0x1000004, 0x400, 0x4, 0x1000404,
4686 0x10404, 0x1010404, 0x10004, 0x1010000, 0x1000404, 0x1000004, 0x404, 0x10404, 0x1010400, 0x404, 0x1000400,
4687 0x1000400, 0, 0x10004, 0x10400, 0, 0x1010004
4688 ];
4689 const spfunction2 = [
4690 -0x7fef7fe0, -0x7fff8000, 0x8000, 0x108020, 0x100000, 0x20, -0x7fefffe0, -0x7fff7fe0,
4691 -0x7fffffe0, -0x7fef7fe0, -0x7fef8000, -0x80000000, -0x7fff8000, 0x100000, 0x20, -0x7fefffe0, 0x108000, 0x100020,
4692 -0x7fff7fe0, 0, -0x80000000, 0x8000, 0x108020, -0x7ff00000, 0x100020, -0x7fffffe0, 0, 0x108000, 0x8020, -0x7fef8000,
4693 -0x7ff00000, 0x8020, 0, 0x108020, -0x7fefffe0, 0x100000, -0x7fff7fe0, -0x7ff00000, -0x7fef8000, 0x8000, -0x7ff00000,
4694 -0x7fff8000, 0x20, -0x7fef7fe0, 0x108020, 0x20, 0x8000, -0x80000000, 0x8020, -0x7fef8000, 0x100000, -0x7fffffe0,
4695 0x100020, -0x7fff7fe0, -0x7fffffe0, 0x100020, 0x108000, 0, -0x7fff8000, 0x8020, -0x80000000, -0x7fefffe0,
4696 -0x7fef7fe0, 0x108000
4697 ];
4698 const spfunction3 = [
4699 0x208, 0x8020200, 0, 0x8020008, 0x8000200, 0, 0x20208, 0x8000200, 0x20008, 0x8000008,
4700 0x8000008, 0x20000, 0x8020208, 0x20008, 0x8020000, 0x208, 0x8000000, 0x8, 0x8020200, 0x200, 0x20200, 0x8020000,
4701 0x8020008, 0x20208, 0x8000208, 0x20200, 0x20000, 0x8000208, 0x8, 0x8020208, 0x200, 0x8000000, 0x8020200, 0x8000000,
4702 0x20008, 0x208, 0x20000, 0x8020200, 0x8000200, 0, 0x200, 0x20008, 0x8020208, 0x8000200, 0x8000008, 0x200, 0,
4703 0x8020008, 0x8000208, 0x20000, 0x8000000, 0x8020208, 0x8, 0x20208, 0x20200, 0x8000008, 0x8020000, 0x8000208, 0x208,
4704 0x8020000, 0x20208, 0x8, 0x8020008, 0x20200
4705 ];
4706 const spfunction4 = [
4707 0x802001, 0x2081, 0x2081, 0x80, 0x802080, 0x800081, 0x800001, 0x2001, 0, 0x802000,
4708 0x802000, 0x802081, 0x81, 0, 0x800080, 0x800001, 0x1, 0x2000, 0x800000, 0x802001, 0x80, 0x800000, 0x2001, 0x2080,
4709 0x800081, 0x1, 0x2080, 0x800080, 0x2000, 0x802080, 0x802081, 0x81, 0x800080, 0x800001, 0x802000, 0x802081, 0x81, 0,
4710 0, 0x802000, 0x2080, 0x800080, 0x800081, 0x1, 0x802001, 0x2081, 0x2081, 0x80, 0x802081, 0x81, 0x1, 0x2000, 0x800001,
4711 0x2001, 0x802080, 0x800081, 0x2001, 0x2080, 0x800000, 0x802001, 0x80, 0x800000, 0x2000, 0x802080
4712 ];
4713 const spfunction5 = [
4714 0x100, 0x2080100, 0x2080000, 0x42000100, 0x80000, 0x100, 0x40000000, 0x2080000,
4715 0x40080100, 0x80000, 0x2000100, 0x40080100, 0x42000100, 0x42080000, 0x80100, 0x40000000, 0x2000000, 0x40080000,
4716 0x40080000, 0, 0x40000100, 0x42080100, 0x42080100, 0x2000100, 0x42080000, 0x40000100, 0, 0x42000000, 0x2080100,
4717 0x2000000, 0x42000000, 0x80100, 0x80000, 0x42000100, 0x100, 0x2000000, 0x40000000, 0x2080000, 0x42000100,
4718 0x40080100, 0x2000100, 0x40000000, 0x42080000, 0x2080100, 0x40080100, 0x100, 0x2000000, 0x42080000, 0x42080100,
4719 0x80100, 0x42000000, 0x42080100, 0x2080000, 0, 0x40080000, 0x42000000, 0x80100, 0x2000100, 0x40000100, 0x80000, 0,
4720 0x40080000, 0x2080100, 0x40000100
4721 ];
4722 const spfunction6 = [
4723 0x20000010, 0x20400000, 0x4000, 0x20404010, 0x20400000, 0x10, 0x20404010, 0x400000,
4724 0x20004000, 0x404010, 0x400000, 0x20000010, 0x400010, 0x20004000, 0x20000000, 0x4010, 0, 0x400010, 0x20004010,
4725 0x4000, 0x404000, 0x20004010, 0x10, 0x20400010, 0x20400010, 0, 0x404010, 0x20404000, 0x4010, 0x404000, 0x20404000,
4726 0x20000000, 0x20004000, 0x10, 0x20400010, 0x404000, 0x20404010, 0x400000, 0x4010, 0x20000010, 0x400000, 0x20004000,
4727 0x20000000, 0x4010, 0x20000010, 0x20404010, 0x404000, 0x20400000, 0x404010, 0x20404000, 0, 0x20400010, 0x10, 0x4000,
4728 0x20400000, 0x404010, 0x4000, 0x400010, 0x20004010, 0, 0x20404000, 0x20000000, 0x400010, 0x20004010
4729 ];
4730 const spfunction7 = [
4731 0x200000, 0x4200002, 0x4000802, 0, 0x800, 0x4000802, 0x200802, 0x4200800, 0x4200802,
4732 0x200000, 0, 0x4000002, 0x2, 0x4000000, 0x4200002, 0x802, 0x4000800, 0x200802, 0x200002, 0x4000800, 0x4000002,
4733 0x4200000, 0x4200800, 0x200002, 0x4200000, 0x800, 0x802, 0x4200802, 0x200800, 0x2, 0x4000000, 0x200800, 0x4000000,
4734 0x200800, 0x200000, 0x4000802, 0x4000802, 0x4200002, 0x4200002, 0x2, 0x200002, 0x4000000, 0x4000800, 0x200000,
4735 0x4200800, 0x802, 0x200802, 0x4200800, 0x802, 0x4000002, 0x4200802, 0x4200000, 0x200800, 0, 0x2, 0x4200802, 0,
4736 0x200802, 0x4200000, 0x800, 0x4000002, 0x4000800, 0x800, 0x200002
4737 ];
4738 const spfunction8 = [
4739 0x10001040, 0x1000, 0x40000, 0x10041040, 0x10000000, 0x10001040, 0x40, 0x10000000,
4740 0x40040, 0x10040000, 0x10041040, 0x41000, 0x10041000, 0x41040, 0x1000, 0x40, 0x10040000, 0x10000040, 0x10001000,
4741 0x1040, 0x41000, 0x40040, 0x10040040, 0x10041000, 0x1040, 0, 0, 0x10040040, 0x10000040, 0x10001000, 0x41040,
4742 0x40000, 0x41040, 0x40000, 0x10041000, 0x1000, 0x40, 0x10040040, 0x1000, 0x41040, 0x10001000, 0x40, 0x10000040,
4743 0x10040000, 0x10040040, 0x10000000, 0x40000, 0x10001040, 0, 0x10041040, 0x40040, 0x10000040, 0x10040000, 0x10001000,
4744 0x10001040, 0, 0x10041040, 0x41000, 0x41000, 0x1040, 0x1040, 0x40040, 0x10000000, 0x10041000
4745 ];
4746
4747 //create the 16 or 48 subkeys we will need
4748 let m = 0;
4749 let i;
4750 let j;
4751 let temp;
4752 let right1;
4753 let right2;
4754 let left;
4755 let right;
4756 let looping;
4757 let cbcleft;
4758 let cbcleft2;
4759 let cbcright;
4760 let cbcright2;
4761 let endloop;
4762 let loopinc;
4763 let len = message.length;
4764
4765 //set up the loops for single and triple des
4766 const iterations = keys.length === 32 ? 3 : 9; //single or triple des
4767 if (iterations === 3) {
4768 looping = encrypt ? [0, 32, 2] : [30, -2, -2];
4769 } else {
4770 looping = encrypt ? [0, 32, 2, 62, 30, -2, 64, 96, 2] : [94, 62, -2, 32, 64, 2, 30, -2, -2];
4771 }
4772
4773 //pad the message depending on the padding parameter
4774 //only add padding if encrypting - note that you need to use the same padding option for both encrypt and decrypt
4775 if (encrypt) {
4776 message = desAddPadding(message, padding);
4777 len = message.length;
4778 }
4779
4780 //store the result here
4781 let result = new Uint8Array(len);
4782 let k = 0;
4783
4784 if (mode === 1) { //CBC mode
4785 cbcleft = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
4786 cbcright = (iv[m++] << 24) | (iv[m++] << 16) | (iv[m++] << 8) | iv[m++];
4787 m = 0;
4788 }
4789
4790 //loop through each 64 bit chunk of the message
4791 while (m < len) {
4792 left = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
4793 right = (message[m++] << 24) | (message[m++] << 16) | (message[m++] << 8) | message[m++];
4794
4795 //for Cipher Block Chaining mode, xor the message with the previous result
4796 if (mode === 1) {
4797 if (encrypt) {
4798 left ^= cbcleft;
4799 right ^= cbcright;
4800 } else {
4801 cbcleft2 = cbcleft;
4802 cbcright2 = cbcright;
4803 cbcleft = left;
4804 cbcright = right;
4805 }
4806 }
4807
4808 //first each 64 but chunk of the message must be permuted according to IP
4809 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
4810 right ^= temp;
4811 left ^= (temp << 4);
4812 temp = ((left >>> 16) ^ right) & 0x0000ffff;
4813 right ^= temp;
4814 left ^= (temp << 16);
4815 temp = ((right >>> 2) ^ left) & 0x33333333;
4816 left ^= temp;
4817 right ^= (temp << 2);
4818 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
4819 left ^= temp;
4820 right ^= (temp << 8);
4821 temp = ((left >>> 1) ^ right) & 0x55555555;
4822 right ^= temp;
4823 left ^= (temp << 1);
4824
4825 left = ((left << 1) | (left >>> 31));
4826 right = ((right << 1) | (right >>> 31));
4827
4828 //do this either 1 or 3 times for each chunk of the message
4829 for (j = 0; j < iterations; j += 3) {
4830 endloop = looping[j + 1];
4831 loopinc = looping[j + 2];
4832 //now go through and perform the encryption or decryption
4833 for (i = looping[j]; i !== endloop; i += loopinc) { //for efficiency
4834 right1 = right ^ keys[i];
4835 right2 = ((right >>> 4) | (right << 28)) ^ keys[i + 1];
4836 //the result is attained by passing these bytes through the S selection functions
4837 temp = left;
4838 left = right;
4839 right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f] | spfunction6[(right1 >>>
4840 8) & 0x3f] | spfunction8[right1 & 0x3f] | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) &
4841 0x3f] | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
4842 }
4843 temp = left;
4844 left = right;
4845 right = temp; //unreverse left and right
4846 } //for either 1 or 3 iterations
4847
4848 //move then each one bit to the right
4849 left = ((left >>> 1) | (left << 31));
4850 right = ((right >>> 1) | (right << 31));
4851
4852 //now perform IP-1, which is IP in the opposite direction
4853 temp = ((left >>> 1) ^ right) & 0x55555555;
4854 right ^= temp;
4855 left ^= (temp << 1);
4856 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
4857 left ^= temp;
4858 right ^= (temp << 8);
4859 temp = ((right >>> 2) ^ left) & 0x33333333;
4860 left ^= temp;
4861 right ^= (temp << 2);
4862 temp = ((left >>> 16) ^ right) & 0x0000ffff;
4863 right ^= temp;
4864 left ^= (temp << 16);
4865 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
4866 right ^= temp;
4867 left ^= (temp << 4);
4868
4869 //for Cipher Block Chaining mode, xor the message with the previous result
4870 if (mode === 1) {
4871 if (encrypt) {
4872 cbcleft = left;
4873 cbcright = right;
4874 } else {
4875 left ^= cbcleft2;
4876 right ^= cbcright2;
4877 }
4878 }
4879
4880 result[k++] = (left >>> 24);
4881 result[k++] = ((left >>> 16) & 0xff);
4882 result[k++] = ((left >>> 8) & 0xff);
4883 result[k++] = (left & 0xff);
4884 result[k++] = (right >>> 24);
4885 result[k++] = ((right >>> 16) & 0xff);
4886 result[k++] = ((right >>> 8) & 0xff);
4887 result[k++] = (right & 0xff);
4888 } //for every 8 characters, or 64 bits in the message
4889
4890 //only remove padding if decrypting - note that you need to use the same padding option for both encrypt and decrypt
4891 if (!encrypt) {
4892 result = desRemovePadding(result, padding);
4893 }
4894
4895 return result;
4896} //end of des
4897
4898
4899//desCreateKeys
4900//this takes as input a 64 bit key (even though only 56 bits are used)
4901//as an array of 2 integers, and returns 16 48 bit keys
4902
4903function desCreateKeys(key) {
4904 //declaring this locally speeds things up a bit
4905 const pc2bytes0 = [
4906 0, 0x4, 0x20000000, 0x20000004, 0x10000, 0x10004, 0x20010000, 0x20010004, 0x200, 0x204,
4907 0x20000200, 0x20000204, 0x10200, 0x10204, 0x20010200, 0x20010204
4908 ];
4909 const pc2bytes1 = [
4910 0, 0x1, 0x100000, 0x100001, 0x4000000, 0x4000001, 0x4100000, 0x4100001, 0x100, 0x101, 0x100100,
4911 0x100101, 0x4000100, 0x4000101, 0x4100100, 0x4100101
4912 ];
4913 const pc2bytes2 = [
4914 0, 0x8, 0x800, 0x808, 0x1000000, 0x1000008, 0x1000800, 0x1000808, 0, 0x8, 0x800, 0x808,
4915 0x1000000, 0x1000008, 0x1000800, 0x1000808
4916 ];
4917 const pc2bytes3 = [
4918 0, 0x200000, 0x8000000, 0x8200000, 0x2000, 0x202000, 0x8002000, 0x8202000, 0x20000, 0x220000,
4919 0x8020000, 0x8220000, 0x22000, 0x222000, 0x8022000, 0x8222000
4920 ];
4921 const pc2bytes4 = [
4922 0, 0x40000, 0x10, 0x40010, 0, 0x40000, 0x10, 0x40010, 0x1000, 0x41000, 0x1010, 0x41010, 0x1000,
4923 0x41000, 0x1010, 0x41010
4924 ];
4925 const pc2bytes5 = [
4926 0, 0x400, 0x20, 0x420, 0, 0x400, 0x20, 0x420, 0x2000000, 0x2000400, 0x2000020, 0x2000420,
4927 0x2000000, 0x2000400, 0x2000020, 0x2000420
4928 ];
4929 const pc2bytes6 = [
4930 0, 0x10000000, 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002, 0, 0x10000000,
4931 0x80000, 0x10080000, 0x2, 0x10000002, 0x80002, 0x10080002
4932 ];
4933 const pc2bytes7 = [
4934 0, 0x10000, 0x800, 0x10800, 0x20000000, 0x20010000, 0x20000800, 0x20010800, 0x20000, 0x30000,
4935 0x20800, 0x30800, 0x20020000, 0x20030000, 0x20020800, 0x20030800
4936 ];
4937 const pc2bytes8 = [
4938 0, 0x40000, 0, 0x40000, 0x2, 0x40002, 0x2, 0x40002, 0x2000000, 0x2040000, 0x2000000, 0x2040000,
4939 0x2000002, 0x2040002, 0x2000002, 0x2040002
4940 ];
4941 const pc2bytes9 = [
4942 0, 0x10000000, 0x8, 0x10000008, 0, 0x10000000, 0x8, 0x10000008, 0x400, 0x10000400, 0x408,
4943 0x10000408, 0x400, 0x10000400, 0x408, 0x10000408
4944 ];
4945 const pc2bytes10 = [
4946 0, 0x20, 0, 0x20, 0x100000, 0x100020, 0x100000, 0x100020, 0x2000, 0x2020, 0x2000, 0x2020,
4947 0x102000, 0x102020, 0x102000, 0x102020
4948 ];
4949 const pc2bytes11 = [
4950 0, 0x1000000, 0x200, 0x1000200, 0x200000, 0x1200000, 0x200200, 0x1200200, 0x4000000, 0x5000000,
4951 0x4000200, 0x5000200, 0x4200000, 0x5200000, 0x4200200, 0x5200200
4952 ];
4953 const pc2bytes12 = [
4954 0, 0x1000, 0x8000000, 0x8001000, 0x80000, 0x81000, 0x8080000, 0x8081000, 0x10, 0x1010,
4955 0x8000010, 0x8001010, 0x80010, 0x81010, 0x8080010, 0x8081010
4956 ];
4957 const pc2bytes13 = [0, 0x4, 0x100, 0x104, 0, 0x4, 0x100, 0x104, 0x1, 0x5, 0x101, 0x105, 0x1, 0x5, 0x101, 0x105];
4958
4959 //how many iterations (1 for des, 3 for triple des)
4960 const iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
4961 //stores the return keys
4962 const keys = new Array(32 * iterations);
4963 //now define the left shifts which need to be done
4964 const shifts = [0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0];
4965 //other variables
4966 let lefttemp;
4967 let righttemp;
4968 let m = 0;
4969 let n = 0;
4970 let temp;
4971
4972 for (let j = 0; j < iterations; j++) { //either 1 or 3 iterations
4973 let left = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
4974 let right = (key[m++] << 24) | (key[m++] << 16) | (key[m++] << 8) | key[m++];
4975
4976 temp = ((left >>> 4) ^ right) & 0x0f0f0f0f;
4977 right ^= temp;
4978 left ^= (temp << 4);
4979 temp = ((right >>> -16) ^ left) & 0x0000ffff;
4980 left ^= temp;
4981 right ^= (temp << -16);
4982 temp = ((left >>> 2) ^ right) & 0x33333333;
4983 right ^= temp;
4984 left ^= (temp << 2);
4985 temp = ((right >>> -16) ^ left) & 0x0000ffff;
4986 left ^= temp;
4987 right ^= (temp << -16);
4988 temp = ((left >>> 1) ^ right) & 0x55555555;
4989 right ^= temp;
4990 left ^= (temp << 1);
4991 temp = ((right >>> 8) ^ left) & 0x00ff00ff;
4992 left ^= temp;
4993 right ^= (temp << 8);
4994 temp = ((left >>> 1) ^ right) & 0x55555555;
4995 right ^= temp;
4996 left ^= (temp << 1);
4997
4998 //the right side needs to be shifted and to get the last four bits of the left side
4999 temp = (left << 8) | ((right >>> 20) & 0x000000f0);
5000 //left needs to be put upside down
5001 left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
5002 right = temp;
5003
5004 //now go through and perform these shifts on the left and right keys
5005 for (let i = 0; i < shifts.length; i++) {
5006 //shift the keys either one or two bits to the left
5007 if (shifts[i]) {
5008 left = (left << 2) | (left >>> 26);
5009 right = (right << 2) | (right >>> 26);
5010 } else {
5011 left = (left << 1) | (left >>> 27);
5012 right = (right << 1) | (right >>> 27);
5013 }
5014 left &= -0xf;
5015 right &= -0xf;
5016
5017 //now apply PC-2, in such a way that E is easier when encrypting or decrypting
5018 //this conversion will look like PC-2 except only the last 6 bits of each byte are used
5019 //rather than 48 consecutive bits and the order of lines will be according to
5020 //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
5021 lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf] | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(
5022 left >>> 16) & 0xf] | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf] | pc2bytes6[(left >>> 4) &
5023 0xf];
5024 righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf] | pc2bytes9[(right >>> 20) & 0xf] |
5025 pc2bytes10[(right >>> 16) & 0xf] | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf] |
5026 pc2bytes13[(right >>> 4) & 0xf];
5027 temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
5028 keys[n++] = lefttemp ^ temp;
5029 keys[n++] = righttemp ^ (temp << 16);
5030 }
5031 } //for each iterations
5032 //return the keys we've created
5033 return keys;
5034} //end of desCreateKeys
5035
5036
5037function desAddPadding(message, padding) {
5038 const padLength = 8 - (message.length % 8);
5039
5040 let pad;
5041 if (padding === 2 && (padLength < 8)) { //pad the message with spaces
5042 pad = ' '.charCodeAt(0);
5043 } else if (padding === 1) { //PKCS7 padding
5044 pad = padLength;
5045 } else if (!padding && (padLength < 8)) { //pad the message out with null bytes
5046 pad = 0;
5047 } else if (padLength === 8) {
5048 return message;
5049 } else {
5050 throw new Error('des: invalid padding');
5051 }
5052
5053 const paddedMessage = new Uint8Array(message.length + padLength);
5054 for (let i = 0; i < message.length; i++) {
5055 paddedMessage[i] = message[i];
5056 }
5057 for (let j = 0; j < padLength; j++) {
5058 paddedMessage[message.length + j] = pad;
5059 }
5060
5061 return paddedMessage;
5062}
5063
5064function desRemovePadding(message, padding) {
5065 let padLength = null;
5066 let pad;
5067 if (padding === 2) { // space padded
5068 pad = ' '.charCodeAt(0);
5069 } else if (padding === 1) { // PKCS7
5070 padLength = message[message.length - 1];
5071 } else if (!padding) { // null padding
5072 pad = 0;
5073 } else {
5074 throw new Error('des: invalid padding');
5075 }
5076
5077 if (!padLength) {
5078 padLength = 1;
5079 while (message[message.length - padLength] === pad) {
5080 padLength++;
5081 }
5082 padLength--;
5083 }
5084
5085 return message.subarray(0, message.length - padLength);
5086}
5087
5088// added by Recurity Labs
5089
5090function TripleDES(key) {
5091 this.key = [];
5092
5093 for (let i = 0; i < 3; i++) {
5094 this.key.push(new Uint8Array(key.subarray(i * 8, (i * 8) + 8)));
5095 }
5096
5097 this.encrypt = function(block) {
5098 return des(
5099 desCreateKeys(this.key[2]),
5100 des(
5101 desCreateKeys(this.key[1]),
5102 des(
5103 desCreateKeys(this.key[0]),
5104 block, true, 0, null, null
5105 ),
5106 false, 0, null, null
5107 ), true, 0, null, null
5108 );
5109 };
5110}
5111
5112TripleDES.keySize = TripleDES.prototype.keySize = 24;
5113TripleDES.blockSize = TripleDES.prototype.blockSize = 8;
5114
5115// This is "original" DES
5116
5117function DES(key) {
5118 this.key = key;
5119
5120 this.encrypt = function(block, padding) {
5121 const keys = desCreateKeys(this.key);
5122 return des(keys, block, true, 0, null, padding);
5123 };
5124
5125 this.decrypt = function(block, padding) {
5126 const keys = desCreateKeys(this.key);
5127 return des(keys, block, false, 0, null, padding);
5128 };
5129}
5130
5131// Use of this source code is governed by a BSD-style
5132// license that can be found in the LICENSE file.
5133
5134// Copyright 2010 pjacobs@xeekr.com . All rights reserved.
5135
5136// Modified by Recurity Labs GmbH
5137
5138// fixed/modified by Herbert Hanewinkel, www.haneWIN.de
5139// check www.haneWIN.de for the latest version
5140
5141// cast5.js is a Javascript implementation of CAST-128, as defined in RFC 2144.
5142// CAST-128 is a common OpenPGP cipher.
5143
5144
5145// CAST5 constructor
5146
5147function OpenPGPSymEncCAST5() {
5148 this.BlockSize = 8;
5149 this.KeySize = 16;
5150
5151 this.setKey = function(key) {
5152 this.masking = new Array(16);
5153 this.rotate = new Array(16);
5154
5155 this.reset();
5156
5157 if (key.length === this.KeySize) {
5158 this.keySchedule(key);
5159 } else {
5160 throw new Error('CAST-128: keys must be 16 bytes');
5161 }
5162 return true;
5163 };
5164
5165 this.reset = function() {
5166 for (let i = 0; i < 16; i++) {
5167 this.masking[i] = 0;
5168 this.rotate[i] = 0;
5169 }
5170 };
5171
5172 this.getBlockSize = function() {
5173 return this.BlockSize;
5174 };
5175
5176 this.encrypt = function(src) {
5177 const dst = new Array(src.length);
5178
5179 for (let i = 0; i < src.length; i += 8) {
5180 let l = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
5181 let r = (src[i + 4] << 24) | (src[i + 5] << 16) | (src[i + 6] << 8) | src[i + 7];
5182 let t;
5183
5184 t = r;
5185 r = l ^ f1(r, this.masking[0], this.rotate[0]);
5186 l = t;
5187 t = r;
5188 r = l ^ f2(r, this.masking[1], this.rotate[1]);
5189 l = t;
5190 t = r;
5191 r = l ^ f3(r, this.masking[2], this.rotate[2]);
5192 l = t;
5193 t = r;
5194 r = l ^ f1(r, this.masking[3], this.rotate[3]);
5195 l = t;
5196
5197 t = r;
5198 r = l ^ f2(r, this.masking[4], this.rotate[4]);
5199 l = t;
5200 t = r;
5201 r = l ^ f3(r, this.masking[5], this.rotate[5]);
5202 l = t;
5203 t = r;
5204 r = l ^ f1(r, this.masking[6], this.rotate[6]);
5205 l = t;
5206 t = r;
5207 r = l ^ f2(r, this.masking[7], this.rotate[7]);
5208 l = t;
5209
5210 t = r;
5211 r = l ^ f3(r, this.masking[8], this.rotate[8]);
5212 l = t;
5213 t = r;
5214 r = l ^ f1(r, this.masking[9], this.rotate[9]);
5215 l = t;
5216 t = r;
5217 r = l ^ f2(r, this.masking[10], this.rotate[10]);
5218 l = t;
5219 t = r;
5220 r = l ^ f3(r, this.masking[11], this.rotate[11]);
5221 l = t;
5222
5223 t = r;
5224 r = l ^ f1(r, this.masking[12], this.rotate[12]);
5225 l = t;
5226 t = r;
5227 r = l ^ f2(r, this.masking[13], this.rotate[13]);
5228 l = t;
5229 t = r;
5230 r = l ^ f3(r, this.masking[14], this.rotate[14]);
5231 l = t;
5232 t = r;
5233 r = l ^ f1(r, this.masking[15], this.rotate[15]);
5234 l = t;
5235
5236 dst[i] = (r >>> 24) & 255;
5237 dst[i + 1] = (r >>> 16) & 255;
5238 dst[i + 2] = (r >>> 8) & 255;
5239 dst[i + 3] = r & 255;
5240 dst[i + 4] = (l >>> 24) & 255;
5241 dst[i + 5] = (l >>> 16) & 255;
5242 dst[i + 6] = (l >>> 8) & 255;
5243 dst[i + 7] = l & 255;
5244 }
5245
5246 return dst;
5247 };
5248
5249 this.decrypt = function(src) {
5250 const dst = new Array(src.length);
5251
5252 for (let i = 0; i < src.length; i += 8) {
5253 let l = (src[i] << 24) | (src[i + 1] << 16) | (src[i + 2] << 8) | src[i + 3];
5254 let r = (src[i + 4] << 24) | (src[i + 5] << 16) | (src[i + 6] << 8) | src[i + 7];
5255 let t;
5256
5257 t = r;
5258 r = l ^ f1(r, this.masking[15], this.rotate[15]);
5259 l = t;
5260 t = r;
5261 r = l ^ f3(r, this.masking[14], this.rotate[14]);
5262 l = t;
5263 t = r;
5264 r = l ^ f2(r, this.masking[13], this.rotate[13]);
5265 l = t;
5266 t = r;
5267 r = l ^ f1(r, this.masking[12], this.rotate[12]);
5268 l = t;
5269
5270 t = r;
5271 r = l ^ f3(r, this.masking[11], this.rotate[11]);
5272 l = t;
5273 t = r;
5274 r = l ^ f2(r, this.masking[10], this.rotate[10]);
5275 l = t;
5276 t = r;
5277 r = l ^ f1(r, this.masking[9], this.rotate[9]);
5278 l = t;
5279 t = r;
5280 r = l ^ f3(r, this.masking[8], this.rotate[8]);
5281 l = t;
5282
5283 t = r;
5284 r = l ^ f2(r, this.masking[7], this.rotate[7]);
5285 l = t;
5286 t = r;
5287 r = l ^ f1(r, this.masking[6], this.rotate[6]);
5288 l = t;
5289 t = r;
5290 r = l ^ f3(r, this.masking[5], this.rotate[5]);
5291 l = t;
5292 t = r;
5293 r = l ^ f2(r, this.masking[4], this.rotate[4]);
5294 l = t;
5295
5296 t = r;
5297 r = l ^ f1(r, this.masking[3], this.rotate[3]);
5298 l = t;
5299 t = r;
5300 r = l ^ f3(r, this.masking[2], this.rotate[2]);
5301 l = t;
5302 t = r;
5303 r = l ^ f2(r, this.masking[1], this.rotate[1]);
5304 l = t;
5305 t = r;
5306 r = l ^ f1(r, this.masking[0], this.rotate[0]);
5307 l = t;
5308
5309 dst[i] = (r >>> 24) & 255;
5310 dst[i + 1] = (r >>> 16) & 255;
5311 dst[i + 2] = (r >>> 8) & 255;
5312 dst[i + 3] = r & 255;
5313 dst[i + 4] = (l >>> 24) & 255;
5314 dst[i + 5] = (l >> 16) & 255;
5315 dst[i + 6] = (l >> 8) & 255;
5316 dst[i + 7] = l & 255;
5317 }
5318
5319 return dst;
5320 };
5321 const scheduleA = new Array(4);
5322
5323 scheduleA[0] = new Array(4);
5324 scheduleA[0][0] = [4, 0, 0xd, 0xf, 0xc, 0xe, 0x8];
5325 scheduleA[0][1] = [5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa];
5326 scheduleA[0][2] = [6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9];
5327 scheduleA[0][3] = [7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb];
5328
5329 scheduleA[1] = new Array(4);
5330 scheduleA[1][0] = [0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0];
5331 scheduleA[1][1] = [1, 4, 0, 2, 1, 3, 16 + 2];
5332 scheduleA[1][2] = [2, 5, 7, 6, 5, 4, 16 + 1];
5333 scheduleA[1][3] = [3, 7, 0xa, 9, 0xb, 8, 16 + 3];
5334
5335 scheduleA[2] = new Array(4);
5336 scheduleA[2][0] = [4, 0, 0xd, 0xf, 0xc, 0xe, 8];
5337 scheduleA[2][1] = [5, 2, 16 + 0, 16 + 2, 16 + 1, 16 + 3, 0xa];
5338 scheduleA[2][2] = [6, 3, 16 + 7, 16 + 6, 16 + 5, 16 + 4, 9];
5339 scheduleA[2][3] = [7, 1, 16 + 0xa, 16 + 9, 16 + 0xb, 16 + 8, 0xb];
5340
5341
5342 scheduleA[3] = new Array(4);
5343 scheduleA[3][0] = [0, 6, 16 + 5, 16 + 7, 16 + 4, 16 + 6, 16 + 0];
5344 scheduleA[3][1] = [1, 4, 0, 2, 1, 3, 16 + 2];
5345 scheduleA[3][2] = [2, 5, 7, 6, 5, 4, 16 + 1];
5346 scheduleA[3][3] = [3, 7, 0xa, 9, 0xb, 8, 16 + 3];
5347
5348 const scheduleB = new Array(4);
5349
5350 scheduleB[0] = new Array(4);
5351 scheduleB[0][0] = [16 + 8, 16 + 9, 16 + 7, 16 + 6, 16 + 2];
5352 scheduleB[0][1] = [16 + 0xa, 16 + 0xb, 16 + 5, 16 + 4, 16 + 6];
5353 scheduleB[0][2] = [16 + 0xc, 16 + 0xd, 16 + 3, 16 + 2, 16 + 9];
5354 scheduleB[0][3] = [16 + 0xe, 16 + 0xf, 16 + 1, 16 + 0, 16 + 0xc];
5355
5356 scheduleB[1] = new Array(4);
5357 scheduleB[1][0] = [3, 2, 0xc, 0xd, 8];
5358 scheduleB[1][1] = [1, 0, 0xe, 0xf, 0xd];
5359 scheduleB[1][2] = [7, 6, 8, 9, 3];
5360 scheduleB[1][3] = [5, 4, 0xa, 0xb, 7];
5361
5362
5363 scheduleB[2] = new Array(4);
5364 scheduleB[2][0] = [16 + 3, 16 + 2, 16 + 0xc, 16 + 0xd, 16 + 9];
5365 scheduleB[2][1] = [16 + 1, 16 + 0, 16 + 0xe, 16 + 0xf, 16 + 0xc];
5366 scheduleB[2][2] = [16 + 7, 16 + 6, 16 + 8, 16 + 9, 16 + 2];
5367 scheduleB[2][3] = [16 + 5, 16 + 4, 16 + 0xa, 16 + 0xb, 16 + 6];
5368
5369
5370 scheduleB[3] = new Array(4);
5371 scheduleB[3][0] = [8, 9, 7, 6, 3];
5372 scheduleB[3][1] = [0xa, 0xb, 5, 4, 7];
5373 scheduleB[3][2] = [0xc, 0xd, 3, 2, 8];
5374 scheduleB[3][3] = [0xe, 0xf, 1, 0, 0xd];
5375
5376 // changed 'in' to 'inn' (in javascript 'in' is a reserved word)
5377 this.keySchedule = function(inn) {
5378 const t = new Array(8);
5379 const k = new Array(32);
5380
5381 let j;
5382
5383 for (let i = 0; i < 4; i++) {
5384 j = i * 4;
5385 t[i] = (inn[j] << 24) | (inn[j + 1] << 16) | (inn[j + 2] << 8) | inn[j + 3];
5386 }
5387
5388 const x = [6, 7, 4, 5];
5389 let ki = 0;
5390 let w;
5391
5392 for (let half = 0; half < 2; half++) {
5393 for (let round = 0; round < 4; round++) {
5394 for (j = 0; j < 4; j++) {
5395 const a = scheduleA[round][j];
5396 w = t[a[1]];
5397
5398 w ^= sBox[4][(t[a[2] >>> 2] >>> (24 - 8 * (a[2] & 3))) & 0xff];
5399 w ^= sBox[5][(t[a[3] >>> 2] >>> (24 - 8 * (a[3] & 3))) & 0xff];
5400 w ^= sBox[6][(t[a[4] >>> 2] >>> (24 - 8 * (a[4] & 3))) & 0xff];
5401 w ^= sBox[7][(t[a[5] >>> 2] >>> (24 - 8 * (a[5] & 3))) & 0xff];
5402 w ^= sBox[x[j]][(t[a[6] >>> 2] >>> (24 - 8 * (a[6] & 3))) & 0xff];
5403 t[a[0]] = w;
5404 }
5405
5406 for (j = 0; j < 4; j++) {
5407 const b = scheduleB[round][j];
5408 w = sBox[4][(t[b[0] >>> 2] >>> (24 - 8 * (b[0] & 3))) & 0xff];
5409
5410 w ^= sBox[5][(t[b[1] >>> 2] >>> (24 - 8 * (b[1] & 3))) & 0xff];
5411 w ^= sBox[6][(t[b[2] >>> 2] >>> (24 - 8 * (b[2] & 3))) & 0xff];
5412 w ^= sBox[7][(t[b[3] >>> 2] >>> (24 - 8 * (b[3] & 3))) & 0xff];
5413 w ^= sBox[4 + j][(t[b[4] >>> 2] >>> (24 - 8 * (b[4] & 3))) & 0xff];
5414 k[ki] = w;
5415 ki++;
5416 }
5417 }
5418 }
5419
5420 for (let i = 0; i < 16; i++) {
5421 this.masking[i] = k[i];
5422 this.rotate[i] = k[16 + i] & 0x1f;
5423 }
5424 };
5425
5426 // These are the three 'f' functions. See RFC 2144, section 2.2.
5427
5428 function f1(d, m, r) {
5429 const t = m + d;
5430 const I = (t << r) | (t >>> (32 - r));
5431 return ((sBox[0][I >>> 24] ^ sBox[1][(I >>> 16) & 255]) - sBox[2][(I >>> 8) & 255]) + sBox[3][I & 255];
5432 }
5433
5434 function f2(d, m, r) {
5435 const t = m ^ d;
5436 const I = (t << r) | (t >>> (32 - r));
5437 return ((sBox[0][I >>> 24] - sBox[1][(I >>> 16) & 255]) + sBox[2][(I >>> 8) & 255]) ^ sBox[3][I & 255];
5438 }
5439
5440 function f3(d, m, r) {
5441 const t = m - d;
5442 const I = (t << r) | (t >>> (32 - r));
5443 return ((sBox[0][I >>> 24] + sBox[1][(I >>> 16) & 255]) ^ sBox[2][(I >>> 8) & 255]) - sBox[3][I & 255];
5444 }
5445
5446 const sBox = new Array(8);
5447 sBox[0] = [
5448 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
5449 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
5450 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
5451 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0,
5452 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7,
5453 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
5454 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d,
5455 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50,
5456 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
5457 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3,
5458 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167,
5459 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
5460 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779,
5461 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2,
5462 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
5463 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d,
5464 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5,
5465 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
5466 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c,
5467 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc,
5468 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
5469 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96,
5470 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a,
5471 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
5472 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd,
5473 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6,
5474 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
5475 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872,
5476 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c,
5477 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
5478 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
5479 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
5480 ];
5481
5482 sBox[1] = [
5483 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
5484 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
5485 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
5486 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806,
5487 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b,
5488 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
5489 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b,
5490 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c,
5491 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
5492 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb,
5493 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd,
5494 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
5495 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b,
5496 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304,
5497 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
5498 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf,
5499 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c,
5500 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
5501 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f,
5502 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6,
5503 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
5504 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58,
5505 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906,
5506 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
5507 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6,
5508 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4,
5509 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
5510 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f,
5511 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249,
5512 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
5513 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
5514 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
5515 ];
5516
5517 sBox[2] = [
5518 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
5519 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
5520 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
5521 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240,
5522 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5,
5523 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
5524 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71,
5525 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04,
5526 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
5527 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15,
5528 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2,
5529 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
5530 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148,
5531 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc,
5532 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
5533 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e,
5534 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51,
5535 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
5536 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a,
5537 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b,
5538 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
5539 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5,
5540 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45,
5541 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
5542 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc,
5543 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0,
5544 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
5545 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2,
5546 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49,
5547 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
5548 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
5549 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
5550 ];
5551
5552 sBox[3] = [
5553 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
5554 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
5555 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
5556 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121,
5557 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25,
5558 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
5559 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb,
5560 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5,
5561 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
5562 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6,
5563 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23,
5564 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
5565 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6,
5566 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119,
5567 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
5568 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a,
5569 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79,
5570 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
5571 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26,
5572 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab,
5573 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
5574 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417,
5575 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2,
5576 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
5577 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a,
5578 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919,
5579 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
5580 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876,
5581 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab,
5582 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
5583 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
5584 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
5585 ];
5586
5587 sBox[4] = [
5588 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
5589 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
5590 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
5591 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02,
5592 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a,
5593 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
5594 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9,
5595 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981,
5596 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
5597 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655,
5598 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2,
5599 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
5600 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1,
5601 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da,
5602 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
5603 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f,
5604 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba,
5605 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
5606 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3,
5607 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840,
5608 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
5609 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2,
5610 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7,
5611 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
5612 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e,
5613 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e,
5614 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
5615 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad,
5616 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0,
5617 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
5618 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8,
5619 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4
5620 ];
5621
5622 sBox[5] = [
5623 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac,
5624 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138,
5625 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
5626 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98,
5627 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072,
5628 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
5629 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd,
5630 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8,
5631 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
5632 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54,
5633 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387,
5634 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
5635 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf,
5636 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf,
5637 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
5638 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289,
5639 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950,
5640 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
5641 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b,
5642 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be,
5643 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
5644 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976,
5645 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0,
5646 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
5647 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da,
5648 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc,
5649 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
5650 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25,
5651 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121,
5652 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
5653 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd,
5654 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f
5655 ];
5656
5657 sBox[6] = [
5658 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f,
5659 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de,
5660 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
5661 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19,
5662 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2,
5663 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
5664 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88,
5665 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816,
5666 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
5667 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a,
5668 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264,
5669 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
5670 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28,
5671 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3,
5672 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
5673 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06,
5674 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033,
5675 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
5676 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566,
5677 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509,
5678 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
5679 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e,
5680 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c,
5681 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
5682 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285,
5683 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301,
5684 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
5685 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767,
5686 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647,
5687 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
5688 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c,
5689 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3
5690 ];
5691
5692 sBox[7] = [
5693 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5,
5694 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc,
5695 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
5696 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d,
5697 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2,
5698 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
5699 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc,
5700 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c,
5701 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
5702 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039,
5703 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8,
5704 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
5705 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5,
5706 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472,
5707 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
5708 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c,
5709 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb,
5710 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
5711 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70,
5712 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc,
5713 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
5714 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3,
5715 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4,
5716 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
5717 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f,
5718 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e,
5719 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
5720 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c,
5721 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384,
5722 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
5723 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82,
5724 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e
5725 ];
5726}
5727
5728function CAST5(key) {
5729 this.cast5 = new OpenPGPSymEncCAST5();
5730 this.cast5.setKey(key);
5731
5732 this.encrypt = function(block) {
5733 return this.cast5.encrypt(block);
5734 };
5735}
5736
5737CAST5.blockSize = CAST5.prototype.blockSize = 8;
5738CAST5.keySize = CAST5.prototype.keySize = 16;
5739
5740/* eslint-disable no-mixed-operators, no-fallthrough */
5741
5742
5743/* Modified by Recurity Labs GmbH
5744 *
5745 * Cipher.js
5746 * A block-cipher algorithm implementation on JavaScript
5747 * See Cipher.readme.txt for further information.
5748 *
5749 * Copyright(c) 2009 Atsushi Oka [ http://oka.nu/ ]
5750 * This script file is distributed under the LGPL
5751 *
5752 * ACKNOWLEDGMENT
5753 *
5754 * The main subroutines are written by Michiel van Everdingen.
5755 *
5756 * Michiel van Everdingen
5757 * http://home.versatel.nl/MAvanEverdingen/index.html
5758 *
5759 * All rights for these routines are reserved to Michiel van Everdingen.
5760 *
5761 */
5762
5763////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5764//Math
5765////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5766
5767const MAXINT = 0xFFFFFFFF;
5768
5769function rotw(w, n) {
5770 return (w << n | w >>> (32 - n)) & MAXINT;
5771}
5772
5773function getW(a, i) {
5774 return a[i] | a[i + 1] << 8 | a[i + 2] << 16 | a[i + 3] << 24;
5775}
5776
5777function setW(a, i, w) {
5778 a.splice(i, 4, w & 0xFF, (w >>> 8) & 0xFF, (w >>> 16) & 0xFF, (w >>> 24) & 0xFF);
5779}
5780
5781function getB(x, n) {
5782 return (x >>> (n * 8)) & 0xFF;
5783}
5784
5785// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5786// Twofish
5787// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
5788
5789function createTwofish() {
5790 //
5791 let keyBytes = null;
5792 let dataBytes = null;
5793 let dataOffset = -1;
5794 // var dataLength = -1;
5795 // var idx2 = -1;
5796 //
5797
5798 let tfsKey = [];
5799 let tfsM = [
5800 [],
5801 [],
5802 [],
5803 []
5804 ];
5805
5806 function tfsInit(key) {
5807 keyBytes = key;
5808 let i;
5809 let a;
5810 let b;
5811 let c;
5812 let d;
5813 const meKey = [];
5814 const moKey = [];
5815 const inKey = [];
5816 let kLen;
5817 const sKey = [];
5818 let f01;
5819 let f5b;
5820 let fef;
5821
5822 const q0 = [
5823 [8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4],
5824 [2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5]
5825 ];
5826 const q1 = [
5827 [14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13],
5828 [1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8]
5829 ];
5830 const q2 = [
5831 [11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1],
5832 [4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15]
5833 ];
5834 const q3 = [
5835 [13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10],
5836 [11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10]
5837 ];
5838 const ror4 = [0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15];
5839 const ashx = [0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7];
5840 const q = [
5841 [],
5842 []
5843 ];
5844 const m = [
5845 [],
5846 [],
5847 [],
5848 []
5849 ];
5850
5851 function ffm5b(x) {
5852 return x ^ (x >> 2) ^ [0, 90, 180, 238][x & 3];
5853 }
5854
5855 function ffmEf(x) {
5856 return x ^ (x >> 1) ^ (x >> 2) ^ [0, 238, 180, 90][x & 3];
5857 }
5858
5859 function mdsRem(p, q) {
5860 let i;
5861 let t;
5862 let u;
5863 for (i = 0; i < 8; i++) {
5864 t = q >>> 24;
5865 q = ((q << 8) & MAXINT) | p >>> 24;
5866 p = (p << 8) & MAXINT;
5867 u = t << 1;
5868 if (t & 128) {
5869 u ^= 333;
5870 }
5871 q ^= t ^ (u << 16);
5872 u ^= t >>> 1;
5873 if (t & 1) {
5874 u ^= 166;
5875 }
5876 q ^= u << 24 | u << 8;
5877 }
5878 return q;
5879 }
5880
5881 function qp(n, x) {
5882 const a = x >> 4;
5883 const b = x & 15;
5884 const c = q0[n][a ^ b];
5885 const d = q1[n][ror4[b] ^ ashx[a]];
5886 return q3[n][ror4[d] ^ ashx[c]] << 4 | q2[n][c ^ d];
5887 }
5888
5889 function hFun(x, key) {
5890 let a = getB(x, 0);
5891 let b = getB(x, 1);
5892 let c = getB(x, 2);
5893 let d = getB(x, 3);
5894 switch (kLen) {
5895 case 4:
5896 a = q[1][a] ^ getB(key[3], 0);
5897 b = q[0][b] ^ getB(key[3], 1);
5898 c = q[0][c] ^ getB(key[3], 2);
5899 d = q[1][d] ^ getB(key[3], 3);
5900 case 3:
5901 a = q[1][a] ^ getB(key[2], 0);
5902 b = q[1][b] ^ getB(key[2], 1);
5903 c = q[0][c] ^ getB(key[2], 2);
5904 d = q[0][d] ^ getB(key[2], 3);
5905 case 2:
5906 a = q[0][q[0][a] ^ getB(key[1], 0)] ^ getB(key[0], 0);
5907 b = q[0][q[1][b] ^ getB(key[1], 1)] ^ getB(key[0], 1);
5908 c = q[1][q[0][c] ^ getB(key[1], 2)] ^ getB(key[0], 2);
5909 d = q[1][q[1][d] ^ getB(key[1], 3)] ^ getB(key[0], 3);
5910 }
5911 return m[0][a] ^ m[1][b] ^ m[2][c] ^ m[3][d];
5912 }
5913
5914 keyBytes = keyBytes.slice(0, 32);
5915 i = keyBytes.length;
5916 while (i !== 16 && i !== 24 && i !== 32) {
5917 keyBytes[i++] = 0;
5918 }
5919
5920 for (i = 0; i < keyBytes.length; i += 4) {
5921 inKey[i >> 2] = getW(keyBytes, i);
5922 }
5923 for (i = 0; i < 256; i++) {
5924 q[0][i] = qp(0, i);
5925 q[1][i] = qp(1, i);
5926 }
5927 for (i = 0; i < 256; i++) {
5928 f01 = q[1][i];
5929 f5b = ffm5b(f01);
5930 fef = ffmEf(f01);
5931 m[0][i] = f01 + (f5b << 8) + (fef << 16) + (fef << 24);
5932 m[2][i] = f5b + (fef << 8) + (f01 << 16) + (fef << 24);
5933 f01 = q[0][i];
5934 f5b = ffm5b(f01);
5935 fef = ffmEf(f01);
5936 m[1][i] = fef + (fef << 8) + (f5b << 16) + (f01 << 24);
5937 m[3][i] = f5b + (f01 << 8) + (fef << 16) + (f5b << 24);
5938 }
5939
5940 kLen = inKey.length / 2;
5941 for (i = 0; i < kLen; i++) {
5942 a = inKey[i + i];
5943 meKey[i] = a;
5944 b = inKey[i + i + 1];
5945 moKey[i] = b;
5946 sKey[kLen - i - 1] = mdsRem(a, b);
5947 }
5948 for (i = 0; i < 40; i += 2) {
5949 a = 0x1010101 * i;
5950 b = a + 0x1010101;
5951 a = hFun(a, meKey);
5952 b = rotw(hFun(b, moKey), 8);
5953 tfsKey[i] = (a + b) & MAXINT;
5954 tfsKey[i + 1] = rotw(a + 2 * b, 9);
5955 }
5956 for (i = 0; i < 256; i++) {
5957 a = b = c = d = i;
5958 switch (kLen) {
5959 case 4:
5960 a = q[1][a] ^ getB(sKey[3], 0);
5961 b = q[0][b] ^ getB(sKey[3], 1);
5962 c = q[0][c] ^ getB(sKey[3], 2);
5963 d = q[1][d] ^ getB(sKey[3], 3);
5964 case 3:
5965 a = q[1][a] ^ getB(sKey[2], 0);
5966 b = q[1][b] ^ getB(sKey[2], 1);
5967 c = q[0][c] ^ getB(sKey[2], 2);
5968 d = q[0][d] ^ getB(sKey[2], 3);
5969 case 2:
5970 tfsM[0][i] = m[0][q[0][q[0][a] ^ getB(sKey[1], 0)] ^ getB(sKey[0], 0)];
5971 tfsM[1][i] = m[1][q[0][q[1][b] ^ getB(sKey[1], 1)] ^ getB(sKey[0], 1)];
5972 tfsM[2][i] = m[2][q[1][q[0][c] ^ getB(sKey[1], 2)] ^ getB(sKey[0], 2)];
5973 tfsM[3][i] = m[3][q[1][q[1][d] ^ getB(sKey[1], 3)] ^ getB(sKey[0], 3)];
5974 }
5975 }
5976 }
5977
5978 function tfsG0(x) {
5979 return tfsM[0][getB(x, 0)] ^ tfsM[1][getB(x, 1)] ^ tfsM[2][getB(x, 2)] ^ tfsM[3][getB(x, 3)];
5980 }
5981
5982 function tfsG1(x) {
5983 return tfsM[0][getB(x, 3)] ^ tfsM[1][getB(x, 0)] ^ tfsM[2][getB(x, 1)] ^ tfsM[3][getB(x, 2)];
5984 }
5985
5986 function tfsFrnd(r, blk) {
5987 let a = tfsG0(blk[0]);
5988 let b = tfsG1(blk[1]);
5989 blk[2] = rotw(blk[2] ^ (a + b + tfsKey[4 * r + 8]) & MAXINT, 31);
5990 blk[3] = rotw(blk[3], 1) ^ (a + 2 * b + tfsKey[4 * r + 9]) & MAXINT;
5991 a = tfsG0(blk[2]);
5992 b = tfsG1(blk[3]);
5993 blk[0] = rotw(blk[0] ^ (a + b + tfsKey[4 * r + 10]) & MAXINT, 31);
5994 blk[1] = rotw(blk[1], 1) ^ (a + 2 * b + tfsKey[4 * r + 11]) & MAXINT;
5995 }
5996
5997 function tfsIrnd(i, blk) {
5998 let a = tfsG0(blk[0]);
5999 let b = tfsG1(blk[1]);
6000 blk[2] = rotw(blk[2], 1) ^ (a + b + tfsKey[4 * i + 10]) & MAXINT;
6001 blk[3] = rotw(blk[3] ^ (a + 2 * b + tfsKey[4 * i + 11]) & MAXINT, 31);
6002 a = tfsG0(blk[2]);
6003 b = tfsG1(blk[3]);
6004 blk[0] = rotw(blk[0], 1) ^ (a + b + tfsKey[4 * i + 8]) & MAXINT;
6005 blk[1] = rotw(blk[1] ^ (a + 2 * b + tfsKey[4 * i + 9]) & MAXINT, 31);
6006 }
6007
6008 function tfsClose() {
6009 tfsKey = [];
6010 tfsM = [
6011 [],
6012 [],
6013 [],
6014 []
6015 ];
6016 }
6017
6018 function tfsEncrypt(data, offset) {
6019 dataBytes = data;
6020 dataOffset = offset;
6021 const blk = [getW(dataBytes, dataOffset) ^ tfsKey[0],
6022 getW(dataBytes, dataOffset + 4) ^ tfsKey[1],
6023 getW(dataBytes, dataOffset + 8) ^ tfsKey[2],
6024 getW(dataBytes, dataOffset + 12) ^ tfsKey[3]];
6025 for (let j = 0; j < 8; j++) {
6026 tfsFrnd(j, blk);
6027 }
6028 setW(dataBytes, dataOffset, blk[2] ^ tfsKey[4]);
6029 setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[5]);
6030 setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[6]);
6031 setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[7]);
6032 dataOffset += 16;
6033 return dataBytes;
6034 }
6035
6036 function tfsDecrypt(data, offset) {
6037 dataBytes = data;
6038 dataOffset = offset;
6039 const blk = [getW(dataBytes, dataOffset) ^ tfsKey[4],
6040 getW(dataBytes, dataOffset + 4) ^ tfsKey[5],
6041 getW(dataBytes, dataOffset + 8) ^ tfsKey[6],
6042 getW(dataBytes, dataOffset + 12) ^ tfsKey[7]];
6043 for (let j = 7; j >= 0; j--) {
6044 tfsIrnd(j, blk);
6045 }
6046 setW(dataBytes, dataOffset, blk[2] ^ tfsKey[0]);
6047 setW(dataBytes, dataOffset + 4, blk[3] ^ tfsKey[1]);
6048 setW(dataBytes, dataOffset + 8, blk[0] ^ tfsKey[2]);
6049 setW(dataBytes, dataOffset + 12, blk[1] ^ tfsKey[3]);
6050 dataOffset += 16;
6051 }
6052
6053 // added by Recurity Labs
6054
6055 function tfsFinal() {
6056 return dataBytes;
6057 }
6058
6059 return {
6060 name: 'twofish',
6061 blocksize: 128 / 8,
6062 open: tfsInit,
6063 close: tfsClose,
6064 encrypt: tfsEncrypt,
6065 decrypt: tfsDecrypt,
6066 // added by Recurity Labs
6067 finalize: tfsFinal
6068 };
6069}
6070
6071// added by Recurity Labs
6072
6073function TF(key) {
6074 this.tf = createTwofish();
6075 this.tf.open(Array.from(key), 0);
6076
6077 this.encrypt = function(block) {
6078 return this.tf.encrypt(Array.from(block), 0);
6079 };
6080}
6081
6082TF.keySize = TF.prototype.keySize = 32;
6083TF.blockSize = TF.prototype.blockSize = 16;
6084
6085/* Modified by Recurity Labs GmbH
6086 *
6087 * Originally written by nklein software (nklein.com)
6088 */
6089
6090/*
6091 * Javascript implementation based on Bruce Schneier's reference implementation.
6092 *
6093 *
6094 * The constructor doesn't do much of anything. It's just here
6095 * so we can start defining properties and methods and such.
6096 */
6097function Blowfish() {}
6098
6099/*
6100 * Declare the block size so that protocols know what size
6101 * Initialization Vector (IV) they will need.
6102 */
6103Blowfish.prototype.BLOCKSIZE = 8;
6104
6105/*
6106 * These are the default SBOXES.
6107 */
6108Blowfish.prototype.SBOXES = [
6109 [
6110 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
6111 0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
6112 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
6113 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
6114 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
6115 0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
6116 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
6117 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
6118 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
6119 0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
6120 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
6121 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
6122 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
6123 0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
6124 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
6125 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
6126 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
6127 0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
6128 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
6129 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
6130 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
6131 0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
6132 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
6133 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
6134 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
6135 0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
6136 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
6137 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
6138 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
6139 0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
6140 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
6141 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
6142 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
6143 0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
6144 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
6145 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
6146 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
6147 0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
6148 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
6149 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
6150 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
6151 0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
6152 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
6153 ],
6154 [
6155 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
6156 0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
6157 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
6158 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
6159 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
6160 0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
6161 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
6162 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
6163 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
6164 0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
6165 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
6166 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
6167 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
6168 0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
6169 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
6170 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
6171 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
6172 0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
6173 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
6174 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
6175 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
6176 0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
6177 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
6178 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
6179 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
6180 0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
6181 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
6182 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
6183 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
6184 0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
6185 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
6186 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
6187 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
6188 0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
6189 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
6190 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
6191 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
6192 0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
6193 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
6194 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
6195 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
6196 0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
6197 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
6198 ],
6199 [
6200 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
6201 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
6202 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
6203 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
6204 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
6205 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
6206 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
6207 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
6208 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
6209 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
6210 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
6211 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
6212 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
6213 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
6214 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
6215 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
6216 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
6217 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
6218 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
6219 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
6220 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
6221 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
6222 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
6223 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
6224 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
6225 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
6226 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
6227 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
6228 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
6229 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
6230 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
6231 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
6232 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
6233 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
6234 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
6235 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
6236 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
6237 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
6238 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
6239 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
6240 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
6241 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
6242 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
6243 ],
6244 [
6245 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
6246 0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
6247 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
6248 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
6249 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
6250 0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
6251 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
6252 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
6253 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
6254 0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
6255 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
6256 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
6257 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
6258 0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
6259 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
6260 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
6261 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
6262 0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
6263 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
6264 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
6265 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
6266 0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
6267 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
6268 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
6269 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
6270 0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
6271 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
6272 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
6273 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
6274 0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
6275 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
6276 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
6277 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
6278 0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
6279 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
6280 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
6281 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
6282 0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
6283 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
6284 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
6285 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
6286 0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
6287 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
6288 ]
6289];
6290
6291//*
6292//* This is the default PARRAY
6293//*
6294Blowfish.prototype.PARRAY = [
6295 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
6296 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
6297 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
6298];
6299
6300//*
6301//* This is the number of rounds the cipher will go
6302//*
6303Blowfish.prototype.NN = 16;
6304
6305//*
6306//* This function is needed to get rid of problems
6307//* with the high-bit getting set. If we don't do
6308//* this, then sometimes ( aa & 0x00FFFFFFFF ) is not
6309//* equal to ( bb & 0x00FFFFFFFF ) even when they
6310//* agree bit-for-bit for the first 32 bits.
6311//*
6312Blowfish.prototype._clean = function(xx) {
6313 if (xx < 0) {
6314 const yy = xx & 0x7FFFFFFF;
6315 xx = yy + 0x80000000;
6316 }
6317 return xx;
6318};
6319
6320//*
6321//* This is the mixing function that uses the sboxes
6322//*
6323Blowfish.prototype._F = function(xx) {
6324 let yy;
6325
6326 const dd = xx & 0x00FF;
6327 xx >>>= 8;
6328 const cc = xx & 0x00FF;
6329 xx >>>= 8;
6330 const bb = xx & 0x00FF;
6331 xx >>>= 8;
6332 const aa = xx & 0x00FF;
6333
6334 yy = this.sboxes[0][aa] + this.sboxes[1][bb];
6335 yy ^= this.sboxes[2][cc];
6336 yy += this.sboxes[3][dd];
6337
6338 return yy;
6339};
6340
6341//*
6342//* This method takes an array with two values, left and right
6343//* and does NN rounds of Blowfish on them.
6344//*
6345Blowfish.prototype._encryptBlock = function(vals) {
6346 let dataL = vals[0];
6347 let dataR = vals[1];
6348
6349 let ii;
6350
6351 for (ii = 0; ii < this.NN; ++ii) {
6352 dataL ^= this.parray[ii];
6353 dataR = this._F(dataL) ^ dataR;
6354
6355 const tmp = dataL;
6356 dataL = dataR;
6357 dataR = tmp;
6358 }
6359
6360 dataL ^= this.parray[this.NN + 0];
6361 dataR ^= this.parray[this.NN + 1];
6362
6363 vals[0] = this._clean(dataR);
6364 vals[1] = this._clean(dataL);
6365};
6366
6367//*
6368//* This method takes a vector of numbers and turns them
6369//* into long words so that they can be processed by the
6370//* real algorithm.
6371//*
6372//* Maybe I should make the real algorithm above take a vector
6373//* instead. That will involve more looping, but it won't require
6374//* the F() method to deconstruct the vector.
6375//*
6376Blowfish.prototype.encryptBlock = function(vector) {
6377 let ii;
6378 const vals = [0, 0];
6379 const off = this.BLOCKSIZE / 2;
6380 for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
6381 vals[0] = (vals[0] << 8) | (vector[ii + 0] & 0x00FF);
6382 vals[1] = (vals[1] << 8) | (vector[ii + off] & 0x00FF);
6383 }
6384
6385 this._encryptBlock(vals);
6386
6387 const ret = [];
6388 for (ii = 0; ii < this.BLOCKSIZE / 2; ++ii) {
6389 ret[ii + 0] = ((vals[0] >>> (24 - 8 * (ii))) & 0x00FF);
6390 ret[ii + off] = ((vals[1] >>> (24 - 8 * (ii))) & 0x00FF);
6391 // vals[ 0 ] = ( vals[ 0 ] >>> 8 );
6392 // vals[ 1 ] = ( vals[ 1 ] >>> 8 );
6393 }
6394
6395 return ret;
6396};
6397
6398//*
6399//* This method takes an array with two values, left and right
6400//* and undoes NN rounds of Blowfish on them.
6401//*
6402Blowfish.prototype._decryptBlock = function(vals) {
6403 let dataL = vals[0];
6404 let dataR = vals[1];
6405
6406 let ii;
6407
6408 for (ii = this.NN + 1; ii > 1; --ii) {
6409 dataL ^= this.parray[ii];
6410 dataR = this._F(dataL) ^ dataR;
6411
6412 const tmp = dataL;
6413 dataL = dataR;
6414 dataR = tmp;
6415 }
6416
6417 dataL ^= this.parray[1];
6418 dataR ^= this.parray[0];
6419
6420 vals[0] = this._clean(dataR);
6421 vals[1] = this._clean(dataL);
6422};
6423
6424//*
6425//* This method takes a key array and initializes the
6426//* sboxes and parray for this encryption.
6427//*
6428Blowfish.prototype.init = function(key) {
6429 let ii;
6430 let jj = 0;
6431
6432 this.parray = [];
6433 for (ii = 0; ii < this.NN + 2; ++ii) {
6434 let data = 0x00000000;
6435 for (let kk = 0; kk < 4; ++kk) {
6436 data = (data << 8) | (key[jj] & 0x00FF);
6437 if (++jj >= key.length) {
6438 jj = 0;
6439 }
6440 }
6441 this.parray[ii] = this.PARRAY[ii] ^ data;
6442 }
6443
6444 this.sboxes = [];
6445 for (ii = 0; ii < 4; ++ii) {
6446 this.sboxes[ii] = [];
6447 for (jj = 0; jj < 256; ++jj) {
6448 this.sboxes[ii][jj] = this.SBOXES[ii][jj];
6449 }
6450 }
6451
6452 const vals = [0x00000000, 0x00000000];
6453
6454 for (ii = 0; ii < this.NN + 2; ii += 2) {
6455 this._encryptBlock(vals);
6456 this.parray[ii + 0] = vals[0];
6457 this.parray[ii + 1] = vals[1];
6458 }
6459
6460 for (ii = 0; ii < 4; ++ii) {
6461 for (jj = 0; jj < 256; jj += 2) {
6462 this._encryptBlock(vals);
6463 this.sboxes[ii][jj + 0] = vals[0];
6464 this.sboxes[ii][jj + 1] = vals[1];
6465 }
6466 }
6467};
6468
6469// added by Recurity Labs
6470function BF(key) {
6471 this.bf = new Blowfish();
6472 this.bf.init(key);
6473
6474 this.encrypt = function(block) {
6475 return this.bf.encryptBlock(block);
6476 };
6477}
6478
6479BF.keySize = BF.prototype.keySize = 16;
6480BF.blockSize = BF.prototype.blockSize = 8;
6481
6482/**
6483 * @fileoverview Symmetric cryptography functions
6484 * @module crypto/cipher
6485 * @private
6486 */
6487
6488/**
6489 * AES-128 encryption and decryption (ID 7)
6490 * @function
6491 * @param {String} key - 128-bit key
6492 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
6493 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
6494 * @returns {Object}
6495 */
6496const aes128 = aes(128);
6497/**
6498 * AES-128 Block Cipher (ID 8)
6499 * @function
6500 * @param {String} key - 192-bit key
6501 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
6502 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
6503 * @returns {Object}
6504 */
6505const aes192 = aes(192);
6506/**
6507 * AES-128 Block Cipher (ID 9)
6508 * @function
6509 * @param {String} key - 256-bit key
6510 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
6511 * @see {@link https://csrc.nist.gov/publications/fips/fips197/fips-197.pdf|NIST FIPS-197}
6512 * @returns {Object}
6513 */
6514const aes256 = aes(256);
6515// Not in OpenPGP specifications
6516const des$1 = DES;
6517/**
6518 * Triple DES Block Cipher (ID 2)
6519 * @function
6520 * @param {String} key - 192-bit key
6521 * @see {@link https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf|NIST SP 800-67}
6522 * @returns {Object}
6523 */
6524const tripledes = TripleDES;
6525/**
6526 * CAST-128 Block Cipher (ID 3)
6527 * @function
6528 * @param {String} key - 128-bit key
6529 * @see {@link https://tools.ietf.org/html/rfc2144|The CAST-128 Encryption Algorithm}
6530 * @returns {Object}
6531 */
6532const cast5 = CAST5;
6533/**
6534 * Twofish Block Cipher (ID 10)
6535 * @function
6536 * @param {String} key - 256-bit key
6537 * @see {@link https://tools.ietf.org/html/rfc4880#ref-TWOFISH|TWOFISH}
6538 * @returns {Object}
6539 */
6540const twofish = TF;
6541/**
6542 * Blowfish Block Cipher (ID 4)
6543 * @function
6544 * @param {String} key - 128-bit key
6545 * @see {@link https://tools.ietf.org/html/rfc4880#ref-BLOWFISH|BLOWFISH}
6546 * @returns {Object}
6547 */
6548const blowfish = BF;
6549/**
6550 * Not implemented
6551 * @function
6552 * @throws {Error}
6553 */
6554const idea = function() {
6555 throw new Error('IDEA symmetric-key algorithm not implemented');
6556};
6557
6558var cipher = /*#__PURE__*/Object.freeze({
6559 __proto__: null,
6560 aes128: aes128,
6561 aes192: aes192,
6562 aes256: aes256,
6563 des: des$1,
6564 tripledes: tripledes,
6565 cast5: cast5,
6566 twofish: twofish,
6567 blowfish: blowfish,
6568 idea: idea
6569});
6570
6571var sha1_asm = function ( stdlib, foreign, buffer ) {
6572 "use asm";
6573
6574 // SHA256 state
6575 var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0,
6576 TOTAL0 = 0, TOTAL1 = 0;
6577
6578 // HMAC state
6579 var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0,
6580 O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0;
6581
6582 // I/O buffer
6583 var HEAP = new stdlib.Uint8Array(buffer);
6584
6585 function _core ( w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15 ) {
6586 w0 = w0|0;
6587 w1 = w1|0;
6588 w2 = w2|0;
6589 w3 = w3|0;
6590 w4 = w4|0;
6591 w5 = w5|0;
6592 w6 = w6|0;
6593 w7 = w7|0;
6594 w8 = w8|0;
6595 w9 = w9|0;
6596 w10 = w10|0;
6597 w11 = w11|0;
6598 w12 = w12|0;
6599 w13 = w13|0;
6600 w14 = w14|0;
6601 w15 = w15|0;
6602
6603 var a = 0, b = 0, c = 0, d = 0, e = 0, n = 0, t = 0,
6604 w16 = 0, w17 = 0, w18 = 0, w19 = 0,
6605 w20 = 0, w21 = 0, w22 = 0, w23 = 0, w24 = 0, w25 = 0, w26 = 0, w27 = 0, w28 = 0, w29 = 0,
6606 w30 = 0, w31 = 0, w32 = 0, w33 = 0, w34 = 0, w35 = 0, w36 = 0, w37 = 0, w38 = 0, w39 = 0,
6607 w40 = 0, w41 = 0, w42 = 0, w43 = 0, w44 = 0, w45 = 0, w46 = 0, w47 = 0, w48 = 0, w49 = 0,
6608 w50 = 0, w51 = 0, w52 = 0, w53 = 0, w54 = 0, w55 = 0, w56 = 0, w57 = 0, w58 = 0, w59 = 0,
6609 w60 = 0, w61 = 0, w62 = 0, w63 = 0, w64 = 0, w65 = 0, w66 = 0, w67 = 0, w68 = 0, w69 = 0,
6610 w70 = 0, w71 = 0, w72 = 0, w73 = 0, w74 = 0, w75 = 0, w76 = 0, w77 = 0, w78 = 0, w79 = 0;
6611
6612 a = H0;
6613 b = H1;
6614 c = H2;
6615 d = H3;
6616 e = H4;
6617
6618 // 0
6619 t = ( w0 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6620 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6621
6622 // 1
6623 t = ( w1 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6624 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6625
6626 // 2
6627 t = ( w2 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6628 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6629
6630 // 3
6631 t = ( w3 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6632 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6633
6634 // 4
6635 t = ( w4 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6636 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6637
6638 // 5
6639 t = ( w5 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6640 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6641
6642 // 6
6643 t = ( w6 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6644 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6645
6646 // 7
6647 t = ( w7 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6648 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6649
6650 // 8
6651 t = ( w8 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6652 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6653
6654 // 9
6655 t = ( w9 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6656 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6657
6658 // 10
6659 t = ( w10 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6660 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6661
6662 // 11
6663 t = ( w11 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6664 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6665
6666 // 12
6667 t = ( w12 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6668 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6669
6670 // 13
6671 t = ( w13 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6672 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6673
6674 // 14
6675 t = ( w14 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6676 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6677
6678 // 15
6679 t = ( w15 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6680 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6681
6682 // 16
6683 n = w13 ^ w8 ^ w2 ^ w0;
6684 w16 = (n << 1) | (n >>> 31);
6685 t = (w16 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6686 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6687
6688 // 17
6689 n = w14 ^ w9 ^ w3 ^ w1;
6690 w17 = (n << 1) | (n >>> 31);
6691 t = (w17 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6692 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6693
6694 // 18
6695 n = w15 ^ w10 ^ w4 ^ w2;
6696 w18 = (n << 1) | (n >>> 31);
6697 t = (w18 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6698 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6699
6700 // 19
6701 n = w16 ^ w11 ^ w5 ^ w3;
6702 w19 = (n << 1) | (n >>> 31);
6703 t = (w19 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (~b & d)) + 0x5a827999 )|0;
6704 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6705
6706 // 20
6707 n = w17 ^ w12 ^ w6 ^ w4;
6708 w20 = (n << 1) | (n >>> 31);
6709 t = (w20 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6710 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6711
6712 // 21
6713 n = w18 ^ w13 ^ w7 ^ w5;
6714 w21 = (n << 1) | (n >>> 31);
6715 t = (w21 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6716 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6717
6718 // 22
6719 n = w19 ^ w14 ^ w8 ^ w6;
6720 w22 = (n << 1) | (n >>> 31);
6721 t = (w22 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6722 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6723
6724 // 23
6725 n = w20 ^ w15 ^ w9 ^ w7;
6726 w23 = (n << 1) | (n >>> 31);
6727 t = (w23 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6728 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6729
6730 // 24
6731 n = w21 ^ w16 ^ w10 ^ w8;
6732 w24 = (n << 1) | (n >>> 31);
6733 t = (w24 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6734 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6735
6736 // 25
6737 n = w22 ^ w17 ^ w11 ^ w9;
6738 w25 = (n << 1) | (n >>> 31);
6739 t = (w25 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6740 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6741
6742 // 26
6743 n = w23 ^ w18 ^ w12 ^ w10;
6744 w26 = (n << 1) | (n >>> 31);
6745 t = (w26 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6746 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6747
6748 // 27
6749 n = w24 ^ w19 ^ w13 ^ w11;
6750 w27 = (n << 1) | (n >>> 31);
6751 t = (w27 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6752 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6753
6754 // 28
6755 n = w25 ^ w20 ^ w14 ^ w12;
6756 w28 = (n << 1) | (n >>> 31);
6757 t = (w28 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6758 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6759
6760 // 29
6761 n = w26 ^ w21 ^ w15 ^ w13;
6762 w29 = (n << 1) | (n >>> 31);
6763 t = (w29 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6764 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6765
6766 // 30
6767 n = w27 ^ w22 ^ w16 ^ w14;
6768 w30 = (n << 1) | (n >>> 31);
6769 t = (w30 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6770 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6771
6772 // 31
6773 n = w28 ^ w23 ^ w17 ^ w15;
6774 w31 = (n << 1) | (n >>> 31);
6775 t = (w31 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6776 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6777
6778 // 32
6779 n = w29 ^ w24 ^ w18 ^ w16;
6780 w32 = (n << 1) | (n >>> 31);
6781 t = (w32 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6782 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6783
6784 // 33
6785 n = w30 ^ w25 ^ w19 ^ w17;
6786 w33 = (n << 1) | (n >>> 31);
6787 t = (w33 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6788 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6789
6790 // 34
6791 n = w31 ^ w26 ^ w20 ^ w18;
6792 w34 = (n << 1) | (n >>> 31);
6793 t = (w34 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6794 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6795
6796 // 35
6797 n = w32 ^ w27 ^ w21 ^ w19;
6798 w35 = (n << 1) | (n >>> 31);
6799 t = (w35 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6800 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6801
6802 // 36
6803 n = w33 ^ w28 ^ w22 ^ w20;
6804 w36 = (n << 1) | (n >>> 31);
6805 t = (w36 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6806 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6807
6808 // 37
6809 n = w34 ^ w29 ^ w23 ^ w21;
6810 w37 = (n << 1) | (n >>> 31);
6811 t = (w37 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6812 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6813
6814 // 38
6815 n = w35 ^ w30 ^ w24 ^ w22;
6816 w38 = (n << 1) | (n >>> 31);
6817 t = (w38 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6818 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6819
6820 // 39
6821 n = w36 ^ w31 ^ w25 ^ w23;
6822 w39 = (n << 1) | (n >>> 31);
6823 t = (w39 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) + 0x6ed9eba1 )|0;
6824 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6825
6826 // 40
6827 n = w37 ^ w32 ^ w26 ^ w24;
6828 w40 = (n << 1) | (n >>> 31);
6829 t = (w40 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6830 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6831
6832 // 41
6833 n = w38 ^ w33 ^ w27 ^ w25;
6834 w41 = (n << 1) | (n >>> 31);
6835 t = (w41 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6836 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6837
6838 // 42
6839 n = w39 ^ w34 ^ w28 ^ w26;
6840 w42 = (n << 1) | (n >>> 31);
6841 t = (w42 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6842 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6843
6844 // 43
6845 n = w40 ^ w35 ^ w29 ^ w27;
6846 w43 = (n << 1) | (n >>> 31);
6847 t = (w43 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6848 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6849
6850 // 44
6851 n = w41 ^ w36 ^ w30 ^ w28;
6852 w44 = (n << 1) | (n >>> 31);
6853 t = (w44 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6854 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6855
6856 // 45
6857 n = w42 ^ w37 ^ w31 ^ w29;
6858 w45 = (n << 1) | (n >>> 31);
6859 t = (w45 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6860 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6861
6862 // 46
6863 n = w43 ^ w38 ^ w32 ^ w30;
6864 w46 = (n << 1) | (n >>> 31);
6865 t = (w46 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6866 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6867
6868 // 47
6869 n = w44 ^ w39 ^ w33 ^ w31;
6870 w47 = (n << 1) | (n >>> 31);
6871 t = (w47 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6872 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6873
6874 // 48
6875 n = w45 ^ w40 ^ w34 ^ w32;
6876 w48 = (n << 1) | (n >>> 31);
6877 t = (w48 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6878 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6879
6880 // 49
6881 n = w46 ^ w41 ^ w35 ^ w33;
6882 w49 = (n << 1) | (n >>> 31);
6883 t = (w49 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6884 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6885
6886 // 50
6887 n = w47 ^ w42 ^ w36 ^ w34;
6888 w50 = (n << 1) | (n >>> 31);
6889 t = (w50 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6890 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6891
6892 // 51
6893 n = w48 ^ w43 ^ w37 ^ w35;
6894 w51 = (n << 1) | (n >>> 31);
6895 t = (w51 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6896 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6897
6898 // 52
6899 n = w49 ^ w44 ^ w38 ^ w36;
6900 w52 = (n << 1) | (n >>> 31);
6901 t = (w52 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6902 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6903
6904 // 53
6905 n = w50 ^ w45 ^ w39 ^ w37;
6906 w53 = (n << 1) | (n >>> 31);
6907 t = (w53 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6908 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6909
6910 // 54
6911 n = w51 ^ w46 ^ w40 ^ w38;
6912 w54 = (n << 1) | (n >>> 31);
6913 t = (w54 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6914 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6915
6916 // 55
6917 n = w52 ^ w47 ^ w41 ^ w39;
6918 w55 = (n << 1) | (n >>> 31);
6919 t = (w55 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6920 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6921
6922 // 56
6923 n = w53 ^ w48 ^ w42 ^ w40;
6924 w56 = (n << 1) | (n >>> 31);
6925 t = (w56 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6926 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6927
6928 // 57
6929 n = w54 ^ w49 ^ w43 ^ w41;
6930 w57 = (n << 1) | (n >>> 31);
6931 t = (w57 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6932 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6933
6934 // 58
6935 n = w55 ^ w50 ^ w44 ^ w42;
6936 w58 = (n << 1) | (n >>> 31);
6937 t = (w58 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6938 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6939
6940 // 59
6941 n = w56 ^ w51 ^ w45 ^ w43;
6942 w59 = (n << 1) | (n >>> 31);
6943 t = (w59 + ((a << 5) | (a >>> 27)) + e + ((b & c) | (b & d) | (c & d)) - 0x70e44324 )|0;
6944 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6945
6946 // 60
6947 n = w57 ^ w52 ^ w46 ^ w44;
6948 w60 = (n << 1) | (n >>> 31);
6949 t = (w60 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6950 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6951
6952 // 61
6953 n = w58 ^ w53 ^ w47 ^ w45;
6954 w61 = (n << 1) | (n >>> 31);
6955 t = (w61 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6956 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6957
6958 // 62
6959 n = w59 ^ w54 ^ w48 ^ w46;
6960 w62 = (n << 1) | (n >>> 31);
6961 t = (w62 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6962 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6963
6964 // 63
6965 n = w60 ^ w55 ^ w49 ^ w47;
6966 w63 = (n << 1) | (n >>> 31);
6967 t = (w63 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6968 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6969
6970 // 64
6971 n = w61 ^ w56 ^ w50 ^ w48;
6972 w64 = (n << 1) | (n >>> 31);
6973 t = (w64 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6974 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6975
6976 // 65
6977 n = w62 ^ w57 ^ w51 ^ w49;
6978 w65 = (n << 1) | (n >>> 31);
6979 t = (w65 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6980 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6981
6982 // 66
6983 n = w63 ^ w58 ^ w52 ^ w50;
6984 w66 = (n << 1) | (n >>> 31);
6985 t = (w66 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6986 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6987
6988 // 67
6989 n = w64 ^ w59 ^ w53 ^ w51;
6990 w67 = (n << 1) | (n >>> 31);
6991 t = (w67 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6992 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6993
6994 // 68
6995 n = w65 ^ w60 ^ w54 ^ w52;
6996 w68 = (n << 1) | (n >>> 31);
6997 t = (w68 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
6998 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
6999
7000 // 69
7001 n = w66 ^ w61 ^ w55 ^ w53;
7002 w69 = (n << 1) | (n >>> 31);
7003 t = (w69 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7004 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7005
7006 // 70
7007 n = w67 ^ w62 ^ w56 ^ w54;
7008 w70 = (n << 1) | (n >>> 31);
7009 t = (w70 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7010 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7011
7012 // 71
7013 n = w68 ^ w63 ^ w57 ^ w55;
7014 w71 = (n << 1) | (n >>> 31);
7015 t = (w71 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7016 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7017
7018 // 72
7019 n = w69 ^ w64 ^ w58 ^ w56;
7020 w72 = (n << 1) | (n >>> 31);
7021 t = (w72 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7022 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7023
7024 // 73
7025 n = w70 ^ w65 ^ w59 ^ w57;
7026 w73 = (n << 1) | (n >>> 31);
7027 t = (w73 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7028 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7029
7030 // 74
7031 n = w71 ^ w66 ^ w60 ^ w58;
7032 w74 = (n << 1) | (n >>> 31);
7033 t = (w74 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7034 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7035
7036 // 75
7037 n = w72 ^ w67 ^ w61 ^ w59;
7038 w75 = (n << 1) | (n >>> 31);
7039 t = (w75 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7040 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7041
7042 // 76
7043 n = w73 ^ w68 ^ w62 ^ w60;
7044 w76 = (n << 1) | (n >>> 31);
7045 t = (w76 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7046 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7047
7048 // 77
7049 n = w74 ^ w69 ^ w63 ^ w61;
7050 w77 = (n << 1) | (n >>> 31);
7051 t = (w77 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7052 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7053
7054 // 78
7055 n = w75 ^ w70 ^ w64 ^ w62;
7056 w78 = (n << 1) | (n >>> 31);
7057 t = (w78 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7058 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7059
7060 // 79
7061 n = w76 ^ w71 ^ w65 ^ w63;
7062 w79 = (n << 1) | (n >>> 31);
7063 t = (w79 + ((a << 5) | (a >>> 27)) + e + (b ^ c ^ d) - 0x359d3e2a )|0;
7064 e = d; d = c; c = (b << 30) | (b >>> 2); b = a; a = t;
7065
7066 H0 = ( H0 + a )|0;
7067 H1 = ( H1 + b )|0;
7068 H2 = ( H2 + c )|0;
7069 H3 = ( H3 + d )|0;
7070 H4 = ( H4 + e )|0;
7071
7072 }
7073
7074 function _core_heap ( offset ) {
7075 offset = offset|0;
7076
7077 _core(
7078 HEAP[offset|0]<<24 | HEAP[offset|1]<<16 | HEAP[offset|2]<<8 | HEAP[offset|3],
7079 HEAP[offset|4]<<24 | HEAP[offset|5]<<16 | HEAP[offset|6]<<8 | HEAP[offset|7],
7080 HEAP[offset|8]<<24 | HEAP[offset|9]<<16 | HEAP[offset|10]<<8 | HEAP[offset|11],
7081 HEAP[offset|12]<<24 | HEAP[offset|13]<<16 | HEAP[offset|14]<<8 | HEAP[offset|15],
7082 HEAP[offset|16]<<24 | HEAP[offset|17]<<16 | HEAP[offset|18]<<8 | HEAP[offset|19],
7083 HEAP[offset|20]<<24 | HEAP[offset|21]<<16 | HEAP[offset|22]<<8 | HEAP[offset|23],
7084 HEAP[offset|24]<<24 | HEAP[offset|25]<<16 | HEAP[offset|26]<<8 | HEAP[offset|27],
7085 HEAP[offset|28]<<24 | HEAP[offset|29]<<16 | HEAP[offset|30]<<8 | HEAP[offset|31],
7086 HEAP[offset|32]<<24 | HEAP[offset|33]<<16 | HEAP[offset|34]<<8 | HEAP[offset|35],
7087 HEAP[offset|36]<<24 | HEAP[offset|37]<<16 | HEAP[offset|38]<<8 | HEAP[offset|39],
7088 HEAP[offset|40]<<24 | HEAP[offset|41]<<16 | HEAP[offset|42]<<8 | HEAP[offset|43],
7089 HEAP[offset|44]<<24 | HEAP[offset|45]<<16 | HEAP[offset|46]<<8 | HEAP[offset|47],
7090 HEAP[offset|48]<<24 | HEAP[offset|49]<<16 | HEAP[offset|50]<<8 | HEAP[offset|51],
7091 HEAP[offset|52]<<24 | HEAP[offset|53]<<16 | HEAP[offset|54]<<8 | HEAP[offset|55],
7092 HEAP[offset|56]<<24 | HEAP[offset|57]<<16 | HEAP[offset|58]<<8 | HEAP[offset|59],
7093 HEAP[offset|60]<<24 | HEAP[offset|61]<<16 | HEAP[offset|62]<<8 | HEAP[offset|63]
7094 );
7095 }
7096
7097 // offset — multiple of 32
7098 function _state_to_heap ( output ) {
7099 output = output|0;
7100
7101 HEAP[output|0] = H0>>>24;
7102 HEAP[output|1] = H0>>>16&255;
7103 HEAP[output|2] = H0>>>8&255;
7104 HEAP[output|3] = H0&255;
7105 HEAP[output|4] = H1>>>24;
7106 HEAP[output|5] = H1>>>16&255;
7107 HEAP[output|6] = H1>>>8&255;
7108 HEAP[output|7] = H1&255;
7109 HEAP[output|8] = H2>>>24;
7110 HEAP[output|9] = H2>>>16&255;
7111 HEAP[output|10] = H2>>>8&255;
7112 HEAP[output|11] = H2&255;
7113 HEAP[output|12] = H3>>>24;
7114 HEAP[output|13] = H3>>>16&255;
7115 HEAP[output|14] = H3>>>8&255;
7116 HEAP[output|15] = H3&255;
7117 HEAP[output|16] = H4>>>24;
7118 HEAP[output|17] = H4>>>16&255;
7119 HEAP[output|18] = H4>>>8&255;
7120 HEAP[output|19] = H4&255;
7121 }
7122
7123 function reset () {
7124 H0 = 0x67452301;
7125 H1 = 0xefcdab89;
7126 H2 = 0x98badcfe;
7127 H3 = 0x10325476;
7128 H4 = 0xc3d2e1f0;
7129 TOTAL0 = TOTAL1 = 0;
7130 }
7131
7132 function init ( h0, h1, h2, h3, h4, total0, total1 ) {
7133 h0 = h0|0;
7134 h1 = h1|0;
7135 h2 = h2|0;
7136 h3 = h3|0;
7137 h4 = h4|0;
7138 total0 = total0|0;
7139 total1 = total1|0;
7140
7141 H0 = h0;
7142 H1 = h1;
7143 H2 = h2;
7144 H3 = h3;
7145 H4 = h4;
7146 TOTAL0 = total0;
7147 TOTAL1 = total1;
7148 }
7149
7150 // offset — multiple of 64
7151 function process ( offset, length ) {
7152 offset = offset|0;
7153 length = length|0;
7154
7155 var hashed = 0;
7156
7157 if ( offset & 63 )
7158 return -1;
7159
7160 while ( (length|0) >= 64 ) {
7161 _core_heap(offset);
7162
7163 offset = ( offset + 64 )|0;
7164 length = ( length - 64 )|0;
7165
7166 hashed = ( hashed + 64 )|0;
7167 }
7168
7169 TOTAL0 = ( TOTAL0 + hashed )|0;
7170 if ( TOTAL0>>>0 < hashed>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
7171
7172 return hashed|0;
7173 }
7174
7175 // offset — multiple of 64
7176 // output — multiple of 32
7177 function finish ( offset, length, output ) {
7178 offset = offset|0;
7179 length = length|0;
7180 output = output|0;
7181
7182 var hashed = 0,
7183 i = 0;
7184
7185 if ( offset & 63 )
7186 return -1;
7187
7188 if ( ~output )
7189 if ( output & 31 )
7190 return -1;
7191
7192 if ( (length|0) >= 64 ) {
7193 hashed = process( offset, length )|0;
7194 if ( (hashed|0) == -1 )
7195 return -1;
7196
7197 offset = ( offset + hashed )|0;
7198 length = ( length - hashed )|0;
7199 }
7200
7201 hashed = ( hashed + length )|0;
7202 TOTAL0 = ( TOTAL0 + length )|0;
7203 if ( TOTAL0>>>0 < length>>>0 ) TOTAL1 = (TOTAL1 + 1)|0;
7204
7205 HEAP[offset|length] = 0x80;
7206
7207 if ( (length|0) >= 56 ) {
7208 for ( i = (length+1)|0; (i|0) < 64; i = (i+1)|0 )
7209 HEAP[offset|i] = 0x00;
7210 _core_heap(offset);
7211
7212 length = 0;
7213
7214 HEAP[offset|0] = 0;
7215 }
7216
7217 for ( i = (length+1)|0; (i|0) < 59; i = (i+1)|0 )
7218 HEAP[offset|i] = 0;
7219
7220 HEAP[offset|56] = TOTAL1>>>21&255;
7221 HEAP[offset|57] = TOTAL1>>>13&255;
7222 HEAP[offset|58] = TOTAL1>>>5&255;
7223 HEAP[offset|59] = TOTAL1<<3&255 | TOTAL0>>>29;
7224 HEAP[offset|60] = TOTAL0>>>21&255;
7225 HEAP[offset|61] = TOTAL0>>>13&255;
7226 HEAP[offset|62] = TOTAL0>>>5&255;
7227 HEAP[offset|63] = TOTAL0<<3&255;
7228 _core_heap(offset);
7229
7230 if ( ~output )
7231 _state_to_heap(output);
7232
7233 return hashed|0;
7234 }
7235
7236 function hmac_reset () {
7237 H0 = I0;
7238 H1 = I1;
7239 H2 = I2;
7240 H3 = I3;
7241 H4 = I4;
7242 TOTAL0 = 64;
7243 TOTAL1 = 0;
7244 }
7245
7246 function _hmac_opad () {
7247 H0 = O0;
7248 H1 = O1;
7249 H2 = O2;
7250 H3 = O3;
7251 H4 = O4;
7252 TOTAL0 = 64;
7253 TOTAL1 = 0;
7254 }
7255
7256 function hmac_init ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 ) {
7257 p0 = p0|0;
7258 p1 = p1|0;
7259 p2 = p2|0;
7260 p3 = p3|0;
7261 p4 = p4|0;
7262 p5 = p5|0;
7263 p6 = p6|0;
7264 p7 = p7|0;
7265 p8 = p8|0;
7266 p9 = p9|0;
7267 p10 = p10|0;
7268 p11 = p11|0;
7269 p12 = p12|0;
7270 p13 = p13|0;
7271 p14 = p14|0;
7272 p15 = p15|0;
7273
7274 // opad
7275 reset();
7276 _core(
7277 p0 ^ 0x5c5c5c5c,
7278 p1 ^ 0x5c5c5c5c,
7279 p2 ^ 0x5c5c5c5c,
7280 p3 ^ 0x5c5c5c5c,
7281 p4 ^ 0x5c5c5c5c,
7282 p5 ^ 0x5c5c5c5c,
7283 p6 ^ 0x5c5c5c5c,
7284 p7 ^ 0x5c5c5c5c,
7285 p8 ^ 0x5c5c5c5c,
7286 p9 ^ 0x5c5c5c5c,
7287 p10 ^ 0x5c5c5c5c,
7288 p11 ^ 0x5c5c5c5c,
7289 p12 ^ 0x5c5c5c5c,
7290 p13 ^ 0x5c5c5c5c,
7291 p14 ^ 0x5c5c5c5c,
7292 p15 ^ 0x5c5c5c5c
7293 );
7294 O0 = H0;
7295 O1 = H1;
7296 O2 = H2;
7297 O3 = H3;
7298 O4 = H4;
7299
7300 // ipad
7301 reset();
7302 _core(
7303 p0 ^ 0x36363636,
7304 p1 ^ 0x36363636,
7305 p2 ^ 0x36363636,
7306 p3 ^ 0x36363636,
7307 p4 ^ 0x36363636,
7308 p5 ^ 0x36363636,
7309 p6 ^ 0x36363636,
7310 p7 ^ 0x36363636,
7311 p8 ^ 0x36363636,
7312 p9 ^ 0x36363636,
7313 p10 ^ 0x36363636,
7314 p11 ^ 0x36363636,
7315 p12 ^ 0x36363636,
7316 p13 ^ 0x36363636,
7317 p14 ^ 0x36363636,
7318 p15 ^ 0x36363636
7319 );
7320 I0 = H0;
7321 I1 = H1;
7322 I2 = H2;
7323 I3 = H3;
7324 I4 = H4;
7325
7326 TOTAL0 = 64;
7327 TOTAL1 = 0;
7328 }
7329
7330 // offset — multiple of 64
7331 // output — multiple of 32
7332 function hmac_finish ( offset, length, output ) {
7333 offset = offset|0;
7334 length = length|0;
7335 output = output|0;
7336
7337 var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, hashed = 0;
7338
7339 if ( offset & 63 )
7340 return -1;
7341
7342 if ( ~output )
7343 if ( output & 31 )
7344 return -1;
7345
7346 hashed = finish( offset, length, -1 )|0;
7347 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
7348
7349 _hmac_opad();
7350 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
7351
7352 if ( ~output )
7353 _state_to_heap(output);
7354
7355 return hashed|0;
7356 }
7357
7358 // salt is assumed to be already processed
7359 // offset — multiple of 64
7360 // output — multiple of 32
7361 function pbkdf2_generate_block ( offset, length, block, count, output ) {
7362 offset = offset|0;
7363 length = length|0;
7364 block = block|0;
7365 count = count|0;
7366 output = output|0;
7367
7368 var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0,
7369 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;
7370
7371 if ( offset & 63 )
7372 return -1;
7373
7374 if ( ~output )
7375 if ( output & 31 )
7376 return -1;
7377
7378 // pad block number into heap
7379 // FIXME probable OOB write
7380 HEAP[(offset+length)|0] = block>>>24;
7381 HEAP[(offset+length+1)|0] = block>>>16&255;
7382 HEAP[(offset+length+2)|0] = block>>>8&255;
7383 HEAP[(offset+length+3)|0] = block&255;
7384
7385 // finish first iteration
7386 hmac_finish( offset, (length+4)|0, -1 )|0;
7387 h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4;
7388 count = (count-1)|0;
7389
7390 // perform the rest iterations
7391 while ( (count|0) > 0 ) {
7392 hmac_reset();
7393 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
7394 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
7395
7396 _hmac_opad();
7397 _core( t0, t1, t2, t3, t4, 0x80000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 672 );
7398 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4;
7399
7400 h0 = h0 ^ H0;
7401 h1 = h1 ^ H1;
7402 h2 = h2 ^ H2;
7403 h3 = h3 ^ H3;
7404 h4 = h4 ^ H4;
7405
7406 count = (count-1)|0;
7407 }
7408
7409 H0 = h0;
7410 H1 = h1;
7411 H2 = h2;
7412 H3 = h3;
7413 H4 = h4;
7414
7415 if ( ~output )
7416 _state_to_heap(output);
7417
7418 return 0;
7419 }
7420
7421 return {
7422 // SHA1
7423 reset: reset,
7424 init: init,
7425 process: process,
7426 finish: finish,
7427
7428 // HMAC-SHA1
7429 hmac_reset: hmac_reset,
7430 hmac_init: hmac_init,
7431 hmac_finish: hmac_finish,
7432
7433 // PBKDF2-HMAC-SHA1
7434 pbkdf2_generate_block: pbkdf2_generate_block
7435 }
7436};
7437
7438class Hash {
7439 constructor() {
7440 this.pos = 0;
7441 this.len = 0;
7442 }
7443 reset() {
7444 const { asm } = this.acquire_asm();
7445 this.result = null;
7446 this.pos = 0;
7447 this.len = 0;
7448 asm.reset();
7449 return this;
7450 }
7451 process(data) {
7452 if (this.result !== null)
7453 throw new IllegalStateError('state must be reset before processing new data');
7454 const { asm, heap } = this.acquire_asm();
7455 let hpos = this.pos;
7456 let hlen = this.len;
7457 let dpos = 0;
7458 let dlen = data.length;
7459 let wlen = 0;
7460 while (dlen > 0) {
7461 wlen = _heap_write(heap, hpos + hlen, data, dpos, dlen);
7462 hlen += wlen;
7463 dpos += wlen;
7464 dlen -= wlen;
7465 wlen = asm.process(hpos, hlen);
7466 hpos += wlen;
7467 hlen -= wlen;
7468 if (!hlen)
7469 hpos = 0;
7470 }
7471 this.pos = hpos;
7472 this.len = hlen;
7473 return this;
7474 }
7475 finish() {
7476 if (this.result !== null)
7477 throw new IllegalStateError('state must be reset before processing new data');
7478 const { asm, heap } = this.acquire_asm();
7479 asm.finish(this.pos, this.len, 0);
7480 this.result = new Uint8Array(this.HASH_SIZE);
7481 this.result.set(heap.subarray(0, this.HASH_SIZE));
7482 this.pos = 0;
7483 this.len = 0;
7484 this.release_asm();
7485 return this;
7486 }
7487}
7488
7489const _sha1_block_size = 64;
7490const _sha1_hash_size = 20;
7491const heap_pool$1 = [];
7492const asm_pool$1 = [];
7493class Sha1 extends Hash {
7494 constructor() {
7495 super();
7496 this.NAME = 'sha1';
7497 this.BLOCK_SIZE = _sha1_block_size;
7498 this.HASH_SIZE = _sha1_hash_size;
7499 this.acquire_asm();
7500 }
7501 acquire_asm() {
7502 if (this.heap === undefined || this.asm === undefined) {
7503 this.heap = heap_pool$1.pop() || _heap_init();
7504 this.asm = asm_pool$1.pop() || sha1_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
7505 this.reset();
7506 }
7507 return { heap: this.heap, asm: this.asm };
7508 }
7509 release_asm() {
7510 if (this.heap !== undefined && this.asm !== undefined) {
7511 heap_pool$1.push(this.heap);
7512 asm_pool$1.push(this.asm);
7513 }
7514 this.heap = undefined;
7515 this.asm = undefined;
7516 }
7517 static bytes(data) {
7518 return new Sha1().process(data).finish().result;
7519 }
7520}
7521Sha1.NAME = 'sha1';
7522Sha1.heap_pool = [];
7523Sha1.asm_pool = [];
7524Sha1.asm_function = sha1_asm;
7525
7526var sha256_asm = function ( stdlib, foreign, buffer ) {
7527 "use asm";
7528
7529 // SHA256 state
7530 var H0 = 0, H1 = 0, H2 = 0, H3 = 0, H4 = 0, H5 = 0, H6 = 0, H7 = 0,
7531 TOTAL0 = 0, TOTAL1 = 0;
7532
7533 // HMAC state
7534 var I0 = 0, I1 = 0, I2 = 0, I3 = 0, I4 = 0, I5 = 0, I6 = 0, I7 = 0,
7535 O0 = 0, O1 = 0, O2 = 0, O3 = 0, O4 = 0, O5 = 0, O6 = 0, O7 = 0;
7536
7537 // I/O buffer
7538 var HEAP = new stdlib.Uint8Array(buffer);
7539
7540 function _core ( w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15 ) {
7541 w0 = w0|0;
7542 w1 = w1|0;
7543 w2 = w2|0;
7544 w3 = w3|0;
7545 w4 = w4|0;
7546 w5 = w5|0;
7547 w6 = w6|0;
7548 w7 = w7|0;
7549 w8 = w8|0;
7550 w9 = w9|0;
7551 w10 = w10|0;
7552 w11 = w11|0;
7553 w12 = w12|0;
7554 w13 = w13|0;
7555 w14 = w14|0;
7556 w15 = w15|0;
7557
7558 var a = 0, b = 0, c = 0, d = 0, e = 0, f = 0, g = 0, h = 0;
7559
7560 a = H0;
7561 b = H1;
7562 c = H2;
7563 d = H3;
7564 e = H4;
7565 f = H5;
7566 g = H6;
7567 h = H7;
7568
7569 // 0
7570 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x428a2f98 )|0;
7571 d = ( d + h )|0;
7572 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7573
7574 // 1
7575 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x71374491 )|0;
7576 c = ( c + g )|0;
7577 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7578
7579 // 2
7580 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xb5c0fbcf )|0;
7581 b = ( b + f )|0;
7582 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7583
7584 // 3
7585 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xe9b5dba5 )|0;
7586 a = ( a + e )|0;
7587 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7588
7589 // 4
7590 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x3956c25b )|0;
7591 h = ( h + d )|0;
7592 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7593
7594 // 5
7595 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x59f111f1 )|0;
7596 g = ( g + c )|0;
7597 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7598
7599 // 6
7600 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x923f82a4 )|0;
7601 f = ( f + b )|0;
7602 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7603
7604 // 7
7605 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xab1c5ed5 )|0;
7606 e = ( e + a )|0;
7607 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7608
7609 // 8
7610 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xd807aa98 )|0;
7611 d = ( d + h )|0;
7612 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7613
7614 // 9
7615 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x12835b01 )|0;
7616 c = ( c + g )|0;
7617 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7618
7619 // 10
7620 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x243185be )|0;
7621 b = ( b + f )|0;
7622 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7623
7624 // 11
7625 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x550c7dc3 )|0;
7626 a = ( a + e )|0;
7627 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7628
7629 // 12
7630 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x72be5d74 )|0;
7631 h = ( h + d )|0;
7632 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7633
7634 // 13
7635 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x80deb1fe )|0;
7636 g = ( g + c )|0;
7637 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7638
7639 // 14
7640 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x9bdc06a7 )|0;
7641 f = ( f + b )|0;
7642 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7643
7644 // 15
7645 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xc19bf174 )|0;
7646 e = ( e + a )|0;
7647 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7648
7649 // 16
7650 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
7651 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xe49b69c1 )|0;
7652 d = ( d + h )|0;
7653 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7654
7655 // 17
7656 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
7657 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xefbe4786 )|0;
7658 c = ( c + g )|0;
7659 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7660
7661 // 18
7662 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
7663 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x0fc19dc6 )|0;
7664 b = ( b + f )|0;
7665 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7666
7667 // 19
7668 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
7669 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x240ca1cc )|0;
7670 a = ( a + e )|0;
7671 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7672
7673 // 20
7674 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
7675 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x2de92c6f )|0;
7676 h = ( h + d )|0;
7677 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7678
7679 // 21
7680 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
7681 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x4a7484aa )|0;
7682 g = ( g + c )|0;
7683 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7684
7685 // 22
7686 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
7687 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x5cb0a9dc )|0;
7688 f = ( f + b )|0;
7689 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7690
7691 // 23
7692 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
7693 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x76f988da )|0;
7694 e = ( e + a )|0;
7695 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7696
7697 // 24
7698 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
7699 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x983e5152 )|0;
7700 d = ( d + h )|0;
7701 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7702
7703 // 25
7704 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
7705 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xa831c66d )|0;
7706 c = ( c + g )|0;
7707 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7708
7709 // 26
7710 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
7711 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xb00327c8 )|0;
7712 b = ( b + f )|0;
7713 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7714
7715 // 27
7716 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
7717 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xbf597fc7 )|0;
7718 a = ( a + e )|0;
7719 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7720
7721 // 28
7722 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
7723 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0xc6e00bf3 )|0;
7724 h = ( h + d )|0;
7725 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7726
7727 // 29
7728 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
7729 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xd5a79147 )|0;
7730 g = ( g + c )|0;
7731 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7732
7733 // 30
7734 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
7735 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x06ca6351 )|0;
7736 f = ( f + b )|0;
7737 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7738
7739 // 31
7740 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
7741 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x14292967 )|0;
7742 e = ( e + a )|0;
7743 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7744
7745 // 32
7746 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
7747 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x27b70a85 )|0;
7748 d = ( d + h )|0;
7749 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7750
7751 // 33
7752 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
7753 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x2e1b2138 )|0;
7754 c = ( c + g )|0;
7755 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7756
7757 // 34
7758 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
7759 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x4d2c6dfc )|0;
7760 b = ( b + f )|0;
7761 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7762
7763 // 35
7764 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
7765 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x53380d13 )|0;
7766 a = ( a + e )|0;
7767 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7768
7769 // 36
7770 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
7771 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x650a7354 )|0;
7772 h = ( h + d )|0;
7773 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7774
7775 // 37
7776 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
7777 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x766a0abb )|0;
7778 g = ( g + c )|0;
7779 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7780
7781 // 38
7782 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
7783 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x81c2c92e )|0;
7784 f = ( f + b )|0;
7785 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7786
7787 // 39
7788 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
7789 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x92722c85 )|0;
7790 e = ( e + a )|0;
7791 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7792
7793 // 40
7794 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
7795 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0xa2bfe8a1 )|0;
7796 d = ( d + h )|0;
7797 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7798
7799 // 41
7800 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
7801 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0xa81a664b )|0;
7802 c = ( c + g )|0;
7803 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7804
7805 // 42
7806 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
7807 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0xc24b8b70 )|0;
7808 b = ( b + f )|0;
7809 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7810
7811 // 43
7812 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
7813 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0xc76c51a3 )|0;
7814 a = ( a + e )|0;
7815 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7816
7817 // 44
7818 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
7819 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0xd192e819 )|0;
7820 h = ( h + d )|0;
7821 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7822
7823 // 45
7824 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
7825 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xd6990624 )|0;
7826 g = ( g + c )|0;
7827 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7828
7829 // 46
7830 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
7831 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0xf40e3585 )|0;
7832 f = ( f + b )|0;
7833 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7834
7835 // 47
7836 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
7837 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x106aa070 )|0;
7838 e = ( e + a )|0;
7839 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7840
7841 // 48
7842 w0 = ( ( w1>>>7 ^ w1>>>18 ^ w1>>>3 ^ w1<<25 ^ w1<<14 ) + ( w14>>>17 ^ w14>>>19 ^ w14>>>10 ^ w14<<15 ^ w14<<13 ) + w0 + w9 )|0;
7843 h = ( w0 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x19a4c116 )|0;
7844 d = ( d + h )|0;
7845 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7846
7847 // 49
7848 w1 = ( ( w2>>>7 ^ w2>>>18 ^ w2>>>3 ^ w2<<25 ^ w2<<14 ) + ( w15>>>17 ^ w15>>>19 ^ w15>>>10 ^ w15<<15 ^ w15<<13 ) + w1 + w10 )|0;
7849 g = ( w1 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x1e376c08 )|0;
7850 c = ( c + g )|0;
7851 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7852
7853 // 50
7854 w2 = ( ( w3>>>7 ^ w3>>>18 ^ w3>>>3 ^ w3<<25 ^ w3<<14 ) + ( w0>>>17 ^ w0>>>19 ^ w0>>>10 ^ w0<<15 ^ w0<<13 ) + w2 + w11 )|0;
7855 f = ( w2 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x2748774c )|0;
7856 b = ( b + f )|0;
7857 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7858
7859 // 51
7860 w3 = ( ( w4>>>7 ^ w4>>>18 ^ w4>>>3 ^ w4<<25 ^ w4<<14 ) + ( w1>>>17 ^ w1>>>19 ^ w1>>>10 ^ w1<<15 ^ w1<<13 ) + w3 + w12 )|0;
7861 e = ( w3 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x34b0bcb5 )|0;
7862 a = ( a + e )|0;
7863 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7864
7865 // 52
7866 w4 = ( ( w5>>>7 ^ w5>>>18 ^ w5>>>3 ^ w5<<25 ^ w5<<14 ) + ( w2>>>17 ^ w2>>>19 ^ w2>>>10 ^ w2<<15 ^ w2<<13 ) + w4 + w13 )|0;
7867 d = ( w4 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x391c0cb3 )|0;
7868 h = ( h + d )|0;
7869 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7870
7871 // 53
7872 w5 = ( ( w6>>>7 ^ w6>>>18 ^ w6>>>3 ^ w6<<25 ^ w6<<14 ) + ( w3>>>17 ^ w3>>>19 ^ w3>>>10 ^ w3<<15 ^ w3<<13 ) + w5 + w14 )|0;
7873 c = ( w5 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0x4ed8aa4a )|0;
7874 g = ( g + c )|0;
7875 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7876
7877 // 54
7878 w6 = ( ( w7>>>7 ^ w7>>>18 ^ w7>>>3 ^ w7<<25 ^ w7<<14 ) + ( w4>>>17 ^ w4>>>19 ^ w4>>>10 ^ w4<<15 ^ w4<<13 ) + w6 + w15 )|0;
7879 b = ( w6 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0x5b9cca4f )|0;
7880 f = ( f + b )|0;
7881 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7882
7883 // 55
7884 w7 = ( ( w8>>>7 ^ w8>>>18 ^ w8>>>3 ^ w8<<25 ^ w8<<14 ) + ( w5>>>17 ^ w5>>>19 ^ w5>>>10 ^ w5<<15 ^ w5<<13 ) + w7 + w0 )|0;
7885 a = ( w7 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0x682e6ff3 )|0;
7886 e = ( e + a )|0;
7887 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7888
7889 // 56
7890 w8 = ( ( w9>>>7 ^ w9>>>18 ^ w9>>>3 ^ w9<<25 ^ w9<<14 ) + ( w6>>>17 ^ w6>>>19 ^ w6>>>10 ^ w6<<15 ^ w6<<13 ) + w8 + w1 )|0;
7891 h = ( w8 + h + ( e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7 ) + ( g ^ e & (f^g) ) + 0x748f82ee )|0;
7892 d = ( d + h )|0;
7893 h = ( h + ( (a & b) ^ ( c & (a ^ b) ) ) + ( a>>>2 ^ a>>>13 ^ a>>>22 ^ a<<30 ^ a<<19 ^ a<<10 ) )|0;
7894
7895 // 57
7896 w9 = ( ( w10>>>7 ^ w10>>>18 ^ w10>>>3 ^ w10<<25 ^ w10<<14 ) + ( w7>>>17 ^ w7>>>19 ^ w7>>>10 ^ w7<<15 ^ w7<<13 ) + w9 + w2 )|0;
7897 g = ( w9 + g + ( d>>>6 ^ d>>>11 ^ d>>>25 ^ d<<26 ^ d<<21 ^ d<<7 ) + ( f ^ d & (e^f) ) + 0x78a5636f )|0;
7898 c = ( c + g )|0;
7899 g = ( g + ( (h & a) ^ ( b & (h ^ a) ) ) + ( h>>>2 ^ h>>>13 ^ h>>>22 ^ h<<30 ^ h<<19 ^ h<<10 ) )|0;
7900
7901 // 58
7902 w10 = ( ( w11>>>7 ^ w11>>>18 ^ w11>>>3 ^ w11<<25 ^ w11<<14 ) + ( w8>>>17 ^ w8>>>19 ^ w8>>>10 ^ w8<<15 ^ w8<<13 ) + w10 + w3 )|0;
7903 f = ( w10 + f + ( c>>>6 ^ c>>>11 ^ c>>>25 ^ c<<26 ^ c<<21 ^ c<<7 ) + ( e ^ c & (d^e) ) + 0x84c87814 )|0;
7904 b = ( b + f )|0;
7905 f = ( f + ( (g & h) ^ ( a & (g ^ h) ) ) + ( g>>>2 ^ g>>>13 ^ g>>>22 ^ g<<30 ^ g<<19 ^ g<<10 ) )|0;
7906
7907 // 59
7908 w11 = ( ( w12>>>7 ^ w12>>>18 ^ w12>>>3 ^ w12<<25 ^ w12<<14 ) + ( w9>>>17 ^ w9>>>19 ^ w9>>>10 ^ w9<<15 ^ w9<<13 ) + w11 + w4 )|0;
7909 e = ( w11 + e + ( b>>>6 ^ b>>>11 ^ b>>>25 ^ b<<26 ^ b<<21 ^ b<<7 ) + ( d ^ b & (c^d) ) + 0x8cc70208 )|0;
7910 a = ( a + e )|0;
7911 e = ( e + ( (f & g) ^ ( h & (f ^ g) ) ) + ( f>>>2 ^ f>>>13 ^ f>>>22 ^ f<<30 ^ f<<19 ^ f<<10 ) )|0;
7912
7913 // 60
7914 w12 = ( ( w13>>>7 ^ w13>>>18 ^ w13>>>3 ^ w13<<25 ^ w13<<14 ) + ( w10>>>17 ^ w10>>>19 ^ w10>>>10 ^ w10<<15 ^ w10<<13 ) + w12 + w5 )|0;
7915 d = ( w12 + d + ( a>>>6 ^ a>>>11 ^ a>>>25 ^ a<<26 ^ a<<21 ^ a<<7 ) + ( c ^ a & (b^c) ) + 0x90befffa )|0;
7916 h = ( h + d )|0;
7917 d = ( d + ( (e & f) ^ ( g & (e ^ f) ) ) + ( e>>>2 ^ e>>>13 ^ e>>>22 ^ e<<30 ^ e<<19 ^ e<<10 ) )|0;
7918
7919 // 61
7920 w13 = ( ( w14>>>7 ^ w14>>>18 ^ w14>>>3 ^ w14<<25 ^ w14<<14 ) + ( w11>>>17 ^ w11>>>19 ^ w11>>>10 ^ w11<<15 ^ w11<<13 ) + w13 + w6 )|0;
7921 c = ( w13 + c + ( h>>>6 ^ h>>>11 ^ h>>>25 ^ h<<26 ^ h<<21 ^ h<<7 ) + ( b ^ h & (a^b) ) + 0xa4506ceb )|0;
7922 g = ( g + c )|0;
7923 c = ( c + ( (d & e) ^ ( f & (d ^ e) ) ) + ( d>>>2 ^ d>>>13 ^ d>>>22 ^ d<<30 ^ d<<19 ^ d<<10 ) )|0;
7924
7925 // 62
7926 w14 = ( ( w15>>>7 ^ w15>>>18 ^ w15>>>3 ^ w15<<25 ^ w15<<14 ) + ( w12>>>17 ^ w12>>>19 ^ w12>>>10 ^ w12<<15 ^ w12<<13 ) + w14 + w7 )|0;
7927 b = ( w14 + b + ( g>>>6 ^ g>>>11 ^ g>>>25 ^ g<<26 ^ g<<21 ^ g<<7 ) + ( a ^ g & (h^a) ) + 0xbef9a3f7 )|0;
7928 f = ( f + b )|0;
7929 b = ( b + ( (c & d) ^ ( e & (c ^ d) ) ) + ( c>>>2 ^ c>>>13 ^ c>>>22 ^ c<<30 ^ c<<19 ^ c<<10 ) )|0;
7930
7931 // 63
7932 w15 = ( ( w0>>>7 ^ w0>>>18 ^ w0>>>3 ^ w0<<25 ^ w0<<14 ) + ( w13>>>17 ^ w13>>>19 ^ w13>>>10 ^ w13<<15 ^ w13<<13 ) + w15 + w8 )|0;
7933 a = ( w15 + a + ( f>>>6 ^ f>>>11 ^ f>>>25 ^ f<<26 ^ f<<21 ^ f<<7 ) + ( h ^ f & (g^h) ) + 0xc67178f2 )|0;
7934 e = ( e + a )|0;
7935 a = ( a + ( (b & c) ^ ( d & (b ^ c) ) ) + ( b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10 ) )|0;
7936
7937 H0 = ( H0 + a )|0;
7938 H1 = ( H1 + b )|0;
7939 H2 = ( H2 + c )|0;
7940 H3 = ( H3 + d )|0;
7941 H4 = ( H4 + e )|0;
7942 H5 = ( H5 + f )|0;
7943 H6 = ( H6 + g )|0;
7944 H7 = ( H7 + h )|0;
7945 }
7946
7947 function _core_heap ( offset ) {
7948 offset = offset|0;
7949
7950 _core(
7951 HEAP[offset|0]<<24 | HEAP[offset|1]<<16 | HEAP[offset|2]<<8 | HEAP[offset|3],
7952 HEAP[offset|4]<<24 | HEAP[offset|5]<<16 | HEAP[offset|6]<<8 | HEAP[offset|7],
7953 HEAP[offset|8]<<24 | HEAP[offset|9]<<16 | HEAP[offset|10]<<8 | HEAP[offset|11],
7954 HEAP[offset|12]<<24 | HEAP[offset|13]<<16 | HEAP[offset|14]<<8 | HEAP[offset|15],
7955 HEAP[offset|16]<<24 | HEAP[offset|17]<<16 | HEAP[offset|18]<<8 | HEAP[offset|19],
7956 HEAP[offset|20]<<24 | HEAP[offset|21]<<16 | HEAP[offset|22]<<8 | HEAP[offset|23],
7957 HEAP[offset|24]<<24 | HEAP[offset|25]<<16 | HEAP[offset|26]<<8 | HEAP[offset|27],
7958 HEAP[offset|28]<<24 | HEAP[offset|29]<<16 | HEAP[offset|30]<<8 | HEAP[offset|31],
7959 HEAP[offset|32]<<24 | HEAP[offset|33]<<16 | HEAP[offset|34]<<8 | HEAP[offset|35],
7960 HEAP[offset|36]<<24 | HEAP[offset|37]<<16 | HEAP[offset|38]<<8 | HEAP[offset|39],
7961 HEAP[offset|40]<<24 | HEAP[offset|41]<<16 | HEAP[offset|42]<<8 | HEAP[offset|43],
7962 HEAP[offset|44]<<24 | HEAP[offset|45]<<16 | HEAP[offset|46]<<8 | HEAP[offset|47],
7963 HEAP[offset|48]<<24 | HEAP[offset|49]<<16 | HEAP[offset|50]<<8 | HEAP[offset|51],
7964 HEAP[offset|52]<<24 | HEAP[offset|53]<<16 | HEAP[offset|54]<<8 | HEAP[offset|55],
7965 HEAP[offset|56]<<24 | HEAP[offset|57]<<16 | HEAP[offset|58]<<8 | HEAP[offset|59],
7966 HEAP[offset|60]<<24 | HEAP[offset|61]<<16 | HEAP[offset|62]<<8 | HEAP[offset|63]
7967 );
7968 }
7969
7970 // offset — multiple of 32
7971 function _state_to_heap ( output ) {
7972 output = output|0;
7973
7974 HEAP[output|0] = H0>>>24;
7975 HEAP[output|1] = H0>>>16&255;
7976 HEAP[output|2] = H0>>>8&255;
7977 HEAP[output|3] = H0&255;
7978 HEAP[output|4] = H1>>>24;
7979 HEAP[output|5] = H1>>>16&255;
7980 HEAP[output|6] = H1>>>8&255;
7981 HEAP[output|7] = H1&255;
7982 HEAP[output|8] = H2>>>24;
7983 HEAP[output|9] = H2>>>16&255;
7984 HEAP[output|10] = H2>>>8&255;
7985 HEAP[output|11] = H2&255;
7986 HEAP[output|12] = H3>>>24;
7987 HEAP[output|13] = H3>>>16&255;
7988 HEAP[output|14] = H3>>>8&255;
7989 HEAP[output|15] = H3&255;
7990 HEAP[output|16] = H4>>>24;
7991 HEAP[output|17] = H4>>>16&255;
7992 HEAP[output|18] = H4>>>8&255;
7993 HEAP[output|19] = H4&255;
7994 HEAP[output|20] = H5>>>24;
7995 HEAP[output|21] = H5>>>16&255;
7996 HEAP[output|22] = H5>>>8&255;
7997 HEAP[output|23] = H5&255;
7998 HEAP[output|24] = H6>>>24;
7999 HEAP[output|25] = H6>>>16&255;
8000 HEAP[output|26] = H6>>>8&255;
8001 HEAP[output|27] = H6&255;
8002 HEAP[output|28] = H7>>>24;
8003 HEAP[output|29] = H7>>>16&255;
8004 HEAP[output|30] = H7>>>8&255;
8005 HEAP[output|31] = H7&255;
8006 }
8007
8008 function reset () {
8009 H0 = 0x6a09e667;
8010 H1 = 0xbb67ae85;
8011 H2 = 0x3c6ef372;
8012 H3 = 0xa54ff53a;
8013 H4 = 0x510e527f;
8014 H5 = 0x9b05688c;
8015 H6 = 0x1f83d9ab;
8016 H7 = 0x5be0cd19;
8017 TOTAL0 = TOTAL1 = 0;
8018 }
8019
8020 function init ( h0, h1, h2, h3, h4, h5, h6, h7, total0, total1 ) {
8021 h0 = h0|0;
8022 h1 = h1|0;
8023 h2 = h2|0;
8024 h3 = h3|0;
8025 h4 = h4|0;
8026 h5 = h5|0;
8027 h6 = h6|0;
8028 h7 = h7|0;
8029 total0 = total0|0;
8030 total1 = total1|0;
8031
8032 H0 = h0;
8033 H1 = h1;
8034 H2 = h2;
8035 H3 = h3;
8036 H4 = h4;
8037 H5 = h5;
8038 H6 = h6;
8039 H7 = h7;
8040 TOTAL0 = total0;
8041 TOTAL1 = total1;
8042 }
8043
8044 // offset — multiple of 64
8045 function process ( offset, length ) {
8046 offset = offset|0;
8047 length = length|0;
8048
8049 var hashed = 0;
8050
8051 if ( offset & 63 )
8052 return -1;
8053
8054 while ( (length|0) >= 64 ) {
8055 _core_heap(offset);
8056
8057 offset = ( offset + 64 )|0;
8058 length = ( length - 64 )|0;
8059
8060 hashed = ( hashed + 64 )|0;
8061 }
8062
8063 TOTAL0 = ( TOTAL0 + hashed )|0;
8064 if ( TOTAL0>>>0 < hashed>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
8065
8066 return hashed|0;
8067 }
8068
8069 // offset — multiple of 64
8070 // output — multiple of 32
8071 function finish ( offset, length, output ) {
8072 offset = offset|0;
8073 length = length|0;
8074 output = output|0;
8075
8076 var hashed = 0,
8077 i = 0;
8078
8079 if ( offset & 63 )
8080 return -1;
8081
8082 if ( ~output )
8083 if ( output & 31 )
8084 return -1;
8085
8086 if ( (length|0) >= 64 ) {
8087 hashed = process( offset, length )|0;
8088 if ( (hashed|0) == -1 )
8089 return -1;
8090
8091 offset = ( offset + hashed )|0;
8092 length = ( length - hashed )|0;
8093 }
8094
8095 hashed = ( hashed + length )|0;
8096 TOTAL0 = ( TOTAL0 + length )|0;
8097 if ( TOTAL0>>>0 < length>>>0 ) TOTAL1 = ( TOTAL1 + 1 )|0;
8098
8099 HEAP[offset|length] = 0x80;
8100
8101 if ( (length|0) >= 56 ) {
8102 for ( i = (length+1)|0; (i|0) < 64; i = (i+1)|0 )
8103 HEAP[offset|i] = 0x00;
8104
8105 _core_heap(offset);
8106
8107 length = 0;
8108
8109 HEAP[offset|0] = 0;
8110 }
8111
8112 for ( i = (length+1)|0; (i|0) < 59; i = (i+1)|0 )
8113 HEAP[offset|i] = 0;
8114
8115 HEAP[offset|56] = TOTAL1>>>21&255;
8116 HEAP[offset|57] = TOTAL1>>>13&255;
8117 HEAP[offset|58] = TOTAL1>>>5&255;
8118 HEAP[offset|59] = TOTAL1<<3&255 | TOTAL0>>>29;
8119 HEAP[offset|60] = TOTAL0>>>21&255;
8120 HEAP[offset|61] = TOTAL0>>>13&255;
8121 HEAP[offset|62] = TOTAL0>>>5&255;
8122 HEAP[offset|63] = TOTAL0<<3&255;
8123 _core_heap(offset);
8124
8125 if ( ~output )
8126 _state_to_heap(output);
8127
8128 return hashed|0;
8129 }
8130
8131 function hmac_reset () {
8132 H0 = I0;
8133 H1 = I1;
8134 H2 = I2;
8135 H3 = I3;
8136 H4 = I4;
8137 H5 = I5;
8138 H6 = I6;
8139 H7 = I7;
8140 TOTAL0 = 64;
8141 TOTAL1 = 0;
8142 }
8143
8144 function _hmac_opad () {
8145 H0 = O0;
8146 H1 = O1;
8147 H2 = O2;
8148 H3 = O3;
8149 H4 = O4;
8150 H5 = O5;
8151 H6 = O6;
8152 H7 = O7;
8153 TOTAL0 = 64;
8154 TOTAL1 = 0;
8155 }
8156
8157 function hmac_init ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 ) {
8158 p0 = p0|0;
8159 p1 = p1|0;
8160 p2 = p2|0;
8161 p3 = p3|0;
8162 p4 = p4|0;
8163 p5 = p5|0;
8164 p6 = p6|0;
8165 p7 = p7|0;
8166 p8 = p8|0;
8167 p9 = p9|0;
8168 p10 = p10|0;
8169 p11 = p11|0;
8170 p12 = p12|0;
8171 p13 = p13|0;
8172 p14 = p14|0;
8173 p15 = p15|0;
8174
8175 // opad
8176 reset();
8177 _core(
8178 p0 ^ 0x5c5c5c5c,
8179 p1 ^ 0x5c5c5c5c,
8180 p2 ^ 0x5c5c5c5c,
8181 p3 ^ 0x5c5c5c5c,
8182 p4 ^ 0x5c5c5c5c,
8183 p5 ^ 0x5c5c5c5c,
8184 p6 ^ 0x5c5c5c5c,
8185 p7 ^ 0x5c5c5c5c,
8186 p8 ^ 0x5c5c5c5c,
8187 p9 ^ 0x5c5c5c5c,
8188 p10 ^ 0x5c5c5c5c,
8189 p11 ^ 0x5c5c5c5c,
8190 p12 ^ 0x5c5c5c5c,
8191 p13 ^ 0x5c5c5c5c,
8192 p14 ^ 0x5c5c5c5c,
8193 p15 ^ 0x5c5c5c5c
8194 );
8195 O0 = H0;
8196 O1 = H1;
8197 O2 = H2;
8198 O3 = H3;
8199 O4 = H4;
8200 O5 = H5;
8201 O6 = H6;
8202 O7 = H7;
8203
8204 // ipad
8205 reset();
8206 _core(
8207 p0 ^ 0x36363636,
8208 p1 ^ 0x36363636,
8209 p2 ^ 0x36363636,
8210 p3 ^ 0x36363636,
8211 p4 ^ 0x36363636,
8212 p5 ^ 0x36363636,
8213 p6 ^ 0x36363636,
8214 p7 ^ 0x36363636,
8215 p8 ^ 0x36363636,
8216 p9 ^ 0x36363636,
8217 p10 ^ 0x36363636,
8218 p11 ^ 0x36363636,
8219 p12 ^ 0x36363636,
8220 p13 ^ 0x36363636,
8221 p14 ^ 0x36363636,
8222 p15 ^ 0x36363636
8223 );
8224 I0 = H0;
8225 I1 = H1;
8226 I2 = H2;
8227 I3 = H3;
8228 I4 = H4;
8229 I5 = H5;
8230 I6 = H6;
8231 I7 = H7;
8232
8233 TOTAL0 = 64;
8234 TOTAL1 = 0;
8235 }
8236
8237 // offset — multiple of 64
8238 // output — multiple of 32
8239 function hmac_finish ( offset, length, output ) {
8240 offset = offset|0;
8241 length = length|0;
8242 output = output|0;
8243
8244 var t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
8245 hashed = 0;
8246
8247 if ( offset & 63 )
8248 return -1;
8249
8250 if ( ~output )
8251 if ( output & 31 )
8252 return -1;
8253
8254 hashed = finish( offset, length, -1 )|0;
8255 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
8256
8257 _hmac_opad();
8258 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
8259
8260 if ( ~output )
8261 _state_to_heap(output);
8262
8263 return hashed|0;
8264 }
8265
8266 // salt is assumed to be already processed
8267 // offset — multiple of 64
8268 // output — multiple of 32
8269 function pbkdf2_generate_block ( offset, length, block, count, output ) {
8270 offset = offset|0;
8271 length = length|0;
8272 block = block|0;
8273 count = count|0;
8274 output = output|0;
8275
8276 var h0 = 0, h1 = 0, h2 = 0, h3 = 0, h4 = 0, h5 = 0, h6 = 0, h7 = 0,
8277 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0;
8278
8279 if ( offset & 63 )
8280 return -1;
8281
8282 if ( ~output )
8283 if ( output & 31 )
8284 return -1;
8285
8286 // pad block number into heap
8287 // FIXME probable OOB write
8288 HEAP[(offset+length)|0] = block>>>24;
8289 HEAP[(offset+length+1)|0] = block>>>16&255;
8290 HEAP[(offset+length+2)|0] = block>>>8&255;
8291 HEAP[(offset+length+3)|0] = block&255;
8292
8293 // finish first iteration
8294 hmac_finish( offset, (length+4)|0, -1 )|0;
8295 h0 = t0 = H0, h1 = t1 = H1, h2 = t2 = H2, h3 = t3 = H3, h4 = t4 = H4, h5 = t5 = H5, h6 = t6 = H6, h7 = t7 = H7;
8296 count = (count-1)|0;
8297
8298 // perform the rest iterations
8299 while ( (count|0) > 0 ) {
8300 hmac_reset();
8301 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
8302 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
8303
8304 _hmac_opad();
8305 _core( t0, t1, t2, t3, t4, t5, t6, t7, 0x80000000, 0, 0, 0, 0, 0, 0, 768 );
8306 t0 = H0, t1 = H1, t2 = H2, t3 = H3, t4 = H4, t5 = H5, t6 = H6, t7 = H7;
8307
8308 h0 = h0 ^ H0;
8309 h1 = h1 ^ H1;
8310 h2 = h2 ^ H2;
8311 h3 = h3 ^ H3;
8312 h4 = h4 ^ H4;
8313 h5 = h5 ^ H5;
8314 h6 = h6 ^ H6;
8315 h7 = h7 ^ H7;
8316
8317 count = (count-1)|0;
8318 }
8319
8320 H0 = h0;
8321 H1 = h1;
8322 H2 = h2;
8323 H3 = h3;
8324 H4 = h4;
8325 H5 = h5;
8326 H6 = h6;
8327 H7 = h7;
8328
8329 if ( ~output )
8330 _state_to_heap(output);
8331
8332 return 0;
8333 }
8334
8335 return {
8336 // SHA256
8337 reset: reset,
8338 init: init,
8339 process: process,
8340 finish: finish,
8341
8342 // HMAC-SHA256
8343 hmac_reset: hmac_reset,
8344 hmac_init: hmac_init,
8345 hmac_finish: hmac_finish,
8346
8347 // PBKDF2-HMAC-SHA256
8348 pbkdf2_generate_block: pbkdf2_generate_block
8349 }
8350};
8351
8352const _sha256_block_size = 64;
8353const _sha256_hash_size = 32;
8354const heap_pool$2 = [];
8355const asm_pool$2 = [];
8356class Sha256 extends Hash {
8357 constructor() {
8358 super();
8359 this.NAME = 'sha256';
8360 this.BLOCK_SIZE = _sha256_block_size;
8361 this.HASH_SIZE = _sha256_hash_size;
8362 this.acquire_asm();
8363 }
8364 acquire_asm() {
8365 if (this.heap === undefined || this.asm === undefined) {
8366 this.heap = heap_pool$2.pop() || _heap_init();
8367 this.asm = asm_pool$2.pop() || sha256_asm({ Uint8Array: Uint8Array }, null, this.heap.buffer);
8368 this.reset();
8369 }
8370 return { heap: this.heap, asm: this.asm };
8371 }
8372 release_asm() {
8373 if (this.heap !== undefined && this.asm !== undefined) {
8374 heap_pool$2.push(this.heap);
8375 asm_pool$2.push(this.asm);
8376 }
8377 this.heap = undefined;
8378 this.asm = undefined;
8379 }
8380 static bytes(data) {
8381 return new Sha256().process(data).finish().result;
8382 }
8383}
8384Sha256.NAME = 'sha256';
8385
8386var minimalisticAssert = assert;
8387
8388function assert(val, msg) {
8389 if (!val)
8390 throw new Error(msg || 'Assertion failed');
8391}
8392
8393assert.equal = function assertEqual(l, r, msg) {
8394 if (l != r)
8395 throw new Error(msg || ('Assertion failed: ' + l + ' != ' + r));
8396};
8397
8398var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8399
8400function createCommonjsModule(fn, module) {
8401 return module = { exports: {} }, fn(module, module.exports), module.exports;
8402}
8403
8404function commonjsRequire () {
8405 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
8406}
8407
8408var inherits_browser = createCommonjsModule(function (module) {
8409if (typeof Object.create === 'function') {
8410 // implementation from standard node.js 'util' module
8411 module.exports = function inherits(ctor, superCtor) {
8412 ctor.super_ = superCtor;
8413 ctor.prototype = Object.create(superCtor.prototype, {
8414 constructor: {
8415 value: ctor,
8416 enumerable: false,
8417 writable: true,
8418 configurable: true
8419 }
8420 });
8421 };
8422} else {
8423 // old school shim for old browsers
8424 module.exports = function inherits(ctor, superCtor) {
8425 ctor.super_ = superCtor;
8426 var TempCtor = function () {};
8427 TempCtor.prototype = superCtor.prototype;
8428 ctor.prototype = new TempCtor();
8429 ctor.prototype.constructor = ctor;
8430 };
8431}
8432});
8433
8434var inherits = createCommonjsModule(function (module) {
8435try {
8436 var util = util$1;
8437 if (typeof util.inherits !== 'function') throw '';
8438 module.exports = util.inherits;
8439} catch (e) {
8440 module.exports = inherits_browser;
8441}
8442});
8443
8444var inherits_1 = inherits;
8445
8446function toArray(msg, enc) {
8447 if (Array.isArray(msg))
8448 return msg.slice();
8449 if (!msg)
8450 return [];
8451 var res = [];
8452 if (typeof msg === 'string') {
8453 if (!enc) {
8454 for (var i = 0; i < msg.length; i++) {
8455 var c = msg.charCodeAt(i);
8456 var hi = c >> 8;
8457 var lo = c & 0xff;
8458 if (hi)
8459 res.push(hi, lo);
8460 else
8461 res.push(lo);
8462 }
8463 } else if (enc === 'hex') {
8464 msg = msg.replace(/[^a-z0-9]+/ig, '');
8465 if (msg.length % 2 !== 0)
8466 msg = '0' + msg;
8467 for (i = 0; i < msg.length; i += 2)
8468 res.push(parseInt(msg[i] + msg[i + 1], 16));
8469 }
8470 } else {
8471 for (i = 0; i < msg.length; i++)
8472 res[i] = msg[i] | 0;
8473 }
8474 return res;
8475}
8476var toArray_1 = toArray;
8477
8478function toHex(msg) {
8479 var res = '';
8480 for (var i = 0; i < msg.length; i++)
8481 res += zero2(msg[i].toString(16));
8482 return res;
8483}
8484var toHex_1 = toHex;
8485
8486function htonl(w) {
8487 var res = (w >>> 24) |
8488 ((w >>> 8) & 0xff00) |
8489 ((w << 8) & 0xff0000) |
8490 ((w & 0xff) << 24);
8491 return res >>> 0;
8492}
8493var htonl_1 = htonl;
8494
8495function toHex32(msg, endian) {
8496 var res = '';
8497 for (var i = 0; i < msg.length; i++) {
8498 var w = msg[i];
8499 if (endian === 'little')
8500 w = htonl(w);
8501 res += zero8(w.toString(16));
8502 }
8503 return res;
8504}
8505var toHex32_1 = toHex32;
8506
8507function zero2(word) {
8508 if (word.length === 1)
8509 return '0' + word;
8510 else
8511 return word;
8512}
8513var zero2_1 = zero2;
8514
8515function zero8(word) {
8516 if (word.length === 7)
8517 return '0' + word;
8518 else if (word.length === 6)
8519 return '00' + word;
8520 else if (word.length === 5)
8521 return '000' + word;
8522 else if (word.length === 4)
8523 return '0000' + word;
8524 else if (word.length === 3)
8525 return '00000' + word;
8526 else if (word.length === 2)
8527 return '000000' + word;
8528 else if (word.length === 1)
8529 return '0000000' + word;
8530 else
8531 return word;
8532}
8533var zero8_1 = zero8;
8534
8535function join32(msg, start, end, endian) {
8536 var len = end - start;
8537 minimalisticAssert(len % 4 === 0);
8538 var res = new Array(len / 4);
8539 for (var i = 0, k = start; i < res.length; i++, k += 4) {
8540 var w;
8541 if (endian === 'big')
8542 w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
8543 else
8544 w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
8545 res[i] = w >>> 0;
8546 }
8547 return res;
8548}
8549var join32_1 = join32;
8550
8551function split32(msg, endian) {
8552 var res = new Array(msg.length * 4);
8553 for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
8554 var m = msg[i];
8555 if (endian === 'big') {
8556 res[k] = m >>> 24;
8557 res[k + 1] = (m >>> 16) & 0xff;
8558 res[k + 2] = (m >>> 8) & 0xff;
8559 res[k + 3] = m & 0xff;
8560 } else {
8561 res[k + 3] = m >>> 24;
8562 res[k + 2] = (m >>> 16) & 0xff;
8563 res[k + 1] = (m >>> 8) & 0xff;
8564 res[k] = m & 0xff;
8565 }
8566 }
8567 return res;
8568}
8569var split32_1 = split32;
8570
8571function rotr32(w, b) {
8572 return (w >>> b) | (w << (32 - b));
8573}
8574var rotr32_1 = rotr32;
8575
8576function rotl32(w, b) {
8577 return (w << b) | (w >>> (32 - b));
8578}
8579var rotl32_1 = rotl32;
8580
8581function sum32(a, b) {
8582 return (a + b) >>> 0;
8583}
8584var sum32_1 = sum32;
8585
8586function sum32_3(a, b, c) {
8587 return (a + b + c) >>> 0;
8588}
8589var sum32_3_1 = sum32_3;
8590
8591function sum32_4(a, b, c, d) {
8592 return (a + b + c + d) >>> 0;
8593}
8594var sum32_4_1 = sum32_4;
8595
8596function sum32_5(a, b, c, d, e) {
8597 return (a + b + c + d + e) >>> 0;
8598}
8599var sum32_5_1 = sum32_5;
8600
8601function sum64(buf, pos, ah, al) {
8602 var bh = buf[pos];
8603 var bl = buf[pos + 1];
8604
8605 var lo = (al + bl) >>> 0;
8606 var hi = (lo < al ? 1 : 0) + ah + bh;
8607 buf[pos] = hi >>> 0;
8608 buf[pos + 1] = lo;
8609}
8610var sum64_1 = sum64;
8611
8612function sum64_hi(ah, al, bh, bl) {
8613 var lo = (al + bl) >>> 0;
8614 var hi = (lo < al ? 1 : 0) + ah + bh;
8615 return hi >>> 0;
8616}
8617var sum64_hi_1 = sum64_hi;
8618
8619function sum64_lo(ah, al, bh, bl) {
8620 var lo = al + bl;
8621 return lo >>> 0;
8622}
8623var sum64_lo_1 = sum64_lo;
8624
8625function sum64_4_hi(ah, al, bh, bl, ch, cl, dh, dl) {
8626 var carry = 0;
8627 var lo = al;
8628 lo = (lo + bl) >>> 0;
8629 carry += lo < al ? 1 : 0;
8630 lo = (lo + cl) >>> 0;
8631 carry += lo < cl ? 1 : 0;
8632 lo = (lo + dl) >>> 0;
8633 carry += lo < dl ? 1 : 0;
8634
8635 var hi = ah + bh + ch + dh + carry;
8636 return hi >>> 0;
8637}
8638var sum64_4_hi_1 = sum64_4_hi;
8639
8640function sum64_4_lo(ah, al, bh, bl, ch, cl, dh, dl) {
8641 var lo = al + bl + cl + dl;
8642 return lo >>> 0;
8643}
8644var sum64_4_lo_1 = sum64_4_lo;
8645
8646function sum64_5_hi(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
8647 var carry = 0;
8648 var lo = al;
8649 lo = (lo + bl) >>> 0;
8650 carry += lo < al ? 1 : 0;
8651 lo = (lo + cl) >>> 0;
8652 carry += lo < cl ? 1 : 0;
8653 lo = (lo + dl) >>> 0;
8654 carry += lo < dl ? 1 : 0;
8655 lo = (lo + el) >>> 0;
8656 carry += lo < el ? 1 : 0;
8657
8658 var hi = ah + bh + ch + dh + eh + carry;
8659 return hi >>> 0;
8660}
8661var sum64_5_hi_1 = sum64_5_hi;
8662
8663function sum64_5_lo(ah, al, bh, bl, ch, cl, dh, dl, eh, el) {
8664 var lo = al + bl + cl + dl + el;
8665
8666 return lo >>> 0;
8667}
8668var sum64_5_lo_1 = sum64_5_lo;
8669
8670function rotr64_hi(ah, al, num) {
8671 var r = (al << (32 - num)) | (ah >>> num);
8672 return r >>> 0;
8673}
8674var rotr64_hi_1 = rotr64_hi;
8675
8676function rotr64_lo(ah, al, num) {
8677 var r = (ah << (32 - num)) | (al >>> num);
8678 return r >>> 0;
8679}
8680var rotr64_lo_1 = rotr64_lo;
8681
8682function shr64_hi(ah, al, num) {
8683 return ah >>> num;
8684}
8685var shr64_hi_1 = shr64_hi;
8686
8687function shr64_lo(ah, al, num) {
8688 var r = (ah << (32 - num)) | (al >>> num);
8689 return r >>> 0;
8690}
8691var shr64_lo_1 = shr64_lo;
8692
8693var utils = {
8694 inherits: inherits_1,
8695 toArray: toArray_1,
8696 toHex: toHex_1,
8697 htonl: htonl_1,
8698 toHex32: toHex32_1,
8699 zero2: zero2_1,
8700 zero8: zero8_1,
8701 join32: join32_1,
8702 split32: split32_1,
8703 rotr32: rotr32_1,
8704 rotl32: rotl32_1,
8705 sum32: sum32_1,
8706 sum32_3: sum32_3_1,
8707 sum32_4: sum32_4_1,
8708 sum32_5: sum32_5_1,
8709 sum64: sum64_1,
8710 sum64_hi: sum64_hi_1,
8711 sum64_lo: sum64_lo_1,
8712 sum64_4_hi: sum64_4_hi_1,
8713 sum64_4_lo: sum64_4_lo_1,
8714 sum64_5_hi: sum64_5_hi_1,
8715 sum64_5_lo: sum64_5_lo_1,
8716 rotr64_hi: rotr64_hi_1,
8717 rotr64_lo: rotr64_lo_1,
8718 shr64_hi: shr64_hi_1,
8719 shr64_lo: shr64_lo_1
8720};
8721
8722function BlockHash() {
8723 this.pending = null;
8724 this.pendingTotal = 0;
8725 this.blockSize = this.constructor.blockSize;
8726 this.outSize = this.constructor.outSize;
8727 this.hmacStrength = this.constructor.hmacStrength;
8728 this.padLength = this.constructor.padLength / 8;
8729 this.endian = 'big';
8730
8731 this._delta8 = this.blockSize / 8;
8732 this._delta32 = this.blockSize / 32;
8733}
8734var BlockHash_1 = BlockHash;
8735
8736BlockHash.prototype.update = function update(msg, enc) {
8737 // Convert message to array, pad it, and join into 32bit blocks
8738 msg = utils.toArray(msg, enc);
8739 if (!this.pending)
8740 this.pending = msg;
8741 else
8742 this.pending = this.pending.concat(msg);
8743 this.pendingTotal += msg.length;
8744
8745 // Enough data, try updating
8746 if (this.pending.length >= this._delta8) {
8747 msg = this.pending;
8748
8749 // Process pending data in blocks
8750 var r = msg.length % this._delta8;
8751 this.pending = msg.slice(msg.length - r, msg.length);
8752 if (this.pending.length === 0)
8753 this.pending = null;
8754
8755 msg = utils.join32(msg, 0, msg.length - r, this.endian);
8756 for (var i = 0; i < msg.length; i += this._delta32)
8757 this._update(msg, i, i + this._delta32);
8758 }
8759
8760 return this;
8761};
8762
8763BlockHash.prototype.digest = function digest(enc) {
8764 this.update(this._pad());
8765 minimalisticAssert(this.pending === null);
8766
8767 return this._digest(enc);
8768};
8769
8770BlockHash.prototype._pad = function pad() {
8771 var len = this.pendingTotal;
8772 var bytes = this._delta8;
8773 var k = bytes - ((len + this.padLength) % bytes);
8774 var res = new Array(k + this.padLength);
8775 res[0] = 0x80;
8776 for (var i = 1; i < k; i++)
8777 res[i] = 0;
8778
8779 // Append length
8780 len <<= 3;
8781 if (this.endian === 'big') {
8782 for (var t = 8; t < this.padLength; t++)
8783 res[i++] = 0;
8784
8785 res[i++] = 0;
8786 res[i++] = 0;
8787 res[i++] = 0;
8788 res[i++] = 0;
8789 res[i++] = (len >>> 24) & 0xff;
8790 res[i++] = (len >>> 16) & 0xff;
8791 res[i++] = (len >>> 8) & 0xff;
8792 res[i++] = len & 0xff;
8793 } else {
8794 res[i++] = len & 0xff;
8795 res[i++] = (len >>> 8) & 0xff;
8796 res[i++] = (len >>> 16) & 0xff;
8797 res[i++] = (len >>> 24) & 0xff;
8798 res[i++] = 0;
8799 res[i++] = 0;
8800 res[i++] = 0;
8801 res[i++] = 0;
8802
8803 for (t = 8; t < this.padLength; t++)
8804 res[i++] = 0;
8805 }
8806
8807 return res;
8808};
8809
8810var common = {
8811 BlockHash: BlockHash_1
8812};
8813
8814var rotr32$1 = utils.rotr32;
8815
8816function ft_1(s, x, y, z) {
8817 if (s === 0)
8818 return ch32(x, y, z);
8819 if (s === 1 || s === 3)
8820 return p32(x, y, z);
8821 if (s === 2)
8822 return maj32(x, y, z);
8823}
8824var ft_1_1 = ft_1;
8825
8826function ch32(x, y, z) {
8827 return (x & y) ^ ((~x) & z);
8828}
8829var ch32_1 = ch32;
8830
8831function maj32(x, y, z) {
8832 return (x & y) ^ (x & z) ^ (y & z);
8833}
8834var maj32_1 = maj32;
8835
8836function p32(x, y, z) {
8837 return x ^ y ^ z;
8838}
8839var p32_1 = p32;
8840
8841function s0_256(x) {
8842 return rotr32$1(x, 2) ^ rotr32$1(x, 13) ^ rotr32$1(x, 22);
8843}
8844var s0_256_1 = s0_256;
8845
8846function s1_256(x) {
8847 return rotr32$1(x, 6) ^ rotr32$1(x, 11) ^ rotr32$1(x, 25);
8848}
8849var s1_256_1 = s1_256;
8850
8851function g0_256(x) {
8852 return rotr32$1(x, 7) ^ rotr32$1(x, 18) ^ (x >>> 3);
8853}
8854var g0_256_1 = g0_256;
8855
8856function g1_256(x) {
8857 return rotr32$1(x, 17) ^ rotr32$1(x, 19) ^ (x >>> 10);
8858}
8859var g1_256_1 = g1_256;
8860
8861var common$1 = {
8862 ft_1: ft_1_1,
8863 ch32: ch32_1,
8864 maj32: maj32_1,
8865 p32: p32_1,
8866 s0_256: s0_256_1,
8867 s1_256: s1_256_1,
8868 g0_256: g0_256_1,
8869 g1_256: g1_256_1
8870};
8871
8872var sum32$1 = utils.sum32;
8873var sum32_4$1 = utils.sum32_4;
8874var sum32_5$1 = utils.sum32_5;
8875var ch32$1 = common$1.ch32;
8876var maj32$1 = common$1.maj32;
8877var s0_256$1 = common$1.s0_256;
8878var s1_256$1 = common$1.s1_256;
8879var g0_256$1 = common$1.g0_256;
8880var g1_256$1 = common$1.g1_256;
8881
8882var BlockHash$1 = common.BlockHash;
8883
8884var sha256_K = [
8885 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
8886 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
8887 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
8888 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
8889 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
8890 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
8891 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
8892 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
8893 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
8894 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
8895 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
8896 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
8897 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
8898 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
8899 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
8900 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
8901];
8902
8903function SHA256() {
8904 if (!(this instanceof SHA256))
8905 return new SHA256();
8906
8907 BlockHash$1.call(this);
8908 this.h = [
8909 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
8910 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
8911 ];
8912 this.k = sha256_K;
8913 this.W = new Array(64);
8914}
8915utils.inherits(SHA256, BlockHash$1);
8916var _256 = SHA256;
8917
8918SHA256.blockSize = 512;
8919SHA256.outSize = 256;
8920SHA256.hmacStrength = 192;
8921SHA256.padLength = 64;
8922
8923SHA256.prototype._update = function _update(msg, start) {
8924 var W = this.W;
8925
8926 for (var i = 0; i < 16; i++)
8927 W[i] = msg[start + i];
8928 for (; i < W.length; i++)
8929 W[i] = sum32_4$1(g1_256$1(W[i - 2]), W[i - 7], g0_256$1(W[i - 15]), W[i - 16]);
8930
8931 var a = this.h[0];
8932 var b = this.h[1];
8933 var c = this.h[2];
8934 var d = this.h[3];
8935 var e = this.h[4];
8936 var f = this.h[5];
8937 var g = this.h[6];
8938 var h = this.h[7];
8939
8940 minimalisticAssert(this.k.length === W.length);
8941 for (i = 0; i < W.length; i++) {
8942 var T1 = sum32_5$1(h, s1_256$1(e), ch32$1(e, f, g), this.k[i], W[i]);
8943 var T2 = sum32$1(s0_256$1(a), maj32$1(a, b, c));
8944 h = g;
8945 g = f;
8946 f = e;
8947 e = sum32$1(d, T1);
8948 d = c;
8949 c = b;
8950 b = a;
8951 a = sum32$1(T1, T2);
8952 }
8953
8954 this.h[0] = sum32$1(this.h[0], a);
8955 this.h[1] = sum32$1(this.h[1], b);
8956 this.h[2] = sum32$1(this.h[2], c);
8957 this.h[3] = sum32$1(this.h[3], d);
8958 this.h[4] = sum32$1(this.h[4], e);
8959 this.h[5] = sum32$1(this.h[5], f);
8960 this.h[6] = sum32$1(this.h[6], g);
8961 this.h[7] = sum32$1(this.h[7], h);
8962};
8963
8964SHA256.prototype._digest = function digest(enc) {
8965 if (enc === 'hex')
8966 return utils.toHex32(this.h, 'big');
8967 else
8968 return utils.split32(this.h, 'big');
8969};
8970
8971function SHA224() {
8972 if (!(this instanceof SHA224))
8973 return new SHA224();
8974
8975 _256.call(this);
8976 this.h = [
8977 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
8978 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
8979}
8980utils.inherits(SHA224, _256);
8981var _224 = SHA224;
8982
8983SHA224.blockSize = 512;
8984SHA224.outSize = 224;
8985SHA224.hmacStrength = 192;
8986SHA224.padLength = 64;
8987
8988SHA224.prototype._digest = function digest(enc) {
8989 // Just truncate output
8990 if (enc === 'hex')
8991 return utils.toHex32(this.h.slice(0, 7), 'big');
8992 else
8993 return utils.split32(this.h.slice(0, 7), 'big');
8994};
8995
8996var rotr64_hi$1 = utils.rotr64_hi;
8997var rotr64_lo$1 = utils.rotr64_lo;
8998var shr64_hi$1 = utils.shr64_hi;
8999var shr64_lo$1 = utils.shr64_lo;
9000var sum64$1 = utils.sum64;
9001var sum64_hi$1 = utils.sum64_hi;
9002var sum64_lo$1 = utils.sum64_lo;
9003var sum64_4_hi$1 = utils.sum64_4_hi;
9004var sum64_4_lo$1 = utils.sum64_4_lo;
9005var sum64_5_hi$1 = utils.sum64_5_hi;
9006var sum64_5_lo$1 = utils.sum64_5_lo;
9007
9008var BlockHash$2 = common.BlockHash;
9009
9010var sha512_K = [
9011 0x428a2f98, 0xd728ae22, 0x71374491, 0x23ef65cd,
9012 0xb5c0fbcf, 0xec4d3b2f, 0xe9b5dba5, 0x8189dbbc,
9013 0x3956c25b, 0xf348b538, 0x59f111f1, 0xb605d019,
9014 0x923f82a4, 0xaf194f9b, 0xab1c5ed5, 0xda6d8118,
9015 0xd807aa98, 0xa3030242, 0x12835b01, 0x45706fbe,
9016 0x243185be, 0x4ee4b28c, 0x550c7dc3, 0xd5ffb4e2,
9017 0x72be5d74, 0xf27b896f, 0x80deb1fe, 0x3b1696b1,
9018 0x9bdc06a7, 0x25c71235, 0xc19bf174, 0xcf692694,
9019 0xe49b69c1, 0x9ef14ad2, 0xefbe4786, 0x384f25e3,
9020 0x0fc19dc6, 0x8b8cd5b5, 0x240ca1cc, 0x77ac9c65,
9021 0x2de92c6f, 0x592b0275, 0x4a7484aa, 0x6ea6e483,
9022 0x5cb0a9dc, 0xbd41fbd4, 0x76f988da, 0x831153b5,
9023 0x983e5152, 0xee66dfab, 0xa831c66d, 0x2db43210,
9024 0xb00327c8, 0x98fb213f, 0xbf597fc7, 0xbeef0ee4,
9025 0xc6e00bf3, 0x3da88fc2, 0xd5a79147, 0x930aa725,
9026 0x06ca6351, 0xe003826f, 0x14292967, 0x0a0e6e70,
9027 0x27b70a85, 0x46d22ffc, 0x2e1b2138, 0x5c26c926,
9028 0x4d2c6dfc, 0x5ac42aed, 0x53380d13, 0x9d95b3df,
9029 0x650a7354, 0x8baf63de, 0x766a0abb, 0x3c77b2a8,
9030 0x81c2c92e, 0x47edaee6, 0x92722c85, 0x1482353b,
9031 0xa2bfe8a1, 0x4cf10364, 0xa81a664b, 0xbc423001,
9032 0xc24b8b70, 0xd0f89791, 0xc76c51a3, 0x0654be30,
9033 0xd192e819, 0xd6ef5218, 0xd6990624, 0x5565a910,
9034 0xf40e3585, 0x5771202a, 0x106aa070, 0x32bbd1b8,
9035 0x19a4c116, 0xb8d2d0c8, 0x1e376c08, 0x5141ab53,
9036 0x2748774c, 0xdf8eeb99, 0x34b0bcb5, 0xe19b48a8,
9037 0x391c0cb3, 0xc5c95a63, 0x4ed8aa4a, 0xe3418acb,
9038 0x5b9cca4f, 0x7763e373, 0x682e6ff3, 0xd6b2b8a3,
9039 0x748f82ee, 0x5defb2fc, 0x78a5636f, 0x43172f60,
9040 0x84c87814, 0xa1f0ab72, 0x8cc70208, 0x1a6439ec,
9041 0x90befffa, 0x23631e28, 0xa4506ceb, 0xde82bde9,
9042 0xbef9a3f7, 0xb2c67915, 0xc67178f2, 0xe372532b,
9043 0xca273ece, 0xea26619c, 0xd186b8c7, 0x21c0c207,
9044 0xeada7dd6, 0xcde0eb1e, 0xf57d4f7f, 0xee6ed178,
9045 0x06f067aa, 0x72176fba, 0x0a637dc5, 0xa2c898a6,
9046 0x113f9804, 0xbef90dae, 0x1b710b35, 0x131c471b,
9047 0x28db77f5, 0x23047d84, 0x32caab7b, 0x40c72493,
9048 0x3c9ebe0a, 0x15c9bebc, 0x431d67c4, 0x9c100d4c,
9049 0x4cc5d4be, 0xcb3e42b6, 0x597f299c, 0xfc657e2a,
9050 0x5fcb6fab, 0x3ad6faec, 0x6c44198c, 0x4a475817
9051];
9052
9053function SHA512() {
9054 if (!(this instanceof SHA512))
9055 return new SHA512();
9056
9057 BlockHash$2.call(this);
9058 this.h = [
9059 0x6a09e667, 0xf3bcc908,
9060 0xbb67ae85, 0x84caa73b,
9061 0x3c6ef372, 0xfe94f82b,
9062 0xa54ff53a, 0x5f1d36f1,
9063 0x510e527f, 0xade682d1,
9064 0x9b05688c, 0x2b3e6c1f,
9065 0x1f83d9ab, 0xfb41bd6b,
9066 0x5be0cd19, 0x137e2179 ];
9067 this.k = sha512_K;
9068 this.W = new Array(160);
9069}
9070utils.inherits(SHA512, BlockHash$2);
9071var _512 = SHA512;
9072
9073SHA512.blockSize = 1024;
9074SHA512.outSize = 512;
9075SHA512.hmacStrength = 192;
9076SHA512.padLength = 128;
9077
9078SHA512.prototype._prepareBlock = function _prepareBlock(msg, start) {
9079 var W = this.W;
9080
9081 // 32 x 32bit words
9082 for (var i = 0; i < 32; i++)
9083 W[i] = msg[start + i];
9084 for (; i < W.length; i += 2) {
9085 var c0_hi = g1_512_hi(W[i - 4], W[i - 3]); // i - 2
9086 var c0_lo = g1_512_lo(W[i - 4], W[i - 3]);
9087 var c1_hi = W[i - 14]; // i - 7
9088 var c1_lo = W[i - 13];
9089 var c2_hi = g0_512_hi(W[i - 30], W[i - 29]); // i - 15
9090 var c2_lo = g0_512_lo(W[i - 30], W[i - 29]);
9091 var c3_hi = W[i - 32]; // i - 16
9092 var c3_lo = W[i - 31];
9093
9094 W[i] = sum64_4_hi$1(
9095 c0_hi, c0_lo,
9096 c1_hi, c1_lo,
9097 c2_hi, c2_lo,
9098 c3_hi, c3_lo);
9099 W[i + 1] = sum64_4_lo$1(
9100 c0_hi, c0_lo,
9101 c1_hi, c1_lo,
9102 c2_hi, c2_lo,
9103 c3_hi, c3_lo);
9104 }
9105};
9106
9107SHA512.prototype._update = function _update(msg, start) {
9108 this._prepareBlock(msg, start);
9109
9110 var W = this.W;
9111
9112 var ah = this.h[0];
9113 var al = this.h[1];
9114 var bh = this.h[2];
9115 var bl = this.h[3];
9116 var ch = this.h[4];
9117 var cl = this.h[5];
9118 var dh = this.h[6];
9119 var dl = this.h[7];
9120 var eh = this.h[8];
9121 var el = this.h[9];
9122 var fh = this.h[10];
9123 var fl = this.h[11];
9124 var gh = this.h[12];
9125 var gl = this.h[13];
9126 var hh = this.h[14];
9127 var hl = this.h[15];
9128
9129 minimalisticAssert(this.k.length === W.length);
9130 for (var i = 0; i < W.length; i += 2) {
9131 var c0_hi = hh;
9132 var c0_lo = hl;
9133 var c1_hi = s1_512_hi(eh, el);
9134 var c1_lo = s1_512_lo(eh, el);
9135 var c2_hi = ch64_hi(eh, el, fh, fl, gh);
9136 var c2_lo = ch64_lo(eh, el, fh, fl, gh, gl);
9137 var c3_hi = this.k[i];
9138 var c3_lo = this.k[i + 1];
9139 var c4_hi = W[i];
9140 var c4_lo = W[i + 1];
9141
9142 var T1_hi = sum64_5_hi$1(
9143 c0_hi, c0_lo,
9144 c1_hi, c1_lo,
9145 c2_hi, c2_lo,
9146 c3_hi, c3_lo,
9147 c4_hi, c4_lo);
9148 var T1_lo = sum64_5_lo$1(
9149 c0_hi, c0_lo,
9150 c1_hi, c1_lo,
9151 c2_hi, c2_lo,
9152 c3_hi, c3_lo,
9153 c4_hi, c4_lo);
9154
9155 c0_hi = s0_512_hi(ah, al);
9156 c0_lo = s0_512_lo(ah, al);
9157 c1_hi = maj64_hi(ah, al, bh, bl, ch);
9158 c1_lo = maj64_lo(ah, al, bh, bl, ch, cl);
9159
9160 var T2_hi = sum64_hi$1(c0_hi, c0_lo, c1_hi, c1_lo);
9161 var T2_lo = sum64_lo$1(c0_hi, c0_lo, c1_hi, c1_lo);
9162
9163 hh = gh;
9164 hl = gl;
9165
9166 gh = fh;
9167 gl = fl;
9168
9169 fh = eh;
9170 fl = el;
9171
9172 eh = sum64_hi$1(dh, dl, T1_hi, T1_lo);
9173 el = sum64_lo$1(dl, dl, T1_hi, T1_lo);
9174
9175 dh = ch;
9176 dl = cl;
9177
9178 ch = bh;
9179 cl = bl;
9180
9181 bh = ah;
9182 bl = al;
9183
9184 ah = sum64_hi$1(T1_hi, T1_lo, T2_hi, T2_lo);
9185 al = sum64_lo$1(T1_hi, T1_lo, T2_hi, T2_lo);
9186 }
9187
9188 sum64$1(this.h, 0, ah, al);
9189 sum64$1(this.h, 2, bh, bl);
9190 sum64$1(this.h, 4, ch, cl);
9191 sum64$1(this.h, 6, dh, dl);
9192 sum64$1(this.h, 8, eh, el);
9193 sum64$1(this.h, 10, fh, fl);
9194 sum64$1(this.h, 12, gh, gl);
9195 sum64$1(this.h, 14, hh, hl);
9196};
9197
9198SHA512.prototype._digest = function digest(enc) {
9199 if (enc === 'hex')
9200 return utils.toHex32(this.h, 'big');
9201 else
9202 return utils.split32(this.h, 'big');
9203};
9204
9205function ch64_hi(xh, xl, yh, yl, zh) {
9206 var r = (xh & yh) ^ ((~xh) & zh);
9207 if (r < 0)
9208 r += 0x100000000;
9209 return r;
9210}
9211
9212function ch64_lo(xh, xl, yh, yl, zh, zl) {
9213 var r = (xl & yl) ^ ((~xl) & zl);
9214 if (r < 0)
9215 r += 0x100000000;
9216 return r;
9217}
9218
9219function maj64_hi(xh, xl, yh, yl, zh) {
9220 var r = (xh & yh) ^ (xh & zh) ^ (yh & zh);
9221 if (r < 0)
9222 r += 0x100000000;
9223 return r;
9224}
9225
9226function maj64_lo(xh, xl, yh, yl, zh, zl) {
9227 var r = (xl & yl) ^ (xl & zl) ^ (yl & zl);
9228 if (r < 0)
9229 r += 0x100000000;
9230 return r;
9231}
9232
9233function s0_512_hi(xh, xl) {
9234 var c0_hi = rotr64_hi$1(xh, xl, 28);
9235 var c1_hi = rotr64_hi$1(xl, xh, 2); // 34
9236 var c2_hi = rotr64_hi$1(xl, xh, 7); // 39
9237
9238 var r = c0_hi ^ c1_hi ^ c2_hi;
9239 if (r < 0)
9240 r += 0x100000000;
9241 return r;
9242}
9243
9244function s0_512_lo(xh, xl) {
9245 var c0_lo = rotr64_lo$1(xh, xl, 28);
9246 var c1_lo = rotr64_lo$1(xl, xh, 2); // 34
9247 var c2_lo = rotr64_lo$1(xl, xh, 7); // 39
9248
9249 var r = c0_lo ^ c1_lo ^ c2_lo;
9250 if (r < 0)
9251 r += 0x100000000;
9252 return r;
9253}
9254
9255function s1_512_hi(xh, xl) {
9256 var c0_hi = rotr64_hi$1(xh, xl, 14);
9257 var c1_hi = rotr64_hi$1(xh, xl, 18);
9258 var c2_hi = rotr64_hi$1(xl, xh, 9); // 41
9259
9260 var r = c0_hi ^ c1_hi ^ c2_hi;
9261 if (r < 0)
9262 r += 0x100000000;
9263 return r;
9264}
9265
9266function s1_512_lo(xh, xl) {
9267 var c0_lo = rotr64_lo$1(xh, xl, 14);
9268 var c1_lo = rotr64_lo$1(xh, xl, 18);
9269 var c2_lo = rotr64_lo$1(xl, xh, 9); // 41
9270
9271 var r = c0_lo ^ c1_lo ^ c2_lo;
9272 if (r < 0)
9273 r += 0x100000000;
9274 return r;
9275}
9276
9277function g0_512_hi(xh, xl) {
9278 var c0_hi = rotr64_hi$1(xh, xl, 1);
9279 var c1_hi = rotr64_hi$1(xh, xl, 8);
9280 var c2_hi = shr64_hi$1(xh, xl, 7);
9281
9282 var r = c0_hi ^ c1_hi ^ c2_hi;
9283 if (r < 0)
9284 r += 0x100000000;
9285 return r;
9286}
9287
9288function g0_512_lo(xh, xl) {
9289 var c0_lo = rotr64_lo$1(xh, xl, 1);
9290 var c1_lo = rotr64_lo$1(xh, xl, 8);
9291 var c2_lo = shr64_lo$1(xh, xl, 7);
9292
9293 var r = c0_lo ^ c1_lo ^ c2_lo;
9294 if (r < 0)
9295 r += 0x100000000;
9296 return r;
9297}
9298
9299function g1_512_hi(xh, xl) {
9300 var c0_hi = rotr64_hi$1(xh, xl, 19);
9301 var c1_hi = rotr64_hi$1(xl, xh, 29); // 61
9302 var c2_hi = shr64_hi$1(xh, xl, 6);
9303
9304 var r = c0_hi ^ c1_hi ^ c2_hi;
9305 if (r < 0)
9306 r += 0x100000000;
9307 return r;
9308}
9309
9310function g1_512_lo(xh, xl) {
9311 var c0_lo = rotr64_lo$1(xh, xl, 19);
9312 var c1_lo = rotr64_lo$1(xl, xh, 29); // 61
9313 var c2_lo = shr64_lo$1(xh, xl, 6);
9314
9315 var r = c0_lo ^ c1_lo ^ c2_lo;
9316 if (r < 0)
9317 r += 0x100000000;
9318 return r;
9319}
9320
9321function SHA384() {
9322 if (!(this instanceof SHA384))
9323 return new SHA384();
9324
9325 _512.call(this);
9326 this.h = [
9327 0xcbbb9d5d, 0xc1059ed8,
9328 0x629a292a, 0x367cd507,
9329 0x9159015a, 0x3070dd17,
9330 0x152fecd8, 0xf70e5939,
9331 0x67332667, 0xffc00b31,
9332 0x8eb44a87, 0x68581511,
9333 0xdb0c2e0d, 0x64f98fa7,
9334 0x47b5481d, 0xbefa4fa4 ];
9335}
9336utils.inherits(SHA384, _512);
9337var _384 = SHA384;
9338
9339SHA384.blockSize = 1024;
9340SHA384.outSize = 384;
9341SHA384.hmacStrength = 192;
9342SHA384.padLength = 128;
9343
9344SHA384.prototype._digest = function digest(enc) {
9345 if (enc === 'hex')
9346 return utils.toHex32(this.h.slice(0, 12), 'big');
9347 else
9348 return utils.split32(this.h.slice(0, 12), 'big');
9349};
9350
9351var rotl32$1 = utils.rotl32;
9352var sum32$2 = utils.sum32;
9353var sum32_3$1 = utils.sum32_3;
9354var sum32_4$2 = utils.sum32_4;
9355var BlockHash$3 = common.BlockHash;
9356
9357function RIPEMD160() {
9358 if (!(this instanceof RIPEMD160))
9359 return new RIPEMD160();
9360
9361 BlockHash$3.call(this);
9362
9363 this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
9364 this.endian = 'little';
9365}
9366utils.inherits(RIPEMD160, BlockHash$3);
9367var ripemd160 = RIPEMD160;
9368
9369RIPEMD160.blockSize = 512;
9370RIPEMD160.outSize = 160;
9371RIPEMD160.hmacStrength = 192;
9372RIPEMD160.padLength = 64;
9373
9374RIPEMD160.prototype._update = function update(msg, start) {
9375 var A = this.h[0];
9376 var B = this.h[1];
9377 var C = this.h[2];
9378 var D = this.h[3];
9379 var E = this.h[4];
9380 var Ah = A;
9381 var Bh = B;
9382 var Ch = C;
9383 var Dh = D;
9384 var Eh = E;
9385 for (var j = 0; j < 80; j++) {
9386 var T = sum32$2(
9387 rotl32$1(
9388 sum32_4$2(A, f(j, B, C, D), msg[r[j] + start], K(j)),
9389 s[j]),
9390 E);
9391 A = E;
9392 E = D;
9393 D = rotl32$1(C, 10);
9394 C = B;
9395 B = T;
9396 T = sum32$2(
9397 rotl32$1(
9398 sum32_4$2(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j] + start], Kh(j)),
9399 sh[j]),
9400 Eh);
9401 Ah = Eh;
9402 Eh = Dh;
9403 Dh = rotl32$1(Ch, 10);
9404 Ch = Bh;
9405 Bh = T;
9406 }
9407 T = sum32_3$1(this.h[1], C, Dh);
9408 this.h[1] = sum32_3$1(this.h[2], D, Eh);
9409 this.h[2] = sum32_3$1(this.h[3], E, Ah);
9410 this.h[3] = sum32_3$1(this.h[4], A, Bh);
9411 this.h[4] = sum32_3$1(this.h[0], B, Ch);
9412 this.h[0] = T;
9413};
9414
9415RIPEMD160.prototype._digest = function digest(enc) {
9416 if (enc === 'hex')
9417 return utils.toHex32(this.h, 'little');
9418 else
9419 return utils.split32(this.h, 'little');
9420};
9421
9422function f(j, x, y, z) {
9423 if (j <= 15)
9424 return x ^ y ^ z;
9425 else if (j <= 31)
9426 return (x & y) | ((~x) & z);
9427 else if (j <= 47)
9428 return (x | (~y)) ^ z;
9429 else if (j <= 63)
9430 return (x & z) | (y & (~z));
9431 else
9432 return x ^ (y | (~z));
9433}
9434
9435function K(j) {
9436 if (j <= 15)
9437 return 0x00000000;
9438 else if (j <= 31)
9439 return 0x5a827999;
9440 else if (j <= 47)
9441 return 0x6ed9eba1;
9442 else if (j <= 63)
9443 return 0x8f1bbcdc;
9444 else
9445 return 0xa953fd4e;
9446}
9447
9448function Kh(j) {
9449 if (j <= 15)
9450 return 0x50a28be6;
9451 else if (j <= 31)
9452 return 0x5c4dd124;
9453 else if (j <= 47)
9454 return 0x6d703ef3;
9455 else if (j <= 63)
9456 return 0x7a6d76e9;
9457 else
9458 return 0x00000000;
9459}
9460
9461var r = [
9462 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
9463 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
9464 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
9465 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
9466 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
9467];
9468
9469var rh = [
9470 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
9471 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
9472 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
9473 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
9474 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
9475];
9476
9477var s = [
9478 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
9479 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
9480 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
9481 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9482 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
9483];
9484
9485var sh = [
9486 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9487 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9488 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
9489 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
9490 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
9491];
9492
9493var ripemd = {
9494 ripemd160: ripemd160
9495};
9496
9497/**
9498 * A fast MD5 JavaScript implementation
9499 * Copyright (c) 2012 Joseph Myers
9500 * http://www.myersdaily.org/joseph/javascript/md5-text.html
9501 *
9502 * Permission to use, copy, modify, and distribute this software
9503 * and its documentation for any purposes and without
9504 * fee is hereby granted provided that this copyright notice
9505 * appears in all copies.
9506 *
9507 * Of course, this soft is provided "as is" without express or implied
9508 * warranty of any kind.
9509 */
9510
9511// MD5 Digest
9512async function md5(entree) {
9513 const digest = md51(util.uint8ArrayToString(entree));
9514 return util.hexToUint8Array(hex(digest));
9515}
9516
9517function md5cycle(x, k) {
9518 let a = x[0];
9519 let b = x[1];
9520 let c = x[2];
9521 let d = x[3];
9522
9523 a = ff(a, b, c, d, k[0], 7, -680876936);
9524 d = ff(d, a, b, c, k[1], 12, -389564586);
9525 c = ff(c, d, a, b, k[2], 17, 606105819);
9526 b = ff(b, c, d, a, k[3], 22, -1044525330);
9527 a = ff(a, b, c, d, k[4], 7, -176418897);
9528 d = ff(d, a, b, c, k[5], 12, 1200080426);
9529 c = ff(c, d, a, b, k[6], 17, -1473231341);
9530 b = ff(b, c, d, a, k[7], 22, -45705983);
9531 a = ff(a, b, c, d, k[8], 7, 1770035416);
9532 d = ff(d, a, b, c, k[9], 12, -1958414417);
9533 c = ff(c, d, a, b, k[10], 17, -42063);
9534 b = ff(b, c, d, a, k[11], 22, -1990404162);
9535 a = ff(a, b, c, d, k[12], 7, 1804603682);
9536 d = ff(d, a, b, c, k[13], 12, -40341101);
9537 c = ff(c, d, a, b, k[14], 17, -1502002290);
9538 b = ff(b, c, d, a, k[15], 22, 1236535329);
9539
9540 a = gg(a, b, c, d, k[1], 5, -165796510);
9541 d = gg(d, a, b, c, k[6], 9, -1069501632);
9542 c = gg(c, d, a, b, k[11], 14, 643717713);
9543 b = gg(b, c, d, a, k[0], 20, -373897302);
9544 a = gg(a, b, c, d, k[5], 5, -701558691);
9545 d = gg(d, a, b, c, k[10], 9, 38016083);
9546 c = gg(c, d, a, b, k[15], 14, -660478335);
9547 b = gg(b, c, d, a, k[4], 20, -405537848);
9548 a = gg(a, b, c, d, k[9], 5, 568446438);
9549 d = gg(d, a, b, c, k[14], 9, -1019803690);
9550 c = gg(c, d, a, b, k[3], 14, -187363961);
9551 b = gg(b, c, d, a, k[8], 20, 1163531501);
9552 a = gg(a, b, c, d, k[13], 5, -1444681467);
9553 d = gg(d, a, b, c, k[2], 9, -51403784);
9554 c = gg(c, d, a, b, k[7], 14, 1735328473);
9555 b = gg(b, c, d, a, k[12], 20, -1926607734);
9556
9557 a = hh(a, b, c, d, k[5], 4, -378558);
9558 d = hh(d, a, b, c, k[8], 11, -2022574463);
9559 c = hh(c, d, a, b, k[11], 16, 1839030562);
9560 b = hh(b, c, d, a, k[14], 23, -35309556);
9561 a = hh(a, b, c, d, k[1], 4, -1530992060);
9562 d = hh(d, a, b, c, k[4], 11, 1272893353);
9563 c = hh(c, d, a, b, k[7], 16, -155497632);
9564 b = hh(b, c, d, a, k[10], 23, -1094730640);
9565 a = hh(a, b, c, d, k[13], 4, 681279174);
9566 d = hh(d, a, b, c, k[0], 11, -358537222);
9567 c = hh(c, d, a, b, k[3], 16, -722521979);
9568 b = hh(b, c, d, a, k[6], 23, 76029189);
9569 a = hh(a, b, c, d, k[9], 4, -640364487);
9570 d = hh(d, a, b, c, k[12], 11, -421815835);
9571 c = hh(c, d, a, b, k[15], 16, 530742520);
9572 b = hh(b, c, d, a, k[2], 23, -995338651);
9573
9574 a = ii(a, b, c, d, k[0], 6, -198630844);
9575 d = ii(d, a, b, c, k[7], 10, 1126891415);
9576 c = ii(c, d, a, b, k[14], 15, -1416354905);
9577 b = ii(b, c, d, a, k[5], 21, -57434055);
9578 a = ii(a, b, c, d, k[12], 6, 1700485571);
9579 d = ii(d, a, b, c, k[3], 10, -1894986606);
9580 c = ii(c, d, a, b, k[10], 15, -1051523);
9581 b = ii(b, c, d, a, k[1], 21, -2054922799);
9582 a = ii(a, b, c, d, k[8], 6, 1873313359);
9583 d = ii(d, a, b, c, k[15], 10, -30611744);
9584 c = ii(c, d, a, b, k[6], 15, -1560198380);
9585 b = ii(b, c, d, a, k[13], 21, 1309151649);
9586 a = ii(a, b, c, d, k[4], 6, -145523070);
9587 d = ii(d, a, b, c, k[11], 10, -1120210379);
9588 c = ii(c, d, a, b, k[2], 15, 718787259);
9589 b = ii(b, c, d, a, k[9], 21, -343485551);
9590
9591 x[0] = add32(a, x[0]);
9592 x[1] = add32(b, x[1]);
9593 x[2] = add32(c, x[2]);
9594 x[3] = add32(d, x[3]);
9595}
9596
9597function cmn(q, a, b, x, s, t) {
9598 a = add32(add32(a, q), add32(x, t));
9599 return add32((a << s) | (a >>> (32 - s)), b);
9600}
9601
9602function ff(a, b, c, d, x, s, t) {
9603 return cmn((b & c) | ((~b) & d), a, b, x, s, t);
9604}
9605
9606function gg(a, b, c, d, x, s, t) {
9607 return cmn((b & d) | (c & (~d)), a, b, x, s, t);
9608}
9609
9610function hh(a, b, c, d, x, s, t) {
9611 return cmn(b ^ c ^ d, a, b, x, s, t);
9612}
9613
9614function ii(a, b, c, d, x, s, t) {
9615 return cmn(c ^ (b | (~d)), a, b, x, s, t);
9616}
9617
9618function md51(s) {
9619 const n = s.length;
9620 const state = [1732584193, -271733879, -1732584194, 271733878];
9621 let i;
9622 for (i = 64; i <= s.length; i += 64) {
9623 md5cycle(state, md5blk(s.substring(i - 64, i)));
9624 }
9625 s = s.substring(i - 64);
9626 const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
9627 for (i = 0; i < s.length; i++) {
9628 tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
9629 }
9630 tail[i >> 2] |= 0x80 << ((i % 4) << 3);
9631 if (i > 55) {
9632 md5cycle(state, tail);
9633 for (i = 0; i < 16; i++) {
9634 tail[i] = 0;
9635 }
9636 }
9637 tail[14] = n * 8;
9638 md5cycle(state, tail);
9639 return state;
9640}
9641
9642/* there needs to be support for Unicode here,
9643 * unless we pretend that we can redefine the MD-5
9644 * algorithm for multi-byte characters (perhaps
9645 * by adding every four 16-bit characters and
9646 * shortening the sum to 32 bits). Otherwise
9647 * I suggest performing MD-5 as if every character
9648 * was two bytes--e.g., 0040 0025 = @%--but then
9649 * how will an ordinary MD-5 sum be matched?
9650 * There is no way to standardize text to something
9651 * like UTF-8 before transformation; speed cost is
9652 * utterly prohibitive. The JavaScript standard
9653 * itself needs to look at this: it should start
9654 * providing access to strings as preformed UTF-8
9655 * 8-bit unsigned value arrays.
9656 */
9657function md5blk(s) { /* I figured global was faster. */
9658 const md5blks = [];
9659 let i; /* Andy King said do it this way. */
9660 for (i = 0; i < 64; i += 4) {
9661 md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) <<
9662 24);
9663 }
9664 return md5blks;
9665}
9666
9667const hex_chr = '0123456789abcdef'.split('');
9668
9669function rhex(n) {
9670 let s = '';
9671 let j = 0;
9672 for (; j < 4; j++) {
9673 s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] + hex_chr[(n >> (j * 8)) & 0x0F];
9674 }
9675 return s;
9676}
9677
9678function hex(x) {
9679 for (let i = 0; i < x.length; i++) {
9680 x[i] = rhex(x[i]);
9681 }
9682 return x.join('');
9683}
9684
9685/* this function is much faster,
9686so if possible we use it. Some IEs
9687are the only ones I know of that
9688need the idiotic second function,
9689generated by an if clause. */
9690
9691function add32(a, b) {
9692 return (a + b) & 0xFFFFFFFF;
9693}
9694
9695/**
9696 * @fileoverview Provides an interface to hashing functions available in Node.js or external libraries.
9697 * @see {@link https://github.com/asmcrypto/asmcrypto.js|asmCrypto}
9698 * @see {@link https://github.com/indutny/hash.js|hash.js}
9699 * @module crypto/hash
9700 * @private
9701 */
9702
9703const webCrypto = util.getWebCrypto();
9704const nodeCrypto = util.getNodeCrypto();
9705const nodeCryptoHashes = nodeCrypto && nodeCrypto.getHashes();
9706
9707function nodeHash(type) {
9708 if (!nodeCrypto || !nodeCryptoHashes.includes(type)) {
9709 return;
9710 }
9711 return async function (data) {
9712 const shasum = nodeCrypto.createHash(type);
9713 return transform(data, value => {
9714 shasum.update(value);
9715 }, () => new Uint8Array(shasum.digest()));
9716 };
9717}
9718
9719function hashjsHash(hash, webCryptoHash) {
9720 return async function(data, config = defaultConfig) {
9721 if (isArrayStream(data)) {
9722 data = await readToEnd(data);
9723 }
9724 if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
9725 return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
9726 }
9727 const hashInstance = hash();
9728 return transform(data, value => {
9729 hashInstance.update(value);
9730 }, () => new Uint8Array(hashInstance.digest()));
9731 };
9732}
9733
9734function asmcryptoHash(hash, webCryptoHash) {
9735 return async function(data, config = defaultConfig) {
9736 if (isArrayStream(data)) {
9737 data = await readToEnd(data);
9738 }
9739 if (util.isStream(data)) {
9740 const hashInstance = new hash();
9741 return transform(data, value => {
9742 hashInstance.process(value);
9743 }, () => hashInstance.finish().result);
9744 } else if (webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) {
9745 return new Uint8Array(await webCrypto.digest(webCryptoHash, data));
9746 } else {
9747 return hash.bytes(data);
9748 }
9749 };
9750}
9751
9752const hashFunctions = {
9753 md5: nodeHash('md5') || md5,
9754 sha1: nodeHash('sha1') || asmcryptoHash(Sha1, 'SHA-1'),
9755 sha224: nodeHash('sha224') || hashjsHash(_224),
9756 sha256: nodeHash('sha256') || asmcryptoHash(Sha256, 'SHA-256'),
9757 sha384: nodeHash('sha384') || hashjsHash(_384, 'SHA-384'),
9758 sha512: nodeHash('sha512') || hashjsHash(_512, 'SHA-512'), // asmcrypto sha512 is huge.
9759 ripemd: nodeHash('ripemd160') || hashjsHash(ripemd160)
9760};
9761
9762var hash = {
9763
9764 /** @see module:md5 */
9765 md5: hashFunctions.md5,
9766 /** @see asmCrypto */
9767 sha1: hashFunctions.sha1,
9768 /** @see hash.js */
9769 sha224: hashFunctions.sha224,
9770 /** @see asmCrypto */
9771 sha256: hashFunctions.sha256,
9772 /** @see hash.js */
9773 sha384: hashFunctions.sha384,
9774 /** @see asmCrypto */
9775 sha512: hashFunctions.sha512,
9776 /** @see hash.js */
9777 ripemd: hashFunctions.ripemd,
9778
9779 /**
9780 * Create a hash on the specified data using the specified algorithm
9781 * @param {module:enums.hash} algo - Hash algorithm type (see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
9782 * @param {Uint8Array} data - Data to be hashed
9783 * @returns {Promise<Uint8Array>} Hash value.
9784 */
9785 digest: function(algo, data) {
9786 switch (algo) {
9787 case enums.hash.md5:
9788 return this.md5(data);
9789 case enums.hash.sha1:
9790 return this.sha1(data);
9791 case enums.hash.ripemd:
9792 return this.ripemd(data);
9793 case enums.hash.sha256:
9794 return this.sha256(data);
9795 case enums.hash.sha384:
9796 return this.sha384(data);
9797 case enums.hash.sha512:
9798 return this.sha512(data);
9799 case enums.hash.sha224:
9800 return this.sha224(data);
9801 default:
9802 throw new Error('Invalid hash function.');
9803 }
9804 },
9805
9806 /**
9807 * Returns the hash size in bytes of the specified hash algorithm type
9808 * @param {module:enums.hash} algo - Hash algorithm type (See {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4})
9809 * @returns {Integer} Size in bytes of the resulting hash.
9810 */
9811 getHashByteLength: function(algo) {
9812 switch (algo) {
9813 case enums.hash.md5:
9814 return 16;
9815 case enums.hash.sha1:
9816 case enums.hash.ripemd:
9817 return 20;
9818 case enums.hash.sha256:
9819 return 32;
9820 case enums.hash.sha384:
9821 return 48;
9822 case enums.hash.sha512:
9823 return 64;
9824 case enums.hash.sha224:
9825 return 28;
9826 default:
9827 throw new Error('Invalid hash algorithm.');
9828 }
9829 }
9830};
9831
9832class AES_CFB {
9833 static encrypt(data, key, iv) {
9834 return new AES_CFB(key, iv).encrypt(data);
9835 }
9836 static decrypt(data, key, iv) {
9837 return new AES_CFB(key, iv).decrypt(data);
9838 }
9839 constructor(key, iv, aes) {
9840 this.aes = aes ? aes : new AES(key, iv, true, 'CFB');
9841 delete this.aes.padding;
9842 }
9843 encrypt(data) {
9844 const r1 = this.aes.AES_Encrypt_process(data);
9845 const r2 = this.aes.AES_Encrypt_finish();
9846 return joinBytes(r1, r2);
9847 }
9848 decrypt(data) {
9849 const r1 = this.aes.AES_Decrypt_process(data);
9850 const r2 = this.aes.AES_Decrypt_finish();
9851 return joinBytes(r1, r2);
9852 }
9853}
9854
9855var naclFastLight = createCommonjsModule(function (module) {
9856/*jshint bitwise: false*/
9857
9858(function(nacl) {
9859
9860// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
9861// Public domain.
9862//
9863// Implementation derived from TweetNaCl version 20140427.
9864// See for details: http://tweetnacl.cr.yp.to/
9865
9866var gf = function(init) {
9867 var i, r = new Float64Array(16);
9868 if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
9869 return r;
9870};
9871
9872// Pluggable, initialized in high-level API below.
9873var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
9874
9875var _9 = new Uint8Array(32); _9[0] = 9;
9876
9877var gf0 = gf(),
9878 gf1 = gf([1]),
9879 _121665 = gf([0xdb41, 1]),
9880 D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
9881 D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
9882 X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
9883 Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
9884 I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
9885
9886function vn(x, xi, y, yi, n) {
9887 var i,d = 0;
9888 for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
9889 return (1 & ((d - 1) >>> 8)) - 1;
9890}
9891
9892function crypto_verify_32(x, xi, y, yi) {
9893 return vn(x,xi,y,yi,32);
9894}
9895
9896function set25519(r, a) {
9897 var i;
9898 for (i = 0; i < 16; i++) r[i] = a[i]|0;
9899}
9900
9901function car25519(o) {
9902 var i, v, c = 1;
9903 for (i = 0; i < 16; i++) {
9904 v = o[i] + c + 65535;
9905 c = Math.floor(v / 65536);
9906 o[i] = v - c * 65536;
9907 }
9908 o[0] += c-1 + 37 * (c-1);
9909}
9910
9911function sel25519(p, q, b) {
9912 var t, c = ~(b-1);
9913 for (var i = 0; i < 16; i++) {
9914 t = c & (p[i] ^ q[i]);
9915 p[i] ^= t;
9916 q[i] ^= t;
9917 }
9918}
9919
9920function pack25519(o, n) {
9921 var i, j, b;
9922 var m = gf(), t = gf();
9923 for (i = 0; i < 16; i++) t[i] = n[i];
9924 car25519(t);
9925 car25519(t);
9926 car25519(t);
9927 for (j = 0; j < 2; j++) {
9928 m[0] = t[0] - 0xffed;
9929 for (i = 1; i < 15; i++) {
9930 m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
9931 m[i-1] &= 0xffff;
9932 }
9933 m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
9934 b = (m[15]>>16) & 1;
9935 m[14] &= 0xffff;
9936 sel25519(t, m, 1-b);
9937 }
9938 for (i = 0; i < 16; i++) {
9939 o[2*i] = t[i] & 0xff;
9940 o[2*i+1] = t[i]>>8;
9941 }
9942}
9943
9944function neq25519(a, b) {
9945 var c = new Uint8Array(32), d = new Uint8Array(32);
9946 pack25519(c, a);
9947 pack25519(d, b);
9948 return crypto_verify_32(c, 0, d, 0);
9949}
9950
9951function par25519(a) {
9952 var d = new Uint8Array(32);
9953 pack25519(d, a);
9954 return d[0] & 1;
9955}
9956
9957function unpack25519(o, n) {
9958 var i;
9959 for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
9960 o[15] &= 0x7fff;
9961}
9962
9963function A(o, a, b) {
9964 for (var i = 0; i < 16; i++) o[i] = a[i] + b[i];
9965}
9966
9967function Z(o, a, b) {
9968 for (var i = 0; i < 16; i++) o[i] = a[i] - b[i];
9969}
9970
9971function M(o, a, b) {
9972 var v, c,
9973 t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0, t5 = 0, t6 = 0, t7 = 0,
9974 t8 = 0, t9 = 0, t10 = 0, t11 = 0, t12 = 0, t13 = 0, t14 = 0, t15 = 0,
9975 t16 = 0, t17 = 0, t18 = 0, t19 = 0, t20 = 0, t21 = 0, t22 = 0, t23 = 0,
9976 t24 = 0, t25 = 0, t26 = 0, t27 = 0, t28 = 0, t29 = 0, t30 = 0,
9977 b0 = b[0],
9978 b1 = b[1],
9979 b2 = b[2],
9980 b3 = b[3],
9981 b4 = b[4],
9982 b5 = b[5],
9983 b6 = b[6],
9984 b7 = b[7],
9985 b8 = b[8],
9986 b9 = b[9],
9987 b10 = b[10],
9988 b11 = b[11],
9989 b12 = b[12],
9990 b13 = b[13],
9991 b14 = b[14],
9992 b15 = b[15];
9993
9994 v = a[0];
9995 t0 += v * b0;
9996 t1 += v * b1;
9997 t2 += v * b2;
9998 t3 += v * b3;
9999 t4 += v * b4;
10000 t5 += v * b5;
10001 t6 += v * b6;
10002 t7 += v * b7;
10003 t8 += v * b8;
10004 t9 += v * b9;
10005 t10 += v * b10;
10006 t11 += v * b11;
10007 t12 += v * b12;
10008 t13 += v * b13;
10009 t14 += v * b14;
10010 t15 += v * b15;
10011 v = a[1];
10012 t1 += v * b0;
10013 t2 += v * b1;
10014 t3 += v * b2;
10015 t4 += v * b3;
10016 t5 += v * b4;
10017 t6 += v * b5;
10018 t7 += v * b6;
10019 t8 += v * b7;
10020 t9 += v * b8;
10021 t10 += v * b9;
10022 t11 += v * b10;
10023 t12 += v * b11;
10024 t13 += v * b12;
10025 t14 += v * b13;
10026 t15 += v * b14;
10027 t16 += v * b15;
10028 v = a[2];
10029 t2 += v * b0;
10030 t3 += v * b1;
10031 t4 += v * b2;
10032 t5 += v * b3;
10033 t6 += v * b4;
10034 t7 += v * b5;
10035 t8 += v * b6;
10036 t9 += v * b7;
10037 t10 += v * b8;
10038 t11 += v * b9;
10039 t12 += v * b10;
10040 t13 += v * b11;
10041 t14 += v * b12;
10042 t15 += v * b13;
10043 t16 += v * b14;
10044 t17 += v * b15;
10045 v = a[3];
10046 t3 += v * b0;
10047 t4 += v * b1;
10048 t5 += v * b2;
10049 t6 += v * b3;
10050 t7 += v * b4;
10051 t8 += v * b5;
10052 t9 += v * b6;
10053 t10 += v * b7;
10054 t11 += v * b8;
10055 t12 += v * b9;
10056 t13 += v * b10;
10057 t14 += v * b11;
10058 t15 += v * b12;
10059 t16 += v * b13;
10060 t17 += v * b14;
10061 t18 += v * b15;
10062 v = a[4];
10063 t4 += v * b0;
10064 t5 += v * b1;
10065 t6 += v * b2;
10066 t7 += v * b3;
10067 t8 += v * b4;
10068 t9 += v * b5;
10069 t10 += v * b6;
10070 t11 += v * b7;
10071 t12 += v * b8;
10072 t13 += v * b9;
10073 t14 += v * b10;
10074 t15 += v * b11;
10075 t16 += v * b12;
10076 t17 += v * b13;
10077 t18 += v * b14;
10078 t19 += v * b15;
10079 v = a[5];
10080 t5 += v * b0;
10081 t6 += v * b1;
10082 t7 += v * b2;
10083 t8 += v * b3;
10084 t9 += v * b4;
10085 t10 += v * b5;
10086 t11 += v * b6;
10087 t12 += v * b7;
10088 t13 += v * b8;
10089 t14 += v * b9;
10090 t15 += v * b10;
10091 t16 += v * b11;
10092 t17 += v * b12;
10093 t18 += v * b13;
10094 t19 += v * b14;
10095 t20 += v * b15;
10096 v = a[6];
10097 t6 += v * b0;
10098 t7 += v * b1;
10099 t8 += v * b2;
10100 t9 += v * b3;
10101 t10 += v * b4;
10102 t11 += v * b5;
10103 t12 += v * b6;
10104 t13 += v * b7;
10105 t14 += v * b8;
10106 t15 += v * b9;
10107 t16 += v * b10;
10108 t17 += v * b11;
10109 t18 += v * b12;
10110 t19 += v * b13;
10111 t20 += v * b14;
10112 t21 += v * b15;
10113 v = a[7];
10114 t7 += v * b0;
10115 t8 += v * b1;
10116 t9 += v * b2;
10117 t10 += v * b3;
10118 t11 += v * b4;
10119 t12 += v * b5;
10120 t13 += v * b6;
10121 t14 += v * b7;
10122 t15 += v * b8;
10123 t16 += v * b9;
10124 t17 += v * b10;
10125 t18 += v * b11;
10126 t19 += v * b12;
10127 t20 += v * b13;
10128 t21 += v * b14;
10129 t22 += v * b15;
10130 v = a[8];
10131 t8 += v * b0;
10132 t9 += v * b1;
10133 t10 += v * b2;
10134 t11 += v * b3;
10135 t12 += v * b4;
10136 t13 += v * b5;
10137 t14 += v * b6;
10138 t15 += v * b7;
10139 t16 += v * b8;
10140 t17 += v * b9;
10141 t18 += v * b10;
10142 t19 += v * b11;
10143 t20 += v * b12;
10144 t21 += v * b13;
10145 t22 += v * b14;
10146 t23 += v * b15;
10147 v = a[9];
10148 t9 += v * b0;
10149 t10 += v * b1;
10150 t11 += v * b2;
10151 t12 += v * b3;
10152 t13 += v * b4;
10153 t14 += v * b5;
10154 t15 += v * b6;
10155 t16 += v * b7;
10156 t17 += v * b8;
10157 t18 += v * b9;
10158 t19 += v * b10;
10159 t20 += v * b11;
10160 t21 += v * b12;
10161 t22 += v * b13;
10162 t23 += v * b14;
10163 t24 += v * b15;
10164 v = a[10];
10165 t10 += v * b0;
10166 t11 += v * b1;
10167 t12 += v * b2;
10168 t13 += v * b3;
10169 t14 += v * b4;
10170 t15 += v * b5;
10171 t16 += v * b6;
10172 t17 += v * b7;
10173 t18 += v * b8;
10174 t19 += v * b9;
10175 t20 += v * b10;
10176 t21 += v * b11;
10177 t22 += v * b12;
10178 t23 += v * b13;
10179 t24 += v * b14;
10180 t25 += v * b15;
10181 v = a[11];
10182 t11 += v * b0;
10183 t12 += v * b1;
10184 t13 += v * b2;
10185 t14 += v * b3;
10186 t15 += v * b4;
10187 t16 += v * b5;
10188 t17 += v * b6;
10189 t18 += v * b7;
10190 t19 += v * b8;
10191 t20 += v * b9;
10192 t21 += v * b10;
10193 t22 += v * b11;
10194 t23 += v * b12;
10195 t24 += v * b13;
10196 t25 += v * b14;
10197 t26 += v * b15;
10198 v = a[12];
10199 t12 += v * b0;
10200 t13 += v * b1;
10201 t14 += v * b2;
10202 t15 += v * b3;
10203 t16 += v * b4;
10204 t17 += v * b5;
10205 t18 += v * b6;
10206 t19 += v * b7;
10207 t20 += v * b8;
10208 t21 += v * b9;
10209 t22 += v * b10;
10210 t23 += v * b11;
10211 t24 += v * b12;
10212 t25 += v * b13;
10213 t26 += v * b14;
10214 t27 += v * b15;
10215 v = a[13];
10216 t13 += v * b0;
10217 t14 += v * b1;
10218 t15 += v * b2;
10219 t16 += v * b3;
10220 t17 += v * b4;
10221 t18 += v * b5;
10222 t19 += v * b6;
10223 t20 += v * b7;
10224 t21 += v * b8;
10225 t22 += v * b9;
10226 t23 += v * b10;
10227 t24 += v * b11;
10228 t25 += v * b12;
10229 t26 += v * b13;
10230 t27 += v * b14;
10231 t28 += v * b15;
10232 v = a[14];
10233 t14 += v * b0;
10234 t15 += v * b1;
10235 t16 += v * b2;
10236 t17 += v * b3;
10237 t18 += v * b4;
10238 t19 += v * b5;
10239 t20 += v * b6;
10240 t21 += v * b7;
10241 t22 += v * b8;
10242 t23 += v * b9;
10243 t24 += v * b10;
10244 t25 += v * b11;
10245 t26 += v * b12;
10246 t27 += v * b13;
10247 t28 += v * b14;
10248 t29 += v * b15;
10249 v = a[15];
10250 t15 += v * b0;
10251 t16 += v * b1;
10252 t17 += v * b2;
10253 t18 += v * b3;
10254 t19 += v * b4;
10255 t20 += v * b5;
10256 t21 += v * b6;
10257 t22 += v * b7;
10258 t23 += v * b8;
10259 t24 += v * b9;
10260 t25 += v * b10;
10261 t26 += v * b11;
10262 t27 += v * b12;
10263 t28 += v * b13;
10264 t29 += v * b14;
10265 t30 += v * b15;
10266
10267 t0 += 38 * t16;
10268 t1 += 38 * t17;
10269 t2 += 38 * t18;
10270 t3 += 38 * t19;
10271 t4 += 38 * t20;
10272 t5 += 38 * t21;
10273 t6 += 38 * t22;
10274 t7 += 38 * t23;
10275 t8 += 38 * t24;
10276 t9 += 38 * t25;
10277 t10 += 38 * t26;
10278 t11 += 38 * t27;
10279 t12 += 38 * t28;
10280 t13 += 38 * t29;
10281 t14 += 38 * t30;
10282 // t15 left as is
10283
10284 // first car
10285 c = 1;
10286 v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
10287 v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
10288 v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
10289 v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
10290 v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
10291 v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
10292 v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
10293 v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
10294 v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
10295 v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
10296 v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
10297 v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
10298 v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
10299 v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
10300 v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
10301 v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
10302 t0 += c-1 + 37 * (c-1);
10303
10304 // second car
10305 c = 1;
10306 v = t0 + c + 65535; c = Math.floor(v / 65536); t0 = v - c * 65536;
10307 v = t1 + c + 65535; c = Math.floor(v / 65536); t1 = v - c * 65536;
10308 v = t2 + c + 65535; c = Math.floor(v / 65536); t2 = v - c * 65536;
10309 v = t3 + c + 65535; c = Math.floor(v / 65536); t3 = v - c * 65536;
10310 v = t4 + c + 65535; c = Math.floor(v / 65536); t4 = v - c * 65536;
10311 v = t5 + c + 65535; c = Math.floor(v / 65536); t5 = v - c * 65536;
10312 v = t6 + c + 65535; c = Math.floor(v / 65536); t6 = v - c * 65536;
10313 v = t7 + c + 65535; c = Math.floor(v / 65536); t7 = v - c * 65536;
10314 v = t8 + c + 65535; c = Math.floor(v / 65536); t8 = v - c * 65536;
10315 v = t9 + c + 65535; c = Math.floor(v / 65536); t9 = v - c * 65536;
10316 v = t10 + c + 65535; c = Math.floor(v / 65536); t10 = v - c * 65536;
10317 v = t11 + c + 65535; c = Math.floor(v / 65536); t11 = v - c * 65536;
10318 v = t12 + c + 65535; c = Math.floor(v / 65536); t12 = v - c * 65536;
10319 v = t13 + c + 65535; c = Math.floor(v / 65536); t13 = v - c * 65536;
10320 v = t14 + c + 65535; c = Math.floor(v / 65536); t14 = v - c * 65536;
10321 v = t15 + c + 65535; c = Math.floor(v / 65536); t15 = v - c * 65536;
10322 t0 += c-1 + 37 * (c-1);
10323
10324 o[ 0] = t0;
10325 o[ 1] = t1;
10326 o[ 2] = t2;
10327 o[ 3] = t3;
10328 o[ 4] = t4;
10329 o[ 5] = t5;
10330 o[ 6] = t6;
10331 o[ 7] = t7;
10332 o[ 8] = t8;
10333 o[ 9] = t9;
10334 o[10] = t10;
10335 o[11] = t11;
10336 o[12] = t12;
10337 o[13] = t13;
10338 o[14] = t14;
10339 o[15] = t15;
10340}
10341
10342function S(o, a) {
10343 M(o, a, a);
10344}
10345
10346function inv25519(o, i) {
10347 var c = gf();
10348 var a;
10349 for (a = 0; a < 16; a++) c[a] = i[a];
10350 for (a = 253; a >= 0; a--) {
10351 S(c, c);
10352 if(a !== 2 && a !== 4) M(c, c, i);
10353 }
10354 for (a = 0; a < 16; a++) o[a] = c[a];
10355}
10356
10357function pow2523(o, i) {
10358 var c = gf();
10359 var a;
10360 for (a = 0; a < 16; a++) c[a] = i[a];
10361 for (a = 250; a >= 0; a--) {
10362 S(c, c);
10363 if(a !== 1) M(c, c, i);
10364 }
10365 for (a = 0; a < 16; a++) o[a] = c[a];
10366}
10367
10368function crypto_scalarmult(q, n, p) {
10369 var z = new Uint8Array(32);
10370 var x = new Float64Array(80), r, i;
10371 var a = gf(), b = gf(), c = gf(),
10372 d = gf(), e = gf(), f = gf();
10373 for (i = 0; i < 31; i++) z[i] = n[i];
10374 z[31]=(n[31]&127)|64;
10375 z[0]&=248;
10376 unpack25519(x,p);
10377 for (i = 0; i < 16; i++) {
10378 b[i]=x[i];
10379 d[i]=a[i]=c[i]=0;
10380 }
10381 a[0]=d[0]=1;
10382 for (i=254; i>=0; --i) {
10383 r=(z[i>>>3]>>>(i&7))&1;
10384 sel25519(a,b,r);
10385 sel25519(c,d,r);
10386 A(e,a,c);
10387 Z(a,a,c);
10388 A(c,b,d);
10389 Z(b,b,d);
10390 S(d,e);
10391 S(f,a);
10392 M(a,c,a);
10393 M(c,b,e);
10394 A(e,a,c);
10395 Z(a,a,c);
10396 S(b,a);
10397 Z(c,d,f);
10398 M(a,c,_121665);
10399 A(a,a,d);
10400 M(c,c,a);
10401 M(a,d,f);
10402 M(d,b,x);
10403 S(b,e);
10404 sel25519(a,b,r);
10405 sel25519(c,d,r);
10406 }
10407 for (i = 0; i < 16; i++) {
10408 x[i+16]=a[i];
10409 x[i+32]=c[i];
10410 x[i+48]=b[i];
10411 x[i+64]=d[i];
10412 }
10413 var x32 = x.subarray(32);
10414 var x16 = x.subarray(16);
10415 inv25519(x32,x32);
10416 M(x16,x16,x32);
10417 pack25519(q,x16);
10418 return 0;
10419}
10420
10421function crypto_scalarmult_base(q, n) {
10422 return crypto_scalarmult(q, n, _9);
10423}
10424
10425function crypto_box_keypair(y, x) {
10426 randombytes(x, 32);
10427 return crypto_scalarmult_base(y, x);
10428}
10429
10430function add(p, q) {
10431 var a = gf(), b = gf(), c = gf(),
10432 d = gf(), e = gf(), f = gf(),
10433 g = gf(), h = gf(), t = gf();
10434
10435 Z(a, p[1], p[0]);
10436 Z(t, q[1], q[0]);
10437 M(a, a, t);
10438 A(b, p[0], p[1]);
10439 A(t, q[0], q[1]);
10440 M(b, b, t);
10441 M(c, p[3], q[3]);
10442 M(c, c, D2);
10443 M(d, p[2], q[2]);
10444 A(d, d, d);
10445 Z(e, b, a);
10446 Z(f, d, c);
10447 A(g, d, c);
10448 A(h, b, a);
10449
10450 M(p[0], e, f);
10451 M(p[1], h, g);
10452 M(p[2], g, f);
10453 M(p[3], e, h);
10454}
10455
10456function cswap(p, q, b) {
10457 var i;
10458 for (i = 0; i < 4; i++) {
10459 sel25519(p[i], q[i], b);
10460 }
10461}
10462
10463function pack(r, p) {
10464 var tx = gf(), ty = gf(), zi = gf();
10465 inv25519(zi, p[2]);
10466 M(tx, p[0], zi);
10467 M(ty, p[1], zi);
10468 pack25519(r, ty);
10469 r[31] ^= par25519(tx) << 7;
10470}
10471
10472function scalarmult(p, q, s) {
10473 var b, i;
10474 set25519(p[0], gf0);
10475 set25519(p[1], gf1);
10476 set25519(p[2], gf1);
10477 set25519(p[3], gf0);
10478 for (i = 255; i >= 0; --i) {
10479 b = (s[(i/8)|0] >> (i&7)) & 1;
10480 cswap(p, q, b);
10481 add(q, p);
10482 add(p, p);
10483 cswap(p, q, b);
10484 }
10485}
10486
10487function scalarbase(p, s) {
10488 var q = [gf(), gf(), gf(), gf()];
10489 set25519(q[0], X);
10490 set25519(q[1], Y);
10491 set25519(q[2], gf1);
10492 M(q[3], X, Y);
10493 scalarmult(p, q, s);
10494}
10495
10496function crypto_sign_keypair(pk, sk, seeded) {
10497 var d;
10498 var p = [gf(), gf(), gf(), gf()];
10499 var i;
10500
10501 if (!seeded) randombytes(sk, 32);
10502 d = nacl.hash(sk.subarray(0, 32));
10503 d[0] &= 248;
10504 d[31] &= 127;
10505 d[31] |= 64;
10506
10507 scalarbase(p, d);
10508 pack(pk, p);
10509
10510 for (i = 0; i < 32; i++) sk[i+32] = pk[i];
10511 return 0;
10512}
10513
10514var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]);
10515
10516function modL(r, x) {
10517 var carry, i, j, k;
10518 for (i = 63; i >= 32; --i) {
10519 carry = 0;
10520 for (j = i - 32, k = i - 12; j < k; ++j) {
10521 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
10522 carry = Math.floor((x[j] + 128) / 256);
10523 x[j] -= carry * 256;
10524 }
10525 x[j] += carry;
10526 x[i] = 0;
10527 }
10528 carry = 0;
10529 for (j = 0; j < 32; j++) {
10530 x[j] += carry - (x[31] >> 4) * L[j];
10531 carry = x[j] >> 8;
10532 x[j] &= 255;
10533 }
10534 for (j = 0; j < 32; j++) x[j] -= carry * L[j];
10535 for (i = 0; i < 32; i++) {
10536 x[i+1] += x[i] >> 8;
10537 r[i] = x[i] & 255;
10538 }
10539}
10540
10541function reduce(r) {
10542 var x = new Float64Array(64), i;
10543 for (i = 0; i < 64; i++) x[i] = r[i];
10544 for (i = 0; i < 64; i++) r[i] = 0;
10545 modL(r, x);
10546}
10547
10548// Note: difference from C - smlen returned, not passed as argument.
10549function crypto_sign(sm, m, n, sk) {
10550 var d, h, r;
10551 var i, j, x = new Float64Array(64);
10552 var p = [gf(), gf(), gf(), gf()];
10553
10554 d = nacl.hash(sk.subarray(0, 32));
10555 d[0] &= 248;
10556 d[31] &= 127;
10557 d[31] |= 64;
10558
10559 var smlen = n + 64;
10560 for (i = 0; i < n; i++) sm[64 + i] = m[i];
10561 for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
10562
10563 r = nacl.hash(sm.subarray(32, smlen));
10564 reduce(r);
10565 scalarbase(p, r);
10566 pack(sm, p);
10567
10568 for (i = 32; i < 64; i++) sm[i] = sk[i];
10569 h = nacl.hash(sm.subarray(0, smlen));
10570 reduce(h);
10571
10572 for (i = 0; i < 64; i++) x[i] = 0;
10573 for (i = 0; i < 32; i++) x[i] = r[i];
10574 for (i = 0; i < 32; i++) {
10575 for (j = 0; j < 32; j++) {
10576 x[i+j] += h[i] * d[j];
10577 }
10578 }
10579
10580 modL(sm.subarray(32), x);
10581 return smlen;
10582}
10583
10584function unpackneg(r, p) {
10585 var t = gf(), chk = gf(), num = gf(),
10586 den = gf(), den2 = gf(), den4 = gf(),
10587 den6 = gf();
10588
10589 set25519(r[2], gf1);
10590 unpack25519(r[1], p);
10591 S(num, r[1]);
10592 M(den, num, D);
10593 Z(num, num, r[2]);
10594 A(den, r[2], den);
10595
10596 S(den2, den);
10597 S(den4, den2);
10598 M(den6, den4, den2);
10599 M(t, den6, num);
10600 M(t, t, den);
10601
10602 pow2523(t, t);
10603 M(t, t, num);
10604 M(t, t, den);
10605 M(t, t, den);
10606 M(r[0], t, den);
10607
10608 S(chk, r[0]);
10609 M(chk, chk, den);
10610 if (neq25519(chk, num)) M(r[0], r[0], I);
10611
10612 S(chk, r[0]);
10613 M(chk, chk, den);
10614 if (neq25519(chk, num)) return -1;
10615
10616 if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
10617
10618 M(r[3], r[0], r[1]);
10619 return 0;
10620}
10621
10622function crypto_sign_open(m, sm, n, pk) {
10623 var i;
10624 var t = new Uint8Array(32), h;
10625 var p = [gf(), gf(), gf(), gf()],
10626 q = [gf(), gf(), gf(), gf()];
10627
10628 if (n < 64) return -1;
10629
10630 if (unpackneg(q, pk)) return -1;
10631
10632 for (i = 0; i < n; i++) m[i] = sm[i];
10633 for (i = 0; i < 32; i++) m[i+32] = pk[i];
10634 h = nacl.hash(m.subarray(0, n));
10635 reduce(h);
10636 scalarmult(p, q, h);
10637
10638 scalarbase(q, sm.subarray(32));
10639 add(p, q);
10640 pack(t, p);
10641
10642 n -= 64;
10643 if (crypto_verify_32(sm, 0, t, 0)) {
10644 for (i = 0; i < n; i++) m[i] = 0;
10645 return -1;
10646 }
10647
10648 for (i = 0; i < n; i++) m[i] = sm[i + 64];
10649 return n;
10650}
10651
10652var crypto_scalarmult_BYTES = 32,
10653 crypto_scalarmult_SCALARBYTES = 32,
10654 crypto_box_PUBLICKEYBYTES = 32,
10655 crypto_box_SECRETKEYBYTES = 32,
10656 crypto_sign_BYTES = 64,
10657 crypto_sign_PUBLICKEYBYTES = 32,
10658 crypto_sign_SECRETKEYBYTES = 64,
10659 crypto_sign_SEEDBYTES = 32;
10660
10661function checkArrayTypes() {
10662 for (var i = 0; i < arguments.length; i++) {
10663 if (!(arguments[i] instanceof Uint8Array))
10664 throw new TypeError('unexpected type, use Uint8Array');
10665 }
10666}
10667
10668function cleanup(arr) {
10669 for (var i = 0; i < arr.length; i++) arr[i] = 0;
10670}
10671
10672nacl.scalarMult = function(n, p) {
10673 checkArrayTypes(n, p);
10674 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
10675 if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
10676 var q = new Uint8Array(crypto_scalarmult_BYTES);
10677 crypto_scalarmult(q, n, p);
10678 return q;
10679};
10680
10681nacl.box = {};
10682
10683nacl.box.keyPair = function() {
10684 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
10685 var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
10686 crypto_box_keypair(pk, sk);
10687 return {publicKey: pk, secretKey: sk};
10688};
10689
10690nacl.box.keyPair.fromSecretKey = function(secretKey) {
10691 checkArrayTypes(secretKey);
10692 if (secretKey.length !== crypto_box_SECRETKEYBYTES)
10693 throw new Error('bad secret key size');
10694 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
10695 crypto_scalarmult_base(pk, secretKey);
10696 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
10697};
10698
10699nacl.sign = function(msg, secretKey) {
10700 checkArrayTypes(msg, secretKey);
10701 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
10702 throw new Error('bad secret key size');
10703 var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
10704 crypto_sign(signedMsg, msg, msg.length, secretKey);
10705 return signedMsg;
10706};
10707
10708nacl.sign.detached = function(msg, secretKey) {
10709 var signedMsg = nacl.sign(msg, secretKey);
10710 var sig = new Uint8Array(crypto_sign_BYTES);
10711 for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
10712 return sig;
10713};
10714
10715nacl.sign.detached.verify = function(msg, sig, publicKey) {
10716 checkArrayTypes(msg, sig, publicKey);
10717 if (sig.length !== crypto_sign_BYTES)
10718 throw new Error('bad signature size');
10719 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
10720 throw new Error('bad public key size');
10721 var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
10722 var m = new Uint8Array(crypto_sign_BYTES + msg.length);
10723 var i;
10724 for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
10725 for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
10726 return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
10727};
10728
10729nacl.sign.keyPair = function() {
10730 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10731 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
10732 crypto_sign_keypair(pk, sk);
10733 return {publicKey: pk, secretKey: sk};
10734};
10735
10736nacl.sign.keyPair.fromSecretKey = function(secretKey) {
10737 checkArrayTypes(secretKey);
10738 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
10739 throw new Error('bad secret key size');
10740 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10741 for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i];
10742 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
10743};
10744
10745nacl.sign.keyPair.fromSeed = function(seed) {
10746 checkArrayTypes(seed);
10747 if (seed.length !== crypto_sign_SEEDBYTES)
10748 throw new Error('bad seed size');
10749 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
10750 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
10751 for (var i = 0; i < 32; i++) sk[i] = seed[i];
10752 crypto_sign_keypair(pk, sk, true);
10753 return {publicKey: pk, secretKey: sk};
10754};
10755
10756nacl.setPRNG = function(fn) {
10757 randombytes = fn;
10758};
10759
10760(function() {
10761 // Initialize PRNG if environment provides CSPRNG.
10762 // If not, methods calling randombytes will throw.
10763 var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
10764 if (crypto && crypto.getRandomValues) {
10765 // Browsers.
10766 var QUOTA = 65536;
10767 nacl.setPRNG(function(x, n) {
10768 var i, v = new Uint8Array(n);
10769 for (i = 0; i < n; i += QUOTA) {
10770 crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
10771 }
10772 for (i = 0; i < n; i++) x[i] = v[i];
10773 cleanup(v);
10774 });
10775 } else if (typeof commonjsRequire !== 'undefined') {
10776 // Node.js.
10777 crypto = crypto$3;
10778 if (crypto && crypto.randomBytes) {
10779 nacl.setPRNG(function(x, n) {
10780 var i, v = crypto.randomBytes(n);
10781 for (i = 0; i < n; i++) x[i] = v[i];
10782 cleanup(v);
10783 });
10784 }
10785 }
10786})();
10787
10788})(module.exports ? module.exports : (self.nacl = self.nacl || {}));
10789});
10790
10791// GPG4Browsers - An OpenPGP implementation in javascript
10792
10793const nodeCrypto$1 = util.getNodeCrypto();
10794
10795/**
10796 * Buffer for secure random numbers
10797 */
10798class RandomBuffer {
10799 constructor() {
10800 this.buffer = null;
10801 this.size = null;
10802 this.callback = null;
10803 }
10804
10805 /**
10806 * Initialize buffer
10807 * @param {Integer} size - size of buffer
10808 */
10809 init(size, callback) {
10810 this.buffer = new Uint8Array(size);
10811 this.size = 0;
10812 this.callback = callback;
10813 }
10814
10815 /**
10816 * Concat array of secure random numbers to buffer
10817 * @param {Uint8Array} buf
10818 */
10819 set(buf) {
10820 if (!this.buffer) {
10821 throw new Error('RandomBuffer is not initialized');
10822 }
10823 if (!(buf instanceof Uint8Array)) {
10824 throw new Error('Invalid type: buf not an Uint8Array');
10825 }
10826 const freeSpace = this.buffer.length - this.size;
10827 if (buf.length > freeSpace) {
10828 buf = buf.subarray(0, freeSpace);
10829 }
10830 // set buf with offset old size of buffer
10831 this.buffer.set(buf, this.size);
10832 this.size += buf.length;
10833 }
10834
10835 /**
10836 * Take numbers out of buffer and copy to array
10837 * @param {Uint8Array} buf - The destination array
10838 */
10839 async get(buf) {
10840 if (!this.buffer) {
10841 throw new Error('RandomBuffer is not initialized');
10842 }
10843 if (!(buf instanceof Uint8Array)) {
10844 throw new Error('Invalid type: buf not an Uint8Array');
10845 }
10846 if (this.size < buf.length) {
10847 if (!this.callback) {
10848 throw new Error('Random number buffer depleted');
10849 }
10850 // Wait for random bytes from main context, then try again
10851 await this.callback();
10852 return this.get(buf);
10853 }
10854 for (let i = 0; i < buf.length; i++) {
10855 buf[i] = this.buffer[--this.size];
10856 // clear buffer value
10857 this.buffer[this.size] = 0;
10858 }
10859 }
10860}
10861
10862/**
10863 * Retrieve secure random byte array of the specified length
10864 * @param {Integer} length - Length in bytes to generate
10865 * @returns {Promise<Uint8Array>} Random byte array.
10866 * @async
10867 */
10868async function getRandomBytes(length) {
10869 const buf = new Uint8Array(length);
10870 if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
10871 crypto.getRandomValues(buf);
10872 } else if (nodeCrypto$1) {
10873 const bytes = nodeCrypto$1.randomBytes(buf.length);
10874 buf.set(bytes);
10875 } else if (randomBuffer.buffer) {
10876 await randomBuffer.get(buf);
10877 } else {
10878 throw new Error('No secure random number generator available.');
10879 }
10880 return buf;
10881}
10882
10883/**
10884 * Create a secure random BigInteger that is greater than or equal to min and less than max.
10885 * @param {module:BigInteger} min - Lower bound, included
10886 * @param {module:BigInteger} max - Upper bound, excluded
10887 * @returns {Promise<module:BigInteger>} Random BigInteger.
10888 * @async
10889 */
10890async function getRandomBigInteger(min, max) {
10891 const BigInteger = await util.getBigInteger();
10892
10893 if (max.lt(min)) {
10894 throw new Error('Illegal parameter value: max <= min');
10895 }
10896
10897 const modulus = max.sub(min);
10898 const bytes = modulus.byteLength();
10899
10900 // Using a while loop is necessary to avoid bias introduced by the mod operation.
10901 // However, we request 64 extra random bits so that the bias is negligible.
10902 // Section B.1.1 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
10903 const r = new BigInteger(await getRandomBytes(bytes + 8));
10904 return r.mod(modulus).add(min);
10905}
10906
10907const randomBuffer = new RandomBuffer();
10908
10909var random = /*#__PURE__*/Object.freeze({
10910 __proto__: null,
10911 getRandomBytes: getRandomBytes,
10912 getRandomBigInteger: getRandomBigInteger,
10913 randomBuffer: randomBuffer
10914});
10915
10916// OpenPGP.js - An OpenPGP implementation in javascript
10917
10918/**
10919 * Generate a probably prime random number
10920 * @param {Integer} bits - Bit length of the prime
10921 * @param {BigInteger} e - Optional RSA exponent to check against the prime
10922 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
10923 * @returns BigInteger
10924 * @async
10925 */
10926async function randomProbablePrime(bits, e, k) {
10927 const BigInteger = await util.getBigInteger();
10928 const one = new BigInteger(1);
10929 const min = one.leftShift(new BigInteger(bits - 1));
10930 const thirty = new BigInteger(30);
10931 /*
10932 * We can avoid any multiples of 3 and 5 by looking at n mod 30
10933 * n mod 30 = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
10934 * the next possible prime is mod 30:
10935 * 1 7 7 7 7 7 7 11 11 11 11 13 13 17 17 17 17 19 19 23 23 23 23 29 29 29 29 29 29 1
10936 */
10937 const adds = [1, 6, 5, 4, 3, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 2, 1, 4, 3, 2, 1, 6, 5, 4, 3, 2, 1, 2];
10938
10939 const n = await getRandomBigInteger(min, min.leftShift(one));
10940 let i = n.mod(thirty).toNumber();
10941
10942 do {
10943 n.iadd(new BigInteger(adds[i]));
10944 i = (i + adds[i]) % adds.length;
10945 // If reached the maximum, go back to the minimum.
10946 if (n.bitLength() > bits) {
10947 n.imod(min.leftShift(one)).iadd(min);
10948 i = n.mod(thirty).toNumber();
10949 }
10950 } while (!await isProbablePrime(n, e, k));
10951 return n;
10952}
10953
10954/**
10955 * Probabilistic primality testing
10956 * @param {BigInteger} n - Number to test
10957 * @param {BigInteger} e - Optional RSA exponent to check against the prime
10958 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
10959 * @returns {boolean}
10960 * @async
10961 */
10962async function isProbablePrime(n, e, k) {
10963 if (e && !n.dec().gcd(e).isOne()) {
10964 return false;
10965 }
10966 if (!await divisionTest(n)) {
10967 return false;
10968 }
10969 if (!await fermat(n)) {
10970 return false;
10971 }
10972 if (!await millerRabin(n, k)) {
10973 return false;
10974 }
10975 // TODO implement the Lucas test
10976 // See Section C.3.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
10977 return true;
10978}
10979
10980/**
10981 * Tests whether n is probably prime or not using Fermat's test with b = 2.
10982 * Fails if b^(n-1) mod n != 1.
10983 * @param {BigInteger} n - Number to test
10984 * @param {BigInteger} b - Optional Fermat test base
10985 * @returns {boolean}
10986 */
10987async function fermat(n, b) {
10988 const BigInteger = await util.getBigInteger();
10989 b = b || new BigInteger(2);
10990 return b.modExp(n.dec(), n).isOne();
10991}
10992
10993async function divisionTest(n) {
10994 const BigInteger = await util.getBigInteger();
10995 return smallPrimes.every(m => {
10996 return n.mod(new BigInteger(m)) !== 0;
10997 });
10998}
10999
11000// https://github.com/gpg/libgcrypt/blob/master/cipher/primegen.c
11001const smallPrimes = [
11002 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
11003 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
11004 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
11005 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
11006 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
11007 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
11008 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
11009 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
11010 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
11011 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
11012 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
11013 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
11014 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
11015 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
11016 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
11017 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
11018 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
11019 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
11020 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
11021 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
11022 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
11023 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
11024 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
11025 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
11026 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
11027 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
11028 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
11029 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
11030 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
11031 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
11032 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
11033 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
11034 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
11035 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
11036 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
11037 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
11038 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
11039 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
11040 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
11041 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
11042 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
11043 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
11044 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
11045 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
11046 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
11047 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
11048 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
11049 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
11050 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
11051 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
11052 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
11053 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
11054 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
11055 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
11056 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
11057 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
11058 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
11059 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
11060 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
11061 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
11062 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
11063 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
11064 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
11065 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
11066 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
11067 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
11068 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
11069 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
11070 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
11071 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
11072 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
11073 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
11074 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
11075 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
11076 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
11077 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
11078 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
11079 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
11080 4957, 4967, 4969, 4973, 4987, 4993, 4999
11081];
11082
11083
11084// Miller-Rabin - Miller Rabin algorithm for primality test
11085// Copyright Fedor Indutny, 2014.
11086//
11087// This software is licensed under the MIT License.
11088//
11089// Permission is hereby granted, free of charge, to any person obtaining a
11090// copy of this software and associated documentation files (the
11091// "Software"), to deal in the Software without restriction, including
11092// without limitation the rights to use, copy, modify, merge, publish,
11093// distribute, sublicense, and/or sell copies of the Software, and to permit
11094// persons to whom the Software is furnished to do so, subject to the
11095// following conditions:
11096//
11097// The above copyright notice and this permission notice shall be included
11098// in all copies or substantial portions of the Software.
11099//
11100// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
11101// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11102// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
11103// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
11104// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
11105// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
11106// USE OR OTHER DEALINGS IN THE SOFTWARE.
11107
11108// Adapted on Jan 2018 from version 4.0.1 at https://github.com/indutny/miller-rabin
11109
11110// Sample syntax for Fixed-Base Miller-Rabin:
11111// millerRabin(n, k, () => new BN(small_primes[Math.random() * small_primes.length | 0]))
11112
11113/**
11114 * Tests whether n is probably prime or not using the Miller-Rabin test.
11115 * See HAC Remark 4.28.
11116 * @param {BigInteger} n - Number to test
11117 * @param {Integer} k - Optional number of iterations of Miller-Rabin test
11118 * @param {Function} rand - Optional function to generate potential witnesses
11119 * @returns {boolean}
11120 * @async
11121 */
11122async function millerRabin(n, k, rand) {
11123 const BigInteger = await util.getBigInteger();
11124 const len = n.bitLength();
11125
11126 if (!k) {
11127 k = Math.max(1, (len / 48) | 0);
11128 }
11129
11130 const n1 = n.dec(); // n - 1
11131
11132 // Find d and s, (n - 1) = (2 ^ s) * d;
11133 let s = 0;
11134 while (!n1.getBit(s)) { s++; }
11135 const d = n.rightShift(new BigInteger(s));
11136
11137 for (; k > 0; k--) {
11138 const a = rand ? rand() : await getRandomBigInteger(new BigInteger(2), n1);
11139
11140 let x = a.modExp(d, n);
11141 if (x.isOne() || x.equal(n1)) {
11142 continue;
11143 }
11144
11145 let i;
11146 for (i = 1; i < s; i++) {
11147 x = x.mul(x).mod(n);
11148
11149 if (x.isOne()) {
11150 return false;
11151 }
11152 if (x.equal(n1)) {
11153 break;
11154 }
11155 }
11156
11157 if (i === s) {
11158 return false;
11159 }
11160 }
11161
11162 return true;
11163}
11164
11165// GPG4Browsers - An OpenPGP implementation in javascript
11166
11167/**
11168 * ASN1 object identifiers for hashes
11169 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.2}
11170 */
11171const hash_headers = [];
11172hash_headers[1] = [0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04,
11173 0x10];
11174hash_headers[2] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14];
11175hash_headers[3] = [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14];
11176hash_headers[8] = [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00,
11177 0x04, 0x20];
11178hash_headers[9] = [0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00,
11179 0x04, 0x30];
11180hash_headers[10] = [0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
11181 0x00, 0x04, 0x40];
11182hash_headers[11] = [0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05,
11183 0x00, 0x04, 0x1C];
11184
11185/**
11186 * Create padding with secure random data
11187 * @private
11188 * @param {Integer} length - Length of the padding in bytes
11189 * @returns {Promise<Uint8Array>} Random padding.
11190 * @async
11191 */
11192async function getPKCS1Padding(length) {
11193 const result = new Uint8Array(length);
11194 let count = 0;
11195 while (count < length) {
11196 const randomBytes = await getRandomBytes(length - count);
11197 for (let i = 0; i < randomBytes.length; i++) {
11198 if (randomBytes[i] !== 0) {
11199 result[count++] = randomBytes[i];
11200 }
11201 }
11202 }
11203 return result;
11204}
11205
11206/**
11207 * Create a EME-PKCS1-v1_5 padded message
11208 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.1|RFC 4880 13.1.1}
11209 * @param {Uint8Array} message - Message to be encoded
11210 * @param {Integer} keyLength - The length in octets of the key modulus
11211 * @returns {Promise<Uint8Array>} EME-PKCS1 padded message.
11212 * @async
11213 */
11214async function emeEncode(message, keyLength) {
11215 const mLength = message.length;
11216 // length checking
11217 if (mLength > keyLength - 11) {
11218 throw new Error('Message too long');
11219 }
11220 // Generate an octet string PS of length k - mLen - 3 consisting of
11221 // pseudo-randomly generated nonzero octets
11222 const PS = await getPKCS1Padding(keyLength - mLength - 3);
11223 // Concatenate PS, the message M, and other padding to form an
11224 // encoded message EM of length k octets as EM = 0x00 || 0x02 || PS || 0x00 || M.
11225 const encoded = new Uint8Array(keyLength);
11226 // 0x00 byte
11227 encoded[1] = 2;
11228 encoded.set(PS, 2);
11229 // 0x00 bytes
11230 encoded.set(message, keyLength - mLength);
11231 return encoded;
11232}
11233
11234/**
11235 * Decode a EME-PKCS1-v1_5 padded message
11236 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.2|RFC 4880 13.1.2}
11237 * @param {Uint8Array} encoded - Encoded message bytes
11238 * @param {Uint8Array} randomPayload - Data to return in case of decoding error (needed for constant-time processing)
11239 * @returns {Uint8Array} decoded data or `randomPayload` (on error, if given)
11240 * @throws {Error} on decoding failure, unless `randomPayload` is provided
11241 */
11242function emeDecode(encoded, randomPayload) {
11243 // encoded format: 0x00 0x02 <PS> 0x00 <payload>
11244 let offset = 2;
11245 let separatorNotFound = 1;
11246 for (let j = offset; j < encoded.length; j++) {
11247 separatorNotFound &= encoded[j] !== 0;
11248 offset += separatorNotFound;
11249 }
11250
11251 const psLen = offset - 2;
11252 const payload = encoded.subarray(offset + 1); // discard the 0x00 separator
11253 const isValidPadding = encoded[0] === 0 & encoded[1] === 2 & psLen >= 8 & !separatorNotFound;
11254
11255 if (randomPayload) {
11256 return util.selectUint8Array(isValidPadding, payload, randomPayload);
11257 }
11258
11259 if (isValidPadding) {
11260 return payload;
11261 }
11262
11263 throw new Error('Decryption error');
11264}
11265
11266/**
11267 * Create a EMSA-PKCS1-v1_5 padded message
11268 * @see {@link https://tools.ietf.org/html/rfc4880#section-13.1.3|RFC 4880 13.1.3}
11269 * @param {Integer} algo - Hash algorithm type used
11270 * @param {Uint8Array} hashed - Message to be encoded
11271 * @param {Integer} emLen - Intended length in octets of the encoded message
11272 * @returns {Uint8Array} Encoded message.
11273 */
11274async function emsaEncode(algo, hashed, emLen) {
11275 let i;
11276 if (hashed.length !== hash.getHashByteLength(algo)) {
11277 throw new Error('Invalid hash length');
11278 }
11279 // produce an ASN.1 DER value for the hash function used.
11280 // Let T be the full hash prefix
11281 const hashPrefix = new Uint8Array(hash_headers[algo].length);
11282 for (i = 0; i < hash_headers[algo].length; i++) {
11283 hashPrefix[i] = hash_headers[algo][i];
11284 }
11285 // and let tLen be the length in octets prefix and hashed data
11286 const tLen = hashPrefix.length + hashed.length;
11287 if (emLen < tLen + 11) {
11288 throw new Error('Intended encoded message length too short');
11289 }
11290 // an octet string PS consisting of emLen - tLen - 3 octets with hexadecimal value 0xFF
11291 // The length of PS will be at least 8 octets
11292 const PS = new Uint8Array(emLen - tLen - 3).fill(0xff);
11293
11294 // Concatenate PS, the hash prefix, hashed data, and other padding to form the
11295 // encoded message EM as EM = 0x00 || 0x01 || PS || 0x00 || prefix || hashed
11296 const EM = new Uint8Array(emLen);
11297 EM[1] = 0x01;
11298 EM.set(PS, 2);
11299 EM.set(hashPrefix, emLen - tLen);
11300 EM.set(hashed, emLen - hashed.length);
11301 return EM;
11302}
11303
11304var pkcs1 = /*#__PURE__*/Object.freeze({
11305 __proto__: null,
11306 emeEncode: emeEncode,
11307 emeDecode: emeDecode,
11308 emsaEncode: emsaEncode
11309});
11310
11311const webCrypto$1 = util.getWebCrypto();
11312const nodeCrypto$2 = util.getNodeCrypto();
11313const asn1 = nodeCrypto$2 ? asn1$2 : undefined;
11314
11315/* eslint-disable no-invalid-this */
11316const RSAPrivateKey = nodeCrypto$2 ? asn1.define('RSAPrivateKey', function () {
11317 this.seq().obj( // used for native NodeJS crypto
11318 this.key('version').int(), // 0
11319 this.key('modulus').int(), // n
11320 this.key('publicExponent').int(), // e
11321 this.key('privateExponent').int(), // d
11322 this.key('prime1').int(), // p
11323 this.key('prime2').int(), // q
11324 this.key('exponent1').int(), // dp
11325 this.key('exponent2').int(), // dq
11326 this.key('coefficient').int() // u
11327 );
11328}) : undefined;
11329
11330const RSAPublicKey = nodeCrypto$2 ? asn1.define('RSAPubliceKey', function () {
11331 this.seq().obj( // used for native NodeJS crypto
11332 this.key('modulus').int(), // n
11333 this.key('publicExponent').int(), // e
11334 );
11335}) : undefined;
11336/* eslint-enable no-invalid-this */
11337
11338/** Create signature
11339 * @param {module:enums.hash} hashAlgo - Hash algorithm
11340 * @param {Uint8Array} data - Message
11341 * @param {Uint8Array} n - RSA public modulus
11342 * @param {Uint8Array} e - RSA public exponent
11343 * @param {Uint8Array} d - RSA private exponent
11344 * @param {Uint8Array} p - RSA private prime p
11345 * @param {Uint8Array} q - RSA private prime q
11346 * @param {Uint8Array} u - RSA private coefficient
11347 * @param {Uint8Array} hashed - Hashed message
11348 * @returns {Promise<Uint8Array>} RSA Signature.
11349 * @async
11350 */
11351async function sign(hashAlgo, data, n, e, d, p, q, u, hashed) {
11352 if (data && !util.isStream(data)) {
11353 if (util.getWebCrypto()) {
11354 try {
11355 return await webSign(enums.read(enums.webHash, hashAlgo), data, n, e, d, p, q, u);
11356 } catch (err) {
11357 util.printDebugError(err);
11358 }
11359 } else if (util.getNodeCrypto()) {
11360 return nodeSign(hashAlgo, data, n, e, d, p, q, u);
11361 }
11362 }
11363 return bnSign(hashAlgo, n, d, hashed);
11364}
11365
11366/**
11367 * Verify signature
11368 * @param {module:enums.hash} hashAlgo - Hash algorithm
11369 * @param {Uint8Array} data - Message
11370 * @param {Uint8Array} s - Signature
11371 * @param {Uint8Array} n - RSA public modulus
11372 * @param {Uint8Array} e - RSA public exponent
11373 * @param {Uint8Array} hashed - Hashed message
11374 * @returns {Boolean}
11375 * @async
11376 */
11377async function verify(hashAlgo, data, s, n, e, hashed) {
11378 if (data && !util.isStream(data)) {
11379 if (util.getWebCrypto()) {
11380 try {
11381 return await webVerify(enums.read(enums.webHash, hashAlgo), data, s, n, e);
11382 } catch (err) {
11383 util.printDebugError(err);
11384 }
11385 } else if (util.getNodeCrypto()) {
11386 return nodeVerify(hashAlgo, data, s, n, e);
11387 }
11388 }
11389 return bnVerify(hashAlgo, s, n, e, hashed);
11390}
11391
11392/**
11393 * Encrypt message
11394 * @param {Uint8Array} data - Message
11395 * @param {Uint8Array} n - RSA public modulus
11396 * @param {Uint8Array} e - RSA public exponent
11397 * @returns {Promise<Uint8Array>} RSA Ciphertext.
11398 * @async
11399 */
11400async function encrypt(data, n, e) {
11401 if (util.getNodeCrypto()) {
11402 return nodeEncrypt(data, n, e);
11403 }
11404 return bnEncrypt(data, n, e);
11405}
11406
11407/**
11408 * Decrypt RSA message
11409 * @param {Uint8Array} m - Message
11410 * @param {Uint8Array} n - RSA public modulus
11411 * @param {Uint8Array} e - RSA public exponent
11412 * @param {Uint8Array} d - RSA private exponent
11413 * @param {Uint8Array} p - RSA private prime p
11414 * @param {Uint8Array} q - RSA private prime q
11415 * @param {Uint8Array} u - RSA private coefficient
11416 * @param {Uint8Array} randomPayload - Data to return on decryption error, instead of throwing
11417 * (needed for constant-time processing)
11418 * @returns {Promise<String>} RSA Plaintext.
11419 * @throws {Error} on decryption error, unless `randomPayload` is given
11420 * @async
11421 */
11422async function decrypt(data, n, e, d, p, q, u, randomPayload) {
11423 if (util.getNodeCrypto()) {
11424 return nodeDecrypt(data, n, e, d, p, q, u, randomPayload);
11425 }
11426 return bnDecrypt(data, n, e, d, p, q, u, randomPayload);
11427}
11428
11429/**
11430 * Generate a new random private key B bits long with public exponent E.
11431 *
11432 * When possible, webCrypto or nodeCrypto is used. Otherwise, primes are generated using
11433 * 40 rounds of the Miller-Rabin probabilistic random prime generation algorithm.
11434 * @see module:crypto/public_key/prime
11435 * @param {Integer} bits - RSA bit length
11436 * @param {Integer} e - RSA public exponent
11437 * @returns {{n, e, d,
11438 * p, q ,u: Uint8Array}} RSA public modulus, RSA public exponent, RSA private exponent,
11439 * RSA private prime p, RSA private prime q, u = p ** -1 mod q
11440 * @async
11441 */
11442async function generate(bits, e) {
11443 const BigInteger = await util.getBigInteger();
11444
11445 e = new BigInteger(e);
11446
11447 // Native RSA keygen using Web Crypto
11448 if (util.getWebCrypto()) {
11449 const keyGenOpt = {
11450 name: 'RSASSA-PKCS1-v1_5',
11451 modulusLength: bits, // the specified keysize in bits
11452 publicExponent: e.toUint8Array(), // take three bytes (max 65537) for exponent
11453 hash: {
11454 name: 'SHA-1' // not required for actual RSA keys, but for crypto api 'sign' and 'verify'
11455 }
11456 };
11457 const keyPair = await webCrypto$1.generateKey(keyGenOpt, true, ['sign', 'verify']);
11458
11459 // export the generated keys as JsonWebKey (JWK)
11460 // https://tools.ietf.org/html/draft-ietf-jose-json-web-key-33
11461 const jwk = await webCrypto$1.exportKey('jwk', keyPair.privateKey);
11462 // map JWK parameters to corresponding OpenPGP names
11463 return {
11464 n: b64ToUint8Array(jwk.n),
11465 e: e.toUint8Array(),
11466 d: b64ToUint8Array(jwk.d),
11467 // switch p and q
11468 p: b64ToUint8Array(jwk.q),
11469 q: b64ToUint8Array(jwk.p),
11470 // Since p and q are switched in places, u is the inverse of jwk.q
11471 u: b64ToUint8Array(jwk.qi)
11472 };
11473 } else if (util.getNodeCrypto() && nodeCrypto$2.generateKeyPair && RSAPrivateKey) {
11474 const opts = {
11475 modulusLength: bits,
11476 publicExponent: e.toNumber(),
11477 publicKeyEncoding: { type: 'pkcs1', format: 'der' },
11478 privateKeyEncoding: { type: 'pkcs1', format: 'der' }
11479 };
11480 const prv = await new Promise((resolve, reject) => nodeCrypto$2.generateKeyPair('rsa', opts, (err, _, der) => {
11481 if (err) {
11482 reject(err);
11483 } else {
11484 resolve(RSAPrivateKey.decode(der, 'der'));
11485 }
11486 }));
11487 /**
11488 * OpenPGP spec differs from DER spec, DER: `u = (inverse of q) mod p`, OpenPGP: `u = (inverse of p) mod q`.
11489 * @link https://tools.ietf.org/html/rfc3447#section-3.2
11490 * @link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-08#section-5.6.1
11491 */
11492 return {
11493 n: prv.modulus.toArrayLike(Uint8Array),
11494 e: prv.publicExponent.toArrayLike(Uint8Array),
11495 d: prv.privateExponent.toArrayLike(Uint8Array),
11496 // switch p and q
11497 p: prv.prime2.toArrayLike(Uint8Array),
11498 q: prv.prime1.toArrayLike(Uint8Array),
11499 // Since p and q are switched in places, we can keep u as defined by DER
11500 u: prv.coefficient.toArrayLike(Uint8Array)
11501 };
11502 }
11503
11504 // RSA keygen fallback using 40 iterations of the Miller-Rabin test
11505 // See https://stackoverflow.com/a/6330138 for justification
11506 // Also see section C.3 here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST
11507 let p;
11508 let q;
11509 let n;
11510 do {
11511 q = await randomProbablePrime(bits - (bits >> 1), e, 40);
11512 p = await randomProbablePrime(bits >> 1, e, 40);
11513 n = p.mul(q);
11514 } while (n.bitLength() !== bits);
11515
11516 const phi = p.dec().imul(q.dec());
11517
11518 if (q.lt(p)) {
11519 [p, q] = [q, p];
11520 }
11521
11522 return {
11523 n: n.toUint8Array(),
11524 e: e.toUint8Array(),
11525 d: e.modInv(phi).toUint8Array(),
11526 p: p.toUint8Array(),
11527 q: q.toUint8Array(),
11528 // dp: d.mod(p.subn(1)),
11529 // dq: d.mod(q.subn(1)),
11530 u: p.modInv(q).toUint8Array()
11531 };
11532}
11533
11534/**
11535 * Validate RSA parameters
11536 * @param {Uint8Array} n - RSA public modulus
11537 * @param {Uint8Array} e - RSA public exponent
11538 * @param {Uint8Array} d - RSA private exponent
11539 * @param {Uint8Array} p - RSA private prime p
11540 * @param {Uint8Array} q - RSA private prime q
11541 * @param {Uint8Array} u - RSA inverse of p w.r.t. q
11542 * @returns {Promise<Boolean>} Whether params are valid.
11543 * @async
11544 */
11545async function validateParams(n, e, d, p, q, u) {
11546 const BigInteger = await util.getBigInteger();
11547 n = new BigInteger(n);
11548 p = new BigInteger(p);
11549 q = new BigInteger(q);
11550
11551 // expect pq = n
11552 if (!p.mul(q).equal(n)) {
11553 return false;
11554 }
11555
11556 const two = new BigInteger(2);
11557 // expect p*u = 1 mod q
11558 u = new BigInteger(u);
11559 if (!p.mul(u).mod(q).isOne()) {
11560 return false;
11561 }
11562
11563 e = new BigInteger(e);
11564 d = new BigInteger(d);
11565 /**
11566 * In RSA pkcs#1 the exponents (d, e) are inverses modulo lcm(p-1, q-1)
11567 * We check that [de = 1 mod (p-1)] and [de = 1 mod (q-1)]
11568 * By CRT on coprime factors of (p-1, q-1) it follows that [de = 1 mod lcm(p-1, q-1)]
11569 *
11570 * We blind the multiplication with r, and check that rde = r mod lcm(p-1, q-1)
11571 */
11572 const nSizeOver3 = new BigInteger(Math.floor(n.bitLength() / 3));
11573 const r = await getRandomBigInteger(two, two.leftShift(nSizeOver3)); // r in [ 2, 2^{|n|/3} ) < p and q
11574 const rde = r.mul(d).mul(e);
11575
11576 const areInverses = rde.mod(p.dec()).equal(r) && rde.mod(q.dec()).equal(r);
11577 if (!areInverses) {
11578 return false;
11579 }
11580
11581 return true;
11582}
11583
11584async function bnSign(hashAlgo, n, d, hashed) {
11585 const BigInteger = await util.getBigInteger();
11586 n = new BigInteger(n);
11587 const m = new BigInteger(await emsaEncode(hashAlgo, hashed, n.byteLength()));
11588 d = new BigInteger(d);
11589 if (m.gte(n)) {
11590 throw new Error('Message size cannot exceed modulus size');
11591 }
11592 return m.modExp(d, n).toUint8Array('be', n.byteLength());
11593}
11594
11595async function webSign(hashName, data, n, e, d, p, q, u) {
11596 /** OpenPGP keys require that p < q, and Safari Web Crypto requires that p > q.
11597 * We swap them in privateToJWK, so it usually works out, but nevertheless,
11598 * not all OpenPGP keys are compatible with this requirement.
11599 * OpenPGP.js used to generate RSA keys the wrong way around (p > q), and still
11600 * does if the underlying Web Crypto does so (though the tested implementations
11601 * don't do so).
11602 */
11603 const jwk = await privateToJWK(n, e, d, p, q, u);
11604 const algo = {
11605 name: 'RSASSA-PKCS1-v1_5',
11606 hash: { name: hashName }
11607 };
11608 const key = await webCrypto$1.importKey('jwk', jwk, algo, false, ['sign']);
11609 return new Uint8Array(await webCrypto$1.sign('RSASSA-PKCS1-v1_5', key, data));
11610}
11611
11612async function nodeSign(hashAlgo, data, n, e, d, p, q, u) {
11613 const { default: BN } = await Promise.resolve().then(function () { return bn$1; });
11614 const pBNum = new BN(p);
11615 const qBNum = new BN(q);
11616 const dBNum = new BN(d);
11617 const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1)
11618 const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1)
11619 const sign = nodeCrypto$2.createSign(enums.read(enums.hash, hashAlgo));
11620 sign.write(data);
11621 sign.end();
11622 const keyObject = {
11623 version: 0,
11624 modulus: new BN(n),
11625 publicExponent: new BN(e),
11626 privateExponent: new BN(d),
11627 // switch p and q
11628 prime1: new BN(q),
11629 prime2: new BN(p),
11630 // switch dp and dq
11631 exponent1: dq,
11632 exponent2: dp,
11633 coefficient: new BN(u)
11634 };
11635 if (typeof nodeCrypto$2.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects
11636 const der = RSAPrivateKey.encode(keyObject, 'der');
11637 return new Uint8Array(sign.sign({ key: der, format: 'der', type: 'pkcs1' }));
11638 }
11639 const pem = RSAPrivateKey.encode(keyObject, 'pem', {
11640 label: 'RSA PRIVATE KEY'
11641 });
11642 return new Uint8Array(sign.sign(pem));
11643}
11644
11645async function bnVerify(hashAlgo, s, n, e, hashed) {
11646 const BigInteger = await util.getBigInteger();
11647 n = new BigInteger(n);
11648 s = new BigInteger(s);
11649 e = new BigInteger(e);
11650 if (s.gte(n)) {
11651 throw new Error('Signature size cannot exceed modulus size');
11652 }
11653 const EM1 = s.modExp(e, n).toUint8Array('be', n.byteLength());
11654 const EM2 = await emsaEncode(hashAlgo, hashed, n.byteLength());
11655 return util.equalsUint8Array(EM1, EM2);
11656}
11657
11658async function webVerify(hashName, data, s, n, e) {
11659 const jwk = publicToJWK(n, e);
11660 const key = await webCrypto$1.importKey('jwk', jwk, {
11661 name: 'RSASSA-PKCS1-v1_5',
11662 hash: { name: hashName }
11663 }, false, ['verify']);
11664 return webCrypto$1.verify('RSASSA-PKCS1-v1_5', key, s, data);
11665}
11666
11667async function nodeVerify(hashAlgo, data, s, n, e) {
11668 const { default: BN } = await Promise.resolve().then(function () { return bn$1; });
11669
11670 const verify = nodeCrypto$2.createVerify(enums.read(enums.hash, hashAlgo));
11671 verify.write(data);
11672 verify.end();
11673 const keyObject = {
11674 modulus: new BN(n),
11675 publicExponent: new BN(e)
11676 };
11677 let key;
11678 if (typeof nodeCrypto$2.createPrivateKey !== 'undefined') { //from version 11.6.0 Node supports der encoded key objects
11679 const der = RSAPublicKey.encode(keyObject, 'der');
11680 key = { key: der, format: 'der', type: 'pkcs1' };
11681 } else {
11682 key = RSAPublicKey.encode(keyObject, 'pem', {
11683 label: 'RSA PUBLIC KEY'
11684 });
11685 }
11686 try {
11687 return await verify.verify(key, s);
11688 } catch (err) {
11689 return false;
11690 }
11691}
11692
11693async function nodeEncrypt(data, n, e) {
11694 const { default: BN } = await Promise.resolve().then(function () { return bn$1; });
11695
11696 const keyObject = {
11697 modulus: new BN(n),
11698 publicExponent: new BN(e)
11699 };
11700 let key;
11701 if (typeof nodeCrypto$2.createPrivateKey !== 'undefined') {
11702 const der = RSAPublicKey.encode(keyObject, 'der');
11703 key = { key: der, format: 'der', type: 'pkcs1', padding: nodeCrypto$2.constants.RSA_PKCS1_PADDING };
11704 } else {
11705 const pem = RSAPublicKey.encode(keyObject, 'pem', {
11706 label: 'RSA PUBLIC KEY'
11707 });
11708 key = { key: pem, padding: nodeCrypto$2.constants.RSA_PKCS1_PADDING };
11709 }
11710 return new Uint8Array(nodeCrypto$2.publicEncrypt(key, data));
11711}
11712
11713async function bnEncrypt(data, n, e) {
11714 const BigInteger = await util.getBigInteger();
11715 n = new BigInteger(n);
11716 data = new BigInteger(await emeEncode(data, n.byteLength()));
11717 e = new BigInteger(e);
11718 if (data.gte(n)) {
11719 throw new Error('Message size cannot exceed modulus size');
11720 }
11721 return data.modExp(e, n).toUint8Array('be', n.byteLength());
11722}
11723
11724async function nodeDecrypt(data, n, e, d, p, q, u, randomPayload) {
11725 const { default: BN } = await Promise.resolve().then(function () { return bn$1; });
11726
11727 const pBNum = new BN(p);
11728 const qBNum = new BN(q);
11729 const dBNum = new BN(d);
11730 const dq = dBNum.mod(qBNum.subn(1)); // d mod (q-1)
11731 const dp = dBNum.mod(pBNum.subn(1)); // d mod (p-1)
11732 const keyObject = {
11733 version: 0,
11734 modulus: new BN(n),
11735 publicExponent: new BN(e),
11736 privateExponent: new BN(d),
11737 // switch p and q
11738 prime1: new BN(q),
11739 prime2: new BN(p),
11740 // switch dp and dq
11741 exponent1: dq,
11742 exponent2: dp,
11743 coefficient: new BN(u)
11744 };
11745 let key;
11746 if (typeof nodeCrypto$2.createPrivateKey !== 'undefined') {
11747 const der = RSAPrivateKey.encode(keyObject, 'der');
11748 key = { key: der, format: 'der' , type: 'pkcs1', padding: nodeCrypto$2.constants.RSA_PKCS1_PADDING };
11749 } else {
11750 const pem = RSAPrivateKey.encode(keyObject, 'pem', {
11751 label: 'RSA PRIVATE KEY'
11752 });
11753 key = { key: pem, padding: nodeCrypto$2.constants.RSA_PKCS1_PADDING };
11754 }
11755 try {
11756 return new Uint8Array(nodeCrypto$2.privateDecrypt(key, data));
11757 } catch (err) {
11758 if (randomPayload) {
11759 return randomPayload;
11760 }
11761 throw new Error('Decryption error');
11762 }
11763}
11764
11765async function bnDecrypt(data, n, e, d, p, q, u, randomPayload) {
11766 const BigInteger = await util.getBigInteger();
11767 data = new BigInteger(data);
11768 n = new BigInteger(n);
11769 e = new BigInteger(e);
11770 d = new BigInteger(d);
11771 p = new BigInteger(p);
11772 q = new BigInteger(q);
11773 u = new BigInteger(u);
11774 if (data.gte(n)) {
11775 throw new Error('Data too large.');
11776 }
11777 const dq = d.mod(q.dec()); // d mod (q-1)
11778 const dp = d.mod(p.dec()); // d mod (p-1)
11779
11780 const unblinder = (await getRandomBigInteger(new BigInteger(2), n)).mod(n);
11781 const blinder = unblinder.modInv(n).modExp(e, n);
11782 data = data.mul(blinder).mod(n);
11783
11784
11785 const mp = data.modExp(dp, p); // data**{d mod (q-1)} mod p
11786 const mq = data.modExp(dq, q); // data**{d mod (p-1)} mod q
11787 const h = u.mul(mq.sub(mp)).mod(q); // u * (mq-mp) mod q (operands already < q)
11788
11789 let result = h.mul(p).add(mp); // result < n due to relations above
11790
11791 result = result.mul(unblinder).mod(n);
11792
11793
11794 return emeDecode(result.toUint8Array('be', n.byteLength()), randomPayload);
11795}
11796
11797/** Convert Openpgp private key params to jwk key according to
11798 * @link https://tools.ietf.org/html/rfc7517
11799 * @param {String} hashAlgo
11800 * @param {Uint8Array} n
11801 * @param {Uint8Array} e
11802 * @param {Uint8Array} d
11803 * @param {Uint8Array} p
11804 * @param {Uint8Array} q
11805 * @param {Uint8Array} u
11806 */
11807async function privateToJWK(n, e, d, p, q, u) {
11808 const BigInteger = await util.getBigInteger();
11809 const pNum = new BigInteger(p);
11810 const qNum = new BigInteger(q);
11811 const dNum = new BigInteger(d);
11812
11813 let dq = dNum.mod(qNum.dec()); // d mod (q-1)
11814 let dp = dNum.mod(pNum.dec()); // d mod (p-1)
11815 dp = dp.toUint8Array();
11816 dq = dq.toUint8Array();
11817 return {
11818 kty: 'RSA',
11819 n: uint8ArrayToB64(n, true),
11820 e: uint8ArrayToB64(e, true),
11821 d: uint8ArrayToB64(d, true),
11822 // switch p and q
11823 p: uint8ArrayToB64(q, true),
11824 q: uint8ArrayToB64(p, true),
11825 // switch dp and dq
11826 dp: uint8ArrayToB64(dq, true),
11827 dq: uint8ArrayToB64(dp, true),
11828 qi: uint8ArrayToB64(u, true),
11829 ext: true
11830 };
11831}
11832
11833/** Convert Openpgp key public params to jwk key according to
11834 * @link https://tools.ietf.org/html/rfc7517
11835 * @param {String} hashAlgo
11836 * @param {Uint8Array} n
11837 * @param {Uint8Array} e
11838 */
11839function publicToJWK(n, e) {
11840 return {
11841 kty: 'RSA',
11842 n: uint8ArrayToB64(n, true),
11843 e: uint8ArrayToB64(e, true),
11844 ext: true
11845 };
11846}
11847
11848var rsa = /*#__PURE__*/Object.freeze({
11849 __proto__: null,
11850 sign: sign,
11851 verify: verify,
11852 encrypt: encrypt,
11853 decrypt: decrypt,
11854 generate: generate,
11855 validateParams: validateParams
11856});
11857
11858// GPG4Browsers - An OpenPGP implementation in javascript
11859
11860/**
11861 * ElGamal Encryption function
11862 * Note that in OpenPGP, the message needs to be padded with PKCS#1 (same as RSA)
11863 * @param {Uint8Array} data - To be padded and encrypted
11864 * @param {Uint8Array} p
11865 * @param {Uint8Array} g
11866 * @param {Uint8Array} y
11867 * @returns {Promise<{ c1: Uint8Array, c2: Uint8Array }>}
11868 * @async
11869 */
11870async function encrypt$1(data, p, g, y) {
11871 const BigInteger = await util.getBigInteger();
11872 p = new BigInteger(p);
11873 g = new BigInteger(g);
11874 y = new BigInteger(y);
11875
11876 const padded = await emeEncode(data, p.byteLength());
11877 const m = new BigInteger(padded);
11878
11879 // OpenPGP uses a "special" version of ElGamal where g is generator of the full group Z/pZ*
11880 // hence g has order p-1, and to avoid that k = 0 mod p-1, we need to pick k in [1, p-2]
11881 const k = await getRandomBigInteger(new BigInteger(1), p.dec());
11882 return {
11883 c1: g.modExp(k, p).toUint8Array(),
11884 c2: y.modExp(k, p).imul(m).imod(p).toUint8Array()
11885 };
11886}
11887
11888/**
11889 * ElGamal Encryption function
11890 * @param {Uint8Array} c1
11891 * @param {Uint8Array} c2
11892 * @param {Uint8Array} p
11893 * @param {Uint8Array} x
11894 * @param {Uint8Array} randomPayload - Data to return on unpadding error, instead of throwing
11895 * (needed for constant-time processing)
11896 * @returns {Promise<Uint8Array>} Unpadded message.
11897 * @throws {Error} on decryption error, unless `randomPayload` is given
11898 * @async
11899 */
11900async function decrypt$1(c1, c2, p, x, randomPayload) {
11901 const BigInteger = await util.getBigInteger();
11902 c1 = new BigInteger(c1);
11903 c2 = new BigInteger(c2);
11904 p = new BigInteger(p);
11905 x = new BigInteger(x);
11906
11907 const padded = c1.modExp(x, p).modInv(p).imul(c2).imod(p);
11908 return emeDecode(padded.toUint8Array('be', p.byteLength()), randomPayload);
11909}
11910
11911/**
11912 * Validate ElGamal parameters
11913 * @param {Uint8Array} p - ElGamal prime
11914 * @param {Uint8Array} g - ElGamal group generator
11915 * @param {Uint8Array} y - ElGamal public key
11916 * @param {Uint8Array} x - ElGamal private exponent
11917 * @returns {Promise<Boolean>} Whether params are valid.
11918 * @async
11919 */
11920async function validateParams$1(p, g, y, x) {
11921 const BigInteger = await util.getBigInteger();
11922 p = new BigInteger(p);
11923 g = new BigInteger(g);
11924 y = new BigInteger(y);
11925
11926 const one = new BigInteger(1);
11927 // Check that 1 < g < p
11928 if (g.lte(one) || g.gte(p)) {
11929 return false;
11930 }
11931
11932 // Expect p-1 to be large
11933 const pSize = new BigInteger(p.bitLength());
11934 const n1023 = new BigInteger(1023);
11935 if (pSize.lt(n1023)) {
11936 return false;
11937 }
11938
11939 /**
11940 * g should have order p-1
11941 * Check that g ** (p-1) = 1 mod p
11942 */
11943 if (!g.modExp(p.dec(), p).isOne()) {
11944 return false;
11945 }
11946
11947 /**
11948 * Since p-1 is not prime, g might have a smaller order that divides p-1
11949 * We want to make sure that the order is large enough to hinder a small subgroup attack
11950 *
11951 * We just check g**i != 1 for all i up to a threshold
11952 */
11953 let res = g;
11954 const i = new BigInteger(1);
11955 const threshold = new BigInteger(2).leftShift(new BigInteger(17)); // we want order > threshold
11956 while (i.lt(threshold)) {
11957 res = res.mul(g).imod(p);
11958 if (res.isOne()) {
11959 return false;
11960 }
11961 i.iinc();
11962 }
11963
11964 /**
11965 * Re-derive public key y' = g ** x mod p
11966 * Expect y == y'
11967 *
11968 * Blinded exponentiation computes g**{r(p-1) + x} to compare to y
11969 */
11970 x = new BigInteger(x);
11971 const two = new BigInteger(2);
11972 const r = await getRandomBigInteger(two.leftShift(pSize.dec()), two.leftShift(pSize)); // draw r of same size as p-1
11973 const rqx = p.dec().imul(r).iadd(x);
11974 if (!y.equal(g.modExp(rqx, p))) {
11975 return false;
11976 }
11977
11978 return true;
11979}
11980
11981var elgamal = /*#__PURE__*/Object.freeze({
11982 __proto__: null,
11983 encrypt: encrypt$1,
11984 decrypt: decrypt$1,
11985 validateParams: validateParams$1
11986});
11987
11988// OpenPGP.js - An OpenPGP implementation in javascript
11989
11990class OID {
11991 constructor(oid) {
11992 if (oid instanceof OID) {
11993 this.oid = oid.oid;
11994 } else if (util.isArray(oid) ||
11995 util.isUint8Array(oid)) {
11996 oid = new Uint8Array(oid);
11997 if (oid[0] === 0x06) { // DER encoded oid byte array
11998 if (oid[1] !== oid.length - 2) {
11999 throw new Error('Length mismatch in DER encoded oid');
12000 }
12001 oid = oid.subarray(2);
12002 }
12003 this.oid = oid;
12004 } else {
12005 this.oid = '';
12006 }
12007 }
12008
12009 /**
12010 * Method to read an OID object
12011 * @param {Uint8Array} input - Where to read the OID from
12012 * @returns {Number} Number of read bytes.
12013 */
12014 read(input) {
12015 if (input.length >= 1) {
12016 const length = input[0];
12017 if (input.length >= 1 + length) {
12018 this.oid = input.subarray(1, 1 + length);
12019 return 1 + this.oid.length;
12020 }
12021 }
12022 throw new Error('Invalid oid');
12023 }
12024
12025 /**
12026 * Serialize an OID object
12027 * @returns {Uint8Array} Array with the serialized value the OID.
12028 */
12029 write() {
12030 return util.concatUint8Array([new Uint8Array([this.oid.length]), this.oid]);
12031 }
12032
12033 /**
12034 * Serialize an OID object as a hex string
12035 * @returns {string} String with the hex value of the OID.
12036 */
12037 toHex() {
12038 return util.uint8ArrayToHex(this.oid);
12039 }
12040
12041 /**
12042 * If a known curve object identifier, return the canonical name of the curve
12043 * @returns {string} String with the canonical name of the curve.
12044 */
12045 getName() {
12046 const hex = this.toHex();
12047 if (enums.curve[hex]) {
12048 return enums.write(enums.curve, hex);
12049 } else {
12050 throw new Error('Unknown curve object identifier.');
12051 }
12052 }
12053}
12054
12055// OpenPGP.js - An OpenPGP implementation in javascript
12056
12057function keyFromPrivate(indutnyCurve, priv) {
12058 const keyPair = indutnyCurve.keyPair({ priv: priv });
12059 return keyPair;
12060}
12061
12062function keyFromPublic(indutnyCurve, pub) {
12063 const keyPair = indutnyCurve.keyPair({ pub: pub });
12064 if (keyPair.validate().result !== true) {
12065 throw new Error('Invalid elliptic public key');
12066 }
12067 return keyPair;
12068}
12069
12070async function getIndutnyCurve(name) {
12071 if (!defaultConfig.useIndutnyElliptic) {
12072 throw new Error('This curve is only supported in the full build of OpenPGP.js');
12073 }
12074 const { default: elliptic } = await Promise.resolve().then(function () { return elliptic$1; });
12075 return new elliptic.ec(name);
12076}
12077
12078// GPG4Browsers - An OpenPGP implementation in javascript
12079
12080function readSimpleLength(bytes) {
12081 let len = 0;
12082 let offset;
12083 const type = bytes[0];
12084
12085
12086 if (type < 192) {
12087 [len] = bytes;
12088 offset = 1;
12089 } else if (type < 255) {
12090 len = ((bytes[0] - 192) << 8) + (bytes[1]) + 192;
12091 offset = 2;
12092 } else if (type === 255) {
12093 len = util.readNumber(bytes.subarray(1, 1 + 4));
12094 offset = 5;
12095 }
12096
12097 return {
12098 len: len,
12099 offset: offset
12100 };
12101}
12102
12103/**
12104 * Encodes a given integer of length to the openpgp length specifier to a
12105 * string
12106 *
12107 * @param {Integer} length - The length to encode
12108 * @returns {Uint8Array} String with openpgp length representation.
12109 */
12110function writeSimpleLength(length) {
12111 if (length < 192) {
12112 return new Uint8Array([length]);
12113 } else if (length > 191 && length < 8384) {
12114 /*
12115 * let a = (total data packet length) - 192 let bc = two octet
12116 * representation of a let d = b + 192
12117 */
12118 return new Uint8Array([((length - 192) >> 8) + 192, (length - 192) & 0xFF]);
12119 }
12120 return util.concatUint8Array([new Uint8Array([255]), util.writeNumber(length, 4)]);
12121}
12122
12123function writePartialLength(power) {
12124 if (power < 0 || power > 30) {
12125 throw new Error('Partial Length power must be between 1 and 30');
12126 }
12127 return new Uint8Array([224 + power]);
12128}
12129
12130function writeTag(tag_type) {
12131 /* we're only generating v4 packet headers here */
12132 return new Uint8Array([0xC0 | tag_type]);
12133}
12134
12135/**
12136 * Writes a packet header version 4 with the given tag_type and length to a
12137 * string
12138 *
12139 * @param {Integer} tag_type - Tag type
12140 * @param {Integer} length - Length of the payload
12141 * @returns {String} String of the header.
12142 */
12143function writeHeader(tag_type, length) {
12144 /* we're only generating v4 packet headers here */
12145 return util.concatUint8Array([writeTag(tag_type), writeSimpleLength(length)]);
12146}
12147
12148/**
12149 * Whether the packet type supports partial lengths per RFC4880
12150 * @param {Integer} tag - Tag type
12151 * @returns {Boolean} String of the header.
12152 */
12153function supportsStreaming(tag) {
12154 return [
12155 enums.packet.literalData,
12156 enums.packet.compressedData,
12157 enums.packet.symmetricallyEncryptedData,
12158 enums.packet.symEncryptedIntegrityProtectedData,
12159 enums.packet.aeadEncryptedData
12160 ].includes(tag);
12161}
12162
12163/**
12164 * Generic static Packet Parser function
12165 *
12166 * @param {Uint8Array | ReadableStream<Uint8Array>} input - Input stream as string
12167 * @param {Function} callback - Function to call with the parsed packet
12168 * @returns {Boolean} Returns false if the stream was empty and parsing is done, and true otherwise.
12169 */
12170async function readPackets(input, callback) {
12171 const reader = getReader(input);
12172 let writer;
12173 let callbackReturned;
12174 try {
12175 const peekedBytes = await reader.peekBytes(2);
12176 // some sanity checks
12177 if (!peekedBytes || peekedBytes.length < 2 || (peekedBytes[0] & 0x80) === 0) {
12178 throw new Error('Error during parsing. This message / key probably does not conform to a valid OpenPGP format.');
12179 }
12180 const headerByte = await reader.readByte();
12181 let tag = -1;
12182 let format = -1;
12183 let packetLength;
12184
12185 format = 0; // 0 = old format; 1 = new format
12186 if ((headerByte & 0x40) !== 0) {
12187 format = 1;
12188 }
12189
12190 let packetLengthType;
12191 if (format) {
12192 // new format header
12193 tag = headerByte & 0x3F; // bit 5-0
12194 } else {
12195 // old format header
12196 tag = (headerByte & 0x3F) >> 2; // bit 5-2
12197 packetLengthType = headerByte & 0x03; // bit 1-0
12198 }
12199
12200 const packetSupportsStreaming = supportsStreaming(tag);
12201 let packet = null;
12202 if (packetSupportsStreaming) {
12203 if (util.isStream(input) === 'array') {
12204 const arrayStream = new ArrayStream();
12205 writer = getWriter(arrayStream);
12206 packet = arrayStream;
12207 } else {
12208 const transform = new TransformStream();
12209 writer = getWriter(transform.writable);
12210 packet = transform.readable;
12211 }
12212 callbackReturned = callback({ tag, packet });
12213 } else {
12214 packet = [];
12215 }
12216
12217 let wasPartialLength;
12218 do {
12219 if (!format) {
12220 // 4.2.1. Old Format Packet Lengths
12221 switch (packetLengthType) {
12222 case 0:
12223 // The packet has a one-octet length. The header is 2 octets
12224 // long.
12225 packetLength = await reader.readByte();
12226 break;
12227 case 1:
12228 // The packet has a two-octet length. The header is 3 octets
12229 // long.
12230 packetLength = (await reader.readByte() << 8) | await reader.readByte();
12231 break;
12232 case 2:
12233 // The packet has a four-octet length. The header is 5
12234 // octets long.
12235 packetLength = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
12236 8) | await reader.readByte();
12237 break;
12238 default:
12239 // 3 - The packet is of indeterminate length. The header is 1
12240 // octet long, and the implementation must determine how long
12241 // the packet is. If the packet is in a file, this means that
12242 // the packet extends until the end of the file. In general,
12243 // an implementation SHOULD NOT use indeterminate-length
12244 // packets except where the end of the data will be clear
12245 // from the context, and even then it is better to use a
12246 // definite length, or a new format header. The new format
12247 // headers described below have a mechanism for precisely
12248 // encoding data of indeterminate length.
12249 packetLength = Infinity;
12250 break;
12251 }
12252 } else { // 4.2.2. New Format Packet Lengths
12253 // 4.2.2.1. One-Octet Lengths
12254 const lengthByte = await reader.readByte();
12255 wasPartialLength = false;
12256 if (lengthByte < 192) {
12257 packetLength = lengthByte;
12258 // 4.2.2.2. Two-Octet Lengths
12259 } else if (lengthByte >= 192 && lengthByte < 224) {
12260 packetLength = ((lengthByte - 192) << 8) + (await reader.readByte()) + 192;
12261 // 4.2.2.4. Partial Body Lengths
12262 } else if (lengthByte > 223 && lengthByte < 255) {
12263 packetLength = 1 << (lengthByte & 0x1F);
12264 wasPartialLength = true;
12265 if (!packetSupportsStreaming) {
12266 throw new TypeError('This packet type does not support partial lengths.');
12267 }
12268 // 4.2.2.3. Five-Octet Lengths
12269 } else {
12270 packetLength = (await reader.readByte() << 24) | (await reader.readByte() << 16) | (await reader.readByte() <<
12271 8) | await reader.readByte();
12272 }
12273 }
12274 if (packetLength > 0) {
12275 let bytesRead = 0;
12276 while (true) {
12277 if (writer) await writer.ready;
12278 const { done, value } = await reader.read();
12279 if (done) {
12280 if (packetLength === Infinity) break;
12281 throw new Error('Unexpected end of packet');
12282 }
12283 const chunk = packetLength === Infinity ? value : value.subarray(0, packetLength - bytesRead);
12284 if (writer) await writer.write(chunk);
12285 else packet.push(chunk);
12286 bytesRead += value.length;
12287 if (bytesRead >= packetLength) {
12288 reader.unshift(value.subarray(packetLength - bytesRead + value.length));
12289 break;
12290 }
12291 }
12292 }
12293 } while (wasPartialLength);
12294
12295 // If this was not a packet that "supports streaming", we peek to check
12296 // whether it is the last packet in the message. We peek 2 bytes instead
12297 // of 1 because the beginning of this function also peeks 2 bytes, and we
12298 // want to cut a `subarray` of the correct length into `web-stream-tools`'
12299 // `externalBuffer` as a tiny optimization here.
12300 //
12301 // If it *was* a streaming packet (i.e. the data packets), we peek at the
12302 // entire remainder of the stream, in order to forward errors in the
12303 // remainder of the stream to the packet data. (Note that this means we
12304 // read/peek at all signature packets before closing the literal data
12305 // packet, for example.) This forwards MDC errors to the literal data
12306 // stream, for example, so that they don't get lost / forgotten on
12307 // decryptedMessage.packets.stream, which we never look at.
12308 //
12309 // An example of what we do when stream-parsing a message containing
12310 // [ one-pass signature packet, literal data packet, signature packet ]:
12311 // 1. Read the one-pass signature packet
12312 // 2. Peek 2 bytes of the literal data packet
12313 // 3. Parse the one-pass signature packet
12314 //
12315 // 4. Read the literal data packet, simultaneously stream-parsing it
12316 // 5. Peek until the end of the message
12317 // 6. Finish parsing the literal data packet
12318 //
12319 // 7. Read the signature packet again (we already peeked at it in step 5)
12320 // 8. Peek at the end of the stream again (`peekBytes` returns undefined)
12321 // 9. Parse the signature packet
12322 //
12323 // Note that this means that if there's an error in the very end of the
12324 // stream, such as an MDC error, we throw in step 5 instead of in step 8
12325 // (or never), which is the point of this exercise.
12326 const nextPacket = await reader.peekBytes(packetSupportsStreaming ? Infinity : 2);
12327 if (writer) {
12328 await writer.ready;
12329 await writer.close();
12330 } else {
12331 packet = util.concatUint8Array(packet);
12332 await callback({ tag, packet });
12333 }
12334 return !nextPacket || !nextPacket.length;
12335 } catch (e) {
12336 if (writer) {
12337 await writer.abort(e);
12338 return true;
12339 } else {
12340 throw e;
12341 }
12342 } finally {
12343 if (writer) {
12344 await callbackReturned;
12345 }
12346 reader.releaseLock();
12347 }
12348}
12349
12350class UnsupportedError extends Error {
12351 constructor(...params) {
12352 super(...params);
12353
12354 if (Error.captureStackTrace) {
12355 Error.captureStackTrace(this, UnsupportedError);
12356 }
12357
12358 this.name = 'UnsupportedError';
12359 }
12360}
12361
12362class UnparseablePacket {
12363 constructor(tag, rawContent) {
12364 this.tag = tag;
12365 this.rawContent = rawContent;
12366 }
12367
12368 write() {
12369 return this.rawContent;
12370 }
12371}
12372
12373// OpenPGP.js - An OpenPGP implementation in javascript
12374
12375const webCrypto$2 = util.getWebCrypto();
12376const nodeCrypto$3 = util.getNodeCrypto();
12377
12378const webCurves = {
12379 'p256': 'P-256',
12380 'p384': 'P-384',
12381 'p521': 'P-521'
12382};
12383const knownCurves = nodeCrypto$3 ? nodeCrypto$3.getCurves() : [];
12384const nodeCurves = nodeCrypto$3 ? {
12385 secp256k1: knownCurves.includes('secp256k1') ? 'secp256k1' : undefined,
12386 p256: knownCurves.includes('prime256v1') ? 'prime256v1' : undefined,
12387 p384: knownCurves.includes('secp384r1') ? 'secp384r1' : undefined,
12388 p521: knownCurves.includes('secp521r1') ? 'secp521r1' : undefined,
12389 ed25519: knownCurves.includes('ED25519') ? 'ED25519' : undefined,
12390 curve25519: knownCurves.includes('X25519') ? 'X25519' : undefined,
12391 brainpoolP256r1: knownCurves.includes('brainpoolP256r1') ? 'brainpoolP256r1' : undefined,
12392 brainpoolP384r1: knownCurves.includes('brainpoolP384r1') ? 'brainpoolP384r1' : undefined,
12393 brainpoolP512r1: knownCurves.includes('brainpoolP512r1') ? 'brainpoolP512r1' : undefined
12394} : {};
12395
12396const curves = {
12397 p256: {
12398 oid: [0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07],
12399 keyType: enums.publicKey.ecdsa,
12400 hash: enums.hash.sha256,
12401 cipher: enums.symmetric.aes128,
12402 node: nodeCurves.p256,
12403 web: webCurves.p256,
12404 payloadSize: 32,
12405 sharedSize: 256
12406 },
12407 p384: {
12408 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x22],
12409 keyType: enums.publicKey.ecdsa,
12410 hash: enums.hash.sha384,
12411 cipher: enums.symmetric.aes192,
12412 node: nodeCurves.p384,
12413 web: webCurves.p384,
12414 payloadSize: 48,
12415 sharedSize: 384
12416 },
12417 p521: {
12418 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23],
12419 keyType: enums.publicKey.ecdsa,
12420 hash: enums.hash.sha512,
12421 cipher: enums.symmetric.aes256,
12422 node: nodeCurves.p521,
12423 web: webCurves.p521,
12424 payloadSize: 66,
12425 sharedSize: 528
12426 },
12427 secp256k1: {
12428 oid: [0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x0A],
12429 keyType: enums.publicKey.ecdsa,
12430 hash: enums.hash.sha256,
12431 cipher: enums.symmetric.aes128,
12432 node: nodeCurves.secp256k1,
12433 payloadSize: 32
12434 },
12435 ed25519: {
12436 oid: [0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0F, 0x01],
12437 keyType: enums.publicKey.eddsa,
12438 hash: enums.hash.sha512,
12439 node: false, // nodeCurves.ed25519 TODO
12440 payloadSize: 32
12441 },
12442 curve25519: {
12443 oid: [0x06, 0x0A, 0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01],
12444 keyType: enums.publicKey.ecdh,
12445 hash: enums.hash.sha256,
12446 cipher: enums.symmetric.aes128,
12447 node: false, // nodeCurves.curve25519 TODO
12448 payloadSize: 32
12449 },
12450 brainpoolP256r1: {
12451 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07],
12452 keyType: enums.publicKey.ecdsa,
12453 hash: enums.hash.sha256,
12454 cipher: enums.symmetric.aes128,
12455 node: nodeCurves.brainpoolP256r1,
12456 payloadSize: 32
12457 },
12458 brainpoolP384r1: {
12459 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B],
12460 keyType: enums.publicKey.ecdsa,
12461 hash: enums.hash.sha384,
12462 cipher: enums.symmetric.aes192,
12463 node: nodeCurves.brainpoolP384r1,
12464 payloadSize: 48
12465 },
12466 brainpoolP512r1: {
12467 oid: [0x06, 0x09, 0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D],
12468 keyType: enums.publicKey.ecdsa,
12469 hash: enums.hash.sha512,
12470 cipher: enums.symmetric.aes256,
12471 node: nodeCurves.brainpoolP512r1,
12472 payloadSize: 64
12473 }
12474};
12475
12476class Curve {
12477 constructor(oidOrName, params) {
12478 try {
12479 if (util.isArray(oidOrName) ||
12480 util.isUint8Array(oidOrName)) {
12481 // by oid byte array
12482 oidOrName = new OID(oidOrName);
12483 }
12484 if (oidOrName instanceof OID) {
12485 // by curve OID
12486 oidOrName = oidOrName.getName();
12487 }
12488 // by curve name or oid string
12489 this.name = enums.write(enums.curve, oidOrName);
12490 } catch (err) {
12491 throw new UnsupportedError('Unknown curve');
12492 }
12493 params = params || curves[this.name];
12494
12495 this.keyType = params.keyType;
12496
12497 this.oid = params.oid;
12498 this.hash = params.hash;
12499 this.cipher = params.cipher;
12500 this.node = params.node && curves[this.name];
12501 this.web = params.web && curves[this.name];
12502 this.payloadSize = params.payloadSize;
12503 if (this.web && util.getWebCrypto()) {
12504 this.type = 'web';
12505 } else if (this.node && util.getNodeCrypto()) {
12506 this.type = 'node';
12507 } else if (this.name === 'curve25519') {
12508 this.type = 'curve25519';
12509 } else if (this.name === 'ed25519') {
12510 this.type = 'ed25519';
12511 }
12512 }
12513
12514 async genKeyPair() {
12515 let keyPair;
12516 switch (this.type) {
12517 case 'web':
12518 try {
12519 return await webGenKeyPair(this.name);
12520 } catch (err) {
12521 util.printDebugError('Browser did not support generating ec key ' + err.message);
12522 break;
12523 }
12524 case 'node':
12525 return nodeGenKeyPair(this.name);
12526 case 'curve25519': {
12527 const privateKey = await getRandomBytes(32);
12528 privateKey[0] = (privateKey[0] & 127) | 64;
12529 privateKey[31] &= 248;
12530 const secretKey = privateKey.slice().reverse();
12531 keyPair = naclFastLight.box.keyPair.fromSecretKey(secretKey);
12532 const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]);
12533 return { publicKey, privateKey };
12534 }
12535 case 'ed25519': {
12536 const privateKey = await getRandomBytes(32);
12537 const keyPair = naclFastLight.sign.keyPair.fromSeed(privateKey);
12538 const publicKey = util.concatUint8Array([new Uint8Array([0x40]), keyPair.publicKey]);
12539 return { publicKey, privateKey };
12540 }
12541 }
12542 const indutnyCurve = await getIndutnyCurve(this.name);
12543 keyPair = await indutnyCurve.genKeyPair({
12544 entropy: util.uint8ArrayToString(await getRandomBytes(32))
12545 });
12546 return { publicKey: new Uint8Array(keyPair.getPublic('array', false)), privateKey: keyPair.getPrivate().toArrayLike(Uint8Array) };
12547 }
12548}
12549
12550async function generate$1(curve) {
12551 const BigInteger = await util.getBigInteger();
12552
12553 curve = new Curve(curve);
12554 const keyPair = await curve.genKeyPair();
12555 const Q = new BigInteger(keyPair.publicKey).toUint8Array();
12556 const secret = new BigInteger(keyPair.privateKey).toUint8Array('be', curve.payloadSize);
12557 return {
12558 oid: curve.oid,
12559 Q,
12560 secret,
12561 hash: curve.hash,
12562 cipher: curve.cipher
12563 };
12564}
12565
12566/**
12567 * Get preferred hash algo to use with the given curve
12568 * @param {module:type/oid} oid - curve oid
12569 * @returns {enums.hash} hash algorithm
12570 */
12571function getPreferredHashAlgo(oid) {
12572 return curves[enums.write(enums.curve, oid.toHex())].hash;
12573}
12574
12575/**
12576 * Validate ECDH and ECDSA parameters
12577 * Not suitable for EdDSA (different secret key format)
12578 * @param {module:enums.publicKey} algo - EC algorithm, to filter supported curves
12579 * @param {module:type/oid} oid - EC object identifier
12580 * @param {Uint8Array} Q - EC public point
12581 * @param {Uint8Array} d - EC secret scalar
12582 * @returns {Promise<Boolean>} Whether params are valid.
12583 * @async
12584 */
12585async function validateStandardParams(algo, oid, Q, d) {
12586 const supportedCurves = {
12587 p256: true,
12588 p384: true,
12589 p521: true,
12590 secp256k1: true,
12591 curve25519: algo === enums.publicKey.ecdh,
12592 brainpoolP256r1: true,
12593 brainpoolP384r1: true,
12594 brainpoolP512r1: true
12595 };
12596
12597 // Check whether the given curve is supported
12598 const curveName = oid.getName();
12599 if (!supportedCurves[curveName]) {
12600 return false;
12601 }
12602
12603 if (curveName === 'curve25519') {
12604 d = d.slice().reverse();
12605 // Re-derive public point Q'
12606 const { publicKey } = naclFastLight.box.keyPair.fromSecretKey(d);
12607
12608 Q = new Uint8Array(Q);
12609 const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
12610 if (!util.equalsUint8Array(dG, Q)) {
12611 return false;
12612 }
12613
12614 return true;
12615 }
12616
12617 const curve = await getIndutnyCurve(curveName);
12618 try {
12619 // Parse Q and check that it is on the curve but not at infinity
12620 Q = keyFromPublic(curve, Q).getPublic();
12621 } catch (validationErrors) {
12622 return false;
12623 }
12624
12625 /**
12626 * Re-derive public point Q' = dG from private key
12627 * Expect Q == Q'
12628 */
12629 const dG = keyFromPrivate(curve, d).getPublic();
12630 if (!dG.eq(Q)) {
12631 return false;
12632 }
12633
12634 return true;
12635}
12636
12637//////////////////////////
12638// //
12639// Helper functions //
12640// //
12641//////////////////////////
12642
12643
12644async function webGenKeyPair(name) {
12645 // Note: keys generated with ECDSA and ECDH are structurally equivalent
12646 const webCryptoKey = await webCrypto$2.generateKey({ name: 'ECDSA', namedCurve: webCurves[name] }, true, ['sign', 'verify']);
12647
12648 const privateKey = await webCrypto$2.exportKey('jwk', webCryptoKey.privateKey);
12649 const publicKey = await webCrypto$2.exportKey('jwk', webCryptoKey.publicKey);
12650
12651 return {
12652 publicKey: jwkToRawPublic(publicKey),
12653 privateKey: b64ToUint8Array(privateKey.d)
12654 };
12655}
12656
12657async function nodeGenKeyPair(name) {
12658 // Note: ECDSA and ECDH key generation is structurally equivalent
12659 const ecdh = nodeCrypto$3.createECDH(nodeCurves[name]);
12660 await ecdh.generateKeys();
12661 return {
12662 publicKey: new Uint8Array(ecdh.getPublicKey()),
12663 privateKey: new Uint8Array(ecdh.getPrivateKey())
12664 };
12665}
12666
12667//////////////////////////
12668// //
12669// Helper functions //
12670// //
12671//////////////////////////
12672
12673/**
12674 * @param {JsonWebKey} jwk - key for conversion
12675 *
12676 * @returns {Uint8Array} Raw public key.
12677 */
12678function jwkToRawPublic(jwk) {
12679 const bufX = b64ToUint8Array(jwk.x);
12680 const bufY = b64ToUint8Array(jwk.y);
12681 const publicKey = new Uint8Array(bufX.length + bufY.length + 1);
12682 publicKey[0] = 0x04;
12683 publicKey.set(bufX, 1);
12684 publicKey.set(bufY, bufX.length + 1);
12685 return publicKey;
12686}
12687
12688/**
12689 * @param {Integer} payloadSize - ec payload size
12690 * @param {String} name - curve name
12691 * @param {Uint8Array} publicKey - public key
12692 *
12693 * @returns {JsonWebKey} Public key in jwk format.
12694 */
12695function rawPublicToJWK(payloadSize, name, publicKey) {
12696 const len = payloadSize;
12697 const bufX = publicKey.slice(1, len + 1);
12698 const bufY = publicKey.slice(len + 1, len * 2 + 1);
12699 // https://www.rfc-editor.org/rfc/rfc7518.txt
12700 const jwk = {
12701 kty: 'EC',
12702 crv: name,
12703 x: uint8ArrayToB64(bufX, true),
12704 y: uint8ArrayToB64(bufY, true),
12705 ext: true
12706 };
12707 return jwk;
12708}
12709
12710/**
12711 * @param {Integer} payloadSize - ec payload size
12712 * @param {String} name - curve name
12713 * @param {Uint8Array} publicKey - public key
12714 * @param {Uint8Array} privateKey - private key
12715 *
12716 * @returns {JsonWebKey} Private key in jwk format.
12717 */
12718function privateToJWK$1(payloadSize, name, publicKey, privateKey) {
12719 const jwk = rawPublicToJWK(payloadSize, name, publicKey);
12720 jwk.d = uint8ArrayToB64(privateKey, true);
12721 return jwk;
12722}
12723
12724const webCrypto$3 = util.getWebCrypto();
12725const nodeCrypto$4 = util.getNodeCrypto();
12726
12727/**
12728 * Sign a message using the provided key
12729 * @param {module:type/oid} oid - Elliptic curve object identifier
12730 * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign
12731 * @param {Uint8Array} message - Message to sign
12732 * @param {Uint8Array} publicKey - Public key
12733 * @param {Uint8Array} privateKey - Private key used to sign the message
12734 * @param {Uint8Array} hashed - The hashed message
12735 * @returns {Promise<{
12736 * r: Uint8Array,
12737 * s: Uint8Array
12738 * }>} Signature of the message
12739 * @async
12740 */
12741async function sign$1(oid, hashAlgo, message, publicKey, privateKey, hashed) {
12742 const curve = new Curve(oid);
12743 if (message && !util.isStream(message)) {
12744 const keyPair = { publicKey, privateKey };
12745 switch (curve.type) {
12746 case 'web': {
12747 // If browser doesn't support a curve, we'll catch it
12748 try {
12749 // Need to await to make sure browser succeeds
12750 return await webSign$1(curve, hashAlgo, message, keyPair);
12751 } catch (err) {
12752 // We do not fallback if the error is related to key integrity
12753 // Unfortunaley Safari does not support p521 and throws a DataError when using it
12754 // So we need to always fallback for that curve
12755 if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) {
12756 throw err;
12757 }
12758 util.printDebugError('Browser did not support signing: ' + err.message);
12759 }
12760 break;
12761 }
12762 case 'node': {
12763 const signature = await nodeSign$1(curve, hashAlgo, message, keyPair);
12764 return {
12765 r: signature.r.toArrayLike(Uint8Array),
12766 s: signature.s.toArrayLike(Uint8Array)
12767 };
12768 }
12769 }
12770 }
12771 return ellipticSign(curve, hashed, privateKey);
12772}
12773
12774/**
12775 * Verifies if a signature is valid for a message
12776 * @param {module:type/oid} oid - Elliptic curve object identifier
12777 * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
12778 * @param {{r: Uint8Array,
12779 s: Uint8Array}} signature Signature to verify
12780 * @param {Uint8Array} message - Message to verify
12781 * @param {Uint8Array} publicKey - Public key used to verify the message
12782 * @param {Uint8Array} hashed - The hashed message
12783 * @returns {Boolean}
12784 * @async
12785 */
12786async function verify$1(oid, hashAlgo, signature, message, publicKey, hashed) {
12787 const curve = new Curve(oid);
12788 if (message && !util.isStream(message)) {
12789 switch (curve.type) {
12790 case 'web':
12791 try {
12792 // Need to await to make sure browser succeeds
12793 return await webVerify$1(curve, hashAlgo, signature, message, publicKey);
12794 } catch (err) {
12795 // We do not fallback if the error is related to key integrity
12796 // Unfortunately Safari does not support p521 and throws a DataError when using it
12797 // So we need to always fallback for that curve
12798 if (curve.name !== 'p521' && (err.name === 'DataError' || err.name === 'OperationError')) {
12799 throw err;
12800 }
12801 util.printDebugError('Browser did not support verifying: ' + err.message);
12802 }
12803 break;
12804 case 'node':
12805 return nodeVerify$1(curve, hashAlgo, signature, message, publicKey);
12806 }
12807 }
12808 const digest = (typeof hashAlgo === 'undefined') ? message : hashed;
12809 return ellipticVerify(curve, signature, digest, publicKey);
12810}
12811
12812/**
12813 * Validate ECDSA parameters
12814 * @param {module:type/oid} oid - Elliptic curve object identifier
12815 * @param {Uint8Array} Q - ECDSA public point
12816 * @param {Uint8Array} d - ECDSA secret scalar
12817 * @returns {Promise<Boolean>} Whether params are valid.
12818 * @async
12819 */
12820async function validateParams$2(oid, Q, d) {
12821 const curve = new Curve(oid);
12822 // Reject curves x25519 and ed25519
12823 if (curve.keyType !== enums.publicKey.ecdsa) {
12824 return false;
12825 }
12826
12827 // To speed up the validation, we try to use node- or webcrypto when available
12828 // and sign + verify a random message
12829 switch (curve.type) {
12830 case 'web':
12831 case 'node': {
12832 const message = await getRandomBytes(8);
12833 const hashAlgo = enums.hash.sha256;
12834 const hashed = await hash.digest(hashAlgo, message);
12835 try {
12836 const signature = await sign$1(oid, hashAlgo, message, Q, d, hashed);
12837 return await verify$1(oid, hashAlgo, signature, message, Q, hashed);
12838 } catch (err) {
12839 return false;
12840 }
12841 }
12842 default:
12843 return validateStandardParams(enums.publicKey.ecdsa, oid, Q, d);
12844 }
12845}
12846
12847
12848//////////////////////////
12849// //
12850// Helper functions //
12851// //
12852//////////////////////////
12853
12854async function ellipticSign(curve, hashed, privateKey) {
12855 const indutnyCurve = await getIndutnyCurve(curve.name);
12856 const key = keyFromPrivate(indutnyCurve, privateKey);
12857 const signature = key.sign(hashed);
12858 return {
12859 r: signature.r.toArrayLike(Uint8Array),
12860 s: signature.s.toArrayLike(Uint8Array)
12861 };
12862}
12863
12864async function ellipticVerify(curve, signature, digest, publicKey) {
12865 const indutnyCurve = await getIndutnyCurve(curve.name);
12866 const key = keyFromPublic(indutnyCurve, publicKey);
12867 return key.verify(digest, signature);
12868}
12869
12870async function webSign$1(curve, hashAlgo, message, keyPair) {
12871 const len = curve.payloadSize;
12872 const jwk = privateToJWK$1(curve.payloadSize, webCurves[curve.name], keyPair.publicKey, keyPair.privateKey);
12873 const key = await webCrypto$3.importKey(
12874 'jwk',
12875 jwk,
12876 {
12877 'name': 'ECDSA',
12878 'namedCurve': webCurves[curve.name],
12879 'hash': { name: enums.read(enums.webHash, curve.hash) }
12880 },
12881 false,
12882 ['sign']
12883 );
12884
12885 const signature = new Uint8Array(await webCrypto$3.sign(
12886 {
12887 'name': 'ECDSA',
12888 'namedCurve': webCurves[curve.name],
12889 'hash': { name: enums.read(enums.webHash, hashAlgo) }
12890 },
12891 key,
12892 message
12893 ));
12894
12895 return {
12896 r: signature.slice(0, len),
12897 s: signature.slice(len, len << 1)
12898 };
12899}
12900
12901async function webVerify$1(curve, hashAlgo, { r, s }, message, publicKey) {
12902 const jwk = rawPublicToJWK(curve.payloadSize, webCurves[curve.name], publicKey);
12903 const key = await webCrypto$3.importKey(
12904 'jwk',
12905 jwk,
12906 {
12907 'name': 'ECDSA',
12908 'namedCurve': webCurves[curve.name],
12909 'hash': { name: enums.read(enums.webHash, curve.hash) }
12910 },
12911 false,
12912 ['verify']
12913 );
12914
12915 const signature = util.concatUint8Array([r, s]).buffer;
12916
12917 return webCrypto$3.verify(
12918 {
12919 'name': 'ECDSA',
12920 'namedCurve': webCurves[curve.name],
12921 'hash': { name: enums.read(enums.webHash, hashAlgo) }
12922 },
12923 key,
12924 signature,
12925 message
12926 );
12927}
12928
12929async function nodeSign$1(curve, hashAlgo, message, keyPair) {
12930 const sign = nodeCrypto$4.createSign(enums.read(enums.hash, hashAlgo));
12931 sign.write(message);
12932 sign.end();
12933 const key = ECPrivateKey.encode({
12934 version: 1,
12935 parameters: curve.oid,
12936 privateKey: Array.from(keyPair.privateKey),
12937 publicKey: { unused: 0, data: Array.from(keyPair.publicKey) }
12938 }, 'pem', {
12939 label: 'EC PRIVATE KEY'
12940 });
12941
12942 return ECDSASignature.decode(sign.sign(key), 'der');
12943}
12944
12945async function nodeVerify$1(curve, hashAlgo, { r, s }, message, publicKey) {
12946 const { default: BN } = await Promise.resolve().then(function () { return bn$1; });
12947
12948 const verify = nodeCrypto$4.createVerify(enums.read(enums.hash, hashAlgo));
12949 verify.write(message);
12950 verify.end();
12951 const key = SubjectPublicKeyInfo.encode({
12952 algorithm: {
12953 algorithm: [1, 2, 840, 10045, 2, 1],
12954 parameters: curve.oid
12955 },
12956 subjectPublicKey: { unused: 0, data: Array.from(publicKey) }
12957 }, 'pem', {
12958 label: 'PUBLIC KEY'
12959 });
12960 const signature = ECDSASignature.encode({
12961 r: new BN(r), s: new BN(s)
12962 }, 'der');
12963
12964 try {
12965 return verify.verify(key, signature);
12966 } catch (err) {
12967 return false;
12968 }
12969}
12970
12971// Originally written by Owen Smith https://github.com/omsmith
12972// Adapted on Feb 2018 from https://github.com/Brightspace/node-jwk-to-pem/
12973
12974/* eslint-disable no-invalid-this */
12975
12976const asn1$1 = nodeCrypto$4 ? asn1$2 : undefined;
12977
12978const ECDSASignature = nodeCrypto$4 ?
12979 asn1$1.define('ECDSASignature', function() {
12980 this.seq().obj(
12981 this.key('r').int(),
12982 this.key('s').int()
12983 );
12984 }) : undefined;
12985
12986const ECPrivateKey = nodeCrypto$4 ?
12987 asn1$1.define('ECPrivateKey', function() {
12988 this.seq().obj(
12989 this.key('version').int(),
12990 this.key('privateKey').octstr(),
12991 this.key('parameters').explicit(0).optional().any(),
12992 this.key('publicKey').explicit(1).optional().bitstr()
12993 );
12994 }) : undefined;
12995
12996const AlgorithmIdentifier = nodeCrypto$4 ?
12997 asn1$1.define('AlgorithmIdentifier', function() {
12998 this.seq().obj(
12999 this.key('algorithm').objid(),
13000 this.key('parameters').optional().any()
13001 );
13002 }) : undefined;
13003
13004const SubjectPublicKeyInfo = nodeCrypto$4 ?
13005 asn1$1.define('SubjectPublicKeyInfo', function() {
13006 this.seq().obj(
13007 this.key('algorithm').use(AlgorithmIdentifier),
13008 this.key('subjectPublicKey').bitstr()
13009 );
13010 }) : undefined;
13011
13012var ecdsa = /*#__PURE__*/Object.freeze({
13013 __proto__: null,
13014 sign: sign$1,
13015 verify: verify$1,
13016 validateParams: validateParams$2
13017});
13018
13019// OpenPGP.js - An OpenPGP implementation in javascript
13020
13021naclFastLight.hash = bytes => new Uint8Array(_512().update(bytes).digest());
13022
13023/**
13024 * Sign a message using the provided key
13025 * @param {module:type/oid} oid - Elliptic curve object identifier
13026 * @param {module:enums.hash} hashAlgo - Hash algorithm used to sign (must be sha256 or stronger)
13027 * @param {Uint8Array} message - Message to sign
13028 * @param {Uint8Array} publicKey - Public key
13029 * @param {Uint8Array} privateKey - Private key used to sign the message
13030 * @param {Uint8Array} hashed - The hashed message
13031 * @returns {Promise<{
13032 * r: Uint8Array,
13033 * s: Uint8Array
13034 * }>} Signature of the message
13035 * @async
13036 */
13037async function sign$2(oid, hashAlgo, message, publicKey, privateKey, hashed) {
13038 if (hash.getHashByteLength(hashAlgo) < hash.getHashByteLength(enums.hash.sha256)) {
13039 // see https://tools.ietf.org/id/draft-ietf-openpgp-rfc4880bis-10.html#section-15-7.2
13040 throw new Error('Hash algorithm too weak: sha256 or stronger is required for EdDSA.');
13041 }
13042 const secretKey = util.concatUint8Array([privateKey, publicKey.subarray(1)]);
13043 const signature = naclFastLight.sign.detached(hashed, secretKey);
13044 // EdDSA signature params are returned in little-endian format
13045 return {
13046 r: signature.subarray(0, 32),
13047 s: signature.subarray(32)
13048 };
13049}
13050
13051/**
13052 * Verifies if a signature is valid for a message
13053 * @param {module:type/oid} oid - Elliptic curve object identifier
13054 * @param {module:enums.hash} hashAlgo - Hash algorithm used in the signature
13055 * @param {{r: Uint8Array,
13056 s: Uint8Array}} signature Signature to verify the message
13057 * @param {Uint8Array} m - Message to verify
13058 * @param {Uint8Array} publicKey - Public key used to verify the message
13059 * @param {Uint8Array} hashed - The hashed message
13060 * @returns {Boolean}
13061 * @async
13062 */
13063async function verify$2(oid, hashAlgo, { r, s }, m, publicKey, hashed) {
13064 const signature = util.concatUint8Array([r, s]);
13065 return naclFastLight.sign.detached.verify(hashed, signature, publicKey.subarray(1));
13066}
13067/**
13068 * Validate EdDSA parameters
13069 * @param {module:type/oid} oid - Elliptic curve object identifier
13070 * @param {Uint8Array} Q - EdDSA public point
13071 * @param {Uint8Array} k - EdDSA secret seed
13072 * @returns {Promise<Boolean>} Whether params are valid.
13073 * @async
13074 */
13075async function validateParams$3(oid, Q, k) {
13076 // Check whether the given curve is supported
13077 if (oid.getName() !== 'ed25519') {
13078 return false;
13079 }
13080
13081 /**
13082 * Derive public point Q' = dG from private key
13083 * and expect Q == Q'
13084 */
13085 const { publicKey } = naclFastLight.sign.keyPair.fromSeed(k);
13086 const dG = new Uint8Array([0x40, ...publicKey]); // Add public key prefix
13087 return util.equalsUint8Array(Q, dG);
13088}
13089
13090var eddsa = /*#__PURE__*/Object.freeze({
13091 __proto__: null,
13092 sign: sign$2,
13093 verify: verify$2,
13094 validateParams: validateParams$3
13095});
13096
13097// OpenPGP.js - An OpenPGP implementation in javascript
13098
13099/**
13100 * AES key wrap
13101 * @function
13102 * @param {Uint8Array} key
13103 * @param {Uint8Array} data
13104 * @returns {Uint8Array}
13105 */
13106function wrap(key, data) {
13107 const aes = new cipher['aes' + (key.length * 8)](key);
13108 const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
13109 const P = unpack(data);
13110 let A = IV;
13111 const R = P;
13112 const n = P.length / 2;
13113 const t = new Uint32Array([0, 0]);
13114 let B = new Uint32Array(4);
13115 for (let j = 0; j <= 5; ++j) {
13116 for (let i = 0; i < n; ++i) {
13117 t[1] = n * j + (1 + i);
13118 // B = A
13119 B[0] = A[0];
13120 B[1] = A[1];
13121 // B = A || R[i]
13122 B[2] = R[2 * i];
13123 B[3] = R[2 * i + 1];
13124 // B = AES(K, B)
13125 B = unpack(aes.encrypt(pack(B)));
13126 // A = MSB(64, B) ^ t
13127 A = B.subarray(0, 2);
13128 A[0] ^= t[0];
13129 A[1] ^= t[1];
13130 // R[i] = LSB(64, B)
13131 R[2 * i] = B[2];
13132 R[2 * i + 1] = B[3];
13133 }
13134 }
13135 return pack(A, R);
13136}
13137
13138/**
13139 * AES key unwrap
13140 * @function
13141 * @param {String} key
13142 * @param {String} data
13143 * @returns {Uint8Array}
13144 * @throws {Error}
13145 */
13146function unwrap(key, data) {
13147 const aes = new cipher['aes' + (key.length * 8)](key);
13148 const IV = new Uint32Array([0xA6A6A6A6, 0xA6A6A6A6]);
13149 const C = unpack(data);
13150 let A = C.subarray(0, 2);
13151 const R = C.subarray(2);
13152 const n = C.length / 2 - 1;
13153 const t = new Uint32Array([0, 0]);
13154 let B = new Uint32Array(4);
13155 for (let j = 5; j >= 0; --j) {
13156 for (let i = n - 1; i >= 0; --i) {
13157 t[1] = n * j + (i + 1);
13158 // B = A ^ t
13159 B[0] = A[0] ^ t[0];
13160 B[1] = A[1] ^ t[1];
13161 // B = (A ^ t) || R[i]
13162 B[2] = R[2 * i];
13163 B[3] = R[2 * i + 1];
13164 // B = AES-1(B)
13165 B = unpack(aes.decrypt(pack(B)));
13166 // A = MSB(64, B)
13167 A = B.subarray(0, 2);
13168 // R[i] = LSB(64, B)
13169 R[2 * i] = B[2];
13170 R[2 * i + 1] = B[3];
13171 }
13172 }
13173 if (A[0] === IV[0] && A[1] === IV[1]) {
13174 return pack(R);
13175 }
13176 throw new Error('Key Data Integrity failed');
13177}
13178
13179function createArrayBuffer(data) {
13180 if (util.isString(data)) {
13181 const { length } = data;
13182 const buffer = new ArrayBuffer(length);
13183 const view = new Uint8Array(buffer);
13184 for (let j = 0; j < length; ++j) {
13185 view[j] = data.charCodeAt(j);
13186 }
13187 return buffer;
13188 }
13189 return new Uint8Array(data).buffer;
13190}
13191
13192function unpack(data) {
13193 const { length } = data;
13194 const buffer = createArrayBuffer(data);
13195 const view = new DataView(buffer);
13196 const arr = new Uint32Array(length / 4);
13197 for (let i = 0; i < length / 4; ++i) {
13198 arr[i] = view.getUint32(4 * i);
13199 }
13200 return arr;
13201}
13202
13203function pack() {
13204 let length = 0;
13205 for (let k = 0; k < arguments.length; ++k) {
13206 length += 4 * arguments[k].length;
13207 }
13208 const buffer = new ArrayBuffer(length);
13209 const view = new DataView(buffer);
13210 let offset = 0;
13211 for (let i = 0; i < arguments.length; ++i) {
13212 for (let j = 0; j < arguments[i].length; ++j) {
13213 view.setUint32(offset + 4 * j, arguments[i][j]);
13214 }
13215 offset += 4 * arguments[i].length;
13216 }
13217 return new Uint8Array(buffer);
13218}
13219
13220var aesKW = /*#__PURE__*/Object.freeze({
13221 __proto__: null,
13222 wrap: wrap,
13223 unwrap: unwrap
13224});
13225
13226// OpenPGP.js - An OpenPGP implementation in javascript
13227
13228/**
13229 * @fileoverview Functions to add and remove PKCS5 padding
13230 * @see PublicKeyEncryptedSessionKeyPacket
13231 * @module crypto/pkcs5
13232 * @private
13233 */
13234
13235/**
13236 * Add pkcs5 padding to a message
13237 * @param {Uint8Array} message - message to pad
13238 * @returns {Uint8Array} Padded message.
13239 */
13240function encode$1(message) {
13241 const c = 8 - (message.length % 8);
13242 const padded = new Uint8Array(message.length + c).fill(c);
13243 padded.set(message);
13244 return padded;
13245}
13246
13247/**
13248 * Remove pkcs5 padding from a message
13249 * @param {Uint8Array} message - message to remove padding from
13250 * @returns {Uint8Array} Message without padding.
13251 */
13252function decode$1(message) {
13253 const len = message.length;
13254 if (len > 0) {
13255 const c = message[len - 1];
13256 if (c >= 1) {
13257 const provided = message.subarray(len - c);
13258 const computed = new Uint8Array(c).fill(c);
13259 if (util.equalsUint8Array(provided, computed)) {
13260 return message.subarray(0, len - c);
13261 }
13262 }
13263 }
13264 throw new Error('Invalid padding');
13265}
13266
13267var pkcs5 = /*#__PURE__*/Object.freeze({
13268 __proto__: null,
13269 encode: encode$1,
13270 decode: decode$1
13271});
13272
13273// OpenPGP.js - An OpenPGP implementation in javascript
13274
13275const webCrypto$4 = util.getWebCrypto();
13276const nodeCrypto$5 = util.getNodeCrypto();
13277
13278/**
13279 * Validate ECDH parameters
13280 * @param {module:type/oid} oid - Elliptic curve object identifier
13281 * @param {Uint8Array} Q - ECDH public point
13282 * @param {Uint8Array} d - ECDH secret scalar
13283 * @returns {Promise<Boolean>} Whether params are valid.
13284 * @async
13285 */
13286async function validateParams$4(oid, Q, d) {
13287 return validateStandardParams(enums.publicKey.ecdh, oid, Q, d);
13288}
13289
13290// Build Param for ECDH algorithm (RFC 6637)
13291function buildEcdhParam(public_algo, oid, kdfParams, fingerprint) {
13292 return util.concatUint8Array([
13293 oid.write(),
13294 new Uint8Array([public_algo]),
13295 kdfParams.write(),
13296 util.stringToUint8Array('Anonymous Sender '),
13297 fingerprint.subarray(0, 20)
13298 ]);
13299}
13300
13301// Key Derivation Function (RFC 6637)
13302async function kdf(hashAlgo, X, length, param, stripLeading = false, stripTrailing = false) {
13303 // Note: X is little endian for Curve25519, big-endian for all others.
13304 // This is not ideal, but the RFC's are unclear
13305 // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
13306 let i;
13307 if (stripLeading) {
13308 // Work around old go crypto bug
13309 for (i = 0; i < X.length && X[i] === 0; i++);
13310 X = X.subarray(i);
13311 }
13312 if (stripTrailing) {
13313 // Work around old OpenPGP.js bug
13314 for (i = X.length - 1; i >= 0 && X[i] === 0; i--);
13315 X = X.subarray(0, i + 1);
13316 }
13317 const digest = await hash.digest(hashAlgo, util.concatUint8Array([
13318 new Uint8Array([0, 0, 0, 1]),
13319 X,
13320 param
13321 ]));
13322 return digest.subarray(0, length);
13323}
13324
13325/**
13326 * Generate ECDHE ephemeral key and secret from public key
13327 *
13328 * @param {Curve} curve - Elliptic curve object
13329 * @param {Uint8Array} Q - Recipient public key
13330 * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
13331 * @async
13332 */
13333async function genPublicEphemeralKey(curve, Q) {
13334 switch (curve.type) {
13335 case 'curve25519': {
13336 const d = await getRandomBytes(32);
13337 const { secretKey, sharedKey } = await genPrivateEphemeralKey(curve, Q, null, d);
13338 let { publicKey } = naclFastLight.box.keyPair.fromSecretKey(secretKey);
13339 publicKey = util.concatUint8Array([new Uint8Array([0x40]), publicKey]);
13340 return { publicKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
13341 }
13342 case 'web':
13343 if (curve.web && util.getWebCrypto()) {
13344 try {
13345 return await webPublicEphemeralKey(curve, Q);
13346 } catch (err) {
13347 util.printDebugError(err);
13348 }
13349 }
13350 break;
13351 case 'node':
13352 return nodePublicEphemeralKey(curve, Q);
13353 }
13354 return ellipticPublicEphemeralKey(curve, Q);
13355}
13356
13357/**
13358 * Encrypt and wrap a session key
13359 *
13360 * @param {module:type/oid} oid - Elliptic curve object identifier
13361 * @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
13362 * @param {Uint8Array} data - Unpadded session key data
13363 * @param {Uint8Array} Q - Recipient public key
13364 * @param {Uint8Array} fingerprint - Recipient fingerprint
13365 * @returns {Promise<{publicKey: Uint8Array, wrappedKey: Uint8Array}>}
13366 * @async
13367 */
13368async function encrypt$2(oid, kdfParams, data, Q, fingerprint) {
13369 const m = encode$1(data);
13370
13371 const curve = new Curve(oid);
13372 const { publicKey, sharedKey } = await genPublicEphemeralKey(curve, Q);
13373 const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
13374 const { keySize } = getCipher(kdfParams.cipher);
13375 const Z = await kdf(kdfParams.hash, sharedKey, keySize, param);
13376 const wrappedKey = wrap(Z, m);
13377 return { publicKey, wrappedKey };
13378}
13379
13380/**
13381 * Generate ECDHE secret from private key and public part of ephemeral key
13382 *
13383 * @param {Curve} curve - Elliptic curve object
13384 * @param {Uint8Array} V - Public part of ephemeral key
13385 * @param {Uint8Array} Q - Recipient public key
13386 * @param {Uint8Array} d - Recipient private key
13387 * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
13388 * @async
13389 */
13390async function genPrivateEphemeralKey(curve, V, Q, d) {
13391 if (d.length !== curve.payloadSize) {
13392 const privateKey = new Uint8Array(curve.payloadSize);
13393 privateKey.set(d, curve.payloadSize - d.length);
13394 d = privateKey;
13395 }
13396 switch (curve.type) {
13397 case 'curve25519': {
13398 const secretKey = d.slice().reverse();
13399 const sharedKey = naclFastLight.scalarMult(secretKey, V.subarray(1));
13400 return { secretKey, sharedKey }; // Note: sharedKey is little-endian here, unlike below
13401 }
13402 case 'web':
13403 if (curve.web && util.getWebCrypto()) {
13404 try {
13405 return await webPrivateEphemeralKey(curve, V, Q, d);
13406 } catch (err) {
13407 util.printDebugError(err);
13408 }
13409 }
13410 break;
13411 case 'node':
13412 return nodePrivateEphemeralKey(curve, V, d);
13413 }
13414 return ellipticPrivateEphemeralKey(curve, V, d);
13415}
13416
13417/**
13418 * Decrypt and unwrap the value derived from session key
13419 *
13420 * @param {module:type/oid} oid - Elliptic curve object identifier
13421 * @param {module:type/kdf_params} kdfParams - KDF params including cipher and algorithm to use
13422 * @param {Uint8Array} V - Public part of ephemeral key
13423 * @param {Uint8Array} C - Encrypted and wrapped value derived from session key
13424 * @param {Uint8Array} Q - Recipient public key
13425 * @param {Uint8Array} d - Recipient private key
13426 * @param {Uint8Array} fingerprint - Recipient fingerprint
13427 * @returns {Promise<Uint8Array>} Value derived from session key.
13428 * @async
13429 */
13430async function decrypt$2(oid, kdfParams, V, C, Q, d, fingerprint) {
13431 const curve = new Curve(oid);
13432 const { sharedKey } = await genPrivateEphemeralKey(curve, V, Q, d);
13433 const param = buildEcdhParam(enums.publicKey.ecdh, oid, kdfParams, fingerprint);
13434 const { keySize } = getCipher(kdfParams.cipher);
13435 let err;
13436 for (let i = 0; i < 3; i++) {
13437 try {
13438 // Work around old go crypto bug and old OpenPGP.js bug, respectively.
13439 const Z = await kdf(kdfParams.hash, sharedKey, keySize, param, i === 1, i === 2);
13440 return decode$1(unwrap(Z, C));
13441 } catch (e) {
13442 err = e;
13443 }
13444 }
13445 throw err;
13446}
13447
13448/**
13449 * Generate ECDHE secret from private key and public part of ephemeral key using webCrypto
13450 *
13451 * @param {Curve} curve - Elliptic curve object
13452 * @param {Uint8Array} V - Public part of ephemeral key
13453 * @param {Uint8Array} Q - Recipient public key
13454 * @param {Uint8Array} d - Recipient private key
13455 * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
13456 * @async
13457 */
13458async function webPrivateEphemeralKey(curve, V, Q, d) {
13459 const recipient = privateToJWK$1(curve.payloadSize, curve.web.web, Q, d);
13460 let privateKey = webCrypto$4.importKey(
13461 'jwk',
13462 recipient,
13463 {
13464 name: 'ECDH',
13465 namedCurve: curve.web.web
13466 },
13467 true,
13468 ['deriveKey', 'deriveBits']
13469 );
13470 const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, V);
13471 let sender = webCrypto$4.importKey(
13472 'jwk',
13473 jwk,
13474 {
13475 name: 'ECDH',
13476 namedCurve: curve.web.web
13477 },
13478 true,
13479 []
13480 );
13481 [privateKey, sender] = await Promise.all([privateKey, sender]);
13482 let S = webCrypto$4.deriveBits(
13483 {
13484 name: 'ECDH',
13485 namedCurve: curve.web.web,
13486 public: sender
13487 },
13488 privateKey,
13489 curve.web.sharedSize
13490 );
13491 let secret = webCrypto$4.exportKey(
13492 'jwk',
13493 privateKey
13494 );
13495 [S, secret] = await Promise.all([S, secret]);
13496 const sharedKey = new Uint8Array(S);
13497 const secretKey = b64ToUint8Array(secret.d);
13498 return { secretKey, sharedKey };
13499}
13500
13501/**
13502 * Generate ECDHE ephemeral key and secret from public key using webCrypto
13503 *
13504 * @param {Curve} curve - Elliptic curve object
13505 * @param {Uint8Array} Q - Recipient public key
13506 * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
13507 * @async
13508 */
13509async function webPublicEphemeralKey(curve, Q) {
13510 const jwk = rawPublicToJWK(curve.payloadSize, curve.web.web, Q);
13511 let keyPair = webCrypto$4.generateKey(
13512 {
13513 name: 'ECDH',
13514 namedCurve: curve.web.web
13515 },
13516 true,
13517 ['deriveKey', 'deriveBits']
13518 );
13519 let recipient = webCrypto$4.importKey(
13520 'jwk',
13521 jwk,
13522 {
13523 name: 'ECDH',
13524 namedCurve: curve.web.web
13525 },
13526 false,
13527 []
13528 );
13529 [keyPair, recipient] = await Promise.all([keyPair, recipient]);
13530 let s = webCrypto$4.deriveBits(
13531 {
13532 name: 'ECDH',
13533 namedCurve: curve.web.web,
13534 public: recipient
13535 },
13536 keyPair.privateKey,
13537 curve.web.sharedSize
13538 );
13539 let p = webCrypto$4.exportKey(
13540 'jwk',
13541 keyPair.publicKey
13542 );
13543 [s, p] = await Promise.all([s, p]);
13544 const sharedKey = new Uint8Array(s);
13545 const publicKey = new Uint8Array(jwkToRawPublic(p));
13546 return { publicKey, sharedKey };
13547}
13548
13549/**
13550 * Generate ECDHE secret from private key and public part of ephemeral key using indutny/elliptic
13551 *
13552 * @param {Curve} curve - Elliptic curve object
13553 * @param {Uint8Array} V - Public part of ephemeral key
13554 * @param {Uint8Array} d - Recipient private key
13555 * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
13556 * @async
13557 */
13558async function ellipticPrivateEphemeralKey(curve, V, d) {
13559 const indutnyCurve = await getIndutnyCurve(curve.name);
13560 V = keyFromPublic(indutnyCurve, V);
13561 d = keyFromPrivate(indutnyCurve, d);
13562 const secretKey = new Uint8Array(d.getPrivate());
13563 const S = d.derive(V.getPublic());
13564 const len = indutnyCurve.curve.p.byteLength();
13565 const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
13566 return { secretKey, sharedKey };
13567}
13568
13569/**
13570 * Generate ECDHE ephemeral key and secret from public key using indutny/elliptic
13571 *
13572 * @param {Curve} curve - Elliptic curve object
13573 * @param {Uint8Array} Q - Recipient public key
13574 * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
13575 * @async
13576 */
13577async function ellipticPublicEphemeralKey(curve, Q) {
13578 const indutnyCurve = await getIndutnyCurve(curve.name);
13579 const v = await curve.genKeyPair();
13580 Q = keyFromPublic(indutnyCurve, Q);
13581 const V = keyFromPrivate(indutnyCurve, v.privateKey);
13582 const publicKey = v.publicKey;
13583 const S = V.derive(Q.getPublic());
13584 const len = indutnyCurve.curve.p.byteLength();
13585 const sharedKey = S.toArrayLike(Uint8Array, 'be', len);
13586 return { publicKey, sharedKey };
13587}
13588
13589/**
13590 * Generate ECDHE secret from private key and public part of ephemeral key using nodeCrypto
13591 *
13592 * @param {Curve} curve - Elliptic curve object
13593 * @param {Uint8Array} V - Public part of ephemeral key
13594 * @param {Uint8Array} d - Recipient private key
13595 * @returns {Promise<{secretKey: Uint8Array, sharedKey: Uint8Array}>}
13596 * @async
13597 */
13598async function nodePrivateEphemeralKey(curve, V, d) {
13599 const recipient = nodeCrypto$5.createECDH(curve.node.node);
13600 recipient.setPrivateKey(d);
13601 const sharedKey = new Uint8Array(recipient.computeSecret(V));
13602 const secretKey = new Uint8Array(recipient.getPrivateKey());
13603 return { secretKey, sharedKey };
13604}
13605
13606/**
13607 * Generate ECDHE ephemeral key and secret from public key using nodeCrypto
13608 *
13609 * @param {Curve} curve - Elliptic curve object
13610 * @param {Uint8Array} Q - Recipient public key
13611 * @returns {Promise<{publicKey: Uint8Array, sharedKey: Uint8Array}>}
13612 * @async
13613 */
13614async function nodePublicEphemeralKey(curve, Q) {
13615 const sender = nodeCrypto$5.createECDH(curve.node.node);
13616 sender.generateKeys();
13617 const sharedKey = new Uint8Array(sender.computeSecret(Q));
13618 const publicKey = new Uint8Array(sender.getPublicKey());
13619 return { publicKey, sharedKey };
13620}
13621
13622var ecdh = /*#__PURE__*/Object.freeze({
13623 __proto__: null,
13624 validateParams: validateParams$4,
13625 encrypt: encrypt$2,
13626 decrypt: decrypt$2
13627});
13628
13629// OpenPGP.js - An OpenPGP implementation in javascript
13630
13631var elliptic = /*#__PURE__*/Object.freeze({
13632 __proto__: null,
13633 Curve: Curve,
13634 ecdh: ecdh,
13635 ecdsa: ecdsa,
13636 eddsa: eddsa,
13637 generate: generate$1,
13638 getPreferredHashAlgo: getPreferredHashAlgo
13639});
13640
13641// GPG4Browsers - An OpenPGP implementation in javascript
13642
13643/*
13644 TODO regarding the hash function, read:
13645 https://tools.ietf.org/html/rfc4880#section-13.6
13646 https://tools.ietf.org/html/rfc4880#section-14
13647*/
13648
13649/**
13650 * DSA Sign function
13651 * @param {Integer} hashAlgo
13652 * @param {Uint8Array} hashed
13653 * @param {Uint8Array} g
13654 * @param {Uint8Array} p
13655 * @param {Uint8Array} q
13656 * @param {Uint8Array} x
13657 * @returns {Promise<{ r: Uint8Array, s: Uint8Array }>}
13658 * @async
13659 */
13660async function sign$3(hashAlgo, hashed, g, p, q, x) {
13661 const BigInteger = await util.getBigInteger();
13662 const one = new BigInteger(1);
13663 p = new BigInteger(p);
13664 q = new BigInteger(q);
13665 g = new BigInteger(g);
13666 x = new BigInteger(x);
13667
13668 let k;
13669 let r;
13670 let s;
13671 let t;
13672 g = g.mod(p);
13673 x = x.mod(q);
13674 // If the output size of the chosen hash is larger than the number of
13675 // bits of q, the hash result is truncated to fit by taking the number
13676 // of leftmost bits equal to the number of bits of q. This (possibly
13677 // truncated) hash function result is treated as a number and used
13678 // directly in the DSA signature algorithm.
13679 const h = new BigInteger(hashed.subarray(0, q.byteLength())).mod(q);
13680 // FIPS-186-4, section 4.6:
13681 // The values of r and s shall be checked to determine if r = 0 or s = 0.
13682 // If either r = 0 or s = 0, a new value of k shall be generated, and the
13683 // signature shall be recalculated. It is extremely unlikely that r = 0
13684 // or s = 0 if signatures are generated properly.
13685 while (true) {
13686 // See Appendix B here: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
13687 k = await getRandomBigInteger(one, q); // returns in [1, q-1]
13688 r = g.modExp(k, p).imod(q); // (g**k mod p) mod q
13689 if (r.isZero()) {
13690 continue;
13691 }
13692 const xr = x.mul(r).imod(q);
13693 t = h.add(xr).imod(q); // H(m) + x*r mod q
13694 s = k.modInv(q).imul(t).imod(q); // k**-1 * (H(m) + x*r) mod q
13695 if (s.isZero()) {
13696 continue;
13697 }
13698 break;
13699 }
13700 return {
13701 r: r.toUint8Array('be', q.byteLength()),
13702 s: s.toUint8Array('be', q.byteLength())
13703 };
13704}
13705
13706/**
13707 * DSA Verify function
13708 * @param {Integer} hashAlgo
13709 * @param {Uint8Array} r
13710 * @param {Uint8Array} s
13711 * @param {Uint8Array} hashed
13712 * @param {Uint8Array} g
13713 * @param {Uint8Array} p
13714 * @param {Uint8Array} q
13715 * @param {Uint8Array} y
13716 * @returns {boolean}
13717 * @async
13718 */
13719async function verify$3(hashAlgo, r, s, hashed, g, p, q, y) {
13720 const BigInteger = await util.getBigInteger();
13721 const zero = new BigInteger(0);
13722 r = new BigInteger(r);
13723 s = new BigInteger(s);
13724
13725 p = new BigInteger(p);
13726 q = new BigInteger(q);
13727 g = new BigInteger(g);
13728 y = new BigInteger(y);
13729
13730 if (r.lte(zero) || r.gte(q) ||
13731 s.lte(zero) || s.gte(q)) {
13732 util.printDebug('invalid DSA Signature');
13733 return false;
13734 }
13735 const h = new BigInteger(hashed.subarray(0, q.byteLength())).imod(q);
13736 const w = s.modInv(q); // s**-1 mod q
13737 if (w.isZero()) {
13738 util.printDebug('invalid DSA Signature');
13739 return false;
13740 }
13741
13742 g = g.mod(p);
13743 y = y.mod(p);
13744 const u1 = h.mul(w).imod(q); // H(m) * w mod q
13745 const u2 = r.mul(w).imod(q); // r * w mod q
13746 const t1 = g.modExp(u1, p); // g**u1 mod p
13747 const t2 = y.modExp(u2, p); // y**u2 mod p
13748 const v = t1.mul(t2).imod(p).imod(q); // (g**u1 * y**u2 mod p) mod q
13749 return v.equal(r);
13750}
13751
13752/**
13753 * Validate DSA parameters
13754 * @param {Uint8Array} p - DSA prime
13755 * @param {Uint8Array} q - DSA group order
13756 * @param {Uint8Array} g - DSA sub-group generator
13757 * @param {Uint8Array} y - DSA public key
13758 * @param {Uint8Array} x - DSA private key
13759 * @returns {Promise<Boolean>} Whether params are valid.
13760 * @async
13761 */
13762async function validateParams$5(p, q, g, y, x) {
13763 const BigInteger = await util.getBigInteger();
13764 p = new BigInteger(p);
13765 q = new BigInteger(q);
13766 g = new BigInteger(g);
13767 y = new BigInteger(y);
13768 const one = new BigInteger(1);
13769 // Check that 1 < g < p
13770 if (g.lte(one) || g.gte(p)) {
13771 return false;
13772 }
13773
13774 /**
13775 * Check that subgroup order q divides p-1
13776 */
13777 if (!p.dec().mod(q).isZero()) {
13778 return false;
13779 }
13780
13781 /**
13782 * g has order q
13783 * Check that g ** q = 1 mod p
13784 */
13785 if (!g.modExp(q, p).isOne()) {
13786 return false;
13787 }
13788
13789 /**
13790 * Check q is large and probably prime (we mainly want to avoid small factors)
13791 */
13792 const qSize = new BigInteger(q.bitLength());
13793 const n150 = new BigInteger(150);
13794 if (qSize.lt(n150) || !(await isProbablePrime(q, null, 32))) {
13795 return false;
13796 }
13797
13798 /**
13799 * Re-derive public key y' = g ** x mod p
13800 * Expect y == y'
13801 *
13802 * Blinded exponentiation computes g**{rq + x} to compare to y
13803 */
13804 x = new BigInteger(x);
13805 const two = new BigInteger(2);
13806 const r = await getRandomBigInteger(two.leftShift(qSize.dec()), two.leftShift(qSize)); // draw r of same size as q
13807 const rqx = q.mul(r).add(x);
13808 if (!y.equal(g.modExp(rqx, p))) {
13809 return false;
13810 }
13811
13812 return true;
13813}
13814
13815var dsa = /*#__PURE__*/Object.freeze({
13816 __proto__: null,
13817 sign: sign$3,
13818 verify: verify$3,
13819 validateParams: validateParams$5
13820});
13821
13822/**
13823 * @fileoverview Asymmetric cryptography functions
13824 * @module crypto/public_key
13825 * @private
13826 */
13827
13828var publicKey = {
13829 /** @see module:crypto/public_key/rsa */
13830 rsa: rsa,
13831 /** @see module:crypto/public_key/elgamal */
13832 elgamal: elgamal,
13833 /** @see module:crypto/public_key/elliptic */
13834 elliptic: elliptic,
13835 /** @see module:crypto/public_key/dsa */
13836 dsa: dsa,
13837 /** @see tweetnacl */
13838 nacl: naclFastLight
13839};
13840
13841// OpenPGP.js - An OpenPGP implementation in javascript
13842
13843class ECDHSymmetricKey {
13844 constructor(data) {
13845 if (typeof data === 'undefined') {
13846 data = new Uint8Array([]);
13847 } else if (util.isString(data)) {
13848 data = util.stringToUint8Array(data);
13849 } else {
13850 data = new Uint8Array(data);
13851 }
13852 this.data = data;
13853 }
13854
13855 /**
13856 * Read an ECDHSymmetricKey from an Uint8Array
13857 * @param {Uint8Array} input - Where to read the encoded symmetric key from
13858 * @returns {Number} Number of read bytes.
13859 */
13860 read(input) {
13861 if (input.length >= 1) {
13862 const length = input[0];
13863 if (input.length >= 1 + length) {
13864 this.data = input.subarray(1, 1 + length);
13865 return 1 + this.data.length;
13866 }
13867 }
13868 throw new Error('Invalid symmetric key');
13869 }
13870
13871 /**
13872 * Write an ECDHSymmetricKey as an Uint8Array
13873 * @returns {Uint8Array} An array containing the value
13874 */
13875 write() {
13876 return util.concatUint8Array([new Uint8Array([this.data.length]), this.data]);
13877 }
13878}
13879
13880// OpenPGP.js - An OpenPGP implementation in javascript
13881// Copyright (C) 2015-2016 Decentral
13882//
13883// This library is free software; you can redistribute it and/or
13884// modify it under the terms of the GNU Lesser General Public
13885// License as published by the Free Software Foundation; either
13886// version 3.0 of the License, or (at your option) any later version.
13887//
13888// This library is distributed in the hope that it will be useful,
13889// but WITHOUT ANY WARRANTY; without even the implied warranty of
13890// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13891// Lesser General Public License for more details.
13892//
13893// You should have received a copy of the GNU Lesser General Public
13894// License along with this library; if not, write to the Free Software
13895// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
13896
13897/**
13898 * Implementation of type KDF parameters
13899 *
13900 * {@link https://tools.ietf.org/html/rfc6637#section-7|RFC 6637 7}:
13901 * A key derivation function (KDF) is necessary to implement the EC
13902 * encryption. The Concatenation Key Derivation Function (Approved
13903 * Alternative 1) [NIST-SP800-56A] with the KDF hash function that is
13904 * SHA2-256 [FIPS-180-3] or stronger is REQUIRED.
13905 * @module type/kdf_params
13906 * @private
13907 */
13908
13909class KDFParams {
13910 /**
13911 * @param {enums.hash} hash - Hash algorithm
13912 * @param {enums.symmetric} cipher - Symmetric algorithm
13913 */
13914 constructor(data) {
13915 if (data) {
13916 const { hash, cipher } = data;
13917 this.hash = hash;
13918 this.cipher = cipher;
13919 } else {
13920 this.hash = null;
13921 this.cipher = null;
13922 }
13923 }
13924
13925 /**
13926 * Read KDFParams from an Uint8Array
13927 * @param {Uint8Array} input - Where to read the KDFParams from
13928 * @returns {Number} Number of read bytes.
13929 */
13930 read(input) {
13931 if (input.length < 4 || input[0] !== 3 || input[1] !== 1) {
13932 throw new Error('Cannot read KDFParams');
13933 }
13934 this.hash = input[2];
13935 this.cipher = input[3];
13936 return 4;
13937 }
13938
13939 /**
13940 * Write KDFParams to an Uint8Array
13941 * @returns {Uint8Array} Array with the KDFParams value
13942 */
13943 write() {
13944 return new Uint8Array([3, 1, this.hash, this.cipher]);
13945 }
13946}
13947
13948// GPG4Browsers - An OpenPGP implementation in javascript
13949
13950/**
13951 * Encrypts data using specified algorithm and public key parameters.
13952 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1} for public key algorithms.
13953 * @param {module:enums.publicKey} algo - Public key algorithm
13954 * @param {Object} publicParams - Algorithm-specific public key parameters
13955 * @param {Uint8Array} data - Data to be encrypted
13956 * @param {Uint8Array} fingerprint - Recipient fingerprint
13957 * @returns {Promise<Object>} Encrypted session key parameters.
13958 * @async
13959 */
13960async function publicKeyEncrypt(algo, publicParams, data, fingerprint) {
13961 switch (algo) {
13962 case enums.publicKey.rsaEncrypt:
13963 case enums.publicKey.rsaEncryptSign: {
13964 const { n, e } = publicParams;
13965 const c = await publicKey.rsa.encrypt(data, n, e);
13966 return { c };
13967 }
13968 case enums.publicKey.elgamal: {
13969 const { p, g, y } = publicParams;
13970 return publicKey.elgamal.encrypt(data, p, g, y);
13971 }
13972 case enums.publicKey.ecdh: {
13973 const { oid, Q, kdfParams } = publicParams;
13974 const { publicKey: V, wrappedKey: C } = await publicKey.elliptic.ecdh.encrypt(
13975 oid, kdfParams, data, Q, fingerprint);
13976 return { V, C: new ECDHSymmetricKey(C) };
13977 }
13978 default:
13979 return [];
13980 }
13981}
13982
13983/**
13984 * Decrypts data using specified algorithm and private key parameters.
13985 * See {@link https://tools.ietf.org/html/rfc4880#section-5.5.3|RFC 4880 5.5.3}
13986 * @param {module:enums.publicKey} algo - Public key algorithm
13987 * @param {Object} publicKeyParams - Algorithm-specific public key parameters
13988 * @param {Object} privateKeyParams - Algorithm-specific private key parameters
13989 * @param {Object} sessionKeyParams - Encrypted session key parameters
13990 * @param {Uint8Array} fingerprint - Recipient fingerprint
13991 * @param {Uint8Array} [randomPayload] - Data to return on decryption error, instead of throwing
13992 * (needed for constant-time processing in RSA and ElGamal)
13993 * @returns {Promise<Uint8Array>} Decrypted data.
13994 * @throws {Error} on sensitive decryption error, unless `randomPayload` is given
13995 * @async
13996 */
13997async function publicKeyDecrypt(algo, publicKeyParams, privateKeyParams, sessionKeyParams, fingerprint, randomPayload) {
13998 switch (algo) {
13999 case enums.publicKey.rsaEncryptSign:
14000 case enums.publicKey.rsaEncrypt: {
14001 const { c } = sessionKeyParams;
14002 const { n, e } = publicKeyParams;
14003 const { d, p, q, u } = privateKeyParams;
14004 return publicKey.rsa.decrypt(c, n, e, d, p, q, u, randomPayload);
14005 }
14006 case enums.publicKey.elgamal: {
14007 const { c1, c2 } = sessionKeyParams;
14008 const p = publicKeyParams.p;
14009 const x = privateKeyParams.x;
14010 return publicKey.elgamal.decrypt(c1, c2, p, x, randomPayload);
14011 }
14012 case enums.publicKey.ecdh: {
14013 const { oid, Q, kdfParams } = publicKeyParams;
14014 const { d } = privateKeyParams;
14015 const { V, C } = sessionKeyParams;
14016 return publicKey.elliptic.ecdh.decrypt(
14017 oid, kdfParams, V, C.data, Q, d, fingerprint);
14018 }
14019 default:
14020 throw new Error('Unknown public key encryption algorithm.');
14021 }
14022}
14023
14024/**
14025 * Parse public key material in binary form to get the key parameters
14026 * @param {module:enums.publicKey} algo - The key algorithm
14027 * @param {Uint8Array} bytes - The key material to parse
14028 * @returns {{ read: Number, publicParams: Object }} Number of read bytes plus key parameters referenced by name.
14029 */
14030function parsePublicKeyParams(algo, bytes) {
14031 let read = 0;
14032 switch (algo) {
14033 case enums.publicKey.rsaEncrypt:
14034 case enums.publicKey.rsaEncryptSign:
14035 case enums.publicKey.rsaSign: {
14036 const n = util.readMPI(bytes.subarray(read)); read += n.length + 2;
14037 const e = util.readMPI(bytes.subarray(read)); read += e.length + 2;
14038 return { read, publicParams: { n, e } };
14039 }
14040 case enums.publicKey.dsa: {
14041 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
14042 const q = util.readMPI(bytes.subarray(read)); read += q.length + 2;
14043 const g = util.readMPI(bytes.subarray(read)); read += g.length + 2;
14044 const y = util.readMPI(bytes.subarray(read)); read += y.length + 2;
14045 return { read, publicParams: { p, q, g, y } };
14046 }
14047 case enums.publicKey.elgamal: {
14048 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
14049 const g = util.readMPI(bytes.subarray(read)); read += g.length + 2;
14050 const y = util.readMPI(bytes.subarray(read)); read += y.length + 2;
14051 return { read, publicParams: { p, g, y } };
14052 }
14053 case enums.publicKey.ecdsa: {
14054 const oid = new OID(); read += oid.read(bytes);
14055 checkSupportedCurve(oid);
14056 const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
14057 return { read: read, publicParams: { oid, Q } };
14058 }
14059 case enums.publicKey.eddsa: {
14060 const oid = new OID(); read += oid.read(bytes);
14061 checkSupportedCurve(oid);
14062 let Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
14063 Q = util.leftPad(Q, 33);
14064 return { read: read, publicParams: { oid, Q } };
14065 }
14066 case enums.publicKey.ecdh: {
14067 const oid = new OID(); read += oid.read(bytes);
14068 checkSupportedCurve(oid);
14069 const Q = util.readMPI(bytes.subarray(read)); read += Q.length + 2;
14070 const kdfParams = new KDFParams(); read += kdfParams.read(bytes.subarray(read));
14071 return { read: read, publicParams: { oid, Q, kdfParams } };
14072 }
14073 default:
14074 throw new UnsupportedError('Unknown public key encryption algorithm.');
14075 }
14076}
14077
14078/**
14079 * Parse private key material in binary form to get the key parameters
14080 * @param {module:enums.publicKey} algo - The key algorithm
14081 * @param {Uint8Array} bytes - The key material to parse
14082 * @param {Object} publicParams - (ECC only) public params, needed to format some private params
14083 * @returns {{ read: Number, privateParams: Object }} Number of read bytes plus the key parameters referenced by name.
14084 */
14085function parsePrivateKeyParams(algo, bytes, publicParams) {
14086 let read = 0;
14087 switch (algo) {
14088 case enums.publicKey.rsaEncrypt:
14089 case enums.publicKey.rsaEncryptSign:
14090 case enums.publicKey.rsaSign: {
14091 const d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
14092 const p = util.readMPI(bytes.subarray(read)); read += p.length + 2;
14093 const q = util.readMPI(bytes.subarray(read)); read += q.length + 2;
14094 const u = util.readMPI(bytes.subarray(read)); read += u.length + 2;
14095 return { read, privateParams: { d, p, q, u } };
14096 }
14097 case enums.publicKey.dsa:
14098 case enums.publicKey.elgamal: {
14099 const x = util.readMPI(bytes.subarray(read)); read += x.length + 2;
14100 return { read, privateParams: { x } };
14101 }
14102 case enums.publicKey.ecdsa:
14103 case enums.publicKey.ecdh: {
14104 const curve = new Curve(publicParams.oid);
14105 let d = util.readMPI(bytes.subarray(read)); read += d.length + 2;
14106 d = util.leftPad(d, curve.payloadSize);
14107 return { read, privateParams: { d } };
14108 }
14109 case enums.publicKey.eddsa: {
14110 const curve = new Curve(publicParams.oid);
14111 let seed = util.readMPI(bytes.subarray(read)); read += seed.length + 2;
14112 seed = util.leftPad(seed, curve.payloadSize);
14113 return { read, privateParams: { seed } };
14114 }
14115 default:
14116 throw new UnsupportedError('Unknown public key encryption algorithm.');
14117 }
14118}
14119
14120/** Returns the types comprising the encrypted session key of an algorithm
14121 * @param {module:enums.publicKey} algo - The key algorithm
14122 * @param {Uint8Array} bytes - The key material to parse
14123 * @returns {Object} The session key parameters referenced by name.
14124 */
14125function parseEncSessionKeyParams(algo, bytes) {
14126 let read = 0;
14127 switch (algo) {
14128 // Algorithm-Specific Fields for RSA encrypted session keys:
14129 // - MPI of RSA encrypted value m**e mod n.
14130 case enums.publicKey.rsaEncrypt:
14131 case enums.publicKey.rsaEncryptSign: {
14132 const c = util.readMPI(bytes.subarray(read));
14133 return { c };
14134 }
14135
14136 // Algorithm-Specific Fields for Elgamal encrypted session keys:
14137 // - MPI of Elgamal value g**k mod p
14138 // - MPI of Elgamal value m * y**k mod p
14139 case enums.publicKey.elgamal: {
14140 const c1 = util.readMPI(bytes.subarray(read)); read += c1.length + 2;
14141 const c2 = util.readMPI(bytes.subarray(read));
14142 return { c1, c2 };
14143 }
14144 // Algorithm-Specific Fields for ECDH encrypted session keys:
14145 // - MPI containing the ephemeral key used to establish the shared secret
14146 // - ECDH Symmetric Key
14147 case enums.publicKey.ecdh: {
14148 const V = util.readMPI(bytes.subarray(read)); read += V.length + 2;
14149 const C = new ECDHSymmetricKey(); C.read(bytes.subarray(read));
14150 return { V, C };
14151 }
14152 default:
14153 throw new UnsupportedError('Unknown public key encryption algorithm.');
14154 }
14155}
14156
14157/**
14158 * Convert params to MPI and serializes them in the proper order
14159 * @param {module:enums.publicKey} algo - The public key algorithm
14160 * @param {Object} params - The key parameters indexed by name
14161 * @returns {Uint8Array} The array containing the MPIs.
14162 */
14163function serializeParams(algo, params) {
14164 const orderedParams = Object.keys(params).map(name => {
14165 const param = params[name];
14166 return util.isUint8Array(param) ? util.uint8ArrayToMPI(param) : param.write();
14167 });
14168 return util.concatUint8Array(orderedParams);
14169}
14170
14171/**
14172 * Generate algorithm-specific key parameters
14173 * @param {module:enums.publicKey} algo - The public key algorithm
14174 * @param {Integer} bits - Bit length for RSA keys
14175 * @param {module:type/oid} oid - Object identifier for ECC keys
14176 * @returns {Promise<{ publicParams: {Object}, privateParams: {Object} }>} The parameters referenced by name.
14177 * @async
14178 */
14179function generateParams(algo, bits, oid) {
14180 switch (algo) {
14181 case enums.publicKey.rsaEncrypt:
14182 case enums.publicKey.rsaEncryptSign:
14183 case enums.publicKey.rsaSign: {
14184 return publicKey.rsa.generate(bits, 65537).then(({ n, e, d, p, q, u }) => ({
14185 privateParams: { d, p, q, u },
14186 publicParams: { n, e }
14187 }));
14188 }
14189 case enums.publicKey.ecdsa:
14190 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
14191 privateParams: { d: secret },
14192 publicParams: { oid: new OID(oid), Q }
14193 }));
14194 case enums.publicKey.eddsa:
14195 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret }) => ({
14196 privateParams: { seed: secret },
14197 publicParams: { oid: new OID(oid), Q }
14198 }));
14199 case enums.publicKey.ecdh:
14200 return publicKey.elliptic.generate(oid).then(({ oid, Q, secret, hash, cipher }) => ({
14201 privateParams: { d: secret },
14202 publicParams: {
14203 oid: new OID(oid),
14204 Q,
14205 kdfParams: new KDFParams({ hash, cipher })
14206 }
14207 }));
14208 case enums.publicKey.dsa:
14209 case enums.publicKey.elgamal:
14210 throw new Error('Unsupported algorithm for key generation.');
14211 default:
14212 throw new Error('Unknown public key algorithm.');
14213 }
14214}
14215
14216/**
14217 * Validate algorithm-specific key parameters
14218 * @param {module:enums.publicKey} algo - The public key algorithm
14219 * @param {Object} publicParams - Algorithm-specific public key parameters
14220 * @param {Object} privateParams - Algorithm-specific private key parameters
14221 * @returns {Promise<Boolean>} Whether the parameters are valid.
14222 * @async
14223 */
14224async function validateParams$6(algo, publicParams, privateParams) {
14225 if (!publicParams || !privateParams) {
14226 throw new Error('Missing key parameters');
14227 }
14228 switch (algo) {
14229 case enums.publicKey.rsaEncrypt:
14230 case enums.publicKey.rsaEncryptSign:
14231 case enums.publicKey.rsaSign: {
14232 const { n, e } = publicParams;
14233 const { d, p, q, u } = privateParams;
14234 return publicKey.rsa.validateParams(n, e, d, p, q, u);
14235 }
14236 case enums.publicKey.dsa: {
14237 const { p, q, g, y } = publicParams;
14238 const { x } = privateParams;
14239 return publicKey.dsa.validateParams(p, q, g, y, x);
14240 }
14241 case enums.publicKey.elgamal: {
14242 const { p, g, y } = publicParams;
14243 const { x } = privateParams;
14244 return publicKey.elgamal.validateParams(p, g, y, x);
14245 }
14246 case enums.publicKey.ecdsa:
14247 case enums.publicKey.ecdh: {
14248 const algoModule = publicKey.elliptic[enums.read(enums.publicKey, algo)];
14249 const { oid, Q } = publicParams;
14250 const { d } = privateParams;
14251 return algoModule.validateParams(oid, Q, d);
14252 }
14253 case enums.publicKey.eddsa: {
14254 const { oid, Q } = publicParams;
14255 const { seed } = privateParams;
14256 return publicKey.elliptic.eddsa.validateParams(oid, Q, seed);
14257 }
14258 default:
14259 throw new Error('Unknown public key algorithm.');
14260 }
14261}
14262
14263/**
14264 * Generates a random byte prefix for the specified algorithm
14265 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
14266 * @param {module:enums.symmetric} algo - Symmetric encryption algorithm
14267 * @returns {Promise<Uint8Array>} Random bytes with length equal to the block size of the cipher, plus the last two bytes repeated.
14268 * @async
14269 */
14270async function getPrefixRandom(algo) {
14271 const { blockSize } = getCipher(algo);
14272 const prefixrandom = await getRandomBytes(blockSize);
14273 const repeat = new Uint8Array([prefixrandom[prefixrandom.length - 2], prefixrandom[prefixrandom.length - 1]]);
14274 return util.concat([prefixrandom, repeat]);
14275}
14276
14277/**
14278 * Generating a session key for the specified symmetric algorithm
14279 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
14280 * @param {module:enums.symmetric} algo - Symmetric encryption algorithm
14281 * @returns {Promise<Uint8Array>} Random bytes as a string to be used as a key.
14282 * @async
14283 */
14284function generateSessionKey(algo) {
14285 const { keySize } = getCipher(algo);
14286 return getRandomBytes(keySize);
14287}
14288
14289/**
14290 * Get implementation of the given AEAD mode
14291 * @param {enums.aead} algo
14292 * @returns {Object}
14293 * @throws {Error} on invalid algo
14294 */
14295function getAEADMode(algo) {
14296 const algoName = enums.read(enums.aead, algo);
14297 return mode[algoName];
14298}
14299
14300/**
14301 * Get implementation of the given cipher
14302 * @param {enums.symmetric} algo
14303 * @returns {Object}
14304 * @throws {Error} on invalid algo
14305 */
14306function getCipher(algo) {
14307 const algoName = enums.read(enums.symmetric, algo);
14308 return cipher[algoName];
14309}
14310
14311/**
14312 * Check whether the given curve OID is supported
14313 * @param {module:type/oid} oid - EC object identifier
14314 * @throws {UnsupportedError} if curve is not supported
14315 */
14316function checkSupportedCurve(oid) {
14317 try {
14318 oid.getName();
14319 } catch (e) {
14320 throw new UnsupportedError('Unknown curve OID');
14321 }
14322}
14323
14324var crypto$1 = /*#__PURE__*/Object.freeze({
14325 __proto__: null,
14326 publicKeyEncrypt: publicKeyEncrypt,
14327 publicKeyDecrypt: publicKeyDecrypt,
14328 parsePublicKeyParams: parsePublicKeyParams,
14329 parsePrivateKeyParams: parsePrivateKeyParams,
14330 parseEncSessionKeyParams: parseEncSessionKeyParams,
14331 serializeParams: serializeParams,
14332 generateParams: generateParams,
14333 validateParams: validateParams$6,
14334 getPrefixRandom: getPrefixRandom,
14335 generateSessionKey: generateSessionKey,
14336 getAEADMode: getAEADMode,
14337 getCipher: getCipher
14338});
14339
14340// Modified by ProtonTech AG
14341
14342const webCrypto$5 = util.getWebCrypto();
14343const nodeCrypto$6 = util.getNodeCrypto();
14344
14345const knownAlgos = nodeCrypto$6 ? nodeCrypto$6.getCiphers() : [];
14346const nodeAlgos = {
14347 idea: knownAlgos.includes('idea-cfb') ? 'idea-cfb' : undefined, /* Unused, not implemented */
14348 tripledes: knownAlgos.includes('des-ede3-cfb') ? 'des-ede3-cfb' : undefined,
14349 cast5: knownAlgos.includes('cast5-cfb') ? 'cast5-cfb' : undefined,
14350 blowfish: knownAlgos.includes('bf-cfb') ? 'bf-cfb' : undefined,
14351 aes128: knownAlgos.includes('aes-128-cfb') ? 'aes-128-cfb' : undefined,
14352 aes192: knownAlgos.includes('aes-192-cfb') ? 'aes-192-cfb' : undefined,
14353 aes256: knownAlgos.includes('aes-256-cfb') ? 'aes-256-cfb' : undefined
14354 /* twofish is not implemented in OpenSSL */
14355};
14356
14357/**
14358 * CFB encryption
14359 * @param {enums.symmetric} algo - block cipher algorithm
14360 * @param {Uint8Array} key
14361 * @param {MaybeStream<Uint8Array>} plaintext
14362 * @param {Uint8Array} iv
14363 * @param {Object} config - full configuration, defaults to openpgp.config
14364 * @returns MaybeStream<Uint8Array>
14365 */
14366async function encrypt$3(algo, key, plaintext, iv, config) {
14367 const algoName = enums.read(enums.symmetric, algo);
14368 if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
14369 return nodeEncrypt$1(algo, key, plaintext, iv);
14370 }
14371 if (algoName.substr(0, 3) === 'aes') {
14372 return aesEncrypt(algo, key, plaintext, iv, config);
14373 }
14374
14375 const cipherfn = new cipher[algoName](key);
14376 const block_size = cipherfn.blockSize;
14377
14378 const blockc = iv.slice();
14379 let pt = new Uint8Array();
14380 const process = chunk => {
14381 if (chunk) {
14382 pt = util.concatUint8Array([pt, chunk]);
14383 }
14384 const ciphertext = new Uint8Array(pt.length);
14385 let i;
14386 let j = 0;
14387 while (chunk ? pt.length >= block_size : pt.length) {
14388 const encblock = cipherfn.encrypt(blockc);
14389 for (i = 0; i < block_size; i++) {
14390 blockc[i] = pt[i] ^ encblock[i];
14391 ciphertext[j++] = blockc[i];
14392 }
14393 pt = pt.subarray(block_size);
14394 }
14395 return ciphertext.subarray(0, j);
14396 };
14397 return transform(plaintext, process, process);
14398}
14399
14400/**
14401 * CFB decryption
14402 * @param {enums.symmetric} algo - block cipher algorithm
14403 * @param {Uint8Array} key
14404 * @param {MaybeStream<Uint8Array>} ciphertext
14405 * @param {Uint8Array} iv
14406 * @returns MaybeStream<Uint8Array>
14407 */
14408async function decrypt$3(algo, key, ciphertext, iv) {
14409 const algoName = enums.read(enums.symmetric, algo);
14410 if (util.getNodeCrypto() && nodeAlgos[algoName]) { // Node crypto library.
14411 return nodeDecrypt$1(algo, key, ciphertext, iv);
14412 }
14413 if (algoName.substr(0, 3) === 'aes') {
14414 return aesDecrypt(algo, key, ciphertext, iv);
14415 }
14416
14417 const cipherfn = new cipher[algoName](key);
14418 const block_size = cipherfn.blockSize;
14419
14420 let blockp = iv;
14421 let ct = new Uint8Array();
14422 const process = chunk => {
14423 if (chunk) {
14424 ct = util.concatUint8Array([ct, chunk]);
14425 }
14426 const plaintext = new Uint8Array(ct.length);
14427 let i;
14428 let j = 0;
14429 while (chunk ? ct.length >= block_size : ct.length) {
14430 const decblock = cipherfn.encrypt(blockp);
14431 blockp = ct;
14432 for (i = 0; i < block_size; i++) {
14433 plaintext[j++] = blockp[i] ^ decblock[i];
14434 }
14435 ct = ct.subarray(block_size);
14436 }
14437 return plaintext.subarray(0, j);
14438 };
14439 return transform(ciphertext, process, process);
14440}
14441
14442function aesEncrypt(algo, key, pt, iv, config) {
14443 if (
14444 util.getWebCrypto() &&
14445 key.length !== 24 && // Chrome doesn't support 192 bit keys, see https://www.chromium.org/blink/webcrypto#TOC-AES-support
14446 !util.isStream(pt) &&
14447 pt.length >= 3000 * config.minBytesForWebCrypto // Default to a 3MB minimum. Chrome is pretty slow for small messages, see: https://bugs.chromium.org/p/chromium/issues/detail?id=701188#c2
14448 ) { // Web Crypto
14449 return webEncrypt(algo, key, pt, iv);
14450 }
14451 // asm.js fallback
14452 const cfb = new AES_CFB(key, iv);
14453 return transform(pt, value => cfb.aes.AES_Encrypt_process(value), () => cfb.aes.AES_Encrypt_finish());
14454}
14455
14456function aesDecrypt(algo, key, ct, iv) {
14457 if (util.isStream(ct)) {
14458 const cfb = new AES_CFB(key, iv);
14459 return transform(ct, value => cfb.aes.AES_Decrypt_process(value), () => cfb.aes.AES_Decrypt_finish());
14460 }
14461 return AES_CFB.decrypt(ct, key, iv);
14462}
14463
14464function xorMut(a, b) {
14465 for (let i = 0; i < a.length; i++) {
14466 a[i] = a[i] ^ b[i];
14467 }
14468}
14469
14470async function webEncrypt(algo, key, pt, iv) {
14471 const ALGO = 'AES-CBC';
14472 const _key = await webCrypto$5.importKey('raw', key, { name: ALGO }, false, ['encrypt']);
14473 const { blockSize } = getCipher(algo);
14474 const cbc_pt = util.concatUint8Array([new Uint8Array(blockSize), pt]);
14475 const ct = new Uint8Array(await webCrypto$5.encrypt({ name: ALGO, iv }, _key, cbc_pt)).subarray(0, pt.length);
14476 xorMut(ct, pt);
14477 return ct;
14478}
14479
14480function nodeEncrypt$1(algo, key, pt, iv) {
14481 const algoName = enums.read(enums.symmetric, algo);
14482 const cipherObj = new nodeCrypto$6.createCipheriv(nodeAlgos[algoName], key, iv);
14483 return transform(pt, value => new Uint8Array(cipherObj.update(value)));
14484}
14485
14486function nodeDecrypt$1(algo, key, ct, iv) {
14487 const algoName = enums.read(enums.symmetric, algo);
14488 const decipherObj = new nodeCrypto$6.createDecipheriv(nodeAlgos[algoName], key, iv);
14489 return transform(ct, value => new Uint8Array(decipherObj.update(value)));
14490}
14491
14492var cfb = /*#__PURE__*/Object.freeze({
14493 __proto__: null,
14494 encrypt: encrypt$3,
14495 decrypt: decrypt$3
14496});
14497
14498class AES_CTR {
14499 static encrypt(data, key, nonce) {
14500 return new AES_CTR(key, nonce).encrypt(data);
14501 }
14502 static decrypt(data, key, nonce) {
14503 return new AES_CTR(key, nonce).encrypt(data);
14504 }
14505 constructor(key, nonce, aes) {
14506 this.aes = aes ? aes : new AES(key, undefined, false, 'CTR');
14507 delete this.aes.padding;
14508 this.AES_CTR_set_options(nonce);
14509 }
14510 encrypt(data) {
14511 const r1 = this.aes.AES_Encrypt_process(data);
14512 const r2 = this.aes.AES_Encrypt_finish();
14513 return joinBytes(r1, r2);
14514 }
14515 decrypt(data) {
14516 const r1 = this.aes.AES_Encrypt_process(data);
14517 const r2 = this.aes.AES_Encrypt_finish();
14518 return joinBytes(r1, r2);
14519 }
14520 AES_CTR_set_options(nonce, counter, size) {
14521 let { asm } = this.aes.acquire_asm();
14522 if (size !== undefined) {
14523 if (size < 8 || size > 48)
14524 throw new IllegalArgumentError('illegal counter size');
14525 let mask = Math.pow(2, size) - 1;
14526 asm.set_mask(0, 0, (mask / 0x100000000) | 0, mask | 0);
14527 }
14528 else {
14529 size = 48;
14530 asm.set_mask(0, 0, 0xffff, 0xffffffff);
14531 }
14532 if (nonce !== undefined) {
14533 let len = nonce.length;
14534 if (!len || len > 16)
14535 throw new IllegalArgumentError('illegal nonce size');
14536 let view = new DataView(new ArrayBuffer(16));
14537 new Uint8Array(view.buffer).set(nonce);
14538 asm.set_nonce(view.getUint32(0), view.getUint32(4), view.getUint32(8), view.getUint32(12));
14539 }
14540 else {
14541 throw new Error('nonce is required');
14542 }
14543 if (counter !== undefined) {
14544 if (counter < 0 || counter >= Math.pow(2, size))
14545 throw new IllegalArgumentError('illegal counter value');
14546 asm.set_counter(0, 0, (counter / 0x100000000) | 0, counter | 0);
14547 }
14548 }
14549}
14550
14551class AES_CBC {
14552 static encrypt(data, key, padding = true, iv) {
14553 return new AES_CBC(key, iv, padding).encrypt(data);
14554 }
14555 static decrypt(data, key, padding = true, iv) {
14556 return new AES_CBC(key, iv, padding).decrypt(data);
14557 }
14558 constructor(key, iv, padding = true, aes) {
14559 this.aes = aes ? aes : new AES(key, iv, padding, 'CBC');
14560 }
14561 encrypt(data) {
14562 const r1 = this.aes.AES_Encrypt_process(data);
14563 const r2 = this.aes.AES_Encrypt_finish();
14564 return joinBytes(r1, r2);
14565 }
14566 decrypt(data) {
14567 const r1 = this.aes.AES_Decrypt_process(data);
14568 const r2 = this.aes.AES_Decrypt_finish();
14569 return joinBytes(r1, r2);
14570 }
14571}
14572
14573/**
14574 * @fileoverview This module implements AES-CMAC on top of
14575 * native AES-CBC using either the WebCrypto API or Node.js' crypto API.
14576 * @module crypto/cmac
14577 * @private
14578 */
14579
14580const webCrypto$6 = util.getWebCrypto();
14581const nodeCrypto$7 = util.getNodeCrypto();
14582
14583
14584/**
14585 * This implementation of CMAC is based on the description of OMAC in
14586 * http://web.cs.ucdavis.edu/~rogaway/papers/eax.pdf. As per that
14587 * document:
14588 *
14589 * We have made a small modification to the OMAC algorithm as it was
14590 * originally presented, changing one of its two constants.
14591 * Specifically, the constant 4 at line 85 was the constant 1/2 (the
14592 * multiplicative inverse of 2) in the original definition of OMAC [14].
14593 * The OMAC authors indicate that they will promulgate this modification
14594 * [15], which slightly simplifies implementations.
14595 */
14596
14597const blockLength = 16;
14598
14599
14600/**
14601 * xor `padding` into the end of `data`. This function implements "the
14602 * operation xor→ [which] xors the shorter string into the end of longer
14603 * one". Since data is always as least as long as padding, we can
14604 * simplify the implementation.
14605 * @param {Uint8Array} data
14606 * @param {Uint8Array} padding
14607 */
14608function rightXORMut(data, padding) {
14609 const offset = data.length - blockLength;
14610 for (let i = 0; i < blockLength; i++) {
14611 data[i + offset] ^= padding[i];
14612 }
14613 return data;
14614}
14615
14616function pad(data, padding, padding2) {
14617 // if |M| in {n, 2n, 3n, ...}
14618 if (data.length && data.length % blockLength === 0) {
14619 // then return M xor→ B,
14620 return rightXORMut(data, padding);
14621 }
14622 // else return (M || 10^(n−1−(|M| mod n))) xor→ P
14623 const padded = new Uint8Array(data.length + (blockLength - data.length % blockLength));
14624 padded.set(data);
14625 padded[data.length] = 0b10000000;
14626 return rightXORMut(padded, padding2);
14627}
14628
14629const zeroBlock = new Uint8Array(blockLength);
14630
14631async function CMAC(key) {
14632 const cbc = await CBC(key);
14633
14634 // L ← E_K(0^n); B ← 2L; P ← 4L
14635 const padding = util.double(await cbc(zeroBlock));
14636 const padding2 = util.double(padding);
14637
14638 return async function(data) {
14639 // return CBC_K(pad(M; B, P))
14640 return (await cbc(pad(data, padding, padding2))).subarray(-blockLength);
14641 };
14642}
14643
14644async function CBC(key) {
14645 if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
14646 key = await webCrypto$6.importKey('raw', key, { name: 'AES-CBC', length: key.length * 8 }, false, ['encrypt']);
14647 return async function(pt) {
14648 const ct = await webCrypto$6.encrypt({ name: 'AES-CBC', iv: zeroBlock, length: blockLength * 8 }, key, pt);
14649 return new Uint8Array(ct).subarray(0, ct.byteLength - blockLength);
14650 };
14651 }
14652 if (util.getNodeCrypto()) { // Node crypto library
14653 return async function(pt) {
14654 const en = new nodeCrypto$7.createCipheriv('aes-' + (key.length * 8) + '-cbc', key, zeroBlock);
14655 const ct = en.update(pt);
14656 return new Uint8Array(ct);
14657 };
14658 }
14659 // asm.js fallback
14660 return async function(pt) {
14661 return AES_CBC.encrypt(pt, key, false, zeroBlock);
14662 };
14663}
14664
14665// OpenPGP.js - An OpenPGP implementation in javascript
14666
14667const webCrypto$7 = util.getWebCrypto();
14668const nodeCrypto$8 = util.getNodeCrypto();
14669const Buffer$1 = util.getNodeBuffer();
14670
14671
14672const blockLength$1 = 16;
14673const ivLength = blockLength$1;
14674const tagLength = blockLength$1;
14675
14676const zero = new Uint8Array(blockLength$1);
14677const one = new Uint8Array(blockLength$1); one[blockLength$1 - 1] = 1;
14678const two = new Uint8Array(blockLength$1); two[blockLength$1 - 1] = 2;
14679
14680async function OMAC(key) {
14681 const cmac = await CMAC(key);
14682 return function(t, message) {
14683 return cmac(util.concatUint8Array([t, message]));
14684 };
14685}
14686
14687async function CTR(key) {
14688 if (
14689 util.getWebCrypto() &&
14690 key.length !== 24 // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
14691 ) {
14692 key = await webCrypto$7.importKey('raw', key, { name: 'AES-CTR', length: key.length * 8 }, false, ['encrypt']);
14693 return async function(pt, iv) {
14694 const ct = await webCrypto$7.encrypt({ name: 'AES-CTR', counter: iv, length: blockLength$1 * 8 }, key, pt);
14695 return new Uint8Array(ct);
14696 };
14697 }
14698 if (util.getNodeCrypto()) { // Node crypto library
14699 return async function(pt, iv) {
14700 const en = new nodeCrypto$8.createCipheriv('aes-' + (key.length * 8) + '-ctr', key, iv);
14701 const ct = Buffer$1.concat([en.update(pt), en.final()]);
14702 return new Uint8Array(ct);
14703 };
14704 }
14705 // asm.js fallback
14706 return async function(pt, iv) {
14707 return AES_CTR.encrypt(pt, key, iv);
14708 };
14709}
14710
14711
14712/**
14713 * Class to en/decrypt using EAX mode.
14714 * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
14715 * @param {Uint8Array} key - The encryption key
14716 */
14717async function EAX(cipher, key) {
14718 if (cipher !== enums.symmetric.aes128 &&
14719 cipher !== enums.symmetric.aes192 &&
14720 cipher !== enums.symmetric.aes256) {
14721 throw new Error('EAX mode supports only AES cipher');
14722 }
14723
14724 const [
14725 omac,
14726 ctr
14727 ] = await Promise.all([
14728 OMAC(key),
14729 CTR(key)
14730 ]);
14731
14732 return {
14733 /**
14734 * Encrypt plaintext input.
14735 * @param {Uint8Array} plaintext - The cleartext input to be encrypted
14736 * @param {Uint8Array} nonce - The nonce (16 bytes)
14737 * @param {Uint8Array} adata - Associated data to sign
14738 * @returns {Promise<Uint8Array>} The ciphertext output.
14739 */
14740 encrypt: async function(plaintext, nonce, adata) {
14741 const [
14742 omacNonce,
14743 omacAdata
14744 ] = await Promise.all([
14745 omac(zero, nonce),
14746 omac(one, adata)
14747 ]);
14748 const ciphered = await ctr(plaintext, omacNonce);
14749 const omacCiphered = await omac(two, ciphered);
14750 const tag = omacCiphered; // Assumes that omac(*).length === tagLength.
14751 for (let i = 0; i < tagLength; i++) {
14752 tag[i] ^= omacAdata[i] ^ omacNonce[i];
14753 }
14754 return util.concatUint8Array([ciphered, tag]);
14755 },
14756
14757 /**
14758 * Decrypt ciphertext input.
14759 * @param {Uint8Array} ciphertext - The ciphertext input to be decrypted
14760 * @param {Uint8Array} nonce - The nonce (16 bytes)
14761 * @param {Uint8Array} adata - Associated data to verify
14762 * @returns {Promise<Uint8Array>} The plaintext output.
14763 */
14764 decrypt: async function(ciphertext, nonce, adata) {
14765 if (ciphertext.length < tagLength) throw new Error('Invalid EAX ciphertext');
14766 const ciphered = ciphertext.subarray(0, -tagLength);
14767 const ctTag = ciphertext.subarray(-tagLength);
14768 const [
14769 omacNonce,
14770 omacAdata,
14771 omacCiphered
14772 ] = await Promise.all([
14773 omac(zero, nonce),
14774 omac(one, adata),
14775 omac(two, ciphered)
14776 ]);
14777 const tag = omacCiphered; // Assumes that omac(*).length === tagLength.
14778 for (let i = 0; i < tagLength; i++) {
14779 tag[i] ^= omacAdata[i] ^ omacNonce[i];
14780 }
14781 if (!util.equalsUint8Array(ctTag, tag)) throw new Error('Authentication tag mismatch');
14782 const plaintext = await ctr(ciphered, omacNonce);
14783 return plaintext;
14784 }
14785 };
14786}
14787
14788
14789/**
14790 * Get EAX nonce as defined by {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.1|RFC4880bis-04, section 5.16.1}.
14791 * @param {Uint8Array} iv - The initialization vector (16 bytes)
14792 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
14793 */
14794EAX.getNonce = function(iv, chunkIndex) {
14795 const nonce = iv.slice();
14796 for (let i = 0; i < chunkIndex.length; i++) {
14797 nonce[8 + i] ^= chunkIndex[i];
14798 }
14799 return nonce;
14800};
14801
14802EAX.blockLength = blockLength$1;
14803EAX.ivLength = ivLength;
14804EAX.tagLength = tagLength;
14805
14806// OpenPGP.js - An OpenPGP implementation in javascript
14807
14808const blockLength$2 = 16;
14809const ivLength$1 = 15;
14810
14811// https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.2:
14812// While OCB [RFC7253] allows the authentication tag length to be of any
14813// number up to 128 bits long, this document requires a fixed
14814// authentication tag length of 128 bits (16 octets) for simplicity.
14815const tagLength$1 = 16;
14816
14817
14818function ntz(n) {
14819 let ntz = 0;
14820 for (let i = 1; (n & i) === 0; i <<= 1) {
14821 ntz++;
14822 }
14823 return ntz;
14824}
14825
14826function xorMut$1(S, T) {
14827 for (let i = 0; i < S.length; i++) {
14828 S[i] ^= T[i];
14829 }
14830 return S;
14831}
14832
14833function xor(S, T) {
14834 return xorMut$1(S.slice(), T);
14835}
14836
14837const zeroBlock$1 = new Uint8Array(blockLength$2);
14838const one$1 = new Uint8Array([1]);
14839
14840/**
14841 * Class to en/decrypt using OCB mode.
14842 * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
14843 * @param {Uint8Array} key - The encryption key
14844 */
14845async function OCB(cipher$1, key) {
14846
14847 let maxNtz = 0;
14848 let encipher;
14849 let decipher;
14850 let mask;
14851
14852 constructKeyVariables(cipher$1, key);
14853
14854 function constructKeyVariables(cipher$1, key) {
14855 const cipherName = enums.read(enums.symmetric, cipher$1);
14856 const aes = new cipher[cipherName](key);
14857 encipher = aes.encrypt.bind(aes);
14858 decipher = aes.decrypt.bind(aes);
14859
14860 const mask_x = encipher(zeroBlock$1);
14861 const mask_$ = util.double(mask_x);
14862 mask = [];
14863 mask[0] = util.double(mask_$);
14864
14865
14866 mask.x = mask_x;
14867 mask.$ = mask_$;
14868 }
14869
14870 function extendKeyVariables(text, adata) {
14871 const newMaxNtz = util.nbits(Math.max(text.length, adata.length) / blockLength$2 | 0) - 1;
14872 for (let i = maxNtz + 1; i <= newMaxNtz; i++) {
14873 mask[i] = util.double(mask[i - 1]);
14874 }
14875 maxNtz = newMaxNtz;
14876 }
14877
14878 function hash(adata) {
14879 if (!adata.length) {
14880 // Fast path
14881 return zeroBlock$1;
14882 }
14883
14884 //
14885 // Consider A as a sequence of 128-bit blocks
14886 //
14887 const m = adata.length / blockLength$2 | 0;
14888
14889 const offset = new Uint8Array(blockLength$2);
14890 const sum = new Uint8Array(blockLength$2);
14891 for (let i = 0; i < m; i++) {
14892 xorMut$1(offset, mask[ntz(i + 1)]);
14893 xorMut$1(sum, encipher(xor(offset, adata)));
14894 adata = adata.subarray(blockLength$2);
14895 }
14896
14897 //
14898 // Process any final partial block; compute final hash value
14899 //
14900 if (adata.length) {
14901 xorMut$1(offset, mask.x);
14902
14903 const cipherInput = new Uint8Array(blockLength$2);
14904 cipherInput.set(adata, 0);
14905 cipherInput[adata.length] = 0b10000000;
14906 xorMut$1(cipherInput, offset);
14907
14908 xorMut$1(sum, encipher(cipherInput));
14909 }
14910
14911 return sum;
14912 }
14913
14914 /**
14915 * Encrypt/decrypt data.
14916 * @param {encipher|decipher} fn - Encryption/decryption block cipher function
14917 * @param {Uint8Array} text - The cleartext or ciphertext (without tag) input
14918 * @param {Uint8Array} nonce - The nonce (15 bytes)
14919 * @param {Uint8Array} adata - Associated data to sign
14920 * @returns {Promise<Uint8Array>} The ciphertext or plaintext output, with tag appended in both cases.
14921 */
14922 function crypt(fn, text, nonce, adata) {
14923 //
14924 // Consider P as a sequence of 128-bit blocks
14925 //
14926 const m = text.length / blockLength$2 | 0;
14927
14928 //
14929 // Key-dependent variables
14930 //
14931 extendKeyVariables(text, adata);
14932
14933 //
14934 // Nonce-dependent and per-encryption variables
14935 //
14936 // Nonce = num2str(TAGLEN mod 128,7) || zeros(120-bitlen(N)) || 1 || N
14937 // Note: We assume here that tagLength mod 16 == 0.
14938 const paddedNonce = util.concatUint8Array([zeroBlock$1.subarray(0, ivLength$1 - nonce.length), one$1, nonce]);
14939 // bottom = str2num(Nonce[123..128])
14940 const bottom = paddedNonce[blockLength$2 - 1] & 0b111111;
14941 // Ktop = ENCIPHER(K, Nonce[1..122] || zeros(6))
14942 paddedNonce[blockLength$2 - 1] &= 0b11000000;
14943 const kTop = encipher(paddedNonce);
14944 // Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72])
14945 const stretched = util.concatUint8Array([kTop, xor(kTop.subarray(0, 8), kTop.subarray(1, 9))]);
14946 // Offset_0 = Stretch[1+bottom..128+bottom]
14947 const offset = util.shiftRight(stretched.subarray(0 + (bottom >> 3), 17 + (bottom >> 3)), 8 - (bottom & 7)).subarray(1);
14948 // Checksum_0 = zeros(128)
14949 const checksum = new Uint8Array(blockLength$2);
14950
14951 const ct = new Uint8Array(text.length + tagLength$1);
14952
14953 //
14954 // Process any whole blocks
14955 //
14956 let i;
14957 let pos = 0;
14958 for (i = 0; i < m; i++) {
14959 // Offset_i = Offset_{i-1} xor L_{ntz(i)}
14960 xorMut$1(offset, mask[ntz(i + 1)]);
14961 // C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i)
14962 // P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i)
14963 ct.set(xorMut$1(fn(xor(offset, text)), offset), pos);
14964 // Checksum_i = Checksum_{i-1} xor P_i
14965 xorMut$1(checksum, fn === encipher ? text : ct.subarray(pos));
14966
14967 text = text.subarray(blockLength$2);
14968 pos += blockLength$2;
14969 }
14970
14971 //
14972 // Process any final partial block and compute raw tag
14973 //
14974 if (text.length) {
14975 // Offset_* = Offset_m xor L_*
14976 xorMut$1(offset, mask.x);
14977 // Pad = ENCIPHER(K, Offset_*)
14978 const padding = encipher(offset);
14979 // C_* = P_* xor Pad[1..bitlen(P_*)]
14980 ct.set(xor(text, padding), pos);
14981
14982 // Checksum_* = Checksum_m xor (P_* || 1 || new Uint8Array(127-bitlen(P_*)))
14983 const xorInput = new Uint8Array(blockLength$2);
14984 xorInput.set(fn === encipher ? text : ct.subarray(pos, -tagLength$1), 0);
14985 xorInput[text.length] = 0b10000000;
14986 xorMut$1(checksum, xorInput);
14987 pos += text.length;
14988 }
14989 // Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A)
14990 const tag = xorMut$1(encipher(xorMut$1(xorMut$1(checksum, offset), mask.$)), hash(adata));
14991
14992 //
14993 // Assemble ciphertext
14994 //
14995 // C = C_1 || C_2 || ... || C_m || C_* || Tag[1..TAGLEN]
14996 ct.set(tag, pos);
14997 return ct;
14998 }
14999
15000
15001 return {
15002 /**
15003 * Encrypt plaintext input.
15004 * @param {Uint8Array} plaintext - The cleartext input to be encrypted
15005 * @param {Uint8Array} nonce - The nonce (15 bytes)
15006 * @param {Uint8Array} adata - Associated data to sign
15007 * @returns {Promise<Uint8Array>} The ciphertext output.
15008 */
15009 encrypt: async function(plaintext, nonce, adata) {
15010 return crypt(encipher, plaintext, nonce, adata);
15011 },
15012
15013 /**
15014 * Decrypt ciphertext input.
15015 * @param {Uint8Array} ciphertext - The ciphertext input to be decrypted
15016 * @param {Uint8Array} nonce - The nonce (15 bytes)
15017 * @param {Uint8Array} adata - Associated data to sign
15018 * @returns {Promise<Uint8Array>} The ciphertext output.
15019 */
15020 decrypt: async function(ciphertext, nonce, adata) {
15021 if (ciphertext.length < tagLength$1) throw new Error('Invalid OCB ciphertext');
15022
15023 const tag = ciphertext.subarray(-tagLength$1);
15024 ciphertext = ciphertext.subarray(0, -tagLength$1);
15025
15026 const crypted = crypt(decipher, ciphertext, nonce, adata);
15027 // if (Tag[1..TAGLEN] == T)
15028 if (util.equalsUint8Array(tag, crypted.subarray(-tagLength$1))) {
15029 return crypted.subarray(0, -tagLength$1);
15030 }
15031 throw new Error('Authentication tag mismatch');
15032 }
15033 };
15034}
15035
15036
15037/**
15038 * Get OCB nonce as defined by {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.16.2|RFC4880bis-04, section 5.16.2}.
15039 * @param {Uint8Array} iv - The initialization vector (15 bytes)
15040 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
15041 */
15042OCB.getNonce = function(iv, chunkIndex) {
15043 const nonce = iv.slice();
15044 for (let i = 0; i < chunkIndex.length; i++) {
15045 nonce[7 + i] ^= chunkIndex[i];
15046 }
15047 return nonce;
15048};
15049
15050OCB.blockLength = blockLength$2;
15051OCB.ivLength = ivLength$1;
15052OCB.tagLength = tagLength$1;
15053
15054const _AES_GCM_data_maxLength = 68719476704; // 2^36 - 2^5
15055class AES_GCM {
15056 constructor(key, nonce, adata, tagSize = 16, aes) {
15057 this.tagSize = tagSize;
15058 this.gamma0 = 0;
15059 this.counter = 1;
15060 this.aes = aes ? aes : new AES(key, undefined, false, 'CTR');
15061 let { asm, heap } = this.aes.acquire_asm();
15062 // Init GCM
15063 asm.gcm_init();
15064 // Tag size
15065 if (this.tagSize < 4 || this.tagSize > 16)
15066 throw new IllegalArgumentError('illegal tagSize value');
15067 // Nonce
15068 const noncelen = nonce.length || 0;
15069 const noncebuf = new Uint8Array(16);
15070 if (noncelen !== 12) {
15071 this._gcm_mac_process(nonce);
15072 heap[0] = 0;
15073 heap[1] = 0;
15074 heap[2] = 0;
15075 heap[3] = 0;
15076 heap[4] = 0;
15077 heap[5] = 0;
15078 heap[6] = 0;
15079 heap[7] = 0;
15080 heap[8] = 0;
15081 heap[9] = 0;
15082 heap[10] = 0;
15083 heap[11] = noncelen >>> 29;
15084 heap[12] = (noncelen >>> 21) & 255;
15085 heap[13] = (noncelen >>> 13) & 255;
15086 heap[14] = (noncelen >>> 5) & 255;
15087 heap[15] = (noncelen << 3) & 255;
15088 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
15089 asm.get_iv(AES_asm.HEAP_DATA);
15090 asm.set_iv(0, 0, 0, 0);
15091 noncebuf.set(heap.subarray(0, 16));
15092 }
15093 else {
15094 noncebuf.set(nonce);
15095 noncebuf[15] = 1;
15096 }
15097 const nonceview = new DataView(noncebuf.buffer);
15098 this.gamma0 = nonceview.getUint32(12);
15099 asm.set_nonce(nonceview.getUint32(0), nonceview.getUint32(4), nonceview.getUint32(8), 0);
15100 asm.set_mask(0, 0, 0, 0xffffffff);
15101 // Associated data
15102 if (adata !== undefined) {
15103 if (adata.length > _AES_GCM_data_maxLength)
15104 throw new IllegalArgumentError('illegal adata length');
15105 if (adata.length) {
15106 this.adata = adata;
15107 this._gcm_mac_process(adata);
15108 }
15109 else {
15110 this.adata = undefined;
15111 }
15112 }
15113 else {
15114 this.adata = undefined;
15115 }
15116 // Counter
15117 if (this.counter < 1 || this.counter > 0xffffffff)
15118 throw new RangeError('counter must be a positive 32-bit integer');
15119 asm.set_counter(0, 0, 0, (this.gamma0 + this.counter) | 0);
15120 }
15121 static encrypt(cleartext, key, nonce, adata, tagsize) {
15122 return new AES_GCM(key, nonce, adata, tagsize).encrypt(cleartext);
15123 }
15124 static decrypt(ciphertext, key, nonce, adata, tagsize) {
15125 return new AES_GCM(key, nonce, adata, tagsize).decrypt(ciphertext);
15126 }
15127 encrypt(data) {
15128 return this.AES_GCM_encrypt(data);
15129 }
15130 decrypt(data) {
15131 return this.AES_GCM_decrypt(data);
15132 }
15133 AES_GCM_Encrypt_process(data) {
15134 let dpos = 0;
15135 let dlen = data.length || 0;
15136 let { asm, heap } = this.aes.acquire_asm();
15137 let counter = this.counter;
15138 let pos = this.aes.pos;
15139 let len = this.aes.len;
15140 let rpos = 0;
15141 let rlen = (len + dlen) & -16;
15142 let wlen = 0;
15143 if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength)
15144 throw new RangeError('counter overflow');
15145 const result = new Uint8Array(rlen);
15146 while (dlen > 0) {
15147 wlen = _heap_write(heap, pos + len, data, dpos, dlen);
15148 len += wlen;
15149 dpos += wlen;
15150 dlen -= wlen;
15151 wlen = asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, len);
15152 wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
15153 if (wlen)
15154 result.set(heap.subarray(pos, pos + wlen), rpos);
15155 counter += wlen >>> 4;
15156 rpos += wlen;
15157 if (wlen < len) {
15158 pos += wlen;
15159 len -= wlen;
15160 }
15161 else {
15162 pos = 0;
15163 len = 0;
15164 }
15165 }
15166 this.counter = counter;
15167 this.aes.pos = pos;
15168 this.aes.len = len;
15169 return result;
15170 }
15171 AES_GCM_Encrypt_finish() {
15172 let { asm, heap } = this.aes.acquire_asm();
15173 let counter = this.counter;
15174 let tagSize = this.tagSize;
15175 let adata = this.adata;
15176 let pos = this.aes.pos;
15177 let len = this.aes.len;
15178 const result = new Uint8Array(len + tagSize);
15179 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA + pos, (len + 15) & -16);
15180 if (len)
15181 result.set(heap.subarray(pos, pos + len));
15182 let i = len;
15183 for (; i & 15; i++)
15184 heap[pos + i] = 0;
15185 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
15186 const alen = adata !== undefined ? adata.length : 0;
15187 const clen = ((counter - 1) << 4) + len;
15188 heap[0] = 0;
15189 heap[1] = 0;
15190 heap[2] = 0;
15191 heap[3] = alen >>> 29;
15192 heap[4] = alen >>> 21;
15193 heap[5] = (alen >>> 13) & 255;
15194 heap[6] = (alen >>> 5) & 255;
15195 heap[7] = (alen << 3) & 255;
15196 heap[8] = heap[9] = heap[10] = 0;
15197 heap[11] = clen >>> 29;
15198 heap[12] = (clen >>> 21) & 255;
15199 heap[13] = (clen >>> 13) & 255;
15200 heap[14] = (clen >>> 5) & 255;
15201 heap[15] = (clen << 3) & 255;
15202 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
15203 asm.get_iv(AES_asm.HEAP_DATA);
15204 asm.set_counter(0, 0, 0, this.gamma0);
15205 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
15206 result.set(heap.subarray(0, tagSize), len);
15207 this.counter = 1;
15208 this.aes.pos = 0;
15209 this.aes.len = 0;
15210 return result;
15211 }
15212 AES_GCM_Decrypt_process(data) {
15213 let dpos = 0;
15214 let dlen = data.length || 0;
15215 let { asm, heap } = this.aes.acquire_asm();
15216 let counter = this.counter;
15217 let tagSize = this.tagSize;
15218 let pos = this.aes.pos;
15219 let len = this.aes.len;
15220 let rpos = 0;
15221 let rlen = len + dlen > tagSize ? (len + dlen - tagSize) & -16 : 0;
15222 let tlen = len + dlen - rlen;
15223 let wlen = 0;
15224 if (((counter - 1) << 4) + len + dlen > _AES_GCM_data_maxLength)
15225 throw new RangeError('counter overflow');
15226 const result = new Uint8Array(rlen);
15227 while (dlen > tlen) {
15228 wlen = _heap_write(heap, pos + len, data, dpos, dlen - tlen);
15229 len += wlen;
15230 dpos += wlen;
15231 dlen -= wlen;
15232 wlen = asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, wlen);
15233 wlen = asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, wlen);
15234 if (wlen)
15235 result.set(heap.subarray(pos, pos + wlen), rpos);
15236 counter += wlen >>> 4;
15237 rpos += wlen;
15238 pos = 0;
15239 len = 0;
15240 }
15241 if (dlen > 0) {
15242 len += _heap_write(heap, 0, data, dpos, dlen);
15243 }
15244 this.counter = counter;
15245 this.aes.pos = pos;
15246 this.aes.len = len;
15247 return result;
15248 }
15249 AES_GCM_Decrypt_finish() {
15250 let { asm, heap } = this.aes.acquire_asm();
15251 let tagSize = this.tagSize;
15252 let adata = this.adata;
15253 let counter = this.counter;
15254 let pos = this.aes.pos;
15255 let len = this.aes.len;
15256 let rlen = len - tagSize;
15257 if (len < tagSize)
15258 throw new IllegalStateError('authentication tag not found');
15259 const result = new Uint8Array(rlen);
15260 const atag = new Uint8Array(heap.subarray(pos + rlen, pos + len));
15261 let i = rlen;
15262 for (; i & 15; i++)
15263 heap[pos + i] = 0;
15264 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA + pos, i);
15265 asm.cipher(AES_asm.DEC.CTR, AES_asm.HEAP_DATA + pos, i);
15266 if (rlen)
15267 result.set(heap.subarray(pos, pos + rlen));
15268 const alen = adata !== undefined ? adata.length : 0;
15269 const clen = ((counter - 1) << 4) + len - tagSize;
15270 heap[0] = 0;
15271 heap[1] = 0;
15272 heap[2] = 0;
15273 heap[3] = alen >>> 29;
15274 heap[4] = alen >>> 21;
15275 heap[5] = (alen >>> 13) & 255;
15276 heap[6] = (alen >>> 5) & 255;
15277 heap[7] = (alen << 3) & 255;
15278 heap[8] = heap[9] = heap[10] = 0;
15279 heap[11] = clen >>> 29;
15280 heap[12] = (clen >>> 21) & 255;
15281 heap[13] = (clen >>> 13) & 255;
15282 heap[14] = (clen >>> 5) & 255;
15283 heap[15] = (clen << 3) & 255;
15284 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, 16);
15285 asm.get_iv(AES_asm.HEAP_DATA);
15286 asm.set_counter(0, 0, 0, this.gamma0);
15287 asm.cipher(AES_asm.ENC.CTR, AES_asm.HEAP_DATA, 16);
15288 let acheck = 0;
15289 for (let i = 0; i < tagSize; ++i)
15290 acheck |= atag[i] ^ heap[i];
15291 if (acheck)
15292 throw new SecurityError('data integrity check failed');
15293 this.counter = 1;
15294 this.aes.pos = 0;
15295 this.aes.len = 0;
15296 return result;
15297 }
15298 AES_GCM_decrypt(data) {
15299 const result1 = this.AES_GCM_Decrypt_process(data);
15300 const result2 = this.AES_GCM_Decrypt_finish();
15301 const result = new Uint8Array(result1.length + result2.length);
15302 if (result1.length)
15303 result.set(result1);
15304 if (result2.length)
15305 result.set(result2, result1.length);
15306 return result;
15307 }
15308 AES_GCM_encrypt(data) {
15309 const result1 = this.AES_GCM_Encrypt_process(data);
15310 const result2 = this.AES_GCM_Encrypt_finish();
15311 const result = new Uint8Array(result1.length + result2.length);
15312 if (result1.length)
15313 result.set(result1);
15314 if (result2.length)
15315 result.set(result2, result1.length);
15316 return result;
15317 }
15318 _gcm_mac_process(data) {
15319 let { asm, heap } = this.aes.acquire_asm();
15320 let dpos = 0;
15321 let dlen = data.length || 0;
15322 let wlen = 0;
15323 while (dlen > 0) {
15324 wlen = _heap_write(heap, 0, data, dpos, dlen);
15325 dpos += wlen;
15326 dlen -= wlen;
15327 while (wlen & 15)
15328 heap[wlen++] = 0;
15329 asm.mac(AES_asm.MAC.GCM, AES_asm.HEAP_DATA, wlen);
15330 }
15331 }
15332}
15333
15334// OpenPGP.js - An OpenPGP implementation in javascript
15335
15336const webCrypto$8 = util.getWebCrypto();
15337const nodeCrypto$9 = util.getNodeCrypto();
15338const Buffer$2 = util.getNodeBuffer();
15339
15340const blockLength$3 = 16;
15341const ivLength$2 = 12; // size of the IV in bytes
15342const tagLength$2 = 16; // size of the tag in bytes
15343const ALGO = 'AES-GCM';
15344
15345/**
15346 * Class to en/decrypt using GCM mode.
15347 * @param {enums.symmetric} cipher - The symmetric cipher algorithm to use
15348 * @param {Uint8Array} key - The encryption key
15349 */
15350async function GCM(cipher, key) {
15351 if (cipher !== enums.symmetric.aes128 &&
15352 cipher !== enums.symmetric.aes192 &&
15353 cipher !== enums.symmetric.aes256) {
15354 throw new Error('GCM mode supports only AES cipher');
15355 }
15356
15357 if (util.getWebCrypto() && key.length !== 24) { // WebCrypto (no 192 bit support) see: https://www.chromium.org/blink/webcrypto#TOC-AES-support
15358 const _key = await webCrypto$8.importKey('raw', key, { name: ALGO }, false, ['encrypt', 'decrypt']);
15359
15360 return {
15361 encrypt: async function(pt, iv, adata = new Uint8Array()) {
15362 if (!pt.length) { // iOS does not support GCM-en/decrypting empty messages
15363 return AES_GCM.encrypt(pt, key, iv, adata);
15364 }
15365 const ct = await webCrypto$8.encrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, pt);
15366 return new Uint8Array(ct);
15367 },
15368
15369 decrypt: async function(ct, iv, adata = new Uint8Array()) {
15370 if (ct.length === tagLength$2) { // iOS does not support GCM-en/decrypting empty messages
15371 return AES_GCM.decrypt(ct, key, iv, adata);
15372 }
15373 const pt = await webCrypto$8.decrypt({ name: ALGO, iv, additionalData: adata, tagLength: tagLength$2 * 8 }, _key, ct);
15374 return new Uint8Array(pt);
15375 }
15376 };
15377 }
15378
15379 if (util.getNodeCrypto()) { // Node crypto library
15380 return {
15381 encrypt: async function(pt, iv, adata = new Uint8Array()) {
15382 const en = new nodeCrypto$9.createCipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
15383 en.setAAD(adata);
15384 const ct = Buffer$2.concat([en.update(pt), en.final(), en.getAuthTag()]); // append auth tag to ciphertext
15385 return new Uint8Array(ct);
15386 },
15387
15388 decrypt: async function(ct, iv, adata = new Uint8Array()) {
15389 const de = new nodeCrypto$9.createDecipheriv('aes-' + (key.length * 8) + '-gcm', key, iv);
15390 de.setAAD(adata);
15391 de.setAuthTag(ct.slice(ct.length - tagLength$2, ct.length)); // read auth tag at end of ciphertext
15392 const pt = Buffer$2.concat([de.update(ct.slice(0, ct.length - tagLength$2)), de.final()]);
15393 return new Uint8Array(pt);
15394 }
15395 };
15396 }
15397
15398 return {
15399 encrypt: async function(pt, iv, adata) {
15400 return AES_GCM.encrypt(pt, key, iv, adata);
15401 },
15402
15403 decrypt: async function(ct, iv, adata) {
15404 return AES_GCM.decrypt(ct, key, iv, adata);
15405 }
15406 };
15407}
15408
15409
15410/**
15411 * Get GCM nonce. Note: this operation is not defined by the standard.
15412 * A future version of the standard may define GCM mode differently,
15413 * hopefully under a different ID (we use Private/Experimental algorithm
15414 * ID 100) so that we can maintain backwards compatibility.
15415 * @param {Uint8Array} iv - The initialization vector (12 bytes)
15416 * @param {Uint8Array} chunkIndex - The chunk index (8 bytes)
15417 */
15418GCM.getNonce = function(iv, chunkIndex) {
15419 const nonce = iv.slice();
15420 for (let i = 0; i < chunkIndex.length; i++) {
15421 nonce[4 + i] ^= chunkIndex[i];
15422 }
15423 return nonce;
15424};
15425
15426GCM.blockLength = blockLength$3;
15427GCM.ivLength = ivLength$2;
15428GCM.tagLength = tagLength$2;
15429
15430/**
15431 * @fileoverview Cipher modes
15432 * @module crypto/mode
15433 * @private
15434 */
15435
15436var mode = {
15437 /** @see module:crypto/mode/cfb */
15438 cfb: cfb,
15439 /** @see module:crypto/mode/gcm */
15440 gcm: GCM,
15441 experimentalGCM: GCM,
15442 /** @see module:crypto/mode/eax */
15443 eax: EAX,
15444 /** @see module:crypto/mode/ocb */
15445 ocb: OCB
15446};
15447
15448/**
15449 * @fileoverview Provides functions for asymmetric signing and signature verification
15450 * @module crypto/signature
15451 * @private
15452 */
15453
15454/**
15455 * Parse signature in binary form to get the parameters.
15456 * The returned values are only padded for EdDSA, since in the other cases their expected length
15457 * depends on the key params, hence we delegate the padding to the signature verification function.
15458 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
15459 * See {@link https://tools.ietf.org/html/rfc4880#section-5.2.2|RFC 4880 5.2.2.}
15460 * @param {module:enums.publicKey} algo - Public key algorithm
15461 * @param {Uint8Array} signature - Data for which the signature was created
15462 * @returns {Promise<Object>} True if signature is valid.
15463 * @async
15464 */
15465function parseSignatureParams(algo, signature) {
15466 let read = 0;
15467 switch (algo) {
15468 // Algorithm-Specific Fields for RSA signatures:
15469 // - MPI of RSA signature value m**d mod n.
15470 case enums.publicKey.rsaEncryptSign:
15471 case enums.publicKey.rsaEncrypt:
15472 case enums.publicKey.rsaSign: {
15473 const s = util.readMPI(signature.subarray(read));
15474 // The signature needs to be the same length as the public key modulo n.
15475 // We pad s on signature verification, where we have access to n.
15476 return { s };
15477 }
15478 // Algorithm-Specific Fields for DSA or ECDSA signatures:
15479 // - MPI of DSA or ECDSA value r.
15480 // - MPI of DSA or ECDSA value s.
15481 case enums.publicKey.dsa:
15482 case enums.publicKey.ecdsa:
15483 {
15484 const r = util.readMPI(signature.subarray(read)); read += r.length + 2;
15485 const s = util.readMPI(signature.subarray(read));
15486 return { r, s };
15487 }
15488 // Algorithm-Specific Fields for EdDSA signatures:
15489 // - MPI of an EC point r.
15490 // - EdDSA value s, in MPI, in the little endian representation
15491 case enums.publicKey.eddsa: {
15492 // When parsing little-endian MPI data, we always need to left-pad it, as done with big-endian values:
15493 // https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-3.2-9
15494 let r = util.readMPI(signature.subarray(read)); read += r.length + 2;
15495 r = util.leftPad(r, 32);
15496 let s = util.readMPI(signature.subarray(read));
15497 s = util.leftPad(s, 32);
15498 return { r, s };
15499 }
15500 default:
15501 throw new UnsupportedError('Unknown signature algorithm.');
15502 }
15503}
15504
15505/**
15506 * Verifies the signature provided for data using specified algorithms and public key parameters.
15507 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
15508 * and {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4}
15509 * for public key and hash algorithms.
15510 * @param {module:enums.publicKey} algo - Public key algorithm
15511 * @param {module:enums.hash} hashAlgo - Hash algorithm
15512 * @param {Object} signature - Named algorithm-specific signature parameters
15513 * @param {Object} publicParams - Algorithm-specific public key parameters
15514 * @param {Uint8Array} data - Data for which the signature was created
15515 * @param {Uint8Array} hashed - The hashed data
15516 * @returns {Promise<Boolean>} True if signature is valid.
15517 * @async
15518 */
15519async function verify$4(algo, hashAlgo, signature, publicParams, data, hashed) {
15520 switch (algo) {
15521 case enums.publicKey.rsaEncryptSign:
15522 case enums.publicKey.rsaEncrypt:
15523 case enums.publicKey.rsaSign: {
15524 const { n, e } = publicParams;
15525 const s = util.leftPad(signature.s, n.length); // padding needed for webcrypto and node crypto
15526 return publicKey.rsa.verify(hashAlgo, data, s, n, e, hashed);
15527 }
15528 case enums.publicKey.dsa: {
15529 const { g, p, q, y } = publicParams;
15530 const { r, s } = signature; // no need to pad, since we always handle them as BigIntegers
15531 return publicKey.dsa.verify(hashAlgo, r, s, hashed, g, p, q, y);
15532 }
15533 case enums.publicKey.ecdsa: {
15534 const { oid, Q } = publicParams;
15535 const curveSize = new publicKey.elliptic.Curve(oid).payloadSize;
15536 // padding needed for webcrypto
15537 const r = util.leftPad(signature.r, curveSize);
15538 const s = util.leftPad(signature.s, curveSize);
15539 return publicKey.elliptic.ecdsa.verify(oid, hashAlgo, { r, s }, data, Q, hashed);
15540 }
15541 case enums.publicKey.eddsa: {
15542 const { oid, Q } = publicParams;
15543 // signature already padded on parsing
15544 return publicKey.elliptic.eddsa.verify(oid, hashAlgo, signature, data, Q, hashed);
15545 }
15546 default:
15547 throw new Error('Unknown signature algorithm.');
15548 }
15549}
15550
15551/**
15552 * Creates a signature on data using specified algorithms and private key parameters.
15553 * See {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC 4880 9.1}
15554 * and {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC 4880 9.4}
15555 * for public key and hash algorithms.
15556 * @param {module:enums.publicKey} algo - Public key algorithm
15557 * @param {module:enums.hash} hashAlgo - Hash algorithm
15558 * @param {Object} publicKeyParams - Algorithm-specific public and private key parameters
15559 * @param {Object} privateKeyParams - Algorithm-specific public and private key parameters
15560 * @param {Uint8Array} data - Data to be signed
15561 * @param {Uint8Array} hashed - The hashed data
15562 * @returns {Promise<Object>} Signature Object containing named signature parameters.
15563 * @async
15564 */
15565async function sign$4(algo, hashAlgo, publicKeyParams, privateKeyParams, data, hashed) {
15566 if (!publicKeyParams || !privateKeyParams) {
15567 throw new Error('Missing key parameters');
15568 }
15569 switch (algo) {
15570 case enums.publicKey.rsaEncryptSign:
15571 case enums.publicKey.rsaEncrypt:
15572 case enums.publicKey.rsaSign: {
15573 const { n, e } = publicKeyParams;
15574 const { d, p, q, u } = privateKeyParams;
15575 const s = await publicKey.rsa.sign(hashAlgo, data, n, e, d, p, q, u, hashed);
15576 return { s };
15577 }
15578 case enums.publicKey.dsa: {
15579 const { g, p, q } = publicKeyParams;
15580 const { x } = privateKeyParams;
15581 return publicKey.dsa.sign(hashAlgo, hashed, g, p, q, x);
15582 }
15583 case enums.publicKey.elgamal: {
15584 throw new Error('Signing with Elgamal is not defined in the OpenPGP standard.');
15585 }
15586 case enums.publicKey.ecdsa: {
15587 const { oid, Q } = publicKeyParams;
15588 const { d } = privateKeyParams;
15589 return publicKey.elliptic.ecdsa.sign(oid, hashAlgo, data, Q, d, hashed);
15590 }
15591 case enums.publicKey.eddsa: {
15592 const { oid, Q } = publicKeyParams;
15593 const { seed } = privateKeyParams;
15594 return publicKey.elliptic.eddsa.sign(oid, hashAlgo, data, Q, seed, hashed);
15595 }
15596 default:
15597 throw new Error('Unknown signature algorithm.');
15598 }
15599}
15600
15601var signature = /*#__PURE__*/Object.freeze({
15602 __proto__: null,
15603 parseSignatureParams: parseSignatureParams,
15604 verify: verify$4,
15605 sign: sign$4
15606});
15607
15608/**
15609 * @fileoverview Provides access to all cryptographic primitives used in OpenPGP.js
15610 * @see module:crypto/crypto
15611 * @see module:crypto/signature
15612 * @see module:crypto/public_key
15613 * @see module:crypto/cipher
15614 * @see module:crypto/random
15615 * @see module:crypto/hash
15616 * @module crypto
15617 * @private
15618 */
15619
15620// TODO move cfb and gcm to cipher
15621const mod = {
15622 /** @see module:crypto/cipher */
15623 cipher: cipher,
15624 /** @see module:crypto/hash */
15625 hash: hash,
15626 /** @see module:crypto/mode */
15627 mode: mode,
15628 /** @see module:crypto/public_key */
15629 publicKey: publicKey,
15630 /** @see module:crypto/signature */
15631 signature: signature,
15632 /** @see module:crypto/random */
15633 random: random,
15634 /** @see module:crypto/pkcs1 */
15635 pkcs1: pkcs1,
15636 /** @see module:crypto/pkcs5 */
15637 pkcs5: pkcs5,
15638 /** @see module:crypto/aes_kw */
15639 aesKW: aesKW
15640};
15641
15642Object.assign(mod, crypto$1);
15643
15644var TYPED_OK = typeof Uint8Array !== "undefined" &&
15645 typeof Uint16Array !== "undefined" &&
15646 typeof Int32Array !== "undefined";
15647
15648
15649// reduce buffer size, avoiding mem copy
15650function shrinkBuf(buf, size) {
15651 if (buf.length === size) {
15652 return buf;
15653 }
15654 if (buf.subarray) {
15655 return buf.subarray(0, size);
15656 }
15657 buf.length = size;
15658 return buf;
15659}
15660
15661
15662const fnTyped = {
15663 arraySet: function (dest, src, src_offs, len, dest_offs) {
15664 if (src.subarray && dest.subarray) {
15665 dest.set(src.subarray(src_offs, src_offs + len), dest_offs);
15666 return;
15667 }
15668 // Fallback to ordinary array
15669 for (let i = 0; i < len; i++) {
15670 dest[dest_offs + i] = src[src_offs + i];
15671 }
15672 },
15673 // Join array of chunks to single array.
15674 flattenChunks: function (chunks) {
15675 let i, l, len, pos, chunk;
15676
15677 // calculate data length
15678 len = 0;
15679 for (i = 0, l = chunks.length; i < l; i++) {
15680 len += chunks[i].length;
15681 }
15682
15683 // join chunks
15684 const result = new Uint8Array(len);
15685 pos = 0;
15686 for (i = 0, l = chunks.length; i < l; i++) {
15687 chunk = chunks[i];
15688 result.set(chunk, pos);
15689 pos += chunk.length;
15690 }
15691
15692 return result;
15693 }
15694};
15695
15696const fnUntyped = {
15697 arraySet: function (dest, src, src_offs, len, dest_offs) {
15698 for (let i = 0; i < len; i++) {
15699 dest[dest_offs + i] = src[src_offs + i];
15700 }
15701 },
15702 // Join array of chunks to single array.
15703 flattenChunks: function (chunks) {
15704 return [].concat.apply([], chunks);
15705 }
15706};
15707
15708
15709// Enable/Disable typed arrays use, for testing
15710//
15711
15712let Buf8 = TYPED_OK ? Uint8Array : Array;
15713let Buf16 = TYPED_OK ? Uint16Array : Array;
15714let Buf32 = TYPED_OK ? Int32Array : Array;
15715let flattenChunks = TYPED_OK ? fnTyped.flattenChunks : fnUntyped.flattenChunks;
15716let arraySet = TYPED_OK ? fnTyped.arraySet : fnUntyped.arraySet;
15717
15718// (C) 1995-2013 Jean-loup Gailly and Mark Adler
15719// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
15720//
15721// This software is provided 'as-is', without any express or implied
15722// warranty. In no event will the authors be held liable for any damages
15723// arising from the use of this software.
15724//
15725// Permission is granted to anyone to use this software for any purpose,
15726// including commercial applications, and to alter it and redistribute it
15727// freely, subject to the following restrictions:
15728//
15729// 1. The origin of this software must not be misrepresented; you must not
15730// claim that you wrote the original software. If you use this software
15731// in a product, an acknowledgment in the product documentation would be
15732// appreciated but is not required.
15733// 2. Altered source versions must be plainly marked as such, and must not be
15734// misrepresented as being the original software.
15735// 3. This notice may not be removed or altered from any source distribution.
15736
15737/* Allowed flush values; see deflate() and inflate() below for details */
15738const Z_NO_FLUSH = 0;
15739const Z_PARTIAL_FLUSH = 1;
15740const Z_SYNC_FLUSH = 2;
15741const Z_FULL_FLUSH = 3;
15742const Z_FINISH = 4;
15743const Z_BLOCK = 5;
15744const Z_TREES = 6;
15745
15746/* Return codes for the compression/decompression functions. Negative values
15747 * are errors, positive values are used for special but normal events.
15748 */
15749const Z_OK = 0;
15750const Z_STREAM_END = 1;
15751const Z_NEED_DICT = 2;
15752const Z_STREAM_ERROR = -2;
15753const Z_DATA_ERROR = -3;
15754//export const Z_MEM_ERROR = -4;
15755const Z_BUF_ERROR = -5;
15756const Z_DEFAULT_COMPRESSION = -1;
15757
15758
15759const Z_FILTERED = 1;
15760const Z_HUFFMAN_ONLY = 2;
15761const Z_RLE = 3;
15762const Z_FIXED = 4;
15763const Z_DEFAULT_STRATEGY = 0;
15764
15765/* Possible values of the data_type field (though see inflate()) */
15766const Z_BINARY = 0;
15767const Z_TEXT = 1;
15768//export const Z_ASCII = 1; // = Z_TEXT (deprecated)
15769const Z_UNKNOWN = 2;
15770
15771/* The deflate compression method */
15772const Z_DEFLATED = 8;
15773//export const Z_NULL = null // Use -1 or null inline, depending on var type
15774
15775/*============================================================================*/
15776
15777
15778function zero$1(buf) {
15779 let len = buf.length; while (--len >= 0) {
15780 buf[len] = 0;
15781 }
15782}
15783
15784// From zutil.h
15785
15786const STORED_BLOCK = 0;
15787const STATIC_TREES = 1;
15788const DYN_TREES = 2;
15789/* The three kinds of block type */
15790
15791const MIN_MATCH = 3;
15792const MAX_MATCH = 258;
15793/* The minimum and maximum match lengths */
15794
15795// From deflate.h
15796/* ===========================================================================
15797 * Internal compression state.
15798 */
15799
15800const LENGTH_CODES = 29;
15801/* number of length codes, not counting the special END_BLOCK code */
15802
15803const LITERALS = 256;
15804/* number of literal bytes 0..255 */
15805
15806const L_CODES = LITERALS + 1 + LENGTH_CODES;
15807/* number of Literal or Length codes, including the END_BLOCK code */
15808
15809const D_CODES = 30;
15810/* number of distance codes */
15811
15812const BL_CODES = 19;
15813/* number of codes used to transfer the bit lengths */
15814
15815const HEAP_SIZE = 2 * L_CODES + 1;
15816/* maximum heap size */
15817
15818const MAX_BITS = 15;
15819/* All codes must not exceed MAX_BITS bits */
15820
15821const Buf_size = 16;
15822/* size of bit buffer in bi_buf */
15823
15824
15825/* ===========================================================================
15826 * Constants
15827 */
15828
15829const MAX_BL_BITS = 7;
15830/* Bit length codes must not exceed MAX_BL_BITS bits */
15831
15832const END_BLOCK = 256;
15833/* end of block literal code */
15834
15835const REP_3_6 = 16;
15836/* repeat previous bit length 3-6 times (2 bits of repeat count) */
15837
15838const REPZ_3_10 = 17;
15839/* repeat a zero length 3-10 times (3 bits of repeat count) */
15840
15841const REPZ_11_138 = 18;
15842/* repeat a zero length 11-138 times (7 bits of repeat count) */
15843
15844/* eslint-disable comma-spacing,array-bracket-spacing */
15845const extra_lbits = /* extra bits for each length code */
15846 [0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0];
15847
15848const extra_dbits = /* extra bits for each distance code */
15849 [0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13];
15850
15851const extra_blbits = /* extra bits for each bit length code */
15852 [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7];
15853
15854const bl_order =
15855 [16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];
15856/* eslint-enable comma-spacing,array-bracket-spacing */
15857
15858/* The lengths of the bit length codes are sent in order of decreasing
15859 * probability, to avoid transmitting the lengths for unused bit length codes.
15860 */
15861
15862/* ===========================================================================
15863 * Local data. These are initialized only once.
15864 */
15865
15866// We pre-fill arrays with 0 to avoid uninitialized gaps
15867
15868const DIST_CODE_LEN = 512; /* see definition of array dist_code below */
15869
15870// !!!! Use flat array instead of structure, Freq = i*2, Len = i*2+1
15871const static_ltree = new Array((L_CODES + 2) * 2);
15872zero$1(static_ltree);
15873/* The static literal tree. Since the bit lengths are imposed, there is no
15874 * need for the L_CODES extra codes used during heap construction. However
15875 * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
15876 * below).
15877 */
15878
15879const static_dtree = new Array(D_CODES * 2);
15880zero$1(static_dtree);
15881/* The static distance tree. (Actually a trivial tree since all codes use
15882 * 5 bits.)
15883 */
15884
15885const _dist_code = new Array(DIST_CODE_LEN);
15886zero$1(_dist_code);
15887/* Distance codes. The first 256 values correspond to the distances
15888 * 3 .. 258, the last 256 values correspond to the top 8 bits of
15889 * the 15 bit distances.
15890 */
15891
15892const _length_code = new Array(MAX_MATCH - MIN_MATCH + 1);
15893zero$1(_length_code);
15894/* length code for each normalized match length (0 == MIN_MATCH) */
15895
15896const base_length = new Array(LENGTH_CODES);
15897zero$1(base_length);
15898/* First normalized length for each code (0 = MIN_MATCH) */
15899
15900const base_dist = new Array(D_CODES);
15901zero$1(base_dist);
15902/* First normalized distance for each code (0 = distance of 1) */
15903
15904
15905function StaticTreeDesc(static_tree, extra_bits, extra_base, elems, max_length) {
15906
15907 this.static_tree = static_tree; /* static tree or NULL */
15908 this.extra_bits = extra_bits; /* extra bits for each code or NULL */
15909 this.extra_base = extra_base; /* base index for extra_bits */
15910 this.elems = elems; /* max number of elements in the tree */
15911 this.max_length = max_length; /* max bit length for the codes */
15912
15913 // show if `static_tree` has data or dummy - needed for monomorphic objects
15914 this.has_stree = static_tree && static_tree.length;
15915}
15916
15917
15918let static_l_desc;
15919let static_d_desc;
15920let static_bl_desc;
15921
15922
15923function TreeDesc(dyn_tree, stat_desc) {
15924 this.dyn_tree = dyn_tree; /* the dynamic tree */
15925 this.max_code = 0; /* largest code with non zero frequency */
15926 this.stat_desc = stat_desc; /* the corresponding static tree */
15927}
15928
15929
15930
15931function d_code(dist) {
15932 return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
15933}
15934
15935
15936/* ===========================================================================
15937 * Output a short LSB first on the stream.
15938 * IN assertion: there is enough room in pendingBuf.
15939 */
15940function put_short(s, w) {
15941// put_byte(s, (uch)((w) & 0xff));
15942// put_byte(s, (uch)((ush)(w) >> 8));
15943 s.pending_buf[s.pending++] = w & 0xff;
15944 s.pending_buf[s.pending++] = w >>> 8 & 0xff;
15945}
15946
15947
15948/* ===========================================================================
15949 * Send a value on a given number of bits.
15950 * IN assertion: length <= 16 and value fits in length bits.
15951 */
15952function send_bits(s, value, length) {
15953 if (s.bi_valid > Buf_size - length) {
15954 s.bi_buf |= value << s.bi_valid & 0xffff;
15955 put_short(s, s.bi_buf);
15956 s.bi_buf = value >> Buf_size - s.bi_valid;
15957 s.bi_valid += length - Buf_size;
15958 } else {
15959 s.bi_buf |= value << s.bi_valid & 0xffff;
15960 s.bi_valid += length;
15961 }
15962}
15963
15964
15965function send_code(s, c, tree) {
15966 send_bits(s, tree[c * 2]/*.Code*/, tree[c * 2 + 1]/*.Len*/);
15967}
15968
15969
15970/* ===========================================================================
15971 * Reverse the first len bits of a code, using straightforward code (a faster
15972 * method would use a table)
15973 * IN assertion: 1 <= len <= 15
15974 */
15975function bi_reverse(code, len) {
15976 let res = 0;
15977 do {
15978 res |= code & 1;
15979 code >>>= 1;
15980 res <<= 1;
15981 } while (--len > 0);
15982 return res >>> 1;
15983}
15984
15985
15986/* ===========================================================================
15987 * Flush the bit buffer, keeping at most 7 bits in it.
15988 */
15989function bi_flush(s) {
15990 if (s.bi_valid === 16) {
15991 put_short(s, s.bi_buf);
15992 s.bi_buf = 0;
15993 s.bi_valid = 0;
15994
15995 } else if (s.bi_valid >= 8) {
15996 s.pending_buf[s.pending++] = s.bi_buf & 0xff;
15997 s.bi_buf >>= 8;
15998 s.bi_valid -= 8;
15999 }
16000}
16001
16002
16003/* ===========================================================================
16004 * Compute the optimal bit lengths for a tree and update the total bit length
16005 * for the current block.
16006 * IN assertion: the fields freq and dad are set, heap[heap_max] and
16007 * above are the tree nodes sorted by increasing frequency.
16008 * OUT assertions: the field len is set to the optimal bit length, the
16009 * array bl_count contains the frequencies for each bit length.
16010 * The length opt_len is updated; static_len is also updated if stree is
16011 * not null.
16012 */
16013function gen_bitlen(s, desc)
16014// deflate_state *s;
16015// tree_desc *desc; /* the tree descriptor */
16016{
16017 const tree = desc.dyn_tree;
16018 const max_code = desc.max_code;
16019 const stree = desc.stat_desc.static_tree;
16020 const has_stree = desc.stat_desc.has_stree;
16021 const extra = desc.stat_desc.extra_bits;
16022 const base = desc.stat_desc.extra_base;
16023 const max_length = desc.stat_desc.max_length;
16024 let h; /* heap index */
16025 let n, m; /* iterate over the tree elements */
16026 let bits; /* bit length */
16027 let xbits; /* extra bits */
16028 let f; /* frequency */
16029 let overflow = 0; /* number of elements with bit length too large */
16030
16031 for (bits = 0; bits <= MAX_BITS; bits++) {
16032 s.bl_count[bits] = 0;
16033 }
16034
16035 /* In a first pass, compute the optimal bit lengths (which may
16036 * overflow in the case of the bit length tree).
16037 */
16038 tree[s.heap[s.heap_max] * 2 + 1]/*.Len*/ = 0; /* root of the heap */
16039
16040 for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
16041 n = s.heap[h];
16042 bits = tree[tree[n * 2 + 1]/*.Dad*/ * 2 + 1]/*.Len*/ + 1;
16043 if (bits > max_length) {
16044 bits = max_length;
16045 overflow++;
16046 }
16047 tree[n * 2 + 1]/*.Len*/ = bits;
16048 /* We overwrite tree[n].Dad which is no longer needed */
16049
16050 if (n > max_code) {
16051 continue;
16052 } /* not a leaf node */
16053
16054 s.bl_count[bits]++;
16055 xbits = 0;
16056 if (n >= base) {
16057 xbits = extra[n - base];
16058 }
16059 f = tree[n * 2]/*.Freq*/;
16060 s.opt_len += f * (bits + xbits);
16061 if (has_stree) {
16062 s.static_len += f * (stree[n * 2 + 1]/*.Len*/ + xbits);
16063 }
16064 }
16065 if (overflow === 0) {
16066 return;
16067 }
16068
16069 // Trace((stderr,"\nbit length overflow\n"));
16070 /* This happens for example on obj2 and pic of the Calgary corpus */
16071
16072 /* Find the first bit length which could increase: */
16073 do {
16074 bits = max_length - 1;
16075 while (s.bl_count[bits] === 0) {
16076 bits--;
16077 }
16078 s.bl_count[bits]--; /* move one leaf down the tree */
16079 s.bl_count[bits + 1] += 2; /* move one overflow item as its brother */
16080 s.bl_count[max_length]--;
16081 /* The brother of the overflow item also moves one step up,
16082 * but this does not affect bl_count[max_length]
16083 */
16084 overflow -= 2;
16085 } while (overflow > 0);
16086
16087 /* Now recompute all bit lengths, scanning in increasing frequency.
16088 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
16089 * lengths instead of fixing only the wrong ones. This idea is taken
16090 * from 'ar' written by Haruhiko Okumura.)
16091 */
16092 for (bits = max_length; bits !== 0; bits--) {
16093 n = s.bl_count[bits];
16094 while (n !== 0) {
16095 m = s.heap[--h];
16096 if (m > max_code) {
16097 continue;
16098 }
16099 if (tree[m * 2 + 1]/*.Len*/ !== bits) {
16100 // Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
16101 s.opt_len += (bits - tree[m * 2 + 1]/*.Len*/) * tree[m * 2]/*.Freq*/;
16102 tree[m * 2 + 1]/*.Len*/ = bits;
16103 }
16104 n--;
16105 }
16106 }
16107}
16108
16109
16110/* ===========================================================================
16111 * Generate the codes for a given tree and bit counts (which need not be
16112 * optimal).
16113 * IN assertion: the array bl_count contains the bit length statistics for
16114 * the given tree and the field len is set for all tree elements.
16115 * OUT assertion: the field code is set for all tree elements of non
16116 * zero code length.
16117 */
16118function gen_codes(tree, max_code, bl_count)
16119// ct_data *tree; /* the tree to decorate */
16120// int max_code; /* largest code with non zero frequency */
16121// ushf *bl_count; /* number of codes at each bit length */
16122{
16123 const next_code = new Array(MAX_BITS + 1); /* next code value for each bit length */
16124 let code = 0; /* running code value */
16125 let bits; /* bit index */
16126 let n; /* code index */
16127
16128 /* The distribution counts are first used to generate the code values
16129 * without bit reversal.
16130 */
16131 for (bits = 1; bits <= MAX_BITS; bits++) {
16132 next_code[bits] = code = code + bl_count[bits - 1] << 1;
16133 }
16134 /* Check that the bit counts in bl_count are consistent. The last code
16135 * must be all ones.
16136 */
16137 //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
16138 // "inconsistent bit counts");
16139 //Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
16140
16141 for (n = 0; n <= max_code; n++) {
16142 const len = tree[n * 2 + 1]/*.Len*/;
16143 if (len === 0) {
16144 continue;
16145 }
16146 /* Now reverse the bits */
16147 tree[n * 2]/*.Code*/ = bi_reverse(next_code[len]++, len);
16148
16149 //Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
16150 // n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
16151 }
16152}
16153
16154
16155/* ===========================================================================
16156 * Initialize the various 'constant' tables.
16157 */
16158function tr_static_init() {
16159 let n; /* iterates over tree elements */
16160 let bits; /* bit counter */
16161 let length; /* length value */
16162 let code; /* code value */
16163 let dist; /* distance index */
16164 const bl_count = new Array(MAX_BITS + 1);
16165 /* number of codes at each bit length for an optimal tree */
16166
16167 // do check in _tr_init()
16168 //if (static_init_done) return;
16169
16170 /* For some embedded targets, global variables are not initialized: */
16171 /*#ifdef NO_INIT_GLOBAL_POINTERS
16172 static_l_desc.static_tree = static_ltree;
16173 static_l_desc.extra_bits = extra_lbits;
16174 static_d_desc.static_tree = static_dtree;
16175 static_d_desc.extra_bits = extra_dbits;
16176 static_bl_desc.extra_bits = extra_blbits;
16177#endif*/
16178
16179 /* Initialize the mapping length (0..255) -> length code (0..28) */
16180 length = 0;
16181 for (code = 0; code < LENGTH_CODES - 1; code++) {
16182 base_length[code] = length;
16183 for (n = 0; n < 1 << extra_lbits[code]; n++) {
16184 _length_code[length++] = code;
16185 }
16186 }
16187 //Assert (length == 256, "tr_static_init: length != 256");
16188 /* Note that the length 255 (match length 258) can be represented
16189 * in two different ways: code 284 + 5 bits or code 285, so we
16190 * overwrite length_code[255] to use the best encoding:
16191 */
16192 _length_code[length - 1] = code;
16193
16194 /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
16195 dist = 0;
16196 for (code = 0; code < 16; code++) {
16197 base_dist[code] = dist;
16198 for (n = 0; n < 1 << extra_dbits[code]; n++) {
16199 _dist_code[dist++] = code;
16200 }
16201 }
16202 //Assert (dist == 256, "tr_static_init: dist != 256");
16203 dist >>= 7; /* from now on, all distances are divided by 128 */
16204 for (; code < D_CODES; code++) {
16205 base_dist[code] = dist << 7;
16206 for (n = 0; n < 1 << extra_dbits[code] - 7; n++) {
16207 _dist_code[256 + dist++] = code;
16208 }
16209 }
16210 //Assert (dist == 256, "tr_static_init: 256+dist != 512");
16211
16212 /* Construct the codes of the static literal tree */
16213 for (bits = 0; bits <= MAX_BITS; bits++) {
16214 bl_count[bits] = 0;
16215 }
16216
16217 n = 0;
16218 while (n <= 143) {
16219 static_ltree[n * 2 + 1]/*.Len*/ = 8;
16220 n++;
16221 bl_count[8]++;
16222 }
16223 while (n <= 255) {
16224 static_ltree[n * 2 + 1]/*.Len*/ = 9;
16225 n++;
16226 bl_count[9]++;
16227 }
16228 while (n <= 279) {
16229 static_ltree[n * 2 + 1]/*.Len*/ = 7;
16230 n++;
16231 bl_count[7]++;
16232 }
16233 while (n <= 287) {
16234 static_ltree[n * 2 + 1]/*.Len*/ = 8;
16235 n++;
16236 bl_count[8]++;
16237 }
16238 /* Codes 286 and 287 do not exist, but we must include them in the
16239 * tree construction to get a canonical Huffman tree (longest code
16240 * all ones)
16241 */
16242 gen_codes(static_ltree, L_CODES + 1, bl_count);
16243
16244 /* The static distance tree is trivial: */
16245 for (n = 0; n < D_CODES; n++) {
16246 static_dtree[n * 2 + 1]/*.Len*/ = 5;
16247 static_dtree[n * 2]/*.Code*/ = bi_reverse(n, 5);
16248 }
16249
16250 // Now data ready and we can init static trees
16251 static_l_desc = new StaticTreeDesc(static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS);
16252 static_d_desc = new StaticTreeDesc(static_dtree, extra_dbits, 0, D_CODES, MAX_BITS);
16253 static_bl_desc = new StaticTreeDesc(new Array(0), extra_blbits, 0, BL_CODES, MAX_BL_BITS);
16254
16255 //static_init_done = true;
16256}
16257
16258
16259/* ===========================================================================
16260 * Initialize a new block.
16261 */
16262function init_block(s) {
16263 let n; /* iterates over tree elements */
16264
16265 /* Initialize the trees. */
16266 for (n = 0; n < L_CODES; n++) {
16267 s.dyn_ltree[n * 2]/*.Freq*/ = 0;
16268 }
16269 for (n = 0; n < D_CODES; n++) {
16270 s.dyn_dtree[n * 2]/*.Freq*/ = 0;
16271 }
16272 for (n = 0; n < BL_CODES; n++) {
16273 s.bl_tree[n * 2]/*.Freq*/ = 0;
16274 }
16275
16276 s.dyn_ltree[END_BLOCK * 2]/*.Freq*/ = 1;
16277 s.opt_len = s.static_len = 0;
16278 s.last_lit = s.matches = 0;
16279}
16280
16281
16282/* ===========================================================================
16283 * Flush the bit buffer and align the output on a byte boundary
16284 */
16285function bi_windup(s) {
16286 if (s.bi_valid > 8) {
16287 put_short(s, s.bi_buf);
16288 } else if (s.bi_valid > 0) {
16289 //put_byte(s, (Byte)s->bi_buf);
16290 s.pending_buf[s.pending++] = s.bi_buf;
16291 }
16292 s.bi_buf = 0;
16293 s.bi_valid = 0;
16294}
16295
16296/* ===========================================================================
16297 * Copy a stored block, storing first the length and its
16298 * one's complement if requested.
16299 */
16300function copy_block(s, buf, len, header)
16301//DeflateState *s;
16302//charf *buf; /* the input data */
16303//unsigned len; /* its length */
16304//int header; /* true if block header must be written */
16305{
16306 bi_windup(s); /* align on byte boundary */
16307
16308 if (header) {
16309 put_short(s, len);
16310 put_short(s, ~len);
16311 }
16312 // while (len--) {
16313 // put_byte(s, *buf++);
16314 // }
16315 arraySet(s.pending_buf, s.window, buf, len, s.pending);
16316 s.pending += len;
16317}
16318
16319/* ===========================================================================
16320 * Compares to subtrees, using the tree depth as tie breaker when
16321 * the subtrees have equal frequency. This minimizes the worst case length.
16322 */
16323function smaller(tree, n, m, depth) {
16324 const _n2 = n * 2;
16325 const _m2 = m * 2;
16326 return tree[_n2]/*.Freq*/ < tree[_m2]/*.Freq*/ ||
16327 tree[_n2]/*.Freq*/ === tree[_m2]/*.Freq*/ && depth[n] <= depth[m];
16328}
16329
16330/* ===========================================================================
16331 * Restore the heap property by moving down the tree starting at node k,
16332 * exchanging a node with the smallest of its two sons if necessary, stopping
16333 * when the heap property is re-established (each father smaller than its
16334 * two sons).
16335 */
16336function pqdownheap(s, tree, k)
16337// deflate_state *s;
16338// ct_data *tree; /* the tree to restore */
16339// int k; /* node to move down */
16340{
16341 const v = s.heap[k];
16342 let j = k << 1; /* left son of k */
16343 while (j <= s.heap_len) {
16344 /* Set j to the smallest of the two sons: */
16345 if (j < s.heap_len &&
16346 smaller(tree, s.heap[j + 1], s.heap[j], s.depth)) {
16347 j++;
16348 }
16349 /* Exit if v is smaller than both sons */
16350 if (smaller(tree, v, s.heap[j], s.depth)) {
16351 break;
16352 }
16353
16354 /* Exchange v with the smallest son */
16355 s.heap[k] = s.heap[j];
16356 k = j;
16357
16358 /* And continue down the tree, setting j to the left son of k */
16359 j <<= 1;
16360 }
16361 s.heap[k] = v;
16362}
16363
16364
16365// inlined manually
16366// var SMALLEST = 1;
16367
16368/* ===========================================================================
16369 * Send the block data compressed using the given Huffman trees
16370 */
16371function compress_block(s, ltree, dtree)
16372// deflate_state *s;
16373// const ct_data *ltree; /* literal tree */
16374// const ct_data *dtree; /* distance tree */
16375{
16376 let dist; /* distance of matched string */
16377 let lc; /* match length or unmatched char (if dist == 0) */
16378 let lx = 0; /* running index in l_buf */
16379 let code; /* the code to send */
16380 let extra; /* number of extra bits to send */
16381
16382 if (s.last_lit !== 0) {
16383 do {
16384 dist = s.pending_buf[s.d_buf + lx * 2] << 8 | s.pending_buf[s.d_buf + lx * 2 + 1];
16385 lc = s.pending_buf[s.l_buf + lx];
16386 lx++;
16387
16388 if (dist === 0) {
16389 send_code(s, lc, ltree); /* send a literal byte */
16390 //Tracecv(isgraph(lc), (stderr," '%c' ", lc));
16391 } else {
16392 /* Here, lc is the match length - MIN_MATCH */
16393 code = _length_code[lc];
16394 send_code(s, code + LITERALS + 1, ltree); /* send the length code */
16395 extra = extra_lbits[code];
16396 if (extra !== 0) {
16397 lc -= base_length[code];
16398 send_bits(s, lc, extra); /* send the extra length bits */
16399 }
16400 dist--; /* dist is now the match distance - 1 */
16401 code = d_code(dist);
16402 //Assert (code < D_CODES, "bad d_code");
16403
16404 send_code(s, code, dtree); /* send the distance code */
16405 extra = extra_dbits[code];
16406 if (extra !== 0) {
16407 dist -= base_dist[code];
16408 send_bits(s, dist, extra); /* send the extra distance bits */
16409 }
16410 } /* literal or match pair ? */
16411
16412 /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
16413 //Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
16414 // "pendingBuf overflow");
16415
16416 } while (lx < s.last_lit);
16417 }
16418
16419 send_code(s, END_BLOCK, ltree);
16420}
16421
16422
16423/* ===========================================================================
16424 * Construct one Huffman tree and assigns the code bit strings and lengths.
16425 * Update the total bit length for the current block.
16426 * IN assertion: the field freq is set for all tree elements.
16427 * OUT assertions: the fields len and code are set to the optimal bit length
16428 * and corresponding code. The length opt_len is updated; static_len is
16429 * also updated if stree is not null. The field max_code is set.
16430 */
16431function build_tree(s, desc)
16432// deflate_state *s;
16433// tree_desc *desc; /* the tree descriptor */
16434{
16435 const tree = desc.dyn_tree;
16436 const stree = desc.stat_desc.static_tree;
16437 const has_stree = desc.stat_desc.has_stree;
16438 const elems = desc.stat_desc.elems;
16439 let n, m; /* iterate over heap elements */
16440 let max_code = -1; /* largest code with non zero frequency */
16441 let node; /* new node being created */
16442
16443 /* Construct the initial heap, with least frequent element in
16444 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
16445 * heap[0] is not used.
16446 */
16447 s.heap_len = 0;
16448 s.heap_max = HEAP_SIZE;
16449
16450 for (n = 0; n < elems; n++) {
16451 if (tree[n * 2]/*.Freq*/ !== 0) {
16452 s.heap[++s.heap_len] = max_code = n;
16453 s.depth[n] = 0;
16454
16455 } else {
16456 tree[n * 2 + 1]/*.Len*/ = 0;
16457 }
16458 }
16459
16460 /* The pkzip format requires that at least one distance code exists,
16461 * and that at least one bit should be sent even if there is only one
16462 * possible code. So to avoid special checks later on we force at least
16463 * two codes of non zero frequency.
16464 */
16465 while (s.heap_len < 2) {
16466 node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
16467 tree[node * 2]/*.Freq*/ = 1;
16468 s.depth[node] = 0;
16469 s.opt_len--;
16470
16471 if (has_stree) {
16472 s.static_len -= stree[node * 2 + 1]/*.Len*/;
16473 }
16474 /* node is 0 or 1 so it does not have extra bits */
16475 }
16476 desc.max_code = max_code;
16477
16478 /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
16479 * establish sub-heaps of increasing lengths:
16480 */
16481 for (n = s.heap_len >> 1/*int /2*/; n >= 1; n--) {
16482 pqdownheap(s, tree, n);
16483 }
16484
16485 /* Construct the Huffman tree by repeatedly combining the least two
16486 * frequent nodes.
16487 */
16488 node = elems; /* next internal node of the tree */
16489 do {
16490 //pqremove(s, tree, n); /* n = node of least frequency */
16491 /*** pqremove ***/
16492 n = s.heap[1/*SMALLEST*/];
16493 s.heap[1/*SMALLEST*/] = s.heap[s.heap_len--];
16494 pqdownheap(s, tree, 1/*SMALLEST*/);
16495 /***/
16496
16497 m = s.heap[1/*SMALLEST*/]; /* m = node of next least frequency */
16498
16499 s.heap[--s.heap_max] = n; /* keep the nodes sorted by frequency */
16500 s.heap[--s.heap_max] = m;
16501
16502 /* Create a new node father of n and m */
16503 tree[node * 2]/*.Freq*/ = tree[n * 2]/*.Freq*/ + tree[m * 2]/*.Freq*/;
16504 s.depth[node] = (s.depth[n] >= s.depth[m] ? s.depth[n] : s.depth[m]) + 1;
16505 tree[n * 2 + 1]/*.Dad*/ = tree[m * 2 + 1]/*.Dad*/ = node;
16506
16507 /* and insert the new node in the heap */
16508 s.heap[1/*SMALLEST*/] = node++;
16509 pqdownheap(s, tree, 1/*SMALLEST*/);
16510
16511 } while (s.heap_len >= 2);
16512
16513 s.heap[--s.heap_max] = s.heap[1/*SMALLEST*/];
16514
16515 /* At this point, the fields freq and dad are set. We can now
16516 * generate the bit lengths.
16517 */
16518 gen_bitlen(s, desc);
16519
16520 /* The field len is now set, we can generate the bit codes */
16521 gen_codes(tree, max_code, s.bl_count);
16522}
16523
16524
16525/* ===========================================================================
16526 * Scan a literal or distance tree to determine the frequencies of the codes
16527 * in the bit length tree.
16528 */
16529function scan_tree(s, tree, max_code)
16530// deflate_state *s;
16531// ct_data *tree; /* the tree to be scanned */
16532// int max_code; /* and its largest code of non zero frequency */
16533{
16534 let n; /* iterates over all tree elements */
16535 let prevlen = -1; /* last emitted length */
16536 let curlen; /* length of current code */
16537
16538 let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
16539
16540 let count = 0; /* repeat count of the current code */
16541 let max_count = 7; /* max repeat count */
16542 let min_count = 4; /* min repeat count */
16543
16544 if (nextlen === 0) {
16545 max_count = 138;
16546 min_count = 3;
16547 }
16548 tree[(max_code + 1) * 2 + 1]/*.Len*/ = 0xffff; /* guard */
16549
16550 for (n = 0; n <= max_code; n++) {
16551 curlen = nextlen;
16552 nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
16553
16554 if (++count < max_count && curlen === nextlen) {
16555 continue;
16556
16557 } else if (count < min_count) {
16558 s.bl_tree[curlen * 2]/*.Freq*/ += count;
16559
16560 } else if (curlen !== 0) {
16561
16562 if (curlen !== prevlen) {
16563 s.bl_tree[curlen * 2]/*.Freq*/++;
16564 }
16565 s.bl_tree[REP_3_6 * 2]/*.Freq*/++;
16566
16567 } else if (count <= 10) {
16568 s.bl_tree[REPZ_3_10 * 2]/*.Freq*/++;
16569
16570 } else {
16571 s.bl_tree[REPZ_11_138 * 2]/*.Freq*/++;
16572 }
16573
16574 count = 0;
16575 prevlen = curlen;
16576
16577 if (nextlen === 0) {
16578 max_count = 138;
16579 min_count = 3;
16580
16581 } else if (curlen === nextlen) {
16582 max_count = 6;
16583 min_count = 3;
16584
16585 } else {
16586 max_count = 7;
16587 min_count = 4;
16588 }
16589 }
16590}
16591
16592
16593/* ===========================================================================
16594 * Send a literal or distance tree in compressed form, using the codes in
16595 * bl_tree.
16596 */
16597function send_tree(s, tree, max_code)
16598// deflate_state *s;
16599// ct_data *tree; /* the tree to be scanned */
16600// int max_code; /* and its largest code of non zero frequency */
16601{
16602 let n; /* iterates over all tree elements */
16603 let prevlen = -1; /* last emitted length */
16604 let curlen; /* length of current code */
16605
16606 let nextlen = tree[0 * 2 + 1]/*.Len*/; /* length of next code */
16607
16608 let count = 0; /* repeat count of the current code */
16609 let max_count = 7; /* max repeat count */
16610 let min_count = 4; /* min repeat count */
16611
16612 /* tree[max_code+1].Len = -1; */ /* guard already set */
16613 if (nextlen === 0) {
16614 max_count = 138;
16615 min_count = 3;
16616 }
16617
16618 for (n = 0; n <= max_code; n++) {
16619 curlen = nextlen;
16620 nextlen = tree[(n + 1) * 2 + 1]/*.Len*/;
16621
16622 if (++count < max_count && curlen === nextlen) {
16623 continue;
16624
16625 } else if (count < min_count) {
16626 do {
16627 send_code(s, curlen, s.bl_tree);
16628 } while (--count !== 0);
16629
16630 } else if (curlen !== 0) {
16631 if (curlen !== prevlen) {
16632 send_code(s, curlen, s.bl_tree);
16633 count--;
16634 }
16635 //Assert(count >= 3 && count <= 6, " 3_6?");
16636 send_code(s, REP_3_6, s.bl_tree);
16637 send_bits(s, count - 3, 2);
16638
16639 } else if (count <= 10) {
16640 send_code(s, REPZ_3_10, s.bl_tree);
16641 send_bits(s, count - 3, 3);
16642
16643 } else {
16644 send_code(s, REPZ_11_138, s.bl_tree);
16645 send_bits(s, count - 11, 7);
16646 }
16647
16648 count = 0;
16649 prevlen = curlen;
16650 if (nextlen === 0) {
16651 max_count = 138;
16652 min_count = 3;
16653
16654 } else if (curlen === nextlen) {
16655 max_count = 6;
16656 min_count = 3;
16657
16658 } else {
16659 max_count = 7;
16660 min_count = 4;
16661 }
16662 }
16663}
16664
16665
16666/* ===========================================================================
16667 * Construct the Huffman tree for the bit lengths and return the index in
16668 * bl_order of the last bit length code to send.
16669 */
16670function build_bl_tree(s) {
16671 let max_blindex; /* index of last bit length code of non zero freq */
16672
16673 /* Determine the bit length frequencies for literal and distance trees */
16674 scan_tree(s, s.dyn_ltree, s.l_desc.max_code);
16675 scan_tree(s, s.dyn_dtree, s.d_desc.max_code);
16676
16677 /* Build the bit length tree: */
16678 build_tree(s, s.bl_desc);
16679 /* opt_len now includes the length of the tree representations, except
16680 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
16681 */
16682
16683 /* Determine the number of bit length codes to send. The pkzip format
16684 * requires that at least 4 bit length codes be sent. (appnote.txt says
16685 * 3 but the actual value used is 4.)
16686 */
16687 for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
16688 if (s.bl_tree[bl_order[max_blindex] * 2 + 1]/*.Len*/ !== 0) {
16689 break;
16690 }
16691 }
16692 /* Update opt_len to include the bit length tree and counts */
16693 s.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
16694 //Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
16695 // s->opt_len, s->static_len));
16696
16697 return max_blindex;
16698}
16699
16700
16701/* ===========================================================================
16702 * Send the header for a block using dynamic Huffman trees: the counts, the
16703 * lengths of the bit length codes, the literal tree and the distance tree.
16704 * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
16705 */
16706function send_all_trees(s, lcodes, dcodes, blcodes)
16707// deflate_state *s;
16708// int lcodes, dcodes, blcodes; /* number of codes for each tree */
16709{
16710 let rank; /* index in bl_order */
16711
16712 //Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
16713 //Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
16714 // "too many codes");
16715 //Tracev((stderr, "\nbl counts: "));
16716 send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */
16717 send_bits(s, dcodes - 1, 5);
16718 send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */
16719 for (rank = 0; rank < blcodes; rank++) {
16720 //Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
16721 send_bits(s, s.bl_tree[bl_order[rank] * 2 + 1]/*.Len*/, 3);
16722 }
16723 //Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
16724
16725 send_tree(s, s.dyn_ltree, lcodes - 1); /* literal tree */
16726 //Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
16727
16728 send_tree(s, s.dyn_dtree, dcodes - 1); /* distance tree */
16729 //Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
16730}
16731
16732
16733/* ===========================================================================
16734 * Check if the data type is TEXT or BINARY, using the following algorithm:
16735 * - TEXT if the two conditions below are satisfied:
16736 * a) There are no non-portable control characters belonging to the
16737 * "black list" (0..6, 14..25, 28..31).
16738 * b) There is at least one printable character belonging to the
16739 * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
16740 * - BINARY otherwise.
16741 * - The following partially-portable control characters form a
16742 * "gray list" that is ignored in this detection algorithm:
16743 * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
16744 * IN assertion: the fields Freq of dyn_ltree are set.
16745 */
16746function detect_data_type(s) {
16747 /* black_mask is the bit mask of black-listed bytes
16748 * set bits 0..6, 14..25, and 28..31
16749 * 0xf3ffc07f = binary 11110011111111111100000001111111
16750 */
16751 let black_mask = 0xf3ffc07f;
16752 let n;
16753
16754 /* Check for non-textual ("black-listed") bytes. */
16755 for (n = 0; n <= 31; n++, black_mask >>>= 1) {
16756 if (black_mask & 1 && s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
16757 return Z_BINARY;
16758 }
16759 }
16760
16761 /* Check for textual ("white-listed") bytes. */
16762 if (s.dyn_ltree[9 * 2]/*.Freq*/ !== 0 || s.dyn_ltree[10 * 2]/*.Freq*/ !== 0 ||
16763 s.dyn_ltree[13 * 2]/*.Freq*/ !== 0) {
16764 return Z_TEXT;
16765 }
16766 for (n = 32; n < LITERALS; n++) {
16767 if (s.dyn_ltree[n * 2]/*.Freq*/ !== 0) {
16768 return Z_TEXT;
16769 }
16770 }
16771
16772 /* There are no "black-listed" or "white-listed" bytes:
16773 * this stream either is empty or has tolerated ("gray-listed") bytes only.
16774 */
16775 return Z_BINARY;
16776}
16777
16778
16779let static_init_done = false;
16780
16781/* ===========================================================================
16782 * Initialize the tree data structures for a new zlib stream.
16783 */
16784function _tr_init(s) {
16785
16786 if (!static_init_done) {
16787 tr_static_init();
16788 static_init_done = true;
16789 }
16790
16791 s.l_desc = new TreeDesc(s.dyn_ltree, static_l_desc);
16792 s.d_desc = new TreeDesc(s.dyn_dtree, static_d_desc);
16793 s.bl_desc = new TreeDesc(s.bl_tree, static_bl_desc);
16794
16795 s.bi_buf = 0;
16796 s.bi_valid = 0;
16797
16798 /* Initialize the first block of the first file: */
16799 init_block(s);
16800}
16801
16802
16803/* ===========================================================================
16804 * Send a stored block
16805 */
16806function _tr_stored_block(s, buf, stored_len, last)
16807//DeflateState *s;
16808//charf *buf; /* input block */
16809//ulg stored_len; /* length of input block */
16810//int last; /* one if this is the last block for a file */
16811{
16812 send_bits(s, (STORED_BLOCK << 1) + (last ? 1 : 0), 3); /* send block type */
16813 copy_block(s, buf, stored_len, true); /* with header */
16814}
16815
16816
16817/* ===========================================================================
16818 * Send one empty static block to give enough lookahead for inflate.
16819 * This takes 10 bits, of which 7 may remain in the bit buffer.
16820 */
16821function _tr_align(s) {
16822 send_bits(s, STATIC_TREES << 1, 3);
16823 send_code(s, END_BLOCK, static_ltree);
16824 bi_flush(s);
16825}
16826
16827
16828/* ===========================================================================
16829 * Determine the best encoding for the current block: dynamic trees, static
16830 * trees or store, and output the encoded block to the zip file.
16831 */
16832function _tr_flush_block(s, buf, stored_len, last)
16833//DeflateState *s;
16834//charf *buf; /* input block, or NULL if too old */
16835//ulg stored_len; /* length of input block */
16836//int last; /* one if this is the last block for a file */
16837{
16838 let opt_lenb, static_lenb; /* opt_len and static_len in bytes */
16839 let max_blindex = 0; /* index of last bit length code of non zero freq */
16840
16841 /* Build the Huffman trees unless a stored block is forced */
16842 if (s.level > 0) {
16843
16844 /* Check if the file is binary or text */
16845 if (s.strm.data_type === Z_UNKNOWN) {
16846 s.strm.data_type = detect_data_type(s);
16847 }
16848
16849 /* Construct the literal and distance trees */
16850 build_tree(s, s.l_desc);
16851 // Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
16852 // s->static_len));
16853
16854 build_tree(s, s.d_desc);
16855 // Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
16856 // s->static_len));
16857 /* At this point, opt_len and static_len are the total bit lengths of
16858 * the compressed block data, excluding the tree representations.
16859 */
16860
16861 /* Build the bit length tree for the above two trees, and get the index
16862 * in bl_order of the last bit length code to send.
16863 */
16864 max_blindex = build_bl_tree(s);
16865
16866 /* Determine the best encoding. Compute the block lengths in bytes. */
16867 opt_lenb = s.opt_len + 3 + 7 >>> 3;
16868 static_lenb = s.static_len + 3 + 7 >>> 3;
16869
16870 // Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
16871 // opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
16872 // s->last_lit));
16873
16874 if (static_lenb <= opt_lenb) {
16875 opt_lenb = static_lenb;
16876 }
16877
16878 } else {
16879 // Assert(buf != (char*)0, "lost buf");
16880 opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
16881 }
16882
16883 if (stored_len + 4 <= opt_lenb && buf !== -1) {
16884 /* 4: two words for the lengths */
16885
16886 /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
16887 * Otherwise we can't have processed more than WSIZE input bytes since
16888 * the last block flush, because compression would have been
16889 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
16890 * transform a block into a stored block.
16891 */
16892 _tr_stored_block(s, buf, stored_len, last);
16893
16894 } else if (s.strategy === Z_FIXED || static_lenb === opt_lenb) {
16895
16896 send_bits(s, (STATIC_TREES << 1) + (last ? 1 : 0), 3);
16897 compress_block(s, static_ltree, static_dtree);
16898
16899 } else {
16900 send_bits(s, (DYN_TREES << 1) + (last ? 1 : 0), 3);
16901 send_all_trees(s, s.l_desc.max_code + 1, s.d_desc.max_code + 1, max_blindex + 1);
16902 compress_block(s, s.dyn_ltree, s.dyn_dtree);
16903 }
16904 // Assert (s->compressed_len == s->bits_sent, "bad compressed size");
16905 /* The above check is made mod 2^32, for files larger than 512 MB
16906 * and uLong implemented on 32 bits.
16907 */
16908 init_block(s);
16909
16910 if (last) {
16911 bi_windup(s);
16912 }
16913 // Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
16914 // s->compressed_len-7*last));
16915}
16916
16917/* ===========================================================================
16918 * Save the match info and tally the frequency counts. Return true if
16919 * the current block must be flushed.
16920 */
16921function _tr_tally(s, dist, lc)
16922// deflate_state *s;
16923// unsigned dist; /* distance of matched string */
16924// unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
16925{
16926 //var out_length, in_length, dcode;
16927
16928 s.pending_buf[s.d_buf + s.last_lit * 2] = dist >>> 8 & 0xff;
16929 s.pending_buf[s.d_buf + s.last_lit * 2 + 1] = dist & 0xff;
16930
16931 s.pending_buf[s.l_buf + s.last_lit] = lc & 0xff;
16932 s.last_lit++;
16933
16934 if (dist === 0) {
16935 /* lc is the unmatched char */
16936 s.dyn_ltree[lc * 2]/*.Freq*/++;
16937 } else {
16938 s.matches++;
16939 /* Here, lc is the match length - MIN_MATCH */
16940 dist--; /* dist = match distance - 1 */
16941 //Assert((ush)dist < (ush)MAX_DIST(s) &&
16942 // (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
16943 // (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
16944
16945 s.dyn_ltree[(_length_code[lc] + LITERALS + 1) * 2]/*.Freq*/++;
16946 s.dyn_dtree[d_code(dist) * 2]/*.Freq*/++;
16947 }
16948
16949 // (!) This block is disabled in zlib defaults,
16950 // don't enable it for binary compatibility
16951
16952 //#ifdef TRUNCATE_BLOCK
16953 // /* Try to guess if it is profitable to stop the current block here */
16954 // if ((s.last_lit & 0x1fff) === 0 && s.level > 2) {
16955 // /* Compute an upper bound for the compressed length */
16956 // out_length = s.last_lit*8;
16957 // in_length = s.strstart - s.block_start;
16958 //
16959 // for (dcode = 0; dcode < D_CODES; dcode++) {
16960 // out_length += s.dyn_dtree[dcode*2]/*.Freq*/ * (5 + extra_dbits[dcode]);
16961 // }
16962 // out_length >>>= 3;
16963 // //Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
16964 // // s->last_lit, in_length, out_length,
16965 // // 100L - out_length*100L/in_length));
16966 // if (s.matches < (s.last_lit>>1)/*int /2*/ && out_length < (in_length>>1)/*int /2*/) {
16967 // return true;
16968 // }
16969 // }
16970 //#endif
16971
16972 return s.last_lit === s.lit_bufsize - 1;
16973 /* We avoid equality with lit_bufsize because of wraparound at 64K
16974 * on 16 bit machines and because stored blocks are restricted to
16975 * 64K-1 bytes.
16976 */
16977}
16978
16979// Note: adler32 takes 12% for level 0 and 2% for level 6.
16980// It isn't worth it to make additional optimizations as in original.
16981// Small size is preferable.
16982
16983// (C) 1995-2013 Jean-loup Gailly and Mark Adler
16984// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
16985//
16986// This software is provided 'as-is', without any express or implied
16987// warranty. In no event will the authors be held liable for any damages
16988// arising from the use of this software.
16989//
16990// Permission is granted to anyone to use this software for any purpose,
16991// including commercial applications, and to alter it and redistribute it
16992// freely, subject to the following restrictions:
16993//
16994// 1. The origin of this software must not be misrepresented; you must not
16995// claim that you wrote the original software. If you use this software
16996// in a product, an acknowledgment in the product documentation would be
16997// appreciated but is not required.
16998// 2. Altered source versions must be plainly marked as such, and must not be
16999// misrepresented as being the original software.
17000// 3. This notice may not be removed or altered from any source distribution.
17001
17002function adler32(adler, buf, len, pos) {
17003 let s1 = adler & 0xffff |0,
17004 s2 = adler >>> 16 & 0xffff |0,
17005 n = 0;
17006
17007 while (len !== 0) {
17008 // Set limit ~ twice less than 5552, to keep
17009 // s2 in 31-bits, because we force signed ints.
17010 // in other case %= will fail.
17011 n = len > 2000 ? 2000 : len;
17012 len -= n;
17013
17014 do {
17015 s1 = s1 + buf[pos++] |0;
17016 s2 = s2 + s1 |0;
17017 } while (--n);
17018
17019 s1 %= 65521;
17020 s2 %= 65521;
17021 }
17022
17023 return s1 | s2 << 16 |0;
17024}
17025
17026// Note: we can't get significant speed boost here.
17027// So write code to minimize size - no pregenerated tables
17028// and array tools dependencies.
17029
17030// (C) 1995-2013 Jean-loup Gailly and Mark Adler
17031// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
17032//
17033// This software is provided 'as-is', without any express or implied
17034// warranty. In no event will the authors be held liable for any damages
17035// arising from the use of this software.
17036//
17037// Permission is granted to anyone to use this software for any purpose,
17038// including commercial applications, and to alter it and redistribute it
17039// freely, subject to the following restrictions:
17040//
17041// 1. The origin of this software must not be misrepresented; you must not
17042// claim that you wrote the original software. If you use this software
17043// in a product, an acknowledgment in the product documentation would be
17044// appreciated but is not required.
17045// 2. Altered source versions must be plainly marked as such, and must not be
17046// misrepresented as being the original software.
17047// 3. This notice may not be removed or altered from any source distribution.
17048
17049// Use ordinary array, since untyped makes no boost here
17050function makeTable() {
17051 let c;
17052 const table = [];
17053
17054 for (let n = 0; n < 256; n++) {
17055 c = n;
17056 for (let k = 0; k < 8; k++) {
17057 c = c & 1 ? 0xEDB88320 ^ c >>> 1 : c >>> 1;
17058 }
17059 table[n] = c;
17060 }
17061
17062 return table;
17063}
17064
17065// Create table on load. Just 255 signed longs. Not a problem.
17066const crcTable = makeTable();
17067
17068
17069function crc32(crc, buf, len, pos) {
17070 const t = crcTable,
17071 end = pos + len;
17072
17073 crc ^= -1;
17074
17075 for (let i = pos; i < end; i++) {
17076 crc = crc >>> 8 ^ t[(crc ^ buf[i]) & 0xFF];
17077 }
17078
17079 return crc ^ -1; // >>> 0;
17080}
17081
17082// (C) 1995-2013 Jean-loup Gailly and Mark Adler
17083// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
17084//
17085// This software is provided 'as-is', without any express or implied
17086// warranty. In no event will the authors be held liable for any damages
17087// arising from the use of this software.
17088//
17089// Permission is granted to anyone to use this software for any purpose,
17090// including commercial applications, and to alter it and redistribute it
17091// freely, subject to the following restrictions:
17092//
17093// 1. The origin of this software must not be misrepresented; you must not
17094// claim that you wrote the original software. If you use this software
17095// in a product, an acknowledgment in the product documentation would be
17096// appreciated but is not required.
17097// 2. Altered source versions must be plainly marked as such, and must not be
17098// misrepresented as being the original software.
17099// 3. This notice may not be removed or altered from any source distribution.
17100
17101var msg = {
17102 2: "need dictionary", /* Z_NEED_DICT 2 */
17103 1: "stream end", /* Z_STREAM_END 1 */
17104 0: "", /* Z_OK 0 */
17105 "-1": "file error", /* Z_ERRNO (-1) */
17106 "-2": "stream error", /* Z_STREAM_ERROR (-2) */
17107 "-3": "data error", /* Z_DATA_ERROR (-3) */
17108 "-4": "insufficient memory", /* Z_MEM_ERROR (-4) */
17109 "-5": "buffer error", /* Z_BUF_ERROR (-5) */
17110 "-6": "incompatible version" /* Z_VERSION_ERROR (-6) */
17111};
17112
17113/*============================================================================*/
17114
17115
17116const MAX_MEM_LEVEL = 9;
17117
17118
17119const LENGTH_CODES$1 = 29;
17120/* number of length codes, not counting the special END_BLOCK code */
17121const LITERALS$1 = 256;
17122/* number of literal bytes 0..255 */
17123const L_CODES$1 = LITERALS$1 + 1 + LENGTH_CODES$1;
17124/* number of Literal or Length codes, including the END_BLOCK code */
17125const D_CODES$1 = 30;
17126/* number of distance codes */
17127const BL_CODES$1 = 19;
17128/* number of codes used to transfer the bit lengths */
17129const HEAP_SIZE$1 = 2 * L_CODES$1 + 1;
17130/* maximum heap size */
17131const MAX_BITS$1 = 15;
17132/* All codes must not exceed MAX_BITS bits */
17133
17134const MIN_MATCH$1 = 3;
17135const MAX_MATCH$1 = 258;
17136const MIN_LOOKAHEAD = (MAX_MATCH$1 + MIN_MATCH$1 + 1);
17137
17138const PRESET_DICT = 0x20;
17139
17140const INIT_STATE = 42;
17141const EXTRA_STATE = 69;
17142const NAME_STATE = 73;
17143const COMMENT_STATE = 91;
17144const HCRC_STATE = 103;
17145const BUSY_STATE = 113;
17146const FINISH_STATE = 666;
17147
17148const BS_NEED_MORE = 1; /* block not completed, need more input or more output */
17149const BS_BLOCK_DONE = 2; /* block flush performed */
17150const BS_FINISH_STARTED = 3; /* finish started, need only more output at next deflate */
17151const BS_FINISH_DONE = 4; /* finish done, accept no more input or output */
17152
17153const OS_CODE = 0x03; // Unix :) . Don't detect, use this default.
17154
17155function err(strm, errorCode) {
17156 strm.msg = msg[errorCode];
17157 return errorCode;
17158}
17159
17160function rank(f) {
17161 return ((f) << 1) - ((f) > 4 ? 9 : 0);
17162}
17163
17164function zero$2(buf) { let len = buf.length; while (--len >= 0) { buf[len] = 0; } }
17165
17166
17167/* =========================================================================
17168 * Flush as much pending output as possible. All deflate() output goes
17169 * through this function so some applications may wish to modify it
17170 * to avoid allocating a large strm->output buffer and copying into it.
17171 * (See also read_buf()).
17172 */
17173function flush_pending(strm) {
17174 const s = strm.state;
17175
17176 //_tr_flush_bits(s);
17177 let len = s.pending;
17178 if (len > strm.avail_out) {
17179 len = strm.avail_out;
17180 }
17181 if (len === 0) { return; }
17182
17183 arraySet(strm.output, s.pending_buf, s.pending_out, len, strm.next_out);
17184 strm.next_out += len;
17185 s.pending_out += len;
17186 strm.total_out += len;
17187 strm.avail_out -= len;
17188 s.pending -= len;
17189 if (s.pending === 0) {
17190 s.pending_out = 0;
17191 }
17192}
17193
17194
17195function flush_block_only(s, last) {
17196 _tr_flush_block(s, (s.block_start >= 0 ? s.block_start : -1), s.strstart - s.block_start, last);
17197 s.block_start = s.strstart;
17198 flush_pending(s.strm);
17199}
17200
17201
17202function put_byte(s, b) {
17203 s.pending_buf[s.pending++] = b;
17204}
17205
17206
17207/* =========================================================================
17208 * Put a short in the pending buffer. The 16-bit value is put in MSB order.
17209 * IN assertion: the stream state is correct and there is enough room in
17210 * pending_buf.
17211 */
17212function putShortMSB(s, b) {
17213 // put_byte(s, (Byte)(b >> 8));
17214 // put_byte(s, (Byte)(b & 0xff));
17215 s.pending_buf[s.pending++] = (b >>> 8) & 0xff;
17216 s.pending_buf[s.pending++] = b & 0xff;
17217}
17218
17219
17220/* ===========================================================================
17221 * Read a new buffer from the current input stream, update the adler32
17222 * and total number of bytes read. All deflate() input goes through
17223 * this function so some applications may wish to modify it to avoid
17224 * allocating a large strm->input buffer and copying from it.
17225 * (See also flush_pending()).
17226 */
17227function read_buf(strm, buf, start, size) {
17228 let len = strm.avail_in;
17229
17230 if (len > size) { len = size; }
17231 if (len === 0) { return 0; }
17232
17233 strm.avail_in -= len;
17234
17235 // zmemcpy(buf, strm->next_in, len);
17236 arraySet(buf, strm.input, strm.next_in, len, start);
17237 if (strm.state.wrap === 1) {
17238 strm.adler = adler32(strm.adler, buf, len, start);
17239 }
17240
17241 else if (strm.state.wrap === 2) {
17242 strm.adler = crc32(strm.adler, buf, len, start);
17243 }
17244
17245 strm.next_in += len;
17246 strm.total_in += len;
17247
17248 return len;
17249}
17250
17251
17252/* ===========================================================================
17253 * Set match_start to the longest match starting at the given string and
17254 * return its length. Matches shorter or equal to prev_length are discarded,
17255 * in which case the result is equal to prev_length and match_start is
17256 * garbage.
17257 * IN assertions: cur_match is the head of the hash chain for the current
17258 * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
17259 * OUT assertion: the match length is not greater than s->lookahead.
17260 */
17261function longest_match(s, cur_match) {
17262 let chain_length = s.max_chain_length; /* max hash chain length */
17263 let scan = s.strstart; /* current string */
17264 let match; /* matched string */
17265 let len; /* length of current match */
17266 let best_len = s.prev_length; /* best match length so far */
17267 let nice_match = s.nice_match; /* stop if match long enough */
17268 const limit = (s.strstart > (s.w_size - MIN_LOOKAHEAD)) ?
17269 s.strstart - (s.w_size - MIN_LOOKAHEAD) : 0/*NIL*/;
17270
17271 const _win = s.window; // shortcut
17272
17273 const wmask = s.w_mask;
17274 const prev = s.prev;
17275
17276 /* Stop when cur_match becomes <= limit. To simplify the code,
17277 * we prevent matches with the string of window index 0.
17278 */
17279
17280 const strend = s.strstart + MAX_MATCH$1;
17281 let scan_end1 = _win[scan + best_len - 1];
17282 let scan_end = _win[scan + best_len];
17283
17284 /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
17285 * It is easy to get rid of this optimization if necessary.
17286 */
17287 // Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
17288
17289 /* Do not waste too much time if we already have a good match: */
17290 if (s.prev_length >= s.good_match) {
17291 chain_length >>= 2;
17292 }
17293 /* Do not look for matches beyond the end of the input. This is necessary
17294 * to make deflate deterministic.
17295 */
17296 if (nice_match > s.lookahead) { nice_match = s.lookahead; }
17297
17298 // Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
17299
17300 do {
17301 // Assert(cur_match < s->strstart, "no future");
17302 match = cur_match;
17303
17304 /* Skip to next match if the match length cannot increase
17305 * or if the match length is less than 2. Note that the checks below
17306 * for insufficient lookahead only occur occasionally for performance
17307 * reasons. Therefore uninitialized memory will be accessed, and
17308 * conditional jumps will be made that depend on those values.
17309 * However the length of the match is limited to the lookahead, so
17310 * the output of deflate is not affected by the uninitialized values.
17311 */
17312
17313 if (_win[match + best_len] !== scan_end ||
17314 _win[match + best_len - 1] !== scan_end1 ||
17315 _win[match] !== _win[scan] ||
17316 _win[++match] !== _win[scan + 1]) {
17317 continue;
17318 }
17319
17320 /* The check at best_len-1 can be removed because it will be made
17321 * again later. (This heuristic is not always a win.)
17322 * It is not necessary to compare scan[2] and match[2] since they
17323 * are always equal when the other bytes match, given that
17324 * the hash keys are equal and that HASH_BITS >= 8.
17325 */
17326 scan += 2;
17327 match++;
17328 // Assert(*scan == *match, "match[2]?");
17329
17330 /* We check for insufficient lookahead only every 8th comparison;
17331 * the 256th check will be made at strstart+258.
17332 */
17333 do {
17334 /*jshint noempty:false*/
17335 } while (_win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
17336 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
17337 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
17338 _win[++scan] === _win[++match] && _win[++scan] === _win[++match] &&
17339 scan < strend);
17340
17341 // Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
17342
17343 len = MAX_MATCH$1 - (strend - scan);
17344 scan = strend - MAX_MATCH$1;
17345
17346 if (len > best_len) {
17347 s.match_start = cur_match;
17348 best_len = len;
17349 if (len >= nice_match) {
17350 break;
17351 }
17352 scan_end1 = _win[scan + best_len - 1];
17353 scan_end = _win[scan + best_len];
17354 }
17355 } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length !== 0);
17356
17357 if (best_len <= s.lookahead) {
17358 return best_len;
17359 }
17360 return s.lookahead;
17361}
17362
17363
17364/* ===========================================================================
17365 * Fill the window when the lookahead becomes insufficient.
17366 * Updates strstart and lookahead.
17367 *
17368 * IN assertion: lookahead < MIN_LOOKAHEAD
17369 * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
17370 * At least one byte has been read, or avail_in == 0; reads are
17371 * performed for at least two bytes (required for the zip translate_eol
17372 * option -- not supported here).
17373 */
17374function fill_window(s) {
17375 const _w_size = s.w_size;
17376 let p, n, m, more, str;
17377
17378 //Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
17379
17380 do {
17381 more = s.window_size - s.lookahead - s.strstart;
17382
17383 // JS ints have 32 bit, block below not needed
17384 /* Deal with !@#$% 64K limit: */
17385 //if (sizeof(int) <= 2) {
17386 // if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
17387 // more = wsize;
17388 //
17389 // } else if (more == (unsigned)(-1)) {
17390 // /* Very unlikely, but possible on 16 bit machine if
17391 // * strstart == 0 && lookahead == 1 (input done a byte at time)
17392 // */
17393 // more--;
17394 // }
17395 //}
17396
17397
17398 /* If the window is almost full and there is insufficient lookahead,
17399 * move the upper half to the lower one to make room in the upper half.
17400 */
17401 if (s.strstart >= _w_size + (_w_size - MIN_LOOKAHEAD)) {
17402
17403 arraySet(s.window, s.window, _w_size, _w_size, 0);
17404 s.match_start -= _w_size;
17405 s.strstart -= _w_size;
17406 /* we now have strstart >= MAX_DIST */
17407 s.block_start -= _w_size;
17408
17409 /* Slide the hash table (could be avoided with 32 bit values
17410 at the expense of memory usage). We slide even when level == 0
17411 to keep the hash table consistent if we switch back to level > 0
17412 later. (Using level 0 permanently is not an optimal usage of
17413 zlib, so we don't care about this pathological case.)
17414 */
17415
17416 n = s.hash_size;
17417 p = n;
17418 do {
17419 m = s.head[--p];
17420 s.head[p] = (m >= _w_size ? m - _w_size : 0);
17421 } while (--n);
17422
17423 n = _w_size;
17424 p = n;
17425 do {
17426 m = s.prev[--p];
17427 s.prev[p] = (m >= _w_size ? m - _w_size : 0);
17428 /* If n is not on any hash chain, prev[n] is garbage but
17429 * its value will never be used.
17430 */
17431 } while (--n);
17432
17433 more += _w_size;
17434 }
17435 if (s.strm.avail_in === 0) {
17436 break;
17437 }
17438
17439 /* If there was no sliding:
17440 * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
17441 * more == window_size - lookahead - strstart
17442 * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
17443 * => more >= window_size - 2*WSIZE + 2
17444 * In the BIG_MEM or MMAP case (not yet supported),
17445 * window_size == input_size + MIN_LOOKAHEAD &&
17446 * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
17447 * Otherwise, window_size == 2*WSIZE so more >= 2.
17448 * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
17449 */
17450 //Assert(more >= 2, "more < 2");
17451 n = read_buf(s.strm, s.window, s.strstart + s.lookahead, more);
17452 s.lookahead += n;
17453
17454 /* Initialize the hash value now that we have some input: */
17455 if (s.lookahead + s.insert >= MIN_MATCH$1) {
17456 str = s.strstart - s.insert;
17457 s.ins_h = s.window[str];
17458
17459 /* UPDATE_HASH(s, s->ins_h, s->window[str + 1]); */
17460 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + 1]) & s.hash_mask;
17461 //#if MIN_MATCH != 3
17462 // Call update_hash() MIN_MATCH-3 more times
17463 //#endif
17464 while (s.insert) {
17465 /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
17466 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
17467
17468 s.prev[str & s.w_mask] = s.head[s.ins_h];
17469 s.head[s.ins_h] = str;
17470 str++;
17471 s.insert--;
17472 if (s.lookahead + s.insert < MIN_MATCH$1) {
17473 break;
17474 }
17475 }
17476 }
17477 /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
17478 * but this is not important since only literal bytes will be emitted.
17479 */
17480
17481 } while (s.lookahead < MIN_LOOKAHEAD && s.strm.avail_in !== 0);
17482
17483 /* If the WIN_INIT bytes after the end of the current data have never been
17484 * written, then zero those bytes in order to avoid memory check reports of
17485 * the use of uninitialized (or uninitialised as Julian writes) bytes by
17486 * the longest match routines. Update the high water mark for the next
17487 * time through here. WIN_INIT is set to MAX_MATCH since the longest match
17488 * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
17489 */
17490 // if (s.high_water < s.window_size) {
17491 // var curr = s.strstart + s.lookahead;
17492 // var init = 0;
17493 //
17494 // if (s.high_water < curr) {
17495 // /* Previous high water mark below current data -- zero WIN_INIT
17496 // * bytes or up to end of window, whichever is less.
17497 // */
17498 // init = s.window_size - curr;
17499 // if (init > WIN_INIT)
17500 // init = WIN_INIT;
17501 // zmemzero(s->window + curr, (unsigned)init);
17502 // s->high_water = curr + init;
17503 // }
17504 // else if (s->high_water < (ulg)curr + WIN_INIT) {
17505 // /* High water mark at or above current data, but below current data
17506 // * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
17507 // * to end of window, whichever is less.
17508 // */
17509 // init = (ulg)curr + WIN_INIT - s->high_water;
17510 // if (init > s->window_size - s->high_water)
17511 // init = s->window_size - s->high_water;
17512 // zmemzero(s->window + s->high_water, (unsigned)init);
17513 // s->high_water += init;
17514 // }
17515 // }
17516 //
17517 // Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
17518 // "not enough room for search");
17519}
17520
17521/* ===========================================================================
17522 * Copy without compression as much as possible from the input stream, return
17523 * the current block state.
17524 * This function does not insert new strings in the dictionary since
17525 * uncompressible data is probably not useful. This function is used
17526 * only for the level=0 compression option.
17527 * NOTE: this function should be optimized to avoid extra copying from
17528 * window to pending_buf.
17529 */
17530function deflate_stored(s, flush) {
17531 /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
17532 * to pending_buf_size, and each stored block has a 5 byte header:
17533 */
17534 let max_block_size = 0xffff;
17535
17536 if (max_block_size > s.pending_buf_size - 5) {
17537 max_block_size = s.pending_buf_size - 5;
17538 }
17539
17540 /* Copy as much as possible from input to output: */
17541 for (; ;) {
17542 /* Fill the window as much as possible: */
17543 if (s.lookahead <= 1) {
17544
17545 //Assert(s->strstart < s->w_size+MAX_DIST(s) ||
17546 // s->block_start >= (long)s->w_size, "slide too late");
17547 // if (!(s.strstart < s.w_size + (s.w_size - MIN_LOOKAHEAD) ||
17548 // s.block_start >= s.w_size)) {
17549 // throw new Error("slide too late");
17550 // }
17551
17552 fill_window(s);
17553 if (s.lookahead === 0 && flush === Z_NO_FLUSH) {
17554 return BS_NEED_MORE;
17555 }
17556
17557 if (s.lookahead === 0) {
17558 break;
17559 }
17560 /* flush the current block */
17561 }
17562 //Assert(s->block_start >= 0L, "block gone");
17563 // if (s.block_start < 0) throw new Error("block gone");
17564
17565 s.strstart += s.lookahead;
17566 s.lookahead = 0;
17567
17568 /* Emit a stored block if pending_buf will be full: */
17569 const max_start = s.block_start + max_block_size;
17570
17571 if (s.strstart === 0 || s.strstart >= max_start) {
17572 /* strstart == 0 is possible when wraparound on 16-bit machine */
17573 s.lookahead = s.strstart - max_start;
17574 s.strstart = max_start;
17575 /*** FLUSH_BLOCK(s, 0); ***/
17576 flush_block_only(s, false);
17577 if (s.strm.avail_out === 0) {
17578 return BS_NEED_MORE;
17579 }
17580 /***/
17581
17582
17583 }
17584 /* Flush if we may have to slide, otherwise block_start may become
17585 * negative and the data will be gone:
17586 */
17587 if (s.strstart - s.block_start >= (s.w_size - MIN_LOOKAHEAD)) {
17588 /*** FLUSH_BLOCK(s, 0); ***/
17589 flush_block_only(s, false);
17590 if (s.strm.avail_out === 0) {
17591 return BS_NEED_MORE;
17592 }
17593 /***/
17594 }
17595 }
17596
17597 s.insert = 0;
17598
17599 if (flush === Z_FINISH) {
17600 /*** FLUSH_BLOCK(s, 1); ***/
17601 flush_block_only(s, true);
17602 if (s.strm.avail_out === 0) {
17603 return BS_FINISH_STARTED;
17604 }
17605 /***/
17606 return BS_FINISH_DONE;
17607 }
17608
17609 if (s.strstart > s.block_start) {
17610 /*** FLUSH_BLOCK(s, 0); ***/
17611 flush_block_only(s, false);
17612 if (s.strm.avail_out === 0) {
17613 return BS_NEED_MORE;
17614 }
17615 /***/
17616 }
17617
17618 return BS_NEED_MORE;
17619}
17620
17621/* ===========================================================================
17622 * Compress as much as possible from the input stream, return the current
17623 * block state.
17624 * This function does not perform lazy evaluation of matches and inserts
17625 * new strings in the dictionary only for unmatched strings or for short
17626 * matches. It is used only for the fast compression options.
17627 */
17628function deflate_fast(s, flush) {
17629 let hash_head; /* head of the hash chain */
17630 let bflush; /* set if current block must be flushed */
17631
17632 for (; ;) {
17633 /* Make sure that we always have enough lookahead, except
17634 * at the end of the input file. We need MAX_MATCH bytes
17635 * for the next match, plus MIN_MATCH bytes to insert the
17636 * string following the next match.
17637 */
17638 if (s.lookahead < MIN_LOOKAHEAD) {
17639 fill_window(s);
17640 if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
17641 return BS_NEED_MORE;
17642 }
17643 if (s.lookahead === 0) {
17644 break; /* flush the current block */
17645 }
17646 }
17647
17648 /* Insert the string window[strstart .. strstart+2] in the
17649 * dictionary, and set hash_head to the head of the hash chain:
17650 */
17651 hash_head = 0/*NIL*/;
17652 if (s.lookahead >= MIN_MATCH$1) {
17653 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
17654 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
17655 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
17656 s.head[s.ins_h] = s.strstart;
17657 /***/
17658 }
17659
17660 /* Find the longest match, discarding those <= prev_length.
17661 * At this point we have always match_length < MIN_MATCH
17662 */
17663 if (hash_head !== 0/*NIL*/ && ((s.strstart - hash_head) <= (s.w_size - MIN_LOOKAHEAD))) {
17664 /* To simplify the code, we prevent matches with the string
17665 * of window index 0 (in particular we have to avoid a match
17666 * of the string with itself at the start of the input file).
17667 */
17668 s.match_length = longest_match(s, hash_head);
17669 /* longest_match() sets match_start */
17670 }
17671 if (s.match_length >= MIN_MATCH$1) {
17672 // check_match(s, s.strstart, s.match_start, s.match_length); // for debug only
17673
17674 /*** _tr_tally_dist(s, s.strstart - s.match_start,
17675 s.match_length - MIN_MATCH, bflush); ***/
17676 bflush = _tr_tally(s, s.strstart - s.match_start, s.match_length - MIN_MATCH$1);
17677
17678 s.lookahead -= s.match_length;
17679
17680 /* Insert new strings in the hash table only if the match length
17681 * is not too large. This saves time but degrades compression.
17682 */
17683 if (s.match_length <= s.max_lazy_match/*max_insert_length*/ && s.lookahead >= MIN_MATCH$1) {
17684 s.match_length--; /* string at strstart already in table */
17685 do {
17686 s.strstart++;
17687 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
17688 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
17689 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
17690 s.head[s.ins_h] = s.strstart;
17691 /***/
17692 /* strstart never exceeds WSIZE-MAX_MATCH, so there are
17693 * always MIN_MATCH bytes ahead.
17694 */
17695 } while (--s.match_length !== 0);
17696 s.strstart++;
17697 } else {
17698 s.strstart += s.match_length;
17699 s.match_length = 0;
17700 s.ins_h = s.window[s.strstart];
17701 /* UPDATE_HASH(s, s.ins_h, s.window[s.strstart+1]); */
17702 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + 1]) & s.hash_mask;
17703
17704 //#if MIN_MATCH != 3
17705 // Call UPDATE_HASH() MIN_MATCH-3 more times
17706 //#endif
17707 /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
17708 * matter since it will be recomputed at next deflate call.
17709 */
17710 }
17711 } else {
17712 /* No match, output a literal byte */
17713 //Tracevv((stderr,"%c", s.window[s.strstart]));
17714 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
17715 bflush = _tr_tally(s, 0, s.window[s.strstart]);
17716
17717 s.lookahead--;
17718 s.strstart++;
17719 }
17720 if (bflush) {
17721 /*** FLUSH_BLOCK(s, 0); ***/
17722 flush_block_only(s, false);
17723 if (s.strm.avail_out === 0) {
17724 return BS_NEED_MORE;
17725 }
17726 /***/
17727 }
17728 }
17729 s.insert = ((s.strstart < (MIN_MATCH$1 - 1)) ? s.strstart : MIN_MATCH$1 - 1);
17730 if (flush === Z_FINISH) {
17731 /*** FLUSH_BLOCK(s, 1); ***/
17732 flush_block_only(s, true);
17733 if (s.strm.avail_out === 0) {
17734 return BS_FINISH_STARTED;
17735 }
17736 /***/
17737 return BS_FINISH_DONE;
17738 }
17739 if (s.last_lit) {
17740 /*** FLUSH_BLOCK(s, 0); ***/
17741 flush_block_only(s, false);
17742 if (s.strm.avail_out === 0) {
17743 return BS_NEED_MORE;
17744 }
17745 /***/
17746 }
17747 return BS_BLOCK_DONE;
17748}
17749
17750/* ===========================================================================
17751 * Same as above, but achieves better compression. We use a lazy
17752 * evaluation for matches: a match is finally adopted only if there is
17753 * no better match at the next window position.
17754 */
17755function deflate_slow(s, flush) {
17756 let hash_head; /* head of hash chain */
17757 let bflush; /* set if current block must be flushed */
17758
17759 let max_insert;
17760
17761 /* Process the input block. */
17762 for (; ;) {
17763 /* Make sure that we always have enough lookahead, except
17764 * at the end of the input file. We need MAX_MATCH bytes
17765 * for the next match, plus MIN_MATCH bytes to insert the
17766 * string following the next match.
17767 */
17768 if (s.lookahead < MIN_LOOKAHEAD) {
17769 fill_window(s);
17770 if (s.lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
17771 return BS_NEED_MORE;
17772 }
17773 if (s.lookahead === 0) { break; } /* flush the current block */
17774 }
17775
17776 /* Insert the string window[strstart .. strstart+2] in the
17777 * dictionary, and set hash_head to the head of the hash chain:
17778 */
17779 hash_head = 0/*NIL*/;
17780 if (s.lookahead >= MIN_MATCH$1) {
17781 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
17782 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
17783 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
17784 s.head[s.ins_h] = s.strstart;
17785 /***/
17786 }
17787
17788 /* Find the longest match, discarding those <= prev_length.
17789 */
17790 s.prev_length = s.match_length;
17791 s.prev_match = s.match_start;
17792 s.match_length = MIN_MATCH$1 - 1;
17793
17794 if (hash_head !== 0/*NIL*/ && s.prev_length < s.max_lazy_match &&
17795 s.strstart - hash_head <= (s.w_size - MIN_LOOKAHEAD)/*MAX_DIST(s)*/) {
17796 /* To simplify the code, we prevent matches with the string
17797 * of window index 0 (in particular we have to avoid a match
17798 * of the string with itself at the start of the input file).
17799 */
17800 s.match_length = longest_match(s, hash_head);
17801 /* longest_match() sets match_start */
17802
17803 if (s.match_length <= 5 &&
17804 (s.strategy === Z_FILTERED || (s.match_length === MIN_MATCH$1 && s.strstart - s.match_start > 4096/*TOO_FAR*/))) {
17805
17806 /* If prev_match is also MIN_MATCH, match_start is garbage
17807 * but we will ignore the current match anyway.
17808 */
17809 s.match_length = MIN_MATCH$1 - 1;
17810 }
17811 }
17812 /* If there was a match at the previous step and the current
17813 * match is not better, output the previous match:
17814 */
17815 if (s.prev_length >= MIN_MATCH$1 && s.match_length <= s.prev_length) {
17816 max_insert = s.strstart + s.lookahead - MIN_MATCH$1;
17817 /* Do not insert strings in hash table beyond this. */
17818
17819 //check_match(s, s.strstart-1, s.prev_match, s.prev_length);
17820
17821 /***_tr_tally_dist(s, s.strstart - 1 - s.prev_match,
17822 s.prev_length - MIN_MATCH, bflush);***/
17823 bflush = _tr_tally(s, s.strstart - 1 - s.prev_match, s.prev_length - MIN_MATCH$1);
17824 /* Insert in hash table all strings up to the end of the match.
17825 * strstart-1 and strstart are already inserted. If there is not
17826 * enough lookahead, the last two strings are not inserted in
17827 * the hash table.
17828 */
17829 s.lookahead -= s.prev_length - 1;
17830 s.prev_length -= 2;
17831 do {
17832 if (++s.strstart <= max_insert) {
17833 /*** INSERT_STRING(s, s.strstart, hash_head); ***/
17834 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[s.strstart + MIN_MATCH$1 - 1]) & s.hash_mask;
17835 hash_head = s.prev[s.strstart & s.w_mask] = s.head[s.ins_h];
17836 s.head[s.ins_h] = s.strstart;
17837 /***/
17838 }
17839 } while (--s.prev_length !== 0);
17840 s.match_available = 0;
17841 s.match_length = MIN_MATCH$1 - 1;
17842 s.strstart++;
17843
17844 if (bflush) {
17845 /*** FLUSH_BLOCK(s, 0); ***/
17846 flush_block_only(s, false);
17847 if (s.strm.avail_out === 0) {
17848 return BS_NEED_MORE;
17849 }
17850 /***/
17851 }
17852
17853 } else if (s.match_available) {
17854 /* If there was no match at the previous position, output a
17855 * single literal. If there was a match but the current match
17856 * is longer, truncate the previous match to a single literal.
17857 */
17858 //Tracevv((stderr,"%c", s->window[s->strstart-1]));
17859 /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
17860 bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
17861
17862 if (bflush) {
17863 /*** FLUSH_BLOCK_ONLY(s, 0) ***/
17864 flush_block_only(s, false);
17865 /***/
17866 }
17867 s.strstart++;
17868 s.lookahead--;
17869 if (s.strm.avail_out === 0) {
17870 return BS_NEED_MORE;
17871 }
17872 } else {
17873 /* There is no previous match to compare with, wait for
17874 * the next step to decide.
17875 */
17876 s.match_available = 1;
17877 s.strstart++;
17878 s.lookahead--;
17879 }
17880 }
17881 //Assert (flush != Z_NO_FLUSH, "no flush?");
17882 if (s.match_available) {
17883 //Tracevv((stderr,"%c", s->window[s->strstart-1]));
17884 /*** _tr_tally_lit(s, s.window[s.strstart-1], bflush); ***/
17885 bflush = _tr_tally(s, 0, s.window[s.strstart - 1]);
17886
17887 s.match_available = 0;
17888 }
17889 s.insert = s.strstart < MIN_MATCH$1 - 1 ? s.strstart : MIN_MATCH$1 - 1;
17890 if (flush === Z_FINISH) {
17891 /*** FLUSH_BLOCK(s, 1); ***/
17892 flush_block_only(s, true);
17893 if (s.strm.avail_out === 0) {
17894 return BS_FINISH_STARTED;
17895 }
17896 /***/
17897 return BS_FINISH_DONE;
17898 }
17899 if (s.last_lit) {
17900 /*** FLUSH_BLOCK(s, 0); ***/
17901 flush_block_only(s, false);
17902 if (s.strm.avail_out === 0) {
17903 return BS_NEED_MORE;
17904 }
17905 /***/
17906 }
17907
17908 return BS_BLOCK_DONE;
17909}
17910
17911
17912/* ===========================================================================
17913 * For Z_RLE, simply look for runs of bytes, generate matches only of distance
17914 * one. Do not maintain a hash table. (It will be regenerated if this run of
17915 * deflate switches away from Z_RLE.)
17916 */
17917function deflate_rle(s, flush) {
17918 let bflush; /* set if current block must be flushed */
17919 let prev; /* byte at distance one to match */
17920 let scan, strend; /* scan goes up to strend for length of run */
17921
17922 const _win = s.window;
17923
17924 for (; ;) {
17925 /* Make sure that we always have enough lookahead, except
17926 * at the end of the input file. We need MAX_MATCH bytes
17927 * for the longest run, plus one for the unrolled loop.
17928 */
17929 if (s.lookahead <= MAX_MATCH$1) {
17930 fill_window(s);
17931 if (s.lookahead <= MAX_MATCH$1 && flush === Z_NO_FLUSH) {
17932 return BS_NEED_MORE;
17933 }
17934 if (s.lookahead === 0) { break; } /* flush the current block */
17935 }
17936
17937 /* See how many times the previous byte repeats */
17938 s.match_length = 0;
17939 if (s.lookahead >= MIN_MATCH$1 && s.strstart > 0) {
17940 scan = s.strstart - 1;
17941 prev = _win[scan];
17942 if (prev === _win[++scan] && prev === _win[++scan] && prev === _win[++scan]) {
17943 strend = s.strstart + MAX_MATCH$1;
17944 do {
17945 /*jshint noempty:false*/
17946 } while (prev === _win[++scan] && prev === _win[++scan] &&
17947 prev === _win[++scan] && prev === _win[++scan] &&
17948 prev === _win[++scan] && prev === _win[++scan] &&
17949 prev === _win[++scan] && prev === _win[++scan] &&
17950 scan < strend);
17951 s.match_length = MAX_MATCH$1 - (strend - scan);
17952 if (s.match_length > s.lookahead) {
17953 s.match_length = s.lookahead;
17954 }
17955 }
17956 //Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
17957 }
17958
17959 /* Emit match if have run of MIN_MATCH or longer, else emit literal */
17960 if (s.match_length >= MIN_MATCH$1) {
17961 //check_match(s, s.strstart, s.strstart - 1, s.match_length);
17962
17963 /*** _tr_tally_dist(s, 1, s.match_length - MIN_MATCH, bflush); ***/
17964 bflush = _tr_tally(s, 1, s.match_length - MIN_MATCH$1);
17965
17966 s.lookahead -= s.match_length;
17967 s.strstart += s.match_length;
17968 s.match_length = 0;
17969 } else {
17970 /* No match, output a literal byte */
17971 //Tracevv((stderr,"%c", s->window[s->strstart]));
17972 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
17973 bflush = _tr_tally(s, 0, s.window[s.strstart]);
17974
17975 s.lookahead--;
17976 s.strstart++;
17977 }
17978 if (bflush) {
17979 /*** FLUSH_BLOCK(s, 0); ***/
17980 flush_block_only(s, false);
17981 if (s.strm.avail_out === 0) {
17982 return BS_NEED_MORE;
17983 }
17984 /***/
17985 }
17986 }
17987 s.insert = 0;
17988 if (flush === Z_FINISH) {
17989 /*** FLUSH_BLOCK(s, 1); ***/
17990 flush_block_only(s, true);
17991 if (s.strm.avail_out === 0) {
17992 return BS_FINISH_STARTED;
17993 }
17994 /***/
17995 return BS_FINISH_DONE;
17996 }
17997 if (s.last_lit) {
17998 /*** FLUSH_BLOCK(s, 0); ***/
17999 flush_block_only(s, false);
18000 if (s.strm.avail_out === 0) {
18001 return BS_NEED_MORE;
18002 }
18003 /***/
18004 }
18005 return BS_BLOCK_DONE;
18006}
18007
18008/* ===========================================================================
18009 * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table.
18010 * (It will be regenerated if this run of deflate switches away from Huffman.)
18011 */
18012function deflate_huff(s, flush) {
18013 let bflush; /* set if current block must be flushed */
18014
18015 for (; ;) {
18016 /* Make sure that we have a literal to write. */
18017 if (s.lookahead === 0) {
18018 fill_window(s);
18019 if (s.lookahead === 0) {
18020 if (flush === Z_NO_FLUSH) {
18021 return BS_NEED_MORE;
18022 }
18023 break; /* flush the current block */
18024 }
18025 }
18026
18027 /* Output a literal byte */
18028 s.match_length = 0;
18029 //Tracevv((stderr,"%c", s->window[s->strstart]));
18030 /*** _tr_tally_lit(s, s.window[s.strstart], bflush); ***/
18031 bflush = _tr_tally(s, 0, s.window[s.strstart]);
18032 s.lookahead--;
18033 s.strstart++;
18034 if (bflush) {
18035 /*** FLUSH_BLOCK(s, 0); ***/
18036 flush_block_only(s, false);
18037 if (s.strm.avail_out === 0) {
18038 return BS_NEED_MORE;
18039 }
18040 /***/
18041 }
18042 }
18043 s.insert = 0;
18044 if (flush === Z_FINISH) {
18045 /*** FLUSH_BLOCK(s, 1); ***/
18046 flush_block_only(s, true);
18047 if (s.strm.avail_out === 0) {
18048 return BS_FINISH_STARTED;
18049 }
18050 /***/
18051 return BS_FINISH_DONE;
18052 }
18053 if (s.last_lit) {
18054 /*** FLUSH_BLOCK(s, 0); ***/
18055 flush_block_only(s, false);
18056 if (s.strm.avail_out === 0) {
18057 return BS_NEED_MORE;
18058 }
18059 /***/
18060 }
18061 return BS_BLOCK_DONE;
18062}
18063
18064/* Values for max_lazy_match, good_match and max_chain_length, depending on
18065 * the desired pack level (0..9). The values given below have been tuned to
18066 * exclude worst case performance for pathological files. Better values may be
18067 * found for specific files.
18068 */
18069class Config {
18070 constructor(good_length, max_lazy, nice_length, max_chain, func) {
18071 this.good_length = good_length;
18072 this.max_lazy = max_lazy;
18073 this.nice_length = nice_length;
18074 this.max_chain = max_chain;
18075 this.func = func;
18076 }
18077}
18078const configuration_table = [
18079 /* good lazy nice chain */
18080 new Config(0, 0, 0, 0, deflate_stored), /* 0 store only */
18081 new Config(4, 4, 8, 4, deflate_fast), /* 1 max speed, no lazy matches */
18082 new Config(4, 5, 16, 8, deflate_fast), /* 2 */
18083 new Config(4, 6, 32, 32, deflate_fast), /* 3 */
18084
18085 new Config(4, 4, 16, 16, deflate_slow), /* 4 lazy matches */
18086 new Config(8, 16, 32, 32, deflate_slow), /* 5 */
18087 new Config(8, 16, 128, 128, deflate_slow), /* 6 */
18088 new Config(8, 32, 128, 256, deflate_slow), /* 7 */
18089 new Config(32, 128, 258, 1024, deflate_slow), /* 8 */
18090 new Config(32, 258, 258, 4096, deflate_slow) /* 9 max compression */
18091];
18092
18093
18094/* ===========================================================================
18095 * Initialize the "longest match" routines for a new zlib stream
18096 */
18097function lm_init(s) {
18098 s.window_size = 2 * s.w_size;
18099
18100 /*** CLEAR_HASH(s); ***/
18101 zero$2(s.head); // Fill with NIL (= 0);
18102
18103 /* Set the default configuration parameters:
18104 */
18105 s.max_lazy_match = configuration_table[s.level].max_lazy;
18106 s.good_match = configuration_table[s.level].good_length;
18107 s.nice_match = configuration_table[s.level].nice_length;
18108 s.max_chain_length = configuration_table[s.level].max_chain;
18109
18110 s.strstart = 0;
18111 s.block_start = 0;
18112 s.lookahead = 0;
18113 s.insert = 0;
18114 s.match_length = s.prev_length = MIN_MATCH$1 - 1;
18115 s.match_available = 0;
18116 s.ins_h = 0;
18117}
18118
18119class DeflateState {
18120 constructor() {
18121 this.strm = null; /* pointer back to this zlib stream */
18122 this.status = 0; /* as the name implies */
18123 this.pending_buf = null; /* output still pending */
18124 this.pending_buf_size = 0; /* size of pending_buf */
18125 this.pending_out = 0; /* next pending byte to output to the stream */
18126 this.pending = 0; /* nb of bytes in the pending buffer */
18127 this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
18128 this.gzhead = null; /* gzip header information to write */
18129 this.gzindex = 0; /* where in extra, name, or comment */
18130 this.method = Z_DEFLATED; /* can only be DEFLATED */
18131 this.last_flush = -1; /* value of flush param for previous deflate call */
18132
18133 this.w_size = 0; /* LZ77 window size (32K by default) */
18134 this.w_bits = 0; /* log2(w_size) (8..16) */
18135 this.w_mask = 0; /* w_size - 1 */
18136
18137 this.window = null;
18138 /* Sliding window. Input bytes are read into the second half of the window,
18139 * and move to the first half later to keep a dictionary of at least wSize
18140 * bytes. With this organization, matches are limited to a distance of
18141 * wSize-MAX_MATCH bytes, but this ensures that IO is always
18142 * performed with a length multiple of the block size.
18143 */
18144
18145 this.window_size = 0;
18146 /* Actual size of window: 2*wSize, except when the user input buffer
18147 * is directly used as sliding window.
18148 */
18149
18150 this.prev = null;
18151 /* Link to older string with same hash index. To limit the size of this
18152 * array to 64K, this link is maintained only for the last 32K strings.
18153 * An index in this array is thus a window index modulo 32K.
18154 */
18155
18156 this.head = null; /* Heads of the hash chains or NIL. */
18157
18158 this.ins_h = 0; /* hash index of string to be inserted */
18159 this.hash_size = 0; /* number of elements in hash table */
18160 this.hash_bits = 0; /* log2(hash_size) */
18161 this.hash_mask = 0; /* hash_size-1 */
18162
18163 this.hash_shift = 0;
18164 /* Number of bits by which ins_h must be shifted at each input
18165 * step. It must be such that after MIN_MATCH steps, the oldest
18166 * byte no longer takes part in the hash key, that is:
18167 * hash_shift * MIN_MATCH >= hash_bits
18168 */
18169
18170 this.block_start = 0;
18171 /* Window position at the beginning of the current output block. Gets
18172 * negative when the window is moved backwards.
18173 */
18174
18175 this.match_length = 0; /* length of best match */
18176 this.prev_match = 0; /* previous match */
18177 this.match_available = 0; /* set if previous match exists */
18178 this.strstart = 0; /* start of string to insert */
18179 this.match_start = 0; /* start of matching string */
18180 this.lookahead = 0; /* number of valid bytes ahead in window */
18181
18182 this.prev_length = 0;
18183 /* Length of the best match at previous step. Matches not greater than this
18184 * are discarded. This is used in the lazy match evaluation.
18185 */
18186
18187 this.max_chain_length = 0;
18188 /* To speed up deflation, hash chains are never searched beyond this
18189 * length. A higher limit improves compression ratio but degrades the
18190 * speed.
18191 */
18192
18193 this.max_lazy_match = 0;
18194 /* Attempt to find a better match only when the current match is strictly
18195 * smaller than this value. This mechanism is used only for compression
18196 * levels >= 4.
18197 */
18198 // That's alias to max_lazy_match, don't use directly
18199 //this.max_insert_length = 0;
18200 /* Insert new strings in the hash table only if the match length is not
18201 * greater than this length. This saves time but degrades compression.
18202 * max_insert_length is used only for compression levels <= 3.
18203 */
18204
18205 this.level = 0; /* compression level (1..9) */
18206 this.strategy = 0; /* favor or force Huffman coding*/
18207
18208 this.good_match = 0;
18209 /* Use a faster search when the previous match is longer than this */
18210
18211 this.nice_match = 0; /* Stop searching when current match exceeds this */
18212
18213 /* used by trees.c: */
18214
18215 /* Didn't use ct_data typedef below to suppress compiler warning */
18216
18217 // struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
18218 // struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
18219 // struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
18220
18221 // Use flat array of DOUBLE size, with interleaved fata,
18222 // because JS does not support effective
18223 this.dyn_ltree = new Buf16(HEAP_SIZE$1 * 2);
18224 this.dyn_dtree = new Buf16((2 * D_CODES$1 + 1) * 2);
18225 this.bl_tree = new Buf16((2 * BL_CODES$1 + 1) * 2);
18226 zero$2(this.dyn_ltree);
18227 zero$2(this.dyn_dtree);
18228 zero$2(this.bl_tree);
18229
18230 this.l_desc = null; /* desc. for literal tree */
18231 this.d_desc = null; /* desc. for distance tree */
18232 this.bl_desc = null; /* desc. for bit length tree */
18233
18234 //ush bl_count[MAX_BITS+1];
18235 this.bl_count = new Buf16(MAX_BITS$1 + 1);
18236 /* number of codes at each bit length for an optimal tree */
18237
18238 //int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
18239 this.heap = new Buf16(2 * L_CODES$1 + 1); /* heap used to build the Huffman trees */
18240 zero$2(this.heap);
18241
18242 this.heap_len = 0; /* number of elements in the heap */
18243 this.heap_max = 0; /* element of largest frequency */
18244 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
18245 * The same heap array is used to build all trees.
18246 */
18247
18248 this.depth = new Buf16(2 * L_CODES$1 + 1); //uch depth[2*L_CODES+1];
18249 zero$2(this.depth);
18250 /* Depth of each subtree used as tie breaker for trees of equal frequency
18251 */
18252
18253 this.l_buf = 0; /* buffer index for literals or lengths */
18254
18255 this.lit_bufsize = 0;
18256 /* Size of match buffer for literals/lengths. There are 4 reasons for
18257 * limiting lit_bufsize to 64K:
18258 * - frequencies can be kept in 16 bit counters
18259 * - if compression is not successful for the first block, all input
18260 * data is still in the window so we can still emit a stored block even
18261 * when input comes from standard input. (This can also be done for
18262 * all blocks if lit_bufsize is not greater than 32K.)
18263 * - if compression is not successful for a file smaller than 64K, we can
18264 * even emit a stored file instead of a stored block (saving 5 bytes).
18265 * This is applicable only for zip (not gzip or zlib).
18266 * - creating new Huffman trees less frequently may not provide fast
18267 * adaptation to changes in the input data statistics. (Take for
18268 * example a binary file with poorly compressible code followed by
18269 * a highly compressible string table.) Smaller buffer sizes give
18270 * fast adaptation but have of course the overhead of transmitting
18271 * trees more frequently.
18272 * - I can't count above 4
18273 */
18274
18275 this.last_lit = 0; /* running index in l_buf */
18276
18277 this.d_buf = 0;
18278 /* Buffer index for distances. To simplify the code, d_buf and l_buf have
18279 * the same number of elements. To use different lengths, an extra flag
18280 * array would be necessary.
18281 */
18282
18283 this.opt_len = 0; /* bit length of current block with optimal trees */
18284 this.static_len = 0; /* bit length of current block with static trees */
18285 this.matches = 0; /* number of string matches in current block */
18286 this.insert = 0; /* bytes at end of window left to insert */
18287
18288
18289 this.bi_buf = 0;
18290 /* Output buffer. bits are inserted starting at the bottom (least
18291 * significant bits).
18292 */
18293 this.bi_valid = 0;
18294 /* Number of valid bits in bi_buf. All bits above the last valid bit
18295 * are always zero.
18296 */
18297
18298 // Used for window memory init. We safely ignore it for JS. That makes
18299 // sense only for pointers and memory check tools.
18300 //this.high_water = 0;
18301 /* High water mark offset in window for initialized bytes -- bytes above
18302 * this are set to zero in order to avoid memory check warnings when
18303 * longest match routines access bytes past the input. This is then
18304 * updated to the new high water mark.
18305 */
18306 }
18307}
18308
18309function deflateResetKeep(strm) {
18310 let s;
18311
18312 if (!strm || !strm.state) {
18313 return err(strm, Z_STREAM_ERROR);
18314 }
18315
18316 strm.total_in = strm.total_out = 0;
18317 strm.data_type = Z_UNKNOWN;
18318
18319 s = strm.state;
18320 s.pending = 0;
18321 s.pending_out = 0;
18322
18323 if (s.wrap < 0) {
18324 s.wrap = -s.wrap;
18325 /* was made negative by deflate(..., Z_FINISH); */
18326 }
18327 s.status = (s.wrap ? INIT_STATE : BUSY_STATE);
18328 strm.adler = (s.wrap === 2) ?
18329 0 // crc32(0, Z_NULL, 0)
18330 :
18331 1; // adler32(0, Z_NULL, 0)
18332 s.last_flush = Z_NO_FLUSH;
18333 _tr_init(s);
18334 return Z_OK;
18335}
18336
18337
18338function deflateReset(strm) {
18339 const ret = deflateResetKeep(strm);
18340 if (ret === Z_OK) {
18341 lm_init(strm.state);
18342 }
18343 return ret;
18344}
18345
18346
18347function deflateSetHeader(strm, head) {
18348 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
18349 if (strm.state.wrap !== 2) { return Z_STREAM_ERROR; }
18350 strm.state.gzhead = head;
18351 return Z_OK;
18352}
18353
18354
18355function deflateInit2(strm, level, method, windowBits, memLevel, strategy) {
18356 if (!strm) { // === Z_NULL
18357 return Z_STREAM_ERROR;
18358 }
18359 let wrap = 1;
18360
18361 if (level === Z_DEFAULT_COMPRESSION) {
18362 level = 6;
18363 }
18364
18365 if (windowBits < 0) { /* suppress zlib wrapper */
18366 wrap = 0;
18367 windowBits = -windowBits;
18368 }
18369
18370 else if (windowBits > 15) {
18371 wrap = 2; /* write gzip wrapper instead */
18372 windowBits -= 16;
18373 }
18374
18375
18376 if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method !== Z_DEFLATED ||
18377 windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
18378 strategy < 0 || strategy > Z_FIXED) {
18379 return err(strm, Z_STREAM_ERROR);
18380 }
18381
18382
18383 if (windowBits === 8) {
18384 windowBits = 9;
18385 }
18386 /* until 256-byte window bug fixed */
18387
18388 const s = new DeflateState();
18389
18390 strm.state = s;
18391 s.strm = strm;
18392
18393 s.wrap = wrap;
18394 s.gzhead = null;
18395 s.w_bits = windowBits;
18396 s.w_size = 1 << s.w_bits;
18397 s.w_mask = s.w_size - 1;
18398
18399 s.hash_bits = memLevel + 7;
18400 s.hash_size = 1 << s.hash_bits;
18401 s.hash_mask = s.hash_size - 1;
18402 s.hash_shift = ~~((s.hash_bits + MIN_MATCH$1 - 1) / MIN_MATCH$1);
18403 s.window = new Buf8(s.w_size * 2);
18404 s.head = new Buf16(s.hash_size);
18405 s.prev = new Buf16(s.w_size);
18406
18407 // Don't need mem init magic for JS.
18408 //s.high_water = 0; /* nothing written to s->window yet */
18409
18410 s.lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
18411
18412 s.pending_buf_size = s.lit_bufsize * 4;
18413
18414 //overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
18415 //s->pending_buf = (uchf *) overlay;
18416 s.pending_buf = new Buf8(s.pending_buf_size);
18417
18418 // It is offset from `s.pending_buf` (size is `s.lit_bufsize * 2`)
18419 //s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
18420 s.d_buf = 1 * s.lit_bufsize;
18421
18422 //s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
18423 s.l_buf = (1 + 2) * s.lit_bufsize;
18424
18425 s.level = level;
18426 s.strategy = strategy;
18427 s.method = method;
18428
18429 return deflateReset(strm);
18430}
18431
18432
18433function deflate(strm, flush) {
18434 let old_flush, s;
18435 let beg, val; // for gzip header write only
18436
18437 if (!strm || !strm.state ||
18438 flush > Z_BLOCK || flush < 0) {
18439 return strm ? err(strm, Z_STREAM_ERROR) : Z_STREAM_ERROR;
18440 }
18441
18442 s = strm.state;
18443
18444 if (!strm.output ||
18445 (!strm.input && strm.avail_in !== 0) ||
18446 (s.status === FINISH_STATE && flush !== Z_FINISH)) {
18447 return err(strm, (strm.avail_out === 0) ? Z_BUF_ERROR : Z_STREAM_ERROR);
18448 }
18449
18450 s.strm = strm; /* just in case */
18451 old_flush = s.last_flush;
18452 s.last_flush = flush;
18453
18454 /* Write the header */
18455 if (s.status === INIT_STATE) {
18456
18457 if (s.wrap === 2) { // GZIP header
18458 strm.adler = 0; //crc32(0L, Z_NULL, 0);
18459 put_byte(s, 31);
18460 put_byte(s, 139);
18461 put_byte(s, 8);
18462 if (!s.gzhead) { // s->gzhead == Z_NULL
18463 put_byte(s, 0);
18464 put_byte(s, 0);
18465 put_byte(s, 0);
18466 put_byte(s, 0);
18467 put_byte(s, 0);
18468 put_byte(s, s.level === 9 ? 2 :
18469 (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
18470 4 : 0));
18471 put_byte(s, OS_CODE);
18472 s.status = BUSY_STATE;
18473 }
18474 else {
18475 put_byte(s, (s.gzhead.text ? 1 : 0) +
18476 (s.gzhead.hcrc ? 2 : 0) +
18477 (!s.gzhead.extra ? 0 : 4) +
18478 (!s.gzhead.name ? 0 : 8) +
18479 (!s.gzhead.comment ? 0 : 16)
18480 );
18481 put_byte(s, s.gzhead.time & 0xff);
18482 put_byte(s, (s.gzhead.time >> 8) & 0xff);
18483 put_byte(s, (s.gzhead.time >> 16) & 0xff);
18484 put_byte(s, (s.gzhead.time >> 24) & 0xff);
18485 put_byte(s, s.level === 9 ? 2 :
18486 (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2 ?
18487 4 : 0));
18488 put_byte(s, s.gzhead.os & 0xff);
18489 if (s.gzhead.extra && s.gzhead.extra.length) {
18490 put_byte(s, s.gzhead.extra.length & 0xff);
18491 put_byte(s, (s.gzhead.extra.length >> 8) & 0xff);
18492 }
18493 if (s.gzhead.hcrc) {
18494 strm.adler = crc32(strm.adler, s.pending_buf, s.pending, 0);
18495 }
18496 s.gzindex = 0;
18497 s.status = EXTRA_STATE;
18498 }
18499 }
18500 else // DEFLATE header
18501 {
18502 let header = (Z_DEFLATED + ((s.w_bits - 8) << 4)) << 8;
18503 let level_flags = -1;
18504
18505 if (s.strategy >= Z_HUFFMAN_ONLY || s.level < 2) {
18506 level_flags = 0;
18507 } else if (s.level < 6) {
18508 level_flags = 1;
18509 } else if (s.level === 6) {
18510 level_flags = 2;
18511 } else {
18512 level_flags = 3;
18513 }
18514 header |= (level_flags << 6);
18515 if (s.strstart !== 0) { header |= PRESET_DICT; }
18516 header += 31 - (header % 31);
18517
18518 s.status = BUSY_STATE;
18519 putShortMSB(s, header);
18520
18521 /* Save the adler32 of the preset dictionary: */
18522 if (s.strstart !== 0) {
18523 putShortMSB(s, strm.adler >>> 16);
18524 putShortMSB(s, strm.adler & 0xffff);
18525 }
18526 strm.adler = 1; // adler32(0L, Z_NULL, 0);
18527 }
18528 }
18529
18530 //#ifdef GZIP
18531 if (s.status === EXTRA_STATE) {
18532 if (s.gzhead.extra/* != Z_NULL*/) {
18533 beg = s.pending; /* start of bytes to update crc */
18534
18535 while (s.gzindex < (s.gzhead.extra.length & 0xffff)) {
18536 if (s.pending === s.pending_buf_size) {
18537 if (s.gzhead.hcrc && s.pending > beg) {
18538 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18539 }
18540 flush_pending(strm);
18541 beg = s.pending;
18542 if (s.pending === s.pending_buf_size) {
18543 break;
18544 }
18545 }
18546 put_byte(s, s.gzhead.extra[s.gzindex] & 0xff);
18547 s.gzindex++;
18548 }
18549 if (s.gzhead.hcrc && s.pending > beg) {
18550 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18551 }
18552 if (s.gzindex === s.gzhead.extra.length) {
18553 s.gzindex = 0;
18554 s.status = NAME_STATE;
18555 }
18556 }
18557 else {
18558 s.status = NAME_STATE;
18559 }
18560 }
18561 if (s.status === NAME_STATE) {
18562 if (s.gzhead.name/* != Z_NULL*/) {
18563 beg = s.pending; /* start of bytes to update crc */
18564 //int val;
18565
18566 do {
18567 if (s.pending === s.pending_buf_size) {
18568 if (s.gzhead.hcrc && s.pending > beg) {
18569 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18570 }
18571 flush_pending(strm);
18572 beg = s.pending;
18573 if (s.pending === s.pending_buf_size) {
18574 val = 1;
18575 break;
18576 }
18577 }
18578 // JS specific: little magic to add zero terminator to end of string
18579 if (s.gzindex < s.gzhead.name.length) {
18580 val = s.gzhead.name.charCodeAt(s.gzindex++) & 0xff;
18581 } else {
18582 val = 0;
18583 }
18584 put_byte(s, val);
18585 } while (val !== 0);
18586
18587 if (s.gzhead.hcrc && s.pending > beg) {
18588 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18589 }
18590 if (val === 0) {
18591 s.gzindex = 0;
18592 s.status = COMMENT_STATE;
18593 }
18594 }
18595 else {
18596 s.status = COMMENT_STATE;
18597 }
18598 }
18599 if (s.status === COMMENT_STATE) {
18600 if (s.gzhead.comment/* != Z_NULL*/) {
18601 beg = s.pending; /* start of bytes to update crc */
18602 //int val;
18603
18604 do {
18605 if (s.pending === s.pending_buf_size) {
18606 if (s.gzhead.hcrc && s.pending > beg) {
18607 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18608 }
18609 flush_pending(strm);
18610 beg = s.pending;
18611 if (s.pending === s.pending_buf_size) {
18612 val = 1;
18613 break;
18614 }
18615 }
18616 // JS specific: little magic to add zero terminator to end of string
18617 if (s.gzindex < s.gzhead.comment.length) {
18618 val = s.gzhead.comment.charCodeAt(s.gzindex++) & 0xff;
18619 } else {
18620 val = 0;
18621 }
18622 put_byte(s, val);
18623 } while (val !== 0);
18624
18625 if (s.gzhead.hcrc && s.pending > beg) {
18626 strm.adler = crc32(strm.adler, s.pending_buf, s.pending - beg, beg);
18627 }
18628 if (val === 0) {
18629 s.status = HCRC_STATE;
18630 }
18631 }
18632 else {
18633 s.status = HCRC_STATE;
18634 }
18635 }
18636 if (s.status === HCRC_STATE) {
18637 if (s.gzhead.hcrc) {
18638 if (s.pending + 2 > s.pending_buf_size) {
18639 flush_pending(strm);
18640 }
18641 if (s.pending + 2 <= s.pending_buf_size) {
18642 put_byte(s, strm.adler & 0xff);
18643 put_byte(s, (strm.adler >> 8) & 0xff);
18644 strm.adler = 0; //crc32(0L, Z_NULL, 0);
18645 s.status = BUSY_STATE;
18646 }
18647 }
18648 else {
18649 s.status = BUSY_STATE;
18650 }
18651 }
18652 //#endif
18653
18654 /* Flush as much pending output as possible */
18655 if (s.pending !== 0) {
18656 flush_pending(strm);
18657 if (strm.avail_out === 0) {
18658 /* Since avail_out is 0, deflate will be called again with
18659 * more output space, but possibly with both pending and
18660 * avail_in equal to zero. There won't be anything to do,
18661 * but this is not an error situation so make sure we
18662 * return OK instead of BUF_ERROR at next call of deflate:
18663 */
18664 s.last_flush = -1;
18665 return Z_OK;
18666 }
18667
18668 /* Make sure there is something to do and avoid duplicate consecutive
18669 * flushes. For repeated and useless calls with Z_FINISH, we keep
18670 * returning Z_STREAM_END instead of Z_BUF_ERROR.
18671 */
18672 } else if (strm.avail_in === 0 && rank(flush) <= rank(old_flush) &&
18673 flush !== Z_FINISH) {
18674 return err(strm, Z_BUF_ERROR);
18675 }
18676
18677 /* User must not provide more input after the first FINISH: */
18678 if (s.status === FINISH_STATE && strm.avail_in !== 0) {
18679 return err(strm, Z_BUF_ERROR);
18680 }
18681
18682 /* Start a new block or continue the current one.
18683 */
18684 if (strm.avail_in !== 0 || s.lookahead !== 0 ||
18685 (flush !== Z_NO_FLUSH && s.status !== FINISH_STATE)) {
18686 var bstate = (s.strategy === Z_HUFFMAN_ONLY) ? deflate_huff(s, flush) :
18687 (s.strategy === Z_RLE ? deflate_rle(s, flush) :
18688 configuration_table[s.level].func(s, flush));
18689
18690 if (bstate === BS_FINISH_STARTED || bstate === BS_FINISH_DONE) {
18691 s.status = FINISH_STATE;
18692 }
18693 if (bstate === BS_NEED_MORE || bstate === BS_FINISH_STARTED) {
18694 if (strm.avail_out === 0) {
18695 s.last_flush = -1;
18696 /* avoid BUF_ERROR next call, see above */
18697 }
18698 return Z_OK;
18699 /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
18700 * of deflate should use the same flush parameter to make sure
18701 * that the flush is complete. So we don't have to output an
18702 * empty block here, this will be done at next call. This also
18703 * ensures that for a very small output buffer, we emit at most
18704 * one empty block.
18705 */
18706 }
18707 if (bstate === BS_BLOCK_DONE) {
18708 if (flush === Z_PARTIAL_FLUSH) {
18709 _tr_align(s);
18710 }
18711 else if (flush !== Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
18712
18713 _tr_stored_block(s, 0, 0, false);
18714 /* For a full flush, this empty block will be recognized
18715 * as a special marker by inflate_sync().
18716 */
18717 if (flush === Z_FULL_FLUSH) {
18718 /*** CLEAR_HASH(s); ***/ /* forget history */
18719 zero$2(s.head); // Fill with NIL (= 0);
18720
18721 if (s.lookahead === 0) {
18722 s.strstart = 0;
18723 s.block_start = 0;
18724 s.insert = 0;
18725 }
18726 }
18727 }
18728 flush_pending(strm);
18729 if (strm.avail_out === 0) {
18730 s.last_flush = -1; /* avoid BUF_ERROR at next call, see above */
18731 return Z_OK;
18732 }
18733 }
18734 }
18735 //Assert(strm->avail_out > 0, "bug2");
18736 //if (strm.avail_out <= 0) { throw new Error("bug2");}
18737
18738 if (flush !== Z_FINISH) { return Z_OK; }
18739 if (s.wrap <= 0) { return Z_STREAM_END; }
18740
18741 /* Write the trailer */
18742 if (s.wrap === 2) {
18743 put_byte(s, strm.adler & 0xff);
18744 put_byte(s, (strm.adler >> 8) & 0xff);
18745 put_byte(s, (strm.adler >> 16) & 0xff);
18746 put_byte(s, (strm.adler >> 24) & 0xff);
18747 put_byte(s, strm.total_in & 0xff);
18748 put_byte(s, (strm.total_in >> 8) & 0xff);
18749 put_byte(s, (strm.total_in >> 16) & 0xff);
18750 put_byte(s, (strm.total_in >> 24) & 0xff);
18751 }
18752 else {
18753 putShortMSB(s, strm.adler >>> 16);
18754 putShortMSB(s, strm.adler & 0xffff);
18755 }
18756
18757 flush_pending(strm);
18758 /* If avail_out is zero, the application will call deflate again
18759 * to flush the rest.
18760 */
18761 if (s.wrap > 0) { s.wrap = -s.wrap; }
18762 /* write the trailer only once! */
18763 return s.pending !== 0 ? Z_OK : Z_STREAM_END;
18764}
18765
18766function deflateEnd(strm) {
18767 let status;
18768
18769 if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
18770 return Z_STREAM_ERROR;
18771 }
18772
18773 status = strm.state.status;
18774 if (status !== INIT_STATE &&
18775 status !== EXTRA_STATE &&
18776 status !== NAME_STATE &&
18777 status !== COMMENT_STATE &&
18778 status !== HCRC_STATE &&
18779 status !== BUSY_STATE &&
18780 status !== FINISH_STATE
18781 ) {
18782 return err(strm, Z_STREAM_ERROR);
18783 }
18784
18785 strm.state = null;
18786
18787 return status === BUSY_STATE ? err(strm, Z_DATA_ERROR) : Z_OK;
18788}
18789
18790
18791/* =========================================================================
18792 * Initializes the compression dictionary from the given byte
18793 * sequence without producing any compressed output.
18794 */
18795function deflateSetDictionary(strm, dictionary) {
18796 let dictLength = dictionary.length;
18797
18798 let s;
18799 let str, n;
18800 let wrap;
18801 let avail;
18802 let next;
18803 let input;
18804 let tmpDict;
18805
18806 if (!strm/*== Z_NULL*/ || !strm.state/*== Z_NULL*/) {
18807 return Z_STREAM_ERROR;
18808 }
18809
18810 s = strm.state;
18811 wrap = s.wrap;
18812
18813 if (wrap === 2 || (wrap === 1 && s.status !== INIT_STATE) || s.lookahead) {
18814 return Z_STREAM_ERROR;
18815 }
18816
18817 /* when using zlib wrappers, compute Adler-32 for provided dictionary */
18818 if (wrap === 1) {
18819 /* adler32(strm->adler, dictionary, dictLength); */
18820 strm.adler = adler32(strm.adler, dictionary, dictLength, 0);
18821 }
18822
18823 s.wrap = 0; /* avoid computing Adler-32 in read_buf */
18824
18825 /* if dictionary would fill window, just replace the history */
18826 if (dictLength >= s.w_size) {
18827 if (wrap === 0) { /* already empty otherwise */
18828 /*** CLEAR_HASH(s); ***/
18829 zero$2(s.head); // Fill with NIL (= 0);
18830 s.strstart = 0;
18831 s.block_start = 0;
18832 s.insert = 0;
18833 }
18834 /* use the tail */
18835 // dictionary = dictionary.slice(dictLength - s.w_size);
18836 tmpDict = new Buf8(s.w_size);
18837 arraySet(tmpDict, dictionary, dictLength - s.w_size, s.w_size, 0);
18838 dictionary = tmpDict;
18839 dictLength = s.w_size;
18840 }
18841 /* insert dictionary into window and hash */
18842 avail = strm.avail_in;
18843 next = strm.next_in;
18844 input = strm.input;
18845 strm.avail_in = dictLength;
18846 strm.next_in = 0;
18847 strm.input = dictionary;
18848 fill_window(s);
18849 while (s.lookahead >= MIN_MATCH$1) {
18850 str = s.strstart;
18851 n = s.lookahead - (MIN_MATCH$1 - 1);
18852 do {
18853 /* UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); */
18854 s.ins_h = ((s.ins_h << s.hash_shift) ^ s.window[str + MIN_MATCH$1 - 1]) & s.hash_mask;
18855
18856 s.prev[str & s.w_mask] = s.head[s.ins_h];
18857
18858 s.head[s.ins_h] = str;
18859 str++;
18860 } while (--n);
18861 s.strstart = str;
18862 s.lookahead = MIN_MATCH$1 - 1;
18863 fill_window(s);
18864 }
18865 s.strstart += s.lookahead;
18866 s.block_start = s.strstart;
18867 s.insert = s.lookahead;
18868 s.lookahead = 0;
18869 s.match_length = s.prev_length = MIN_MATCH$1 - 1;
18870 s.match_available = 0;
18871 strm.next_in = next;
18872 strm.input = input;
18873 strm.avail_in = avail;
18874 s.wrap = wrap;
18875 return Z_OK;
18876}
18877
18878/* Not implemented
18879exports.deflateBound = deflateBound;
18880exports.deflateCopy = deflateCopy;
18881exports.deflateParams = deflateParams;
18882exports.deflatePending = deflatePending;
18883exports.deflatePrime = deflatePrime;
18884exports.deflateTune = deflateTune;
18885*/
18886
18887// String encode/decode helpers
18888
18889try {
18890 String.fromCharCode.apply(null, [ 0 ]);
18891} catch (__) {
18892}
18893try {
18894 String.fromCharCode.apply(null, new Uint8Array(1));
18895} catch (__) {
18896}
18897
18898
18899// Table with utf8 lengths (calculated by first byte of sequence)
18900// Note, that 5 & 6-byte values and some 4-byte values can not be represented in JS,
18901// because max possible codepoint is 0x10ffff
18902const _utf8len = new Buf8(256);
18903for (let q = 0; q < 256; q++) {
18904 _utf8len[q] = q >= 252 ? 6 : q >= 248 ? 5 : q >= 240 ? 4 : q >= 224 ? 3 : q >= 192 ? 2 : 1;
18905}
18906_utf8len[254] = _utf8len[254] = 1; // Invalid sequence start
18907
18908
18909// convert string to array (typed, when possible)
18910function string2buf (str) {
18911 let c, c2, m_pos, i, buf_len = 0;
18912 const str_len = str.length;
18913
18914 // count binary size
18915 for (m_pos = 0; m_pos < str_len; m_pos++) {
18916 c = str.charCodeAt(m_pos);
18917 if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
18918 c2 = str.charCodeAt(m_pos + 1);
18919 if ((c2 & 0xfc00) === 0xdc00) {
18920 c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
18921 m_pos++;
18922 }
18923 }
18924 buf_len += c < 0x80 ? 1 : c < 0x800 ? 2 : c < 0x10000 ? 3 : 4;
18925 }
18926
18927 // allocate buffer
18928 const buf = new Buf8(buf_len);
18929
18930 // convert
18931 for (i = 0, m_pos = 0; i < buf_len; m_pos++) {
18932 c = str.charCodeAt(m_pos);
18933 if ((c & 0xfc00) === 0xd800 && m_pos + 1 < str_len) {
18934 c2 = str.charCodeAt(m_pos + 1);
18935 if ((c2 & 0xfc00) === 0xdc00) {
18936 c = 0x10000 + (c - 0xd800 << 10) + (c2 - 0xdc00);
18937 m_pos++;
18938 }
18939 }
18940 if (c < 0x80) {
18941 /* one byte */
18942 buf[i++] = c;
18943 } else if (c < 0x800) {
18944 /* two bytes */
18945 buf[i++] = 0xC0 | c >>> 6;
18946 buf[i++] = 0x80 | c & 0x3f;
18947 } else if (c < 0x10000) {
18948 /* three bytes */
18949 buf[i++] = 0xE0 | c >>> 12;
18950 buf[i++] = 0x80 | c >>> 6 & 0x3f;
18951 buf[i++] = 0x80 | c & 0x3f;
18952 } else {
18953 /* four bytes */
18954 buf[i++] = 0xf0 | c >>> 18;
18955 buf[i++] = 0x80 | c >>> 12 & 0x3f;
18956 buf[i++] = 0x80 | c >>> 6 & 0x3f;
18957 buf[i++] = 0x80 | c & 0x3f;
18958 }
18959 }
18960
18961 return buf;
18962}
18963
18964
18965// Convert binary string (typed, when possible)
18966function binstring2buf (str) {
18967 const buf = new Buf8(str.length);
18968 for (let i = 0, len = buf.length; i < len; i++) {
18969 buf[i] = str.charCodeAt(i);
18970 }
18971 return buf;
18972}
18973
18974// (C) 1995-2013 Jean-loup Gailly and Mark Adler
18975// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
18976//
18977// This software is provided 'as-is', without any express or implied
18978// warranty. In no event will the authors be held liable for any damages
18979// arising from the use of this software.
18980//
18981// Permission is granted to anyone to use this software for any purpose,
18982// including commercial applications, and to alter it and redistribute it
18983// freely, subject to the following restrictions:
18984//
18985// 1. The origin of this software must not be misrepresented; you must not
18986// claim that you wrote the original software. If you use this software
18987// in a product, an acknowledgment in the product documentation would be
18988// appreciated but is not required.
18989// 2. Altered source versions must be plainly marked as such, and must not be
18990// misrepresented as being the original software.
18991// 3. This notice may not be removed or altered from any source distribution.
18992
18993class ZStream {
18994 constructor() {
18995 /* next input byte */
18996 this.input = null; // JS specific, because we have no pointers
18997 this.next_in = 0;
18998 /* number of bytes available at input */
18999 this.avail_in = 0;
19000 /* total number of input bytes read so far */
19001 this.total_in = 0;
19002 /* next output byte should be put there */
19003 this.output = null; // JS specific, because we have no pointers
19004 this.next_out = 0;
19005 /* remaining free space at output */
19006 this.avail_out = 0;
19007 /* total number of bytes output so far */
19008 this.total_out = 0;
19009 /* last error message, NULL if no error */
19010 this.msg = ''/*Z_NULL*/;
19011 /* not visible by applications */
19012 this.state = null;
19013 /* best guess about the data type: binary or text */
19014 this.data_type = 2/*Z_UNKNOWN*/;
19015 /* adler32 value of the uncompressed data */
19016 this.adler = 0;
19017 }
19018}
19019
19020/* ===========================================================================*/
19021
19022
19023/**
19024 * class Deflate
19025 *
19026 * Generic JS-style wrapper for zlib calls. If you don't need
19027 * streaming behaviour - use more simple functions: [[deflate]],
19028 * [[deflateRaw]] and [[gzip]].
19029 **/
19030
19031/* internal
19032 * Deflate.chunks -> Array
19033 *
19034 * Chunks of output data, if [[Deflate#onData]] not overridden.
19035 **/
19036
19037/**
19038 * Deflate.result -> Uint8Array|Array
19039 *
19040 * Compressed result, generated by default [[Deflate#onData]]
19041 * and [[Deflate#onEnd]] handlers. Filled after you push last chunk
19042 * (call [[Deflate#push]] with `Z_FINISH` / `true` param) or if you
19043 * push a chunk with explicit flush (call [[Deflate#push]] with
19044 * `Z_SYNC_FLUSH` param).
19045 **/
19046
19047/**
19048 * Deflate.err -> Number
19049 *
19050 * Error code after deflate finished. 0 (Z_OK) on success.
19051 * You will not need it in real life, because deflate errors
19052 * are possible only on wrong options or bad `onData` / `onEnd`
19053 * custom handlers.
19054 **/
19055
19056/**
19057 * Deflate.msg -> String
19058 *
19059 * Error message, if [[Deflate.err]] != 0
19060 **/
19061
19062
19063/**
19064 * new Deflate(options)
19065 * - options (Object): zlib deflate options.
19066 *
19067 * Creates new deflator instance with specified params. Throws exception
19068 * on bad params. Supported options:
19069 *
19070 * - `level`
19071 * - `windowBits`
19072 * - `memLevel`
19073 * - `strategy`
19074 * - `dictionary`
19075 *
19076 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
19077 * for more information on these.
19078 *
19079 * Additional options, for internal needs:
19080 *
19081 * - `chunkSize` - size of generated data chunks (16K by default)
19082 * - `raw` (Boolean) - do raw deflate
19083 * - `gzip` (Boolean) - create gzip wrapper
19084 * - `to` (String) - if equal to 'string', then result will be "binary string"
19085 * (each char code [0..255])
19086 * - `header` (Object) - custom header for gzip
19087 * - `text` (Boolean) - true if compressed data believed to be text
19088 * - `time` (Number) - modification time, unix timestamp
19089 * - `os` (Number) - operation system code
19090 * - `extra` (Array) - array of bytes with extra data (max 65536)
19091 * - `name` (String) - file name (binary string)
19092 * - `comment` (String) - comment (binary string)
19093 * - `hcrc` (Boolean) - true if header crc should be added
19094 *
19095 * ##### Example:
19096 *
19097 * ```javascript
19098 * var pako = require('pako')
19099 * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
19100 * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
19101 *
19102 * var deflate = new pako.Deflate({ level: 3});
19103 *
19104 * deflate.push(chunk1, false);
19105 * deflate.push(chunk2, true); // true -> last chunk
19106 *
19107 * if (deflate.err) { throw new Error(deflate.err); }
19108 *
19109 * console.log(deflate.result);
19110 * ```
19111 **/
19112
19113class Deflate {
19114 constructor(options) {
19115 this.options = {
19116 level: Z_DEFAULT_COMPRESSION,
19117 method: Z_DEFLATED,
19118 chunkSize: 16384,
19119 windowBits: 15,
19120 memLevel: 8,
19121 strategy: Z_DEFAULT_STRATEGY,
19122 ...(options || {})
19123 };
19124
19125 const opt = this.options;
19126
19127 if (opt.raw && (opt.windowBits > 0)) {
19128 opt.windowBits = -opt.windowBits;
19129 }
19130
19131 else if (opt.gzip && (opt.windowBits > 0) && (opt.windowBits < 16)) {
19132 opt.windowBits += 16;
19133 }
19134
19135 this.err = 0; // error code, if happens (0 = Z_OK)
19136 this.msg = ''; // error message
19137 this.ended = false; // used to avoid multiple onEnd() calls
19138 this.chunks = []; // chunks of compressed data
19139
19140 this.strm = new ZStream();
19141 this.strm.avail_out = 0;
19142
19143 var status = deflateInit2(
19144 this.strm,
19145 opt.level,
19146 opt.method,
19147 opt.windowBits,
19148 opt.memLevel,
19149 opt.strategy
19150 );
19151
19152 if (status !== Z_OK) {
19153 throw new Error(msg[status]);
19154 }
19155
19156 if (opt.header) {
19157 deflateSetHeader(this.strm, opt.header);
19158 }
19159
19160 if (opt.dictionary) {
19161 let dict;
19162 // Convert data if needed
19163 if (typeof opt.dictionary === 'string') {
19164 // If we need to compress text, change encoding to utf8.
19165 dict = string2buf(opt.dictionary);
19166 } else if (opt.dictionary instanceof ArrayBuffer) {
19167 dict = new Uint8Array(opt.dictionary);
19168 } else {
19169 dict = opt.dictionary;
19170 }
19171
19172 status = deflateSetDictionary(this.strm, dict);
19173
19174 if (status !== Z_OK) {
19175 throw new Error(msg[status]);
19176 }
19177
19178 this._dict_set = true;
19179 }
19180 }
19181
19182 /**
19183 * Deflate#push(data[, mode]) -> Boolean
19184 * - data (Uint8Array|Array|ArrayBuffer|String): input data. Strings will be
19185 * converted to utf8 byte sequence.
19186 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
19187 * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
19188 *
19189 * Sends input data to deflate pipe, generating [[Deflate#onData]] calls with
19190 * new compressed chunks. Returns `true` on success. The last data block must have
19191 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
19192 * [[Deflate#onEnd]]. For interim explicit flushes (without ending the stream) you
19193 * can use mode Z_SYNC_FLUSH, keeping the compression context.
19194 *
19195 * On fail call [[Deflate#onEnd]] with error code and return false.
19196 *
19197 * We strongly recommend to use `Uint8Array` on input for best speed (output
19198 * array format is detected automatically). Also, don't skip last param and always
19199 * use the same type in your code (boolean or number). That will improve JS speed.
19200 *
19201 * For regular `Array`-s make sure all elements are [0..255].
19202 *
19203 * ##### Example
19204 *
19205 * ```javascript
19206 * push(chunk, false); // push one of data chunks
19207 * ...
19208 * push(chunk, true); // push last chunk
19209 * ```
19210 **/
19211 push(data, mode) {
19212 const { strm, options: { chunkSize } } = this;
19213 var status, _mode;
19214
19215 if (this.ended) { return false; }
19216
19217 _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
19218
19219 // Convert data if needed
19220 if (typeof data === 'string') {
19221 // If we need to compress text, change encoding to utf8.
19222 strm.input = string2buf(data);
19223 } else if (data instanceof ArrayBuffer) {
19224 strm.input = new Uint8Array(data);
19225 } else {
19226 strm.input = data;
19227 }
19228
19229 strm.next_in = 0;
19230 strm.avail_in = strm.input.length;
19231
19232 do {
19233 if (strm.avail_out === 0) {
19234 strm.output = new Buf8(chunkSize);
19235 strm.next_out = 0;
19236 strm.avail_out = chunkSize;
19237 }
19238 status = deflate(strm, _mode); /* no bad return value */
19239
19240 if (status !== Z_STREAM_END && status !== Z_OK) {
19241 this.onEnd(status);
19242 this.ended = true;
19243 return false;
19244 }
19245 if (strm.avail_out === 0 || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
19246 this.onData(shrinkBuf(strm.output, strm.next_out));
19247 }
19248 } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
19249
19250 // Finalize on the last chunk.
19251 if (_mode === Z_FINISH) {
19252 status = deflateEnd(this.strm);
19253 this.onEnd(status);
19254 this.ended = true;
19255 return status === Z_OK;
19256 }
19257
19258 // callback interim results if Z_SYNC_FLUSH.
19259 if (_mode === Z_SYNC_FLUSH) {
19260 this.onEnd(Z_OK);
19261 strm.avail_out = 0;
19262 return true;
19263 }
19264
19265 return true;
19266 };
19267 /**
19268 * Deflate#onData(chunk) -> Void
19269 * - chunk (Uint8Array|Array|String): output data. Type of array depends
19270 * on js engine support. When string output requested, each chunk
19271 * will be string.
19272 *
19273 * By default, stores data blocks in `chunks[]` property and glue
19274 * those in `onEnd`. Override this handler, if you need another behaviour.
19275 **/
19276 onData(chunk) {
19277 this.chunks.push(chunk);
19278 };
19279
19280 /**
19281 * Deflate#onEnd(status) -> Void
19282 * - status (Number): deflate status. 0 (Z_OK) on success,
19283 * other if not.
19284 *
19285 * Called once after you tell deflate that the input stream is
19286 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
19287 * or if an error happened. By default - join collected chunks,
19288 * free memory and fill `results` / `err` properties.
19289 **/
19290 onEnd(status) {
19291 // On success - join
19292 if (status === Z_OK) {
19293 this.result = flattenChunks(this.chunks);
19294 }
19295 this.chunks = [];
19296 this.err = status;
19297 this.msg = this.strm.msg;
19298 };
19299}
19300
19301// (C) 1995-2013 Jean-loup Gailly and Mark Adler
19302// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
19303//
19304// This software is provided 'as-is', without any express or implied
19305// warranty. In no event will the authors be held liable for any damages
19306// arising from the use of this software.
19307//
19308// Permission is granted to anyone to use this software for any purpose,
19309// including commercial applications, and to alter it and redistribute it
19310// freely, subject to the following restrictions:
19311//
19312// 1. The origin of this software must not be misrepresented; you must not
19313// claim that you wrote the original software. If you use this software
19314// in a product, an acknowledgment in the product documentation would be
19315// appreciated but is not required.
19316// 2. Altered source versions must be plainly marked as such, and must not be
19317// misrepresented as being the original software.
19318// 3. This notice may not be removed or altered from any source distribution.
19319
19320// See state defs from inflate.js
19321const BAD = 30; /* got a data error -- remain here until reset */
19322const TYPE = 12; /* i: waiting for type bits, including last-flag bit */
19323
19324/*
19325 Decode literal, length, and distance codes and write out the resulting
19326 literal and match bytes until either not enough input or output is
19327 available, an end-of-block is encountered, or a data error is encountered.
19328 When large enough input and output buffers are supplied to inflate(), for
19329 example, a 16K input buffer and a 64K output buffer, more than 95% of the
19330 inflate execution time is spent in this routine.
19331
19332 Entry assumptions:
19333
19334 state.mode === LEN
19335 strm.avail_in >= 6
19336 strm.avail_out >= 258
19337 start >= strm.avail_out
19338 state.bits < 8
19339
19340 On return, state.mode is one of:
19341
19342 LEN -- ran out of enough output space or enough available input
19343 TYPE -- reached end of block code, inflate() to interpret next block
19344 BAD -- error in block data
19345
19346 Notes:
19347
19348 - The maximum input bits used by a length/distance pair is 15 bits for the
19349 length code, 5 bits for the length extra, 15 bits for the distance code,
19350 and 13 bits for the distance extra. This totals 48 bits, or six bytes.
19351 Therefore if strm.avail_in >= 6, then there is enough input to avoid
19352 checking for available input while decoding.
19353
19354 - The maximum bytes that a single length/distance pair can output is 258
19355 bytes, which is the maximum length that can be coded. inflate_fast()
19356 requires strm.avail_out >= 258 for each loop to avoid checking for
19357 output space.
19358 */
19359function inflate_fast(strm, start) {
19360 let _in; /* local strm.input */
19361 let _out; /* local strm.output */
19362 // Use `s_window` instead `window`, avoid conflict with instrumentation tools
19363 let hold; /* local strm.hold */
19364 let bits; /* local strm.bits */
19365 let here; /* retrieved table entry */
19366 let op; /* code bits, operation, extra bits, or */
19367 /* window position, window bytes to copy */
19368 let len; /* match length, unused bytes */
19369 let dist; /* match distance */
19370 let from; /* where to copy match from */
19371 let from_source;
19372
19373
19374
19375 /* copy state to local variables */
19376 const state = strm.state;
19377 //here = state.here;
19378 _in = strm.next_in;
19379 const input = strm.input;
19380 const last = _in + (strm.avail_in - 5);
19381 _out = strm.next_out;
19382 const output = strm.output;
19383 const beg = _out - (start - strm.avail_out);
19384 const end = _out + (strm.avail_out - 257);
19385 //#ifdef INFLATE_STRICT
19386 const dmax = state.dmax;
19387 //#endif
19388 const wsize = state.wsize;
19389 const whave = state.whave;
19390 const wnext = state.wnext;
19391 const s_window = state.window;
19392 hold = state.hold;
19393 bits = state.bits;
19394 const lcode = state.lencode;
19395 const dcode = state.distcode;
19396 const lmask = (1 << state.lenbits) - 1;
19397 const dmask = (1 << state.distbits) - 1;
19398
19399
19400 /* decode literals and length/distances until end-of-block or not enough
19401 input data or output space */
19402
19403 top:
19404 do {
19405 if (bits < 15) {
19406 hold += input[_in++] << bits;
19407 bits += 8;
19408 hold += input[_in++] << bits;
19409 bits += 8;
19410 }
19411
19412 here = lcode[hold & lmask];
19413
19414 dolen:
19415 for (;;) { // Goto emulation
19416 op = here >>> 24/*here.bits*/;
19417 hold >>>= op;
19418 bits -= op;
19419 op = here >>> 16 & 0xff/*here.op*/;
19420 if (op === 0) { /* literal */
19421 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
19422 // "inflate: literal '%c'\n" :
19423 // "inflate: literal 0x%02x\n", here.val));
19424 output[_out++] = here & 0xffff/*here.val*/;
19425 } else if (op & 16) { /* length base */
19426 len = here & 0xffff/*here.val*/;
19427 op &= 15; /* number of extra bits */
19428 if (op) {
19429 if (bits < op) {
19430 hold += input[_in++] << bits;
19431 bits += 8;
19432 }
19433 len += hold & (1 << op) - 1;
19434 hold >>>= op;
19435 bits -= op;
19436 }
19437 //Tracevv((stderr, "inflate: length %u\n", len));
19438 if (bits < 15) {
19439 hold += input[_in++] << bits;
19440 bits += 8;
19441 hold += input[_in++] << bits;
19442 bits += 8;
19443 }
19444 here = dcode[hold & dmask];
19445
19446 dodist:
19447 for (;;) { // goto emulation
19448 op = here >>> 24/*here.bits*/;
19449 hold >>>= op;
19450 bits -= op;
19451 op = here >>> 16 & 0xff/*here.op*/;
19452
19453 if (op & 16) { /* distance base */
19454 dist = here & 0xffff/*here.val*/;
19455 op &= 15; /* number of extra bits */
19456 if (bits < op) {
19457 hold += input[_in++] << bits;
19458 bits += 8;
19459 if (bits < op) {
19460 hold += input[_in++] << bits;
19461 bits += 8;
19462 }
19463 }
19464 dist += hold & (1 << op) - 1;
19465 //#ifdef INFLATE_STRICT
19466 if (dist > dmax) {
19467 strm.msg = "invalid distance too far back";
19468 state.mode = BAD;
19469 break top;
19470 }
19471 //#endif
19472 hold >>>= op;
19473 bits -= op;
19474 //Tracevv((stderr, "inflate: distance %u\n", dist));
19475 op = _out - beg; /* max distance in output */
19476 if (dist > op) { /* see if copy from window */
19477 op = dist - op; /* distance back in window */
19478 if (op > whave) {
19479 if (state.sane) {
19480 strm.msg = "invalid distance too far back";
19481 state.mode = BAD;
19482 break top;
19483 }
19484
19485 // (!) This block is disabled in zlib defaults,
19486 // don't enable it for binary compatibility
19487 //#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
19488 // if (len <= op - whave) {
19489 // do {
19490 // output[_out++] = 0;
19491 // } while (--len);
19492 // continue top;
19493 // }
19494 // len -= op - whave;
19495 // do {
19496 // output[_out++] = 0;
19497 // } while (--op > whave);
19498 // if (op === 0) {
19499 // from = _out - dist;
19500 // do {
19501 // output[_out++] = output[from++];
19502 // } while (--len);
19503 // continue top;
19504 // }
19505 //#endif
19506 }
19507 from = 0; // window index
19508 from_source = s_window;
19509 if (wnext === 0) { /* very common case */
19510 from += wsize - op;
19511 if (op < len) { /* some from window */
19512 len -= op;
19513 do {
19514 output[_out++] = s_window[from++];
19515 } while (--op);
19516 from = _out - dist; /* rest from output */
19517 from_source = output;
19518 }
19519 } else if (wnext < op) { /* wrap around window */
19520 from += wsize + wnext - op;
19521 op -= wnext;
19522 if (op < len) { /* some from end of window */
19523 len -= op;
19524 do {
19525 output[_out++] = s_window[from++];
19526 } while (--op);
19527 from = 0;
19528 if (wnext < len) { /* some from start of window */
19529 op = wnext;
19530 len -= op;
19531 do {
19532 output[_out++] = s_window[from++];
19533 } while (--op);
19534 from = _out - dist; /* rest from output */
19535 from_source = output;
19536 }
19537 }
19538 } else { /* contiguous in window */
19539 from += wnext - op;
19540 if (op < len) { /* some from window */
19541 len -= op;
19542 do {
19543 output[_out++] = s_window[from++];
19544 } while (--op);
19545 from = _out - dist; /* rest from output */
19546 from_source = output;
19547 }
19548 }
19549 while (len > 2) {
19550 output[_out++] = from_source[from++];
19551 output[_out++] = from_source[from++];
19552 output[_out++] = from_source[from++];
19553 len -= 3;
19554 }
19555 if (len) {
19556 output[_out++] = from_source[from++];
19557 if (len > 1) {
19558 output[_out++] = from_source[from++];
19559 }
19560 }
19561 } else {
19562 from = _out - dist; /* copy direct from output */
19563 do { /* minimum length is three */
19564 output[_out++] = output[from++];
19565 output[_out++] = output[from++];
19566 output[_out++] = output[from++];
19567 len -= 3;
19568 } while (len > 2);
19569 if (len) {
19570 output[_out++] = output[from++];
19571 if (len > 1) {
19572 output[_out++] = output[from++];
19573 }
19574 }
19575 }
19576 } else if ((op & 64) === 0) { /* 2nd level distance code */
19577 here = dcode[(here & 0xffff)/*here.val*/ + (hold & (1 << op) - 1)];
19578 continue dodist;
19579 } else {
19580 strm.msg = "invalid distance code";
19581 state.mode = BAD;
19582 break top;
19583 }
19584
19585 break; // need to emulate goto via "continue"
19586 }
19587 } else if ((op & 64) === 0) { /* 2nd level length code */
19588 here = lcode[(here & 0xffff)/*here.val*/ + (hold & (1 << op) - 1)];
19589 continue dolen;
19590 } else if (op & 32) { /* end-of-block */
19591 //Tracevv((stderr, "inflate: end of block\n"));
19592 state.mode = TYPE;
19593 break top;
19594 } else {
19595 strm.msg = "invalid literal/length code";
19596 state.mode = BAD;
19597 break top;
19598 }
19599
19600 break; // need to emulate goto via "continue"
19601 }
19602 } while (_in < last && _out < end);
19603
19604 /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
19605 len = bits >> 3;
19606 _in -= len;
19607 bits -= len << 3;
19608 hold &= (1 << bits) - 1;
19609
19610 /* update state and return */
19611 strm.next_in = _in;
19612 strm.next_out = _out;
19613 strm.avail_in = _in < last ? 5 + (last - _in) : 5 - (_in - last);
19614 strm.avail_out = _out < end ? 257 + (end - _out) : 257 - (_out - end);
19615 state.hold = hold;
19616 state.bits = bits;
19617 return;
19618}
19619
19620const MAXBITS = 15;
19621const ENOUGH_LENS = 852;
19622const ENOUGH_DISTS = 592;
19623//var ENOUGH = (ENOUGH_LENS+ENOUGH_DISTS);
19624
19625const CODES = 0;
19626const LENS = 1;
19627const DISTS = 2;
19628
19629const lbase = [ /* Length codes 257..285 base */
19630 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
19631 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0
19632];
19633
19634const lext = [ /* Length codes 257..285 extra */
19635 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
19636 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78
19637];
19638
19639const dbase = [ /* Distance codes 0..29 base */
19640 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
19641 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
19642 8193, 12289, 16385, 24577, 0, 0
19643];
19644
19645const dext = [ /* Distance codes 0..29 extra */
19646 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
19647 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
19648 28, 28, 29, 29, 64, 64
19649];
19650
19651function inflate_table(type, lens, lens_index, codes, table, table_index, work, opts) {
19652 const bits = opts.bits;
19653 //here = opts.here; /* table entry for duplication */
19654
19655 let len = 0; /* a code's length in bits */
19656 let sym = 0; /* index of code symbols */
19657 let min = 0, max = 0; /* minimum and maximum code lengths */
19658 let root = 0; /* number of index bits for root table */
19659 let curr = 0; /* number of index bits for current table */
19660 let drop = 0; /* code bits to drop for sub-table */
19661 let left = 0; /* number of prefix codes available */
19662 let used = 0; /* code entries in table used */
19663 let huff = 0; /* Huffman code */
19664 let incr; /* for incrementing code, index */
19665 let fill; /* index for replicating entries */
19666 let low; /* low bits for current root entry */
19667 let next; /* next available space in table */
19668 let base = null; /* base value table to use */
19669 let base_index = 0;
19670 // var shoextra; /* extra bits table to use */
19671 let end; /* use base and extra for symbol > end */
19672 const count = new Buf16(MAXBITS + 1); //[MAXBITS+1]; /* number of codes of each length */
19673 const offs = new Buf16(MAXBITS + 1); //[MAXBITS+1]; /* offsets in table for each length */
19674 let extra = null;
19675 let extra_index = 0;
19676
19677 let here_bits, here_op, here_val;
19678
19679 /*
19680 Process a set of code lengths to create a canonical Huffman code. The
19681 code lengths are lens[0..codes-1]. Each length corresponds to the
19682 symbols 0..codes-1. The Huffman code is generated by first sorting the
19683 symbols by length from short to long, and retaining the symbol order
19684 for codes with equal lengths. Then the code starts with all zero bits
19685 for the first code of the shortest length, and the codes are integer
19686 increments for the same length, and zeros are appended as the length
19687 increases. For the deflate format, these bits are stored backwards
19688 from their more natural integer increment ordering, and so when the
19689 decoding tables are built in the large loop below, the integer codes
19690 are incremented backwards.
19691
19692 This routine assumes, but does not check, that all of the entries in
19693 lens[] are in the range 0..MAXBITS. The caller must assure this.
19694 1..MAXBITS is interpreted as that code length. zero means that that
19695 symbol does not occur in this code.
19696
19697 The codes are sorted by computing a count of codes for each length,
19698 creating from that a table of starting indices for each length in the
19699 sorted table, and then entering the symbols in order in the sorted
19700 table. The sorted table is work[], with that space being provided by
19701 the caller.
19702
19703 The length counts are used for other purposes as well, i.e. finding
19704 the minimum and maximum length codes, determining if there are any
19705 codes at all, checking for a valid set of lengths, and looking ahead
19706 at length counts to determine sub-table sizes when building the
19707 decoding tables.
19708 */
19709
19710 /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
19711 for (len = 0; len <= MAXBITS; len++) {
19712 count[len] = 0;
19713 }
19714 for (sym = 0; sym < codes; sym++) {
19715 count[lens[lens_index + sym]]++;
19716 }
19717
19718 /* bound code lengths, force root to be within code lengths */
19719 root = bits;
19720 for (max = MAXBITS; max >= 1; max--) {
19721 if (count[max] !== 0) {
19722 break;
19723 }
19724 }
19725 if (root > max) {
19726 root = max;
19727 }
19728 if (max === 0) { /* no symbols to code at all */
19729 //table.op[opts.table_index] = 64; //here.op = (var char)64; /* invalid code marker */
19730 //table.bits[opts.table_index] = 1; //here.bits = (var char)1;
19731 //table.val[opts.table_index++] = 0; //here.val = (var short)0;
19732 table[table_index++] = 1 << 24 | 64 << 16 | 0;
19733
19734
19735 //table.op[opts.table_index] = 64;
19736 //table.bits[opts.table_index] = 1;
19737 //table.val[opts.table_index++] = 0;
19738 table[table_index++] = 1 << 24 | 64 << 16 | 0;
19739
19740 opts.bits = 1;
19741 return 0; /* no symbols, but wait for decoding to report error */
19742 }
19743 for (min = 1; min < max; min++) {
19744 if (count[min] !== 0) {
19745 break;
19746 }
19747 }
19748 if (root < min) {
19749 root = min;
19750 }
19751
19752 /* check for an over-subscribed or incomplete set of lengths */
19753 left = 1;
19754 for (len = 1; len <= MAXBITS; len++) {
19755 left <<= 1;
19756 left -= count[len];
19757 if (left < 0) {
19758 return -1;
19759 } /* over-subscribed */
19760 }
19761 if (left > 0 && (type === CODES || max !== 1)) {
19762 return -1; /* incomplete set */
19763 }
19764
19765 /* generate offsets into symbol table for each length for sorting */
19766 offs[1] = 0;
19767 for (len = 1; len < MAXBITS; len++) {
19768 offs[len + 1] = offs[len] + count[len];
19769 }
19770
19771 /* sort symbols by length, by symbol order within each length */
19772 for (sym = 0; sym < codes; sym++) {
19773 if (lens[lens_index + sym] !== 0) {
19774 work[offs[lens[lens_index + sym]]++] = sym;
19775 }
19776 }
19777
19778 /*
19779 Create and fill in decoding tables. In this loop, the table being
19780 filled is at next and has curr index bits. The code being used is huff
19781 with length len. That code is converted to an index by dropping drop
19782 bits off of the bottom. For codes where len is less than drop + curr,
19783 those top drop + curr - len bits are incremented through all values to
19784 fill the table with replicated entries.
19785
19786 root is the number of index bits for the root table. When len exceeds
19787 root, sub-tables are created pointed to by the root entry with an index
19788 of the low root bits of huff. This is saved in low to check for when a
19789 new sub-table should be started. drop is zero when the root table is
19790 being filled, and drop is root when sub-tables are being filled.
19791
19792 When a new sub-table is needed, it is necessary to look ahead in the
19793 code lengths to determine what size sub-table is needed. The length
19794 counts are used for this, and so count[] is decremented as codes are
19795 entered in the tables.
19796
19797 used keeps track of how many table entries have been allocated from the
19798 provided *table space. It is checked for LENS and DIST tables against
19799 the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
19800 the initial root table size constants. See the comments in inftrees.h
19801 for more information.
19802
19803 sym increments through all symbols, and the loop terminates when
19804 all codes of length max, i.e. all codes, have been processed. This
19805 routine permits incomplete codes, so another loop after this one fills
19806 in the rest of the decoding tables with invalid code markers.
19807 */
19808
19809 /* set up for code type */
19810 // poor man optimization - use if-else instead of switch,
19811 // to avoid deopts in old v8
19812 if (type === CODES) {
19813 base = extra = work; /* dummy value--not used */
19814 end = 19;
19815
19816 } else if (type === LENS) {
19817 base = lbase;
19818 base_index -= 257;
19819 extra = lext;
19820 extra_index -= 257;
19821 end = 256;
19822
19823 } else { /* DISTS */
19824 base = dbase;
19825 extra = dext;
19826 end = -1;
19827 }
19828
19829 /* initialize opts for loop */
19830 huff = 0; /* starting code */
19831 sym = 0; /* starting code symbol */
19832 len = min; /* starting code length */
19833 next = table_index; /* current table to fill in */
19834 curr = root; /* current table index bits */
19835 drop = 0; /* current bits to drop from code for index */
19836 low = -1; /* trigger new sub-table when len > root */
19837 used = 1 << root; /* use root table entries */
19838 const mask = used - 1; /* mask for comparing low */
19839
19840 /* check available table space */
19841 if (type === LENS && used > ENOUGH_LENS ||
19842 type === DISTS && used > ENOUGH_DISTS) {
19843 return 1;
19844 }
19845
19846 /* process all codes and make table entries */
19847 for (;;) {
19848 /* create table entry */
19849 here_bits = len - drop;
19850 if (work[sym] < end) {
19851 here_op = 0;
19852 here_val = work[sym];
19853 } else if (work[sym] > end) {
19854 here_op = extra[extra_index + work[sym]];
19855 here_val = base[base_index + work[sym]];
19856 } else {
19857 here_op = 32 + 64; /* end of block */
19858 here_val = 0;
19859 }
19860
19861 /* replicate for those indices with low len bits equal to huff */
19862 incr = 1 << len - drop;
19863 fill = 1 << curr;
19864 min = fill; /* save offset to next table */
19865 do {
19866 fill -= incr;
19867 table[next + (huff >> drop) + fill] = here_bits << 24 | here_op << 16 | here_val |0;
19868 } while (fill !== 0);
19869
19870 /* backwards increment the len-bit code huff */
19871 incr = 1 << len - 1;
19872 while (huff & incr) {
19873 incr >>= 1;
19874 }
19875 if (incr !== 0) {
19876 huff &= incr - 1;
19877 huff += incr;
19878 } else {
19879 huff = 0;
19880 }
19881
19882 /* go to next symbol, update count, len */
19883 sym++;
19884 if (--count[len] === 0) {
19885 if (len === max) {
19886 break;
19887 }
19888 len = lens[lens_index + work[sym]];
19889 }
19890
19891 /* create new sub-table if needed */
19892 if (len > root && (huff & mask) !== low) {
19893 /* if first time, transition to sub-tables */
19894 if (drop === 0) {
19895 drop = root;
19896 }
19897
19898 /* increment past last table */
19899 next += min; /* here min is 1 << curr */
19900
19901 /* determine length of next table */
19902 curr = len - drop;
19903 left = 1 << curr;
19904 while (curr + drop < max) {
19905 left -= count[curr + drop];
19906 if (left <= 0) {
19907 break;
19908 }
19909 curr++;
19910 left <<= 1;
19911 }
19912
19913 /* check for enough space */
19914 used += 1 << curr;
19915 if (type === LENS && used > ENOUGH_LENS ||
19916 type === DISTS && used > ENOUGH_DISTS) {
19917 return 1;
19918 }
19919
19920 /* point entry in root table to sub-table */
19921 low = huff & mask;
19922 /*table.op[low] = curr;
19923 table.bits[low] = root;
19924 table.val[low] = next - opts.table_index;*/
19925 table[low] = root << 24 | curr << 16 | next - table_index |0;
19926 }
19927 }
19928
19929 /* fill in remaining table entry if code is incomplete (guaranteed to have
19930 at most one remaining entry, since if the code is incomplete, the
19931 maximum code length that was allowed to get this far is one bit) */
19932 if (huff !== 0) {
19933 //table.op[next + huff] = 64; /* invalid code marker */
19934 //table.bits[next + huff] = len - drop;
19935 //table.val[next + huff] = 0;
19936 table[next + huff] = len - drop << 24 | 64 << 16 |0;
19937 }
19938
19939 /* set return parameters */
19940 //opts.table_index += used;
19941 opts.bits = root;
19942 return 0;
19943}
19944
19945const CODES$1 = 0;
19946const LENS$1 = 1;
19947const DISTS$1 = 2;
19948
19949/* STATES ====================================================================*/
19950/* ===========================================================================*/
19951
19952
19953const HEAD = 1; /* i: waiting for magic header */
19954const FLAGS = 2; /* i: waiting for method and flags (gzip) */
19955const TIME = 3; /* i: waiting for modification time (gzip) */
19956const OS = 4; /* i: waiting for extra flags and operating system (gzip) */
19957const EXLEN = 5; /* i: waiting for extra length (gzip) */
19958const EXTRA = 6; /* i: waiting for extra bytes (gzip) */
19959const NAME = 7; /* i: waiting for end of file name (gzip) */
19960const COMMENT = 8; /* i: waiting for end of comment (gzip) */
19961const HCRC = 9; /* i: waiting for header crc (gzip) */
19962const DICTID = 10; /* i: waiting for dictionary check value */
19963const DICT = 11; /* waiting for inflateSetDictionary() call */
19964const TYPE$1 = 12; /* i: waiting for type bits, including last-flag bit */
19965const TYPEDO = 13; /* i: same, but skip check to exit inflate on new block */
19966const STORED = 14; /* i: waiting for stored size (length and complement) */
19967const COPY_ = 15; /* i/o: same as COPY below, but only first time in */
19968const COPY = 16; /* i/o: waiting for input or output to copy stored block */
19969const TABLE = 17; /* i: waiting for dynamic block table lengths */
19970const LENLENS = 18; /* i: waiting for code length code lengths */
19971const CODELENS = 19; /* i: waiting for length/lit and distance code lengths */
19972const LEN_ = 20; /* i: same as LEN below, but only first time in */
19973const LEN = 21; /* i: waiting for length/lit/eob code */
19974const LENEXT = 22; /* i: waiting for length extra bits */
19975const DIST = 23; /* i: waiting for distance code */
19976const DISTEXT = 24; /* i: waiting for distance extra bits */
19977const MATCH = 25; /* o: waiting for output space to copy string */
19978const LIT = 26; /* o: waiting for output space to write literal */
19979const CHECK = 27; /* i: waiting for 32-bit check value */
19980const LENGTH = 28; /* i: waiting for 32-bit length (gzip) */
19981const DONE = 29; /* finished check, done -- remain here until reset */
19982const BAD$1 = 30; /* got a data error -- remain here until reset */
19983//const MEM = 31; /* got an inflate() memory error -- remain here until reset */
19984const SYNC = 32; /* looking for synchronization bytes to restart inflate() */
19985
19986/* ===========================================================================*/
19987
19988
19989
19990const ENOUGH_LENS$1 = 852;
19991const ENOUGH_DISTS$1 = 592;
19992
19993
19994function zswap32(q) {
19995 return (((q >>> 24) & 0xff) +
19996 ((q >>> 8) & 0xff00) +
19997 ((q & 0xff00) << 8) +
19998 ((q & 0xff) << 24));
19999}
20000
20001
20002class InflateState {
20003 constructor() {
20004 this.mode = 0; /* current inflate mode */
20005 this.last = false; /* true if processing last block */
20006 this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
20007 this.havedict = false; /* true if dictionary provided */
20008 this.flags = 0; /* gzip header method and flags (0 if zlib) */
20009 this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
20010 this.check = 0; /* protected copy of check value */
20011 this.total = 0; /* protected copy of output count */
20012 // TODO: may be {}
20013 this.head = null; /* where to save gzip header information */
20014
20015 /* sliding window */
20016 this.wbits = 0; /* log base 2 of requested window size */
20017 this.wsize = 0; /* window size or zero if not using window */
20018 this.whave = 0; /* valid bytes in the window */
20019 this.wnext = 0; /* window write index */
20020 this.window = null; /* allocated sliding window, if needed */
20021
20022 /* bit accumulator */
20023 this.hold = 0; /* input bit accumulator */
20024 this.bits = 0; /* number of bits in "in" */
20025
20026 /* for string and stored block copying */
20027 this.length = 0; /* literal or length of data to copy */
20028 this.offset = 0; /* distance back to copy string from */
20029
20030 /* for table and code decoding */
20031 this.extra = 0; /* extra bits needed */
20032
20033 /* fixed and dynamic code tables */
20034 this.lencode = null; /* starting table for length/literal codes */
20035 this.distcode = null; /* starting table for distance codes */
20036 this.lenbits = 0; /* index bits for lencode */
20037 this.distbits = 0; /* index bits for distcode */
20038
20039 /* dynamic table building */
20040 this.ncode = 0; /* number of code length code lengths */
20041 this.nlen = 0; /* number of length code lengths */
20042 this.ndist = 0; /* number of distance code lengths */
20043 this.have = 0; /* number of code lengths in lens[] */
20044 this.next = null; /* next available space in codes[] */
20045
20046 this.lens = new Buf16(320); /* temporary storage for code lengths */
20047 this.work = new Buf16(288); /* work area for code table building */
20048
20049 /*
20050 because we don't have pointers in js, we use lencode and distcode directly
20051 as buffers so we don't need codes
20052 */
20053 //this.codes = new utils.Buf32(ENOUGH); /* space for code tables */
20054 this.lendyn = null; /* dynamic table for length/literal codes (JS specific) */
20055 this.distdyn = null; /* dynamic table for distance codes (JS specific) */
20056 this.sane = 0; /* if false, allow invalid distance too far */
20057 this.back = 0; /* bits back of last unprocessed length/lit */
20058 this.was = 0; /* initial length of match */
20059 }
20060}
20061
20062function inflateResetKeep(strm) {
20063 let state;
20064
20065 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
20066 state = strm.state;
20067 strm.total_in = strm.total_out = state.total = 0;
20068 strm.msg = ''; /*Z_NULL*/
20069 if (state.wrap) { /* to support ill-conceived Java test suite */
20070 strm.adler = state.wrap & 1;
20071 }
20072 state.mode = HEAD;
20073 state.last = 0;
20074 state.havedict = 0;
20075 state.dmax = 32768;
20076 state.head = null/*Z_NULL*/;
20077 state.hold = 0;
20078 state.bits = 0;
20079 //state.lencode = state.distcode = state.next = state.codes;
20080 state.lencode = state.lendyn = new Buf32(ENOUGH_LENS$1);
20081 state.distcode = state.distdyn = new Buf32(ENOUGH_DISTS$1);
20082
20083 state.sane = 1;
20084 state.back = -1;
20085 //Tracev((stderr, "inflate: reset\n"));
20086 return Z_OK;
20087}
20088
20089function inflateReset(strm) {
20090 let state;
20091
20092 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
20093 state = strm.state;
20094 state.wsize = 0;
20095 state.whave = 0;
20096 state.wnext = 0;
20097 return inflateResetKeep(strm);
20098
20099}
20100
20101function inflateReset2(strm, windowBits) {
20102 let wrap;
20103 let state;
20104
20105 /* get the state */
20106 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
20107 state = strm.state;
20108
20109 /* extract wrap request from windowBits parameter */
20110 if (windowBits < 0) {
20111 wrap = 0;
20112 windowBits = -windowBits;
20113 }
20114 else {
20115 wrap = (windowBits >> 4) + 1;
20116 if (windowBits < 48) {
20117 windowBits &= 15;
20118 }
20119 }
20120
20121 /* set number of window bits, free window if different */
20122 if (windowBits && (windowBits < 8 || windowBits > 15)) {
20123 return Z_STREAM_ERROR;
20124 }
20125 if (state.window !== null && state.wbits !== windowBits) {
20126 state.window = null;
20127 }
20128
20129 /* update state and reset the rest of it */
20130 state.wrap = wrap;
20131 state.wbits = windowBits;
20132 return inflateReset(strm);
20133}
20134
20135function inflateInit2(strm, windowBits) {
20136 let ret;
20137 let state;
20138
20139 if (!strm) { return Z_STREAM_ERROR; }
20140 //strm.msg = Z_NULL; /* in case we return an error */
20141
20142 state = new InflateState();
20143
20144 //if (state === Z_NULL) return Z_MEM_ERROR;
20145 //Tracev((stderr, "inflate: allocated\n"));
20146 strm.state = state;
20147 state.window = null/*Z_NULL*/;
20148 ret = inflateReset2(strm, windowBits);
20149 if (ret !== Z_OK) {
20150 strm.state = null/*Z_NULL*/;
20151 }
20152 return ret;
20153}
20154
20155
20156/*
20157 Return state with length and distance decoding tables and index sizes set to
20158 fixed code decoding. Normally this returns fixed tables from inffixed.h.
20159 If BUILDFIXED is defined, then instead this routine builds the tables the
20160 first time it's called, and returns those tables the first time and
20161 thereafter. This reduces the size of the code by about 2K bytes, in
20162 exchange for a little execution time. However, BUILDFIXED should not be
20163 used for threaded applications, since the rewriting of the tables and virgin
20164 may not be thread-safe.
20165 */
20166let virgin = true;
20167
20168let lenfix, distfix; // We have no pointers in JS, so keep tables separate
20169
20170function fixedtables(state) {
20171 /* build fixed huffman tables if first call (may not be thread safe) */
20172 if (virgin) {
20173 let sym;
20174
20175 lenfix = new Buf32(512);
20176 distfix = new Buf32(32);
20177
20178 /* literal/length table */
20179 sym = 0;
20180 while (sym < 144) { state.lens[sym++] = 8; }
20181 while (sym < 256) { state.lens[sym++] = 9; }
20182 while (sym < 280) { state.lens[sym++] = 7; }
20183 while (sym < 288) { state.lens[sym++] = 8; }
20184
20185 inflate_table(LENS$1, state.lens, 0, 288, lenfix, 0, state.work, { bits: 9 });
20186
20187 /* distance table */
20188 sym = 0;
20189 while (sym < 32) { state.lens[sym++] = 5; }
20190
20191 inflate_table(DISTS$1, state.lens, 0, 32, distfix, 0, state.work, { bits: 5 });
20192
20193 /* do this just once */
20194 virgin = false;
20195 }
20196
20197 state.lencode = lenfix;
20198 state.lenbits = 9;
20199 state.distcode = distfix;
20200 state.distbits = 5;
20201}
20202
20203
20204/*
20205 Update the window with the last wsize (normally 32K) bytes written before
20206 returning. If window does not exist yet, create it. This is only called
20207 when a window is already in use, or when output has been written during this
20208 inflate call, but the end of the deflate stream has not been reached yet.
20209 It is also called to create a window for dictionary data when a dictionary
20210 is loaded.
20211
20212 Providing output buffers larger than 32K to inflate() should provide a speed
20213 advantage, since only the last 32K of output is copied to the sliding window
20214 upon return from inflate(), and since all distances after the first 32K of
20215 output will fall in the output data, making match copies simpler and faster.
20216 The advantage may be dependent on the size of the processor's data caches.
20217 */
20218function updatewindow(strm, src, end, copy) {
20219 let dist;
20220 const state = strm.state;
20221
20222 /* if it hasn't been done already, allocate space for the window */
20223 if (state.window === null) {
20224 state.wsize = 1 << state.wbits;
20225 state.wnext = 0;
20226 state.whave = 0;
20227
20228 state.window = new Buf8(state.wsize);
20229 }
20230
20231 /* copy state->wsize or less output bytes into the circular window */
20232 if (copy >= state.wsize) {
20233 arraySet(state.window, src, end - state.wsize, state.wsize, 0);
20234 state.wnext = 0;
20235 state.whave = state.wsize;
20236 }
20237 else {
20238 dist = state.wsize - state.wnext;
20239 if (dist > copy) {
20240 dist = copy;
20241 }
20242 //zmemcpy(state->window + state->wnext, end - copy, dist);
20243 arraySet(state.window, src, end - copy, dist, state.wnext);
20244 copy -= dist;
20245 if (copy) {
20246 //zmemcpy(state->window, end - copy, copy);
20247 arraySet(state.window, src, end - copy, copy, 0);
20248 state.wnext = copy;
20249 state.whave = state.wsize;
20250 }
20251 else {
20252 state.wnext += dist;
20253 if (state.wnext === state.wsize) { state.wnext = 0; }
20254 if (state.whave < state.wsize) { state.whave += dist; }
20255 }
20256 }
20257 return 0;
20258}
20259
20260function inflate(strm, flush) {
20261 let state;
20262 let input, output; // input/output buffers
20263 let next; /* next input INDEX */
20264 let put; /* next output INDEX */
20265 let have, left; /* available input and output */
20266 let hold; /* bit buffer */
20267 let bits; /* bits in bit buffer */
20268 let _in, _out; /* save starting available input and output */
20269 let copy; /* number of stored or match bytes to copy */
20270 let from; /* where to copy match bytes from */
20271 let from_source;
20272 let here = 0; /* current decoding table entry */
20273 let here_bits, here_op, here_val; // paked "here" denormalized (JS specific)
20274 //var last; /* parent table entry */
20275 let last_bits, last_op, last_val; // paked "last" denormalized (JS specific)
20276 let len; /* length to copy for repeats, bits to drop */
20277 let ret; /* return code */
20278 let hbuf = new Buf8(4); /* buffer for gzip header crc calculation */
20279 let opts;
20280
20281 let n; // temporary var for NEED_BITS
20282
20283 const order = /* permutation of code lengths */
20284 [ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 ];
20285
20286
20287 if (!strm || !strm.state || !strm.output ||
20288 (!strm.input && strm.avail_in !== 0)) {
20289 return Z_STREAM_ERROR;
20290 }
20291
20292 state = strm.state;
20293 if (state.mode === TYPE$1) { state.mode = TYPEDO; } /* skip check */
20294
20295
20296 //--- LOAD() ---
20297 put = strm.next_out;
20298 output = strm.output;
20299 left = strm.avail_out;
20300 next = strm.next_in;
20301 input = strm.input;
20302 have = strm.avail_in;
20303 hold = state.hold;
20304 bits = state.bits;
20305 //---
20306
20307 _in = have;
20308 _out = left;
20309 ret = Z_OK;
20310
20311 inf_leave: // goto emulation
20312 for (;;) {
20313 switch (state.mode) {
20314 case HEAD:
20315 if (state.wrap === 0) {
20316 state.mode = TYPEDO;
20317 break;
20318 }
20319 //=== NEEDBITS(16);
20320 while (bits < 16) {
20321 if (have === 0) { break inf_leave; }
20322 have--;
20323 hold += input[next++] << bits;
20324 bits += 8;
20325 }
20326 //===//
20327 if ((state.wrap & 2) && hold === 0x8b1f) { /* gzip header */
20328 state.check = 0/*crc32(0L, Z_NULL, 0)*/;
20329 //=== CRC2(state.check, hold);
20330 hbuf[0] = hold & 0xff;
20331 hbuf[1] = (hold >>> 8) & 0xff;
20332 state.check = crc32(state.check, hbuf, 2, 0);
20333 //===//
20334
20335 //=== INITBITS();
20336 hold = 0;
20337 bits = 0;
20338 //===//
20339 state.mode = FLAGS;
20340 break;
20341 }
20342 state.flags = 0; /* expect zlib header */
20343 if (state.head) {
20344 state.head.done = false;
20345 }
20346 if (!(state.wrap & 1) || /* check if zlib header allowed */
20347 (((hold & 0xff)/*BITS(8)*/ << 8) + (hold >> 8)) % 31) {
20348 strm.msg = 'incorrect header check';
20349 state.mode = BAD$1;
20350 break;
20351 }
20352 if ((hold & 0x0f)/*BITS(4)*/ !== Z_DEFLATED) {
20353 strm.msg = 'unknown compression method';
20354 state.mode = BAD$1;
20355 break;
20356 }
20357 //--- DROPBITS(4) ---//
20358 hold >>>= 4;
20359 bits -= 4;
20360 //---//
20361 len = (hold & 0x0f)/*BITS(4)*/ + 8;
20362 if (state.wbits === 0) {
20363 state.wbits = len;
20364 }
20365 else if (len > state.wbits) {
20366 strm.msg = 'invalid window size';
20367 state.mode = BAD$1;
20368 break;
20369 }
20370 state.dmax = 1 << len;
20371 //Tracev((stderr, "inflate: zlib header ok\n"));
20372 strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
20373 state.mode = hold & 0x200 ? DICTID : TYPE$1;
20374 //=== INITBITS();
20375 hold = 0;
20376 bits = 0;
20377 //===//
20378 break;
20379 case FLAGS:
20380 //=== NEEDBITS(16); */
20381 while (bits < 16) {
20382 if (have === 0) { break inf_leave; }
20383 have--;
20384 hold += input[next++] << bits;
20385 bits += 8;
20386 }
20387 //===//
20388 state.flags = hold;
20389 if ((state.flags & 0xff) !== Z_DEFLATED) {
20390 strm.msg = 'unknown compression method';
20391 state.mode = BAD$1;
20392 break;
20393 }
20394 if (state.flags & 0xe000) {
20395 strm.msg = 'unknown header flags set';
20396 state.mode = BAD$1;
20397 break;
20398 }
20399 if (state.head) {
20400 state.head.text = ((hold >> 8) & 1);
20401 }
20402 if (state.flags & 0x0200) {
20403 //=== CRC2(state.check, hold);
20404 hbuf[0] = hold & 0xff;
20405 hbuf[1] = (hold >>> 8) & 0xff;
20406 state.check = crc32(state.check, hbuf, 2, 0);
20407 //===//
20408 }
20409 //=== INITBITS();
20410 hold = 0;
20411 bits = 0;
20412 //===//
20413 state.mode = TIME;
20414 /* falls through */
20415 case TIME:
20416 //=== NEEDBITS(32); */
20417 while (bits < 32) {
20418 if (have === 0) { break inf_leave; }
20419 have--;
20420 hold += input[next++] << bits;
20421 bits += 8;
20422 }
20423 //===//
20424 if (state.head) {
20425 state.head.time = hold;
20426 }
20427 if (state.flags & 0x0200) {
20428 //=== CRC4(state.check, hold)
20429 hbuf[0] = hold & 0xff;
20430 hbuf[1] = (hold >>> 8) & 0xff;
20431 hbuf[2] = (hold >>> 16) & 0xff;
20432 hbuf[3] = (hold >>> 24) & 0xff;
20433 state.check = crc32(state.check, hbuf, 4, 0);
20434 //===
20435 }
20436 //=== INITBITS();
20437 hold = 0;
20438 bits = 0;
20439 //===//
20440 state.mode = OS;
20441 /* falls through */
20442 case OS:
20443 //=== NEEDBITS(16); */
20444 while (bits < 16) {
20445 if (have === 0) { break inf_leave; }
20446 have--;
20447 hold += input[next++] << bits;
20448 bits += 8;
20449 }
20450 //===//
20451 if (state.head) {
20452 state.head.xflags = (hold & 0xff);
20453 state.head.os = (hold >> 8);
20454 }
20455 if (state.flags & 0x0200) {
20456 //=== CRC2(state.check, hold);
20457 hbuf[0] = hold & 0xff;
20458 hbuf[1] = (hold >>> 8) & 0xff;
20459 state.check = crc32(state.check, hbuf, 2, 0);
20460 //===//
20461 }
20462 //=== INITBITS();
20463 hold = 0;
20464 bits = 0;
20465 //===//
20466 state.mode = EXLEN;
20467 /* falls through */
20468 case EXLEN:
20469 if (state.flags & 0x0400) {
20470 //=== NEEDBITS(16); */
20471 while (bits < 16) {
20472 if (have === 0) { break inf_leave; }
20473 have--;
20474 hold += input[next++] << bits;
20475 bits += 8;
20476 }
20477 //===//
20478 state.length = hold;
20479 if (state.head) {
20480 state.head.extra_len = hold;
20481 }
20482 if (state.flags & 0x0200) {
20483 //=== CRC2(state.check, hold);
20484 hbuf[0] = hold & 0xff;
20485 hbuf[1] = (hold >>> 8) & 0xff;
20486 state.check = crc32(state.check, hbuf, 2, 0);
20487 //===//
20488 }
20489 //=== INITBITS();
20490 hold = 0;
20491 bits = 0;
20492 //===//
20493 }
20494 else if (state.head) {
20495 state.head.extra = null/*Z_NULL*/;
20496 }
20497 state.mode = EXTRA;
20498 /* falls through */
20499 case EXTRA:
20500 if (state.flags & 0x0400) {
20501 copy = state.length;
20502 if (copy > have) { copy = have; }
20503 if (copy) {
20504 if (state.head) {
20505 len = state.head.extra_len - state.length;
20506 if (!state.head.extra) {
20507 // Use untyped array for more convenient processing later
20508 state.head.extra = new Array(state.head.extra_len);
20509 }
20510 arraySet(
20511 state.head.extra,
20512 input,
20513 next,
20514 // extra field is limited to 65536 bytes
20515 // - no need for additional size check
20516 copy,
20517 /*len + copy > state.head.extra_max - len ? state.head.extra_max : copy,*/
20518 len
20519 );
20520 //zmemcpy(state.head.extra + len, next,
20521 // len + copy > state.head.extra_max ?
20522 // state.head.extra_max - len : copy);
20523 }
20524 if (state.flags & 0x0200) {
20525 state.check = crc32(state.check, input, copy, next);
20526 }
20527 have -= copy;
20528 next += copy;
20529 state.length -= copy;
20530 }
20531 if (state.length) { break inf_leave; }
20532 }
20533 state.length = 0;
20534 state.mode = NAME;
20535 /* falls through */
20536 case NAME:
20537 if (state.flags & 0x0800) {
20538 if (have === 0) { break inf_leave; }
20539 copy = 0;
20540 do {
20541 // TODO: 2 or 1 bytes?
20542 len = input[next + copy++];
20543 /* use constant limit because in js we should not preallocate memory */
20544 if (state.head && len &&
20545 (state.length < 65536 /*state.head.name_max*/)) {
20546 state.head.name += String.fromCharCode(len);
20547 }
20548 } while (len && copy < have);
20549
20550 if (state.flags & 0x0200) {
20551 state.check = crc32(state.check, input, copy, next);
20552 }
20553 have -= copy;
20554 next += copy;
20555 if (len) { break inf_leave; }
20556 }
20557 else if (state.head) {
20558 state.head.name = null;
20559 }
20560 state.length = 0;
20561 state.mode = COMMENT;
20562 /* falls through */
20563 case COMMENT:
20564 if (state.flags & 0x1000) {
20565 if (have === 0) { break inf_leave; }
20566 copy = 0;
20567 do {
20568 len = input[next + copy++];
20569 /* use constant limit because in js we should not preallocate memory */
20570 if (state.head && len &&
20571 (state.length < 65536 /*state.head.comm_max*/)) {
20572 state.head.comment += String.fromCharCode(len);
20573 }
20574 } while (len && copy < have);
20575 if (state.flags & 0x0200) {
20576 state.check = crc32(state.check, input, copy, next);
20577 }
20578 have -= copy;
20579 next += copy;
20580 if (len) { break inf_leave; }
20581 }
20582 else if (state.head) {
20583 state.head.comment = null;
20584 }
20585 state.mode = HCRC;
20586 /* falls through */
20587 case HCRC:
20588 if (state.flags & 0x0200) {
20589 //=== NEEDBITS(16); */
20590 while (bits < 16) {
20591 if (have === 0) { break inf_leave; }
20592 have--;
20593 hold += input[next++] << bits;
20594 bits += 8;
20595 }
20596 //===//
20597 if (hold !== (state.check & 0xffff)) {
20598 strm.msg = 'header crc mismatch';
20599 state.mode = BAD$1;
20600 break;
20601 }
20602 //=== INITBITS();
20603 hold = 0;
20604 bits = 0;
20605 //===//
20606 }
20607 if (state.head) {
20608 state.head.hcrc = ((state.flags >> 9) & 1);
20609 state.head.done = true;
20610 }
20611 strm.adler = state.check = 0;
20612 state.mode = TYPE$1;
20613 break;
20614 case DICTID:
20615 //=== NEEDBITS(32); */
20616 while (bits < 32) {
20617 if (have === 0) { break inf_leave; }
20618 have--;
20619 hold += input[next++] << bits;
20620 bits += 8;
20621 }
20622 //===//
20623 strm.adler = state.check = zswap32(hold);
20624 //=== INITBITS();
20625 hold = 0;
20626 bits = 0;
20627 //===//
20628 state.mode = DICT;
20629 /* falls through */
20630 case DICT:
20631 if (state.havedict === 0) {
20632 //--- RESTORE() ---
20633 strm.next_out = put;
20634 strm.avail_out = left;
20635 strm.next_in = next;
20636 strm.avail_in = have;
20637 state.hold = hold;
20638 state.bits = bits;
20639 //---
20640 return Z_NEED_DICT;
20641 }
20642 strm.adler = state.check = 1/*adler32(0L, Z_NULL, 0)*/;
20643 state.mode = TYPE$1;
20644 /* falls through */
20645 case TYPE$1:
20646 if (flush === Z_BLOCK || flush === Z_TREES) { break inf_leave; }
20647 /* falls through */
20648 case TYPEDO:
20649 if (state.last) {
20650 //--- BYTEBITS() ---//
20651 hold >>>= bits & 7;
20652 bits -= bits & 7;
20653 //---//
20654 state.mode = CHECK;
20655 break;
20656 }
20657 //=== NEEDBITS(3); */
20658 while (bits < 3) {
20659 if (have === 0) { break inf_leave; }
20660 have--;
20661 hold += input[next++] << bits;
20662 bits += 8;
20663 }
20664 //===//
20665 state.last = (hold & 0x01)/*BITS(1)*/;
20666 //--- DROPBITS(1) ---//
20667 hold >>>= 1;
20668 bits -= 1;
20669 //---//
20670
20671 switch ((hold & 0x03)/*BITS(2)*/) {
20672 case 0: /* stored block */
20673 //Tracev((stderr, "inflate: stored block%s\n",
20674 // state.last ? " (last)" : ""));
20675 state.mode = STORED;
20676 break;
20677 case 1: /* fixed block */
20678 fixedtables(state);
20679 //Tracev((stderr, "inflate: fixed codes block%s\n",
20680 // state.last ? " (last)" : ""));
20681 state.mode = LEN_; /* decode codes */
20682 if (flush === Z_TREES) {
20683 //--- DROPBITS(2) ---//
20684 hold >>>= 2;
20685 bits -= 2;
20686 //---//
20687 break inf_leave;
20688 }
20689 break;
20690 case 2: /* dynamic block */
20691 //Tracev((stderr, "inflate: dynamic codes block%s\n",
20692 // state.last ? " (last)" : ""));
20693 state.mode = TABLE;
20694 break;
20695 case 3:
20696 strm.msg = 'invalid block type';
20697 state.mode = BAD$1;
20698 }
20699 //--- DROPBITS(2) ---//
20700 hold >>>= 2;
20701 bits -= 2;
20702 //---//
20703 break;
20704 case STORED:
20705 //--- BYTEBITS() ---// /* go to byte boundary */
20706 hold >>>= bits & 7;
20707 bits -= bits & 7;
20708 //---//
20709 //=== NEEDBITS(32); */
20710 while (bits < 32) {
20711 if (have === 0) { break inf_leave; }
20712 have--;
20713 hold += input[next++] << bits;
20714 bits += 8;
20715 }
20716 //===//
20717 if ((hold & 0xffff) !== ((hold >>> 16) ^ 0xffff)) {
20718 strm.msg = 'invalid stored block lengths';
20719 state.mode = BAD$1;
20720 break;
20721 }
20722 state.length = hold & 0xffff;
20723 //Tracev((stderr, "inflate: stored length %u\n",
20724 // state.length));
20725 //=== INITBITS();
20726 hold = 0;
20727 bits = 0;
20728 //===//
20729 state.mode = COPY_;
20730 if (flush === Z_TREES) { break inf_leave; }
20731 /* falls through */
20732 case COPY_:
20733 state.mode = COPY;
20734 /* falls through */
20735 case COPY:
20736 copy = state.length;
20737 if (copy) {
20738 if (copy > have) { copy = have; }
20739 if (copy > left) { copy = left; }
20740 if (copy === 0) { break inf_leave; }
20741 //--- zmemcpy(put, next, copy); ---
20742 arraySet(output, input, next, copy, put);
20743 //---//
20744 have -= copy;
20745 next += copy;
20746 left -= copy;
20747 put += copy;
20748 state.length -= copy;
20749 break;
20750 }
20751 //Tracev((stderr, "inflate: stored end\n"));
20752 state.mode = TYPE$1;
20753 break;
20754 case TABLE:
20755 //=== NEEDBITS(14); */
20756 while (bits < 14) {
20757 if (have === 0) { break inf_leave; }
20758 have--;
20759 hold += input[next++] << bits;
20760 bits += 8;
20761 }
20762 //===//
20763 state.nlen = (hold & 0x1f)/*BITS(5)*/ + 257;
20764 //--- DROPBITS(5) ---//
20765 hold >>>= 5;
20766 bits -= 5;
20767 //---//
20768 state.ndist = (hold & 0x1f)/*BITS(5)*/ + 1;
20769 //--- DROPBITS(5) ---//
20770 hold >>>= 5;
20771 bits -= 5;
20772 //---//
20773 state.ncode = (hold & 0x0f)/*BITS(4)*/ + 4;
20774 //--- DROPBITS(4) ---//
20775 hold >>>= 4;
20776 bits -= 4;
20777 //---//
20778//#ifndef PKZIP_BUG_WORKAROUND
20779 if (state.nlen > 286 || state.ndist > 30) {
20780 strm.msg = 'too many length or distance symbols';
20781 state.mode = BAD$1;
20782 break;
20783 }
20784//#endif
20785 //Tracev((stderr, "inflate: table sizes ok\n"));
20786 state.have = 0;
20787 state.mode = LENLENS;
20788 /* falls through */
20789 case LENLENS:
20790 while (state.have < state.ncode) {
20791 //=== NEEDBITS(3);
20792 while (bits < 3) {
20793 if (have === 0) { break inf_leave; }
20794 have--;
20795 hold += input[next++] << bits;
20796 bits += 8;
20797 }
20798 //===//
20799 state.lens[order[state.have++]] = (hold & 0x07);//BITS(3);
20800 //--- DROPBITS(3) ---//
20801 hold >>>= 3;
20802 bits -= 3;
20803 //---//
20804 }
20805 while (state.have < 19) {
20806 state.lens[order[state.have++]] = 0;
20807 }
20808 // We have separate tables & no pointers. 2 commented lines below not needed.
20809 //state.next = state.codes;
20810 //state.lencode = state.next;
20811 // Switch to use dynamic table
20812 state.lencode = state.lendyn;
20813 state.lenbits = 7;
20814
20815 opts = { bits: state.lenbits };
20816 ret = inflate_table(CODES$1, state.lens, 0, 19, state.lencode, 0, state.work, opts);
20817 state.lenbits = opts.bits;
20818
20819 if (ret) {
20820 strm.msg = 'invalid code lengths set';
20821 state.mode = BAD$1;
20822 break;
20823 }
20824 //Tracev((stderr, "inflate: code lengths ok\n"));
20825 state.have = 0;
20826 state.mode = CODELENS;
20827 /* falls through */
20828 case CODELENS:
20829 while (state.have < state.nlen + state.ndist) {
20830 for (;;) {
20831 here = state.lencode[hold & ((1 << state.lenbits) - 1)];/*BITS(state.lenbits)*/
20832 here_bits = here >>> 24;
20833 here_op = (here >>> 16) & 0xff;
20834 here_val = here & 0xffff;
20835
20836 if ((here_bits) <= bits) { break; }
20837 //--- PULLBYTE() ---//
20838 if (have === 0) { break inf_leave; }
20839 have--;
20840 hold += input[next++] << bits;
20841 bits += 8;
20842 //---//
20843 }
20844 if (here_val < 16) {
20845 //--- DROPBITS(here.bits) ---//
20846 hold >>>= here_bits;
20847 bits -= here_bits;
20848 //---//
20849 state.lens[state.have++] = here_val;
20850 }
20851 else {
20852 if (here_val === 16) {
20853 //=== NEEDBITS(here.bits + 2);
20854 n = here_bits + 2;
20855 while (bits < n) {
20856 if (have === 0) { break inf_leave; }
20857 have--;
20858 hold += input[next++] << bits;
20859 bits += 8;
20860 }
20861 //===//
20862 //--- DROPBITS(here.bits) ---//
20863 hold >>>= here_bits;
20864 bits -= here_bits;
20865 //---//
20866 if (state.have === 0) {
20867 strm.msg = 'invalid bit length repeat';
20868 state.mode = BAD$1;
20869 break;
20870 }
20871 len = state.lens[state.have - 1];
20872 copy = 3 + (hold & 0x03);//BITS(2);
20873 //--- DROPBITS(2) ---//
20874 hold >>>= 2;
20875 bits -= 2;
20876 //---//
20877 }
20878 else if (here_val === 17) {
20879 //=== NEEDBITS(here.bits + 3);
20880 n = here_bits + 3;
20881 while (bits < n) {
20882 if (have === 0) { break inf_leave; }
20883 have--;
20884 hold += input[next++] << bits;
20885 bits += 8;
20886 }
20887 //===//
20888 //--- DROPBITS(here.bits) ---//
20889 hold >>>= here_bits;
20890 bits -= here_bits;
20891 //---//
20892 len = 0;
20893 copy = 3 + (hold & 0x07);//BITS(3);
20894 //--- DROPBITS(3) ---//
20895 hold >>>= 3;
20896 bits -= 3;
20897 //---//
20898 }
20899 else {
20900 //=== NEEDBITS(here.bits + 7);
20901 n = here_bits + 7;
20902 while (bits < n) {
20903 if (have === 0) { break inf_leave; }
20904 have--;
20905 hold += input[next++] << bits;
20906 bits += 8;
20907 }
20908 //===//
20909 //--- DROPBITS(here.bits) ---//
20910 hold >>>= here_bits;
20911 bits -= here_bits;
20912 //---//
20913 len = 0;
20914 copy = 11 + (hold & 0x7f);//BITS(7);
20915 //--- DROPBITS(7) ---//
20916 hold >>>= 7;
20917 bits -= 7;
20918 //---//
20919 }
20920 if (state.have + copy > state.nlen + state.ndist) {
20921 strm.msg = 'invalid bit length repeat';
20922 state.mode = BAD$1;
20923 break;
20924 }
20925 while (copy--) {
20926 state.lens[state.have++] = len;
20927 }
20928 }
20929 }
20930
20931 /* handle error breaks in while */
20932 if (state.mode === BAD$1) { break; }
20933
20934 /* check for end-of-block code (better have one) */
20935 if (state.lens[256] === 0) {
20936 strm.msg = 'invalid code -- missing end-of-block';
20937 state.mode = BAD$1;
20938 break;
20939 }
20940
20941 /* build code tables -- note: do not change the lenbits or distbits
20942 values here (9 and 6) without reading the comments in inftrees.h
20943 concerning the ENOUGH constants, which depend on those values */
20944 state.lenbits = 9;
20945
20946 opts = { bits: state.lenbits };
20947 ret = inflate_table(LENS$1, state.lens, 0, state.nlen, state.lencode, 0, state.work, opts);
20948 // We have separate tables & no pointers. 2 commented lines below not needed.
20949 // state.next_index = opts.table_index;
20950 state.lenbits = opts.bits;
20951 // state.lencode = state.next;
20952
20953 if (ret) {
20954 strm.msg = 'invalid literal/lengths set';
20955 state.mode = BAD$1;
20956 break;
20957 }
20958
20959 state.distbits = 6;
20960 //state.distcode.copy(state.codes);
20961 // Switch to use dynamic table
20962 state.distcode = state.distdyn;
20963 opts = { bits: state.distbits };
20964 ret = inflate_table(DISTS$1, state.lens, state.nlen, state.ndist, state.distcode, 0, state.work, opts);
20965 // We have separate tables & no pointers. 2 commented lines below not needed.
20966 // state.next_index = opts.table_index;
20967 state.distbits = opts.bits;
20968 // state.distcode = state.next;
20969
20970 if (ret) {
20971 strm.msg = 'invalid distances set';
20972 state.mode = BAD$1;
20973 break;
20974 }
20975 //Tracev((stderr, 'inflate: codes ok\n'));
20976 state.mode = LEN_;
20977 if (flush === Z_TREES) { break inf_leave; }
20978 /* falls through */
20979 case LEN_:
20980 state.mode = LEN;
20981 /* falls through */
20982 case LEN:
20983 if (have >= 6 && left >= 258) {
20984 //--- RESTORE() ---
20985 strm.next_out = put;
20986 strm.avail_out = left;
20987 strm.next_in = next;
20988 strm.avail_in = have;
20989 state.hold = hold;
20990 state.bits = bits;
20991 //---
20992 inflate_fast(strm, _out);
20993 //--- LOAD() ---
20994 put = strm.next_out;
20995 output = strm.output;
20996 left = strm.avail_out;
20997 next = strm.next_in;
20998 input = strm.input;
20999 have = strm.avail_in;
21000 hold = state.hold;
21001 bits = state.bits;
21002 //---
21003
21004 if (state.mode === TYPE$1) {
21005 state.back = -1;
21006 }
21007 break;
21008 }
21009 state.back = 0;
21010 for (;;) {
21011 here = state.lencode[hold & ((1 << state.lenbits) - 1)]; /*BITS(state.lenbits)*/
21012 here_bits = here >>> 24;
21013 here_op = (here >>> 16) & 0xff;
21014 here_val = here & 0xffff;
21015
21016 if (here_bits <= bits) { break; }
21017 //--- PULLBYTE() ---//
21018 if (have === 0) { break inf_leave; }
21019 have--;
21020 hold += input[next++] << bits;
21021 bits += 8;
21022 //---//
21023 }
21024 if (here_op && (here_op & 0xf0) === 0) {
21025 last_bits = here_bits;
21026 last_op = here_op;
21027 last_val = here_val;
21028 for (;;) {
21029 here = state.lencode[last_val +
21030 ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
21031 here_bits = here >>> 24;
21032 here_op = (here >>> 16) & 0xff;
21033 here_val = here & 0xffff;
21034
21035 if ((last_bits + here_bits) <= bits) { break; }
21036 //--- PULLBYTE() ---//
21037 if (have === 0) { break inf_leave; }
21038 have--;
21039 hold += input[next++] << bits;
21040 bits += 8;
21041 //---//
21042 }
21043 //--- DROPBITS(last.bits) ---//
21044 hold >>>= last_bits;
21045 bits -= last_bits;
21046 //---//
21047 state.back += last_bits;
21048 }
21049 //--- DROPBITS(here.bits) ---//
21050 hold >>>= here_bits;
21051 bits -= here_bits;
21052 //---//
21053 state.back += here_bits;
21054 state.length = here_val;
21055 if (here_op === 0) {
21056 //Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
21057 // "inflate: literal '%c'\n" :
21058 // "inflate: literal 0x%02x\n", here.val));
21059 state.mode = LIT;
21060 break;
21061 }
21062 if (here_op & 32) {
21063 //Tracevv((stderr, "inflate: end of block\n"));
21064 state.back = -1;
21065 state.mode = TYPE$1;
21066 break;
21067 }
21068 if (here_op & 64) {
21069 strm.msg = 'invalid literal/length code';
21070 state.mode = BAD$1;
21071 break;
21072 }
21073 state.extra = here_op & 15;
21074 state.mode = LENEXT;
21075 /* falls through */
21076 case LENEXT:
21077 if (state.extra) {
21078 //=== NEEDBITS(state.extra);
21079 n = state.extra;
21080 while (bits < n) {
21081 if (have === 0) { break inf_leave; }
21082 have--;
21083 hold += input[next++] << bits;
21084 bits += 8;
21085 }
21086 //===//
21087 state.length += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
21088 //--- DROPBITS(state.extra) ---//
21089 hold >>>= state.extra;
21090 bits -= state.extra;
21091 //---//
21092 state.back += state.extra;
21093 }
21094 //Tracevv((stderr, "inflate: length %u\n", state.length));
21095 state.was = state.length;
21096 state.mode = DIST;
21097 /* falls through */
21098 case DIST:
21099 for (;;) {
21100 here = state.distcode[hold & ((1 << state.distbits) - 1)];/*BITS(state.distbits)*/
21101 here_bits = here >>> 24;
21102 here_op = (here >>> 16) & 0xff;
21103 here_val = here & 0xffff;
21104
21105 if ((here_bits) <= bits) { break; }
21106 //--- PULLBYTE() ---//
21107 if (have === 0) { break inf_leave; }
21108 have--;
21109 hold += input[next++] << bits;
21110 bits += 8;
21111 //---//
21112 }
21113 if ((here_op & 0xf0) === 0) {
21114 last_bits = here_bits;
21115 last_op = here_op;
21116 last_val = here_val;
21117 for (;;) {
21118 here = state.distcode[last_val +
21119 ((hold & ((1 << (last_bits + last_op)) - 1))/*BITS(last.bits + last.op)*/ >> last_bits)];
21120 here_bits = here >>> 24;
21121 here_op = (here >>> 16) & 0xff;
21122 here_val = here & 0xffff;
21123
21124 if ((last_bits + here_bits) <= bits) { break; }
21125 //--- PULLBYTE() ---//
21126 if (have === 0) { break inf_leave; }
21127 have--;
21128 hold += input[next++] << bits;
21129 bits += 8;
21130 //---//
21131 }
21132 //--- DROPBITS(last.bits) ---//
21133 hold >>>= last_bits;
21134 bits -= last_bits;
21135 //---//
21136 state.back += last_bits;
21137 }
21138 //--- DROPBITS(here.bits) ---//
21139 hold >>>= here_bits;
21140 bits -= here_bits;
21141 //---//
21142 state.back += here_bits;
21143 if (here_op & 64) {
21144 strm.msg = 'invalid distance code';
21145 state.mode = BAD$1;
21146 break;
21147 }
21148 state.offset = here_val;
21149 state.extra = (here_op) & 15;
21150 state.mode = DISTEXT;
21151 /* falls through */
21152 case DISTEXT:
21153 if (state.extra) {
21154 //=== NEEDBITS(state.extra);
21155 n = state.extra;
21156 while (bits < n) {
21157 if (have === 0) { break inf_leave; }
21158 have--;
21159 hold += input[next++] << bits;
21160 bits += 8;
21161 }
21162 //===//
21163 state.offset += hold & ((1 << state.extra) - 1)/*BITS(state.extra)*/;
21164 //--- DROPBITS(state.extra) ---//
21165 hold >>>= state.extra;
21166 bits -= state.extra;
21167 //---//
21168 state.back += state.extra;
21169 }
21170//#ifdef INFLATE_STRICT
21171 if (state.offset > state.dmax) {
21172 strm.msg = 'invalid distance too far back';
21173 state.mode = BAD$1;
21174 break;
21175 }
21176//#endif
21177 //Tracevv((stderr, "inflate: distance %u\n", state.offset));
21178 state.mode = MATCH;
21179 /* falls through */
21180 case MATCH:
21181 if (left === 0) { break inf_leave; }
21182 copy = _out - left;
21183 if (state.offset > copy) { /* copy from window */
21184 copy = state.offset - copy;
21185 if (copy > state.whave) {
21186 if (state.sane) {
21187 strm.msg = 'invalid distance too far back';
21188 state.mode = BAD$1;
21189 break;
21190 }
21191// (!) This block is disabled in zlib defaults,
21192// don't enable it for binary compatibility
21193//#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
21194// Trace((stderr, "inflate.c too far\n"));
21195// copy -= state.whave;
21196// if (copy > state.length) { copy = state.length; }
21197// if (copy > left) { copy = left; }
21198// left -= copy;
21199// state.length -= copy;
21200// do {
21201// output[put++] = 0;
21202// } while (--copy);
21203// if (state.length === 0) { state.mode = LEN; }
21204// break;
21205//#endif
21206 }
21207 if (copy > state.wnext) {
21208 copy -= state.wnext;
21209 from = state.wsize - copy;
21210 }
21211 else {
21212 from = state.wnext - copy;
21213 }
21214 if (copy > state.length) { copy = state.length; }
21215 from_source = state.window;
21216 }
21217 else { /* copy from output */
21218 from_source = output;
21219 from = put - state.offset;
21220 copy = state.length;
21221 }
21222 if (copy > left) { copy = left; }
21223 left -= copy;
21224 state.length -= copy;
21225 do {
21226 output[put++] = from_source[from++];
21227 } while (--copy);
21228 if (state.length === 0) { state.mode = LEN; }
21229 break;
21230 case LIT:
21231 if (left === 0) { break inf_leave; }
21232 output[put++] = state.length;
21233 left--;
21234 state.mode = LEN;
21235 break;
21236 case CHECK:
21237 if (state.wrap) {
21238 //=== NEEDBITS(32);
21239 while (bits < 32) {
21240 if (have === 0) { break inf_leave; }
21241 have--;
21242 // Use '|' instead of '+' to make sure that result is signed
21243 hold |= input[next++] << bits;
21244 bits += 8;
21245 }
21246 //===//
21247 _out -= left;
21248 strm.total_out += _out;
21249 state.total += _out;
21250 if (_out) {
21251 strm.adler = state.check =
21252 /*UPDATE(state.check, put - _out, _out);*/
21253 (state.flags ? crc32(state.check, output, _out, put - _out) : adler32(state.check, output, _out, put - _out));
21254
21255 }
21256 _out = left;
21257 // NB: crc32 stored as signed 32-bit int, zswap32 returns signed too
21258 if ((state.flags ? hold : zswap32(hold)) !== state.check) {
21259 strm.msg = 'incorrect data check';
21260 state.mode = BAD$1;
21261 break;
21262 }
21263 //=== INITBITS();
21264 hold = 0;
21265 bits = 0;
21266 //===//
21267 //Tracev((stderr, "inflate: check matches trailer\n"));
21268 }
21269 state.mode = LENGTH;
21270 /* falls through */
21271 case LENGTH:
21272 if (state.wrap && state.flags) {
21273 //=== NEEDBITS(32);
21274 while (bits < 32) {
21275 if (have === 0) { break inf_leave; }
21276 have--;
21277 hold += input[next++] << bits;
21278 bits += 8;
21279 }
21280 //===//
21281 if (hold !== (state.total & 0xffffffff)) {
21282 strm.msg = 'incorrect length check';
21283 state.mode = BAD$1;
21284 break;
21285 }
21286 //=== INITBITS();
21287 hold = 0;
21288 bits = 0;
21289 //===//
21290 //Tracev((stderr, "inflate: length matches trailer\n"));
21291 }
21292 state.mode = DONE;
21293 /* falls through */
21294 case DONE:
21295 ret = Z_STREAM_END;
21296 break inf_leave;
21297 case BAD$1:
21298 ret = Z_DATA_ERROR;
21299 break inf_leave;
21300 // case MEM:
21301 // return Z_MEM_ERROR;
21302 case SYNC:
21303 /* falls through */
21304 default:
21305 return Z_STREAM_ERROR;
21306 }
21307 }
21308
21309 // inf_leave <- here is real place for "goto inf_leave", emulated via "break inf_leave"
21310
21311 /*
21312 Return from inflate(), updating the total counts and the check value.
21313 If there was no progress during the inflate() call, return a buffer
21314 error. Call updatewindow() to create and/or update the window state.
21315 Note: a memory error from inflate() is non-recoverable.
21316 */
21317
21318 //--- RESTORE() ---
21319 strm.next_out = put;
21320 strm.avail_out = left;
21321 strm.next_in = next;
21322 strm.avail_in = have;
21323 state.hold = hold;
21324 state.bits = bits;
21325 //---
21326
21327 if (state.wsize || (_out !== strm.avail_out && state.mode < BAD$1 &&
21328 (state.mode < CHECK || flush !== Z_FINISH))) {
21329 if (updatewindow(strm, strm.output, strm.next_out, _out - strm.avail_out)) ;
21330 }
21331 _in -= strm.avail_in;
21332 _out -= strm.avail_out;
21333 strm.total_in += _in;
21334 strm.total_out += _out;
21335 state.total += _out;
21336 if (state.wrap && _out) {
21337 strm.adler = state.check = /*UPDATE(state.check, strm.next_out - _out, _out);*/
21338 (state.flags ? crc32(state.check, output, _out, strm.next_out - _out) : adler32(state.check, output, _out, strm.next_out - _out));
21339 }
21340 strm.data_type = state.bits + (state.last ? 64 : 0) +
21341 (state.mode === TYPE$1 ? 128 : 0) +
21342 (state.mode === LEN_ || state.mode === COPY_ ? 256 : 0);
21343 if (((_in === 0 && _out === 0) || flush === Z_FINISH) && ret === Z_OK) {
21344 ret = Z_BUF_ERROR;
21345 }
21346 return ret;
21347}
21348
21349function inflateEnd(strm) {
21350
21351 if (!strm || !strm.state /*|| strm->zfree == (free_func)0*/) {
21352 return Z_STREAM_ERROR;
21353 }
21354
21355 const state = strm.state;
21356 if (state.window) {
21357 state.window = null;
21358 }
21359 strm.state = null;
21360 return Z_OK;
21361}
21362
21363function inflateGetHeader(strm, head) {
21364 let state;
21365
21366 /* check state */
21367 if (!strm || !strm.state) { return Z_STREAM_ERROR; }
21368 state = strm.state;
21369 if ((state.wrap & 2) === 0) { return Z_STREAM_ERROR; }
21370
21371 /* save header structure */
21372 state.head = head;
21373 head.done = false;
21374 return Z_OK;
21375}
21376
21377function inflateSetDictionary(strm, dictionary) {
21378 const dictLength = dictionary.length;
21379
21380 let state;
21381 let dictid;
21382
21383 /* check state */
21384 if (!strm /* == Z_NULL */ || !strm.state /* == Z_NULL */) { return Z_STREAM_ERROR; }
21385 state = strm.state;
21386
21387 if (state.wrap !== 0 && state.mode !== DICT) {
21388 return Z_STREAM_ERROR;
21389 }
21390
21391 /* check for correct dictionary identifier */
21392 if (state.mode === DICT) {
21393 dictid = 1; /* adler32(0, null, 0)*/
21394 /* dictid = adler32(dictid, dictionary, dictLength); */
21395 dictid = adler32(dictid, dictionary, dictLength, 0);
21396 if (dictid !== state.check) {
21397 return Z_DATA_ERROR;
21398 }
21399 }
21400 /* copy dictionary to window using updatewindow(), which will amend the
21401 existing dictionary if appropriate */
21402 updatewindow(strm, dictionary, dictLength, dictLength);
21403 // if (ret) {
21404 // state.mode = MEM;
21405 // return Z_MEM_ERROR;
21406 // }
21407 state.havedict = 1;
21408 // Tracev((stderr, "inflate: dictionary set\n"));
21409 return Z_OK;
21410}
21411
21412/* Not implemented
21413exports.inflateCopy = inflateCopy;
21414exports.inflateGetDictionary = inflateGetDictionary;
21415exports.inflateMark = inflateMark;
21416exports.inflatePrime = inflatePrime;
21417exports.inflateSync = inflateSync;
21418exports.inflateSyncPoint = inflateSyncPoint;
21419exports.inflateUndermine = inflateUndermine;
21420*/
21421
21422// (C) 1995-2013 Jean-loup Gailly and Mark Adler
21423// (C) 2014-2017 Vitaly Puzrin and Andrey Tupitsin
21424//
21425// This software is provided 'as-is', without any express or implied
21426// warranty. In no event will the authors be held liable for any damages
21427// arising from the use of this software.
21428//
21429// Permission is granted to anyone to use this software for any purpose,
21430// including commercial applications, and to alter it and redistribute it
21431// freely, subject to the following restrictions:
21432//
21433// 1. The origin of this software must not be misrepresented; you must not
21434// claim that you wrote the original software. If you use this software
21435// in a product, an acknowledgment in the product documentation would be
21436// appreciated but is not required.
21437// 2. Altered source versions must be plainly marked as such, and must not be
21438// misrepresented as being the original software.
21439// 3. This notice may not be removed or altered from any source distribution.
21440
21441class GZheader {
21442 constructor() {
21443 /* true if compressed data believed to be text */
21444 this.text = 0;
21445 /* modification time */
21446 this.time = 0;
21447 /* extra flags (not used when writing a gzip file) */
21448 this.xflags = 0;
21449 /* operating system */
21450 this.os = 0;
21451 /* pointer to extra field or Z_NULL if none */
21452 this.extra = null;
21453 /* extra field length (valid if extra != Z_NULL) */
21454 this.extra_len = 0; // Actually, we don't need it in JS,
21455 // but leave for few code modifications
21456
21457 //
21458 // Setup limits is not necessary because in js we should not preallocate memory
21459 // for inflate use constant limit in 65536 bytes
21460 //
21461
21462 /* space at extra (only when reading header) */
21463 // this.extra_max = 0;
21464 /* pointer to zero-terminated file name or Z_NULL */
21465 this.name = '';
21466 /* space at name (only when reading header) */
21467 // this.name_max = 0;
21468 /* pointer to zero-terminated comment or Z_NULL */
21469 this.comment = '';
21470 /* space at comment (only when reading header) */
21471 // this.comm_max = 0;
21472 /* true if there was or will be a header crc */
21473 this.hcrc = 0;
21474 /* true when done reading gzip header (not used when writing a gzip file) */
21475 this.done = false;
21476 }
21477}
21478
21479/**
21480 * class Inflate
21481 *
21482 * Generic JS-style wrapper for zlib calls. If you don't need
21483 * streaming behaviour - use more simple functions: [[inflate]]
21484 * and [[inflateRaw]].
21485 **/
21486
21487/* internal
21488 * inflate.chunks -> Array
21489 *
21490 * Chunks of output data, if [[Inflate#onData]] not overridden.
21491 **/
21492
21493/**
21494 * Inflate.result -> Uint8Array|Array|String
21495 *
21496 * Uncompressed result, generated by default [[Inflate#onData]]
21497 * and [[Inflate#onEnd]] handlers. Filled after you push last chunk
21498 * (call [[Inflate#push]] with `Z_FINISH` / `true` param) or if you
21499 * push a chunk with explicit flush (call [[Inflate#push]] with
21500 * `Z_SYNC_FLUSH` param).
21501 **/
21502
21503/**
21504 * Inflate.err -> Number
21505 *
21506 * Error code after inflate finished. 0 (Z_OK) on success.
21507 * Should be checked if broken data possible.
21508 **/
21509
21510/**
21511 * Inflate.msg -> String
21512 *
21513 * Error message, if [[Inflate.err]] != 0
21514 **/
21515
21516
21517/**
21518 * new Inflate(options)
21519 * - options (Object): zlib inflate options.
21520 *
21521 * Creates new inflator instance with specified params. Throws exception
21522 * on bad params. Supported options:
21523 *
21524 * - `windowBits`
21525 * - `dictionary`
21526 *
21527 * [http://zlib.net/manual.html#Advanced](http://zlib.net/manual.html#Advanced)
21528 * for more information on these.
21529 *
21530 * Additional options, for internal needs:
21531 *
21532 * - `chunkSize` - size of generated data chunks (16K by default)
21533 * - `raw` (Boolean) - do raw inflate
21534 * - `to` (String) - if equal to 'string', then result will be converted
21535 * from utf8 to utf16 (javascript) string. When string output requested,
21536 * chunk length can differ from `chunkSize`, depending on content.
21537 *
21538 * By default, when no options set, autodetect deflate/gzip data format via
21539 * wrapper header.
21540 *
21541 * ##### Example:
21542 *
21543 * ```javascript
21544 * var pako = require('pako')
21545 * , chunk1 = Uint8Array([1,2,3,4,5,6,7,8,9])
21546 * , chunk2 = Uint8Array([10,11,12,13,14,15,16,17,18,19]);
21547 *
21548 * var inflate = new pako.Inflate({ level: 3});
21549 *
21550 * inflate.push(chunk1, false);
21551 * inflate.push(chunk2, true); // true -> last chunk
21552 *
21553 * if (inflate.err) { throw new Error(inflate.err); }
21554 *
21555 * console.log(inflate.result);
21556 * ```
21557 **/
21558class Inflate {
21559 constructor(options) {
21560 this.options = {
21561 chunkSize: 16384,
21562 windowBits: 0,
21563 ...(options || {})
21564 };
21565
21566 const opt = this.options;
21567
21568 // Force window size for `raw` data, if not set directly,
21569 // because we have no header for autodetect.
21570 if (opt.raw && (opt.windowBits >= 0) && (opt.windowBits < 16)) {
21571 opt.windowBits = -opt.windowBits;
21572 if (opt.windowBits === 0) { opt.windowBits = -15; }
21573 }
21574
21575 // If `windowBits` not defined (and mode not raw) - set autodetect flag for gzip/deflate
21576 if ((opt.windowBits >= 0) && (opt.windowBits < 16) &&
21577 !(options && options.windowBits)) {
21578 opt.windowBits += 32;
21579 }
21580
21581 // Gzip header has no info about windows size, we can do autodetect only
21582 // for deflate. So, if window size not set, force it to max when gzip possible
21583 if ((opt.windowBits > 15) && (opt.windowBits < 48)) {
21584 // bit 3 (16) -> gzipped data
21585 // bit 4 (32) -> autodetect gzip/deflate
21586 if ((opt.windowBits & 15) === 0) {
21587 opt.windowBits |= 15;
21588 }
21589 }
21590
21591 this.err = 0; // error code, if happens (0 = Z_OK)
21592 this.msg = ''; // error message
21593 this.ended = false; // used to avoid multiple onEnd() calls
21594 this.chunks = []; // chunks of compressed data
21595
21596 this.strm = new ZStream();
21597 this.strm.avail_out = 0;
21598
21599 let status = inflateInit2(
21600 this.strm,
21601 opt.windowBits
21602 );
21603
21604 if (status !== Z_OK) {
21605 throw new Error(msg[status]);
21606 }
21607
21608 this.header = new GZheader();
21609
21610 inflateGetHeader(this.strm, this.header);
21611
21612 // Setup dictionary
21613 if (opt.dictionary) {
21614 // Convert data if needed
21615 if (typeof opt.dictionary === 'string') {
21616 opt.dictionary = string2buf(opt.dictionary);
21617 } else if (opt.dictionary instanceof ArrayBuffer) {
21618 opt.dictionary = new Uint8Array(opt.dictionary);
21619 }
21620 if (opt.raw) { //In raw mode we need to set the dictionary early
21621 status = inflateSetDictionary(this.strm, opt.dictionary);
21622 if (status !== Z_OK) {
21623 throw new Error(msg[status]);
21624 }
21625 }
21626 }
21627 }
21628 /**
21629 * Inflate#push(data[, mode]) -> Boolean
21630 * - data (Uint8Array|Array|ArrayBuffer|String): input data
21631 * - mode (Number|Boolean): 0..6 for corresponding Z_NO_FLUSH..Z_TREE modes.
21632 * See constants. Skipped or `false` means Z_NO_FLUSH, `true` means Z_FINISH.
21633 *
21634 * Sends input data to inflate pipe, generating [[Inflate#onData]] calls with
21635 * new output chunks. Returns `true` on success. The last data block must have
21636 * mode Z_FINISH (or `true`). That will flush internal pending buffers and call
21637 * [[Inflate#onEnd]]. For interim explicit flushes (without ending the stream) you
21638 * can use mode Z_SYNC_FLUSH, keeping the decompression context.
21639 *
21640 * On fail call [[Inflate#onEnd]] with error code and return false.
21641 *
21642 * We strongly recommend to use `Uint8Array` on input for best speed (output
21643 * format is detected automatically). Also, don't skip last param and always
21644 * use the same type in your code (boolean or number). That will improve JS speed.
21645 *
21646 * For regular `Array`-s make sure all elements are [0..255].
21647 *
21648 * ##### Example
21649 *
21650 * ```javascript
21651 * push(chunk, false); // push one of data chunks
21652 * ...
21653 * push(chunk, true); // push last chunk
21654 * ```
21655 **/
21656 push(data, mode) {
21657 const { strm, options: { chunkSize, dictionary } } = this;
21658 let status, _mode;
21659
21660 // Flag to properly process Z_BUF_ERROR on testing inflate call
21661 // when we check that all output data was flushed.
21662 let allowBufError = false;
21663
21664 if (this.ended) { return false; }
21665 _mode = (mode === ~~mode) ? mode : ((mode === true) ? Z_FINISH : Z_NO_FLUSH);
21666
21667 // Convert data if needed
21668 if (typeof data === 'string') {
21669 // Only binary strings can be decompressed on practice
21670 strm.input = binstring2buf(data);
21671 } else if (data instanceof ArrayBuffer) {
21672 strm.input = new Uint8Array(data);
21673 } else {
21674 strm.input = data;
21675 }
21676
21677 strm.next_in = 0;
21678 strm.avail_in = strm.input.length;
21679
21680 do {
21681 if (strm.avail_out === 0) {
21682 strm.output = new Buf8(chunkSize);
21683 strm.next_out = 0;
21684 strm.avail_out = chunkSize;
21685 }
21686
21687 status = inflate(strm, Z_NO_FLUSH); /* no bad return value */
21688
21689 if (status === Z_NEED_DICT && dictionary) {
21690 status = inflateSetDictionary(this.strm, dictionary);
21691 }
21692
21693 if (status === Z_BUF_ERROR && allowBufError === true) {
21694 status = Z_OK;
21695 allowBufError = false;
21696 }
21697
21698 if (status !== Z_STREAM_END && status !== Z_OK) {
21699 this.onEnd(status);
21700 this.ended = true;
21701 return false;
21702 }
21703
21704 if (strm.next_out) {
21705 if (strm.avail_out === 0 || status === Z_STREAM_END || (strm.avail_in === 0 && (_mode === Z_FINISH || _mode === Z_SYNC_FLUSH))) {
21706 this.onData(shrinkBuf(strm.output, strm.next_out));
21707 }
21708 }
21709
21710 // When no more input data, we should check that internal inflate buffers
21711 // are flushed. The only way to do it when avail_out = 0 - run one more
21712 // inflate pass. But if output data not exists, inflate return Z_BUF_ERROR.
21713 // Here we set flag to process this error properly.
21714 //
21715 // NOTE. Deflate does not return error in this case and does not needs such
21716 // logic.
21717 if (strm.avail_in === 0 && strm.avail_out === 0) {
21718 allowBufError = true;
21719 }
21720
21721 } while ((strm.avail_in > 0 || strm.avail_out === 0) && status !== Z_STREAM_END);
21722
21723 if (status === Z_STREAM_END) {
21724 _mode = Z_FINISH;
21725 }
21726
21727 // Finalize on the last chunk.
21728 if (_mode === Z_FINISH) {
21729 status = inflateEnd(this.strm);
21730 this.onEnd(status);
21731 this.ended = true;
21732 return status === Z_OK;
21733 }
21734
21735 // callback interim results if Z_SYNC_FLUSH.
21736 if (_mode === Z_SYNC_FLUSH) {
21737 this.onEnd(Z_OK);
21738 strm.avail_out = 0;
21739 return true;
21740 }
21741
21742 return true;
21743 };
21744
21745 /**
21746 * Inflate#onData(chunk) -> Void
21747 * - chunk (Uint8Array|Array|String): output data. Type of array depends
21748 * on js engine support. When string output requested, each chunk
21749 * will be string.
21750 *
21751 * By default, stores data blocks in `chunks[]` property and glue
21752 * those in `onEnd`. Override this handler, if you need another behaviour.
21753 **/
21754 onData(chunk) {
21755 this.chunks.push(chunk);
21756 };
21757
21758
21759
21760 /**
21761 * Inflate#onEnd(status) -> Void
21762 * - status (Number): inflate status. 0 (Z_OK) on success,
21763 * other if not.
21764 *
21765 * Called either after you tell inflate that the input stream is
21766 * complete (Z_FINISH) or should be flushed (Z_SYNC_FLUSH)
21767 * or if an error happened. By default - join collected chunks,
21768 * free memory and fill `results` / `err` properties.
21769 **/
21770 onEnd(status) {
21771 // On success - join
21772 if (status === Z_OK) {
21773 this.result = flattenChunks(this.chunks);
21774 }
21775 this.chunks = [];
21776 this.err = status;
21777 this.msg = this.strm.msg;
21778 };
21779}
21780
21781/*
21782node-bzip - a pure-javascript Node.JS module for decoding bzip2 data
21783
21784Copyright (C) 2012 Eli Skeggs
21785
21786This library is free software; you can redistribute it and/or
21787modify it under the terms of the GNU Lesser General Public
21788License as published by the Free Software Foundation; either
21789version 2.1 of the License, or (at your option) any later version.
21790
21791This library is distributed in the hope that it will be useful,
21792but WITHOUT ANY WARRANTY; without even the implied warranty of
21793MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21794Lesser General Public License for more details.
21795
21796You should have received a copy of the GNU Lesser General Public
21797License along with this library; if not, see
21798http://www.gnu.org/licenses/lgpl-2.1.html
21799
21800Adapted from bzip2.js, copyright 2011 antimatter15 (antimatter15@gmail.com).
21801
21802Based on micro-bunzip by Rob Landley (rob@landley.net).
21803
21804Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
21805which also acknowledges contributions by Mike Burrows, David Wheeler,
21806Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
21807Robert Sedgewick, and Jon L. Bentley.
21808*/
21809
21810var BITMASK = [0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF];
21811
21812// offset in bytes
21813var BitReader = function(stream) {
21814 this.stream = stream;
21815 this.bitOffset = 0;
21816 this.curByte = 0;
21817 this.hasByte = false;
21818};
21819
21820BitReader.prototype._ensureByte = function() {
21821 if (!this.hasByte) {
21822 this.curByte = this.stream.readByte();
21823 this.hasByte = true;
21824 }
21825};
21826
21827// reads bits from the buffer
21828BitReader.prototype.read = function(bits) {
21829 var result = 0;
21830 while (bits > 0) {
21831 this._ensureByte();
21832 var remaining = 8 - this.bitOffset;
21833 // if we're in a byte
21834 if (bits >= remaining) {
21835 result <<= remaining;
21836 result |= BITMASK[remaining] & this.curByte;
21837 this.hasByte = false;
21838 this.bitOffset = 0;
21839 bits -= remaining;
21840 } else {
21841 result <<= bits;
21842 var shift = remaining - bits;
21843 result |= (this.curByte & (BITMASK[bits] << shift)) >> shift;
21844 this.bitOffset += bits;
21845 bits = 0;
21846 }
21847 }
21848 return result;
21849};
21850
21851// seek to an arbitrary point in the buffer (expressed in bits)
21852BitReader.prototype.seek = function(pos) {
21853 var n_bit = pos % 8;
21854 var n_byte = (pos - n_bit) / 8;
21855 this.bitOffset = n_bit;
21856 this.stream.seek(n_byte);
21857 this.hasByte = false;
21858};
21859
21860// reads 6 bytes worth of data using the read method
21861BitReader.prototype.pi = function() {
21862 var buf = new Uint8Array(6), i;
21863 for (i = 0; i < buf.length; i++) {
21864 buf[i] = this.read(8);
21865 }
21866 return bufToHex(buf);
21867};
21868
21869function bufToHex(buf) {
21870 return Array.prototype.map.call(buf, x => ('00' + x.toString(16)).slice(-2)).join('');
21871}
21872
21873var bitreader = BitReader;
21874
21875/* very simple input/output stream interface */
21876var Stream = function() {
21877};
21878
21879// input streams //////////////
21880/** Returns the next byte, or -1 for EOF. */
21881Stream.prototype.readByte = function() {
21882 throw new Error("abstract method readByte() not implemented");
21883};
21884/** Attempts to fill the buffer; returns number of bytes read, or
21885 * -1 for EOF. */
21886Stream.prototype.read = function(buffer, bufOffset, length) {
21887 var bytesRead = 0;
21888 while (bytesRead < length) {
21889 var c = this.readByte();
21890 if (c < 0) { // EOF
21891 return (bytesRead===0) ? -1 : bytesRead;
21892 }
21893 buffer[bufOffset++] = c;
21894 bytesRead++;
21895 }
21896 return bytesRead;
21897};
21898Stream.prototype.seek = function(new_pos) {
21899 throw new Error("abstract method seek() not implemented");
21900};
21901
21902// output streams ///////////
21903Stream.prototype.writeByte = function(_byte) {
21904 throw new Error("abstract method readByte() not implemented");
21905};
21906Stream.prototype.write = function(buffer, bufOffset, length) {
21907 var i;
21908 for (i=0; i<length; i++) {
21909 this.writeByte(buffer[bufOffset++]);
21910 }
21911 return length;
21912};
21913Stream.prototype.flush = function() {
21914};
21915
21916var stream = Stream;
21917
21918/* CRC32, used in Bzip2 implementation.
21919 * This is a port of CRC32.java from the jbzip2 implementation at
21920 * https://code.google.com/p/jbzip2
21921 * which is:
21922 * Copyright (c) 2011 Matthew Francis
21923 *
21924 * Permission is hereby granted, free of charge, to any person
21925 * obtaining a copy of this software and associated documentation
21926 * files (the "Software"), to deal in the Software without
21927 * restriction, including without limitation the rights to use,
21928 * copy, modify, merge, publish, distribute, sublicense, and/or sell
21929 * copies of the Software, and to permit persons to whom the
21930 * Software is furnished to do so, subject to the following
21931 * conditions:
21932 *
21933 * The above copyright notice and this permission notice shall be
21934 * included in all copies or substantial portions of the Software.
21935 *
21936 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21937 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21938 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21939 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21940 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21941 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21942 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21943 * OTHER DEALINGS IN THE SOFTWARE.
21944 * This JavaScript implementation is:
21945 * Copyright (c) 2013 C. Scott Ananian
21946 * with the same licensing terms as Matthew Francis' original implementation.
21947 */
21948var crc32$1 = (function() {
21949
21950 /**
21951 * A static CRC lookup table
21952 */
21953 var crc32Lookup = new Uint32Array([
21954 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005,
21955 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
21956 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75,
21957 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd,
21958 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5,
21959 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d,
21960 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
21961 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d,
21962 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072,
21963 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca,
21964 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02,
21965 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
21966 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692,
21967 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a,
21968 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2,
21969 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a,
21970 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
21971 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53,
21972 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b,
21973 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623,
21974 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b,
21975 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
21976 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b,
21977 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3,
21978 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c,
21979 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24,
21980 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
21981 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654,
21982 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c,
21983 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4,
21984 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c,
21985 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
21986 ]);
21987
21988 var CRC32 = function() {
21989 /**
21990 * The current CRC
21991 */
21992 var crc = 0xffffffff;
21993
21994 /**
21995 * @return The current CRC
21996 */
21997 this.getCRC = function() {
21998 return (~crc) >>> 0; // return an unsigned value
21999 };
22000
22001 /**
22002 * Update the CRC with a single byte
22003 * @param value The value to update the CRC with
22004 */
22005 this.updateCRC = function(value) {
22006 crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
22007 };
22008
22009 /**
22010 * Update the CRC with a sequence of identical bytes
22011 * @param value The value to update the CRC with
22012 * @param count The number of bytes
22013 */
22014 this.updateCRCRun = function(value, count) {
22015 while (count-- > 0) {
22016 crc = (crc << 8) ^ crc32Lookup[((crc >>> 24) ^ value) & 0xff];
22017 }
22018 };
22019 };
22020 return CRC32;
22021})();
22022
22023/*
22024seek-bzip - a pure-javascript module for seeking within bzip2 data
22025
22026Copyright (C) 2013 C. Scott Ananian
22027Copyright (C) 2012 Eli Skeggs
22028Copyright (C) 2011 Kevin Kwok
22029
22030This library is free software; you can redistribute it and/or
22031modify it under the terms of the GNU Lesser General Public
22032License as published by the Free Software Foundation; either
22033version 2.1 of the License, or (at your option) any later version.
22034
22035This library is distributed in the hope that it will be useful,
22036but WITHOUT ANY WARRANTY; without even the implied warranty of
22037MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22038Lesser General Public License for more details.
22039
22040You should have received a copy of the GNU Lesser General Public
22041License along with this library; if not, see
22042http://www.gnu.org/licenses/lgpl-2.1.html
22043
22044Adapted from node-bzip, copyright 2012 Eli Skeggs.
22045Adapted from bzip2.js, copyright 2011 Kevin Kwok (antimatter15@gmail.com).
22046
22047Based on micro-bunzip by Rob Landley (rob@landley.net).
22048
22049Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
22050which also acknowledges contributions by Mike Burrows, David Wheeler,
22051Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
22052Robert Sedgewick, and Jon L. Bentley.
22053*/
22054
22055
22056
22057
22058
22059var MAX_HUFCODE_BITS = 20;
22060var MAX_SYMBOLS = 258;
22061var SYMBOL_RUNA = 0;
22062var SYMBOL_RUNB = 1;
22063var MIN_GROUPS = 2;
22064var MAX_GROUPS = 6;
22065var GROUP_SIZE = 50;
22066
22067var WHOLEPI = "314159265359";
22068var SQRTPI = "177245385090";
22069
22070var mtf = function(array, index) {
22071 var src = array[index], i;
22072 for (i = index; i > 0; i--) {
22073 array[i] = array[i-1];
22074 }
22075 array[0] = src;
22076 return src;
22077};
22078
22079var Err = {
22080 OK: 0,
22081 LAST_BLOCK: -1,
22082 NOT_BZIP_DATA: -2,
22083 UNEXPECTED_INPUT_EOF: -3,
22084 UNEXPECTED_OUTPUT_EOF: -4,
22085 DATA_ERROR: -5,
22086 OUT_OF_MEMORY: -6,
22087 OBSOLETE_INPUT: -7,
22088 END_OF_BLOCK: -8
22089};
22090var ErrorMessages = {};
22091ErrorMessages[Err.LAST_BLOCK] = "Bad file checksum";
22092ErrorMessages[Err.NOT_BZIP_DATA] = "Not bzip data";
22093ErrorMessages[Err.UNEXPECTED_INPUT_EOF] = "Unexpected input EOF";
22094ErrorMessages[Err.UNEXPECTED_OUTPUT_EOF] = "Unexpected output EOF";
22095ErrorMessages[Err.DATA_ERROR] = "Data error";
22096ErrorMessages[Err.OUT_OF_MEMORY] = "Out of memory";
22097ErrorMessages[Err.OBSOLETE_INPUT] = "Obsolete (pre 0.9.5) bzip format not supported.";
22098
22099var _throw = function(status, optDetail) {
22100 var msg = ErrorMessages[status] || 'unknown error';
22101 if (optDetail) { msg += ': '+optDetail; }
22102 var e = new TypeError(msg);
22103 e.errorCode = status;
22104 throw e;
22105};
22106
22107var Bunzip = function(inputStream, outputStream) {
22108 this.writePos = this.writeCurrent = this.writeCount = 0;
22109
22110 this._start_bunzip(inputStream, outputStream);
22111};
22112Bunzip.prototype._init_block = function() {
22113 var moreBlocks = this._get_next_block();
22114 if ( !moreBlocks ) {
22115 this.writeCount = -1;
22116 return false; /* no more blocks */
22117 }
22118 this.blockCRC = new crc32$1();
22119 return true;
22120};
22121/* XXX micro-bunzip uses (inputStream, inputBuffer, len) as arguments */
22122Bunzip.prototype._start_bunzip = function(inputStream, outputStream) {
22123 /* Ensure that file starts with "BZh['1'-'9']." */
22124 var buf = new Uint8Array(4);
22125 if (inputStream.read(buf, 0, 4) !== 4 ||
22126 String.fromCharCode(buf[0], buf[1], buf[2]) !== 'BZh')
22127 _throw(Err.NOT_BZIP_DATA, 'bad magic');
22128
22129 var level = buf[3] - 0x30;
22130 if (level < 1 || level > 9)
22131 _throw(Err.NOT_BZIP_DATA, 'level out of range');
22132
22133 this.reader = new bitreader(inputStream);
22134
22135 /* Fourth byte (ascii '1'-'9'), indicates block size in units of 100k of
22136 uncompressed data. Allocate intermediate buffer for block. */
22137 this.dbufSize = 100000 * level;
22138 this.nextoutput = 0;
22139 this.outputStream = outputStream;
22140 this.streamCRC = 0;
22141};
22142Bunzip.prototype._get_next_block = function() {
22143 var i, j, k;
22144 var reader = this.reader;
22145 // this is get_next_block() function from micro-bunzip:
22146 /* Read in header signature and CRC, then validate signature.
22147 (last block signature means CRC is for whole file, return now) */
22148 var h = reader.pi();
22149 if (h === SQRTPI) { // last block
22150 return false; /* no more blocks */
22151 }
22152 if (h !== WHOLEPI)
22153 _throw(Err.NOT_BZIP_DATA);
22154 this.targetBlockCRC = reader.read(32) >>> 0; // (convert to unsigned)
22155 this.streamCRC = (this.targetBlockCRC ^
22156 ((this.streamCRC << 1) | (this.streamCRC>>>31))) >>> 0;
22157 /* We can add support for blockRandomised if anybody complains. There was
22158 some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
22159 it didn't actually work. */
22160 if (reader.read(1))
22161 _throw(Err.OBSOLETE_INPUT);
22162 var origPointer = reader.read(24);
22163 if (origPointer > this.dbufSize)
22164 _throw(Err.DATA_ERROR, 'initial position out of bounds');
22165 /* mapping table: if some byte values are never used (encoding things
22166 like ascii text), the compression code removes the gaps to have fewer
22167 symbols to deal with, and writes a sparse bitfield indicating which
22168 values were present. We make a translation table to convert the symbols
22169 back to the corresponding bytes. */
22170 var t = reader.read(16);
22171 var symToByte = new Uint8Array(256), symTotal = 0;
22172 for (i = 0; i < 16; i++) {
22173 if (t & (1 << (0xF - i))) {
22174 var o = i * 16;
22175 k = reader.read(16);
22176 for (j = 0; j < 16; j++)
22177 if (k & (1 << (0xF - j)))
22178 symToByte[symTotal++] = o + j;
22179 }
22180 }
22181
22182 /* How many different huffman coding groups does this block use? */
22183 var groupCount = reader.read(3);
22184 if (groupCount < MIN_GROUPS || groupCount > MAX_GROUPS)
22185 _throw(Err.DATA_ERROR);
22186 /* nSelectors: Every GROUP_SIZE many symbols we select a new huffman coding
22187 group. Read in the group selector list, which is stored as MTF encoded
22188 bit runs. (MTF=Move To Front, as each value is used it's moved to the
22189 start of the list.) */
22190 var nSelectors = reader.read(15);
22191 if (nSelectors === 0)
22192 _throw(Err.DATA_ERROR);
22193
22194 var mtfSymbol = new Uint8Array(256);
22195 for (i = 0; i < groupCount; i++)
22196 mtfSymbol[i] = i;
22197
22198 var selectors = new Uint8Array(nSelectors); // was 32768...
22199
22200 for (i = 0; i < nSelectors; i++) {
22201 /* Get next value */
22202 for (j = 0; reader.read(1); j++)
22203 if (j >= groupCount) _throw(Err.DATA_ERROR);
22204 /* Decode MTF to get the next selector */
22205 selectors[i] = mtf(mtfSymbol, j);
22206 }
22207
22208 /* Read the huffman coding tables for each group, which code for symTotal
22209 literal symbols, plus two run symbols (RUNA, RUNB) */
22210 var symCount = symTotal + 2;
22211 var groups = [], hufGroup;
22212 for (j = 0; j < groupCount; j++) {
22213 var length = new Uint8Array(symCount), temp = new Uint16Array(MAX_HUFCODE_BITS + 1);
22214 /* Read huffman code lengths for each symbol. They're stored in
22215 a way similar to mtf; record a starting value for the first symbol,
22216 and an offset from the previous value for everys symbol after that. */
22217 t = reader.read(5); // lengths
22218 for (i = 0; i < symCount; i++) {
22219 for (;;) {
22220 if (t < 1 || t > MAX_HUFCODE_BITS) _throw(Err.DATA_ERROR);
22221 /* If first bit is 0, stop. Else second bit indicates whether
22222 to increment or decrement the value. */
22223 if(!reader.read(1))
22224 break;
22225 if(!reader.read(1))
22226 t++;
22227 else
22228 t--;
22229 }
22230 length[i] = t;
22231 }
22232
22233 /* Find largest and smallest lengths in this group */
22234 var minLen, maxLen;
22235 minLen = maxLen = length[0];
22236 for (i = 1; i < symCount; i++) {
22237 if (length[i] > maxLen)
22238 maxLen = length[i];
22239 else if (length[i] < minLen)
22240 minLen = length[i];
22241 }
22242
22243 /* Calculate permute[], base[], and limit[] tables from length[].
22244 *
22245 * permute[] is the lookup table for converting huffman coded symbols
22246 * into decoded symbols. base[] is the amount to subtract from the
22247 * value of a huffman symbol of a given length when using permute[].
22248 *
22249 * limit[] indicates the largest numerical value a symbol with a given
22250 * number of bits can have. This is how the huffman codes can vary in
22251 * length: each code with a value>limit[length] needs another bit.
22252 */
22253 hufGroup = {};
22254 groups.push(hufGroup);
22255 hufGroup.permute = new Uint16Array(MAX_SYMBOLS);
22256 hufGroup.limit = new Uint32Array(MAX_HUFCODE_BITS + 2);
22257 hufGroup.base = new Uint32Array(MAX_HUFCODE_BITS + 1);
22258 hufGroup.minLen = minLen;
22259 hufGroup.maxLen = maxLen;
22260 /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */
22261 var pp = 0;
22262 for (i = minLen; i <= maxLen; i++) {
22263 temp[i] = hufGroup.limit[i] = 0;
22264 for (t = 0; t < symCount; t++)
22265 if (length[t] === i)
22266 hufGroup.permute[pp++] = t;
22267 }
22268 /* Count symbols coded for at each bit length */
22269 for (i = 0; i < symCount; i++)
22270 temp[length[i]]++;
22271 /* Calculate limit[] (the largest symbol-coding value at each bit
22272 * length, which is (previous limit<<1)+symbols at this level), and
22273 * base[] (number of symbols to ignore at each bit length, which is
22274 * limit minus the cumulative count of symbols coded for already). */
22275 pp = t = 0;
22276 for (i = minLen; i < maxLen; i++) {
22277 pp += temp[i];
22278 /* We read the largest possible symbol size and then unget bits
22279 after determining how many we need, and those extra bits could
22280 be set to anything. (They're noise from future symbols.) At
22281 each level we're really only interested in the first few bits,
22282 so here we set all the trailing to-be-ignored bits to 1 so they
22283 don't affect the value>limit[length] comparison. */
22284 hufGroup.limit[i] = pp - 1;
22285 pp <<= 1;
22286 t += temp[i];
22287 hufGroup.base[i + 1] = pp - t;
22288 }
22289 hufGroup.limit[maxLen + 1] = Number.MAX_VALUE; /* Sentinal value for reading next sym. */
22290 hufGroup.limit[maxLen] = pp + temp[maxLen] - 1;
22291 hufGroup.base[minLen] = 0;
22292 }
22293 /* We've finished reading and digesting the block header. Now read this
22294 block's huffman coded symbols from the file and undo the huffman coding
22295 and run length encoding, saving the result into dbuf[dbufCount++]=uc */
22296
22297 /* Initialize symbol occurrence counters and symbol Move To Front table */
22298 var byteCount = new Uint32Array(256);
22299 for (i = 0; i < 256; i++)
22300 mtfSymbol[i] = i;
22301 /* Loop through compressed symbols. */
22302 var runPos = 0, dbufCount = 0, selector = 0, uc;
22303 var dbuf = this.dbuf = new Uint32Array(this.dbufSize);
22304 symCount = 0;
22305 for (;;) {
22306 /* Determine which huffman coding group to use. */
22307 if (!(symCount--)) {
22308 symCount = GROUP_SIZE - 1;
22309 if (selector >= nSelectors) { _throw(Err.DATA_ERROR); }
22310 hufGroup = groups[selectors[selector++]];
22311 }
22312 /* Read next huffman-coded symbol. */
22313 i = hufGroup.minLen;
22314 j = reader.read(i);
22315 for (;;i++) {
22316 if (i > hufGroup.maxLen) { _throw(Err.DATA_ERROR); }
22317 if (j <= hufGroup.limit[i])
22318 break;
22319 j = (j << 1) | reader.read(1);
22320 }
22321 /* Huffman decode value to get nextSym (with bounds checking) */
22322 j -= hufGroup.base[i];
22323 if (j < 0 || j >= MAX_SYMBOLS) { _throw(Err.DATA_ERROR); }
22324 var nextSym = hufGroup.permute[j];
22325 /* We have now decoded the symbol, which indicates either a new literal
22326 byte, or a repeated run of the most recent literal byte. First,
22327 check if nextSym indicates a repeated run, and if so loop collecting
22328 how many times to repeat the last literal. */
22329 if (nextSym === SYMBOL_RUNA || nextSym === SYMBOL_RUNB) {
22330 /* If this is the start of a new run, zero out counter */
22331 if (!runPos){
22332 runPos = 1;
22333 t = 0;
22334 }
22335 /* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
22336 each bit position, add 1 or 2 instead. For example,
22337 1011 is 1<<0 + 1<<1 + 2<<2. 1010 is 2<<0 + 2<<1 + 1<<2.
22338 You can make any bit pattern that way using 1 less symbol than
22339 the basic or 0/1 method (except all bits 0, which would use no
22340 symbols, but a run of length 0 doesn't mean anything in this
22341 context). Thus space is saved. */
22342 if (nextSym === SYMBOL_RUNA)
22343 t += runPos;
22344 else
22345 t += 2 * runPos;
22346 runPos <<= 1;
22347 continue;
22348 }
22349 /* When we hit the first non-run symbol after a run, we now know
22350 how many times to repeat the last literal, so append that many
22351 copies to our buffer of decoded symbols (dbuf) now. (The last
22352 literal used is the one at the head of the mtfSymbol array.) */
22353 if (runPos){
22354 runPos = 0;
22355 if (dbufCount + t > this.dbufSize) { _throw(Err.DATA_ERROR); }
22356 uc = symToByte[mtfSymbol[0]];
22357 byteCount[uc] += t;
22358 while (t--)
22359 dbuf[dbufCount++] = uc;
22360 }
22361 /* Is this the terminating symbol? */
22362 if (nextSym > symTotal)
22363 break;
22364 /* At this point, nextSym indicates a new literal character. Subtract
22365 one to get the position in the MTF array at which this literal is
22366 currently to be found. (Note that the result can't be -1 or 0,
22367 because 0 and 1 are RUNA and RUNB. But another instance of the
22368 first symbol in the mtf array, position 0, would have been handled
22369 as part of a run above. Therefore 1 unused mtf position minus
22370 2 non-literal nextSym values equals -1.) */
22371 if (dbufCount >= this.dbufSize) { _throw(Err.DATA_ERROR); }
22372 i = nextSym - 1;
22373 uc = mtf(mtfSymbol, i);
22374 uc = symToByte[uc];
22375 /* We have our literal byte. Save it into dbuf. */
22376 byteCount[uc]++;
22377 dbuf[dbufCount++] = uc;
22378 }
22379 /* At this point, we've read all the huffman-coded symbols (and repeated
22380 runs) for this block from the input stream, and decoded them into the
22381 intermediate buffer. There are dbufCount many decoded bytes in dbuf[].
22382 Now undo the Burrows-Wheeler transform on dbuf.
22383 See http://dogma.net/markn/articles/bwt/bwt.htm
22384 */
22385 if (origPointer < 0 || origPointer >= dbufCount) { _throw(Err.DATA_ERROR); }
22386 /* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
22387 j = 0;
22388 for (i = 0; i < 256; i++) {
22389 k = j + byteCount[i];
22390 byteCount[i] = j;
22391 j = k;
22392 }
22393 /* Figure out what order dbuf would be in if we sorted it. */
22394 for (i = 0; i < dbufCount; i++) {
22395 uc = dbuf[i] & 0xff;
22396 dbuf[byteCount[uc]] |= (i << 8);
22397 byteCount[uc]++;
22398 }
22399 /* Decode first byte by hand to initialize "previous" byte. Note that it
22400 doesn't get output, and if the first three characters are identical
22401 it doesn't qualify as a run (hence writeRunCountdown=5). */
22402 var pos = 0, current = 0, run = 0;
22403 if (dbufCount) {
22404 pos = dbuf[origPointer];
22405 current = (pos & 0xff);
22406 pos >>= 8;
22407 run = -1;
22408 }
22409 this.writePos = pos;
22410 this.writeCurrent = current;
22411 this.writeCount = dbufCount;
22412 this.writeRun = run;
22413
22414 return true; /* more blocks to come */
22415};
22416/* Undo burrows-wheeler transform on intermediate buffer to produce output.
22417 If start_bunzip was initialized with out_fd=-1, then up to len bytes of
22418 data are written to outbuf. Return value is number of bytes written or
22419 error (all errors are negative numbers). If out_fd!=-1, outbuf and len
22420 are ignored, data is written to out_fd and return is RETVAL_OK or error.
22421*/
22422Bunzip.prototype._read_bunzip = function(outputBuffer, len) {
22423 var copies, previous, outbyte;
22424 /* james@jamestaylor.org: writeCount goes to -1 when the buffer is fully
22425 decoded, which results in this returning RETVAL_LAST_BLOCK, also
22426 equal to -1... Confusing, I'm returning 0 here to indicate no
22427 bytes written into the buffer */
22428 if (this.writeCount < 0) { return 0; }
22429 var dbuf = this.dbuf, pos = this.writePos, current = this.writeCurrent;
22430 var dbufCount = this.writeCount; this.outputsize;
22431 var run = this.writeRun;
22432
22433 while (dbufCount) {
22434 dbufCount--;
22435 previous = current;
22436 pos = dbuf[pos];
22437 current = pos & 0xff;
22438 pos >>= 8;
22439 if (run++ === 3){
22440 copies = current;
22441 outbyte = previous;
22442 current = -1;
22443 } else {
22444 copies = 1;
22445 outbyte = current;
22446 }
22447 this.blockCRC.updateCRCRun(outbyte, copies);
22448 while (copies--) {
22449 this.outputStream.writeByte(outbyte);
22450 this.nextoutput++;
22451 }
22452 if (current != previous)
22453 run = 0;
22454 }
22455 this.writeCount = dbufCount;
22456 // check CRC
22457 if (this.blockCRC.getCRC() !== this.targetBlockCRC) {
22458 _throw(Err.DATA_ERROR, "Bad block CRC "+
22459 "(got "+this.blockCRC.getCRC().toString(16)+
22460 " expected "+this.targetBlockCRC.toString(16)+")");
22461 }
22462 return this.nextoutput;
22463};
22464
22465var coerceInputStream = function(input) {
22466 if ('readByte' in input) { return input; }
22467 var inputStream = new stream();
22468 inputStream.pos = 0;
22469 inputStream.readByte = function() { return input[this.pos++]; };
22470 inputStream.seek = function(pos) { this.pos = pos; };
22471 inputStream.eof = function() { return this.pos >= input.length; };
22472 return inputStream;
22473};
22474var coerceOutputStream = function(output) {
22475 var outputStream = new stream();
22476 var resizeOk = true;
22477 if (output) {
22478 if (typeof(output)==='number') {
22479 outputStream.buffer = new Uint8Array(output);
22480 resizeOk = false;
22481 } else if ('writeByte' in output) {
22482 return output;
22483 } else {
22484 outputStream.buffer = output;
22485 resizeOk = false;
22486 }
22487 } else {
22488 outputStream.buffer = new Uint8Array(16384);
22489 }
22490 outputStream.pos = 0;
22491 outputStream.writeByte = function(_byte) {
22492 if (resizeOk && this.pos >= this.buffer.length) {
22493 var newBuffer = new Uint8Array(this.buffer.length*2);
22494 newBuffer.set(this.buffer);
22495 this.buffer = newBuffer;
22496 }
22497 this.buffer[this.pos++] = _byte;
22498 };
22499 outputStream.getBuffer = function() {
22500 // trim buffer
22501 if (this.pos !== this.buffer.length) {
22502 if (!resizeOk)
22503 throw new TypeError('outputsize does not match decoded input');
22504 var newBuffer = new Uint8Array(this.pos);
22505 newBuffer.set(this.buffer.subarray(0, this.pos));
22506 this.buffer = newBuffer;
22507 }
22508 return this.buffer;
22509 };
22510 outputStream._coerced = true;
22511 return outputStream;
22512};
22513
22514/* Static helper functions */
22515// 'input' can be a stream or a buffer
22516// 'output' can be a stream or a buffer or a number (buffer size)
22517const decode$2 = function(input, output, multistream) {
22518 // make a stream from a buffer, if necessary
22519 var inputStream = coerceInputStream(input);
22520 var outputStream = coerceOutputStream(output);
22521
22522 var bz = new Bunzip(inputStream, outputStream);
22523 while (true) {
22524 if ('eof' in inputStream && inputStream.eof()) break;
22525 if (bz._init_block()) {
22526 bz._read_bunzip();
22527 } else {
22528 var targetStreamCRC = bz.reader.read(32) >>> 0; // (convert to unsigned)
22529 if (targetStreamCRC !== bz.streamCRC) {
22530 _throw(Err.DATA_ERROR, "Bad stream CRC "+
22531 "(got "+bz.streamCRC.toString(16)+
22532 " expected "+targetStreamCRC.toString(16)+")");
22533 }
22534 if (multistream &&
22535 'eof' in inputStream &&
22536 !inputStream.eof()) {
22537 // note that start_bunzip will also resync the bit reader to next byte
22538 bz._start_bunzip(inputStream, outputStream);
22539 } else break;
22540 }
22541 }
22542 if ('getBuffer' in outputStream)
22543 return outputStream.getBuffer();
22544};
22545const decodeBlock = function(input, pos, output) {
22546 // make a stream from a buffer, if necessary
22547 var inputStream = coerceInputStream(input);
22548 var outputStream = coerceOutputStream(output);
22549 var bz = new Bunzip(inputStream, outputStream);
22550 bz.reader.seek(pos);
22551 /* Fill the decode buffer for the block */
22552 var moreBlocks = bz._get_next_block();
22553 if (moreBlocks) {
22554 /* Init the CRC for writing */
22555 bz.blockCRC = new crc32$1();
22556
22557 /* Zero this so the current byte from before the seek is not written */
22558 bz.writeCopies = 0;
22559
22560 /* Decompress the block and write to stdout */
22561 bz._read_bunzip();
22562 // XXX keep writing?
22563 }
22564 if ('getBuffer' in outputStream)
22565 return outputStream.getBuffer();
22566};
22567/* Reads bzip2 file from stream or buffer `input`, and invoke
22568 * `callback(position, size)` once for each bzip2 block,
22569 * where position gives the starting position (in *bits*)
22570 * and size gives uncompressed size of the block (in *bytes*). */
22571const table = function(input, callback, multistream) {
22572 // make a stream from a buffer, if necessary
22573 var inputStream = new stream();
22574 inputStream.delegate = coerceInputStream(input);
22575 inputStream.pos = 0;
22576 inputStream.readByte = function() {
22577 this.pos++;
22578 return this.delegate.readByte();
22579 };
22580 if (inputStream.delegate.eof) {
22581 inputStream.eof = inputStream.delegate.eof.bind(inputStream.delegate);
22582 }
22583 var outputStream = new stream();
22584 outputStream.pos = 0;
22585 outputStream.writeByte = function() { this.pos++; };
22586
22587 var bz = new Bunzip(inputStream, outputStream);
22588 var blockSize = bz.dbufSize;
22589 while (true) {
22590 if ('eof' in inputStream && inputStream.eof()) break;
22591
22592 var position = inputStream.pos*8 + bz.reader.bitOffset;
22593 if (bz.reader.hasByte) { position -= 8; }
22594
22595 if (bz._init_block()) {
22596 var start = outputStream.pos;
22597 bz._read_bunzip();
22598 callback(position, outputStream.pos - start);
22599 } else {
22600 bz.reader.read(32); // (but we ignore the crc)
22601 if (multistream &&
22602 'eof' in inputStream &&
22603 !inputStream.eof()) {
22604 // note that start_bunzip will also resync the bit reader to next byte
22605 bz._start_bunzip(inputStream, outputStream);
22606 console.assert(bz.dbufSize === blockSize,
22607 "shouldn't change block size within multistream file");
22608 } else break;
22609 }
22610 }
22611};
22612
22613var lib = {
22614 Bunzip,
22615 Stream: stream,
22616 Err,
22617 decode: decode$2,
22618 decodeBlock,
22619 table
22620};
22621var lib_4 = lib.decode;
22622
22623// GPG4Browsers - An OpenPGP implementation in javascript
22624
22625/**
22626 * Implementation of the Literal Data Packet (Tag 11)
22627 *
22628 * {@link https://tools.ietf.org/html/rfc4880#section-5.9|RFC4880 5.9}:
22629 * A Literal Data packet contains the body of a message; data that is not to be
22630 * further interpreted.
22631 */
22632class LiteralDataPacket {
22633 static get tag() {
22634 return enums.packet.literalData;
22635 }
22636
22637 /**
22638 * @param {Date} date - The creation date of the literal package
22639 */
22640 constructor(date = new Date()) {
22641 this.format = enums.literal.utf8; // default format for literal data packets
22642 this.date = util.normalizeDate(date);
22643 this.text = null; // textual data representation
22644 this.data = null; // literal data representation
22645 this.filename = '';
22646 }
22647
22648 /**
22649 * Set the packet data to a javascript native string, end of line
22650 * will be normalized to \r\n and by default text is converted to UTF8
22651 * @param {String | ReadableStream<String>} text - Any native javascript string
22652 * @param {enums.literal} [format] - The format of the string of bytes
22653 */
22654 setText(text, format = enums.literal.utf8) {
22655 this.format = format;
22656 this.text = text;
22657 this.data = null;
22658 }
22659
22660 /**
22661 * Returns literal data packets as native JavaScript string
22662 * with normalized end of line to \n
22663 * @param {Boolean} [clone] - Whether to return a clone so that getBytes/getText can be called again
22664 * @returns {String | ReadableStream<String>} Literal data as text.
22665 */
22666 getText(clone = false) {
22667 if (this.text === null || util.isStream(this.text)) { // Assume that this.text has been read
22668 this.text = util.decodeUTF8(util.nativeEOL(this.getBytes(clone)));
22669 }
22670 return this.text;
22671 }
22672
22673 /**
22674 * Set the packet data to value represented by the provided string of bytes.
22675 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - The string of bytes
22676 * @param {enums.literal} format - The format of the string of bytes
22677 */
22678 setBytes(bytes, format) {
22679 this.format = format;
22680 this.data = bytes;
22681 this.text = null;
22682 }
22683
22684
22685 /**
22686 * Get the byte sequence representing the literal packet data
22687 * @param {Boolean} [clone] - Whether to return a clone so that getBytes/getText can be called again
22688 * @returns {Uint8Array | ReadableStream<Uint8Array>} A sequence of bytes.
22689 */
22690 getBytes(clone = false) {
22691 if (this.data === null) {
22692 // encode UTF8 and normalize EOL to \r\n
22693 this.data = util.canonicalizeEOL(util.encodeUTF8(this.text));
22694 }
22695 if (clone) {
22696 return passiveClone(this.data);
22697 }
22698 return this.data;
22699 }
22700
22701
22702 /**
22703 * Sets the filename of the literal packet data
22704 * @param {String} filename - Any native javascript string
22705 */
22706 setFilename(filename) {
22707 this.filename = filename;
22708 }
22709
22710
22711 /**
22712 * Get the filename of the literal packet data
22713 * @returns {String} Filename.
22714 */
22715 getFilename() {
22716 return this.filename;
22717 }
22718
22719 /**
22720 * Parsing function for a literal data packet (tag 11).
22721 *
22722 * @param {Uint8Array | ReadableStream<Uint8Array>} input - Payload of a tag 11 packet
22723 * @returns {Promise<LiteralDataPacket>} Object representation.
22724 * @async
22725 */
22726 async read(bytes) {
22727 await parse(bytes, async reader => {
22728 // - A one-octet field that describes how the data is formatted.
22729 const format = await reader.readByte(); // enums.literal
22730
22731 const filename_len = await reader.readByte();
22732 this.filename = util.decodeUTF8(await reader.readBytes(filename_len));
22733
22734 this.date = util.readDate(await reader.readBytes(4));
22735
22736 let data = reader.remainder();
22737 if (isArrayStream(data)) data = await readToEnd(data);
22738 this.setBytes(data, format);
22739 });
22740 }
22741
22742 /**
22743 * Creates a Uint8Array representation of the packet, excluding the data
22744 *
22745 * @returns {Uint8Array} Uint8Array representation of the packet.
22746 */
22747 writeHeader() {
22748 const filename = util.encodeUTF8(this.filename);
22749 const filename_length = new Uint8Array([filename.length]);
22750
22751 const format = new Uint8Array([this.format]);
22752 const date = util.writeDate(this.date);
22753
22754 return util.concatUint8Array([format, filename_length, filename, date]);
22755 }
22756
22757 /**
22758 * Creates a Uint8Array representation of the packet
22759 *
22760 * @returns {Uint8Array | ReadableStream<Uint8Array>} Uint8Array representation of the packet.
22761 */
22762 write() {
22763 const header = this.writeHeader();
22764 const data = this.getBytes();
22765
22766 return util.concat([header, data]);
22767 }
22768}
22769
22770// GPG4Browsers - An OpenPGP implementation in javascript
22771
22772// Symbol to store cryptographic validity of the signature, to avoid recomputing multiple times on verification.
22773const verified = Symbol('verified');
22774
22775// GPG puts the Issuer and Signature subpackets in the unhashed area.
22776// Tampering with those invalidates the signature, so we still trust them and parse them.
22777// All other unhashed subpackets are ignored.
22778const allowedUnhashedSubpackets = new Set([
22779 enums.signatureSubpacket.issuer,
22780 enums.signatureSubpacket.issuerFingerprint,
22781 enums.signatureSubpacket.embeddedSignature
22782]);
22783
22784/**
22785 * Implementation of the Signature Packet (Tag 2)
22786 *
22787 * {@link https://tools.ietf.org/html/rfc4880#section-5.2|RFC4480 5.2}:
22788 * A Signature packet describes a binding between some public key and
22789 * some data. The most common signatures are a signature of a file or a
22790 * block of text, and a signature that is a certification of a User ID.
22791 */
22792class SignaturePacket {
22793 static get tag() {
22794 return enums.packet.signature;
22795 }
22796
22797 constructor() {
22798 this.version = null;
22799 /** @type {enums.signature} */
22800 this.signatureType = null;
22801 /** @type {enums.hash} */
22802 this.hashAlgorithm = null;
22803 /** @type {enums.publicKey} */
22804 this.publicKeyAlgorithm = null;
22805
22806 this.signatureData = null;
22807 this.unhashedSubpackets = [];
22808 this.signedHashValue = null;
22809
22810 this.created = null;
22811 this.signatureExpirationTime = null;
22812 this.signatureNeverExpires = true;
22813 this.exportable = null;
22814 this.trustLevel = null;
22815 this.trustAmount = null;
22816 this.regularExpression = null;
22817 this.revocable = null;
22818 this.keyExpirationTime = null;
22819 this.keyNeverExpires = null;
22820 this.preferredSymmetricAlgorithms = null;
22821 this.revocationKeyClass = null;
22822 this.revocationKeyAlgorithm = null;
22823 this.revocationKeyFingerprint = null;
22824 this.issuerKeyID = new KeyID();
22825 this.rawNotations = [];
22826 this.notations = {};
22827 this.preferredHashAlgorithms = null;
22828 this.preferredCompressionAlgorithms = null;
22829 this.keyServerPreferences = null;
22830 this.preferredKeyServer = null;
22831 this.isPrimaryUserID = null;
22832 this.policyURI = null;
22833 this.keyFlags = null;
22834 this.signersUserID = null;
22835 this.reasonForRevocationFlag = null;
22836 this.reasonForRevocationString = null;
22837 this.features = null;
22838 this.signatureTargetPublicKeyAlgorithm = null;
22839 this.signatureTargetHashAlgorithm = null;
22840 this.signatureTargetHash = null;
22841 this.embeddedSignature = null;
22842 this.issuerKeyVersion = null;
22843 this.issuerFingerprint = null;
22844 this.preferredAEADAlgorithms = null;
22845
22846 this.revoked = null;
22847 this[verified] = null;
22848 }
22849
22850 /**
22851 * parsing function for a signature packet (tag 2).
22852 * @param {String} bytes - Payload of a tag 2 packet
22853 * @returns {SignaturePacket} Object representation.
22854 */
22855 read(bytes) {
22856 let i = 0;
22857 this.version = bytes[i++];
22858
22859 if (this.version !== 4 && this.version !== 5) {
22860 throw new UnsupportedError(`Version ${this.version} of the signature packet is unsupported.`);
22861 }
22862
22863 this.signatureType = bytes[i++];
22864 this.publicKeyAlgorithm = bytes[i++];
22865 this.hashAlgorithm = bytes[i++];
22866
22867 // hashed subpackets
22868 i += this.readSubPackets(bytes.subarray(i, bytes.length), true);
22869 if (!this.created) {
22870 throw new Error('Missing signature creation time subpacket.');
22871 }
22872
22873 // A V4 signature hashes the packet body
22874 // starting from its first field, the version number, through the end
22875 // of the hashed subpacket data. Thus, the fields hashed are the
22876 // signature version, the signature type, the public-key algorithm, the
22877 // hash algorithm, the hashed subpacket length, and the hashed
22878 // subpacket body.
22879 this.signatureData = bytes.subarray(0, i);
22880
22881 // unhashed subpackets
22882 i += this.readSubPackets(bytes.subarray(i, bytes.length), false);
22883
22884 // Two-octet field holding left 16 bits of signed hash value.
22885 this.signedHashValue = bytes.subarray(i, i + 2);
22886 i += 2;
22887
22888 this.params = mod.signature.parseSignatureParams(this.publicKeyAlgorithm, bytes.subarray(i, bytes.length));
22889 }
22890
22891 /**
22892 * @returns {Uint8Array | ReadableStream<Uint8Array>}
22893 */
22894 writeParams() {
22895 if (this.params instanceof Promise) {
22896 return fromAsync(
22897 async () => mod.serializeParams(this.publicKeyAlgorithm, await this.params)
22898 );
22899 }
22900 return mod.serializeParams(this.publicKeyAlgorithm, this.params);
22901 }
22902
22903 write() {
22904 const arr = [];
22905 arr.push(this.signatureData);
22906 arr.push(this.writeUnhashedSubPackets());
22907 arr.push(this.signedHashValue);
22908 arr.push(this.writeParams());
22909 return util.concat(arr);
22910 }
22911
22912 /**
22913 * Signs provided data. This needs to be done prior to serialization.
22914 * @param {SecretKeyPacket} key - Private key used to sign the message.
22915 * @param {Object} data - Contains packets to be signed.
22916 * @param {Date} [date] - The signature creation time.
22917 * @param {Boolean} [detached] - Whether to create a detached signature
22918 * @throws {Error} if signing failed
22919 * @async
22920 */
22921 async sign(key, data, date = new Date(), detached = false) {
22922 if (key.version === 5) {
22923 this.version = 5;
22924 } else {
22925 this.version = 4;
22926 }
22927 const arr = [new Uint8Array([this.version, this.signatureType, this.publicKeyAlgorithm, this.hashAlgorithm])];
22928
22929 this.created = util.normalizeDate(date);
22930 this.issuerKeyVersion = key.version;
22931 this.issuerFingerprint = key.getFingerprintBytes();
22932 this.issuerKeyID = key.getKeyID();
22933
22934 // Add hashed subpackets
22935 arr.push(this.writeHashedSubPackets());
22936
22937 // Remove unhashed subpackets, in case some allowed unhashed
22938 // subpackets existed, in order not to duplicate them (in both
22939 // the hashed and unhashed subpackets) when re-signing.
22940 this.unhashedSubpackets = [];
22941
22942 this.signatureData = util.concat(arr);
22943
22944 const toHash = this.toHash(this.signatureType, data, detached);
22945 const hash = await this.hash(this.signatureType, data, toHash, detached);
22946
22947 this.signedHashValue = slice(clone(hash), 0, 2);
22948 const signed = async () => mod.signature.sign(
22949 this.publicKeyAlgorithm, this.hashAlgorithm, key.publicParams, key.privateParams, toHash, await readToEnd(hash)
22950 );
22951 if (util.isStream(hash)) {
22952 this.params = signed();
22953 } else {
22954 this.params = await signed();
22955
22956 // Store the fact that this signature is valid, e.g. for when we call `await
22957 // getLatestValidSignature(this.revocationSignatures, key, data)` later.
22958 // Note that this only holds up if the key and data passed to verify are the
22959 // same as the ones passed to sign.
22960 this[verified] = true;
22961 }
22962 }
22963
22964 /**
22965 * Creates Uint8Array of bytes of all subpacket data except Issuer and Embedded Signature subpackets
22966 * @returns {Uint8Array} Subpacket data.
22967 */
22968 writeHashedSubPackets() {
22969 const sub = enums.signatureSubpacket;
22970 const arr = [];
22971 let bytes;
22972 if (this.created === null) {
22973 throw new Error('Missing signature creation time');
22974 }
22975 arr.push(writeSubPacket(sub.signatureCreationTime, util.writeDate(this.created)));
22976 if (this.signatureExpirationTime !== null) {
22977 arr.push(writeSubPacket(sub.signatureExpirationTime, util.writeNumber(this.signatureExpirationTime, 4)));
22978 }
22979 if (this.exportable !== null) {
22980 arr.push(writeSubPacket(sub.exportableCertification, new Uint8Array([this.exportable ? 1 : 0])));
22981 }
22982 if (this.trustLevel !== null) {
22983 bytes = new Uint8Array([this.trustLevel, this.trustAmount]);
22984 arr.push(writeSubPacket(sub.trustSignature, bytes));
22985 }
22986 if (this.regularExpression !== null) {
22987 arr.push(writeSubPacket(sub.regularExpression, this.regularExpression));
22988 }
22989 if (this.revocable !== null) {
22990 arr.push(writeSubPacket(sub.revocable, new Uint8Array([this.revocable ? 1 : 0])));
22991 }
22992 if (this.keyExpirationTime !== null) {
22993 arr.push(writeSubPacket(sub.keyExpirationTime, util.writeNumber(this.keyExpirationTime, 4)));
22994 }
22995 if (this.preferredSymmetricAlgorithms !== null) {
22996 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredSymmetricAlgorithms));
22997 arr.push(writeSubPacket(sub.preferredSymmetricAlgorithms, bytes));
22998 }
22999 if (this.revocationKeyClass !== null) {
23000 bytes = new Uint8Array([this.revocationKeyClass, this.revocationKeyAlgorithm]);
23001 bytes = util.concat([bytes, this.revocationKeyFingerprint]);
23002 arr.push(writeSubPacket(sub.revocationKey, bytes));
23003 }
23004 if (!this.issuerKeyID.isNull() && this.issuerKeyVersion !== 5) {
23005 // If the version of [the] key is greater than 4, this subpacket
23006 // MUST NOT be included in the signature.
23007 arr.push(writeSubPacket(sub.issuer, this.issuerKeyID.write()));
23008 }
23009 this.rawNotations.forEach(([{ name, value, humanReadable }]) => {
23010 bytes = [new Uint8Array([humanReadable ? 0x80 : 0, 0, 0, 0])];
23011 // 2 octets of name length
23012 bytes.push(util.writeNumber(name.length, 2));
23013 // 2 octets of value length
23014 bytes.push(util.writeNumber(value.length, 2));
23015 bytes.push(util.stringToUint8Array(name));
23016 bytes.push(value);
23017 bytes = util.concat(bytes);
23018 arr.push(writeSubPacket(sub.notationData, bytes));
23019 });
23020 if (this.preferredHashAlgorithms !== null) {
23021 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredHashAlgorithms));
23022 arr.push(writeSubPacket(sub.preferredHashAlgorithms, bytes));
23023 }
23024 if (this.preferredCompressionAlgorithms !== null) {
23025 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredCompressionAlgorithms));
23026 arr.push(writeSubPacket(sub.preferredCompressionAlgorithms, bytes));
23027 }
23028 if (this.keyServerPreferences !== null) {
23029 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.keyServerPreferences));
23030 arr.push(writeSubPacket(sub.keyServerPreferences, bytes));
23031 }
23032 if (this.preferredKeyServer !== null) {
23033 arr.push(writeSubPacket(sub.preferredKeyServer, util.stringToUint8Array(this.preferredKeyServer)));
23034 }
23035 if (this.isPrimaryUserID !== null) {
23036 arr.push(writeSubPacket(sub.primaryUserID, new Uint8Array([this.isPrimaryUserID ? 1 : 0])));
23037 }
23038 if (this.policyURI !== null) {
23039 arr.push(writeSubPacket(sub.policyURI, util.stringToUint8Array(this.policyURI)));
23040 }
23041 if (this.keyFlags !== null) {
23042 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.keyFlags));
23043 arr.push(writeSubPacket(sub.keyFlags, bytes));
23044 }
23045 if (this.signersUserID !== null) {
23046 arr.push(writeSubPacket(sub.signersUserID, util.stringToUint8Array(this.signersUserID)));
23047 }
23048 if (this.reasonForRevocationFlag !== null) {
23049 bytes = util.stringToUint8Array(String.fromCharCode(this.reasonForRevocationFlag) + this.reasonForRevocationString);
23050 arr.push(writeSubPacket(sub.reasonForRevocation, bytes));
23051 }
23052 if (this.features !== null) {
23053 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.features));
23054 arr.push(writeSubPacket(sub.features, bytes));
23055 }
23056 if (this.signatureTargetPublicKeyAlgorithm !== null) {
23057 bytes = [new Uint8Array([this.signatureTargetPublicKeyAlgorithm, this.signatureTargetHashAlgorithm])];
23058 bytes.push(util.stringToUint8Array(this.signatureTargetHash));
23059 bytes = util.concat(bytes);
23060 arr.push(writeSubPacket(sub.signatureTarget, bytes));
23061 }
23062 if (this.embeddedSignature !== null) {
23063 arr.push(writeSubPacket(sub.embeddedSignature, this.embeddedSignature.write()));
23064 }
23065 if (this.issuerFingerprint !== null) {
23066 bytes = [new Uint8Array([this.issuerKeyVersion]), this.issuerFingerprint];
23067 bytes = util.concat(bytes);
23068 arr.push(writeSubPacket(sub.issuerFingerprint, bytes));
23069 }
23070 if (this.preferredAEADAlgorithms !== null) {
23071 bytes = util.stringToUint8Array(util.uint8ArrayToString(this.preferredAEADAlgorithms));
23072 arr.push(writeSubPacket(sub.preferredAEADAlgorithms, bytes));
23073 }
23074
23075 const result = util.concat(arr);
23076 const length = util.writeNumber(result.length, 2);
23077
23078 return util.concat([length, result]);
23079 }
23080
23081 /**
23082 * Creates an Uint8Array containing the unhashed subpackets
23083 * @returns {Uint8Array} Subpacket data.
23084 */
23085 writeUnhashedSubPackets() {
23086 const arr = [];
23087 this.unhashedSubpackets.forEach(data => {
23088 arr.push(writeSimpleLength(data.length));
23089 arr.push(data);
23090 });
23091
23092 const result = util.concat(arr);
23093 const length = util.writeNumber(result.length, 2);
23094
23095 return util.concat([length, result]);
23096 }
23097
23098 // V4 signature sub packets
23099 readSubPacket(bytes, hashed = true) {
23100 let mypos = 0;
23101
23102 // The leftmost bit denotes a "critical" packet
23103 const critical = bytes[mypos] & 0x80;
23104 const type = bytes[mypos] & 0x7F;
23105
23106 if (!hashed) {
23107 this.unhashedSubpackets.push(bytes.subarray(mypos, bytes.length));
23108 if (!allowedUnhashedSubpackets.has(type)) {
23109 return;
23110 }
23111 }
23112
23113 mypos++;
23114
23115 // subpacket type
23116 switch (type) {
23117 case enums.signatureSubpacket.signatureCreationTime:
23118 // Signature Creation Time
23119 this.created = util.readDate(bytes.subarray(mypos, bytes.length));
23120 break;
23121 case enums.signatureSubpacket.signatureExpirationTime: {
23122 // Signature Expiration Time in seconds
23123 const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
23124
23125 this.signatureNeverExpires = seconds === 0;
23126 this.signatureExpirationTime = seconds;
23127
23128 break;
23129 }
23130 case enums.signatureSubpacket.exportableCertification:
23131 // Exportable Certification
23132 this.exportable = bytes[mypos++] === 1;
23133 break;
23134 case enums.signatureSubpacket.trustSignature:
23135 // Trust Signature
23136 this.trustLevel = bytes[mypos++];
23137 this.trustAmount = bytes[mypos++];
23138 break;
23139 case enums.signatureSubpacket.regularExpression:
23140 // Regular Expression
23141 this.regularExpression = bytes[mypos];
23142 break;
23143 case enums.signatureSubpacket.revocable:
23144 // Revocable
23145 this.revocable = bytes[mypos++] === 1;
23146 break;
23147 case enums.signatureSubpacket.keyExpirationTime: {
23148 // Key Expiration Time in seconds
23149 const seconds = util.readNumber(bytes.subarray(mypos, bytes.length));
23150
23151 this.keyExpirationTime = seconds;
23152 this.keyNeverExpires = seconds === 0;
23153
23154 break;
23155 }
23156 case enums.signatureSubpacket.preferredSymmetricAlgorithms:
23157 // Preferred Symmetric Algorithms
23158 this.preferredSymmetricAlgorithms = [...bytes.subarray(mypos, bytes.length)];
23159 break;
23160 case enums.signatureSubpacket.revocationKey:
23161 // Revocation Key
23162 // (1 octet of class, 1 octet of public-key algorithm ID, 20
23163 // octets of
23164 // fingerprint)
23165 this.revocationKeyClass = bytes[mypos++];
23166 this.revocationKeyAlgorithm = bytes[mypos++];
23167 this.revocationKeyFingerprint = bytes.subarray(mypos, mypos + 20);
23168 break;
23169
23170 case enums.signatureSubpacket.issuer:
23171 // Issuer
23172 this.issuerKeyID.read(bytes.subarray(mypos, bytes.length));
23173 break;
23174
23175 case enums.signatureSubpacket.notationData: {
23176 // Notation Data
23177 const humanReadable = !!(bytes[mypos] & 0x80);
23178
23179 // We extract key/value tuple from the byte stream.
23180 mypos += 4;
23181 const m = util.readNumber(bytes.subarray(mypos, mypos + 2));
23182 mypos += 2;
23183 const n = util.readNumber(bytes.subarray(mypos, mypos + 2));
23184 mypos += 2;
23185
23186 const name = util.uint8ArrayToString(bytes.subarray(mypos, mypos + m));
23187 const value = bytes.subarray(mypos + m, mypos + m + n);
23188
23189 this.rawNotations.push({ name, humanReadable, value, critical });
23190
23191 if (humanReadable) {
23192 this.notations[name] = util.uint8ArrayToString(value);
23193 }
23194 break;
23195 }
23196 case enums.signatureSubpacket.preferredHashAlgorithms:
23197 // Preferred Hash Algorithms
23198 this.preferredHashAlgorithms = [...bytes.subarray(mypos, bytes.length)];
23199 break;
23200 case enums.signatureSubpacket.preferredCompressionAlgorithms:
23201 // Preferred Compression Algorithms
23202 this.preferredCompressionAlgorithms = [...bytes.subarray(mypos, bytes.length)];
23203 break;
23204 case enums.signatureSubpacket.keyServerPreferences:
23205 // Key Server Preferences
23206 this.keyServerPreferences = [...bytes.subarray(mypos, bytes.length)];
23207 break;
23208 case enums.signatureSubpacket.preferredKeyServer:
23209 // Preferred Key Server
23210 this.preferredKeyServer = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
23211 break;
23212 case enums.signatureSubpacket.primaryUserID:
23213 // Primary User ID
23214 this.isPrimaryUserID = bytes[mypos++] !== 0;
23215 break;
23216 case enums.signatureSubpacket.policyURI:
23217 // Policy URI
23218 this.policyURI = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
23219 break;
23220 case enums.signatureSubpacket.keyFlags:
23221 // Key Flags
23222 this.keyFlags = [...bytes.subarray(mypos, bytes.length)];
23223 break;
23224 case enums.signatureSubpacket.signersUserID:
23225 // Signer's User ID
23226 this.signersUserID = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
23227 break;
23228 case enums.signatureSubpacket.reasonForRevocation:
23229 // Reason for Revocation
23230 this.reasonForRevocationFlag = bytes[mypos++];
23231 this.reasonForRevocationString = util.uint8ArrayToString(bytes.subarray(mypos, bytes.length));
23232 break;
23233 case enums.signatureSubpacket.features:
23234 // Features
23235 this.features = [...bytes.subarray(mypos, bytes.length)];
23236 break;
23237 case enums.signatureSubpacket.signatureTarget: {
23238 // Signature Target
23239 // (1 octet public-key algorithm, 1 octet hash algorithm, N octets hash)
23240 this.signatureTargetPublicKeyAlgorithm = bytes[mypos++];
23241 this.signatureTargetHashAlgorithm = bytes[mypos++];
23242
23243 const len = mod.getHashByteLength(this.signatureTargetHashAlgorithm);
23244
23245 this.signatureTargetHash = util.uint8ArrayToString(bytes.subarray(mypos, mypos + len));
23246 break;
23247 }
23248 case enums.signatureSubpacket.embeddedSignature:
23249 // Embedded Signature
23250 this.embeddedSignature = new SignaturePacket();
23251 this.embeddedSignature.read(bytes.subarray(mypos, bytes.length));
23252 break;
23253 case enums.signatureSubpacket.issuerFingerprint:
23254 // Issuer Fingerprint
23255 this.issuerKeyVersion = bytes[mypos++];
23256 this.issuerFingerprint = bytes.subarray(mypos, bytes.length);
23257 if (this.issuerKeyVersion === 5) {
23258 this.issuerKeyID.read(this.issuerFingerprint);
23259 } else {
23260 this.issuerKeyID.read(this.issuerFingerprint.subarray(-8));
23261 }
23262 break;
23263 case enums.signatureSubpacket.preferredAEADAlgorithms:
23264 // Preferred AEAD Algorithms
23265 this.preferredAEADAlgorithms = [...bytes.subarray(mypos, bytes.length)];
23266 break;
23267 default: {
23268 const err = new Error(`Unknown signature subpacket type ${type}`);
23269 if (critical) {
23270 throw err;
23271 } else {
23272 util.printDebug(err);
23273 }
23274 }
23275 }
23276 }
23277
23278 readSubPackets(bytes, trusted = true, config) {
23279 // Two-octet scalar octet count for following subpacket data.
23280 const subpacketLength = util.readNumber(bytes.subarray(0, 2));
23281
23282 let i = 2;
23283
23284 // subpacket data set (zero or more subpackets)
23285 while (i < 2 + subpacketLength) {
23286 const len = readSimpleLength(bytes.subarray(i, bytes.length));
23287 i += len.offset;
23288
23289 this.readSubPacket(bytes.subarray(i, i + len.len), trusted, config);
23290
23291 i += len.len;
23292 }
23293
23294 return i;
23295 }
23296
23297 // Produces data to produce signature on
23298 toSign(type, data) {
23299 const t = enums.signature;
23300
23301 switch (type) {
23302 case t.binary:
23303 if (data.text !== null) {
23304 return util.encodeUTF8(data.getText(true));
23305 }
23306 return data.getBytes(true);
23307
23308 case t.text: {
23309 const bytes = data.getBytes(true);
23310 // normalize EOL to \r\n
23311 return util.canonicalizeEOL(bytes);
23312 }
23313 case t.standalone:
23314 return new Uint8Array(0);
23315
23316 case t.certGeneric:
23317 case t.certPersona:
23318 case t.certCasual:
23319 case t.certPositive:
23320 case t.certRevocation: {
23321 let packet;
23322 let tag;
23323
23324 if (data.userID) {
23325 tag = 0xB4;
23326 packet = data.userID;
23327 } else if (data.userAttribute) {
23328 tag = 0xD1;
23329 packet = data.userAttribute;
23330 } else {
23331 throw new Error('Either a userID or userAttribute packet needs to be ' +
23332 'supplied for certification.');
23333 }
23334
23335 const bytes = packet.write();
23336
23337 return util.concat([this.toSign(t.key, data),
23338 new Uint8Array([tag]),
23339 util.writeNumber(bytes.length, 4),
23340 bytes]);
23341 }
23342 case t.subkeyBinding:
23343 case t.subkeyRevocation:
23344 case t.keyBinding:
23345 return util.concat([this.toSign(t.key, data), this.toSign(t.key, {
23346 key: data.bind
23347 })]);
23348
23349 case t.key:
23350 if (data.key === undefined) {
23351 throw new Error('Key packet is required for this signature.');
23352 }
23353 return data.key.writeForHash(this.version);
23354
23355 case t.keyRevocation:
23356 return this.toSign(t.key, data);
23357 case t.timestamp:
23358 return new Uint8Array(0);
23359 case t.thirdParty:
23360 throw new Error('Not implemented');
23361 default:
23362 throw new Error('Unknown signature type.');
23363 }
23364 }
23365
23366 calculateTrailer(data, detached) {
23367 let length = 0;
23368 return transform(clone(this.signatureData), value => {
23369 length += value.length;
23370 }, () => {
23371 const arr = [];
23372 if (this.version === 5 && (this.signatureType === enums.signature.binary || this.signatureType === enums.signature.text)) {
23373 if (detached) {
23374 arr.push(new Uint8Array(6));
23375 } else {
23376 arr.push(data.writeHeader());
23377 }
23378 }
23379 arr.push(new Uint8Array([this.version, 0xFF]));
23380 if (this.version === 5) {
23381 arr.push(new Uint8Array(4));
23382 }
23383 arr.push(util.writeNumber(length, 4));
23384 // For v5, this should really be writeNumber(length, 8) rather than the
23385 // hardcoded 4 zero bytes above
23386 return util.concat(arr);
23387 });
23388 }
23389
23390 toHash(signatureType, data, detached = false) {
23391 const bytes = this.toSign(signatureType, data);
23392
23393 return util.concat([bytes, this.signatureData, this.calculateTrailer(data, detached)]);
23394 }
23395
23396 async hash(signatureType, data, toHash, detached = false) {
23397 if (!toHash) toHash = this.toHash(signatureType, data, detached);
23398 return mod.hash.digest(this.hashAlgorithm, toHash);
23399 }
23400
23401 /**
23402 * verifies the signature packet. Note: not all signature types are implemented
23403 * @param {PublicSubkeyPacket|PublicKeyPacket|
23404 * SecretSubkeyPacket|SecretKeyPacket} key - the public key to verify the signature
23405 * @param {module:enums.signature} signatureType - Expected signature type
23406 * @param {Uint8Array|Object} data - Data which on the signature applies
23407 * @param {Date} [date] - Use the given date instead of the current time to check for signature validity and expiration
23408 * @param {Boolean} [detached] - Whether to verify a detached signature
23409 * @param {Object} [config] - Full configuration, defaults to openpgp.config
23410 * @throws {Error} if signature validation failed
23411 * @async
23412 */
23413 async verify(key, signatureType, data, date = new Date(), detached = false, config = defaultConfig) {
23414 if (!this.issuerKeyID.equals(key.getKeyID())) {
23415 throw new Error('Signature was not issued by the given public key');
23416 }
23417 if (this.publicKeyAlgorithm !== key.algorithm) {
23418 throw new Error('Public key algorithm used to sign signature does not match issuer key algorithm.');
23419 }
23420
23421 const isMessageSignature = signatureType === enums.signature.binary || signatureType === enums.signature.text;
23422 // Cryptographic validity is cached after one successful verification.
23423 // However, for message signatures, we always re-verify, since the passed `data` can change
23424 const skipVerify = this[verified] && !isMessageSignature;
23425 if (!skipVerify) {
23426 let toHash;
23427 let hash;
23428 if (this.hashed) {
23429 hash = await this.hashed;
23430 } else {
23431 toHash = this.toHash(signatureType, data, detached);
23432 hash = await this.hash(signatureType, data, toHash);
23433 }
23434 hash = await readToEnd(hash);
23435 if (this.signedHashValue[0] !== hash[0] ||
23436 this.signedHashValue[1] !== hash[1]) {
23437 throw new Error('Signed digest did not match');
23438 }
23439
23440 this.params = await this.params;
23441
23442 this[verified] = await mod.signature.verify(
23443 this.publicKeyAlgorithm, this.hashAlgorithm, this.params, key.publicParams,
23444 toHash, hash
23445 );
23446
23447 if (!this[verified]) {
23448 throw new Error('Signature verification failed');
23449 }
23450 }
23451
23452 const normDate = util.normalizeDate(date);
23453 if (normDate && this.created > normDate) {
23454 throw new Error('Signature creation time is in the future');
23455 }
23456 if (normDate && normDate >= this.getExpirationTime()) {
23457 throw new Error('Signature is expired');
23458 }
23459 if (config.rejectHashAlgorithms.has(this.hashAlgorithm)) {
23460 throw new Error('Insecure hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
23461 }
23462 if (config.rejectMessageHashAlgorithms.has(this.hashAlgorithm) &&
23463 [enums.signature.binary, enums.signature.text].includes(this.signatureType)) {
23464 throw new Error('Insecure message hash algorithm: ' + enums.read(enums.hash, this.hashAlgorithm).toUpperCase());
23465 }
23466 this.rawNotations.forEach(({ name, critical }) => {
23467 if (critical && (config.knownNotations.indexOf(name) < 0)) {
23468 throw new Error(`Unknown critical notation: ${name}`);
23469 }
23470 });
23471 if (this.revocationKeyClass !== null) {
23472 throw new Error('This key is intended to be revoked with an authorized key, which OpenPGP.js does not support.');
23473 }
23474 }
23475
23476 /**
23477 * Verifies signature expiration date
23478 * @param {Date} [date] - Use the given date for verification instead of the current time
23479 * @returns {Boolean} True if expired.
23480 */
23481 isExpired(date = new Date()) {
23482 const normDate = util.normalizeDate(date);
23483 if (normDate !== null) {
23484 return !(this.created <= normDate && normDate < this.getExpirationTime());
23485 }
23486 return false;
23487 }
23488
23489 /**
23490 * Returns the expiration time of the signature or Infinity if signature does not expire
23491 * @returns {Date | Infinity} Expiration time.
23492 */
23493 getExpirationTime() {
23494 return this.signatureNeverExpires ? Infinity : new Date(this.created.getTime() + this.signatureExpirationTime * 1000);
23495 }
23496}
23497
23498/**
23499 * Creates a string representation of a sub signature packet
23500 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.1|RFC4880 5.2.3.1}
23501 * @see {@link https://tools.ietf.org/html/rfc4880#section-5.2.3.2|RFC4880 5.2.3.2}
23502 * @param {Integer} type - Subpacket signature type.
23503 * @param {String} data - Data to be included
23504 * @returns {String} A string-representation of a sub signature packet.
23505 * @private
23506 */
23507function writeSubPacket(type, data) {
23508 const arr = [];
23509 arr.push(writeSimpleLength(data.length + 1));
23510 arr.push(new Uint8Array([type]));
23511 arr.push(data);
23512 return util.concat(arr);
23513}
23514
23515// GPG4Browsers - An OpenPGP implementation in javascript
23516
23517const VERSION = 3;
23518
23519/**
23520 * Implementation of the One-Pass Signature Packets (Tag 4)
23521 *
23522 * {@link https://tools.ietf.org/html/rfc4880#section-5.4|RFC4880 5.4}:
23523 * The One-Pass Signature packet precedes the signed data and contains
23524 * enough information to allow the receiver to begin calculating any
23525 * hashes needed to verify the signature. It allows the Signature
23526 * packet to be placed at the end of the message, so that the signer
23527 * can compute the entire signed message in one pass.
23528 */
23529class OnePassSignaturePacket {
23530 static get tag() {
23531 return enums.packet.onePassSignature;
23532 }
23533
23534 constructor() {
23535 /** A one-octet version number. The current version is 3. */
23536 this.version = null;
23537 /**
23538 * A one-octet signature type.
23539 * Signature types are described in
23540 * {@link https://tools.ietf.org/html/rfc4880#section-5.2.1|RFC4880 Section 5.2.1}.
23541 * @type {enums.signature}
23542
23543 */
23544 this.signatureType = null;
23545 /**
23546 * A one-octet number describing the hash algorithm used.
23547 * @see {@link https://tools.ietf.org/html/rfc4880#section-9.4|RFC4880 9.4}
23548 * @type {enums.hash}
23549 */
23550 this.hashAlgorithm = null;
23551 /**
23552 * A one-octet number describing the public-key algorithm used.
23553 * @see {@link https://tools.ietf.org/html/rfc4880#section-9.1|RFC4880 9.1}
23554 * @type {enums.publicKey}
23555 */
23556 this.publicKeyAlgorithm = null;
23557 /** An eight-octet number holding the Key ID of the signing key. */
23558 this.issuerKeyID = null;
23559 /**
23560 * A one-octet number holding a flag showing whether the signature is nested.
23561 * A zero value indicates that the next packet is another One-Pass Signature packet
23562 * that describes another signature to be applied to the same message data.
23563 */
23564 this.flags = null;
23565 }
23566
23567 /**
23568 * parsing function for a one-pass signature packet (tag 4).
23569 * @param {Uint8Array} bytes - Payload of a tag 4 packet
23570 * @returns {OnePassSignaturePacket} Object representation.
23571 */
23572 read(bytes) {
23573 let mypos = 0;
23574 // A one-octet version number. The current version is 3.
23575 this.version = bytes[mypos++];
23576 if (this.version !== VERSION) {
23577 throw new UnsupportedError(`Version ${this.version} of the one-pass signature packet is unsupported.`);
23578 }
23579
23580 // A one-octet signature type. Signature types are described in
23581 // Section 5.2.1.
23582 this.signatureType = bytes[mypos++];
23583
23584 // A one-octet number describing the hash algorithm used.
23585 this.hashAlgorithm = bytes[mypos++];
23586
23587 // A one-octet number describing the public-key algorithm used.
23588 this.publicKeyAlgorithm = bytes[mypos++];
23589
23590 // An eight-octet number holding the Key ID of the signing key.
23591 this.issuerKeyID = new KeyID();
23592 this.issuerKeyID.read(bytes.subarray(mypos, mypos + 8));
23593 mypos += 8;
23594
23595 // A one-octet number holding a flag showing whether the signature
23596 // is nested. A zero value indicates that the next packet is
23597 // another One-Pass Signature packet that describes another
23598 // signature to be applied to the same message data.
23599 this.flags = bytes[mypos++];
23600 return this;
23601 }
23602
23603 /**
23604 * creates a string representation of a one-pass signature packet
23605 * @returns {Uint8Array} A Uint8Array representation of a one-pass signature packet.
23606 */
23607 write() {
23608 const start = new Uint8Array([VERSION, this.signatureType, this.hashAlgorithm, this.publicKeyAlgorithm]);
23609
23610 const end = new Uint8Array([this.flags]);
23611
23612 return util.concatUint8Array([start, this.issuerKeyID.write(), end]);
23613 }
23614
23615 calculateTrailer(...args) {
23616 return fromAsync(async () => SignaturePacket.prototype.calculateTrailer.apply(await this.correspondingSig, args));
23617 }
23618
23619 async verify() {
23620 const correspondingSig = await this.correspondingSig;
23621 if (!correspondingSig || correspondingSig.constructor.tag !== enums.packet.signature) {
23622 throw new Error('Corresponding signature packet missing');
23623 }
23624 if (
23625 correspondingSig.signatureType !== this.signatureType ||
23626 correspondingSig.hashAlgorithm !== this.hashAlgorithm ||
23627 correspondingSig.publicKeyAlgorithm !== this.publicKeyAlgorithm ||
23628 !correspondingSig.issuerKeyID.equals(this.issuerKeyID)
23629 ) {
23630 throw new Error('Corresponding signature packet does not match one-pass signature packet');
23631 }
23632 correspondingSig.hashed = this.hashed;
23633 return correspondingSig.verify.apply(correspondingSig, arguments);
23634 }
23635}
23636
23637OnePassSignaturePacket.prototype.hash = SignaturePacket.prototype.hash;
23638OnePassSignaturePacket.prototype.toHash = SignaturePacket.prototype.toHash;
23639OnePassSignaturePacket.prototype.toSign = SignaturePacket.prototype.toSign;
23640
23641/**
23642 * Instantiate a new packet given its tag
23643 * @function newPacketFromTag
23644 * @param {module:enums.packet} tag - Property value from {@link module:enums.packet}
23645 * @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
23646 * @returns {Object} New packet object with type based on tag
23647 * @throws {Error|UnsupportedError} for disallowed or unknown packets
23648 */
23649function newPacketFromTag(tag, allowedPackets) {
23650 if (!allowedPackets[tag]) {
23651 // distinguish between disallowed packets and unknown ones
23652 let packetType;
23653 try {
23654 packetType = enums.read(enums.packet, tag);
23655 } catch (e) {
23656 throw new UnsupportedError(`Unknown packet type with tag: ${tag}`);
23657 }
23658 throw new Error(`Packet not allowed in this context: ${packetType}`);
23659 }
23660 return new allowedPackets[tag]();
23661}
23662
23663/**
23664 * This class represents a list of openpgp packets.
23665 * Take care when iterating over it - the packets themselves
23666 * are stored as numerical indices.
23667 * @extends Array
23668 */
23669class PacketList extends Array {
23670 /**
23671 * Parses the given binary data and returns a list of packets.
23672 * Equivalent to calling `read` on an empty PacketList instance.
23673 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - binary data to parse
23674 * @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
23675 * @param {Object} [config] - full configuration, defaults to openpgp.config
23676 * @returns {PacketList} parsed list of packets
23677 * @throws on parsing errors
23678 * @async
23679 */
23680 static async fromBinary(bytes, allowedPackets, config = defaultConfig) {
23681 const packets = new PacketList();
23682 await packets.read(bytes, allowedPackets, config);
23683 return packets;
23684 }
23685
23686 /**
23687 * Reads a stream of binary data and interprets it as a list of packets.
23688 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - binary data to parse
23689 * @param {Object} allowedPackets - mapping where keys are allowed packet tags, pointing to their Packet class
23690 * @param {Object} [config] - full configuration, defaults to openpgp.config
23691 * @throws on parsing errors
23692 * @async
23693 */
23694 async read(bytes, allowedPackets, config = defaultConfig) {
23695 this.stream = transformPair(bytes, async (readable, writable) => {
23696 const writer = getWriter(writable);
23697 try {
23698 while (true) {
23699 await writer.ready;
23700 const done = await readPackets(readable, async parsed => {
23701 try {
23702 if (parsed.tag === enums.packet.marker || parsed.tag === enums.packet.trust) {
23703 // According to the spec, these packet types should be ignored and not cause parsing errors, even if not esplicitly allowed:
23704 // - Marker packets MUST be ignored when received: https://github.com/openpgpjs/openpgpjs/issues/1145
23705 // - Trust packets SHOULD be ignored outside of keyrings (unsupported): https://datatracker.ietf.org/doc/html/rfc4880#section-5.10
23706 return;
23707 }
23708 const packet = newPacketFromTag(parsed.tag, allowedPackets);
23709 packet.packets = new PacketList();
23710 packet.fromStream = util.isStream(parsed.packet);
23711 await packet.read(parsed.packet, config);
23712 await writer.write(packet);
23713 } catch (e) {
23714 const throwUnsupportedError = !config.ignoreUnsupportedPackets && e instanceof UnsupportedError;
23715 const throwMalformedError = !config.ignoreMalformedPackets && !(e instanceof UnsupportedError);
23716 if (throwUnsupportedError || throwMalformedError || supportsStreaming(parsed.tag)) {
23717 // The packets that support streaming are the ones that contain message data.
23718 // Those are also the ones we want to be more strict about and throw on parse errors
23719 // (since we likely cannot process the message without these packets anyway).
23720 await writer.abort(e);
23721 } else {
23722 const unparsedPacket = new UnparseablePacket(parsed.tag, parsed.packet);
23723 await writer.write(unparsedPacket);
23724 }
23725 util.printDebugError(e);
23726 }
23727 });
23728 if (done) {
23729 await writer.ready;
23730 await writer.close();
23731 return;
23732 }
23733 }
23734 } catch (e) {
23735 await writer.abort(e);
23736 }
23737 });
23738
23739 // Wait until first few packets have been read
23740 const reader = getReader(this.stream);
23741 while (true) {
23742 const { done, value } = await reader.read();
23743 if (!done) {
23744 this.push(value);
23745 } else {
23746 this.stream = null;
23747 }
23748 if (done || supportsStreaming(value.constructor.tag)) {
23749 break;
23750 }
23751 }
23752 reader.releaseLock();
23753 }
23754
23755 /**
23756 * Creates a binary representation of openpgp objects contained within the
23757 * class instance.
23758 * @returns {Uint8Array} A Uint8Array containing valid openpgp packets.
23759 */
23760 write() {
23761 const arr = [];
23762
23763 for (let i = 0; i < this.length; i++) {
23764 const tag = this[i] instanceof UnparseablePacket ? this[i].tag : this[i].constructor.tag;
23765 const packetbytes = this[i].write();
23766 if (util.isStream(packetbytes) && supportsStreaming(this[i].constructor.tag)) {
23767 let buffer = [];
23768 let bufferLength = 0;
23769 const minLength = 512;
23770 arr.push(writeTag(tag));
23771 arr.push(transform(packetbytes, value => {
23772 buffer.push(value);
23773 bufferLength += value.length;
23774 if (bufferLength >= minLength) {
23775 const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30);
23776 const chunkSize = 2 ** powerOf2;
23777 const bufferConcat = util.concat([writePartialLength(powerOf2)].concat(buffer));
23778 buffer = [bufferConcat.subarray(1 + chunkSize)];
23779 bufferLength = buffer[0].length;
23780 return bufferConcat.subarray(0, 1 + chunkSize);
23781 }
23782 }, () => util.concat([writeSimpleLength(bufferLength)].concat(buffer))));
23783 } else {
23784 if (util.isStream(packetbytes)) {
23785 let length = 0;
23786 arr.push(transform(clone(packetbytes), value => {
23787 length += value.length;
23788 }, () => writeHeader(tag, length)));
23789 } else {
23790 arr.push(writeHeader(tag, packetbytes.length));
23791 }
23792 arr.push(packetbytes);
23793 }
23794 }
23795
23796 return util.concat(arr);
23797 }
23798
23799 /**
23800 * Creates a new PacketList with all packets matching the given tag(s)
23801 * @param {...module:enums.packet} tags - packet tags to look for
23802 * @returns {PacketList}
23803 */
23804 filterByTag(...tags) {
23805 const filtered = new PacketList();
23806
23807 const handle = tag => packetType => tag === packetType;
23808
23809 for (let i = 0; i < this.length; i++) {
23810 if (tags.some(handle(this[i].constructor.tag))) {
23811 filtered.push(this[i]);
23812 }
23813 }
23814
23815 return filtered;
23816 }
23817
23818 /**
23819 * Traverses packet list and returns first packet with matching tag
23820 * @param {module:enums.packet} tag - The packet tag
23821 * @returns {Packet|undefined}
23822 */
23823 findPacket(tag) {
23824 return this.find(packet => packet.constructor.tag === tag);
23825 }
23826
23827 /**
23828 * Find indices of packets with the given tag(s)
23829 * @param {...module:enums.packet} tags - packet tags to look for
23830 * @returns {Integer[]} packet indices
23831 */
23832 indexOfTag(...tags) {
23833 const tagIndex = [];
23834 const that = this;
23835
23836 const handle = tag => packetType => tag === packetType;
23837
23838 for (let i = 0; i < this.length; i++) {
23839 if (tags.some(handle(that[i].constructor.tag))) {
23840 tagIndex.push(i);
23841 }
23842 }
23843 return tagIndex;
23844 }
23845}
23846
23847// GPG4Browsers - An OpenPGP implementation in javascript
23848
23849// A Compressed Data packet can contain the following packet types
23850const allowedPackets = /*#__PURE__*/ util.constructAllowedPackets([
23851 LiteralDataPacket,
23852 OnePassSignaturePacket,
23853 SignaturePacket
23854]);
23855
23856/**
23857 * Implementation of the Compressed Data Packet (Tag 8)
23858 *
23859 * {@link https://tools.ietf.org/html/rfc4880#section-5.6|RFC4880 5.6}:
23860 * The Compressed Data packet contains compressed data. Typically,
23861 * this packet is found as the contents of an encrypted packet, or following
23862 * a Signature or One-Pass Signature packet, and contains a literal data packet.
23863 */
23864class CompressedDataPacket {
23865 static get tag() {
23866 return enums.packet.compressedData;
23867 }
23868
23869 /**
23870 * @param {Object} [config] - Full configuration, defaults to openpgp.config
23871 */
23872 constructor(config = defaultConfig) {
23873 /**
23874 * List of packets
23875 * @type {PacketList}
23876 */
23877 this.packets = null;
23878 /**
23879 * Compression algorithm
23880 * @type {enums.compression}
23881 */
23882 this.algorithm = config.preferredCompressionAlgorithm;
23883
23884 /**
23885 * Compressed packet data
23886 * @type {Uint8Array | ReadableStream<Uint8Array>}
23887 */
23888 this.compressed = null;
23889
23890 /**
23891 * zip/zlib compression level, between 1 and 9
23892 */
23893 this.deflateLevel = config.deflateLevel;
23894 }
23895
23896 /**
23897 * Parsing function for the packet.
23898 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes - Payload of a tag 8 packet
23899 * @param {Object} [config] - Full configuration, defaults to openpgp.config
23900 */
23901 async read(bytes, config = defaultConfig) {
23902 await parse(bytes, async reader => {
23903
23904 // One octet that gives the algorithm used to compress the packet.
23905 this.algorithm = await reader.readByte();
23906
23907 // Compressed data, which makes up the remainder of the packet.
23908 this.compressed = reader.remainder();
23909
23910 await this.decompress(config);
23911 });
23912 }
23913
23914
23915 /**
23916 * Return the compressed packet.
23917 * @returns {Uint8Array | ReadableStream<Uint8Array>} Binary compressed packet.
23918 */
23919 write() {
23920 if (this.compressed === null) {
23921 this.compress();
23922 }
23923
23924 return util.concat([new Uint8Array([this.algorithm]), this.compressed]);
23925 }
23926
23927
23928 /**
23929 * Decompression method for decompressing the compressed data
23930 * read by read_packet
23931 * @param {Object} [config] - Full configuration, defaults to openpgp.config
23932 */
23933 async decompress(config = defaultConfig) {
23934 const compressionName = enums.read(enums.compression, this.algorithm);
23935 const decompressionFn = decompress_fns[compressionName];
23936 if (!decompressionFn) {
23937 throw new Error(`${compressionName} decompression not supported`);
23938 }
23939
23940 this.packets = await PacketList.fromBinary(decompressionFn(this.compressed), allowedPackets, config);
23941 }
23942
23943 /**
23944 * Compress the packet data (member decompressedData)
23945 */
23946 compress() {
23947 const compressionName = enums.read(enums.compression, this.algorithm);
23948 const compressionFn = compress_fns[compressionName];
23949 if (!compressionFn) {
23950 throw new Error(`${compressionName} compression not supported`);
23951 }
23952
23953 this.compressed = compressionFn(this.packets.write(), this.deflateLevel);
23954 }
23955}
23956
23957//////////////////////////
23958// //
23959// Helper functions //
23960// //
23961//////////////////////////
23962
23963
23964const nodeZlib = util.getNodeZlib();
23965
23966function uncompressed(data) {
23967 return data;
23968}
23969
23970function node_zlib(func, create, options = {}) {
23971 return function (data) {
23972 if (!util.isStream(data) || isArrayStream(data)) {
23973 return fromAsync(() => readToEnd(data).then(data => {
23974 return new Promise((resolve, reject) => {
23975 func(data, options, (err, result) => {
23976 if (err) return reject(err);
23977 resolve(result);
23978 });
23979 });
23980 }));
23981 }
23982 return nodeToWeb(webToNode(data).pipe(create(options)));
23983 };
23984}
23985
23986function pako_zlib(constructor, options = {}) {
23987 return function(data) {
23988 const obj = new constructor(options);
23989 return transform(data, value => {
23990 if (value.length) {
23991 obj.push(value, Z_SYNC_FLUSH);
23992 return obj.result;
23993 }
23994 }, () => {
23995 if (constructor === Deflate) {
23996 obj.push([], Z_FINISH);
23997 return obj.result;
23998 }
23999 });
24000 };
24001}
24002
24003function bzip2(func) {
24004 return function(data) {
24005 return fromAsync(async () => func(await readToEnd(data)));
24006 };
24007}
24008
24009const compress_fns = nodeZlib ? {
24010 zip: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflateRaw, nodeZlib.createDeflateRaw, { level })(compressed),
24011 zlib: /*#__PURE__*/ (compressed, level) => node_zlib(nodeZlib.deflate, nodeZlib.createDeflate, { level })(compressed)
24012} : {
24013 zip: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { raw: true, level })(compressed),
24014 zlib: /*#__PURE__*/ (compressed, level) => pako_zlib(Deflate, { level })(compressed)
24015};
24016
24017const decompress_fns = nodeZlib ? {
24018 uncompressed: uncompressed,
24019 zip: /*#__PURE__*/ node_zlib(nodeZlib.inflateRaw, nodeZlib.createInflateRaw),
24020 zlib: /*#__PURE__*/ node_zlib(nodeZlib.inflate, nodeZlib.createInflate),
24021 bzip2: /*#__PURE__*/ bzip2(lib_4)
24022} : {
24023 uncompressed: uncompressed,
24024 zip: /*#__PURE__*/ pako_zlib(Inflate, { raw: true }),
24025 zlib: /*#__PURE__*/ pako_zlib(Inflate),
24026 bzip2: /*#__PURE__*/ bzip2(lib_4)
24027};
24028
24029// GPG4Browsers - An OpenPGP implementation in javascript
24030
24031// A SEIP packet can contain the following packet types
24032const allowedPackets$1 = /*#__PURE__*/ util.constructAllowedPackets([
24033 LiteralDataPacket,
24034 CompressedDataPacket,
24035 OnePassSignaturePacket,
24036 SignaturePacket
24037]);
24038
24039const VERSION$1 = 1; // A one-octet version number of the data packet.
24040
24041/**
24042 * Implementation of the Sym. Encrypted Integrity Protected Data Packet (Tag 18)
24043 *
24044 * {@link https://tools.ietf.org/html/rfc4880#section-5.13|RFC4880 5.13}:
24045 * The Symmetrically Encrypted Integrity Protected Data packet is
24046 * a variant of the Symmetrically Encrypted Data packet. It is a new feature
24047 * created for OpenPGP that addresses the problem of detecting a modification to
24048 * encrypted data. It is used in combination with a Modification Detection Code
24049 * packet.
24050 */
24051class SymEncryptedIntegrityProtectedDataPacket {
24052 static get tag() {
24053 return enums.packet.symEncryptedIntegrityProtectedData;
24054 }
24055
24056 constructor() {
24057 this.version = VERSION$1;
24058 this.encrypted = null;
24059 this.packets = null;
24060 }
24061
24062 async read(bytes) {
24063 await parse(bytes, async reader => {
24064 const version = await reader.readByte();
24065 // - A one-octet version number. The only currently defined value is 1.
24066 if (version !== VERSION$1) {
24067 throw new UnsupportedError(`Version ${version} of the SEIP packet is unsupported.`);
24068 }
24069
24070 // - Encrypted data, the output of the selected symmetric-key cipher
24071 // operating in Cipher Feedback mode with shift amount equal to the
24072 // block size of the cipher (CFB-n where n is the block size).
24073 this.encrypted = reader.remainder();
24074 });
24075 }
24076
24077 write() {
24078 return util.concat([new Uint8Array([VERSION$1]), this.encrypted]);
24079 }
24080
24081 /**
24082 * Encrypt the payload in the packet.
24083 * @param {enums.symmetric} sessionKeyAlgorithm - The symmetric encryption algorithm to use
24084 * @param {Uint8Array} key - The key of cipher blocksize length to be used
24085 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24086 * @returns {Promise<Boolean>}
24087 * @throws {Error} on encryption failure
24088 * @async
24089 */
24090 async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
24091 const { blockSize } = mod.getCipher(sessionKeyAlgorithm);
24092
24093 let bytes = this.packets.write();
24094 if (isArrayStream(bytes)) bytes = await readToEnd(bytes);
24095 const prefix = await mod.getPrefixRandom(sessionKeyAlgorithm);
24096 const mdc = new Uint8Array([0xD3, 0x14]); // modification detection code packet
24097
24098 const tohash = util.concat([prefix, bytes, mdc]);
24099 const hash = await mod.hash.sha1(passiveClone(tohash));
24100 const plaintext = util.concat([tohash, hash]);
24101
24102 this.encrypted = await mod.mode.cfb.encrypt(sessionKeyAlgorithm, key, plaintext, new Uint8Array(blockSize), config);
24103 return true;
24104 }
24105
24106 /**
24107 * Decrypts the encrypted data contained in the packet.
24108 * @param {enums.symmetric} sessionKeyAlgorithm - The selected symmetric encryption algorithm to be used
24109 * @param {Uint8Array} key - The key of cipher blocksize length to be used
24110 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24111 * @returns {Promise<Boolean>}
24112 * @throws {Error} on decryption failure
24113 * @async
24114 */
24115 async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
24116 const { blockSize } = mod.getCipher(sessionKeyAlgorithm);
24117 let encrypted = clone(this.encrypted);
24118 if (isArrayStream(encrypted)) encrypted = await readToEnd(encrypted);
24119 const decrypted = await mod.mode.cfb.decrypt(sessionKeyAlgorithm, key, encrypted, new Uint8Array(blockSize));
24120
24121 // there must be a modification detection code packet as the
24122 // last packet and everything gets hashed except the hash itself
24123 const realHash = slice(passiveClone(decrypted), -20);
24124 const tohash = slice(decrypted, 0, -20);
24125 const verifyHash = Promise.all([
24126 readToEnd(await mod.hash.sha1(passiveClone(tohash))),
24127 readToEnd(realHash)
24128 ]).then(([hash, mdc]) => {
24129 if (!util.equalsUint8Array(hash, mdc)) {
24130 throw new Error('Modification detected.');
24131 }
24132 return new Uint8Array();
24133 });
24134 const bytes = slice(tohash, blockSize + 2); // Remove random prefix
24135 let packetbytes = slice(bytes, 0, -2); // Remove MDC packet
24136 packetbytes = concat([packetbytes, fromAsync(() => verifyHash)]);
24137 if (!util.isStream(encrypted) || !config.allowUnauthenticatedStream) {
24138 packetbytes = await readToEnd(packetbytes);
24139 }
24140 this.packets = await PacketList.fromBinary(packetbytes, allowedPackets$1, config);
24141 return true;
24142 }
24143}
24144
24145// OpenPGP.js - An OpenPGP implementation in javascript
24146
24147// An AEAD-encrypted Data packet can contain the following packet types
24148const allowedPackets$2 = /*#__PURE__*/ util.constructAllowedPackets([
24149 LiteralDataPacket,
24150 CompressedDataPacket,
24151 OnePassSignaturePacket,
24152 SignaturePacket
24153]);
24154
24155const VERSION$2 = 1; // A one-octet version number of the data packet.
24156
24157/**
24158 * Implementation of the Symmetrically Encrypted Authenticated Encryption with
24159 * Additional Data (AEAD) Protected Data Packet
24160 *
24161 * {@link https://tools.ietf.org/html/draft-ford-openpgp-format-00#section-2.1}:
24162 * AEAD Protected Data Packet
24163 */
24164class AEADEncryptedDataPacket {
24165 static get tag() {
24166 return enums.packet.aeadEncryptedData;
24167 }
24168
24169 constructor() {
24170 this.version = VERSION$2;
24171 /** @type {enums.symmetric} */
24172 this.cipherAlgorithm = null;
24173 /** @type {enums.aead} */
24174 this.aeadAlgorithm = enums.aead.eax;
24175 this.chunkSizeByte = null;
24176 this.iv = null;
24177 this.encrypted = null;
24178 this.packets = null;
24179 }
24180
24181 /**
24182 * Parse an encrypted payload of bytes in the order: version, IV, ciphertext (see specification)
24183 * @param {Uint8Array | ReadableStream<Uint8Array>} bytes
24184 * @throws {Error} on parsing failure
24185 */
24186 async read(bytes) {
24187 await parse(bytes, async reader => {
24188 const version = await reader.readByte();
24189 if (version !== VERSION$2) { // The only currently defined value is 1.
24190 throw new UnsupportedError(`Version ${version} of the AEAD-encrypted data packet is not supported.`);
24191 }
24192 this.cipherAlgorithm = await reader.readByte();
24193 this.aeadAlgorithm = await reader.readByte();
24194 this.chunkSizeByte = await reader.readByte();
24195
24196 const mode = mod.getAEADMode(this.aeadAlgorithm);
24197 this.iv = await reader.readBytes(mode.ivLength);
24198 this.encrypted = reader.remainder();
24199 });
24200 }
24201
24202 /**
24203 * Write the encrypted payload of bytes in the order: version, IV, ciphertext (see specification)
24204 * @returns {Uint8Array | ReadableStream<Uint8Array>} The encrypted payload.
24205 */
24206 write() {
24207 return util.concat([new Uint8Array([this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte]), this.iv, this.encrypted]);
24208 }
24209
24210 /**
24211 * Decrypt the encrypted payload.
24212 * @param {enums.symmetric} sessionKeyAlgorithm - The session key's cipher algorithm
24213 * @param {Uint8Array} key - The session key used to encrypt the payload
24214 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24215 * @throws {Error} if decryption was not successful
24216 * @async
24217 */
24218 async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
24219 this.packets = await PacketList.fromBinary(
24220 await this.crypt('decrypt', key, clone(this.encrypted)),
24221 allowedPackets$2,
24222 config
24223 );
24224 }
24225
24226 /**
24227 * Encrypt the packet payload.
24228 * @param {enums.symmetric} sessionKeyAlgorithm - The session key's cipher algorithm
24229 * @param {Uint8Array} key - The session key used to encrypt the payload
24230 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24231 * @throws {Error} if encryption was not successful
24232 * @async
24233 */
24234 async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
24235 this.cipherAlgorithm = sessionKeyAlgorithm;
24236
24237 const { ivLength } = mod.getAEADMode(this.aeadAlgorithm);
24238 this.iv = await mod.random.getRandomBytes(ivLength); // generate new random IV
24239 this.chunkSizeByte = config.aeadChunkSizeByte;
24240 const data = this.packets.write();
24241 this.encrypted = await this.crypt('encrypt', key, data);
24242 }
24243
24244 /**
24245 * En/decrypt the payload.
24246 * @param {encrypt|decrypt} fn - Whether to encrypt or decrypt
24247 * @param {Uint8Array} key - The session key used to en/decrypt the payload
24248 * @param {Uint8Array | ReadableStream<Uint8Array>} data - The data to en/decrypt
24249 * @returns {Promise<Uint8Array | ReadableStream<Uint8Array>>}
24250 * @async
24251 */
24252 async crypt(fn, key, data) {
24253 const mode = mod.getAEADMode(this.aeadAlgorithm);
24254 const modeInstance = await mode(this.cipherAlgorithm, key);
24255 const tagLengthIfDecrypting = fn === 'decrypt' ? mode.tagLength : 0;
24256 const tagLengthIfEncrypting = fn === 'encrypt' ? mode.tagLength : 0;
24257 const chunkSize = 2 ** (this.chunkSizeByte + 6) + tagLengthIfDecrypting; // ((uint64_t)1 << (c + 6))
24258 const adataBuffer = new ArrayBuffer(21);
24259 const adataArray = new Uint8Array(adataBuffer, 0, 13);
24260 const adataTagArray = new Uint8Array(adataBuffer);
24261 const adataView = new DataView(adataBuffer);
24262 const chunkIndexArray = new Uint8Array(adataBuffer, 5, 8);
24263 adataArray.set([0xC0 | AEADEncryptedDataPacket.tag, this.version, this.cipherAlgorithm, this.aeadAlgorithm, this.chunkSizeByte], 0);
24264 let chunkIndex = 0;
24265 let latestPromise = Promise.resolve();
24266 let cryptedBytes = 0;
24267 let queuedBytes = 0;
24268 const iv = this.iv;
24269 return transformPair(data, async (readable, writable) => {
24270 if (util.isStream(readable) !== 'array') {
24271 const buffer = new TransformStream({}, {
24272 highWaterMark: util.getHardwareConcurrency() * 2 ** (this.chunkSizeByte + 6),
24273 size: array => array.length
24274 });
24275 pipe(buffer.readable, writable);
24276 writable = buffer.writable;
24277 }
24278 const reader = getReader(readable);
24279 const writer = getWriter(writable);
24280 try {
24281 while (true) {
24282 let chunk = await reader.readBytes(chunkSize + tagLengthIfDecrypting) || new Uint8Array();
24283 const finalChunk = chunk.subarray(chunk.length - tagLengthIfDecrypting);
24284 chunk = chunk.subarray(0, chunk.length - tagLengthIfDecrypting);
24285 let cryptedPromise;
24286 let done;
24287 if (!chunkIndex || chunk.length) {
24288 reader.unshift(finalChunk);
24289 cryptedPromise = modeInstance[fn](chunk, mode.getNonce(iv, chunkIndexArray), adataArray);
24290 queuedBytes += chunk.length - tagLengthIfDecrypting + tagLengthIfEncrypting;
24291 } else {
24292 // After the last chunk, we either encrypt a final, empty
24293 // data chunk to get the final authentication tag or
24294 // validate that final authentication tag.
24295 adataView.setInt32(13 + 4, cryptedBytes); // Should be setInt64(13, ...)
24296 cryptedPromise = modeInstance[fn](finalChunk, mode.getNonce(iv, chunkIndexArray), adataTagArray);
24297 queuedBytes += tagLengthIfEncrypting;
24298 done = true;
24299 }
24300 cryptedBytes += chunk.length - tagLengthIfDecrypting;
24301 // eslint-disable-next-line no-loop-func
24302 latestPromise = latestPromise.then(() => cryptedPromise).then(async crypted => {
24303 await writer.ready;
24304 await writer.write(crypted);
24305 queuedBytes -= crypted.length;
24306 }).catch(err => writer.abort(err));
24307 if (done || queuedBytes > writer.desiredSize) {
24308 await latestPromise; // Respect backpressure
24309 }
24310 if (!done) {
24311 adataView.setInt32(5 + 4, ++chunkIndex); // Should be setInt64(5, ...)
24312 } else {
24313 await writer.close();
24314 break;
24315 }
24316 }
24317 } catch (e) {
24318 await writer.abort(e);
24319 }
24320 });
24321 }
24322}
24323
24324// GPG4Browsers - An OpenPGP implementation in javascript
24325
24326const VERSION$3 = 3;
24327
24328/**
24329 * Public-Key Encrypted Session Key Packets (Tag 1)
24330 *
24331 * {@link https://tools.ietf.org/html/rfc4880#section-5.1|RFC4880 5.1}:
24332 * A Public-Key Encrypted Session Key packet holds the session key
24333 * used to encrypt a message. Zero or more Public-Key Encrypted Session Key
24334 * packets and/or Symmetric-Key Encrypted Session Key packets may precede a
24335 * Symmetrically Encrypted Data Packet, which holds an encrypted message. The
24336 * message is encrypted with the session key, and the session key is itself
24337 * encrypted and stored in the Encrypted Session Key packet(s). The
24338 * Symmetrically Encrypted Data Packet is preceded by one Public-Key Encrypted
24339 * Session Key packet for each OpenPGP key to which the message is encrypted.
24340 * The recipient of the message finds a session key that is encrypted to their
24341 * public key, decrypts the session key, and then uses the session key to
24342 * decrypt the message.
24343 */
24344class PublicKeyEncryptedSessionKeyPacket {
24345 static get tag() {
24346 return enums.packet.publicKeyEncryptedSessionKey;
24347 }
24348
24349 constructor() {
24350 this.version = 3;
24351
24352 this.publicKeyID = new KeyID();
24353 this.publicKeyAlgorithm = null;
24354
24355 this.sessionKey = null;
24356 /**
24357 * Algorithm to encrypt the message with
24358 * @type {enums.symmetric}
24359 */
24360 this.sessionKeyAlgorithm = null;
24361
24362 /** @type {Object} */
24363 this.encrypted = {};
24364 }
24365
24366 /**
24367 * Parsing function for a publickey encrypted session key packet (tag 1).
24368 *
24369 * @param {Uint8Array} bytes - Payload of a tag 1 packet
24370 */
24371 read(bytes) {
24372 this.version = bytes[0];
24373 if (this.version !== VERSION$3) {
24374 throw new UnsupportedError(`Version ${this.version} of the PKESK packet is unsupported.`);
24375 }
24376 this.publicKeyID.read(bytes.subarray(1, bytes.length));
24377 this.publicKeyAlgorithm = bytes[9];
24378 this.encrypted = mod.parseEncSessionKeyParams(this.publicKeyAlgorithm, bytes.subarray(10));
24379 }
24380
24381 /**
24382 * Create a binary representation of a tag 1 packet
24383 *
24384 * @returns {Uint8Array} The Uint8Array representation.
24385 */
24386 write() {
24387 const arr = [
24388 new Uint8Array([this.version]),
24389 this.publicKeyID.write(),
24390 new Uint8Array([this.publicKeyAlgorithm]),
24391 mod.serializeParams(this.publicKeyAlgorithm, this.encrypted)
24392 ];
24393
24394 return util.concatUint8Array(arr);
24395 }
24396
24397 /**
24398 * Encrypt session key packet
24399 * @param {PublicKeyPacket} key - Public key
24400 * @throws {Error} if encryption failed
24401 * @async
24402 */
24403 async encrypt(key) {
24404 const data = util.concatUint8Array([
24405 new Uint8Array([enums.write(enums.symmetric, this.sessionKeyAlgorithm)]),
24406 this.sessionKey,
24407 util.writeChecksum(this.sessionKey)
24408 ]);
24409 const algo = enums.write(enums.publicKey, this.publicKeyAlgorithm);
24410 this.encrypted = await mod.publicKeyEncrypt(
24411 algo, key.publicParams, data, key.getFingerprintBytes());
24412 }
24413
24414 /**
24415 * Decrypts the session key (only for public key encrypted session key packets (tag 1)
24416 * @param {SecretKeyPacket} key - decrypted private key
24417 * @param {Object} [randomSessionKey] - Bogus session key to use in case of sensitive decryption error, or if the decrypted session key is of a different type/size.
24418 * This is needed for constant-time processing. Expected object of the form: { sessionKey: Uint8Array, sessionKeyAlgorithm: enums.symmetric }
24419 * @throws {Error} if decryption failed, unless `randomSessionKey` is given
24420 * @async
24421 */
24422 async decrypt(key, randomSessionKey) {
24423 // check that session key algo matches the secret key algo
24424 if (this.publicKeyAlgorithm !== key.algorithm) {
24425 throw new Error('Decryption error');
24426 }
24427
24428 const randomPayload = randomSessionKey ? util.concatUint8Array([
24429 new Uint8Array([randomSessionKey.sessionKeyAlgorithm]),
24430 randomSessionKey.sessionKey,
24431 util.writeChecksum(randomSessionKey.sessionKey)
24432 ]) : null;
24433 const decoded = await mod.publicKeyDecrypt(this.publicKeyAlgorithm, key.publicParams, key.privateParams, this.encrypted, key.getFingerprintBytes(), randomPayload);
24434 const symmetricAlgoByte = decoded[0];
24435 const sessionKey = decoded.subarray(1, decoded.length - 2);
24436 const checksum = decoded.subarray(decoded.length - 2);
24437 const computedChecksum = util.writeChecksum(sessionKey);
24438 const isValidChecksum = computedChecksum[0] === checksum[0] & computedChecksum[1] === checksum[1];
24439
24440 if (randomSessionKey) {
24441 // We must not leak info about the validity of the decrypted checksum or cipher algo.
24442 // The decrypted session key must be of the same algo and size as the random session key, otherwise we discard it and use the random data.
24443 const isValidPayload = isValidChecksum & symmetricAlgoByte === randomSessionKey.sessionKeyAlgorithm & sessionKey.length === randomSessionKey.sessionKey.length;
24444 this.sessionKeyAlgorithm = util.selectUint8(isValidPayload, symmetricAlgoByte, randomSessionKey.sessionKeyAlgorithm);
24445 this.sessionKey = util.selectUint8Array(isValidPayload, sessionKey, randomSessionKey.sessionKey);
24446
24447 } else {
24448 const isValidPayload = isValidChecksum && enums.read(enums.symmetric, symmetricAlgoByte);
24449 if (isValidPayload) {
24450 this.sessionKey = sessionKey;
24451 this.sessionKeyAlgorithm = symmetricAlgoByte;
24452 } else {
24453 throw new Error('Decryption error');
24454 }
24455 }
24456 }
24457}
24458
24459// GPG4Browsers - An OpenPGP implementation in javascript
24460
24461class S2K {
24462 /**
24463 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24464 */
24465 constructor(config = defaultConfig) {
24466 /**
24467 * Hash function identifier, or 0 for gnu-dummy keys
24468 * @type {module:enums.hash | 0}
24469 */
24470 this.algorithm = enums.hash.sha256;
24471 /**
24472 * enums.s2k identifier or 'gnu-dummy'
24473 * @type {String}
24474 */
24475 this.type = 'iterated';
24476 /** @type {Integer} */
24477 this.c = config.s2kIterationCountByte;
24478 /** Eight bytes of salt in a binary string.
24479 * @type {Uint8Array}
24480 */
24481 this.salt = null;
24482 }
24483
24484 getCount() {
24485 // Exponent bias, defined in RFC4880
24486 const expbias = 6;
24487
24488 return (16 + (this.c & 15)) << ((this.c >> 4) + expbias);
24489 }
24490
24491 /**
24492 * Parsing function for a string-to-key specifier ({@link https://tools.ietf.org/html/rfc4880#section-3.7|RFC 4880 3.7}).
24493 * @param {Uint8Array} bytes - Payload of string-to-key specifier
24494 * @returns {Integer} Actual length of the object.
24495 */
24496 read(bytes) {
24497 let i = 0;
24498 this.type = enums.read(enums.s2k, bytes[i++]);
24499 this.algorithm = bytes[i++];
24500
24501 switch (this.type) {
24502 case 'simple':
24503 break;
24504
24505 case 'salted':
24506 this.salt = bytes.subarray(i, i + 8);
24507 i += 8;
24508 break;
24509
24510 case 'iterated':
24511 this.salt = bytes.subarray(i, i + 8);
24512 i += 8;
24513
24514 // Octet 10: count, a one-octet, coded value
24515 this.c = bytes[i++];
24516 break;
24517
24518 case 'gnu':
24519 if (util.uint8ArrayToString(bytes.subarray(i, i + 3)) === 'GNU') {
24520 i += 3; // GNU
24521 const gnuExtType = 1000 + bytes[i++];
24522 if (gnuExtType === 1001) {
24523 this.type = 'gnu-dummy';
24524 // GnuPG extension mode 1001 -- don't write secret key at all
24525 } else {
24526 throw new Error('Unknown s2k gnu protection mode.');
24527 }
24528 } else {
24529 throw new Error('Unknown s2k type.');
24530 }
24531 break;
24532
24533 default:
24534 throw new Error('Unknown s2k type.');
24535 }
24536
24537 return i;
24538 }
24539
24540 /**
24541 * Serializes s2k information
24542 * @returns {Uint8Array} Binary representation of s2k.
24543 */
24544 write() {
24545 if (this.type === 'gnu-dummy') {
24546 return new Uint8Array([101, 0, ...util.stringToUint8Array('GNU'), 1]);
24547 }
24548 const arr = [new Uint8Array([enums.write(enums.s2k, this.type), this.algorithm])];
24549
24550 switch (this.type) {
24551 case 'simple':
24552 break;
24553 case 'salted':
24554 arr.push(this.salt);
24555 break;
24556 case 'iterated':
24557 arr.push(this.salt);
24558 arr.push(new Uint8Array([this.c]));
24559 break;
24560 case 'gnu':
24561 throw new Error('GNU s2k type not supported.');
24562 default:
24563 throw new Error('Unknown s2k type.');
24564 }
24565
24566 return util.concatUint8Array(arr);
24567 }
24568
24569 /**
24570 * Produces a key using the specified passphrase and the defined
24571 * hashAlgorithm
24572 * @param {String} passphrase - Passphrase containing user input
24573 * @returns {Promise<Uint8Array>} Produced key with a length corresponding to.
24574 * hashAlgorithm hash length
24575 * @async
24576 */
24577 async produceKey(passphrase, numBytes) {
24578 passphrase = util.encodeUTF8(passphrase);
24579
24580 const arr = [];
24581 let rlength = 0;
24582
24583 let prefixlen = 0;
24584 while (rlength < numBytes) {
24585 let toHash;
24586 switch (this.type) {
24587 case 'simple':
24588 toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]);
24589 break;
24590 case 'salted':
24591 toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]);
24592 break;
24593 case 'iterated': {
24594 const data = util.concatUint8Array([this.salt, passphrase]);
24595 let datalen = data.length;
24596 const count = Math.max(this.getCount(), datalen);
24597 toHash = new Uint8Array(prefixlen + count);
24598 toHash.set(data, prefixlen);
24599 for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) {
24600 toHash.copyWithin(pos, prefixlen, pos);
24601 }
24602 break;
24603 }
24604 case 'gnu':
24605 throw new Error('GNU s2k type not supported.');
24606 default:
24607 throw new Error('Unknown s2k type.');
24608 }
24609 const result = await mod.hash.digest(this.algorithm, toHash);
24610 arr.push(result);
24611 rlength += result.length;
24612 prefixlen++;
24613 }
24614
24615 return util.concatUint8Array(arr).subarray(0, numBytes);
24616 }
24617}
24618
24619// GPG4Browsers - An OpenPGP implementation in javascript
24620
24621/**
24622 * Symmetric-Key Encrypted Session Key Packets (Tag 3)
24623 *
24624 * {@link https://tools.ietf.org/html/rfc4880#section-5.3|RFC4880 5.3}:
24625 * The Symmetric-Key Encrypted Session Key packet holds the
24626 * symmetric-key encryption of a session key used to encrypt a message.
24627 * Zero or more Public-Key Encrypted Session Key packets and/or
24628 * Symmetric-Key Encrypted Session Key packets may precede a
24629 * Symmetrically Encrypted Data packet that holds an encrypted message.
24630 * The message is encrypted with a session key, and the session key is
24631 * itself encrypted and stored in the Encrypted Session Key packet or
24632 * the Symmetric-Key Encrypted Session Key packet.
24633 */
24634class SymEncryptedSessionKeyPacket {
24635 static get tag() {
24636 return enums.packet.symEncryptedSessionKey;
24637 }
24638
24639 /**
24640 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24641 */
24642 constructor(config = defaultConfig) {
24643 this.version = config.aeadProtect ? 5 : 4;
24644 this.sessionKey = null;
24645 /**
24646 * Algorithm to encrypt the session key with
24647 * @type {enums.symmetric}
24648 */
24649 this.sessionKeyEncryptionAlgorithm = null;
24650 /**
24651 * Algorithm to encrypt the message with
24652 * @type {enums.symmetric}
24653 */
24654 this.sessionKeyAlgorithm = enums.symmetric.aes256;
24655 /**
24656 * AEAD mode to encrypt the session key with (if AEAD protection is enabled)
24657 * @type {enums.aead}
24658 */
24659 this.aeadAlgorithm = enums.write(enums.aead, config.preferredAEADAlgorithm);
24660 this.encrypted = null;
24661 this.s2k = null;
24662 this.iv = null;
24663 }
24664
24665 /**
24666 * Parsing function for a symmetric encrypted session key packet (tag 3).
24667 *
24668 * @param {Uint8Array} bytes - Payload of a tag 3 packet
24669 */
24670 read(bytes) {
24671 let offset = 0;
24672
24673 // A one-octet version number. The only currently defined version is 4.
24674 this.version = bytes[offset++];
24675 if (this.version !== 4 && this.version !== 5) {
24676 throw new UnsupportedError(`Version ${this.version} of the SKESK packet is unsupported.`);
24677 }
24678
24679 // A one-octet number describing the symmetric algorithm used.
24680 const algo = bytes[offset++];
24681
24682 if (this.version === 5) {
24683 // A one-octet AEAD algorithm.
24684 this.aeadAlgorithm = bytes[offset++];
24685 }
24686
24687 // A string-to-key (S2K) specifier, length as defined above.
24688 this.s2k = new S2K();
24689 offset += this.s2k.read(bytes.subarray(offset, bytes.length));
24690
24691 if (this.version === 5) {
24692 const mode = mod.getAEADMode(this.aeadAlgorithm);
24693
24694 // A starting initialization vector of size specified by the AEAD
24695 // algorithm.
24696 this.iv = bytes.subarray(offset, offset += mode.ivLength);
24697 }
24698
24699 // The encrypted session key itself, which is decrypted with the
24700 // string-to-key object. This is optional in version 4.
24701 if (this.version === 5 || offset < bytes.length) {
24702 this.encrypted = bytes.subarray(offset, bytes.length);
24703 this.sessionKeyEncryptionAlgorithm = algo;
24704 } else {
24705 this.sessionKeyAlgorithm = algo;
24706 }
24707 }
24708
24709 /**
24710 * Create a binary representation of a tag 3 packet
24711 *
24712 * @returns {Uint8Array} The Uint8Array representation.
24713 */
24714 write() {
24715 const algo = this.encrypted === null ?
24716 this.sessionKeyAlgorithm :
24717 this.sessionKeyEncryptionAlgorithm;
24718
24719 let bytes;
24720
24721 if (this.version === 5) {
24722 bytes = util.concatUint8Array([new Uint8Array([this.version, algo, this.aeadAlgorithm]), this.s2k.write(), this.iv, this.encrypted]);
24723 } else {
24724 bytes = util.concatUint8Array([new Uint8Array([this.version, algo]), this.s2k.write()]);
24725
24726 if (this.encrypted !== null) {
24727 bytes = util.concatUint8Array([bytes, this.encrypted]);
24728 }
24729 }
24730
24731 return bytes;
24732 }
24733
24734 /**
24735 * Decrypts the session key with the given passphrase
24736 * @param {String} passphrase - The passphrase in string form
24737 * @throws {Error} if decryption was not successful
24738 * @async
24739 */
24740 async decrypt(passphrase) {
24741 const algo = this.sessionKeyEncryptionAlgorithm !== null ?
24742 this.sessionKeyEncryptionAlgorithm :
24743 this.sessionKeyAlgorithm;
24744
24745 const { blockSize, keySize } = mod.getCipher(algo);
24746 const key = await this.s2k.produceKey(passphrase, keySize);
24747
24748 if (this.version === 5) {
24749 const mode = mod.getAEADMode(this.aeadAlgorithm);
24750 const adata = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
24751 const modeInstance = await mode(algo, key);
24752 this.sessionKey = await modeInstance.decrypt(this.encrypted, this.iv, adata);
24753 } else if (this.encrypted !== null) {
24754 const decrypted = await mod.mode.cfb.decrypt(algo, key, this.encrypted, new Uint8Array(blockSize));
24755
24756 this.sessionKeyAlgorithm = enums.write(enums.symmetric, decrypted[0]);
24757 this.sessionKey = decrypted.subarray(1, decrypted.length);
24758 } else {
24759 this.sessionKey = key;
24760 }
24761 }
24762
24763 /**
24764 * Encrypts the session key with the given passphrase
24765 * @param {String} passphrase - The passphrase in string form
24766 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24767 * @throws {Error} if encryption was not successful
24768 * @async
24769 */
24770 async encrypt(passphrase, config = defaultConfig) {
24771 const algo = this.sessionKeyEncryptionAlgorithm !== null ?
24772 this.sessionKeyEncryptionAlgorithm :
24773 this.sessionKeyAlgorithm;
24774
24775 this.sessionKeyEncryptionAlgorithm = algo;
24776
24777 this.s2k = new S2K(config);
24778 this.s2k.salt = await mod.random.getRandomBytes(8);
24779
24780 const { blockSize, keySize } = mod.getCipher(algo);
24781 const encryptionKey = await this.s2k.produceKey(passphrase, keySize);
24782
24783 if (this.sessionKey === null) {
24784 this.sessionKey = await mod.generateSessionKey(this.sessionKeyAlgorithm);
24785 }
24786
24787 if (this.version === 5) {
24788 const mode = mod.getAEADMode(this.aeadAlgorithm);
24789 this.iv = await mod.random.getRandomBytes(mode.ivLength); // generate new random IV
24790 const associatedData = new Uint8Array([0xC0 | SymEncryptedSessionKeyPacket.tag, this.version, this.sessionKeyEncryptionAlgorithm, this.aeadAlgorithm]);
24791 const modeInstance = await mode(algo, encryptionKey);
24792 this.encrypted = await modeInstance.encrypt(this.sessionKey, this.iv, associatedData);
24793 } else {
24794 const toEncrypt = util.concatUint8Array([
24795 new Uint8Array([this.sessionKeyAlgorithm]),
24796 this.sessionKey
24797 ]);
24798 this.encrypted = await mod.mode.cfb.encrypt(algo, encryptionKey, toEncrypt, new Uint8Array(blockSize), config);
24799 }
24800 }
24801}
24802
24803// GPG4Browsers - An OpenPGP implementation in javascript
24804
24805/**
24806 * Implementation of the Key Material Packet (Tag 5,6,7,14)
24807 *
24808 * {@link https://tools.ietf.org/html/rfc4880#section-5.5|RFC4480 5.5}:
24809 * A key material packet contains all the information about a public or
24810 * private key. There are four variants of this packet type, and two
24811 * major versions.
24812 *
24813 * A Public-Key packet starts a series of packets that forms an OpenPGP
24814 * key (sometimes called an OpenPGP certificate).
24815 */
24816class PublicKeyPacket {
24817 static get tag() {
24818 return enums.packet.publicKey;
24819 }
24820
24821 /**
24822 * @param {Date} [date] - Creation date
24823 * @param {Object} [config] - Full configuration, defaults to openpgp.config
24824 */
24825 constructor(date = new Date(), config = defaultConfig) {
24826 /**
24827 * Packet version
24828 * @type {Integer}
24829 */
24830 this.version = config.v5Keys ? 5 : 4;
24831 /**
24832 * Key creation date.
24833 * @type {Date}
24834 */
24835 this.created = util.normalizeDate(date);
24836 /**
24837 * Public key algorithm.
24838 * @type {enums.publicKey}
24839 */
24840 this.algorithm = null;
24841 /**
24842 * Algorithm specific public params
24843 * @type {Object}
24844 */
24845 this.publicParams = null;
24846 /**
24847 * Time until expiration in days (V3 only)
24848 * @type {Integer}
24849 */
24850 this.expirationTimeV3 = 0;
24851 /**
24852 * Fingerprint bytes
24853 * @type {Uint8Array}
24854 */
24855 this.fingerprint = null;
24856 /**
24857 * KeyID
24858 * @type {module:type/keyid~KeyID}
24859 */
24860 this.keyID = null;
24861 }
24862
24863 /**
24864 * Create a PublicKeyPacket from a SecretKeyPacket
24865 * @param {SecretKeyPacket} secretKeyPacket - key packet to convert
24866 * @returns {PublicKeyPacket} public key packet
24867 * @static
24868 */
24869 static fromSecretKeyPacket(secretKeyPacket) {
24870 const keyPacket = new PublicKeyPacket();
24871 const { version, created, algorithm, publicParams, keyID, fingerprint } = secretKeyPacket;
24872 keyPacket.version = version;
24873 keyPacket.created = created;
24874 keyPacket.algorithm = algorithm;
24875 keyPacket.publicParams = publicParams;
24876 keyPacket.keyID = keyID;
24877 keyPacket.fingerprint = fingerprint;
24878 return keyPacket;
24879 }
24880
24881 /**
24882 * Internal Parser for public keys as specified in {@link https://tools.ietf.org/html/rfc4880#section-5.5.2|RFC 4880 section 5.5.2 Public-Key Packet Formats}
24883 * @param {Uint8Array} bytes - Input array to read the packet from
24884 * @returns {Object} This object with attributes set by the parser
24885 * @async
24886 */
24887 async read(bytes) {
24888 let pos = 0;
24889 // A one-octet version number (3, 4 or 5).
24890 this.version = bytes[pos++];
24891
24892 if (this.version === 4 || this.version === 5) {
24893 // - A four-octet number denoting the time that the key was created.
24894 this.created = util.readDate(bytes.subarray(pos, pos + 4));
24895 pos += 4;
24896
24897 // - A one-octet number denoting the public-key algorithm of this key.
24898 this.algorithm = bytes[pos++];
24899
24900 if (this.version === 5) {
24901 // - A four-octet scalar octet count for the following key material.
24902 pos += 4;
24903 }
24904
24905 // - A series of values comprising the key material.
24906 const { read, publicParams } = mod.parsePublicKeyParams(this.algorithm, bytes.subarray(pos));
24907 this.publicParams = publicParams;
24908 pos += read;
24909
24910 // we set the fingerprint and keyID already to make it possible to put together the key packets directly in the Key constructor
24911 await this.computeFingerprintAndKeyID();
24912 return pos;
24913 }
24914 throw new UnsupportedError(`Version ${this.version} of the key packet is unsupported.`);
24915 }
24916
24917 /**
24918 * Creates an OpenPGP public key packet for the given key.
24919 * @returns {Uint8Array} Bytes encoding the public key OpenPGP packet.
24920 */
24921 write() {
24922 const arr = [];
24923 // Version
24924 arr.push(new Uint8Array([this.version]));
24925 arr.push(util.writeDate(this.created));
24926 // A one-octet number denoting the public-key algorithm of this key
24927 arr.push(new Uint8Array([this.algorithm]));
24928
24929 const params = mod.serializeParams(this.algorithm, this.publicParams);
24930 if (this.version === 5) {
24931 // A four-octet scalar octet count for the following key material
24932 arr.push(util.writeNumber(params.length, 4));
24933 }
24934 // Algorithm-specific params
24935 arr.push(params);
24936 return util.concatUint8Array(arr);
24937 }
24938
24939 /**
24940 * Write packet in order to be hashed; either for a signature or a fingerprint
24941 * @param {Integer} version - target version of signature or key
24942 */
24943 writeForHash(version) {
24944 const bytes = this.writePublicKey();
24945
24946 if (version === 5) {
24947 return util.concatUint8Array([new Uint8Array([0x9A]), util.writeNumber(bytes.length, 4), bytes]);
24948 }
24949 return util.concatUint8Array([new Uint8Array([0x99]), util.writeNumber(bytes.length, 2), bytes]);
24950 }
24951
24952 /**
24953 * Check whether secret-key data is available in decrypted form. Returns null for public keys.
24954 * @returns {Boolean|null}
24955 */
24956 isDecrypted() {
24957 return null;
24958 }
24959
24960 /**
24961 * Returns the creation time of the key
24962 * @returns {Date}
24963 */
24964 getCreationTime() {
24965 return this.created;
24966 }
24967
24968 /**
24969 * Return the key ID of the key
24970 * @returns {module:type/keyid~KeyID} The 8-byte key ID
24971 */
24972 getKeyID() {
24973 return this.keyID;
24974 }
24975
24976 /**
24977 * Computes and set the key ID and fingerprint of the key
24978 * @async
24979 */
24980 async computeFingerprintAndKeyID() {
24981 await this.computeFingerprint();
24982 this.keyID = new KeyID();
24983
24984 if (this.version === 5) {
24985 this.keyID.read(this.fingerprint.subarray(0, 8));
24986 } else if (this.version === 4) {
24987 this.keyID.read(this.fingerprint.subarray(12, 20));
24988 } else {
24989 throw new Error('Unsupported key version');
24990 }
24991 }
24992
24993 /**
24994 * Computes and set the fingerprint of the key
24995 */
24996 async computeFingerprint() {
24997 const toHash = this.writeForHash(this.version);
24998
24999 if (this.version === 5) {
25000 this.fingerprint = await mod.hash.sha256(toHash);
25001 } else if (this.version === 4) {
25002 this.fingerprint = await mod.hash.sha1(toHash);
25003 } else {
25004 throw new Error('Unsupported key version');
25005 }
25006 }
25007
25008 /**
25009 * Returns the fingerprint of the key, as an array of bytes
25010 * @returns {Uint8Array} A Uint8Array containing the fingerprint
25011 */
25012 getFingerprintBytes() {
25013 return this.fingerprint;
25014 }
25015
25016 /**
25017 * Calculates and returns the fingerprint of the key, as a string
25018 * @returns {String} A string containing the fingerprint in lowercase hex
25019 */
25020 getFingerprint() {
25021 return util.uint8ArrayToHex(this.getFingerprintBytes());
25022 }
25023
25024 /**
25025 * Calculates whether two keys have the same fingerprint without actually calculating the fingerprint
25026 * @returns {Boolean} Whether the two keys have the same version and public key data.
25027 */
25028 hasSameFingerprintAs(other) {
25029 return this.version === other.version && util.equalsUint8Array(this.writePublicKey(), other.writePublicKey());
25030 }
25031
25032 /**
25033 * Returns algorithm information
25034 * @returns {Object} An object of the form {algorithm: String, bits:int, curve:String}.
25035 */
25036 getAlgorithmInfo() {
25037 const result = {};
25038 result.algorithm = enums.read(enums.publicKey, this.algorithm);
25039 // RSA, DSA or ElGamal public modulo
25040 const modulo = this.publicParams.n || this.publicParams.p;
25041 if (modulo) {
25042 result.bits = util.uint8ArrayBitLength(modulo);
25043 } else {
25044 result.curve = this.publicParams.oid.getName();
25045 }
25046 return result;
25047 }
25048}
25049
25050/**
25051 * Alias of read()
25052 * @see PublicKeyPacket#read
25053 */
25054PublicKeyPacket.prototype.readPublicKey = PublicKeyPacket.prototype.read;
25055
25056/**
25057 * Alias of write()
25058 * @see PublicKeyPacket#write
25059 */
25060PublicKeyPacket.prototype.writePublicKey = PublicKeyPacket.prototype.write;
25061
25062// GPG4Browsers - An OpenPGP implementation in javascript
25063
25064// A SE packet can contain the following packet types
25065const allowedPackets$3 = /*#__PURE__*/ util.constructAllowedPackets([
25066 LiteralDataPacket,
25067 CompressedDataPacket,
25068 OnePassSignaturePacket,
25069 SignaturePacket
25070]);
25071
25072/**
25073 * Implementation of the Symmetrically Encrypted Data Packet (Tag 9)
25074 *
25075 * {@link https://tools.ietf.org/html/rfc4880#section-5.7|RFC4880 5.7}:
25076 * The Symmetrically Encrypted Data packet contains data encrypted with a
25077 * symmetric-key algorithm. When it has been decrypted, it contains other
25078 * packets (usually a literal data packet or compressed data packet, but in
25079 * theory other Symmetrically Encrypted Data packets or sequences of packets
25080 * that form whole OpenPGP messages).
25081 */
25082class SymmetricallyEncryptedDataPacket {
25083 static get tag() {
25084 return enums.packet.symmetricallyEncryptedData;
25085 }
25086
25087 constructor() {
25088 /**
25089 * Encrypted secret-key data
25090 */
25091 this.encrypted = null;
25092 /**
25093 * Decrypted packets contained within.
25094 * @type {PacketList}
25095 */
25096 this.packets = null;
25097 }
25098
25099 read(bytes) {
25100 this.encrypted = bytes;
25101 }
25102
25103 write() {
25104 return this.encrypted;
25105 }
25106
25107 /**
25108 * Decrypt the symmetrically-encrypted packet data
25109 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
25110 * @param {module:enums.symmetric} sessionKeyAlgorithm - Symmetric key algorithm to use
25111 * @param {Uint8Array} key - The key of cipher blocksize length to be used
25112 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25113
25114 * @throws {Error} if decryption was not successful
25115 * @async
25116 */
25117 async decrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
25118 // If MDC errors are not being ignored, all missing MDC packets in symmetrically encrypted data should throw an error
25119 if (!config.allowUnauthenticatedMessages) {
25120 throw new Error('Message is not authenticated.');
25121 }
25122
25123 const { blockSize } = mod.getCipher(sessionKeyAlgorithm);
25124 const encrypted = await readToEnd(clone(this.encrypted));
25125 const decrypted = await mod.mode.cfb.decrypt(sessionKeyAlgorithm, key,
25126 encrypted.subarray(blockSize + 2),
25127 encrypted.subarray(2, blockSize + 2)
25128 );
25129
25130 this.packets = await PacketList.fromBinary(decrypted, allowedPackets$3, config);
25131 }
25132
25133 /**
25134 * Encrypt the symmetrically-encrypted packet data
25135 * See {@link https://tools.ietf.org/html/rfc4880#section-9.2|RFC 4880 9.2} for algorithms.
25136 * @param {module:enums.symmetric} sessionKeyAlgorithm - Symmetric key algorithm to use
25137 * @param {Uint8Array} key - The key of cipher blocksize length to be used
25138 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25139 * @throws {Error} if encryption was not successful
25140 * @async
25141 */
25142 async encrypt(sessionKeyAlgorithm, key, config = defaultConfig) {
25143 const data = this.packets.write();
25144 const { blockSize } = mod.getCipher(sessionKeyAlgorithm);
25145
25146 const prefix = await mod.getPrefixRandom(sessionKeyAlgorithm);
25147 const FRE = await mod.mode.cfb.encrypt(sessionKeyAlgorithm, key, prefix, new Uint8Array(blockSize), config);
25148 const ciphertext = await mod.mode.cfb.encrypt(sessionKeyAlgorithm, key, data, FRE.subarray(2), config);
25149 this.encrypted = util.concat([FRE, ciphertext]);
25150 }
25151}
25152
25153// GPG4Browsers - An OpenPGP implementation in javascript
25154
25155/**
25156 * Implementation of the strange "Marker packet" (Tag 10)
25157 *
25158 * {@link https://tools.ietf.org/html/rfc4880#section-5.8|RFC4880 5.8}:
25159 * An experimental version of PGP used this packet as the Literal
25160 * packet, but no released version of PGP generated Literal packets with this
25161 * tag. With PGP 5.x, this packet has been reassigned and is reserved for use as
25162 * the Marker packet.
25163 *
25164 * The body of this packet consists of:
25165 * The three octets 0x50, 0x47, 0x50 (which spell "PGP" in UTF-8).
25166 *
25167 * Such a packet MUST be ignored when received. It may be placed at the
25168 * beginning of a message that uses features not available in PGP
25169 * version 2.6 in order to cause that version to report that newer
25170 * software is necessary to process the message.
25171 */
25172class MarkerPacket {
25173 static get tag() {
25174 return enums.packet.marker;
25175 }
25176
25177 /**
25178 * Parsing function for a marker data packet (tag 10).
25179 * @param {Uint8Array} bytes - Payload of a tag 10 packet
25180 * @returns {Boolean} whether the packet payload contains "PGP"
25181 */
25182 read(bytes) {
25183 if (bytes[0] === 0x50 && // P
25184 bytes[1] === 0x47 && // G
25185 bytes[2] === 0x50) { // P
25186 return true;
25187 }
25188 return false;
25189 }
25190
25191 write() {
25192 return new Uint8Array([0x50, 0x47, 0x50]);
25193 }
25194}
25195
25196// GPG4Browsers - An OpenPGP implementation in javascript
25197
25198/**
25199 * A Public-Subkey packet (tag 14) has exactly the same format as a
25200 * Public-Key packet, but denotes a subkey. One or more subkeys may be
25201 * associated with a top-level key. By convention, the top-level key
25202 * provides signature services, and the subkeys provide encryption
25203 * services.
25204 * @extends PublicKeyPacket
25205 */
25206class PublicSubkeyPacket extends PublicKeyPacket {
25207 static get tag() {
25208 return enums.packet.publicSubkey;
25209 }
25210
25211 /**
25212 * @param {Date} [date] - Creation date
25213 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25214 */
25215 // eslint-disable-next-line no-useless-constructor
25216 constructor(date, config) {
25217 super(date, config);
25218 }
25219
25220 /**
25221 * Create a PublicSubkeyPacket from a SecretSubkeyPacket
25222 * @param {SecretSubkeyPacket} secretSubkeyPacket - subkey packet to convert
25223 * @returns {SecretSubkeyPacket} public key packet
25224 * @static
25225 */
25226 static fromSecretSubkeyPacket(secretSubkeyPacket) {
25227 const keyPacket = new PublicSubkeyPacket();
25228 const { version, created, algorithm, publicParams, keyID, fingerprint } = secretSubkeyPacket;
25229 keyPacket.version = version;
25230 keyPacket.created = created;
25231 keyPacket.algorithm = algorithm;
25232 keyPacket.publicParams = publicParams;
25233 keyPacket.keyID = keyID;
25234 keyPacket.fingerprint = fingerprint;
25235 return keyPacket;
25236 }
25237}
25238
25239// GPG4Browsers - An OpenPGP implementation in javascript
25240
25241/**
25242 * Implementation of the User Attribute Packet (Tag 17)
25243 *
25244 * The User Attribute packet is a variation of the User ID packet. It
25245 * is capable of storing more types of data than the User ID packet,
25246 * which is limited to text. Like the User ID packet, a User Attribute
25247 * packet may be certified by the key owner ("self-signed") or any other
25248 * key owner who cares to certify it. Except as noted, a User Attribute
25249 * packet may be used anywhere that a User ID packet may be used.
25250 *
25251 * While User Attribute packets are not a required part of the OpenPGP
25252 * standard, implementations SHOULD provide at least enough
25253 * compatibility to properly handle a certification signature on the
25254 * User Attribute packet. A simple way to do this is by treating the
25255 * User Attribute packet as a User ID packet with opaque contents, but
25256 * an implementation may use any method desired.
25257 */
25258class UserAttributePacket {
25259 static get tag() {
25260 return enums.packet.userAttribute;
25261 }
25262
25263 constructor() {
25264 this.attributes = [];
25265 }
25266
25267 /**
25268 * parsing function for a user attribute packet (tag 17).
25269 * @param {Uint8Array} input - Payload of a tag 17 packet
25270 */
25271 read(bytes) {
25272 let i = 0;
25273 while (i < bytes.length) {
25274 const len = readSimpleLength(bytes.subarray(i, bytes.length));
25275 i += len.offset;
25276
25277 this.attributes.push(util.uint8ArrayToString(bytes.subarray(i, i + len.len)));
25278 i += len.len;
25279 }
25280 }
25281
25282 /**
25283 * Creates a binary representation of the user attribute packet
25284 * @returns {Uint8Array} String representation.
25285 */
25286 write() {
25287 const arr = [];
25288 for (let i = 0; i < this.attributes.length; i++) {
25289 arr.push(writeSimpleLength(this.attributes[i].length));
25290 arr.push(util.stringToUint8Array(this.attributes[i]));
25291 }
25292 return util.concatUint8Array(arr);
25293 }
25294
25295 /**
25296 * Compare for equality
25297 * @param {UserAttributePacket} usrAttr
25298 * @returns {Boolean} True if equal.
25299 */
25300 equals(usrAttr) {
25301 if (!usrAttr || !(usrAttr instanceof UserAttributePacket)) {
25302 return false;
25303 }
25304 return this.attributes.every(function(attr, index) {
25305 return attr === usrAttr.attributes[index];
25306 });
25307 }
25308}
25309
25310// GPG4Browsers - An OpenPGP implementation in javascript
25311
25312/**
25313 * A Secret-Key packet contains all the information that is found in a
25314 * Public-Key packet, including the public-key material, but also
25315 * includes the secret-key material after all the public-key fields.
25316 * @extends PublicKeyPacket
25317 */
25318class SecretKeyPacket extends PublicKeyPacket {
25319 static get tag() {
25320 return enums.packet.secretKey;
25321 }
25322
25323 /**
25324 * @param {Date} [date] - Creation date
25325 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25326 */
25327 constructor(date = new Date(), config = defaultConfig) {
25328 super(date, config);
25329 /**
25330 * Secret-key data
25331 */
25332 this.keyMaterial = null;
25333 /**
25334 * Indicates whether secret-key data is encrypted. `this.isEncrypted === false` means data is available in decrypted form.
25335 */
25336 this.isEncrypted = null;
25337 /**
25338 * S2K usage
25339 * @type {enums.symmetric}
25340 */
25341 this.s2kUsage = 0;
25342 /**
25343 * S2K object
25344 * @type {type/s2k}
25345 */
25346 this.s2k = null;
25347 /**
25348 * Symmetric algorithm to encrypt the key with
25349 * @type {enums.symmetric}
25350 */
25351 this.symmetric = null;
25352 /**
25353 * AEAD algorithm to encrypt the key with (if AEAD protection is enabled)
25354 * @type {enums.aead}
25355 */
25356 this.aead = null;
25357 /**
25358 * Decrypted private parameters, referenced by name
25359 * @type {Object}
25360 */
25361 this.privateParams = null;
25362 }
25363
25364 // 5.5.3. Secret-Key Packet Formats
25365
25366 /**
25367 * Internal parser for private keys as specified in
25368 * {@link https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-04#section-5.5.3|RFC4880bis-04 section 5.5.3}
25369 * @param {Uint8Array} bytes - Input string to read the packet from
25370 * @async
25371 */
25372 async read(bytes) {
25373 // - A Public-Key or Public-Subkey packet, as described above.
25374 let i = await this.readPublicKey(bytes);
25375
25376 // - One octet indicating string-to-key usage conventions. Zero
25377 // indicates that the secret-key data is not encrypted. 255 or 254
25378 // indicates that a string-to-key specifier is being given. Any
25379 // other value is a symmetric-key encryption algorithm identifier.
25380 this.s2kUsage = bytes[i++];
25381
25382 // - Only for a version 5 packet, a one-octet scalar octet count of
25383 // the next 4 optional fields.
25384 if (this.version === 5) {
25385 i++;
25386 }
25387
25388 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25389 // one-octet symmetric encryption algorithm.
25390 if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
25391 this.symmetric = bytes[i++];
25392
25393 // - [Optional] If string-to-key usage octet was 253, a one-octet
25394 // AEAD algorithm.
25395 if (this.s2kUsage === 253) {
25396 this.aead = bytes[i++];
25397 }
25398
25399 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25400 // string-to-key specifier. The length of the string-to-key
25401 // specifier is implied by its type, as described above.
25402 this.s2k = new S2K();
25403 i += this.s2k.read(bytes.subarray(i, bytes.length));
25404
25405 if (this.s2k.type === 'gnu-dummy') {
25406 return;
25407 }
25408 } else if (this.s2kUsage) {
25409 this.symmetric = this.s2kUsage;
25410 }
25411
25412 // - [Optional] If secret data is encrypted (string-to-key usage octet
25413 // not zero), an Initial Vector (IV) of the same length as the
25414 // cipher's block size.
25415 if (this.s2kUsage) {
25416 this.iv = bytes.subarray(
25417 i,
25418 i + mod.getCipher(this.symmetric).blockSize
25419 );
25420
25421 i += this.iv.length;
25422 }
25423
25424 // - Only for a version 5 packet, a four-octet scalar octet count for
25425 // the following key material.
25426 if (this.version === 5) {
25427 i += 4;
25428 }
25429
25430 // - Plain or encrypted multiprecision integers comprising the secret
25431 // key data. These algorithm-specific fields are as described
25432 // below.
25433 this.keyMaterial = bytes.subarray(i);
25434 this.isEncrypted = !!this.s2kUsage;
25435
25436 if (!this.isEncrypted) {
25437 const cleartext = this.keyMaterial.subarray(0, -2);
25438 if (!util.equalsUint8Array(util.writeChecksum(cleartext), this.keyMaterial.subarray(-2))) {
25439 throw new Error('Key checksum mismatch');
25440 }
25441 try {
25442 const { privateParams } = mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
25443 this.privateParams = privateParams;
25444 } catch (err) {
25445 if (err instanceof UnsupportedError) throw err;
25446 // avoid throwing potentially sensitive errors
25447 throw new Error('Error reading MPIs');
25448 }
25449 }
25450 }
25451
25452 /**
25453 * Creates an OpenPGP key packet for the given key.
25454 * @returns {Uint8Array} A string of bytes containing the secret key OpenPGP packet.
25455 */
25456 write() {
25457 const arr = [this.writePublicKey()];
25458
25459 arr.push(new Uint8Array([this.s2kUsage]));
25460
25461 const optionalFieldsArr = [];
25462 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25463 // one- octet symmetric encryption algorithm.
25464 if (this.s2kUsage === 255 || this.s2kUsage === 254 || this.s2kUsage === 253) {
25465 optionalFieldsArr.push(this.symmetric);
25466
25467 // - [Optional] If string-to-key usage octet was 253, a one-octet
25468 // AEAD algorithm.
25469 if (this.s2kUsage === 253) {
25470 optionalFieldsArr.push(this.aead);
25471 }
25472
25473 // - [Optional] If string-to-key usage octet was 255, 254, or 253, a
25474 // string-to-key specifier. The length of the string-to-key
25475 // specifier is implied by its type, as described above.
25476 optionalFieldsArr.push(...this.s2k.write());
25477 }
25478
25479 // - [Optional] If secret data is encrypted (string-to-key usage octet
25480 // not zero), an Initial Vector (IV) of the same length as the
25481 // cipher's block size.
25482 if (this.s2kUsage && this.s2k.type !== 'gnu-dummy') {
25483 optionalFieldsArr.push(...this.iv);
25484 }
25485
25486 if (this.version === 5) {
25487 arr.push(new Uint8Array([optionalFieldsArr.length]));
25488 }
25489 arr.push(new Uint8Array(optionalFieldsArr));
25490
25491 if (!this.isDummy()) {
25492 if (!this.s2kUsage) {
25493 this.keyMaterial = mod.serializeParams(this.algorithm, this.privateParams);
25494 }
25495
25496 if (this.version === 5) {
25497 arr.push(util.writeNumber(this.keyMaterial.length, 4));
25498 }
25499 arr.push(this.keyMaterial);
25500
25501 if (!this.s2kUsage) {
25502 arr.push(util.writeChecksum(this.keyMaterial));
25503 }
25504 }
25505
25506 return util.concatUint8Array(arr);
25507 }
25508
25509 /**
25510 * Check whether secret-key data is available in decrypted form.
25511 * Returns false for gnu-dummy keys and null for public keys.
25512 * @returns {Boolean|null}
25513 */
25514 isDecrypted() {
25515 return this.isEncrypted === false;
25516 }
25517
25518 /**
25519 * Check whether this is a gnu-dummy key
25520 * @returns {Boolean}
25521 */
25522 isDummy() {
25523 return !!(this.s2k && this.s2k.type === 'gnu-dummy');
25524 }
25525
25526 /**
25527 * Remove private key material, converting the key to a dummy one.
25528 * The resulting key cannot be used for signing/decrypting but can still verify signatures.
25529 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25530 */
25531 makeDummy(config = defaultConfig) {
25532 if (this.isDummy()) {
25533 return;
25534 }
25535 if (this.isDecrypted()) {
25536 this.clearPrivateParams();
25537 }
25538 this.isEncrypted = null;
25539 this.keyMaterial = null;
25540 this.s2k = new S2K(config);
25541 this.s2k.algorithm = 0;
25542 this.s2k.c = 0;
25543 this.s2k.type = 'gnu-dummy';
25544 this.s2kUsage = 254;
25545 this.symmetric = enums.symmetric.aes256;
25546 }
25547
25548 /**
25549 * Encrypt the payload. By default, we use aes256 and iterated, salted string
25550 * to key specifier. If the key is in a decrypted state (isEncrypted === false)
25551 * and the passphrase is empty or undefined, the key will be set as not encrypted.
25552 * This can be used to remove passphrase protection after calling decrypt().
25553 * @param {String} passphrase
25554 * @param {Object} [config] - Full configuration, defaults to openpgp.config
25555 * @throws {Error} if encryption was not successful
25556 * @async
25557 */
25558 async encrypt(passphrase, config = defaultConfig) {
25559 if (this.isDummy()) {
25560 return;
25561 }
25562
25563 if (!this.isDecrypted()) {
25564 throw new Error('Key packet is already encrypted');
25565 }
25566
25567 if (!passphrase) {
25568 throw new Error('A non-empty passphrase is required for key encryption.');
25569 }
25570
25571 this.s2k = new S2K(config);
25572 this.s2k.salt = await mod.random.getRandomBytes(8);
25573 const cleartext = mod.serializeParams(this.algorithm, this.privateParams);
25574 this.symmetric = enums.symmetric.aes256;
25575 const key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
25576
25577 const { blockSize } = mod.getCipher(this.symmetric);
25578 this.iv = await mod.random.getRandomBytes(blockSize);
25579
25580 if (config.aeadProtect) {
25581 this.s2kUsage = 253;
25582 this.aead = enums.aead.eax;
25583 const mode = mod.getAEADMode(this.aead);
25584 const modeInstance = await mode(this.symmetric, key);
25585 this.keyMaterial = await modeInstance.encrypt(cleartext, this.iv.subarray(0, mode.ivLength), new Uint8Array());
25586 } else {
25587 this.s2kUsage = 254;
25588 this.keyMaterial = await mod.mode.cfb.encrypt(this.symmetric, key, util.concatUint8Array([
25589 cleartext,
25590 await mod.hash.sha1(cleartext, config)
25591 ]), this.iv, config);
25592 }
25593 }
25594
25595 /**
25596 * Decrypts the private key params which are needed to use the key.
25597 * Successful decryption does not imply key integrity, call validate() to confirm that.
25598 * {@link SecretKeyPacket.isDecrypted} should be false, as
25599 * otherwise calls to this function will throw an error.
25600 * @param {String} passphrase - The passphrase for this private key as string
25601 * @throws {Error} if the key is already decrypted, or if decryption was not successful
25602 * @async
25603 */
25604 async decrypt(passphrase) {
25605 if (this.isDummy()) {
25606 return false;
25607 }
25608
25609 if (this.isDecrypted()) {
25610 throw new Error('Key packet is already decrypted.');
25611 }
25612
25613 let key;
25614 if (this.s2kUsage === 254 || this.s2kUsage === 253) {
25615 key = await produceEncryptionKey(this.s2k, passphrase, this.symmetric);
25616 } else if (this.s2kUsage === 255) {
25617 throw new Error('Encrypted private key is authenticated using an insecure two-byte hash');
25618 } else {
25619 throw new Error('Private key is encrypted using an insecure S2K function: unsalted MD5');
25620 }
25621
25622 let cleartext;
25623 if (this.s2kUsage === 253) {
25624 const mode = mod.getAEADMode(this.aead);
25625 const modeInstance = await mode(this.symmetric, key);
25626 try {
25627 cleartext = await modeInstance.decrypt(this.keyMaterial, this.iv.subarray(0, mode.ivLength), new Uint8Array());
25628 } catch (err) {
25629 if (err.message === 'Authentication tag mismatch') {
25630 throw new Error('Incorrect key passphrase: ' + err.message);
25631 }
25632 throw err;
25633 }
25634 } else {
25635 const cleartextWithHash = await mod.mode.cfb.decrypt(this.symmetric, key, this.keyMaterial, this.iv);
25636
25637 cleartext = cleartextWithHash.subarray(0, -20);
25638 const hash = await mod.hash.sha1(cleartext);
25639
25640 if (!util.equalsUint8Array(hash, cleartextWithHash.subarray(-20))) {
25641 throw new Error('Incorrect key passphrase');
25642 }
25643 }
25644
25645 try {
25646 const { privateParams } = mod.parsePrivateKeyParams(this.algorithm, cleartext, this.publicParams);
25647 this.privateParams = privateParams;
25648 } catch (err) {
25649 throw new Error('Error reading MPIs');
25650 }
25651 this.isEncrypted = false;
25652 this.keyMaterial = null;
25653 this.s2kUsage = 0;
25654 }
25655
25656 /**
25657 * Checks that the key parameters are consistent
25658 * @throws {Error} if validation was not successful
25659 * @async
25660 */
25661 async validate() {
25662 if (this.isDummy()) {
25663 return;
25664 }
25665
25666 if (!this.isDecrypted()) {
25667 throw new Error('Key is not decrypted');
25668 }
25669
25670 let validParams;
25671 try {
25672 // this can throw if some parameters are undefined
25673 validParams = await mod.validateParams(this.algorithm, this.publicParams, this.privateParams);
25674 } catch (_) {
25675 validParams = false;
25676 }
25677 if (!validParams) {
25678 throw new Error('Key is invalid');
25679 }
25680 }
25681
25682 async generate(bits, curve) {
25683 const { privateParams, publicParams } = await mod.generateParams(this.algorithm, bits, curve);
25684 this.privateParams = privateParams;
25685 this.publicParams = publicParams;
25686 this.isEncrypted = false;
25687 }
25688
25689 /**
25690 * Clear private key parameters
25691 */
25692 clearPrivateParams() {
25693 if (this.isDummy()) {
25694 return;
25695 }
25696
25697 Object.keys(this.privateParams).forEach(name => {
25698 const param = this.privateParams[name];
25699 param.fill(0);
25700 delete this.privateParams[name];
25701 });
25702 this.privateParams = null;
25703 this.isEncrypted = true;
25704 }
25705}
25706
25707async function produceEncryptionKey(s2k, passphrase, algorithm) {
25708 const { keySize } = mod.getCipher(algorithm);
25709 return s2k.produceKey(passphrase, keySize);
25710}
25711
25712var emailAddresses = createCommonjsModule(function (module) {
25713// email-addresses.js - RFC 5322 email address parser
25714// v 3.1.0
25715//
25716// http://tools.ietf.org/html/rfc5322
25717//
25718// This library does not validate email addresses.
25719// emailAddresses attempts to parse addresses using the (fairly liberal)
25720// grammar specified in RFC 5322.
25721//
25722// email-addresses returns {
25723// ast: <an abstract syntax tree based on rfc5322>,
25724// addresses: [{
25725// node: <node in ast for this address>,
25726// name: <display-name>,
25727// address: <addr-spec>,
25728// local: <local-part>,
25729// domain: <domain>
25730// }, ...]
25731// }
25732//
25733// emailAddresses.parseOneAddress and emailAddresses.parseAddressList
25734// work as you might expect. Try it out.
25735//
25736// Many thanks to Dominic Sayers and his documentation on the is_email function,
25737// http://code.google.com/p/isemail/ , which helped greatly in writing this parser.
25738
25739(function (global) {
25740
25741function parse5322(opts) {
25742
25743 // tokenizing functions
25744
25745 function inStr() { return pos < len; }
25746 function curTok() { return parseString[pos]; }
25747 function getPos() { return pos; }
25748 function setPos(i) { pos = i; }
25749 function nextTok() { pos += 1; }
25750 function initialize() {
25751 pos = 0;
25752 len = parseString.length;
25753 }
25754
25755 // parser helper functions
25756
25757 function o(name, value) {
25758 return {
25759 name: name,
25760 tokens: value || "",
25761 semantic: value || "",
25762 children: []
25763 };
25764 }
25765
25766 function wrap(name, ast) {
25767 var n;
25768 if (ast === null) { return null; }
25769 n = o(name);
25770 n.tokens = ast.tokens;
25771 n.semantic = ast.semantic;
25772 n.children.push(ast);
25773 return n;
25774 }
25775
25776 function add(parent, child) {
25777 if (child !== null) {
25778 parent.tokens += child.tokens;
25779 parent.semantic += child.semantic;
25780 }
25781 parent.children.push(child);
25782 return parent;
25783 }
25784
25785 function compareToken(fxnCompare) {
25786 var tok;
25787 if (!inStr()) { return null; }
25788 tok = curTok();
25789 if (fxnCompare(tok)) {
25790 nextTok();
25791 return o('token', tok);
25792 }
25793 return null;
25794 }
25795
25796 function literal(lit) {
25797 return function literalFunc() {
25798 return wrap('literal', compareToken(function (tok) {
25799 return tok === lit;
25800 }));
25801 };
25802 }
25803
25804 function and() {
25805 var args = arguments;
25806 return function andFunc() {
25807 var i, s, result, start;
25808 start = getPos();
25809 s = o('and');
25810 for (i = 0; i < args.length; i += 1) {
25811 result = args[i]();
25812 if (result === null) {
25813 setPos(start);
25814 return null;
25815 }
25816 add(s, result);
25817 }
25818 return s;
25819 };
25820 }
25821
25822 function or() {
25823 var args = arguments;
25824 return function orFunc() {
25825 var i, result, start;
25826 start = getPos();
25827 for (i = 0; i < args.length; i += 1) {
25828 result = args[i]();
25829 if (result !== null) {
25830 return result;
25831 }
25832 setPos(start);
25833 }
25834 return null;
25835 };
25836 }
25837
25838 function opt(prod) {
25839 return function optFunc() {
25840 var result, start;
25841 start = getPos();
25842 result = prod();
25843 if (result !== null) {
25844 return result;
25845 }
25846 else {
25847 setPos(start);
25848 return o('opt');
25849 }
25850 };
25851 }
25852
25853 function invis(prod) {
25854 return function invisFunc() {
25855 var result = prod();
25856 if (result !== null) {
25857 result.semantic = "";
25858 }
25859 return result;
25860 };
25861 }
25862
25863 function colwsp(prod) {
25864 return function collapseSemanticWhitespace() {
25865 var result = prod();
25866 if (result !== null && result.semantic.length > 0) {
25867 result.semantic = " ";
25868 }
25869 return result;
25870 };
25871 }
25872
25873 function star(prod, minimum) {
25874 return function starFunc() {
25875 var s, result, count, start, min;
25876 start = getPos();
25877 s = o('star');
25878 count = 0;
25879 min = minimum === undefined ? 0 : minimum;
25880 while ((result = prod()) !== null) {
25881 count = count + 1;
25882 add(s, result);
25883 }
25884 if (count >= min) {
25885 return s;
25886 }
25887 else {
25888 setPos(start);
25889 return null;
25890 }
25891 };
25892 }
25893
25894 // One expects names to get normalized like this:
25895 // " First Last " -> "First Last"
25896 // "First Last" -> "First Last"
25897 // "First Last" -> "First Last"
25898 function collapseWhitespace(s) {
25899 return s.replace(/([ \t]|\r\n)+/g, ' ').replace(/^\s*/, '').replace(/\s*$/, '');
25900 }
25901
25902 // UTF-8 pseudo-production (RFC 6532)
25903 // RFC 6532 extends RFC 5322 productions to include UTF-8
25904 // using the following productions:
25905 // UTF8-non-ascii = UTF8-2 / UTF8-3 / UTF8-4
25906 // UTF8-2 = <Defined in Section 4 of RFC3629>
25907 // UTF8-3 = <Defined in Section 4 of RFC3629>
25908 // UTF8-4 = <Defined in Section 4 of RFC3629>
25909 //
25910 // For reference, the extended RFC 5322 productions are:
25911 // VCHAR =/ UTF8-non-ascii
25912 // ctext =/ UTF8-non-ascii
25913 // atext =/ UTF8-non-ascii
25914 // qtext =/ UTF8-non-ascii
25915 // dtext =/ UTF8-non-ascii
25916 function isUTF8NonAscii(tok) {
25917 // In JavaScript, we just deal directly with Unicode code points,
25918 // so we aren't checking individual bytes for UTF-8 encoding.
25919 // Just check that the character is non-ascii.
25920 return tok.charCodeAt(0) >= 128;
25921 }
25922
25923
25924 // common productions (RFC 5234)
25925 // http://tools.ietf.org/html/rfc5234
25926 // B.1. Core Rules
25927
25928 // CR = %x0D
25929 // ; carriage return
25930 function cr() { return wrap('cr', literal('\r')()); }
25931
25932 // CRLF = CR LF
25933 // ; Internet standard newline
25934 function crlf() { return wrap('crlf', and(cr, lf)()); }
25935
25936 // DQUOTE = %x22
25937 // ; " (Double Quote)
25938 function dquote() { return wrap('dquote', literal('"')()); }
25939
25940 // HTAB = %x09
25941 // ; horizontal tab
25942 function htab() { return wrap('htab', literal('\t')()); }
25943
25944 // LF = %x0A
25945 // ; linefeed
25946 function lf() { return wrap('lf', literal('\n')()); }
25947
25948 // SP = %x20
25949 function sp() { return wrap('sp', literal(' ')()); }
25950
25951 // VCHAR = %x21-7E
25952 // ; visible (printing) characters
25953 function vchar() {
25954 return wrap('vchar', compareToken(function vcharFunc(tok) {
25955 var code = tok.charCodeAt(0);
25956 var accept = (0x21 <= code && code <= 0x7E);
25957 if (opts.rfc6532) {
25958 accept = accept || isUTF8NonAscii(tok);
25959 }
25960 return accept;
25961 }));
25962 }
25963
25964 // WSP = SP / HTAB
25965 // ; white space
25966 function wsp() { return wrap('wsp', or(sp, htab)()); }
25967
25968
25969 // email productions (RFC 5322)
25970 // http://tools.ietf.org/html/rfc5322
25971 // 3.2.1. Quoted characters
25972
25973 // quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
25974 function quotedPair() {
25975 var qp = wrap('quoted-pair',
25976 or(
25977 and(literal('\\'), or(vchar, wsp)),
25978 obsQP
25979 )());
25980 if (qp === null) { return null; }
25981 // a quoted pair will be two characters, and the "\" character
25982 // should be semantically "invisible" (RFC 5322 3.2.1)
25983 qp.semantic = qp.semantic[1];
25984 return qp;
25985 }
25986
25987 // 3.2.2. Folding White Space and Comments
25988
25989 // FWS = ([*WSP CRLF] 1*WSP) / obs-FWS
25990 function fws() {
25991 return wrap('fws', or(
25992 obsFws,
25993 and(
25994 opt(and(
25995 star(wsp),
25996 invis(crlf)
25997 )),
25998 star(wsp, 1)
25999 )
26000 )());
26001 }
26002
26003 // ctext = %d33-39 / ; Printable US-ASCII
26004 // %d42-91 / ; characters not including
26005 // %d93-126 / ; "(", ")", or "\"
26006 // obs-ctext
26007 function ctext() {
26008 return wrap('ctext', or(
26009 function ctextFunc1() {
26010 return compareToken(function ctextFunc2(tok) {
26011 var code = tok.charCodeAt(0);
26012 var accept =
26013 (33 <= code && code <= 39) ||
26014 (42 <= code && code <= 91) ||
26015 (93 <= code && code <= 126);
26016 if (opts.rfc6532) {
26017 accept = accept || isUTF8NonAscii(tok);
26018 }
26019 return accept;
26020 });
26021 },
26022 obsCtext
26023 )());
26024 }
26025
26026 // ccontent = ctext / quoted-pair / comment
26027 function ccontent() {
26028 return wrap('ccontent', or(ctext, quotedPair, comment)());
26029 }
26030
26031 // comment = "(" *([FWS] ccontent) [FWS] ")"
26032 function comment() {
26033 return wrap('comment', and(
26034 literal('('),
26035 star(and(opt(fws), ccontent)),
26036 opt(fws),
26037 literal(')')
26038 )());
26039 }
26040
26041 // CFWS = (1*([FWS] comment) [FWS]) / FWS
26042 function cfws() {
26043 return wrap('cfws', or(
26044 and(
26045 star(
26046 and(opt(fws), comment),
26047 1
26048 ),
26049 opt(fws)
26050 ),
26051 fws
26052 )());
26053 }
26054
26055 // 3.2.3. Atom
26056
26057 //atext = ALPHA / DIGIT / ; Printable US-ASCII
26058 // "!" / "#" / ; characters not including
26059 // "$" / "%" / ; specials. Used for atoms.
26060 // "&" / "'" /
26061 // "*" / "+" /
26062 // "-" / "/" /
26063 // "=" / "?" /
26064 // "^" / "_" /
26065 // "`" / "{" /
26066 // "|" / "}" /
26067 // "~"
26068 function atext() {
26069 return wrap('atext', compareToken(function atextFunc(tok) {
26070 var accept =
26071 ('a' <= tok && tok <= 'z') ||
26072 ('A' <= tok && tok <= 'Z') ||
26073 ('0' <= tok && tok <= '9') ||
26074 (['!', '#', '$', '%', '&', '\'', '*', '+', '-', '/',
26075 '=', '?', '^', '_', '`', '{', '|', '}', '~'].indexOf(tok) >= 0);
26076 if (opts.rfc6532) {
26077 accept = accept || isUTF8NonAscii(tok);
26078 }
26079 return accept;
26080 }));
26081 }
26082
26083 // atom = [CFWS] 1*atext [CFWS]
26084 function atom() {
26085 return wrap('atom', and(colwsp(opt(cfws)), star(atext, 1), colwsp(opt(cfws)))());
26086 }
26087
26088 // dot-atom-text = 1*atext *("." 1*atext)
26089 function dotAtomText() {
26090 var s, maybeText;
26091 s = wrap('dot-atom-text', star(atext, 1)());
26092 if (s === null) { return s; }
26093 maybeText = star(and(literal('.'), star(atext, 1)))();
26094 if (maybeText !== null) {
26095 add(s, maybeText);
26096 }
26097 return s;
26098 }
26099
26100 // dot-atom = [CFWS] dot-atom-text [CFWS]
26101 function dotAtom() {
26102 return wrap('dot-atom', and(invis(opt(cfws)), dotAtomText, invis(opt(cfws)))());
26103 }
26104
26105 // 3.2.4. Quoted Strings
26106
26107 // qtext = %d33 / ; Printable US-ASCII
26108 // %d35-91 / ; characters not including
26109 // %d93-126 / ; "\" or the quote character
26110 // obs-qtext
26111 function qtext() {
26112 return wrap('qtext', or(
26113 function qtextFunc1() {
26114 return compareToken(function qtextFunc2(tok) {
26115 var code = tok.charCodeAt(0);
26116 var accept =
26117 (33 === code) ||
26118 (35 <= code && code <= 91) ||
26119 (93 <= code && code <= 126);
26120 if (opts.rfc6532) {
26121 accept = accept || isUTF8NonAscii(tok);
26122 }
26123 return accept;
26124 });
26125 },
26126 obsQtext
26127 )());
26128 }
26129
26130 // qcontent = qtext / quoted-pair
26131 function qcontent() {
26132 return wrap('qcontent', or(qtext, quotedPair)());
26133 }
26134
26135 // quoted-string = [CFWS]
26136 // DQUOTE *([FWS] qcontent) [FWS] DQUOTE
26137 // [CFWS]
26138 function quotedString() {
26139 return wrap('quoted-string', and(
26140 invis(opt(cfws)),
26141 invis(dquote), star(and(opt(colwsp(fws)), qcontent)), opt(invis(fws)), invis(dquote),
26142 invis(opt(cfws))
26143 )());
26144 }
26145
26146 // 3.2.5 Miscellaneous Tokens
26147
26148 // word = atom / quoted-string
26149 function word() {
26150 return wrap('word', or(atom, quotedString)());
26151 }
26152
26153 // phrase = 1*word / obs-phrase
26154 function phrase() {
26155 return wrap('phrase', or(obsPhrase, star(word, 1))());
26156 }
26157
26158 // 3.4. Address Specification
26159 // address = mailbox / group
26160 function address() {
26161 return wrap('address', or(mailbox, group)());
26162 }
26163
26164 // mailbox = name-addr / addr-spec
26165 function mailbox() {
26166 return wrap('mailbox', or(nameAddr, addrSpec)());
26167 }
26168
26169 // name-addr = [display-name] angle-addr
26170 function nameAddr() {
26171 return wrap('name-addr', and(opt(displayName), angleAddr)());
26172 }
26173
26174 // angle-addr = [CFWS] "<" addr-spec ">" [CFWS] /
26175 // obs-angle-addr
26176 function angleAddr() {
26177 return wrap('angle-addr', or(
26178 and(
26179 invis(opt(cfws)),
26180 literal('<'),
26181 addrSpec,
26182 literal('>'),
26183 invis(opt(cfws))
26184 ),
26185 obsAngleAddr
26186 )());
26187 }
26188
26189 // group = display-name ":" [group-list] ";" [CFWS]
26190 function group() {
26191 return wrap('group', and(
26192 displayName,
26193 literal(':'),
26194 opt(groupList),
26195 literal(';'),
26196 invis(opt(cfws))
26197 )());
26198 }
26199
26200 // display-name = phrase
26201 function displayName() {
26202 return wrap('display-name', function phraseFixedSemantic() {
26203 var result = phrase();
26204 if (result !== null) {
26205 result.semantic = collapseWhitespace(result.semantic);
26206 }
26207 return result;
26208 }());
26209 }
26210
26211 // mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list
26212 function mailboxList() {
26213 return wrap('mailbox-list', or(
26214 and(
26215 mailbox,
26216 star(and(literal(','), mailbox))
26217 ),
26218 obsMboxList
26219 )());
26220 }
26221
26222 // address-list = (address *("," address)) / obs-addr-list
26223 function addressList() {
26224 return wrap('address-list', or(
26225 and(
26226 address,
26227 star(and(literal(','), address))
26228 ),
26229 obsAddrList
26230 )());
26231 }
26232
26233 // group-list = mailbox-list / CFWS / obs-group-list
26234 function groupList() {
26235 return wrap('group-list', or(
26236 mailboxList,
26237 invis(cfws),
26238 obsGroupList
26239 )());
26240 }
26241
26242 // 3.4.1 Addr-Spec Specification
26243
26244 // local-part = dot-atom / quoted-string / obs-local-part
26245 function localPart() {
26246 // note: quoted-string, dotAtom are proper subsets of obs-local-part
26247 // so we really just have to look for obsLocalPart, if we don't care about the exact parse tree
26248 return wrap('local-part', or(obsLocalPart, dotAtom, quotedString)());
26249 }
26250
26251 // dtext = %d33-90 / ; Printable US-ASCII
26252 // %d94-126 / ; characters not including
26253 // obs-dtext ; "[", "]", or "\"
26254 function dtext() {
26255 return wrap('dtext', or(
26256 function dtextFunc1() {
26257 return compareToken(function dtextFunc2(tok) {
26258 var code = tok.charCodeAt(0);
26259 var accept =
26260 (33 <= code && code <= 90) ||
26261 (94 <= code && code <= 126);
26262 if (opts.rfc6532) {
26263 accept = accept || isUTF8NonAscii(tok);
26264 }
26265 return accept;
26266 });
26267 },
26268 obsDtext
26269 )()
26270 );
26271 }
26272
26273 // domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS]
26274 function domainLiteral() {
26275 return wrap('domain-literal', and(
26276 invis(opt(cfws)),
26277 literal('['),
26278 star(and(opt(fws), dtext)),
26279 opt(fws),
26280 literal(']'),
26281 invis(opt(cfws))
26282 )());
26283 }
26284
26285 // domain = dot-atom / domain-literal / obs-domain
26286 function domain() {
26287 return wrap('domain', function domainCheckTLD() {
26288 var result = or(obsDomain, dotAtom, domainLiteral)();
26289 if (opts.rejectTLD) {
26290 if (result && result.semantic && result.semantic.indexOf('.') < 0) {
26291 return null;
26292 }
26293 }
26294 // strip all whitespace from domains
26295 if (result) {
26296 result.semantic = result.semantic.replace(/\s+/g, '');
26297 }
26298 return result;
26299 }());
26300 }
26301
26302 // addr-spec = local-part "@" domain
26303 function addrSpec() {
26304 return wrap('addr-spec', and(
26305 localPart, literal('@'), domain
26306 )());
26307 }
26308
26309 // 3.6.2 Originator Fields
26310 // Below we only parse the field body, not the name of the field
26311 // like "From:", "Sender:", or "Reply-To:". Other libraries that
26312 // parse email headers can parse those and defer to these productions
26313 // for the "RFC 5322" part.
26314
26315 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
26316 // from = "From:" (mailbox-list / address-list) CRLF
26317 function fromSpec() {
26318 return wrap('from', or(
26319 mailboxList,
26320 addressList
26321 )());
26322 }
26323
26324 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
26325 // sender = "Sender:" (mailbox / address) CRLF
26326 function senderSpec() {
26327 return wrap('sender', or(
26328 mailbox,
26329 address
26330 )());
26331 }
26332
26333 // RFC 6854 2.1. Replacement of RFC 5322, Section 3.6.2. Originator Fields
26334 // reply-to = "Reply-To:" address-list CRLF
26335 function replyToSpec() {
26336 return wrap('reply-to', addressList());
26337 }
26338
26339 // 4.1. Miscellaneous Obsolete Tokens
26340
26341 // obs-NO-WS-CTL = %d1-8 / ; US-ASCII control
26342 // %d11 / ; characters that do not
26343 // %d12 / ; include the carriage
26344 // %d14-31 / ; return, line feed, and
26345 // %d127 ; white space characters
26346 function obsNoWsCtl() {
26347 return opts.strict ? null : wrap('obs-NO-WS-CTL', compareToken(function (tok) {
26348 var code = tok.charCodeAt(0);
26349 return ((1 <= code && code <= 8) ||
26350 (11 === code || 12 === code) ||
26351 (14 <= code && code <= 31) ||
26352 (127 === code));
26353 }));
26354 }
26355
26356 // obs-ctext = obs-NO-WS-CTL
26357 function obsCtext() { return opts.strict ? null : wrap('obs-ctext', obsNoWsCtl()); }
26358
26359 // obs-qtext = obs-NO-WS-CTL
26360 function obsQtext() { return opts.strict ? null : wrap('obs-qtext', obsNoWsCtl()); }
26361
26362 // obs-qp = "\" (%d0 / obs-NO-WS-CTL / LF / CR)
26363 function obsQP() {
26364 return opts.strict ? null : wrap('obs-qp', and(
26365 literal('\\'),
26366 or(literal('\0'), obsNoWsCtl, lf, cr)
26367 )());
26368 }
26369
26370 // obs-phrase = word *(word / "." / CFWS)
26371 function obsPhrase() {
26372 if (opts.strict ) return null;
26373 return opts.atInDisplayName ? wrap('obs-phrase', and(
26374 word,
26375 star(or(word, literal('.'), literal('@'), colwsp(cfws)))
26376 )()) :
26377 wrap('obs-phrase', and(
26378 word,
26379 star(or(word, literal('.'), colwsp(cfws)))
26380 )());
26381 }
26382
26383 // 4.2. Obsolete Folding White Space
26384
26385 // NOTE: read the errata http://www.rfc-editor.org/errata_search.php?rfc=5322&eid=1908
26386 // obs-FWS = 1*([CRLF] WSP)
26387 function obsFws() {
26388 return opts.strict ? null : wrap('obs-FWS', star(
26389 and(invis(opt(crlf)), wsp),
26390 1
26391 )());
26392 }
26393
26394 // 4.4. Obsolete Addressing
26395
26396 // obs-angle-addr = [CFWS] "<" obs-route addr-spec ">" [CFWS]
26397 function obsAngleAddr() {
26398 return opts.strict ? null : wrap('obs-angle-addr', and(
26399 invis(opt(cfws)),
26400 literal('<'),
26401 obsRoute,
26402 addrSpec,
26403 literal('>'),
26404 invis(opt(cfws))
26405 )());
26406 }
26407
26408 // obs-route = obs-domain-list ":"
26409 function obsRoute() {
26410 return opts.strict ? null : wrap('obs-route', and(
26411 obsDomainList,
26412 literal(':')
26413 )());
26414 }
26415
26416 // obs-domain-list = *(CFWS / ",") "@" domain
26417 // *("," [CFWS] ["@" domain])
26418 function obsDomainList() {
26419 return opts.strict ? null : wrap('obs-domain-list', and(
26420 star(or(invis(cfws), literal(','))),
26421 literal('@'),
26422 domain,
26423 star(and(
26424 literal(','),
26425 invis(opt(cfws)),
26426 opt(and(literal('@'), domain))
26427 ))
26428 )());
26429 }
26430
26431 // obs-mbox-list = *([CFWS] ",") mailbox *("," [mailbox / CFWS])
26432 function obsMboxList() {
26433 return opts.strict ? null : wrap('obs-mbox-list', and(
26434 star(and(
26435 invis(opt(cfws)),
26436 literal(',')
26437 )),
26438 mailbox,
26439 star(and(
26440 literal(','),
26441 opt(and(
26442 mailbox,
26443 invis(cfws)
26444 ))
26445 ))
26446 )());
26447 }
26448
26449 // obs-addr-list = *([CFWS] ",") address *("," [address / CFWS])
26450 function obsAddrList() {
26451 return opts.strict ? null : wrap('obs-addr-list', and(
26452 star(and(
26453 invis(opt(cfws)),
26454 literal(',')
26455 )),
26456 address,
26457 star(and(
26458 literal(','),
26459 opt(and(
26460 address,
26461 invis(cfws)
26462 ))
26463 ))
26464 )());
26465 }
26466
26467 // obs-group-list = 1*([CFWS] ",") [CFWS]
26468 function obsGroupList() {
26469 return opts.strict ? null : wrap('obs-group-list', and(
26470 star(and(
26471 invis(opt(cfws)),
26472 literal(',')
26473 ), 1),
26474 invis(opt(cfws))
26475 )());
26476 }
26477
26478 // obs-local-part = word *("." word)
26479 function obsLocalPart() {
26480 return opts.strict ? null : wrap('obs-local-part', and(word, star(and(literal('.'), word)))());
26481 }
26482
26483 // obs-domain = atom *("." atom)
26484 function obsDomain() {
26485 return opts.strict ? null : wrap('obs-domain', and(atom, star(and(literal('.'), atom)))());
26486 }
26487
26488 // obs-dtext = obs-NO-WS-CTL / quoted-pair
26489 function obsDtext() {
26490 return opts.strict ? null : wrap('obs-dtext', or(obsNoWsCtl, quotedPair)());
26491 }
26492
26493 /////////////////////////////////////////////////////
26494
26495 // ast analysis
26496
26497 function findNode(name, root) {
26498 var i, stack, node;
26499 if (root === null || root === undefined) { return null; }
26500 stack = [root];
26501 while (stack.length > 0) {
26502 node = stack.pop();
26503 if (node.name === name) {
26504 return node;
26505 }
26506 for (i = node.children.length - 1; i >= 0; i -= 1) {
26507 stack.push(node.children[i]);
26508 }
26509 }
26510 return null;
26511 }
26512
26513 function findAllNodes(name, root) {
26514 var i, stack, node, result;
26515 if (root === null || root === undefined) { return null; }
26516 stack = [root];
26517 result = [];
26518 while (stack.length > 0) {
26519 node = stack.pop();
26520 if (node.name === name) {
26521 result.push(node);
26522 }
26523 for (i = node.children.length - 1; i >= 0; i -= 1) {
26524 stack.push(node.children[i]);
26525 }
26526 }
26527 return result;
26528 }
26529
26530 function findAllNodesNoChildren(names, root) {
26531 var i, stack, node, result, namesLookup;
26532 if (root === null || root === undefined) { return null; }
26533 stack = [root];
26534 result = [];
26535 namesLookup = {};
26536 for (i = 0; i < names.length; i += 1) {
26537 namesLookup[names[i]] = true;
26538 }
26539
26540 while (stack.length > 0) {
26541 node = stack.pop();
26542 if (node.name in namesLookup) {
26543 result.push(node);
26544 // don't look at children (hence findAllNodesNoChildren)
26545 } else {
26546 for (i = node.children.length - 1; i >= 0; i -= 1) {
26547 stack.push(node.children[i]);
26548 }
26549 }
26550 }
26551 return result;
26552 }
26553
26554 function giveResult(ast) {
26555 var addresses, groupsAndMailboxes, i, groupOrMailbox, result;
26556 if (ast === null) {
26557 return null;
26558 }
26559 addresses = [];
26560
26561 // An address is a 'group' (i.e. a list of mailboxes) or a 'mailbox'.
26562 groupsAndMailboxes = findAllNodesNoChildren(['group', 'mailbox'], ast);
26563 for (i = 0; i < groupsAndMailboxes.length; i += 1) {
26564 groupOrMailbox = groupsAndMailboxes[i];
26565 if (groupOrMailbox.name === 'group') {
26566 addresses.push(giveResultGroup(groupOrMailbox));
26567 } else if (groupOrMailbox.name === 'mailbox') {
26568 addresses.push(giveResultMailbox(groupOrMailbox));
26569 }
26570 }
26571
26572 result = {
26573 ast: ast,
26574 addresses: addresses,
26575 };
26576 if (opts.simple) {
26577 result = simplifyResult(result);
26578 }
26579 if (opts.oneResult) {
26580 return oneResult(result);
26581 }
26582 if (opts.simple) {
26583 return result && result.addresses;
26584 } else {
26585 return result;
26586 }
26587 }
26588
26589 function giveResultGroup(group) {
26590 var i;
26591 var groupName = findNode('display-name', group);
26592 var groupResultMailboxes = [];
26593 var mailboxes = findAllNodesNoChildren(['mailbox'], group);
26594 for (i = 0; i < mailboxes.length; i += 1) {
26595 groupResultMailboxes.push(giveResultMailbox(mailboxes[i]));
26596 }
26597 return {
26598 node: group,
26599 parts: {
26600 name: groupName,
26601 },
26602 type: group.name, // 'group'
26603 name: grabSemantic(groupName),
26604 addresses: groupResultMailboxes,
26605 };
26606 }
26607
26608 function giveResultMailbox(mailbox) {
26609 var name = findNode('display-name', mailbox);
26610 var aspec = findNode('addr-spec', mailbox);
26611 var cfws = findAllNodes('cfws', mailbox);
26612 var comments = findAllNodesNoChildren(['comment'], mailbox);
26613
26614
26615 var local = findNode('local-part', aspec);
26616 var domain = findNode('domain', aspec);
26617 return {
26618 node: mailbox,
26619 parts: {
26620 name: name,
26621 address: aspec,
26622 local: local,
26623 domain: domain,
26624 comments: cfws
26625 },
26626 type: mailbox.name, // 'mailbox'
26627 name: grabSemantic(name),
26628 address: grabSemantic(aspec),
26629 local: grabSemantic(local),
26630 domain: grabSemantic(domain),
26631 comments: concatComments(comments),
26632 groupName: grabSemantic(mailbox.groupName),
26633 };
26634 }
26635
26636 function grabSemantic(n) {
26637 return n !== null && n !== undefined ? n.semantic : null;
26638 }
26639
26640 function simplifyResult(result) {
26641 var i;
26642 if (result && result.addresses) {
26643 for (i = 0; i < result.addresses.length; i += 1) {
26644 delete result.addresses[i].node;
26645 }
26646 }
26647 return result;
26648 }
26649
26650 function concatComments(comments) {
26651 var result = '';
26652 if (comments) {
26653 for (var i = 0; i < comments.length; i += 1) {
26654 result += grabSemantic(comments[i]);
26655 }
26656 }
26657 return result;
26658 }
26659
26660 function oneResult(result) {
26661 if (!result) { return null; }
26662 if (!opts.partial && result.addresses.length > 1) { return null; }
26663 return result.addresses && result.addresses[0];
26664 }
26665
26666 /////////////////////////////////////////////////////
26667
26668 var parseString, pos, len, parsed, startProduction;
26669
26670 opts = handleOpts(opts, {});
26671 if (opts === null) { return null; }
26672
26673 parseString = opts.input;
26674
26675 startProduction = {
26676 'address': address,
26677 'address-list': addressList,
26678 'angle-addr': angleAddr,
26679 'from': fromSpec,
26680 'group': group,
26681 'mailbox': mailbox,
26682 'mailbox-list': mailboxList,
26683 'reply-to': replyToSpec,
26684 'sender': senderSpec,
26685 }[opts.startAt] || addressList;
26686
26687 if (!opts.strict) {
26688 initialize();
26689 opts.strict = true;
26690 parsed = startProduction(parseString);
26691 if (opts.partial || !inStr()) {
26692 return giveResult(parsed);
26693 }
26694 opts.strict = false;
26695 }
26696
26697 initialize();
26698 parsed = startProduction(parseString);
26699 if (!opts.partial && inStr()) { return null; }
26700 return giveResult(parsed);
26701}
26702
26703function parseOneAddressSimple(opts) {
26704 return parse5322(handleOpts(opts, {
26705 oneResult: true,
26706 rfc6532: true,
26707 simple: true,
26708 startAt: 'address-list',
26709 }));
26710}
26711
26712function parseAddressListSimple(opts) {
26713 return parse5322(handleOpts(opts, {
26714 rfc6532: true,
26715 simple: true,
26716 startAt: 'address-list',
26717 }));
26718}
26719
26720function parseFromSimple(opts) {
26721 return parse5322(handleOpts(opts, {
26722 rfc6532: true,
26723 simple: true,
26724 startAt: 'from',
26725 }));
26726}
26727
26728function parseSenderSimple(opts) {
26729 return parse5322(handleOpts(opts, {
26730 oneResult: true,
26731 rfc6532: true,
26732 simple: true,
26733 startAt: 'sender',
26734 }));
26735}
26736
26737function parseReplyToSimple(opts) {
26738 return parse5322(handleOpts(opts, {
26739 rfc6532: true,
26740 simple: true,
26741 startAt: 'reply-to',
26742 }));
26743}
26744
26745function handleOpts(opts, defs) {
26746 function isString(str) {
26747 return Object.prototype.toString.call(str) === '[object String]';
26748 }
26749
26750 function isObject(o) {
26751 return o === Object(o);
26752 }
26753
26754 function isNullUndef(o) {
26755 return o === null || o === undefined;
26756 }
26757
26758 var defaults, o;
26759
26760 if (isString(opts)) {
26761 opts = { input: opts };
26762 } else if (!isObject(opts)) {
26763 return null;
26764 }
26765
26766 if (!isString(opts.input)) { return null; }
26767 if (!defs) { return null; }
26768
26769 defaults = {
26770 oneResult: false,
26771 partial: false,
26772 rejectTLD: false,
26773 rfc6532: false,
26774 simple: false,
26775 startAt: 'address-list',
26776 strict: false,
26777 atInDisplayName: false
26778 };
26779
26780 for (o in defaults) {
26781 if (isNullUndef(opts[o])) {
26782 opts[o] = !isNullUndef(defs[o]) ? defs[o] : defaults[o];
26783 }
26784 }
26785 return opts;
26786}
26787
26788parse5322.parseOneAddress = parseOneAddressSimple;
26789parse5322.parseAddressList = parseAddressListSimple;
26790parse5322.parseFrom = parseFromSimple;
26791parse5322.parseSender = parseSenderSimple;
26792parse5322.parseReplyTo = parseReplyToSimple;
26793
26794{
26795 module.exports = parse5322;
26796}
26797
26798}());
26799});
26800
26801// GPG4Browsers - An OpenPGP implementation in javascript
26802
26803/**
26804 * Implementation of the User ID Packet (Tag 13)
26805 *
26806 * A User ID packet consists of UTF-8 text that is intended to represent
26807 * the name and email address of the key holder. By convention, it
26808 * includes an RFC 2822 [RFC2822] mail name-addr, but there are no
26809 * restrictions on its content. The packet length in the header
26810 * specifies the length of the User ID.
26811 */
26812class UserIDPacket {
26813 static get tag() {
26814 return enums.packet.userID;
26815 }
26816
26817 constructor() {
26818 /** A string containing the user id. Usually in the form
26819 * John Doe <john@example.com>
26820 * @type {String}
26821 */
26822 this.userID = '';
26823
26824 this.name = '';
26825 this.email = '';
26826 this.comment = '';
26827 }
26828
26829 /**
26830 * Create UserIDPacket instance from object
26831 * @param {Object} userID - Object specifying userID name, email and comment
26832 * @returns {UserIDPacket}
26833 * @static
26834 */
26835 static fromObject(userID) {
26836 if (util.isString(userID) ||
26837 (userID.name && !util.isString(userID.name)) ||
26838 (userID.email && !util.isEmailAddress(userID.email)) ||
26839 (userID.comment && !util.isString(userID.comment))) {
26840 throw new Error('Invalid user ID format');
26841 }
26842 const packet = new UserIDPacket();
26843 Object.assign(packet, userID);
26844 const components = [];
26845 if (packet.name) components.push(packet.name);
26846 if (packet.comment) components.push(`(${packet.comment})`);
26847 if (packet.email) components.push(`<${packet.email}>`);
26848 packet.userID = components.join(' ');
26849 return packet;
26850 }
26851
26852 /**
26853 * Parsing function for a user id packet (tag 13).
26854 * @param {Uint8Array} input - Payload of a tag 13 packet
26855 */
26856 read(bytes, config = defaultConfig) {
26857 const userID = util.decodeUTF8(bytes);
26858 if (userID.length > config.maxUserIDLength) {
26859 throw new Error('User ID string is too long');
26860 }
26861 try {
26862 const { name, address: email, comments } = emailAddresses.parseOneAddress({ input: userID, atInDisplayName: true });
26863 this.comment = comments.replace(/^\(|\)$/g, '');
26864 this.name = name;
26865 this.email = email;
26866 } catch (e) {}
26867 this.userID = userID;
26868 }
26869
26870 /**
26871 * Creates a binary representation of the user id packet
26872 * @returns {Uint8Array} Binary representation.
26873 */
26874 write() {
26875 return util.encodeUTF8(this.userID);
26876 }
26877
26878 equals(otherUserID) {
26879 return otherUserID && otherUserID.userID === this.userID;
26880 }
26881}
26882
26883// GPG4Browsers - An OpenPGP implementation in javascript
26884
26885/**
26886 * A Secret-Subkey packet (tag 7) is the subkey analog of the Secret
26887 * Key packet and has exactly the same format.
26888 * @extends SecretKeyPacket
26889 */
26890class SecretSubkeyPacket extends SecretKeyPacket {
26891 static get tag() {
26892 return enums.packet.secretSubkey;
26893 }
26894
26895 /**
26896 * @param {Date} [date] - Creation date
26897 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26898 */
26899 constructor(date = new Date(), config = defaultConfig) {
26900 super(date, config);
26901 }
26902}
26903
26904/**
26905 * Implementation of the Trust Packet (Tag 12)
26906 *
26907 * {@link https://tools.ietf.org/html/rfc4880#section-5.10|RFC4880 5.10}:
26908 * The Trust packet is used only within keyrings and is not normally
26909 * exported. Trust packets contain data that record the user's
26910 * specifications of which key holders are trustworthy introducers,
26911 * along with other information that implementing software uses for
26912 * trust information. The format of Trust packets is defined by a given
26913 * implementation.
26914 *
26915 * Trust packets SHOULD NOT be emitted to output streams that are
26916 * transferred to other users, and they SHOULD be ignored on any input
26917 * other than local keyring files.
26918 */
26919class TrustPacket {
26920 static get tag() {
26921 return enums.packet.trust;
26922 }
26923
26924 /**
26925 * Parsing function for a trust packet (tag 12).
26926 * Currently not implemented as we ignore trust packets
26927 */
26928 read() {
26929 throw new UnsupportedError('Trust packets are not supported');
26930 }
26931
26932 write() {
26933 throw new UnsupportedError('Trust packets are not supported');
26934 }
26935}
26936
26937// GPG4Browsers - An OpenPGP implementation in javascript
26938
26939// A Signature can contain the following packets
26940const allowedPackets$4 = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
26941
26942/**
26943 * Class that represents an OpenPGP signature.
26944 */
26945class Signature {
26946 /**
26947 * @param {PacketList} packetlist - The signature packets
26948 */
26949 constructor(packetlist) {
26950 this.packets = packetlist || new PacketList();
26951 }
26952
26953 /**
26954 * Returns binary encoded signature
26955 * @returns {ReadableStream<Uint8Array>} Binary signature.
26956 */
26957 write() {
26958 return this.packets.write();
26959 }
26960
26961 /**
26962 * Returns ASCII armored text of signature
26963 * @param {Object} [config] - Full configuration, defaults to openpgp.config
26964 * @returns {ReadableStream<String>} ASCII armor.
26965 */
26966 armor(config = defaultConfig) {
26967 return armor(enums.armor.signature, this.write(), undefined, undefined, undefined, config);
26968 }
26969
26970 /**
26971 * Returns an array of KeyIDs of all of the issuers who created this signature
26972 * @returns {Array<KeyID>} The Key IDs of the signing keys
26973 */
26974 getSigningKeyIDs() {
26975 return this.packets.map(packet => packet.issuerKeyID);
26976 }
26977}
26978
26979/**
26980 * reads an (optionally armored) OpenPGP signature and returns a signature object
26981 * @param {Object} options
26982 * @param {String} [options.armoredSignature] - Armored signature to be parsed
26983 * @param {Uint8Array} [options.binarySignature] - Binary signature to be parsed
26984 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
26985 * @returns {Promise<Signature>} New signature object.
26986 * @async
26987 * @static
26988 */
26989async function readSignature({ armoredSignature, binarySignature, config, ...rest }) {
26990 config = { ...defaultConfig, ...config };
26991 let input = armoredSignature || binarySignature;
26992 if (!input) {
26993 throw new Error('readSignature: must pass options object containing `armoredSignature` or `binarySignature`');
26994 }
26995 if (armoredSignature && !util.isString(armoredSignature)) {
26996 throw new Error('readSignature: options.armoredSignature must be a string');
26997 }
26998 if (binarySignature && !util.isUint8Array(binarySignature)) {
26999 throw new Error('readSignature: options.binarySignature must be a Uint8Array');
27000 }
27001 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
27002
27003 if (armoredSignature) {
27004 const { type, data } = await unarmor(input, config);
27005 if (type !== enums.armor.signature) {
27006 throw new Error('Armored text not of type signature');
27007 }
27008 input = data;
27009 }
27010 const packetlist = await PacketList.fromBinary(input, allowedPackets$4, config);
27011 return new Signature(packetlist);
27012}
27013
27014/**
27015 * @fileoverview Provides helpers methods for key module
27016 * @module key/helper
27017 * @private
27018 */
27019
27020async function generateSecretSubkey(options, config) {
27021 const secretSubkeyPacket = new SecretSubkeyPacket(options.date, config);
27022 secretSubkeyPacket.packets = null;
27023 secretSubkeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm);
27024 await secretSubkeyPacket.generate(options.rsaBits, options.curve);
27025 await secretSubkeyPacket.computeFingerprintAndKeyID();
27026 return secretSubkeyPacket;
27027}
27028
27029async function generateSecretKey(options, config) {
27030 const secretKeyPacket = new SecretKeyPacket(options.date, config);
27031 secretKeyPacket.packets = null;
27032 secretKeyPacket.algorithm = enums.write(enums.publicKey, options.algorithm);
27033 await secretKeyPacket.generate(options.rsaBits, options.curve, options.config);
27034 await secretKeyPacket.computeFingerprintAndKeyID();
27035 return secretKeyPacket;
27036}
27037
27038/**
27039 * Returns the valid and non-expired signature that has the latest creation date, while ignoring signatures created in the future.
27040 * @param {Array<SignaturePacket>} signatures - List of signatures
27041 * @param {PublicKeyPacket|PublicSubkeyPacket} publicKey - Public key packet to verify the signature
27042 * @param {Date} date - Use the given date instead of the current time
27043 * @param {Object} config - full configuration
27044 * @returns {Promise<SignaturePacket>} The latest valid signature.
27045 * @async
27046 */
27047async function getLatestValidSignature(signatures, publicKey, signatureType, dataToVerify, date = new Date(), config) {
27048 let latestValid;
27049 let exception;
27050 for (let i = signatures.length - 1; i >= 0; i--) {
27051 try {
27052 if (
27053 (!latestValid || signatures[i].created >= latestValid.created)
27054 ) {
27055 await signatures[i].verify(publicKey, signatureType, dataToVerify, date, undefined, config);
27056 latestValid = signatures[i];
27057 }
27058 } catch (e) {
27059 exception = e;
27060 }
27061 }
27062 if (!latestValid) {
27063 throw util.wrapError(
27064 `Could not find valid ${enums.read(enums.signature, signatureType)} signature in key ${publicKey.getKeyID().toHex()}`
27065 .replace('certGeneric ', 'self-')
27066 .replace(/([a-z])([A-Z])/g, (_, $1, $2) => $1 + ' ' + $2.toLowerCase())
27067 , exception);
27068 }
27069 return latestValid;
27070}
27071
27072function isDataExpired(keyPacket, signature, date = new Date()) {
27073 const normDate = util.normalizeDate(date);
27074 if (normDate !== null) {
27075 const expirationTime = getKeyExpirationTime(keyPacket, signature);
27076 return !(keyPacket.created <= normDate && normDate < expirationTime);
27077 }
27078 return false;
27079}
27080
27081/**
27082 * Create Binding signature to the key according to the {@link https://tools.ietf.org/html/rfc4880#section-5.2.1}
27083 * @param {SecretSubkeyPacket} subkey - Subkey key packet
27084 * @param {SecretKeyPacket} primaryKey - Primary key packet
27085 * @param {Object} options
27086 * @param {Object} config - Full configuration
27087 */
27088async function createBindingSignature(subkey, primaryKey, options, config) {
27089 const dataToSign = {};
27090 dataToSign.key = primaryKey;
27091 dataToSign.bind = subkey;
27092 const subkeySignaturePacket = new SignaturePacket();
27093 subkeySignaturePacket.signatureType = enums.signature.subkeyBinding;
27094 subkeySignaturePacket.publicKeyAlgorithm = primaryKey.algorithm;
27095 subkeySignaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, subkey, undefined, undefined, config);
27096 if (options.sign) {
27097 subkeySignaturePacket.keyFlags = [enums.keyFlags.signData];
27098 subkeySignaturePacket.embeddedSignature = await createSignaturePacket(dataToSign, null, subkey, {
27099 signatureType: enums.signature.keyBinding
27100 }, options.date, undefined, undefined, config);
27101 } else {
27102 subkeySignaturePacket.keyFlags = [enums.keyFlags.encryptCommunication | enums.keyFlags.encryptStorage];
27103 }
27104 if (options.keyExpirationTime > 0) {
27105 subkeySignaturePacket.keyExpirationTime = options.keyExpirationTime;
27106 subkeySignaturePacket.keyNeverExpires = false;
27107 }
27108 await subkeySignaturePacket.sign(primaryKey, dataToSign, options.date);
27109 return subkeySignaturePacket;
27110}
27111
27112/**
27113 * Returns the preferred signature hash algorithm of a key
27114 * @param {Key} [key] - The key to get preferences from
27115 * @param {SecretKeyPacket|SecretSubkeyPacket} keyPacket - key packet used for signing
27116 * @param {Date} [date] - Use the given date for verification instead of the current time
27117 * @param {Object} [userID] - User ID
27118 * @param {Object} config - full configuration
27119 * @returns {Promise<enums.hash>}
27120 * @async
27121 */
27122async function getPreferredHashAlgo$1(key, keyPacket, date = new Date(), userID = {}, config) {
27123 let hashAlgo = config.preferredHashAlgorithm;
27124 let prefAlgo = hashAlgo;
27125 if (key) {
27126 const primaryUser = await key.getPrimaryUser(date, userID, config);
27127 if (primaryUser.selfCertification.preferredHashAlgorithms) {
27128 [prefAlgo] = primaryUser.selfCertification.preferredHashAlgorithms;
27129 hashAlgo = mod.hash.getHashByteLength(hashAlgo) <= mod.hash.getHashByteLength(prefAlgo) ?
27130 prefAlgo : hashAlgo;
27131 }
27132 }
27133 switch (Object.getPrototypeOf(keyPacket)) {
27134 case SecretKeyPacket.prototype:
27135 case PublicKeyPacket.prototype:
27136 case SecretSubkeyPacket.prototype:
27137 case PublicSubkeyPacket.prototype:
27138 switch (keyPacket.algorithm) {
27139 case enums.publicKey.ecdh:
27140 case enums.publicKey.ecdsa:
27141 case enums.publicKey.eddsa:
27142 prefAlgo = mod.publicKey.elliptic.getPreferredHashAlgo(keyPacket.publicParams.oid);
27143 }
27144 }
27145 return mod.hash.getHashByteLength(hashAlgo) <= mod.hash.getHashByteLength(prefAlgo) ?
27146 prefAlgo : hashAlgo;
27147}
27148
27149/**
27150 * Returns the preferred symmetric/aead/compression algorithm for a set of keys
27151 * @param {'symmetric'|'aead'|'compression'} type - Type of preference to return
27152 * @param {Array<Key>} [keys] - Set of keys
27153 * @param {Date} [date] - Use the given date for verification instead of the current time
27154 * @param {Array} [userIDs] - User IDs
27155 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27156 * @returns {Promise<module:enums.symmetric|aead|compression>} Preferred algorithm
27157 * @async
27158 */
27159async function getPreferredAlgo(type, keys = [], date = new Date(), userIDs = [], config = defaultConfig) {
27160 const defaultAlgo = { // these are all must-implement in rfc4880bis
27161 'symmetric': enums.symmetric.aes128,
27162 'aead': enums.aead.eax,
27163 'compression': enums.compression.uncompressed
27164 }[type];
27165 const preferredSenderAlgo = {
27166 'symmetric': config.preferredSymmetricAlgorithm,
27167 'aead': config.preferredAEADAlgorithm,
27168 'compression': config.preferredCompressionAlgorithm
27169 }[type];
27170 const prefPropertyName = {
27171 'symmetric': 'preferredSymmetricAlgorithms',
27172 'aead': 'preferredAEADAlgorithms',
27173 'compression': 'preferredCompressionAlgorithms'
27174 }[type];
27175
27176 // if preferredSenderAlgo appears in the prefs of all recipients, we pick it
27177 // otherwise we use the default algo
27178 // if no keys are available, preferredSenderAlgo is returned
27179 const senderAlgoSupport = await Promise.all(keys.map(async function(key, i) {
27180 const primaryUser = await key.getPrimaryUser(date, userIDs[i], config);
27181 const recipientPrefs = primaryUser.selfCertification[prefPropertyName];
27182 return !!recipientPrefs && recipientPrefs.indexOf(preferredSenderAlgo) >= 0;
27183 }));
27184 return senderAlgoSupport.every(Boolean) ? preferredSenderAlgo : defaultAlgo;
27185}
27186
27187/**
27188 * Create signature packet
27189 * @param {Object} dataToSign - Contains packets to be signed
27190 * @param {PrivateKey} privateKey - key to get preferences from
27191 * @param {SecretKeyPacket|
27192 * SecretSubkeyPacket} signingKeyPacket secret key packet for signing
27193 * @param {Object} [signatureProperties] - Properties to write on the signature packet before signing
27194 * @param {Date} [date] - Override the creationtime of the signature
27195 * @param {Object} [userID] - User ID
27196 * @param {Object} [detached] - Whether to create a detached signature packet
27197 * @param {Object} config - full configuration
27198 * @returns {Promise<SignaturePacket>} Signature packet.
27199 */
27200async function createSignaturePacket(dataToSign, privateKey, signingKeyPacket, signatureProperties, date, userID, detached = false, config) {
27201 if (signingKeyPacket.isDummy()) {
27202 throw new Error('Cannot sign with a gnu-dummy key.');
27203 }
27204 if (!signingKeyPacket.isDecrypted()) {
27205 throw new Error('Signing key is not decrypted.');
27206 }
27207 const signaturePacket = new SignaturePacket();
27208 Object.assign(signaturePacket, signatureProperties);
27209 signaturePacket.publicKeyAlgorithm = signingKeyPacket.algorithm;
27210 signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(privateKey, signingKeyPacket, date, userID, config);
27211 await signaturePacket.sign(signingKeyPacket, dataToSign, date, detached);
27212 return signaturePacket;
27213}
27214
27215/**
27216 * Merges signatures from source[attr] to dest[attr]
27217 * @param {Object} source
27218 * @param {Object} dest
27219 * @param {String} attr
27220 * @param {Date} [date] - date to use for signature expiration check, instead of the current time
27221 * @param {Function} [checkFn] - signature only merged if true
27222 */
27223async function mergeSignatures(source, dest, attr, date = new Date(), checkFn) {
27224 source = source[attr];
27225 if (source) {
27226 if (!dest[attr].length) {
27227 dest[attr] = source;
27228 } else {
27229 await Promise.all(source.map(async function(sourceSig) {
27230 if (!sourceSig.isExpired(date) && (!checkFn || await checkFn(sourceSig)) &&
27231 !dest[attr].some(function(destSig) {
27232 return util.equalsUint8Array(destSig.writeParams(), sourceSig.writeParams());
27233 })) {
27234 dest[attr].push(sourceSig);
27235 }
27236 }));
27237 }
27238 }
27239}
27240
27241/**
27242 * Checks if a given certificate or binding signature is revoked
27243 * @param {SecretKeyPacket|
27244 * PublicKeyPacket} primaryKey The primary key packet
27245 * @param {Object} dataToVerify - The data to check
27246 * @param {Array<SignaturePacket>} revocations - The revocation signatures to check
27247 * @param {SignaturePacket} signature - The certificate or signature to check
27248 * @param {PublicSubkeyPacket|
27249 * SecretSubkeyPacket|
27250 * PublicKeyPacket|
27251 * SecretKeyPacket} key, optional The key packet to verify the signature, instead of the primary key
27252 * @param {Date} date - Use the given date instead of the current time
27253 * @param {Object} config - Full configuration
27254 * @returns {Promise<Boolean>} True if the signature revokes the data.
27255 * @async
27256 */
27257async function isDataRevoked(primaryKey, signatureType, dataToVerify, revocations, signature, key, date = new Date(), config) {
27258 key = key || primaryKey;
27259 const revocationKeyIDs = [];
27260 await Promise.all(revocations.map(async function(revocationSignature) {
27261 try {
27262 if (
27263 // Note: a third-party revocation signature could legitimately revoke a
27264 // self-signature if the signature has an authorized revocation key.
27265 // However, we don't support passing authorized revocation keys, nor
27266 // verifying such revocation signatures. Instead, we indicate an error
27267 // when parsing a key with an authorized revocation key, and ignore
27268 // third-party revocation signatures here. (It could also be revoking a
27269 // third-party key certification, which should only affect
27270 // `verifyAllCertifications`.)
27271 !signature || revocationSignature.issuerKeyID.equals(signature.issuerKeyID)
27272 ) {
27273 await revocationSignature.verify(
27274 key, signatureType, dataToVerify, config.revocationsExpire ? date : null, false, config
27275 );
27276
27277 // TODO get an identifier of the revoked object instead
27278 revocationKeyIDs.push(revocationSignature.issuerKeyID);
27279 }
27280 } catch (e) {}
27281 }));
27282 // TODO further verify that this is the signature that should be revoked
27283 if (signature) {
27284 signature.revoked = revocationKeyIDs.some(keyID => keyID.equals(signature.issuerKeyID)) ? true :
27285 signature.revoked || false;
27286 return signature.revoked;
27287 }
27288 return revocationKeyIDs.length > 0;
27289}
27290
27291/**
27292 * Returns key expiration time based on the given certification signature.
27293 * The expiration time of the signature is ignored.
27294 * @param {PublicSubkeyPacket|PublicKeyPacket} keyPacket - key to check
27295 * @param {SignaturePacket} signature - signature to process
27296 * @returns {Date|Infinity} expiration time or infinity if the key does not expire
27297 */
27298function getKeyExpirationTime(keyPacket, signature) {
27299 let expirationTime;
27300 // check V4 expiration time
27301 if (signature.keyNeverExpires === false) {
27302 expirationTime = keyPacket.created.getTime() + signature.keyExpirationTime * 1000;
27303 }
27304 return expirationTime ? new Date(expirationTime) : Infinity;
27305}
27306
27307/**
27308 * Returns whether aead is supported by all keys in the set
27309 * @param {Array<Key>} keys - Set of keys
27310 * @param {Date} [date] - Use the given date for verification instead of the current time
27311 * @param {Array} [userIDs] - User IDs
27312 * @param {Object} config - full configuration
27313 * @returns {Promise<Boolean>}
27314 * @async
27315 */
27316async function isAEADSupported(keys, date = new Date(), userIDs = [], config = defaultConfig) {
27317 let supported = true;
27318 // TODO replace when Promise.some or Promise.any are implemented
27319 await Promise.all(keys.map(async function(key, i) {
27320 const primaryUser = await key.getPrimaryUser(date, userIDs[i], config);
27321 if (!primaryUser.selfCertification.features ||
27322 !(primaryUser.selfCertification.features[0] & enums.features.aead)) {
27323 supported = false;
27324 }
27325 }));
27326 return supported;
27327}
27328
27329function sanitizeKeyOptions(options, subkeyDefaults = {}) {
27330 options.type = options.type || subkeyDefaults.type;
27331 options.curve = options.curve || subkeyDefaults.curve;
27332 options.rsaBits = options.rsaBits || subkeyDefaults.rsaBits;
27333 options.keyExpirationTime = options.keyExpirationTime !== undefined ? options.keyExpirationTime : subkeyDefaults.keyExpirationTime;
27334 options.passphrase = util.isString(options.passphrase) ? options.passphrase : subkeyDefaults.passphrase;
27335 options.date = options.date || subkeyDefaults.date;
27336
27337 options.sign = options.sign || false;
27338
27339 switch (options.type) {
27340 case 'ecc':
27341 try {
27342 options.curve = enums.write(enums.curve, options.curve);
27343 } catch (e) {
27344 throw new Error('Unknown curve');
27345 }
27346 if (options.curve === enums.curve.ed25519 || options.curve === enums.curve.curve25519) {
27347 options.curve = options.sign ? enums.curve.ed25519 : enums.curve.curve25519;
27348 }
27349 if (options.sign) {
27350 options.algorithm = options.curve === enums.curve.ed25519 ? enums.publicKey.eddsa : enums.publicKey.ecdsa;
27351 } else {
27352 options.algorithm = enums.publicKey.ecdh;
27353 }
27354 break;
27355 case 'rsa':
27356 options.algorithm = enums.publicKey.rsaEncryptSign;
27357 break;
27358 default:
27359 throw new Error(`Unsupported key type ${options.type}`);
27360 }
27361 return options;
27362}
27363
27364function isValidSigningKeyPacket(keyPacket, signature) {
27365 const keyAlgo = keyPacket.algorithm;
27366 return keyAlgo !== enums.publicKey.rsaEncrypt &&
27367 keyAlgo !== enums.publicKey.elgamal &&
27368 keyAlgo !== enums.publicKey.ecdh &&
27369 (!signature.keyFlags ||
27370 (signature.keyFlags[0] & enums.keyFlags.signData) !== 0);
27371}
27372
27373function isValidEncryptionKeyPacket(keyPacket, signature) {
27374 const keyAlgo = keyPacket.algorithm;
27375 return keyAlgo !== enums.publicKey.dsa &&
27376 keyAlgo !== enums.publicKey.rsaSign &&
27377 keyAlgo !== enums.publicKey.ecdsa &&
27378 keyAlgo !== enums.publicKey.eddsa &&
27379 (!signature.keyFlags ||
27380 (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
27381 (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0);
27382}
27383
27384function isValidDecryptionKeyPacket(signature, config) {
27385 if (config.allowInsecureDecryptionWithSigningKeys) {
27386 // This is only relevant for RSA keys, all other signing algorithms cannot decrypt
27387 return true;
27388 }
27389
27390 return !signature.keyFlags ||
27391 (signature.keyFlags[0] & enums.keyFlags.encryptCommunication) !== 0 ||
27392 (signature.keyFlags[0] & enums.keyFlags.encryptStorage) !== 0;
27393}
27394
27395/**
27396 * Check key against blacklisted algorithms and minimum strength requirements.
27397 * @param {SecretKeyPacket|PublicKeyPacket|
27398 * SecretSubkeyPacket|PublicSubkeyPacket} keyPacket
27399 * @param {Config} config
27400 * @throws {Error} if the key packet does not meet the requirements
27401 */
27402function checkKeyRequirements(keyPacket, config) {
27403 const keyAlgo = enums.write(enums.publicKey, keyPacket.algorithm);
27404 const algoInfo = keyPacket.getAlgorithmInfo();
27405 if (config.rejectPublicKeyAlgorithms.has(keyAlgo)) {
27406 throw new Error(`${algoInfo.algorithm} keys are considered too weak.`);
27407 }
27408 switch (keyAlgo) {
27409 case enums.publicKey.rsaEncryptSign:
27410 case enums.publicKey.rsaSign:
27411 case enums.publicKey.rsaEncrypt:
27412 if (algoInfo.bits < config.minRSABits) {
27413 throw new Error(`RSA keys shorter than ${config.minRSABits} bits are considered too weak.`);
27414 }
27415 break;
27416 case enums.publicKey.ecdsa:
27417 case enums.publicKey.eddsa:
27418 case enums.publicKey.ecdh:
27419 if (config.rejectCurves.has(algoInfo.curve)) {
27420 throw new Error(`Support for ${algoInfo.algorithm} keys using curve ${algoInfo.curve} is disabled.`);
27421 }
27422 break;
27423 }
27424}
27425
27426/**
27427 * @module key/User
27428 * @private
27429 */
27430
27431/**
27432 * Class that represents an user ID or attribute packet and the relevant signatures.
27433 * @param {UserIDPacket|UserAttributePacket} userPacket - packet containing the user info
27434 * @param {Key} mainKey - reference to main Key object containing the primary key and subkeys that the user is associated with
27435 */
27436class User {
27437 constructor(userPacket, mainKey) {
27438 this.userID = userPacket.constructor.tag === enums.packet.userID ? userPacket : null;
27439 this.userAttribute = userPacket.constructor.tag === enums.packet.userAttribute ? userPacket : null;
27440 this.selfCertifications = [];
27441 this.otherCertifications = [];
27442 this.revocationSignatures = [];
27443 this.mainKey = mainKey;
27444 }
27445
27446 /**
27447 * Transforms structured user data to packetlist
27448 * @returns {PacketList}
27449 */
27450 toPacketList() {
27451 const packetlist = new PacketList();
27452 packetlist.push(this.userID || this.userAttribute);
27453 packetlist.push(...this.revocationSignatures);
27454 packetlist.push(...this.selfCertifications);
27455 packetlist.push(...this.otherCertifications);
27456 return packetlist;
27457 }
27458
27459 /**
27460 * Shallow clone
27461 * @returns {User}
27462 */
27463 clone() {
27464 const user = new User(this.userID || this.userAttribute, this.mainKey);
27465 user.selfCertifications = [...this.selfCertifications];
27466 user.otherCertifications = [...this.otherCertifications];
27467 user.revocationSignatures = [...this.revocationSignatures];
27468 return user;
27469 }
27470
27471 /**
27472 * Generate third-party certifications over this user and its primary key
27473 * @param {Array<PrivateKey>} signingKeys - Decrypted private keys for signing
27474 * @param {Date} [date] - Date to use as creation date of the certificate, instead of the current time
27475 * @param {Object} config - Full configuration
27476 * @returns {Promise<User>} New user with new certifications.
27477 * @async
27478 */
27479 async certify(signingKeys, date, config) {
27480 const primaryKey = this.mainKey.keyPacket;
27481 const dataToSign = {
27482 userID: this.userID,
27483 userAttribute: this.userAttribute,
27484 key: primaryKey
27485 };
27486 const user = new User(dataToSign.userID || dataToSign.userAttribute, this.mainKey);
27487 user.otherCertifications = await Promise.all(signingKeys.map(async function(privateKey) {
27488 if (!privateKey.isPrivate()) {
27489 throw new Error('Need private key for signing');
27490 }
27491 if (privateKey.hasSameFingerprintAs(primaryKey)) {
27492 throw new Error("The user's own key can only be used for self-certifications");
27493 }
27494 const signingKey = await privateKey.getSigningKey(undefined, date, undefined, config);
27495 return createSignaturePacket(dataToSign, privateKey, signingKey.keyPacket, {
27496 // Most OpenPGP implementations use generic certification (0x10)
27497 signatureType: enums.signature.certGeneric,
27498 keyFlags: [enums.keyFlags.certifyKeys | enums.keyFlags.signData]
27499 }, date, undefined, undefined, config);
27500 }));
27501 await user.update(this, date, config);
27502 return user;
27503 }
27504
27505 /**
27506 * Checks if a given certificate of the user is revoked
27507 * @param {SignaturePacket} certificate - The certificate to verify
27508 * @param {PublicSubkeyPacket|
27509 * SecretSubkeyPacket|
27510 * PublicKeyPacket|
27511 * SecretKeyPacket} [keyPacket] The key packet to verify the signature, instead of the primary key
27512 * @param {Date} [date] - Use the given date for verification instead of the current time
27513 * @param {Object} config - Full configuration
27514 * @returns {Promise<Boolean>} True if the certificate is revoked.
27515 * @async
27516 */
27517 async isRevoked(certificate, keyPacket, date = new Date(), config) {
27518 const primaryKey = this.mainKey.keyPacket;
27519 return isDataRevoked(primaryKey, enums.signature.certRevocation, {
27520 key: primaryKey,
27521 userID: this.userID,
27522 userAttribute: this.userAttribute
27523 }, this.revocationSignatures, certificate, keyPacket, date, config);
27524 }
27525
27526 /**
27527 * Verifies the user certificate.
27528 * @param {SignaturePacket} certificate - A certificate of this user
27529 * @param {Array<PublicKey>} verificationKeys - Array of keys to verify certificate signatures
27530 * @param {Date} [date] - Use the given date instead of the current time
27531 * @param {Object} config - Full configuration
27532 * @returns {Promise<true|null>} true if the certificate could be verified, or null if the verification keys do not correspond to the certificate
27533 * @throws if the user certificate is invalid.
27534 * @async
27535 */
27536 async verifyCertificate(certificate, verificationKeys, date = new Date(), config) {
27537 const that = this;
27538 const primaryKey = this.mainKey.keyPacket;
27539 const dataToVerify = {
27540 userID: this.userID,
27541 userAttribute: this.userAttribute,
27542 key: primaryKey
27543 };
27544 const { issuerKeyID } = certificate;
27545 const issuerKeys = verificationKeys.filter(key => key.getKeys(issuerKeyID).length > 0);
27546 if (issuerKeys.length === 0) {
27547 return null;
27548 }
27549 await Promise.all(issuerKeys.map(async key => {
27550 const signingKey = await key.getSigningKey(issuerKeyID, certificate.created, undefined, config);
27551 if (certificate.revoked || await that.isRevoked(certificate, signingKey.keyPacket, date, config)) {
27552 throw new Error('User certificate is revoked');
27553 }
27554 try {
27555 await certificate.verify(signingKey.keyPacket, enums.signature.certGeneric, dataToVerify, date, undefined, config);
27556 } catch (e) {
27557 throw util.wrapError('User certificate is invalid', e);
27558 }
27559 }));
27560 return true;
27561 }
27562
27563 /**
27564 * Verifies all user certificates
27565 * @param {Array<PublicKey>} verificationKeys - Array of keys to verify certificate signatures
27566 * @param {Date} [date] - Use the given date instead of the current time
27567 * @param {Object} config - Full configuration
27568 * @returns {Promise<Array<{
27569 * keyID: module:type/keyid~KeyID,
27570 * valid: Boolean | null
27571 * }>>} List of signer's keyID and validity of signature.
27572 * Signature validity is null if the verification keys do not correspond to the certificate.
27573 * @async
27574 */
27575 async verifyAllCertifications(verificationKeys, date = new Date(), config) {
27576 const that = this;
27577 const certifications = this.selfCertifications.concat(this.otherCertifications);
27578 return Promise.all(certifications.map(async certification => ({
27579 keyID: certification.issuerKeyID,
27580 valid: await that.verifyCertificate(certification, verificationKeys, date, config).catch(() => false)
27581 })));
27582 }
27583
27584 /**
27585 * Verify User. Checks for existence of self signatures, revocation signatures
27586 * and validity of self signature.
27587 * @param {Date} date - Use the given date instead of the current time
27588 * @param {Object} config - Full configuration
27589 * @returns {Promise<true>} Status of user.
27590 * @throws {Error} if there are no valid self signatures.
27591 * @async
27592 */
27593 async verify(date = new Date(), config) {
27594 if (!this.selfCertifications.length) {
27595 throw new Error('No self-certifications found');
27596 }
27597 const that = this;
27598 const primaryKey = this.mainKey.keyPacket;
27599 const dataToVerify = {
27600 userID: this.userID,
27601 userAttribute: this.userAttribute,
27602 key: primaryKey
27603 };
27604 // TODO replace when Promise.some or Promise.any are implemented
27605 let exception;
27606 for (let i = this.selfCertifications.length - 1; i >= 0; i--) {
27607 try {
27608 const selfCertification = this.selfCertifications[i];
27609 if (selfCertification.revoked || await that.isRevoked(selfCertification, undefined, date, config)) {
27610 throw new Error('Self-certification is revoked');
27611 }
27612 try {
27613 await selfCertification.verify(primaryKey, enums.signature.certGeneric, dataToVerify, date, undefined, config);
27614 } catch (e) {
27615 throw util.wrapError('Self-certification is invalid', e);
27616 }
27617 return true;
27618 } catch (e) {
27619 exception = e;
27620 }
27621 }
27622 throw exception;
27623 }
27624
27625 /**
27626 * Update user with new components from specified user
27627 * @param {User} sourceUser - Source user to merge
27628 * @param {Date} date - Date to verify the validity of signatures
27629 * @param {Object} config - Full configuration
27630 * @returns {Promise<undefined>}
27631 * @async
27632 */
27633 async update(sourceUser, date, config) {
27634 const primaryKey = this.mainKey.keyPacket;
27635 const dataToVerify = {
27636 userID: this.userID,
27637 userAttribute: this.userAttribute,
27638 key: primaryKey
27639 };
27640 // self signatures
27641 await mergeSignatures(sourceUser, this, 'selfCertifications', date, async function(srcSelfSig) {
27642 try {
27643 await srcSelfSig.verify(primaryKey, enums.signature.certGeneric, dataToVerify, date, false, config);
27644 return true;
27645 } catch (e) {
27646 return false;
27647 }
27648 });
27649 // other signatures
27650 await mergeSignatures(sourceUser, this, 'otherCertifications', date);
27651 // revocation signatures
27652 await mergeSignatures(sourceUser, this, 'revocationSignatures', date, function(srcRevSig) {
27653 return isDataRevoked(primaryKey, enums.signature.certRevocation, dataToVerify, [srcRevSig], undefined, undefined, date, config);
27654 });
27655 }
27656}
27657
27658/**
27659 * @module key/Subkey
27660 * @private
27661 */
27662
27663/**
27664 * Class that represents a subkey packet and the relevant signatures.
27665 * @borrows PublicSubkeyPacket#getKeyID as Subkey#getKeyID
27666 * @borrows PublicSubkeyPacket#getFingerprint as Subkey#getFingerprint
27667 * @borrows PublicSubkeyPacket#hasSameFingerprintAs as Subkey#hasSameFingerprintAs
27668 * @borrows PublicSubkeyPacket#getAlgorithmInfo as Subkey#getAlgorithmInfo
27669 * @borrows PublicSubkeyPacket#getCreationTime as Subkey#getCreationTime
27670 * @borrows PublicSubkeyPacket#isDecrypted as Subkey#isDecrypted
27671 */
27672class Subkey {
27673 /**
27674 * @param {SecretSubkeyPacket|PublicSubkeyPacket} subkeyPacket - subkey packet to hold in the Subkey
27675 * @param {Key} mainKey - reference to main Key object, containing the primary key packet corresponding to the subkey
27676 */
27677 constructor(subkeyPacket, mainKey) {
27678 this.keyPacket = subkeyPacket;
27679 this.bindingSignatures = [];
27680 this.revocationSignatures = [];
27681 this.mainKey = mainKey;
27682 }
27683
27684 /**
27685 * Transforms structured subkey data to packetlist
27686 * @returns {PacketList}
27687 */
27688 toPacketList() {
27689 const packetlist = new PacketList();
27690 packetlist.push(this.keyPacket);
27691 packetlist.push(...this.revocationSignatures);
27692 packetlist.push(...this.bindingSignatures);
27693 return packetlist;
27694 }
27695
27696 /**
27697 * Shallow clone
27698 * @return {Subkey}
27699 */
27700 clone() {
27701 const subkey = new Subkey(this.keyPacket, this.mainKey);
27702 subkey.bindingSignatures = [...this.bindingSignatures];
27703 subkey.revocationSignatures = [...this.revocationSignatures];
27704 return subkey;
27705 }
27706
27707 /**
27708 * Checks if a binding signature of a subkey is revoked
27709 * @param {SignaturePacket} signature - The binding signature to verify
27710 * @param {PublicSubkeyPacket|
27711 * SecretSubkeyPacket|
27712 * PublicKeyPacket|
27713 * SecretKeyPacket} key, optional The key to verify the signature
27714 * @param {Date} [date] - Use the given date for verification instead of the current time
27715 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27716 * @returns {Promise<Boolean>} True if the binding signature is revoked.
27717 * @async
27718 */
27719 async isRevoked(signature, key, date = new Date(), config = defaultConfig) {
27720 const primaryKey = this.mainKey.keyPacket;
27721 return isDataRevoked(
27722 primaryKey, enums.signature.subkeyRevocation, {
27723 key: primaryKey,
27724 bind: this.keyPacket
27725 }, this.revocationSignatures, signature, key, date, config
27726 );
27727 }
27728
27729 /**
27730 * Verify subkey. Checks for revocation signatures, expiration time
27731 * and valid binding signature.
27732 * @param {Date} date - Use the given date instead of the current time
27733 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27734 * @returns {Promise<SignaturePacket>}
27735 * @throws {Error} if the subkey is invalid.
27736 * @async
27737 */
27738 async verify(date = new Date(), config = defaultConfig) {
27739 const primaryKey = this.mainKey.keyPacket;
27740 const dataToVerify = { key: primaryKey, bind: this.keyPacket };
27741 // check subkey binding signatures
27742 const bindingSignature = await getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
27743 // check binding signature is not revoked
27744 if (bindingSignature.revoked || await this.isRevoked(bindingSignature, null, date, config)) {
27745 throw new Error('Subkey is revoked');
27746 }
27747 // check for expiration time
27748 if (isDataExpired(this.keyPacket, bindingSignature, date)) {
27749 throw new Error('Subkey is expired');
27750 }
27751 return bindingSignature;
27752 }
27753
27754 /**
27755 * Returns the expiration time of the subkey or Infinity if key does not expire.
27756 * Returns null if the subkey is invalid.
27757 * @param {Date} date - Use the given date instead of the current time
27758 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27759 * @returns {Promise<Date | Infinity | null>}
27760 * @async
27761 */
27762 async getExpirationTime(date = new Date(), config = defaultConfig) {
27763 const primaryKey = this.mainKey.keyPacket;
27764 const dataToVerify = { key: primaryKey, bind: this.keyPacket };
27765 let bindingSignature;
27766 try {
27767 bindingSignature = await getLatestValidSignature(this.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
27768 } catch (e) {
27769 return null;
27770 }
27771 const keyExpiry = getKeyExpirationTime(this.keyPacket, bindingSignature);
27772 const sigExpiry = bindingSignature.getExpirationTime();
27773 return keyExpiry < sigExpiry ? keyExpiry : sigExpiry;
27774 }
27775
27776 /**
27777 * Update subkey with new components from specified subkey
27778 * @param {Subkey} subkey - Source subkey to merge
27779 * @param {Date} [date] - Date to verify validity of signatures
27780 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27781 * @throws {Error} if update failed
27782 * @async
27783 */
27784 async update(subkey, date = new Date(), config = defaultConfig) {
27785 const primaryKey = this.mainKey.keyPacket;
27786 if (!this.hasSameFingerprintAs(subkey)) {
27787 throw new Error('Subkey update method: fingerprints of subkeys not equal');
27788 }
27789 // key packet
27790 if (this.keyPacket.constructor.tag === enums.packet.publicSubkey &&
27791 subkey.keyPacket.constructor.tag === enums.packet.secretSubkey) {
27792 this.keyPacket = subkey.keyPacket;
27793 }
27794 // update missing binding signatures
27795 const that = this;
27796 const dataToVerify = { key: primaryKey, bind: that.keyPacket };
27797 await mergeSignatures(subkey, this, 'bindingSignatures', date, async function(srcBindSig) {
27798 for (let i = 0; i < that.bindingSignatures.length; i++) {
27799 if (that.bindingSignatures[i].issuerKeyID.equals(srcBindSig.issuerKeyID)) {
27800 if (srcBindSig.created > that.bindingSignatures[i].created) {
27801 that.bindingSignatures[i] = srcBindSig;
27802 }
27803 return false;
27804 }
27805 }
27806 try {
27807 await srcBindSig.verify(primaryKey, enums.signature.subkeyBinding, dataToVerify, date, undefined, config);
27808 return true;
27809 } catch (e) {
27810 return false;
27811 }
27812 });
27813 // revocation signatures
27814 await mergeSignatures(subkey, this, 'revocationSignatures', date, function(srcRevSig) {
27815 return isDataRevoked(primaryKey, enums.signature.subkeyRevocation, dataToVerify, [srcRevSig], undefined, undefined, date, config);
27816 });
27817 }
27818
27819 /**
27820 * Revokes the subkey
27821 * @param {SecretKeyPacket} primaryKey - decrypted private primary key for revocation
27822 * @param {Object} reasonForRevocation - optional, object indicating the reason for revocation
27823 * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
27824 * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
27825 * @param {Date} date - optional, override the creationtime of the revocation signature
27826 * @param {Object} [config] - Full configuration, defaults to openpgp.config
27827 * @returns {Promise<Subkey>} New subkey with revocation signature.
27828 * @async
27829 */
27830 async revoke(
27831 primaryKey,
27832 {
27833 flag: reasonForRevocationFlag = enums.reasonForRevocation.noReason,
27834 string: reasonForRevocationString = ''
27835 } = {},
27836 date = new Date(),
27837 config = defaultConfig
27838 ) {
27839 const dataToSign = { key: primaryKey, bind: this.keyPacket };
27840 const subkey = new Subkey(this.keyPacket, this.mainKey);
27841 subkey.revocationSignatures.push(await createSignaturePacket(dataToSign, null, primaryKey, {
27842 signatureType: enums.signature.subkeyRevocation,
27843 reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
27844 reasonForRevocationString
27845 }, date, undefined, false, config));
27846 await subkey.update(this);
27847 return subkey;
27848 }
27849
27850 hasSameFingerprintAs(other) {
27851 return this.keyPacket.hasSameFingerprintAs(other.keyPacket || other);
27852 }
27853}
27854
27855['getKeyID', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'isDecrypted'].forEach(name => {
27856 Subkey.prototype[name] =
27857 function() {
27858 return this.keyPacket[name]();
27859 };
27860});
27861
27862// GPG4Browsers - An OpenPGP implementation in javascript
27863
27864// A key revocation certificate can contain the following packets
27865const allowedRevocationPackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
27866const mainKeyPacketTags = new Set([enums.packet.publicKey, enums.packet.privateKey]);
27867const keyPacketTags = new Set([
27868 enums.packet.publicKey, enums.packet.privateKey,
27869 enums.packet.publicSubkey, enums.packet.privateSubkey
27870]);
27871
27872/**
27873 * Abstract class that represents an OpenPGP key. Must contain a primary key.
27874 * Can contain additional subkeys, signatures, user ids, user attributes.
27875 * @borrows PublicKeyPacket#getKeyID as Key#getKeyID
27876 * @borrows PublicKeyPacket#getFingerprint as Key#getFingerprint
27877 * @borrows PublicKeyPacket#hasSameFingerprintAs as Key#hasSameFingerprintAs
27878 * @borrows PublicKeyPacket#getAlgorithmInfo as Key#getAlgorithmInfo
27879 * @borrows PublicKeyPacket#getCreationTime as Key#getCreationTime
27880 */
27881class Key {
27882 /**
27883 * Transforms packetlist to structured key data
27884 * @param {PacketList} packetlist - The packets that form a key
27885 * @param {Set<enums.packet>} disallowedPackets - disallowed packet tags
27886 */
27887 packetListToStructure(packetlist, disallowedPackets = new Set()) {
27888 let user;
27889 let primaryKeyID;
27890 let subkey;
27891 let ignoreUntil;
27892
27893 for (const packet of packetlist) {
27894
27895 if (packet instanceof UnparseablePacket) {
27896 const isUnparseableKeyPacket = keyPacketTags.has(packet.tag);
27897 if (isUnparseableKeyPacket && !ignoreUntil){
27898 // Since non-key packets apply to the preceding key packet, if a (sub)key is Unparseable we must
27899 // discard all non-key packets that follow, until another (sub)key packet is found.
27900 if (mainKeyPacketTags.has(packet.tag)) {
27901 ignoreUntil = mainKeyPacketTags;
27902 } else {
27903 ignoreUntil = keyPacketTags;
27904 }
27905 }
27906 continue;
27907 }
27908
27909 const tag = packet.constructor.tag;
27910 if (ignoreUntil) {
27911 if (!ignoreUntil.has(tag)) continue;
27912 ignoreUntil = null;
27913 }
27914 if (disallowedPackets.has(tag)) {
27915 throw new Error(`Unexpected packet type: ${tag}`);
27916 }
27917 switch (tag) {
27918 case enums.packet.publicKey:
27919 case enums.packet.secretKey:
27920 if (this.keyPacket) {
27921 throw new Error('Key block contains multiple keys');
27922 }
27923 this.keyPacket = packet;
27924 primaryKeyID = this.getKeyID();
27925 if (!primaryKeyID) {
27926 throw new Error('Missing Key ID');
27927 }
27928 break;
27929 case enums.packet.userID:
27930 case enums.packet.userAttribute:
27931 user = new User(packet, this);
27932 this.users.push(user);
27933 break;
27934 case enums.packet.publicSubkey:
27935 case enums.packet.secretSubkey:
27936 user = null;
27937 subkey = new Subkey(packet, this);
27938 this.subkeys.push(subkey);
27939 break;
27940 case enums.packet.signature:
27941 switch (packet.signatureType) {
27942 case enums.signature.certGeneric:
27943 case enums.signature.certPersona:
27944 case enums.signature.certCasual:
27945 case enums.signature.certPositive:
27946 if (!user) {
27947 util.printDebug('Dropping certification signatures without preceding user packet');
27948 continue;
27949 }
27950 if (packet.issuerKeyID.equals(primaryKeyID)) {
27951 user.selfCertifications.push(packet);
27952 } else {
27953 user.otherCertifications.push(packet);
27954 }
27955 break;
27956 case enums.signature.certRevocation:
27957 if (user) {
27958 user.revocationSignatures.push(packet);
27959 } else {
27960 this.directSignatures.push(packet);
27961 }
27962 break;
27963 case enums.signature.key:
27964 this.directSignatures.push(packet);
27965 break;
27966 case enums.signature.subkeyBinding:
27967 if (!subkey) {
27968 util.printDebug('Dropping subkey binding signature without preceding subkey packet');
27969 continue;
27970 }
27971 subkey.bindingSignatures.push(packet);
27972 break;
27973 case enums.signature.keyRevocation:
27974 this.revocationSignatures.push(packet);
27975 break;
27976 case enums.signature.subkeyRevocation:
27977 if (!subkey) {
27978 util.printDebug('Dropping subkey revocation signature without preceding subkey packet');
27979 continue;
27980 }
27981 subkey.revocationSignatures.push(packet);
27982 break;
27983 }
27984 break;
27985 }
27986 }
27987 }
27988
27989 /**
27990 * Transforms structured key data to packetlist
27991 * @returns {PacketList} The packets that form a key.
27992 */
27993 toPacketList() {
27994 const packetlist = new PacketList();
27995 packetlist.push(this.keyPacket);
27996 packetlist.push(...this.revocationSignatures);
27997 packetlist.push(...this.directSignatures);
27998 this.users.map(user => packetlist.push(...user.toPacketList()));
27999 this.subkeys.map(subkey => packetlist.push(...subkey.toPacketList()));
28000 return packetlist;
28001 }
28002
28003 /**
28004 * Clones the key object
28005 * @param {Boolean} [deep=false] Whether to return a deep clone
28006 * @returns {Promise<Key>} Clone of the key.
28007 */
28008 clone(deep = false) {
28009 const key = new this.constructor(this.toPacketList());
28010 if (deep) {
28011 key.getKeys().forEach(k => {
28012 // shallow clone the key packets
28013 k.keyPacket = Object.create(
28014 Object.getPrototypeOf(k.keyPacket),
28015 Object.getOwnPropertyDescriptors(k.keyPacket)
28016 );
28017 if (!k.keyPacket.isDecrypted()) return;
28018 // deep clone the private params, which are cleared during encryption
28019 const privateParams = {};
28020 Object.keys(k.keyPacket.privateParams).forEach(name => {
28021 privateParams[name] = new Uint8Array(k.keyPacket.privateParams[name]);
28022 });
28023 k.keyPacket.privateParams = privateParams;
28024 });
28025 }
28026 return key;
28027 }
28028
28029 /**
28030 * Returns an array containing all public or private subkeys matching keyID;
28031 * If no keyID is given, returns all subkeys.
28032 * @param {type/keyID} [keyID] - key ID to look for
28033 * @returns {Array<Subkey>} array of subkeys
28034 */
28035 getSubkeys(keyID = null) {
28036 const subkeys = this.subkeys.filter(subkey => (
28037 !keyID || subkey.getKeyID().equals(keyID, true)
28038 ));
28039 return subkeys;
28040 }
28041
28042 /**
28043 * Returns an array containing all public or private keys matching keyID.
28044 * If no keyID is given, returns all keys, starting with the primary key.
28045 * @param {type/keyid~KeyID} [keyID] - key ID to look for
28046 * @returns {Array<Key|Subkey>} array of keys
28047 */
28048 getKeys(keyID = null) {
28049 const keys = [];
28050 if (!keyID || this.getKeyID().equals(keyID, true)) {
28051 keys.push(this);
28052 }
28053 return keys.concat(this.getSubkeys(keyID));
28054 }
28055
28056 /**
28057 * Returns key IDs of all keys
28058 * @returns {Array<module:type/keyid~KeyID>}
28059 */
28060 getKeyIDs() {
28061 return this.getKeys().map(key => key.getKeyID());
28062 }
28063
28064 /**
28065 * Returns userIDs
28066 * @returns {Array<string>} Array of userIDs.
28067 */
28068 getUserIDs() {
28069 return this.users.map(user => {
28070 return user.userID ? user.userID.userID : null;
28071 }).filter(userID => userID !== null);
28072 }
28073
28074 /**
28075 * Returns binary encoded key
28076 * @returns {Uint8Array} Binary key.
28077 */
28078 write() {
28079 return this.toPacketList().write();
28080 }
28081
28082 /**
28083 * Returns last created key or key by given keyID that is available for signing and verification
28084 * @param {module:type/keyid~KeyID} [keyID] - key ID of a specific key to retrieve
28085 * @param {Date} [date] - use the fiven date date to to check key validity instead of the current date
28086 * @param {Object} [userID] - filter keys for the given user ID
28087 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28088 * @returns {Promise<Key|Subkey>} signing key
28089 * @throws if no valid signing key was found
28090 * @async
28091 */
28092 async getSigningKey(keyID = null, date = new Date(), userID = {}, config = defaultConfig) {
28093 await this.verifyPrimaryKey(date, userID, config);
28094 const primaryKey = this.keyPacket;
28095 const subkeys = this.subkeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
28096 let exception;
28097 for (const subkey of subkeys) {
28098 if (!keyID || subkey.getKeyID().equals(keyID)) {
28099 try {
28100 await subkey.verify(date, config);
28101 const dataToVerify = { key: primaryKey, bind: subkey.keyPacket };
28102 const bindingSignature = await getLatestValidSignature(
28103 subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config
28104 );
28105 if (!isValidSigningKeyPacket(subkey.keyPacket, bindingSignature)) {
28106 continue;
28107 }
28108 if (!bindingSignature.embeddedSignature) {
28109 throw new Error('Missing embedded signature');
28110 }
28111 // verify embedded signature
28112 await getLatestValidSignature(
28113 [bindingSignature.embeddedSignature], subkey.keyPacket, enums.signature.keyBinding, dataToVerify, date, config
28114 );
28115 checkKeyRequirements(subkey.keyPacket, config);
28116 return subkey;
28117 } catch (e) {
28118 exception = e;
28119 }
28120 }
28121 }
28122
28123 try {
28124 const primaryUser = await this.getPrimaryUser(date, userID, config);
28125 if ((!keyID || primaryKey.getKeyID().equals(keyID)) &&
28126 isValidSigningKeyPacket(primaryKey, primaryUser.selfCertification, config)) {
28127 checkKeyRequirements(primaryKey, config);
28128 return this;
28129 }
28130 } catch (e) {
28131 exception = e;
28132 }
28133 throw util.wrapError('Could not find valid signing key packet in key ' + this.getKeyID().toHex(), exception);
28134 }
28135
28136 /**
28137 * Returns last created key or key by given keyID that is available for encryption or decryption
28138 * @param {module:type/keyid~KeyID} [keyID] - key ID of a specific key to retrieve
28139 * @param {Date} [date] - use the fiven date date to to check key validity instead of the current date
28140 * @param {Object} [userID] - filter keys for the given user ID
28141 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28142 * @returns {Promise<Key|Subkey>} encryption key
28143 * @throws if no valid encryption key was found
28144 * @async
28145 */
28146 async getEncryptionKey(keyID, date = new Date(), userID = {}, config = defaultConfig) {
28147 await this.verifyPrimaryKey(date, userID, config);
28148 const primaryKey = this.keyPacket;
28149 // V4: by convention subkeys are preferred for encryption service
28150 const subkeys = this.subkeys.slice().sort((a, b) => b.keyPacket.created - a.keyPacket.created);
28151 let exception;
28152 for (const subkey of subkeys) {
28153 if (!keyID || subkey.getKeyID().equals(keyID)) {
28154 try {
28155 await subkey.verify(date, config);
28156 const dataToVerify = { key: primaryKey, bind: subkey.keyPacket };
28157 const bindingSignature = await getLatestValidSignature(subkey.bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
28158 if (isValidEncryptionKeyPacket(subkey.keyPacket, bindingSignature)) {
28159 checkKeyRequirements(subkey.keyPacket, config);
28160 return subkey;
28161 }
28162 } catch (e) {
28163 exception = e;
28164 }
28165 }
28166 }
28167
28168 try {
28169 // if no valid subkey for encryption, evaluate primary key
28170 const primaryUser = await this.getPrimaryUser(date, userID, config);
28171 if ((!keyID || primaryKey.getKeyID().equals(keyID)) &&
28172 isValidEncryptionKeyPacket(primaryKey, primaryUser.selfCertification)) {
28173 checkKeyRequirements(primaryKey, config);
28174 return this;
28175 }
28176 } catch (e) {
28177 exception = e;
28178 }
28179 throw util.wrapError('Could not find valid encryption key packet in key ' + this.getKeyID().toHex(), exception);
28180 }
28181
28182 /**
28183 * Checks if a signature on a key is revoked
28184 * @param {SignaturePacket} signature - The signature to verify
28185 * @param {PublicSubkeyPacket|
28186 * SecretSubkeyPacket|
28187 * PublicKeyPacket|
28188 * SecretKeyPacket} key, optional The key to verify the signature
28189 * @param {Date} [date] - Use the given date for verification, instead of the current time
28190 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28191 * @returns {Promise<Boolean>} True if the certificate is revoked.
28192 * @async
28193 */
28194 async isRevoked(signature, key, date = new Date(), config = defaultConfig) {
28195 return isDataRevoked(
28196 this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, this.revocationSignatures, signature, key, date, config
28197 );
28198 }
28199
28200 /**
28201 * Verify primary key. Checks for revocation signatures, expiration time
28202 * and valid self signature. Throws if the primary key is invalid.
28203 * @param {Date} [date] - Use the given date for verification instead of the current time
28204 * @param {Object} [userID] - User ID
28205 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28206 * @throws {Error} If key verification failed
28207 * @async
28208 */
28209 async verifyPrimaryKey(date = new Date(), userID = {}, config = defaultConfig) {
28210 const primaryKey = this.keyPacket;
28211 // check for key revocation signatures
28212 if (await this.isRevoked(null, null, date, config)) {
28213 throw new Error('Primary key is revoked');
28214 }
28215 // check for valid, unrevoked, unexpired self signature
28216 const { selfCertification } = await this.getPrimaryUser(date, userID, config);
28217 // check for expiration time in binding signatures
28218 if (isDataExpired(primaryKey, selfCertification, date)) {
28219 throw new Error('Primary key is expired');
28220 }
28221 // check for expiration time in direct signatures
28222 const directSignature = await getLatestValidSignature(
28223 this.directSignatures, primaryKey, enums.signature.key, { key: primaryKey }, date, config
28224 ).catch(() => {}); // invalid signatures are discarded, to avoid breaking the key
28225
28226 if (directSignature && isDataExpired(primaryKey, directSignature, date)) {
28227 throw new Error('Primary key is expired');
28228 }
28229 }
28230
28231 /**
28232 * Returns the expiration date of the primary key, considering self-certifications and direct-key signatures.
28233 * Returns `Infinity` if the key doesn't expire, or `null` if the key is revoked or invalid.
28234 * @param {Object} [userID] - User ID to consider instead of the primary user
28235 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28236 * @returns {Promise<Date | Infinity | null>}
28237 * @async
28238 */
28239 async getExpirationTime(userID, config = defaultConfig) {
28240 let primaryKeyExpiry;
28241 try {
28242 const { selfCertification } = await this.getPrimaryUser(null, userID, config);
28243 const selfSigKeyExpiry = getKeyExpirationTime(this.keyPacket, selfCertification);
28244 const selfSigExpiry = selfCertification.getExpirationTime();
28245 const directSignature = await getLatestValidSignature(
28246 this.directSignatures, this.keyPacket, enums.signature.key, { key: this.keyPacket }, null, config
28247 ).catch(() => {});
28248 if (directSignature) {
28249 const directSigKeyExpiry = getKeyExpirationTime(this.keyPacket, directSignature);
28250 // We do not support the edge case where the direct signature expires, since it would invalidate the corresponding key expiration,
28251 // causing a discountinous validy period for the key
28252 primaryKeyExpiry = Math.min(selfSigKeyExpiry, selfSigExpiry, directSigKeyExpiry);
28253 } else {
28254 primaryKeyExpiry = selfSigKeyExpiry < selfSigExpiry ? selfSigKeyExpiry : selfSigExpiry;
28255 }
28256 } catch (e) {
28257 primaryKeyExpiry = null;
28258 }
28259
28260 return util.normalizeDate(primaryKeyExpiry);
28261 }
28262
28263
28264 /**
28265 * Returns primary user and most significant (latest valid) self signature
28266 * - if multiple primary users exist, returns the one with the latest self signature
28267 * - otherwise, returns the user with the latest self signature
28268 * @param {Date} [date] - Use the given date for verification instead of the current time
28269 * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
28270 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28271 * @returns {Promise<{
28272 * user: User,
28273 * selfCertification: SignaturePacket
28274 * }>} The primary user and the self signature
28275 * @async
28276 */
28277 async getPrimaryUser(date = new Date(), userID = {}, config = defaultConfig) {
28278 const primaryKey = this.keyPacket;
28279 const users = [];
28280 let exception;
28281 for (let i = 0; i < this.users.length; i++) {
28282 try {
28283 const user = this.users[i];
28284 if (!user.userID) {
28285 continue;
28286 }
28287 if (
28288 (userID.name !== undefined && user.userID.name !== userID.name) ||
28289 (userID.email !== undefined && user.userID.email !== userID.email) ||
28290 (userID.comment !== undefined && user.userID.comment !== userID.comment)
28291 ) {
28292 throw new Error('Could not find user that matches that user ID');
28293 }
28294 const dataToVerify = { userID: user.userID, key: primaryKey };
28295 const selfCertification = await getLatestValidSignature(user.selfCertifications, primaryKey, enums.signature.certGeneric, dataToVerify, date, config);
28296 users.push({ index: i, user, selfCertification });
28297 } catch (e) {
28298 exception = e;
28299 }
28300 }
28301 if (!users.length) {
28302 throw exception || new Error('Could not find primary user');
28303 }
28304 await Promise.all(users.map(async function (a) {
28305 return a.user.revoked || a.user.isRevoked(a.selfCertification, null, date, config);
28306 }));
28307 // sort by primary user flag and signature creation time
28308 const primaryUser = users.sort(function(a, b) {
28309 const A = a.selfCertification;
28310 const B = b.selfCertification;
28311 return B.revoked - A.revoked || A.isPrimaryUserID - B.isPrimaryUserID || A.created - B.created;
28312 }).pop();
28313 const { user, selfCertification: cert } = primaryUser;
28314 if (cert.revoked || await user.isRevoked(cert, null, date, config)) {
28315 throw new Error('Primary user is revoked');
28316 }
28317 return primaryUser;
28318 }
28319
28320 /**
28321 * Update key with new components from specified key with same key ID:
28322 * users, subkeys, certificates are merged into the destination key,
28323 * duplicates and expired signatures are ignored.
28324 *
28325 * If the source key is a private key and the destination key is public,
28326 * a private key is returned.
28327 * @param {Key} sourceKey - Source key to merge
28328 * @param {Date} [date] - Date to verify validity of signatures and keys
28329 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28330 * @returns {Promise<Key>} updated key
28331 * @async
28332 */
28333 async update(sourceKey, date = new Date(), config = defaultConfig) {
28334 if (!this.hasSameFingerprintAs(sourceKey)) {
28335 throw new Error('Primary key fingerprints must be equal to update the key');
28336 }
28337 if (!this.isPrivate() && sourceKey.isPrivate()) {
28338 // check for equal subkey packets
28339 const equal = (this.subkeys.length === sourceKey.subkeys.length) &&
28340 (this.subkeys.every(destSubkey => {
28341 return sourceKey.subkeys.some(srcSubkey => {
28342 return destSubkey.hasSameFingerprintAs(srcSubkey);
28343 });
28344 }));
28345 if (!equal) {
28346 throw new Error('Cannot update public key with private key if subkeys mismatch');
28347 }
28348
28349 return sourceKey.update(this, config);
28350 }
28351 // from here on, either:
28352 // - destination key is private, source key is public
28353 // - the keys are of the same type
28354 // hence we don't need to convert the destination key type
28355 const updatedKey = this.clone();
28356 // revocation signatures
28357 await mergeSignatures(sourceKey, updatedKey, 'revocationSignatures', date, srcRevSig => {
28358 return isDataRevoked(updatedKey.keyPacket, enums.signature.keyRevocation, updatedKey, [srcRevSig], null, sourceKey.keyPacket, date, config);
28359 });
28360 // direct signatures
28361 await mergeSignatures(sourceKey, updatedKey, 'directSignatures', date);
28362 // update users
28363 await Promise.all(sourceKey.users.map(async srcUser => {
28364 // multiple users with the same ID/attribute are not explicitly disallowed by the spec
28365 // hence we support them, just in case
28366 const usersToUpdate = updatedKey.users.filter(dstUser => (
28367 (srcUser.userID && srcUser.userID.equals(dstUser.userID)) ||
28368 (srcUser.userAttribute && srcUser.userAttribute.equals(dstUser.userAttribute))
28369 ));
28370 if (usersToUpdate.length > 0) {
28371 await Promise.all(
28372 usersToUpdate.map(userToUpdate => userToUpdate.update(srcUser, date, config))
28373 );
28374 } else {
28375 const newUser = srcUser.clone();
28376 newUser.mainKey = updatedKey;
28377 updatedKey.users.push(newUser);
28378 }
28379 }));
28380 // update subkeys
28381 await Promise.all(sourceKey.subkeys.map(async srcSubkey => {
28382 // multiple subkeys with same fingerprint might be preset
28383 const subkeysToUpdate = updatedKey.subkeys.filter(dstSubkey => (
28384 dstSubkey.hasSameFingerprintAs(srcSubkey)
28385 ));
28386 if (subkeysToUpdate.length > 0) {
28387 await Promise.all(
28388 subkeysToUpdate.map(subkeyToUpdate => subkeyToUpdate.update(srcSubkey, date, config))
28389 );
28390 } else {
28391 const newSubkey = srcSubkey.clone();
28392 newSubkey.mainKey = updatedKey;
28393 updatedKey.subkeys.push(newSubkey);
28394 }
28395 }));
28396
28397 return updatedKey;
28398 }
28399
28400 /**
28401 * Get revocation certificate from a revoked key.
28402 * (To get a revocation certificate for an unrevoked key, call revoke() first.)
28403 * @param {Date} date - Use the given date instead of the current time
28404 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28405 * @returns {Promise<String>} Armored revocation certificate.
28406 * @async
28407 */
28408 async getRevocationCertificate(date = new Date(), config = defaultConfig) {
28409 const dataToVerify = { key: this.keyPacket };
28410 const revocationSignature = await getLatestValidSignature(this.revocationSignatures, this.keyPacket, enums.signature.keyRevocation, dataToVerify, date, config);
28411 const packetlist = new PacketList();
28412 packetlist.push(revocationSignature);
28413 return armor(enums.armor.publicKey, packetlist.write(), null, null, 'This is a revocation certificate');
28414 }
28415
28416 /**
28417 * Applies a revocation certificate to a key
28418 * This adds the first signature packet in the armored text to the key,
28419 * if it is a valid revocation signature.
28420 * @param {String} revocationCertificate - armored revocation certificate
28421 * @param {Date} [date] - Date to verify the certificate
28422 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28423 * @returns {Promise<Key>} Revoked key.
28424 * @async
28425 */
28426 async applyRevocationCertificate(revocationCertificate, date = new Date(), config = defaultConfig) {
28427 const input = await unarmor(revocationCertificate, config);
28428 const packetlist = await PacketList.fromBinary(input.data, allowedRevocationPackets, config);
28429 const revocationSignature = packetlist.findPacket(enums.packet.signature);
28430 if (!revocationSignature || revocationSignature.signatureType !== enums.signature.keyRevocation) {
28431 throw new Error('Could not find revocation signature packet');
28432 }
28433 if (!revocationSignature.issuerKeyID.equals(this.getKeyID())) {
28434 throw new Error('Revocation signature does not match key');
28435 }
28436 try {
28437 await revocationSignature.verify(this.keyPacket, enums.signature.keyRevocation, { key: this.keyPacket }, date, undefined, config);
28438 } catch (e) {
28439 throw util.wrapError('Could not verify revocation signature', e);
28440 }
28441 const key = this.clone();
28442 key.revocationSignatures.push(revocationSignature);
28443 return key;
28444 }
28445
28446 /**
28447 * Signs primary user of key
28448 * @param {Array<PrivateKey>} privateKeys - decrypted private keys for signing
28449 * @param {Date} [date] - Use the given date for verification instead of the current time
28450 * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
28451 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28452 * @returns {Promise<Key>} Key with new certificate signature.
28453 * @async
28454 */
28455 async signPrimaryUser(privateKeys, date, userID, config = defaultConfig) {
28456 const { index, user } = await this.getPrimaryUser(date, userID, config);
28457 const userSign = await user.certify(privateKeys, date, config);
28458 const key = this.clone();
28459 key.users[index] = userSign;
28460 return key;
28461 }
28462
28463 /**
28464 * Signs all users of key
28465 * @param {Array<PrivateKey>} privateKeys - decrypted private keys for signing
28466 * @param {Date} [date] - Use the given date for signing, instead of the current time
28467 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28468 * @returns {Promise<Key>} Key with new certificate signature.
28469 * @async
28470 */
28471 async signAllUsers(privateKeys, date = new Date(), config = defaultConfig) {
28472 const key = this.clone();
28473 key.users = await Promise.all(this.users.map(function(user) {
28474 return user.certify(privateKeys, date, config);
28475 }));
28476 return key;
28477 }
28478
28479 /**
28480 * Verifies primary user of key
28481 * - if no arguments are given, verifies the self certificates;
28482 * - otherwise, verifies all certificates signed with given keys.
28483 * @param {Array<PublicKey>} [verificationKeys] - array of keys to verify certificate signatures, instead of the primary key
28484 * @param {Date} [date] - Use the given date for verification instead of the current time
28485 * @param {Object} [userID] - User ID to get instead of the primary user, if it exists
28486 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28487 * @returns {Promise<Array<{
28488 * keyID: module:type/keyid~KeyID,
28489 * valid: Boolean|null
28490 * }>>} List of signer's keyID and validity of signature.
28491 * Signature validity is null if the verification keys do not correspond to the certificate.
28492 * @async
28493 */
28494 async verifyPrimaryUser(verificationKeys, date = new Date(), userID, config = defaultConfig) {
28495 const primaryKey = this.keyPacket;
28496 const { user } = await this.getPrimaryUser(date, userID, config);
28497 const results = verificationKeys ?
28498 await user.verifyAllCertifications(verificationKeys, date, config) :
28499 [{ keyID: primaryKey.getKeyID(), valid: await user.verify(date, config).catch(() => false) }];
28500 return results;
28501 }
28502
28503 /**
28504 * Verifies all users of key
28505 * - if no arguments are given, verifies the self certificates;
28506 * - otherwise, verifies all certificates signed with given keys.
28507 * @param {Array<PublicKey>} [verificationKeys] - array of keys to verify certificate signatures
28508 * @param {Date} [date] - Use the given date for verification instead of the current time
28509 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28510 * @returns {Promise<Array<{
28511 * userID: String,
28512 * keyID: module:type/keyid~KeyID,
28513 * valid: Boolean|null
28514 * }>>} List of userID, signer's keyID and validity of signature.
28515 * Signature validity is null if the verification keys do not correspond to the certificate.
28516 * @async
28517 */
28518 async verifyAllUsers(verificationKeys, date = new Date(), config = defaultConfig) {
28519 const primaryKey = this.keyPacket;
28520 const results = [];
28521 await Promise.all(this.users.map(async user => {
28522 const signatures = verificationKeys ?
28523 await user.verifyAllCertifications(verificationKeys, date, config) :
28524 [{ keyID: primaryKey.getKeyID(), valid: await user.verify(date, config).catch(() => false) }];
28525
28526 results.push(...signatures.map(
28527 signature => ({
28528 userID: user.userID.userID,
28529 keyID: signature.keyID,
28530 valid: signature.valid
28531 }))
28532 );
28533 }));
28534 return results;
28535 }
28536}
28537
28538['getKeyID', 'getFingerprint', 'getAlgorithmInfo', 'getCreationTime', 'hasSameFingerprintAs'].forEach(name => {
28539 Key.prototype[name] =
28540 Subkey.prototype[name];
28541});
28542
28543/**
28544 * Creates a PublicKey or PrivateKey depending on the packetlist in input
28545 * @param {PacketList} - packets to parse
28546 * @return {Key} parsed key
28547 * @throws if no key packet was found
28548 */
28549function createKey(packetlist) {
28550 for (const packet of packetlist) {
28551 switch (packet.constructor.tag) {
28552 case enums.packet.secretKey:
28553 return new PrivateKey(packetlist);
28554 case enums.packet.publicKey:
28555 return new PublicKey(packetlist);
28556 }
28557 }
28558 throw new Error('No key packet found');
28559}
28560
28561// This library is free software; you can redistribute it and/or
28562
28563/**
28564 * Class that represents an OpenPGP Public Key
28565 */
28566class PublicKey extends Key {
28567 /**
28568 * @param {PacketList} packetlist - The packets that form this key
28569 */
28570 constructor(packetlist) {
28571 super();
28572 this.keyPacket = null;
28573 this.revocationSignatures = [];
28574 this.directSignatures = [];
28575 this.users = [];
28576 this.subkeys = [];
28577 if (packetlist) {
28578 this.packetListToStructure(packetlist, new Set([enums.packet.secretKey, enums.packet.secretSubkey]));
28579 if (!this.keyPacket) {
28580 throw new Error('Invalid key: missing public-key packet');
28581 }
28582 }
28583 }
28584
28585 /**
28586 * Returns true if this is a private key
28587 * @returns {false}
28588 */
28589 isPrivate() {
28590 return false;
28591 }
28592
28593 /**
28594 * Returns key as public key (shallow copy)
28595 * @returns {PublicKey} New public Key
28596 */
28597 toPublic() {
28598 return this;
28599 }
28600
28601 /**
28602 * Returns ASCII armored text of key
28603 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28604 * @returns {ReadableStream<String>} ASCII armor.
28605 */
28606 armor(config = defaultConfig) {
28607 return armor(enums.armor.publicKey, this.toPacketList().write(), undefined, undefined, undefined, config);
28608 }
28609}
28610
28611/**
28612 * Class that represents an OpenPGP Private key
28613 */
28614class PrivateKey extends PublicKey {
28615 /**
28616 * @param {PacketList} packetlist - The packets that form this key
28617 */
28618 constructor(packetlist) {
28619 super();
28620 this.packetListToStructure(packetlist, new Set([enums.packet.publicKey, enums.packet.publicSubkey]));
28621 if (!this.keyPacket) {
28622 throw new Error('Invalid key: missing private-key packet');
28623 }
28624 }
28625
28626 /**
28627 * Returns true if this is a private key
28628 * @returns {Boolean}
28629 */
28630 isPrivate() {
28631 return true;
28632 }
28633
28634 /**
28635 * Returns key as public key (shallow copy)
28636 * @returns {PublicKey} New public Key
28637 */
28638 toPublic() {
28639 const packetlist = new PacketList();
28640 const keyPackets = this.toPacketList();
28641 for (const keyPacket of keyPackets) {
28642 switch (keyPacket.constructor.tag) {
28643 case enums.packet.secretKey: {
28644 const pubKeyPacket = PublicKeyPacket.fromSecretKeyPacket(keyPacket);
28645 packetlist.push(pubKeyPacket);
28646 break;
28647 }
28648 case enums.packet.secretSubkey: {
28649 const pubSubkeyPacket = PublicSubkeyPacket.fromSecretSubkeyPacket(keyPacket);
28650 packetlist.push(pubSubkeyPacket);
28651 break;
28652 }
28653 default:
28654 packetlist.push(keyPacket);
28655 }
28656 }
28657 return new PublicKey(packetlist);
28658 }
28659
28660 /**
28661 * Returns ASCII armored text of key
28662 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28663 * @returns {ReadableStream<String>} ASCII armor.
28664 */
28665 armor(config = defaultConfig) {
28666 return armor(enums.armor.privateKey, this.toPacketList().write(), undefined, undefined, undefined, config);
28667 }
28668
28669 /**
28670 * Returns all keys that are available for decryption, matching the keyID when given
28671 * This is useful to retrieve keys for session key decryption
28672 * @param {module:type/keyid~KeyID} keyID, optional
28673 * @param {Date} date, optional
28674 * @param {String} userID, optional
28675 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28676 * @returns {Promise<Array<Key|Subkey>>} Array of decryption keys.
28677 * @async
28678 */
28679 async getDecryptionKeys(keyID, date = new Date(), userID = {}, config = defaultConfig) {
28680 const primaryKey = this.keyPacket;
28681 const keys = [];
28682 for (let i = 0; i < this.subkeys.length; i++) {
28683 if (!keyID || this.subkeys[i].getKeyID().equals(keyID, true)) {
28684 try {
28685 const dataToVerify = { key: primaryKey, bind: this.subkeys[i].keyPacket };
28686 const bindingSignature = await getLatestValidSignature(this.subkeys[i].bindingSignatures, primaryKey, enums.signature.subkeyBinding, dataToVerify, date, config);
28687 if (isValidDecryptionKeyPacket(bindingSignature, config)) {
28688 keys.push(this.subkeys[i]);
28689 }
28690 } catch (e) {}
28691 }
28692 }
28693
28694 // evaluate primary key
28695 const primaryUser = await this.getPrimaryUser(date, userID, config);
28696 if ((!keyID || primaryKey.getKeyID().equals(keyID, true)) &&
28697 isValidDecryptionKeyPacket(primaryUser.selfCertification, config)) {
28698 keys.push(this);
28699 }
28700
28701 return keys;
28702 }
28703
28704 /**
28705 * Returns true if the primary key or any subkey is decrypted.
28706 * A dummy key is considered encrypted.
28707 */
28708 isDecrypted() {
28709 return this.getKeys().some(({ keyPacket }) => keyPacket.isDecrypted());
28710 }
28711
28712 /**
28713 * Check whether the private and public primary key parameters correspond
28714 * Together with verification of binding signatures, this guarantees key integrity
28715 * In case of gnu-dummy primary key, it is enough to validate any signing subkeys
28716 * otherwise all encryption subkeys are validated
28717 * If only gnu-dummy keys are found, we cannot properly validate so we throw an error
28718 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28719 * @throws {Error} if validation was not successful and the key cannot be trusted
28720 * @async
28721 */
28722 async validate(config = defaultConfig) {
28723 if (!this.isPrivate()) {
28724 throw new Error('Cannot validate a public key');
28725 }
28726
28727 let signingKeyPacket;
28728 if (!this.keyPacket.isDummy()) {
28729 signingKeyPacket = this.keyPacket;
28730 } else {
28731 /**
28732 * It is enough to validate any signing keys
28733 * since its binding signatures are also checked
28734 */
28735 const signingKey = await this.getSigningKey(null, null, undefined, { ...config, rejectPublicKeyAlgorithms: new Set(), minRSABits: 0 });
28736 // This could again be a dummy key
28737 if (signingKey && !signingKey.keyPacket.isDummy()) {
28738 signingKeyPacket = signingKey.keyPacket;
28739 }
28740 }
28741
28742 if (signingKeyPacket) {
28743 return signingKeyPacket.validate();
28744 } else {
28745 const keys = this.getKeys();
28746 const allDummies = keys.map(key => key.keyPacket.isDummy()).every(Boolean);
28747 if (allDummies) {
28748 throw new Error('Cannot validate an all-gnu-dummy key');
28749 }
28750
28751 return Promise.all(keys.map(async key => key.keyPacket.validate()));
28752 }
28753 }
28754
28755 /**
28756 * Clear private key parameters
28757 */
28758 clearPrivateParams() {
28759 this.getKeys().forEach(({ keyPacket }) => {
28760 if (keyPacket.isDecrypted()) {
28761 keyPacket.clearPrivateParams();
28762 }
28763 });
28764 }
28765
28766 /**
28767 * Revokes the key
28768 * @param {Object} reasonForRevocation - optional, object indicating the reason for revocation
28769 * @param {module:enums.reasonForRevocation} reasonForRevocation.flag optional, flag indicating the reason for revocation
28770 * @param {String} reasonForRevocation.string optional, string explaining the reason for revocation
28771 * @param {Date} date - optional, override the creationtime of the revocation signature
28772 * @param {Object} [config] - Full configuration, defaults to openpgp.config
28773 * @returns {Promise<PrivateKey>} New key with revocation signature.
28774 * @async
28775 */
28776 async revoke(
28777 {
28778 flag: reasonForRevocationFlag = enums.reasonForRevocation.noReason,
28779 string: reasonForRevocationString = ''
28780 } = {},
28781 date = new Date(),
28782 config = defaultConfig
28783 ) {
28784 if (!this.isPrivate()) {
28785 throw new Error('Need private key for revoking');
28786 }
28787 const dataToSign = { key: this.keyPacket };
28788 const key = this.clone();
28789 key.revocationSignatures.push(await createSignaturePacket(dataToSign, null, this.keyPacket, {
28790 signatureType: enums.signature.keyRevocation,
28791 reasonForRevocationFlag: enums.write(enums.reasonForRevocation, reasonForRevocationFlag),
28792 reasonForRevocationString
28793 }, date, undefined, undefined, config));
28794 return key;
28795 }
28796
28797
28798 /**
28799 * Generates a new OpenPGP subkey, and returns a clone of the Key object with the new subkey added.
28800 * Supports RSA and ECC keys. Defaults to the algorithm and bit size/curve of the primary key. DSA primary keys default to RSA subkeys.
28801 * @param {ecc|rsa} options.type The subkey algorithm: ECC or RSA
28802 * @param {String} options.curve (optional) Elliptic curve for ECC keys
28803 * @param {Integer} options.rsaBits (optional) Number of bits for RSA subkeys
28804 * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires
28805 * @param {Date} options.date (optional) Override the creation date of the key and the key signatures
28806 * @param {Boolean} options.sign (optional) Indicates whether the subkey should sign rather than encrypt. Defaults to false
28807 * @param {Object} options.config (optional) custom configuration settings to overwrite those in [config]{@link module:config}
28808 * @returns {Promise<PrivateKey>}
28809 * @async
28810 */
28811 async addSubkey(options = {}) {
28812 const config = { ...defaultConfig, ...options.config };
28813 if (options.passphrase) {
28814 throw new Error('Subkey could not be encrypted here, please encrypt whole key');
28815 }
28816 if (options.rsaBits < config.minRSABits) {
28817 throw new Error(`rsaBits should be at least ${config.minRSABits}, got: ${options.rsaBits}`);
28818 }
28819 const secretKeyPacket = this.keyPacket;
28820 if (secretKeyPacket.isDummy()) {
28821 throw new Error('Cannot add subkey to gnu-dummy primary key');
28822 }
28823 if (!secretKeyPacket.isDecrypted()) {
28824 throw new Error('Key is not decrypted');
28825 }
28826 const defaultOptions = secretKeyPacket.getAlgorithmInfo();
28827 defaultOptions.type = defaultOptions.curve ? 'ecc' : 'rsa'; // DSA keys default to RSA
28828 defaultOptions.rsaBits = defaultOptions.bits || 4096;
28829 defaultOptions.curve = defaultOptions.curve || 'curve25519';
28830 options = sanitizeKeyOptions(options, defaultOptions);
28831 const keyPacket = await generateSecretSubkey(options);
28832 checkKeyRequirements(keyPacket, config);
28833 const bindingSignature = await createBindingSignature(keyPacket, secretKeyPacket, options, config);
28834 const packetList = this.toPacketList();
28835 packetList.push(keyPacket, bindingSignature);
28836 return new PrivateKey(packetList);
28837 }
28838}
28839
28840// OpenPGP.js - An OpenPGP implementation in javascript
28841
28842// A Key can contain the following packets
28843const allowedKeyPackets = /*#__PURE__*/ util.constructAllowedPackets([
28844 PublicKeyPacket,
28845 PublicSubkeyPacket,
28846 SecretKeyPacket,
28847 SecretSubkeyPacket,
28848 UserIDPacket,
28849 UserAttributePacket,
28850 SignaturePacket
28851]);
28852
28853/**
28854 * Generates a new OpenPGP key. Supports RSA and ECC keys.
28855 * By default, primary and subkeys will be of same type.
28856 * @param {ecc|rsa} options.type The primary key algorithm type: ECC or RSA
28857 * @param {String} options.curve Elliptic curve for ECC keys
28858 * @param {Integer} options.rsaBits Number of bits for RSA keys
28859 * @param {Array<String|Object>} options.userIDs User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' }
28860 * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
28861 * @param {Number} options.keyExpirationTime (optional) Number of seconds from the key creation time after which the key expires
28862 * @param {Date} options.date Creation date of the key and the key signatures
28863 * @param {Object} config - Full configuration
28864 * @param {Array<Object>} options.subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}]
28865 * sign parameter defaults to false, and indicates whether the subkey should sign rather than encrypt
28866 * @returns {Promise<{{ key: PrivateKey, revocationCertificate: String }}>}
28867 * @async
28868 * @static
28869 * @private
28870 */
28871async function generate$2(options, config) {
28872 options.sign = true; // primary key is always a signing key
28873 options = sanitizeKeyOptions(options);
28874 options.subkeys = options.subkeys.map((subkey, index) => sanitizeKeyOptions(options.subkeys[index], options));
28875 let promises = [generateSecretKey(options, config)];
28876 promises = promises.concat(options.subkeys.map(options => generateSecretSubkey(options, config)));
28877 const packets = await Promise.all(promises);
28878
28879 const key = await wrapKeyObject(packets[0], packets.slice(1), options, config);
28880 const revocationCertificate = await key.getRevocationCertificate(options.date, config);
28881 key.revocationSignatures = [];
28882 return { key, revocationCertificate };
28883}
28884
28885/**
28886 * Reformats and signs an OpenPGP key with a given User ID. Currently only supports RSA keys.
28887 * @param {PrivateKey} options.privateKey The private key to reformat
28888 * @param {Array<String|Object>} options.userIDs User IDs as strings or objects: 'Jo Doe <info@jo.com>' or { name:'Jo Doe', email:'info@jo.com' }
28889 * @param {String} options.passphrase Passphrase used to encrypt the resulting private key
28890 * @param {Number} options.keyExpirationTime Number of seconds from the key creation time after which the key expires
28891 * @param {Date} options.date Override the creation date of the key signatures
28892 * @param {Array<Object>} options.subkeys (optional) options for each subkey, default to main key options. e.g. [{sign: true, passphrase: '123'}]
28893 * @param {Object} config - Full configuration
28894 *
28895 * @returns {Promise<{{ key: PrivateKey, revocationCertificate: String }}>}
28896 * @async
28897 * @static
28898 * @private
28899 */
28900async function reformat(options, config) {
28901 options = sanitize(options);
28902 const { privateKey } = options;
28903
28904 if (!privateKey.isPrivate()) {
28905 throw new Error('Cannot reformat a public key');
28906 }
28907
28908 if (privateKey.keyPacket.isDummy()) {
28909 throw new Error('Cannot reformat a gnu-dummy primary key');
28910 }
28911
28912 const isDecrypted = privateKey.getKeys().every(({ keyPacket }) => keyPacket.isDecrypted());
28913 if (!isDecrypted) {
28914 throw new Error('Key is not decrypted');
28915 }
28916
28917 const secretKeyPacket = privateKey.keyPacket;
28918
28919 if (!options.subkeys) {
28920 options.subkeys = await Promise.all(privateKey.subkeys.map(async subkey => {
28921 const secretSubkeyPacket = subkey.keyPacket;
28922 const dataToVerify = { key: secretKeyPacket, bind: secretSubkeyPacket };
28923 const bindingSignature = await (
28924 getLatestValidSignature(subkey.bindingSignatures, secretKeyPacket, enums.signature.subkeyBinding, dataToVerify, null, config)
28925 ).catch(() => ({}));
28926 return {
28927 sign: bindingSignature.keyFlags && (bindingSignature.keyFlags[0] & enums.keyFlags.signData)
28928 };
28929 }));
28930 }
28931
28932 const secretSubkeyPackets = privateKey.subkeys.map(subkey => subkey.keyPacket);
28933 if (options.subkeys.length !== secretSubkeyPackets.length) {
28934 throw new Error('Number of subkey options does not match number of subkeys');
28935 }
28936
28937 options.subkeys = options.subkeys.map(subkeyOptions => sanitize(subkeyOptions, options));
28938
28939 const key = await wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config);
28940 const revocationCertificate = await key.getRevocationCertificate(options.date, config);
28941 key.revocationSignatures = [];
28942 return { key, revocationCertificate };
28943
28944 function sanitize(options, subkeyDefaults = {}) {
28945 options.keyExpirationTime = options.keyExpirationTime || subkeyDefaults.keyExpirationTime;
28946 options.passphrase = util.isString(options.passphrase) ? options.passphrase : subkeyDefaults.passphrase;
28947 options.date = options.date || subkeyDefaults.date;
28948
28949 return options;
28950 }
28951}
28952
28953/**
28954 * Construct PrivateKey object from the given key packets, add certification signatures and set passphrase protection
28955 * The new key includes a revocation certificate that must be removed before returning the key, otherwise the key is considered revoked.
28956 * @param {SecretKeyPacket} secretKeyPacket
28957 * @param {SecretSubkeyPacket} secretSubkeyPackets
28958 * @param {Object} options
28959 * @param {Object} config - Full configuration
28960 * @returns {PrivateKey}
28961 */
28962async function wrapKeyObject(secretKeyPacket, secretSubkeyPackets, options, config) {
28963 // set passphrase protection
28964 if (options.passphrase) {
28965 await secretKeyPacket.encrypt(options.passphrase, config);
28966 }
28967
28968 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
28969 const subkeyPassphrase = options.subkeys[index].passphrase;
28970 if (subkeyPassphrase) {
28971 await secretSubkeyPacket.encrypt(subkeyPassphrase, config);
28972 }
28973 }));
28974
28975 const packetlist = new PacketList();
28976 packetlist.push(secretKeyPacket);
28977
28978 await Promise.all(options.userIDs.map(async function(userID, index) {
28979 function createPreferredAlgos(algos, preferredAlgo) {
28980 return [preferredAlgo, ...algos.filter(algo => algo !== preferredAlgo)];
28981 }
28982
28983 const userIDPacket = UserIDPacket.fromObject(userID);
28984 const dataToSign = {};
28985 dataToSign.userID = userIDPacket;
28986 dataToSign.key = secretKeyPacket;
28987 const signaturePacket = new SignaturePacket();
28988 signaturePacket.signatureType = enums.signature.certGeneric;
28989 signaturePacket.publicKeyAlgorithm = secretKeyPacket.algorithm;
28990 signaturePacket.hashAlgorithm = await getPreferredHashAlgo$1(null, secretKeyPacket, undefined, undefined, config);
28991 signaturePacket.keyFlags = [enums.keyFlags.certifyKeys | enums.keyFlags.signData];
28992 signaturePacket.preferredSymmetricAlgorithms = createPreferredAlgos([
28993 // prefer aes256, aes128, then aes192 (no WebCrypto support: https://www.chromium.org/blink/webcrypto#TOC-AES-support)
28994 enums.symmetric.aes256,
28995 enums.symmetric.aes128,
28996 enums.symmetric.aes192
28997 ], config.preferredSymmetricAlgorithm);
28998 if (config.aeadProtect) {
28999 signaturePacket.preferredAEADAlgorithms = createPreferredAlgos([
29000 enums.aead.eax,
29001 enums.aead.ocb
29002 ], config.preferredAEADAlgorithm);
29003 }
29004 signaturePacket.preferredHashAlgorithms = createPreferredAlgos([
29005 // prefer fast asm.js implementations (SHA-256)
29006 enums.hash.sha256,
29007 enums.hash.sha512
29008 ], config.preferredHashAlgorithm);
29009 signaturePacket.preferredCompressionAlgorithms = createPreferredAlgos([
29010 enums.compression.zlib,
29011 enums.compression.zip,
29012 enums.compression.uncompressed
29013 ], config.preferredCompressionAlgorithm);
29014 if (index === 0) {
29015 signaturePacket.isPrimaryUserID = true;
29016 }
29017 // integrity protection always enabled
29018 signaturePacket.features = [0];
29019 signaturePacket.features[0] |= enums.features.modificationDetection;
29020 if (config.aeadProtect) {
29021 signaturePacket.features[0] |= enums.features.aead;
29022 }
29023 if (config.v5Keys) {
29024 signaturePacket.features[0] |= enums.features.v5Keys;
29025 }
29026 if (options.keyExpirationTime > 0) {
29027 signaturePacket.keyExpirationTime = options.keyExpirationTime;
29028 signaturePacket.keyNeverExpires = false;
29029 }
29030 await signaturePacket.sign(secretKeyPacket, dataToSign, options.date);
29031
29032 return { userIDPacket, signaturePacket };
29033 })).then(list => {
29034 list.forEach(({ userIDPacket, signaturePacket }) => {
29035 packetlist.push(userIDPacket);
29036 packetlist.push(signaturePacket);
29037 });
29038 });
29039
29040 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
29041 const subkeyOptions = options.subkeys[index];
29042 const subkeySignaturePacket = await createBindingSignature(secretSubkeyPacket, secretKeyPacket, subkeyOptions, config);
29043 return { secretSubkeyPacket, subkeySignaturePacket };
29044 })).then(packets => {
29045 packets.forEach(({ secretSubkeyPacket, subkeySignaturePacket }) => {
29046 packetlist.push(secretSubkeyPacket);
29047 packetlist.push(subkeySignaturePacket);
29048 });
29049 });
29050
29051 // Add revocation signature packet for creating a revocation certificate.
29052 // This packet should be removed before returning the key.
29053 const dataToSign = { key: secretKeyPacket };
29054 packetlist.push(await createSignaturePacket(dataToSign, null, secretKeyPacket, {
29055 signatureType: enums.signature.keyRevocation,
29056 reasonForRevocationFlag: enums.reasonForRevocation.noReason,
29057 reasonForRevocationString: ''
29058 }, options.date, undefined, undefined, config));
29059
29060 if (options.passphrase) {
29061 secretKeyPacket.clearPrivateParams();
29062 }
29063
29064 await Promise.all(secretSubkeyPackets.map(async function(secretSubkeyPacket, index) {
29065 const subkeyPassphrase = options.subkeys[index].passphrase;
29066 if (subkeyPassphrase) {
29067 secretSubkeyPacket.clearPrivateParams();
29068 }
29069 }));
29070
29071 return new PrivateKey(packetlist);
29072}
29073
29074/**
29075 * Reads an (optionally armored) OpenPGP key and returns a key object
29076 * @param {Object} options
29077 * @param {String} [options.armoredKey] - Armored key to be parsed
29078 * @param {Uint8Array} [options.binaryKey] - Binary key to be parsed
29079 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
29080 * @returns {Promise<Key>} Key object.
29081 * @async
29082 * @static
29083 */
29084async function readKey({ armoredKey, binaryKey, config, ...rest }) {
29085 config = { ...defaultConfig, ...config };
29086 if (!armoredKey && !binaryKey) {
29087 throw new Error('readKey: must pass options object containing `armoredKey` or `binaryKey`');
29088 }
29089 if (armoredKey && !util.isString(armoredKey)) {
29090 throw new Error('readKey: options.armoredKey must be a string');
29091 }
29092 if (binaryKey && !util.isUint8Array(binaryKey)) {
29093 throw new Error('readKey: options.binaryKey must be a Uint8Array');
29094 }
29095 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
29096
29097 let input;
29098 if (armoredKey) {
29099 const { type, data } = await unarmor(armoredKey, config);
29100 if (!(type === enums.armor.publicKey || type === enums.armor.privateKey)) {
29101 throw new Error('Armored text not of type key');
29102 }
29103 input = data;
29104 } else {
29105 input = binaryKey;
29106 }
29107 const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
29108 return createKey(packetlist);
29109}
29110
29111/**
29112 * Reads an (optionally armored) OpenPGP private key and returns a PrivateKey object
29113 * @param {Object} options
29114 * @param {String} [options.armoredKey] - Armored key to be parsed
29115 * @param {Uint8Array} [options.binaryKey] - Binary key to be parsed
29116 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
29117 * @returns {Promise<PrivateKey>} Key object.
29118 * @async
29119 * @static
29120 */
29121async function readPrivateKey({ armoredKey, binaryKey, config, ...rest }) {
29122 config = { ...defaultConfig, ...config };
29123 if (!armoredKey && !binaryKey) {
29124 throw new Error('readPrivateKey: must pass options object containing `armoredKey` or `binaryKey`');
29125 }
29126 if (armoredKey && !util.isString(armoredKey)) {
29127 throw new Error('readPrivateKey: options.armoredKey must be a string');
29128 }
29129 if (binaryKey && !util.isUint8Array(binaryKey)) {
29130 throw new Error('readPrivateKey: options.binaryKey must be a Uint8Array');
29131 }
29132 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
29133
29134 let input;
29135 if (armoredKey) {
29136 const { type, data } = await unarmor(armoredKey, config);
29137 if (!(type === enums.armor.privateKey)) {
29138 throw new Error('Armored text not of type private key');
29139 }
29140 input = data;
29141 } else {
29142 input = binaryKey;
29143 }
29144 const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
29145 return new PrivateKey(packetlist);
29146}
29147
29148/**
29149 * Reads an (optionally armored) OpenPGP key block and returns a list of key objects
29150 * @param {Object} options
29151 * @param {String} [options.armoredKeys] - Armored keys to be parsed
29152 * @param {Uint8Array} [options.binaryKeys] - Binary keys to be parsed
29153 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
29154 * @returns {Promise<Array<Key>>} Key objects.
29155 * @async
29156 * @static
29157 */
29158async function readKeys({ armoredKeys, binaryKeys, config, ...rest }) {
29159 config = { ...defaultConfig, ...config };
29160 let input = armoredKeys || binaryKeys;
29161 if (!input) {
29162 throw new Error('readKeys: must pass options object containing `armoredKeys` or `binaryKeys`');
29163 }
29164 if (armoredKeys && !util.isString(armoredKeys)) {
29165 throw new Error('readKeys: options.armoredKeys must be a string');
29166 }
29167 if (binaryKeys && !util.isUint8Array(binaryKeys)) {
29168 throw new Error('readKeys: options.binaryKeys must be a Uint8Array');
29169 }
29170 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
29171
29172 if (armoredKeys) {
29173 const { type, data } = await unarmor(armoredKeys, config);
29174 if (type !== enums.armor.publicKey && type !== enums.armor.privateKey) {
29175 throw new Error('Armored text not of type key');
29176 }
29177 input = data;
29178 }
29179 const keys = [];
29180 const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
29181 const keyIndex = packetlist.indexOfTag(enums.packet.publicKey, enums.packet.secretKey);
29182 if (keyIndex.length === 0) {
29183 throw new Error('No key packet found');
29184 }
29185 for (let i = 0; i < keyIndex.length; i++) {
29186 const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
29187 const newKey = createKey(oneKeyList);
29188 keys.push(newKey);
29189 }
29190 return keys;
29191}
29192
29193/**
29194 * Reads an (optionally armored) OpenPGP private key block and returns a list of PrivateKey objects
29195 * @param {Object} options
29196 * @param {String} [options.armoredKeys] - Armored keys to be parsed
29197 * @param {Uint8Array} [options.binaryKeys] - Binary keys to be parsed
29198 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
29199 * @returns {Promise<Array<PrivateKey>>} Key objects.
29200 * @async
29201 * @static
29202 */
29203async function readPrivateKeys({ armoredKeys, binaryKeys, config }) {
29204 config = { ...defaultConfig, ...config };
29205 let input = armoredKeys || binaryKeys;
29206 if (!input) {
29207 throw new Error('readPrivateKeys: must pass options object containing `armoredKeys` or `binaryKeys`');
29208 }
29209 if (armoredKeys && !util.isString(armoredKeys)) {
29210 throw new Error('readPrivateKeys: options.armoredKeys must be a string');
29211 }
29212 if (binaryKeys && !util.isUint8Array(binaryKeys)) {
29213 throw new Error('readPrivateKeys: options.binaryKeys must be a Uint8Array');
29214 }
29215 if (armoredKeys) {
29216 const { type, data } = await unarmor(armoredKeys, config);
29217 if (type !== enums.armor.privateKey) {
29218 throw new Error('Armored text not of type private key');
29219 }
29220 input = data;
29221 }
29222 const keys = [];
29223 const packetlist = await PacketList.fromBinary(input, allowedKeyPackets, config);
29224 const keyIndex = packetlist.indexOfTag(enums.packet.secretKey);
29225 if (keyIndex.length === 0) {
29226 throw new Error('No secret key packet found');
29227 }
29228 for (let i = 0; i < keyIndex.length; i++) {
29229 const oneKeyList = packetlist.slice(keyIndex[i], keyIndex[i + 1]);
29230 const newKey = new PrivateKey(oneKeyList);
29231 keys.push(newKey);
29232 }
29233 return keys;
29234}
29235
29236// GPG4Browsers - An OpenPGP implementation in javascript
29237
29238// A Message can contain the following packets
29239const allowedMessagePackets = /*#__PURE__*/ util.constructAllowedPackets([
29240 LiteralDataPacket,
29241 CompressedDataPacket,
29242 AEADEncryptedDataPacket,
29243 SymEncryptedIntegrityProtectedDataPacket,
29244 SymmetricallyEncryptedDataPacket,
29245 PublicKeyEncryptedSessionKeyPacket,
29246 SymEncryptedSessionKeyPacket,
29247 OnePassSignaturePacket,
29248 SignaturePacket
29249]);
29250// A SKESK packet can contain the following packets
29251const allowedSymSessionKeyPackets = /*#__PURE__*/ util.constructAllowedPackets([SymEncryptedSessionKeyPacket]);
29252// A detached signature can contain the following packets
29253const allowedDetachedSignaturePackets = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
29254
29255/**
29256 * Class that represents an OpenPGP message.
29257 * Can be an encrypted message, signed message, compressed message or literal message
29258 * See {@link https://tools.ietf.org/html/rfc4880#section-11.3}
29259 */
29260class Message {
29261 /**
29262 * @param {PacketList} packetlist - The packets that form this message
29263 */
29264 constructor(packetlist) {
29265 this.packets = packetlist || new PacketList();
29266 }
29267
29268 /**
29269 * Returns the key IDs of the keys to which the session key is encrypted
29270 * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
29271 */
29272 getEncryptionKeyIDs() {
29273 const keyIDs = [];
29274 const pkESKeyPacketlist = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
29275 pkESKeyPacketlist.forEach(function(packet) {
29276 keyIDs.push(packet.publicKeyID);
29277 });
29278 return keyIDs;
29279 }
29280
29281 /**
29282 * Returns the key IDs of the keys that signed the message
29283 * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
29284 */
29285 getSigningKeyIDs() {
29286 const msg = this.unwrapCompressed();
29287 // search for one pass signatures
29288 const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature);
29289 if (onePassSigList.length > 0) {
29290 return onePassSigList.map(packet => packet.issuerKeyID);
29291 }
29292 // if nothing found look for signature packets
29293 const signatureList = msg.packets.filterByTag(enums.packet.signature);
29294 return signatureList.map(packet => packet.issuerKeyID);
29295 }
29296
29297 /**
29298 * Decrypt the message. Either a private key, a session key, or a password must be specified.
29299 * @param {Array<PrivateKey>} [decryptionKeys] - Private keys with decrypted secret data
29300 * @param {Array<String>} [passwords] - Passwords used to decrypt
29301 * @param {Array<Object>} [sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
29302 * @param {Date} [date] - Use the given date for key verification instead of the current time
29303 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29304 * @returns {Promise<Message>} New message with decrypted content.
29305 * @async
29306 */
29307 async decrypt(decryptionKeys, passwords, sessionKeys, date = new Date(), config = defaultConfig) {
29308 const sessionKeyObjects = sessionKeys || await this.decryptSessionKeys(decryptionKeys, passwords, date, config);
29309
29310 const symEncryptedPacketlist = this.packets.filterByTag(
29311 enums.packet.symmetricallyEncryptedData,
29312 enums.packet.symEncryptedIntegrityProtectedData,
29313 enums.packet.aeadEncryptedData
29314 );
29315
29316 if (symEncryptedPacketlist.length === 0) {
29317 throw new Error('No encrypted data found');
29318 }
29319
29320 const symEncryptedPacket = symEncryptedPacketlist[0];
29321 let exception = null;
29322 const decryptedPromise = Promise.all(sessionKeyObjects.map(async ({ algorithm: algorithmName, data }) => {
29323 if (!util.isUint8Array(data) || !util.isString(algorithmName)) {
29324 throw new Error('Invalid session key for decryption.');
29325 }
29326
29327 try {
29328 const algo = enums.write(enums.symmetric, algorithmName);
29329 await symEncryptedPacket.decrypt(algo, data, config);
29330 } catch (e) {
29331 util.printDebugError(e);
29332 exception = e;
29333 }
29334 }));
29335 // We don't await stream.cancel here because it only returns when the other copy is canceled too.
29336 cancel(symEncryptedPacket.encrypted); // Don't keep copy of encrypted data in memory.
29337 symEncryptedPacket.encrypted = null;
29338 await decryptedPromise;
29339
29340 if (!symEncryptedPacket.packets || !symEncryptedPacket.packets.length) {
29341 throw exception || new Error('Decryption failed.');
29342 }
29343
29344 const resultMsg = new Message(symEncryptedPacket.packets);
29345 symEncryptedPacket.packets = new PacketList(); // remove packets after decryption
29346
29347 return resultMsg;
29348 }
29349
29350 /**
29351 * Decrypt encrypted session keys either with private keys or passwords.
29352 * @param {Array<PrivateKey>} [decryptionKeys] - Private keys with decrypted secret data
29353 * @param {Array<String>} [passwords] - Passwords used to decrypt
29354 * @param {Date} [date] - Use the given date for key verification, instead of current time
29355 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29356 * @returns {Promise<Array<{
29357 * data: Uint8Array,
29358 * algorithm: String
29359 * }>>} array of object with potential sessionKey, algorithm pairs
29360 * @async
29361 */
29362 async decryptSessionKeys(decryptionKeys, passwords, date = new Date(), config = defaultConfig) {
29363 let decryptedSessionKeyPackets = [];
29364
29365 let exception;
29366 if (passwords) {
29367 const skeskPackets = this.packets.filterByTag(enums.packet.symEncryptedSessionKey);
29368 if (skeskPackets.length === 0) {
29369 throw new Error('No symmetrically encrypted session key packet found.');
29370 }
29371 await Promise.all(passwords.map(async function(password, i) {
29372 let packets;
29373 if (i) {
29374 packets = await PacketList.fromBinary(skeskPackets.write(), allowedSymSessionKeyPackets, config);
29375 } else {
29376 packets = skeskPackets;
29377 }
29378 await Promise.all(packets.map(async function(skeskPacket) {
29379 try {
29380 await skeskPacket.decrypt(password);
29381 decryptedSessionKeyPackets.push(skeskPacket);
29382 } catch (err) {
29383 util.printDebugError(err);
29384 }
29385 }));
29386 }));
29387 } else if (decryptionKeys) {
29388 const pkeskPackets = this.packets.filterByTag(enums.packet.publicKeyEncryptedSessionKey);
29389 if (pkeskPackets.length === 0) {
29390 throw new Error('No public key encrypted session key packet found.');
29391 }
29392 await Promise.all(pkeskPackets.map(async function(pkeskPacket) {
29393 await Promise.all(decryptionKeys.map(async function(decryptionKey) {
29394 let algos = [
29395 enums.symmetric.aes256, // Old OpenPGP.js default fallback
29396 enums.symmetric.aes128, // RFC4880bis fallback
29397 enums.symmetric.tripledes, // RFC4880 fallback
29398 enums.symmetric.cast5 // Golang OpenPGP fallback
29399 ];
29400 try {
29401 const primaryUser = await decryptionKey.getPrimaryUser(date, undefined, config); // TODO: Pass userID from somewhere.
29402 if (primaryUser.selfCertification.preferredSymmetricAlgorithms) {
29403 algos = algos.concat(primaryUser.selfCertification.preferredSymmetricAlgorithms);
29404 }
29405 } catch (e) {}
29406
29407 // do not check key expiration to allow decryption of old messages
29408 const decryptionKeyPackets = (await decryptionKey.getDecryptionKeys(pkeskPacket.publicKeyID, null, undefined, config)).map(key => key.keyPacket);
29409 await Promise.all(decryptionKeyPackets.map(async function(decryptionKeyPacket) {
29410 if (!decryptionKeyPacket || decryptionKeyPacket.isDummy()) {
29411 return;
29412 }
29413 if (!decryptionKeyPacket.isDecrypted()) {
29414 throw new Error('Decryption key is not decrypted.');
29415 }
29416
29417 // To hinder CCA attacks against PKCS1, we carry out a constant-time decryption flow if the `constantTimePKCS1Decryption` config option is set.
29418 const doConstantTimeDecryption = config.constantTimePKCS1Decryption && (
29419 pkeskPacket.publicKeyAlgorithm === enums.publicKey.rsaEncrypt ||
29420 pkeskPacket.publicKeyAlgorithm === enums.publicKey.rsaEncryptSign ||
29421 pkeskPacket.publicKeyAlgorithm === enums.publicKey.rsaSign ||
29422 pkeskPacket.publicKeyAlgorithm === enums.publicKey.elgamal
29423 );
29424
29425 if (doConstantTimeDecryption) {
29426 // The goal is to not reveal whether PKESK decryption (specifically the PKCS1 decoding step) failed, hence, we always proceed to decrypt the message,
29427 // either with the successfully decrypted session key, or with a randomly generated one.
29428 // Since the SEIP/AEAD's symmetric algorithm and key size are stored in the encrypted portion of the PKESK, and the execution flow cannot depend on
29429 // the decrypted payload, we always assume the message to be encrypted with one of the symmetric algorithms specified in `config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms`:
29430 // - If the PKESK decryption succeeds, and the session key cipher is in the supported set, then we try to decrypt the data with the decrypted session key as well as with the
29431 // randomly generated keys of the remaining key types.
29432 // - If the PKESK decryptions fails, or if it succeeds but support for the cipher is not enabled, then we discard the session key and try to decrypt the data using only the randomly
29433 // generated session keys.
29434 // NB: as a result, if the data is encrypted with a non-suported cipher, decryption will always fail.
29435
29436 const serialisedPKESK = pkeskPacket.write(); // make copies to be able to decrypt the PKESK packet multiple times
29437 await Promise.all(Array.from(config.constantTimePKCS1DecryptionSupportedSymmetricAlgorithms).map(async sessionKeyAlgorithm => {
29438 const pkeskPacketCopy = new PublicKeyEncryptedSessionKeyPacket();
29439 pkeskPacketCopy.read(serialisedPKESK);
29440 const randomSessionKey = {
29441 sessionKeyAlgorithm,
29442 sessionKey: await mod.generateSessionKey(sessionKeyAlgorithm)
29443 };
29444 try {
29445 await pkeskPacketCopy.decrypt(decryptionKeyPacket, randomSessionKey);
29446 decryptedSessionKeyPackets.push(pkeskPacketCopy);
29447 } catch (err) {
29448 // `decrypt` can still throw some non-security-sensitive errors
29449 util.printDebugError(err);
29450 exception = err;
29451 }
29452 }));
29453
29454 } else {
29455 try {
29456 await pkeskPacket.decrypt(decryptionKeyPacket);
29457 if (!algos.includes(enums.write(enums.symmetric, pkeskPacket.sessionKeyAlgorithm))) {
29458 throw new Error('A non-preferred symmetric algorithm was used.');
29459 }
29460 decryptedSessionKeyPackets.push(pkeskPacket);
29461 } catch (err) {
29462 util.printDebugError(err);
29463 exception = err;
29464 }
29465 }
29466 }));
29467 }));
29468 cancel(pkeskPacket.encrypted); // Don't keep copy of encrypted data in memory.
29469 pkeskPacket.encrypted = null;
29470 }));
29471 } else {
29472 throw new Error('No key or password specified.');
29473 }
29474
29475 if (decryptedSessionKeyPackets.length > 0) {
29476 // Return only unique session keys
29477 if (decryptedSessionKeyPackets.length > 1) {
29478 const seen = new Set();
29479 decryptedSessionKeyPackets = decryptedSessionKeyPackets.filter(item => {
29480 const k = item.sessionKeyAlgorithm + util.uint8ArrayToString(item.sessionKey);
29481 if (seen.has(k)) {
29482 return false;
29483 }
29484 seen.add(k);
29485 return true;
29486 });
29487 }
29488
29489 return decryptedSessionKeyPackets.map(packet => ({
29490 data: packet.sessionKey,
29491 algorithm: enums.read(enums.symmetric, packet.sessionKeyAlgorithm)
29492 }));
29493 }
29494 throw exception || new Error('Session key decryption failed.');
29495 }
29496
29497 /**
29498 * Get literal data that is the body of the message
29499 * @returns {(Uint8Array|null)} Literal body of the message as Uint8Array.
29500 */
29501 getLiteralData() {
29502 const msg = this.unwrapCompressed();
29503 const literal = msg.packets.findPacket(enums.packet.literalData);
29504 return (literal && literal.getBytes()) || null;
29505 }
29506
29507 /**
29508 * Get filename from literal data packet
29509 * @returns {(String|null)} Filename of literal data packet as string.
29510 */
29511 getFilename() {
29512 const msg = this.unwrapCompressed();
29513 const literal = msg.packets.findPacket(enums.packet.literalData);
29514 return (literal && literal.getFilename()) || null;
29515 }
29516
29517 /**
29518 * Get literal data as text
29519 * @returns {(String|null)} Literal body of the message interpreted as text.
29520 */
29521 getText() {
29522 const msg = this.unwrapCompressed();
29523 const literal = msg.packets.findPacket(enums.packet.literalData);
29524 if (literal) {
29525 return literal.getText();
29526 }
29527 return null;
29528 }
29529
29530 /**
29531 * Generate a new session key object, taking the algorithm preferences of the passed encryption keys into account, if any.
29532 * @param {Array<PublicKey>} [encryptionKeys] - Public key(s) to select algorithm preferences for
29533 * @param {Date} [date] - Date to select algorithm preferences at
29534 * @param {Array<Object>} [userIDs] - User IDs to select algorithm preferences for
29535 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29536 * @returns {Promise<{ data: Uint8Array, algorithm: String, aeadAlgorithm: undefined|String }>} Object with session key data and algorithms.
29537 * @async
29538 */
29539 static async generateSessionKey(encryptionKeys = [], date = new Date(), userIDs = [], config = defaultConfig) {
29540 const algo = await getPreferredAlgo('symmetric', encryptionKeys, date, userIDs, config);
29541 const algorithmName = enums.read(enums.symmetric, algo);
29542 const aeadAlgorithmName = config.aeadProtect && await isAEADSupported(encryptionKeys, date, userIDs, config) ?
29543 enums.read(enums.aead, await getPreferredAlgo('aead', encryptionKeys, date, userIDs, config)) :
29544 undefined;
29545
29546 const sessionKeyData = await mod.generateSessionKey(algo);
29547 return { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName };
29548 }
29549
29550 /**
29551 * Encrypt the message either with public keys, passwords, or both at once.
29552 * @param {Array<PublicKey>} [encryptionKeys] - Public key(s) for message encryption
29553 * @param {Array<String>} [passwords] - Password(s) for message encryption
29554 * @param {Object} [sessionKey] - Session key in the form: { data:Uint8Array, algorithm:String, [aeadAlgorithm:String] }
29555 * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
29556 * @param {Array<module:type/keyid~KeyID>} [encryptionKeyIDs] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to keys[i]
29557 * @param {Date} [date] - Override the creation date of the literal package
29558 * @param {Array<Object>} [userIDs] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
29559 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29560 * @returns {Promise<Message>} New message with encrypted content.
29561 * @async
29562 */
29563 async encrypt(encryptionKeys, passwords, sessionKey, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
29564 if (sessionKey) {
29565 if (!util.isUint8Array(sessionKey.data) || !util.isString(sessionKey.algorithm)) {
29566 throw new Error('Invalid session key for encryption.');
29567 }
29568 } else if (encryptionKeys && encryptionKeys.length) {
29569 sessionKey = await Message.generateSessionKey(encryptionKeys, date, userIDs, config);
29570 } else if (passwords && passwords.length) {
29571 sessionKey = await Message.generateSessionKey(undefined, undefined, undefined, config);
29572 } else {
29573 throw new Error('No keys, passwords, or session key provided.');
29574 }
29575
29576 const { data: sessionKeyData, algorithm: algorithmName, aeadAlgorithm: aeadAlgorithmName } = sessionKey;
29577
29578 const msg = await Message.encryptSessionKey(sessionKeyData, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, userIDs, config);
29579
29580 let symEncryptedPacket;
29581 if (aeadAlgorithmName) {
29582 symEncryptedPacket = new AEADEncryptedDataPacket();
29583 symEncryptedPacket.aeadAlgorithm = enums.write(enums.aead, aeadAlgorithmName);
29584 } else {
29585 symEncryptedPacket = new SymEncryptedIntegrityProtectedDataPacket();
29586 }
29587 symEncryptedPacket.packets = this.packets;
29588
29589 const algorithm = enums.write(enums.symmetric, algorithmName);
29590 await symEncryptedPacket.encrypt(algorithm, sessionKeyData, config);
29591
29592 msg.packets.push(symEncryptedPacket);
29593 symEncryptedPacket.packets = new PacketList(); // remove packets after encryption
29594 return msg;
29595 }
29596
29597 /**
29598 * Encrypt a session key either with public keys, passwords, or both at once.
29599 * @param {Uint8Array} sessionKey - session key for encryption
29600 * @param {String} algorithmName - session key algorithm
29601 * @param {String} [aeadAlgorithmName] - AEAD algorithm, e.g. 'eax' or 'ocb'
29602 * @param {Array<PublicKey>} [encryptionKeys] - Public key(s) for message encryption
29603 * @param {Array<String>} [passwords] - For message encryption
29604 * @param {Boolean} [wildcard] - Use a key ID of 0 instead of the public key IDs
29605 * @param {Array<module:type/keyid~KeyID>} [encryptionKeyIDs] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to encryptionKeys[i]
29606 * @param {Date} [date] - Override the date
29607 * @param {Array} [userIDs] - User IDs to encrypt for, e.g. [{ name:'Robert Receiver', email:'robert@openpgp.org' }]
29608 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29609 * @returns {Promise<Message>} New message with encrypted content.
29610 * @async
29611 */
29612 static async encryptSessionKey(sessionKey, algorithmName, aeadAlgorithmName, encryptionKeys, passwords, wildcard = false, encryptionKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
29613 const packetlist = new PacketList();
29614 const algorithm = enums.write(enums.symmetric, algorithmName);
29615 const aeadAlgorithm = aeadAlgorithmName && enums.write(enums.aead, aeadAlgorithmName);
29616
29617 if (encryptionKeys) {
29618 const results = await Promise.all(encryptionKeys.map(async function(primaryKey, i) {
29619 const encryptionKey = await primaryKey.getEncryptionKey(encryptionKeyIDs[i], date, userIDs, config);
29620 const pkESKeyPacket = new PublicKeyEncryptedSessionKeyPacket();
29621 pkESKeyPacket.publicKeyID = wildcard ? KeyID.wildcard() : encryptionKey.getKeyID();
29622 pkESKeyPacket.publicKeyAlgorithm = encryptionKey.keyPacket.algorithm;
29623 pkESKeyPacket.sessionKey = sessionKey;
29624 pkESKeyPacket.sessionKeyAlgorithm = algorithm;
29625 await pkESKeyPacket.encrypt(encryptionKey.keyPacket);
29626 delete pkESKeyPacket.sessionKey; // delete plaintext session key after encryption
29627 return pkESKeyPacket;
29628 }));
29629 packetlist.push(...results);
29630 }
29631 if (passwords) {
29632 const testDecrypt = async function(keyPacket, password) {
29633 try {
29634 await keyPacket.decrypt(password);
29635 return 1;
29636 } catch (e) {
29637 return 0;
29638 }
29639 };
29640
29641 const sum = (accumulator, currentValue) => accumulator + currentValue;
29642
29643 const encryptPassword = async function(sessionKey, algorithm, aeadAlgorithm, password) {
29644 const symEncryptedSessionKeyPacket = new SymEncryptedSessionKeyPacket(config);
29645 symEncryptedSessionKeyPacket.sessionKey = sessionKey;
29646 symEncryptedSessionKeyPacket.sessionKeyAlgorithm = algorithm;
29647 if (aeadAlgorithm) {
29648 symEncryptedSessionKeyPacket.aeadAlgorithm = aeadAlgorithm;
29649 }
29650 await symEncryptedSessionKeyPacket.encrypt(password, config);
29651
29652 if (config.passwordCollisionCheck) {
29653 const results = await Promise.all(passwords.map(pwd => testDecrypt(symEncryptedSessionKeyPacket, pwd)));
29654 if (results.reduce(sum) !== 1) {
29655 return encryptPassword(sessionKey, algorithm, password);
29656 }
29657 }
29658
29659 delete symEncryptedSessionKeyPacket.sessionKey; // delete plaintext session key after encryption
29660 return symEncryptedSessionKeyPacket;
29661 };
29662
29663 const results = await Promise.all(passwords.map(pwd => encryptPassword(sessionKey, algorithm, aeadAlgorithm, pwd)));
29664 packetlist.push(...results);
29665 }
29666
29667 return new Message(packetlist);
29668 }
29669
29670 /**
29671 * Sign the message (the literal data packet of the message)
29672 * @param {Array<PrivateKey>} signingKeys - private keys with decrypted secret key data for signing
29673 * @param {Signature} [signature] - Any existing detached signature to add to the message
29674 * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
29675 * @param {Date} [date] - Override the creation time of the signature
29676 * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
29677 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29678 * @returns {Promise<Message>} New message with signed content.
29679 * @async
29680 */
29681 async sign(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
29682 const packetlist = new PacketList();
29683
29684 const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
29685 if (!literalDataPacket) {
29686 throw new Error('No literal data packet to sign.');
29687 }
29688
29689 let i;
29690 let existingSigPacketlist;
29691 // If data packet was created from Uint8Array, use binary, otherwise use text
29692 const signatureType = literalDataPacket.text === null ?
29693 enums.signature.binary : enums.signature.text;
29694
29695 if (signature) {
29696 existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
29697 for (i = existingSigPacketlist.length - 1; i >= 0; i--) {
29698 const signaturePacket = existingSigPacketlist[i];
29699 const onePassSig = new OnePassSignaturePacket();
29700 onePassSig.signatureType = signaturePacket.signatureType;
29701 onePassSig.hashAlgorithm = signaturePacket.hashAlgorithm;
29702 onePassSig.publicKeyAlgorithm = signaturePacket.publicKeyAlgorithm;
29703 onePassSig.issuerKeyID = signaturePacket.issuerKeyID;
29704 if (!signingKeys.length && i === 0) {
29705 onePassSig.flags = 1;
29706 }
29707 packetlist.push(onePassSig);
29708 }
29709 }
29710
29711 await Promise.all(Array.from(signingKeys).reverse().map(async function (primaryKey, i) {
29712 if (!primaryKey.isPrivate()) {
29713 throw new Error('Need private key for signing');
29714 }
29715 const signingKeyID = signingKeyIDs[signingKeys.length - 1 - i];
29716 const signingKey = await primaryKey.getSigningKey(signingKeyID, date, userIDs, config);
29717 const onePassSig = new OnePassSignaturePacket();
29718 onePassSig.signatureType = signatureType;
29719 onePassSig.hashAlgorithm = await getPreferredHashAlgo$1(primaryKey, signingKey.keyPacket, date, userIDs, config);
29720 onePassSig.publicKeyAlgorithm = signingKey.keyPacket.algorithm;
29721 onePassSig.issuerKeyID = signingKey.getKeyID();
29722 if (i === signingKeys.length - 1) {
29723 onePassSig.flags = 1;
29724 }
29725 return onePassSig;
29726 })).then(onePassSignatureList => {
29727 onePassSignatureList.forEach(onePassSig => packetlist.push(onePassSig));
29728 });
29729
29730 packetlist.push(literalDataPacket);
29731 packetlist.push(...(await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, false, config)));
29732
29733 return new Message(packetlist);
29734 }
29735
29736 /**
29737 * Compresses the message (the literal and -if signed- signature data packets of the message)
29738 * @param {module:enums.compression} algo - compression algorithm
29739 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29740 * @returns {Message} New message with compressed content.
29741 */
29742 compress(algo, config = defaultConfig) {
29743 if (algo === enums.compression.uncompressed) {
29744 return this;
29745 }
29746
29747 const compressed = new CompressedDataPacket(config);
29748 compressed.algorithm = algo;
29749 compressed.packets = this.packets;
29750
29751 const packetList = new PacketList();
29752 packetList.push(compressed);
29753
29754 return new Message(packetList);
29755 }
29756
29757 /**
29758 * Create a detached signature for the message (the literal data packet of the message)
29759 * @param {Array<PrivateKey>} signingKeys - private keys with decrypted secret key data for signing
29760 * @param {Signature} [signature] - Any existing detached signature
29761 * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
29762 * @param {Date} [date] - Override the creation time of the signature
29763 * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
29764 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29765 * @returns {Promise<Signature>} New detached signature of message content.
29766 * @async
29767 */
29768 async signDetached(signingKeys = [], signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
29769 const literalDataPacket = this.packets.findPacket(enums.packet.literalData);
29770 if (!literalDataPacket) {
29771 throw new Error('No literal data packet to sign.');
29772 }
29773 return new Signature(await createSignaturePackets(literalDataPacket, signingKeys, signature, signingKeyIDs, date, userIDs, true, config));
29774 }
29775
29776 /**
29777 * Verify message signatures
29778 * @param {Array<PublicKey>} verificationKeys - Array of public keys to verify signatures
29779 * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
29780 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29781 * @returns {Promise<Array<{
29782 * keyID: module:type/keyid~KeyID,
29783 * signature: Promise<Signature>,
29784 * verified: Promise<true>
29785 * }>>} List of signer's keyID and validity of signatures.
29786 * @async
29787 */
29788 async verify(verificationKeys, date = new Date(), config = defaultConfig) {
29789 const msg = this.unwrapCompressed();
29790 const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
29791 if (literalDataList.length !== 1) {
29792 throw new Error('Can only verify message with one literal data packet.');
29793 }
29794 if (isArrayStream(msg.packets.stream)) {
29795 msg.packets.push(...await readToEnd(msg.packets.stream, _ => _ || []));
29796 }
29797 const onePassSigList = msg.packets.filterByTag(enums.packet.onePassSignature).reverse();
29798 const signatureList = msg.packets.filterByTag(enums.packet.signature);
29799 if (onePassSigList.length && !signatureList.length && util.isStream(msg.packets.stream) && !isArrayStream(msg.packets.stream)) {
29800 await Promise.all(onePassSigList.map(async onePassSig => {
29801 onePassSig.correspondingSig = new Promise((resolve, reject) => {
29802 onePassSig.correspondingSigResolve = resolve;
29803 onePassSig.correspondingSigReject = reject;
29804 });
29805 onePassSig.signatureData = fromAsync(async () => (await onePassSig.correspondingSig).signatureData);
29806 onePassSig.hashed = readToEnd(await onePassSig.hash(onePassSig.signatureType, literalDataList[0], undefined, false));
29807 onePassSig.hashed.catch(() => {});
29808 }));
29809 msg.packets.stream = transformPair(msg.packets.stream, async (readable, writable) => {
29810 const reader = getReader(readable);
29811 const writer = getWriter(writable);
29812 try {
29813 for (let i = 0; i < onePassSigList.length; i++) {
29814 const { value: signature } = await reader.read();
29815 onePassSigList[i].correspondingSigResolve(signature);
29816 }
29817 await reader.readToEnd();
29818 await writer.ready;
29819 await writer.close();
29820 } catch (e) {
29821 onePassSigList.forEach(onePassSig => {
29822 onePassSig.correspondingSigReject(e);
29823 });
29824 await writer.abort(e);
29825 }
29826 });
29827 return createVerificationObjects(onePassSigList, literalDataList, verificationKeys, date, false, config);
29828 }
29829 return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, false, config);
29830 }
29831
29832 /**
29833 * Verify detached message signature
29834 * @param {Array<PublicKey>} verificationKeys - Array of public keys to verify signatures
29835 * @param {Signature} signature
29836 * @param {Date} date - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
29837 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29838 * @returns {Promise<Array<{
29839 * keyID: module:type/keyid~KeyID,
29840 * signature: Promise<Signature>,
29841 * verified: Promise<true>
29842 * }>>} List of signer's keyID and validity of signature.
29843 * @async
29844 */
29845 verifyDetached(signature, verificationKeys, date = new Date(), config = defaultConfig) {
29846 const msg = this.unwrapCompressed();
29847 const literalDataList = msg.packets.filterByTag(enums.packet.literalData);
29848 if (literalDataList.length !== 1) {
29849 throw new Error('Can only verify message with one literal data packet.');
29850 }
29851 const signatureList = signature.packets;
29852 return createVerificationObjects(signatureList, literalDataList, verificationKeys, date, true, config);
29853 }
29854
29855 /**
29856 * Unwrap compressed message
29857 * @returns {Message} Message Content of compressed message.
29858 */
29859 unwrapCompressed() {
29860 const compressed = this.packets.filterByTag(enums.packet.compressedData);
29861 if (compressed.length) {
29862 return new Message(compressed[0].packets);
29863 }
29864 return this;
29865 }
29866
29867 /**
29868 * Append signature to unencrypted message object
29869 * @param {String|Uint8Array} detachedSignature - The detached ASCII-armored or Uint8Array PGP signature
29870 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29871 */
29872 async appendSignature(detachedSignature, config = defaultConfig) {
29873 await this.packets.read(
29874 util.isUint8Array(detachedSignature) ? detachedSignature : (await unarmor(detachedSignature)).data,
29875 allowedDetachedSignaturePackets,
29876 config
29877 );
29878 }
29879
29880 /**
29881 * Returns binary encoded message
29882 * @returns {ReadableStream<Uint8Array>} Binary message.
29883 */
29884 write() {
29885 return this.packets.write();
29886 }
29887
29888 /**
29889 * Returns ASCII armored text of message
29890 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29891 * @returns {ReadableStream<String>} ASCII armor.
29892 */
29893 armor(config = defaultConfig) {
29894 return armor(enums.armor.message, this.write(), null, null, null, config);
29895 }
29896}
29897
29898/**
29899 * Create signature packets for the message
29900 * @param {LiteralDataPacket} literalDataPacket - the literal data packet to sign
29901 * @param {Array<PrivateKey>} [signingKeys] - private keys with decrypted secret key data for signing
29902 * @param {Signature} [signature] - Any existing detached signature to append
29903 * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
29904 * @param {Date} [date] - Override the creationtime of the signature
29905 * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
29906 * @param {Boolean} [detached] - Whether to create detached signature packets
29907 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29908 * @returns {Promise<PacketList>} List of signature packets.
29909 * @async
29910 * @private
29911 */
29912async function createSignaturePackets(literalDataPacket, signingKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], detached = false, config = defaultConfig) {
29913 const packetlist = new PacketList();
29914
29915 // If data packet was created from Uint8Array, use binary, otherwise use text
29916 const signatureType = literalDataPacket.text === null ?
29917 enums.signature.binary : enums.signature.text;
29918
29919 await Promise.all(signingKeys.map(async (primaryKey, i) => {
29920 const userID = userIDs[i];
29921 if (!primaryKey.isPrivate()) {
29922 throw new Error('Need private key for signing');
29923 }
29924 const signingKey = await primaryKey.getSigningKey(signingKeyIDs[i], date, userID, config);
29925 return createSignaturePacket(literalDataPacket, primaryKey, signingKey.keyPacket, { signatureType }, date, userID, detached, config);
29926 })).then(signatureList => {
29927 packetlist.push(...signatureList);
29928 });
29929
29930 if (signature) {
29931 const existingSigPacketlist = signature.packets.filterByTag(enums.packet.signature);
29932 packetlist.push(...existingSigPacketlist);
29933 }
29934 return packetlist;
29935}
29936
29937/**
29938 * Create object containing signer's keyID and validity of signature
29939 * @param {SignaturePacket} signature - Signature packet
29940 * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
29941 * @param {Array<PublicKey>} verificationKeys - Array of public keys to verify signatures
29942 * @param {Date} [date] - Check signature validity with respect to the given date
29943 * @param {Boolean} [detached] - Whether to verify detached signature packets
29944 * @param {Object} [config] - Full configuration, defaults to openpgp.config
29945 * @returns {Promise<{
29946 * keyID: module:type/keyid~KeyID,
29947 * signature: Promise<Signature>,
29948 * verified: Promise<true>
29949 * }>} signer's keyID and validity of signature
29950 * @async
29951 * @private
29952 */
29953async function createVerificationObject(signature, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
29954 let primaryKey;
29955 let unverifiedSigningKey;
29956
29957 for (const key of verificationKeys) {
29958 const issuerKeys = key.getKeys(signature.issuerKeyID);
29959 if (issuerKeys.length > 0) {
29960 primaryKey = key;
29961 unverifiedSigningKey = issuerKeys[0];
29962 break;
29963 }
29964 }
29965
29966 const isOnePassSignature = signature instanceof OnePassSignaturePacket;
29967 const signaturePacketPromise = isOnePassSignature ? signature.correspondingSig : signature;
29968
29969 const verifiedSig = {
29970 keyID: signature.issuerKeyID,
29971 verified: (async () => {
29972 if (!unverifiedSigningKey) {
29973 throw new Error(`Could not find signing key with key ID ${signature.issuerKeyID.toHex()}`);
29974 }
29975
29976 await signature.verify(unverifiedSigningKey.keyPacket, signature.signatureType, literalDataList[0], date, detached, config);
29977 const signaturePacket = await signaturePacketPromise;
29978 if (unverifiedSigningKey.getCreationTime() > signaturePacket.created) {
29979 throw new Error('Key is newer than the signature');
29980 }
29981 // We pass the signature creation time to check whether the key was expired at the time of signing.
29982 // We check this after signature verification because for streamed one-pass signatures, the creation time is not available before
29983 try {
29984 await primaryKey.getSigningKey(unverifiedSigningKey.getKeyID(), signaturePacket.created, undefined, config);
29985 } catch (e) {
29986 // If a key was reformatted then the self-signatures of the signing key might be in the future compared to the message signature,
29987 // making the key invalid at the time of signing.
29988 // However, if the key is valid at the given `date`, we still allow using it provided the relevant `config` setting is enabled.
29989 // Note: we do not support the edge case of a key that was reformatted and it has expired.
29990 if (config.allowInsecureVerificationWithReformattedKeys && e.message.match(/Signature creation time is in the future/)) {
29991 await primaryKey.getSigningKey(unverifiedSigningKey.getKeyID(), date, undefined, config);
29992 } else {
29993 throw e;
29994 }
29995 }
29996 return true;
29997 })(),
29998 signature: (async () => {
29999 const signaturePacket = await signaturePacketPromise;
30000 const packetlist = new PacketList();
30001 signaturePacket && packetlist.push(signaturePacket);
30002 return new Signature(packetlist);
30003 })()
30004 };
30005
30006 // Mark potential promise rejections as "handled". This is needed because in
30007 // some cases, we reject them before the user has a reasonable chance to
30008 // handle them (e.g. `await readToEnd(result.data); await result.verified` and
30009 // the data stream errors).
30010 verifiedSig.signature.catch(() => {});
30011 verifiedSig.verified.catch(() => {});
30012
30013 return verifiedSig;
30014}
30015
30016/**
30017 * Create list of objects containing signer's keyID and validity of signature
30018 * @param {Array<SignaturePacket>} signatureList - Array of signature packets
30019 * @param {Array<LiteralDataPacket>} literalDataList - Array of literal data packets
30020 * @param {Array<PublicKey>} verificationKeys - Array of public keys to verify signatures
30021 * @param {Date} date - Verify the signature against the given date,
30022 * i.e. check signature creation time < date < expiration time
30023 * @param {Boolean} [detached] - Whether to verify detached signature packets
30024 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30025 * @returns {Promise<Array<{
30026 * keyID: module:type/keyid~KeyID,
30027 * signature: Promise<Signature>,
30028 * verified: Promise<true>
30029 * }>>} list of signer's keyID and validity of signatures (one entry per signature packet in input)
30030 * @async
30031 * @private
30032 */
30033async function createVerificationObjects(signatureList, literalDataList, verificationKeys, date = new Date(), detached = false, config = defaultConfig) {
30034 return Promise.all(signatureList.filter(function(signature) {
30035 return ['text', 'binary'].includes(enums.read(enums.signature, signature.signatureType));
30036 }).map(async function(signature) {
30037 return createVerificationObject(signature, literalDataList, verificationKeys, date, detached, config);
30038 }));
30039}
30040
30041/**
30042 * Reads an (optionally armored) OpenPGP message and returns a Message object
30043 * @param {Object} options
30044 * @param {String | ReadableStream<String>} [options.armoredMessage] - Armored message to be parsed
30045 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binaryMessage] - Binary to be parsed
30046 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30047 * @returns {Promise<Message>} New message object.
30048 * @async
30049 * @static
30050 */
30051async function readMessage({ armoredMessage, binaryMessage, config, ...rest }) {
30052 config = { ...defaultConfig, ...config };
30053 let input = armoredMessage || binaryMessage;
30054 if (!input) {
30055 throw new Error('readMessage: must pass options object containing `armoredMessage` or `binaryMessage`');
30056 }
30057 if (armoredMessage && !util.isString(armoredMessage) && !util.isStream(armoredMessage)) {
30058 throw new Error('readMessage: options.armoredMessage must be a string or stream');
30059 }
30060 if (binaryMessage && !util.isUint8Array(binaryMessage) && !util.isStream(binaryMessage)) {
30061 throw new Error('readMessage: options.binaryMessage must be a Uint8Array or stream');
30062 }
30063 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30064
30065 const streamType = util.isStream(input);
30066 if (streamType) {
30067 await loadStreamsPonyfill();
30068 input = toStream(input);
30069 }
30070 if (armoredMessage) {
30071 const { type, data } = await unarmor(input, config);
30072 if (type !== enums.armor.message) {
30073 throw new Error('Armored text not of type message');
30074 }
30075 input = data;
30076 }
30077 const packetlist = await PacketList.fromBinary(input, allowedMessagePackets, config);
30078 const message = new Message(packetlist);
30079 message.fromStream = streamType;
30080 return message;
30081}
30082
30083/**
30084 * Creates new message object from text or binary data.
30085 * @param {Object} options
30086 * @param {String | ReadableStream<String>} [options.text] - The text message contents
30087 * @param {Uint8Array | ReadableStream<Uint8Array>} [options.binary] - The binary message contents
30088 * @param {String} [options.filename=""] - Name of the file (if any)
30089 * @param {Date} [options.date=current date] - Date of the message, or modification date of the file
30090 * @param {'utf8'|'binary'|'text'|'mime'} [options.format='utf8' if text is passed, 'binary' otherwise] - Data packet type
30091 * @returns {Promise<Message>} New message object.
30092 * @async
30093 * @static
30094 */
30095async function createMessage({ text, binary, filename, date = new Date(), format = text !== undefined ? 'utf8' : 'binary', ...rest }) {
30096 let input = text !== undefined ? text : binary;
30097 if (input === undefined) {
30098 throw new Error('createMessage: must pass options object containing `text` or `binary`');
30099 }
30100 if (text && !util.isString(text) && !util.isStream(text)) {
30101 throw new Error('createMessage: options.text must be a string or stream');
30102 }
30103 if (binary && !util.isUint8Array(binary) && !util.isStream(binary)) {
30104 throw new Error('createMessage: options.binary must be a Uint8Array or stream');
30105 }
30106 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30107
30108 const streamType = util.isStream(input);
30109 if (streamType) {
30110 await loadStreamsPonyfill();
30111 input = toStream(input);
30112 }
30113 const literalDataPacket = new LiteralDataPacket(date);
30114 if (text !== undefined) {
30115 literalDataPacket.setText(input, enums.write(enums.literal, format));
30116 } else {
30117 literalDataPacket.setBytes(input, enums.write(enums.literal, format));
30118 }
30119 if (filename !== undefined) {
30120 literalDataPacket.setFilename(filename);
30121 }
30122 const literalDataPacketlist = new PacketList();
30123 literalDataPacketlist.push(literalDataPacket);
30124 const message = new Message(literalDataPacketlist);
30125 message.fromStream = streamType;
30126 return message;
30127}
30128
30129// GPG4Browsers - An OpenPGP implementation in javascript
30130
30131// A Cleartext message can contain the following packets
30132const allowedPackets$5 = /*#__PURE__*/ util.constructAllowedPackets([SignaturePacket]);
30133
30134/**
30135 * Class that represents an OpenPGP cleartext signed message.
30136 * See {@link https://tools.ietf.org/html/rfc4880#section-7}
30137 */
30138class CleartextMessage {
30139 /**
30140 * @param {String} text - The cleartext of the signed message
30141 * @param {Signature} signature - The detached signature or an empty signature for unsigned messages
30142 */
30143 constructor(text, signature) {
30144 // remove trailing whitespace and normalize EOL to canonical form <CR><LF>
30145 this.text = util.removeTrailingSpaces(text).replace(/\r?\n/g, '\r\n');
30146 if (signature && !(signature instanceof Signature)) {
30147 throw new Error('Invalid signature input');
30148 }
30149 this.signature = signature || new Signature(new PacketList());
30150 }
30151
30152 /**
30153 * Returns the key IDs of the keys that signed the cleartext message
30154 * @returns {Array<module:type/keyid~KeyID>} Array of keyID objects.
30155 */
30156 getSigningKeyIDs() {
30157 const keyIDs = [];
30158 const signatureList = this.signature.packets;
30159 signatureList.forEach(function(packet) {
30160 keyIDs.push(packet.issuerKeyID);
30161 });
30162 return keyIDs;
30163 }
30164
30165 /**
30166 * Sign the cleartext message
30167 * @param {Array<Key>} privateKeys - private keys with decrypted secret key data for signing
30168 * @param {Signature} [signature] - Any existing detached signature
30169 * @param {Array<module:type/keyid~KeyID>} [signingKeyIDs] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to privateKeys[i]
30170 * @param {Date} [date] - The creation time of the signature that should be created
30171 * @param {Array} [userIDs] - User IDs to sign with, e.g. [{ name:'Steve Sender', email:'steve@openpgp.org' }]
30172 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30173 * @returns {Promise<CleartextMessage>} New cleartext message with signed content.
30174 * @async
30175 */
30176 async sign(privateKeys, signature = null, signingKeyIDs = [], date = new Date(), userIDs = [], config = defaultConfig) {
30177 const literalDataPacket = new LiteralDataPacket();
30178 literalDataPacket.setText(this.text);
30179 const newSignature = new Signature(await createSignaturePackets(literalDataPacket, privateKeys, signature, signingKeyIDs, date, userIDs, true, config));
30180 return new CleartextMessage(this.text, newSignature);
30181 }
30182
30183 /**
30184 * Verify signatures of cleartext signed message
30185 * @param {Array<Key>} keys - Array of keys to verify signatures
30186 * @param {Date} [date] - Verify the signature against the given date, i.e. check signature creation time < date < expiration time
30187 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30188 * @returns {Promise<Array<{
30189 * keyID: module:type/keyid~KeyID,
30190 * signature: Promise<Signature>,
30191 * verified: Promise<true>
30192 * }>>} List of signer's keyID and validity of signature.
30193 * @async
30194 */
30195 verify(keys, date = new Date(), config = defaultConfig) {
30196 const signatureList = this.signature.packets;
30197 const literalDataPacket = new LiteralDataPacket();
30198 // we assume that cleartext signature is generated based on UTF8 cleartext
30199 literalDataPacket.setText(this.text);
30200 return createVerificationObjects(signatureList, [literalDataPacket], keys, date, true, config);
30201 }
30202
30203 /**
30204 * Get cleartext
30205 * @returns {String} Cleartext of message.
30206 */
30207 getText() {
30208 // normalize end of line to \n
30209 return this.text.replace(/\r\n/g, '\n');
30210 }
30211
30212 /**
30213 * Returns ASCII armored text of cleartext signed message
30214 * @param {Object} [config] - Full configuration, defaults to openpgp.config
30215 * @returns {String | ReadableStream<String>} ASCII armor.
30216 */
30217 armor(config = defaultConfig) {
30218 let hashes = this.signature.packets.map(function(packet) {
30219 return enums.read(enums.hash, packet.hashAlgorithm).toUpperCase();
30220 });
30221 hashes = hashes.filter(function(item, i, ar) { return ar.indexOf(item) === i; });
30222 const body = {
30223 hash: hashes.join(),
30224 text: this.text,
30225 data: this.signature.packets.write()
30226 };
30227 return armor(enums.armor.signed, body, undefined, undefined, undefined, config);
30228 }
30229}
30230
30231/**
30232 * Reads an OpenPGP cleartext signed message and returns a CleartextMessage object
30233 * @param {Object} options
30234 * @param {String} options.cleartextMessage - Text to be parsed
30235 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30236 * @returns {Promise<CleartextMessage>} New cleartext message object.
30237 * @async
30238 * @static
30239 */
30240async function readCleartextMessage({ cleartextMessage, config, ...rest }) {
30241 config = { ...defaultConfig, ...config };
30242 if (!cleartextMessage) {
30243 throw new Error('readCleartextMessage: must pass options object containing `cleartextMessage`');
30244 }
30245 if (!util.isString(cleartextMessage)) {
30246 throw new Error('readCleartextMessage: options.cleartextMessage must be a string');
30247 }
30248 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30249
30250 const input = await unarmor(cleartextMessage);
30251 if (input.type !== enums.armor.signed) {
30252 throw new Error('No cleartext signed message.');
30253 }
30254 const packetlist = await PacketList.fromBinary(input.data, allowedPackets$5, config);
30255 verifyHeaders$1(input.headers, packetlist);
30256 const signature = new Signature(packetlist);
30257 return new CleartextMessage(input.text, signature);
30258}
30259
30260/**
30261 * Compare hash algorithm specified in the armor header with signatures
30262 * @param {Array<String>} headers - Armor headers
30263 * @param {PacketList} packetlist - The packetlist with signature packets
30264 * @private
30265 */
30266function verifyHeaders$1(headers, packetlist) {
30267 const checkHashAlgos = function(hashAlgos) {
30268 const check = packet => algo => packet.hashAlgorithm === algo;
30269
30270 for (let i = 0; i < packetlist.length; i++) {
30271 if (packetlist[i].constructor.tag === enums.packet.signature && !hashAlgos.some(check(packetlist[i]))) {
30272 return false;
30273 }
30274 }
30275 return true;
30276 };
30277
30278 let oneHeader = null;
30279 let hashAlgos = [];
30280 headers.forEach(function(header) {
30281 oneHeader = header.match(/Hash: (.+)/); // get header value
30282 if (oneHeader) {
30283 oneHeader = oneHeader[1].replace(/\s/g, ''); // remove whitespace
30284 oneHeader = oneHeader.split(',');
30285 oneHeader = oneHeader.map(function(hash) {
30286 hash = hash.toLowerCase();
30287 try {
30288 return enums.write(enums.hash, hash);
30289 } catch (e) {
30290 throw new Error('Unknown hash algorithm in armor header: ' + hash);
30291 }
30292 });
30293 hashAlgos = hashAlgos.concat(oneHeader);
30294 } else {
30295 throw new Error('Only "Hash" header allowed in cleartext signed message');
30296 }
30297 });
30298
30299 if (!hashAlgos.length && !checkHashAlgos([enums.hash.md5])) {
30300 throw new Error('If no "Hash" header in cleartext signed message, then only MD5 signatures allowed');
30301 } else if (hashAlgos.length && !checkHashAlgos(hashAlgos)) {
30302 throw new Error('Hash algorithm mismatch in armor header and signature');
30303 }
30304}
30305
30306/**
30307 * Creates a new CleartextMessage object from text
30308 * @param {Object} options
30309 * @param {String} options.text
30310 * @static
30311 * @async
30312 */
30313async function createCleartextMessage({ text, ...rest }) {
30314 if (!text) {
30315 throw new Error('createCleartextMessage: must pass options object containing `text`');
30316 }
30317 if (!util.isString(text)) {
30318 throw new Error('createCleartextMessage: options.text must be a string');
30319 }
30320 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30321
30322 return new CleartextMessage(text);
30323}
30324
30325// OpenPGP.js - An OpenPGP implementation in javascript
30326
30327
30328//////////////////////
30329// //
30330// Key handling //
30331// //
30332//////////////////////
30333
30334
30335/**
30336 * Generates a new OpenPGP key pair. Supports RSA and ECC keys. By default, primary and subkeys will be of same type.
30337 * The generated primary key will have signing capabilities. By default, one subkey with encryption capabilities is also generated.
30338 * @param {Object} options
30339 * @param {Object|Array<Object>} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
30340 * @param {'ecc'|'rsa'} [options.type='ecc'] - The primary key algorithm type: ECC (default) or RSA
30341 * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the generated private key. If omitted or empty, the key won't be encrypted.
30342 * @param {Number} [options.rsaBits=4096] - Number of bits for RSA keys
30343 * @param {String} [options.curve='curve25519'] - Elliptic curve for ECC keys:
30344 * curve25519 (default), p256, p384, p521, secp256k1,
30345 * brainpoolP256r1, brainpoolP384r1, or brainpoolP512r1
30346 * @param {Date} [options.date=current date] - Override the creation date of the key and the key signatures
30347 * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
30348 * @param {Array<Object>} [options.subkeys=a single encryption subkey] - Options for each subkey e.g. `[{sign: true, passphrase: '123'}]`
30349 * default to main key options, except for `sign` parameter that defaults to false, and indicates whether the subkey should sign rather than encrypt
30350 * @param {'armored'|'binary'|'object'} [options.format='armored'] - format of the output keys
30351 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30352 * @returns {Promise<Object>} The generated key object in the form:
30353 * { privateKey:PrivateKey|Uint8Array|String, publicKey:PublicKey|Uint8Array|String, revocationCertificate:String }
30354 * @async
30355 * @static
30356 */
30357async function generateKey({ userIDs = [], passphrase, type = 'ecc', rsaBits = 4096, curve = 'curve25519', keyExpirationTime = 0, date = new Date(), subkeys = [{}], format = 'armored', config, ...rest }) {
30358 config = { ...defaultConfig, ...config }; checkConfig(config);
30359 userIDs = toArray$1(userIDs);
30360 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30361
30362 if (userIDs.length === 0) {
30363 throw new Error('UserIDs are required for key generation');
30364 }
30365 if (type === 'rsa' && rsaBits < config.minRSABits) {
30366 throw new Error(`rsaBits should be at least ${config.minRSABits}, got: ${rsaBits}`);
30367 }
30368
30369 const options = { userIDs, passphrase, type, rsaBits, curve, keyExpirationTime, date, subkeys };
30370
30371 try {
30372 const { key, revocationCertificate } = await generate$2(options, config);
30373 key.getKeys().forEach(({ keyPacket }) => checkKeyRequirements(keyPacket, config));
30374
30375 return {
30376 privateKey: formatObject(key, format, config),
30377 publicKey: formatObject(key.toPublic(), format, config),
30378 revocationCertificate
30379 };
30380 } catch (err) {
30381 throw util.wrapError('Error generating keypair', err);
30382 }
30383}
30384
30385/**
30386 * Reformats signature packets for a key and rewraps key object.
30387 * @param {Object} options
30388 * @param {PrivateKey} options.privateKey - Private key to reformat
30389 * @param {Object|Array<Object>} options.userIDs - User IDs as objects: `{ name: 'Jo Doe', email: 'info@jo.com' }`
30390 * @param {String} [options.passphrase=(not protected)] - The passphrase used to encrypt the reformatted private key. If omitted or empty, the key won't be encrypted.
30391 * @param {Number} [options.keyExpirationTime=0 (never expires)] - Number of seconds from the key creation time after which the key expires
30392 * @param {Date} [options.date] - Override the creation date of the key signatures. If the key was previously used to sign messages, it is recommended
30393 * to set the same date as the key creation time to ensure that old message signatures will still be verifiable using the reformatted key.
30394 * @param {'armored'|'binary'|'object'} [options.format='armored'] - format of the output keys
30395 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30396 * @returns {Promise<Object>} The generated key object in the form:
30397 * { privateKey:PrivateKey|Uint8Array|String, publicKey:PublicKey|Uint8Array|String, revocationCertificate:String }
30398 * @async
30399 * @static
30400 */
30401async function reformatKey({ privateKey, userIDs = [], passphrase, keyExpirationTime = 0, date, format = 'armored', config, ...rest }) {
30402 config = { ...defaultConfig, ...config }; checkConfig(config);
30403 userIDs = toArray$1(userIDs);
30404 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30405
30406 if (userIDs.length === 0) {
30407 throw new Error('UserIDs are required for key reformat');
30408 }
30409 const options = { privateKey, userIDs, passphrase, keyExpirationTime, date };
30410
30411 try {
30412 const { key: reformattedKey, revocationCertificate } = await reformat(options, config);
30413
30414 return {
30415 privateKey: formatObject(reformattedKey, format, config),
30416 publicKey: formatObject(reformattedKey.toPublic(), format, config),
30417 revocationCertificate
30418 };
30419 } catch (err) {
30420 throw util.wrapError('Error reformatting keypair', err);
30421 }
30422}
30423
30424/**
30425 * Revokes a key. Requires either a private key or a revocation certificate.
30426 * If a revocation certificate is passed, the reasonForRevocation parameter will be ignored.
30427 * @param {Object} options
30428 * @param {Key} options.key - Public or private key to revoke
30429 * @param {String} [options.revocationCertificate] - Revocation certificate to revoke the key with
30430 * @param {Object} [options.reasonForRevocation] - Object indicating the reason for revocation
30431 * @param {module:enums.reasonForRevocation} [options.reasonForRevocation.flag=[noReason]{@link module:enums.reasonForRevocation}] - Flag indicating the reason for revocation
30432 * @param {String} [options.reasonForRevocation.string=""] - String explaining the reason for revocation
30433 * @param {Date} [options.date] - Use the given date instead of the current time to verify validity of revocation certificate (if provided), or as creation time of the revocation signature
30434 * @param {'armored'|'binary'|'object'} [options.format='armored'] - format of the output key(s)
30435 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30436 * @returns {Promise<Object>} The revoked key in the form:
30437 * { privateKey:PrivateKey|Uint8Array|String, publicKey:PublicKey|Uint8Array|String } if private key is passed, or
30438 * { privateKey: null, publicKey:PublicKey|Uint8Array|String } otherwise
30439 * @async
30440 * @static
30441 */
30442async function revokeKey({ key, revocationCertificate, reasonForRevocation, date = new Date(), format = 'armored', config, ...rest }) {
30443 config = { ...defaultConfig, ...config }; checkConfig(config);
30444 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30445
30446 try {
30447 const revokedKey = revocationCertificate ?
30448 await key.applyRevocationCertificate(revocationCertificate, date, config) :
30449 await key.revoke(reasonForRevocation, date, config);
30450
30451 return revokedKey.isPrivate() ? {
30452 privateKey: formatObject(revokedKey, format, config),
30453 publicKey: formatObject(revokedKey.toPublic(), format, config)
30454 } : {
30455 privateKey: null,
30456 publicKey: formatObject(revokedKey, format, config)
30457 };
30458 } catch (err) {
30459 throw util.wrapError('Error revoking key', err);
30460 }
30461}
30462
30463/**
30464 * Unlock a private key with the given passphrase.
30465 * This method does not change the original key.
30466 * @param {Object} options
30467 * @param {PrivateKey} options.privateKey - The private key to decrypt
30468 * @param {String|Array<String>} options.passphrase - The user's passphrase(s)
30469 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30470 * @returns {Promise<PrivateKey>} The unlocked key object.
30471 * @async
30472 */
30473async function decryptKey({ privateKey, passphrase, config, ...rest }) {
30474 config = { ...defaultConfig, ...config }; checkConfig(config);
30475 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30476
30477 if (!privateKey.isPrivate()) {
30478 throw new Error('Cannot decrypt a public key');
30479 }
30480 const clonedPrivateKey = privateKey.clone(true);
30481 const passphrases = util.isArray(passphrase) ? passphrase : [passphrase];
30482
30483 try {
30484 await Promise.all(clonedPrivateKey.getKeys().map(key => (
30485 // try to decrypt each key with any of the given passphrases
30486 util.anyPromise(passphrases.map(passphrase => key.keyPacket.decrypt(passphrase)))
30487 )));
30488
30489 await clonedPrivateKey.validate(config);
30490 return clonedPrivateKey;
30491 } catch (err) {
30492 clonedPrivateKey.clearPrivateParams();
30493 throw util.wrapError('Error decrypting private key', err);
30494 }
30495}
30496
30497/**
30498 * Lock a private key with the given passphrase.
30499 * This method does not change the original key.
30500 * @param {Object} options
30501 * @param {PrivateKey} options.privateKey - The private key to encrypt
30502 * @param {String|Array<String>} options.passphrase - If multiple passphrases, they should be in the same order as the packets each should encrypt
30503 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30504 * @returns {Promise<PrivateKey>} The locked key object.
30505 * @async
30506 */
30507async function encryptKey({ privateKey, passphrase, config, ...rest }) {
30508 config = { ...defaultConfig, ...config }; checkConfig(config);
30509 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30510
30511 if (!privateKey.isPrivate()) {
30512 throw new Error('Cannot encrypt a public key');
30513 }
30514 const clonedPrivateKey = privateKey.clone(true);
30515
30516 const keys = clonedPrivateKey.getKeys();
30517 const passphrases = util.isArray(passphrase) ? passphrase : new Array(keys.length).fill(passphrase);
30518 if (passphrases.length !== keys.length) {
30519 throw new Error('Invalid number of passphrases given for key encryption');
30520 }
30521
30522 try {
30523 await Promise.all(keys.map(async (key, i) => {
30524 const { keyPacket } = key;
30525 await keyPacket.encrypt(passphrases[i], config);
30526 keyPacket.clearPrivateParams();
30527 }));
30528 return clonedPrivateKey;
30529 } catch (err) {
30530 clonedPrivateKey.clearPrivateParams();
30531 throw util.wrapError('Error encrypting private key', err);
30532 }
30533}
30534
30535
30536///////////////////////////////////////////
30537// //
30538// Message encryption and decryption //
30539// //
30540///////////////////////////////////////////
30541
30542
30543/**
30544 * Encrypts a message using public keys, passwords or both at once. At least one of `encryptionKeys`, `passwords` or `sessionKeys`
30545 * must be specified. If signing keys are specified, those will be used to sign the message.
30546 * @param {Object} options
30547 * @param {Message} options.message - Message to be encrypted as created by {@link createMessage}
30548 * @param {PublicKey|PublicKey[]} [options.encryptionKeys] - Array of keys or single key, used to encrypt the message
30549 * @param {PrivateKey|PrivateKey[]} [options.signingKeys] - Private keys for signing. If omitted message will not be signed
30550 * @param {String|String[]} [options.passwords] - Array of passwords or a single password to encrypt the message
30551 * @param {Object} [options.sessionKey] - Session key in the form: `{ data:Uint8Array, algorithm:String }`
30552 * @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message
30553 * @param {Signature} [options.signature] - A detached signature to add to the encrypted message
30554 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
30555 * @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each `signingKeyIDs[i]` corresponds to `signingKeys[i]`
30556 * @param {KeyID|KeyID[]} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each `encryptionKeyIDs[i]` corresponds to `encryptionKeys[i]`
30557 * @param {Date} [options.date=current date] - Override the creation date of the message signature
30558 * @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
30559 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `encryptionKeys`, e.g. `[{ name: 'Robert Receiver', email: 'robert@openpgp.org' }]`
30560 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30561 * @returns {Promise<MaybeStream<String>|MaybeStream<Uint8Array>>} Encrypted message (string if `armor` was true, the default; Uint8Array if `armor` was false).
30562 * @async
30563 * @static
30564 */
30565async function encrypt$4({ message, encryptionKeys, signingKeys, passwords, sessionKey, format = 'armored', signature = null, wildcard = false, signingKeyIDs = [], encryptionKeyIDs = [], date = new Date(), signingUserIDs = [], encryptionUserIDs = [], config, ...rest }) {
30566 config = { ...defaultConfig, ...config }; checkConfig(config);
30567 checkMessage(message); checkOutputMessageFormat(format);
30568 encryptionKeys = toArray$1(encryptionKeys); signingKeys = toArray$1(signingKeys); passwords = toArray$1(passwords);
30569 signingKeyIDs = toArray$1(signingKeyIDs); encryptionKeyIDs = toArray$1(encryptionKeyIDs); signingUserIDs = toArray$1(signingUserIDs); encryptionUserIDs = toArray$1(encryptionUserIDs);
30570 if (rest.detached) {
30571 throw new Error("The `detached` option has been removed from openpgp.encrypt, separately call openpgp.sign instead. Don't forget to remove the `privateKeys` option as well.");
30572 }
30573 if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.encrypt, pass `encryptionKeys` instead');
30574 if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.encrypt, pass `signingKeys` instead');
30575 if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.encrypt, pass `format` instead.');
30576 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30577
30578 if (!signingKeys) {
30579 signingKeys = [];
30580 }
30581 const streaming = message.fromStream;
30582 try {
30583 if (signingKeys.length || signature) { // sign the message only if signing keys or signature is specified
30584 message = await message.sign(signingKeys, signature, signingKeyIDs, date, signingUserIDs, config);
30585 }
30586 message = message.compress(
30587 await getPreferredAlgo('compression', encryptionKeys, date, encryptionUserIDs, config),
30588 config
30589 );
30590 message = await message.encrypt(encryptionKeys, passwords, sessionKey, wildcard, encryptionKeyIDs, date, encryptionUserIDs, config);
30591 if (format === 'object') return message;
30592 // serialize data
30593 const armor = format === 'armored';
30594 const data = armor ? message.armor(config) : message.write();
30595 return convertStream(data, streaming, armor ? 'utf8' : 'binary');
30596 } catch (err) {
30597 throw util.wrapError('Error encrypting message', err);
30598 }
30599}
30600
30601/**
30602 * Decrypts a message with the user's private key, a session key or a password.
30603 * One of `decryptionKeys`, `sessionkeys` or `passwords` must be specified (passing a combination of these options is not supported).
30604 * @param {Object} options
30605 * @param {Message} options.message - The message object with the encrypted data
30606 * @param {PrivateKey|PrivateKey[]} [options.decryptionKeys] - Private keys with decrypted secret key data or session key
30607 * @param {String|String[]} [options.passwords] - Passwords to decrypt the message
30608 * @param {Object|Object[]} [options.sessionKeys] - Session keys in the form: { data:Uint8Array, algorithm:String }
30609 * @param {PublicKey|PublicKey[]} [options.verificationKeys] - Array of public keys or single key, to verify signatures
30610 * @param {Boolean} [options.expectSigned=false] - If true, data decryption fails if the message is not signed with the provided publicKeys
30611 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
30612 * @param {Signature} [options.signature] - Detached signature for verification
30613 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
30614 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30615 * @returns {Promise<Object>} Object containing decrypted and verified message in the form:
30616 *
30617 * {
30618 * data: MaybeStream<String>, (if format was 'utf8', the default)
30619 * data: MaybeStream<Uint8Array>, (if format was 'binary')
30620 * filename: String,
30621 * signatures: [
30622 * {
30623 * keyID: module:type/keyid~KeyID,
30624 * verified: Promise<true>,
30625 * signature: Promise<Signature>
30626 * }, ...
30627 * ]
30628 * }
30629 *
30630 * where `signatures` contains a separate entry for each signature packet found in the input message.
30631 * @async
30632 * @static
30633 */
30634async function decrypt$4({ message, decryptionKeys, passwords, sessionKeys, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config, ...rest }) {
30635 config = { ...defaultConfig, ...config }; checkConfig(config);
30636 checkMessage(message); verificationKeys = toArray$1(verificationKeys); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords); sessionKeys = toArray$1(sessionKeys);
30637 if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decrypt, pass `decryptionKeys` instead');
30638 if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.decrypt, pass `verificationKeys` instead');
30639 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30640
30641 try {
30642 const decrypted = await message.decrypt(decryptionKeys, passwords, sessionKeys, date, config);
30643 if (!verificationKeys) {
30644 verificationKeys = [];
30645 }
30646
30647 const result = {};
30648 result.signatures = signature ? await decrypted.verifyDetached(signature, verificationKeys, date, config) : await decrypted.verify(verificationKeys, date, config);
30649 result.data = format === 'binary' ? decrypted.getLiteralData() : decrypted.getText();
30650 result.filename = decrypted.getFilename();
30651 linkStreams(result, message);
30652 if (expectSigned) {
30653 if (verificationKeys.length === 0) {
30654 throw new Error('Verification keys are required to verify message signatures');
30655 }
30656 if (result.signatures.length === 0) {
30657 throw new Error('Message is not signed');
30658 }
30659 result.data = concat([
30660 result.data,
30661 fromAsync(async () => {
30662 await util.anyPromise(result.signatures.map(sig => sig.verified));
30663 })
30664 ]);
30665 }
30666 result.data = await convertStream(result.data, message.fromStream, format);
30667 return result;
30668 } catch (err) {
30669 throw util.wrapError('Error decrypting message', err);
30670 }
30671}
30672
30673
30674//////////////////////////////////////////
30675// //
30676// Message signing and verification //
30677// //
30678//////////////////////////////////////////
30679
30680
30681/**
30682 * Signs a message.
30683 * @param {Object} options
30684 * @param {CleartextMessage|Message} options.message - (cleartext) message to be signed
30685 * @param {PrivateKey|PrivateKey[]} options.signingKeys - Array of keys or single key with decrypted secret key data to sign cleartext
30686 * @param {'armored'|'binary'|'object'} [options.format='armored'] - Format of the returned message
30687 * @param {Boolean} [options.detached=false] - If the return value should contain a detached signature
30688 * @param {KeyID|KeyID[]} [options.signingKeyIDs=latest-created valid signing (sub)keys] - Array of key IDs to use for signing. Each signingKeyIDs[i] corresponds to signingKeys[i]
30689 * @param {Date} [options.date=current date] - Override the creation date of the signature
30690 * @param {Object|Object[]} [options.signingUserIDs=primary user IDs] - Array of user IDs to sign with, one per key in `signingKeys`, e.g. `[{ name: 'Steve Sender', email: 'steve@openpgp.org' }]`
30691 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30692 * @returns {Promise<MaybeStream<String|Uint8Array>>} Signed message (string if `armor` was true, the default; Uint8Array if `armor` was false).
30693 * @async
30694 * @static
30695 */
30696async function sign$5({ message, signingKeys, format = 'armored', detached = false, signingKeyIDs = [], date = new Date(), signingUserIDs = [], config, ...rest }) {
30697 config = { ...defaultConfig, ...config }; checkConfig(config);
30698 checkCleartextOrMessage(message); checkOutputMessageFormat(format);
30699 signingKeys = toArray$1(signingKeys); signingKeyIDs = toArray$1(signingKeyIDs); signingUserIDs = toArray$1(signingUserIDs);
30700
30701 if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.sign, pass `signingKeys` instead');
30702 if (rest.armor !== undefined) throw new Error('The `armor` option has been removed from openpgp.sign, pass `format` instead.');
30703 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30704
30705 if (message instanceof CleartextMessage && format === 'binary') throw new Error('Cannot return signed cleartext message in binary format');
30706 if (message instanceof CleartextMessage && detached) throw new Error('Cannot detach-sign a cleartext message');
30707
30708 if (!signingKeys || signingKeys.length === 0) {
30709 throw new Error('No signing keys provided');
30710 }
30711
30712 try {
30713 let signature;
30714 if (detached) {
30715 signature = await message.signDetached(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, config);
30716 } else {
30717 signature = await message.sign(signingKeys, undefined, signingKeyIDs, date, signingUserIDs, config);
30718 }
30719 if (format === 'object') return signature;
30720
30721 const armor = format === 'armored';
30722 signature = armor ? signature.armor(config) : signature.write();
30723 if (detached) {
30724 signature = transformPair(message.packets.write(), async (readable, writable) => {
30725 await Promise.all([
30726 pipe(signature, writable),
30727 readToEnd(readable).catch(() => {})
30728 ]);
30729 });
30730 }
30731 return convertStream(signature, message.fromStream, armor ? 'utf8' : 'binary');
30732 } catch (err) {
30733 throw util.wrapError('Error signing message', err);
30734 }
30735}
30736
30737/**
30738 * Verifies signatures of cleartext signed message
30739 * @param {Object} options
30740 * @param {CleartextMessage|Message} options.message - (cleartext) message object with signatures
30741 * @param {PublicKey|PublicKey[]} options.verificationKeys - Array of publicKeys or single key, to verify signatures
30742 * @param {Boolean} [options.expectSigned=false] - If true, verification throws if the message is not signed with the provided publicKeys
30743 * @param {'utf8'|'binary'} [options.format='utf8'] - Whether to return data as a string(Stream) or Uint8Array(Stream). If 'utf8' (the default), also normalize newlines.
30744 * @param {Signature} [options.signature] - Detached signature for verification
30745 * @param {Date} [options.date=current date] - Use the given date for verification instead of the current time
30746 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30747 * @returns {Promise<Object>} Object containing verified message in the form:
30748 *
30749 * {
30750 * data: MaybeStream<String>, (if `message` was a CleartextMessage)
30751 * data: MaybeStream<Uint8Array>, (if `message` was a Message)
30752 * signatures: [
30753 * {
30754 * keyID: module:type/keyid~KeyID,
30755 * verified: Promise<true>,
30756 * signature: Promise<Signature>
30757 * }, ...
30758 * ]
30759 * }
30760 *
30761 * where `signatures` contains a separate entry for each signature packet found in the input message.
30762 * @async
30763 * @static
30764 */
30765async function verify$5({ message, verificationKeys, expectSigned = false, format = 'utf8', signature = null, date = new Date(), config, ...rest }) {
30766 config = { ...defaultConfig, ...config }; checkConfig(config);
30767 checkCleartextOrMessage(message); verificationKeys = toArray$1(verificationKeys);
30768 if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.verify, pass `verificationKeys` instead');
30769 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30770
30771 if (message instanceof CleartextMessage && format === 'binary') throw new Error("Can't return cleartext message data as binary");
30772 if (message instanceof CleartextMessage && signature) throw new Error("Can't verify detached cleartext signature");
30773
30774 try {
30775 const result = {};
30776 if (signature) {
30777 result.signatures = await message.verifyDetached(signature, verificationKeys, date, config);
30778 } else {
30779 result.signatures = await message.verify(verificationKeys, date, config);
30780 }
30781 result.data = format === 'binary' ? message.getLiteralData() : message.getText();
30782 if (message.fromStream) linkStreams(result, message);
30783 if (expectSigned) {
30784 if (result.signatures.length === 0) {
30785 throw new Error('Message is not signed');
30786 }
30787 result.data = concat([
30788 result.data,
30789 fromAsync(async () => {
30790 await util.anyPromise(result.signatures.map(sig => sig.verified));
30791 })
30792 ]);
30793 }
30794 result.data = await convertStream(result.data, message.fromStream, format);
30795 return result;
30796 } catch (err) {
30797 throw util.wrapError('Error verifying signed message', err);
30798 }
30799}
30800
30801
30802///////////////////////////////////////////////
30803// //
30804// Session key encryption and decryption //
30805// //
30806///////////////////////////////////////////////
30807
30808/**
30809 * Generate a new session key object, taking the algorithm preferences of the passed public keys into account.
30810 * @param {Object} options
30811 * @param {PublicKey|PublicKey[]} options.encryptionKeys - Array of public keys or single key used to select algorithm preferences for
30812 * @param {Date} [options.date=current date] - Date to select algorithm preferences at
30813 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - User IDs to select algorithm preferences for
30814 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30815 * @returns {Promise<{ data: Uint8Array, algorithm: String }>} Object with session key data and algorithm.
30816 * @async
30817 * @static
30818 */
30819async function generateSessionKey$1({ encryptionKeys, date = new Date(), encryptionUserIDs = [], config, ...rest }) {
30820 config = { ...defaultConfig, ...config }; checkConfig(config);
30821 encryptionKeys = toArray$1(encryptionKeys); encryptionUserIDs = toArray$1(encryptionUserIDs);
30822 if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.generateSessionKey, pass `encryptionKeys` instead');
30823 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30824
30825 try {
30826 const sessionKeys = await Message.generateSessionKey(encryptionKeys, date, encryptionUserIDs, config);
30827 return sessionKeys;
30828 } catch (err) {
30829 throw util.wrapError('Error generating session key', err);
30830 }
30831}
30832
30833/**
30834 * Encrypt a symmetric session key with public keys, passwords, or both at once.
30835 * At least one of `encryptionKeys` or `passwords` must be specified.
30836 * @param {Object} options
30837 * @param {Uint8Array} options.data - The session key to be encrypted e.g. 16 random bytes (for aes128)
30838 * @param {String} options.algorithm - Algorithm of the symmetric session key e.g. 'aes128' or 'aes256'
30839 * @param {String} [options.aeadAlgorithm] - AEAD algorithm, e.g. 'eax' or 'ocb'
30840 * @param {PublicKey|PublicKey[]} [options.encryptionKeys] - Array of public keys or single key, used to encrypt the key
30841 * @param {String|String[]} [options.passwords] - Passwords for the message
30842 * @param {'armored'|'binary'} [options.format='armored'] - Format of the returned value
30843 * @param {Boolean} [options.wildcard=false] - Use a key ID of 0 instead of the public key IDs
30844 * @param {KeyID|KeyID[]} [options.encryptionKeyIDs=latest-created valid encryption (sub)keys] - Array of key IDs to use for encryption. Each encryptionKeyIDs[i] corresponds to encryptionKeys[i]
30845 * @param {Date} [options.date=current date] - Override the date
30846 * @param {Object|Object[]} [options.encryptionUserIDs=primary user IDs] - Array of user IDs to encrypt for, one per key in `encryptionKeys`, e.g. `[{ name: 'Phil Zimmermann', email: 'phil@openpgp.org' }]`
30847 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30848 * @returns {Promise<String|Uint8Array>} Encrypted session keys (string if `armor` was true, the default; Uint8Array if `armor` was false).
30849 * @async
30850 * @static
30851 */
30852async function encryptSessionKey({ data, algorithm, aeadAlgorithm, encryptionKeys, passwords, format = 'armored', wildcard = false, encryptionKeyIDs = [], date = new Date(), encryptionUserIDs = [], config, ...rest }) {
30853 config = { ...defaultConfig, ...config }; checkConfig(config);
30854 checkBinary(data); checkString(algorithm, 'algorithm'); checkOutputMessageFormat(format);
30855 encryptionKeys = toArray$1(encryptionKeys); passwords = toArray$1(passwords); encryptionKeyIDs = toArray$1(encryptionKeyIDs); encryptionUserIDs = toArray$1(encryptionUserIDs);
30856 if (rest.publicKeys) throw new Error('The `publicKeys` option has been removed from openpgp.encryptSessionKey, pass `encryptionKeys` instead');
30857 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30858
30859 if ((!encryptionKeys || encryptionKeys.length === 0) && (!passwords || passwords.length === 0)) {
30860 throw new Error('No encryption keys or passwords provided.');
30861 }
30862
30863 try {
30864 const message = await Message.encryptSessionKey(data, algorithm, aeadAlgorithm, encryptionKeys, passwords, wildcard, encryptionKeyIDs, date, encryptionUserIDs, config);
30865 return formatObject(message, format, config);
30866 } catch (err) {
30867 throw util.wrapError('Error encrypting session key', err);
30868 }
30869}
30870
30871/**
30872 * Decrypt symmetric session keys using private keys or passwords (not both).
30873 * One of `decryptionKeys` or `passwords` must be specified.
30874 * @param {Object} options
30875 * @param {Message} options.message - A message object containing the encrypted session key packets
30876 * @param {PrivateKey|PrivateKey[]} [options.decryptionKeys] - Private keys with decrypted secret key data
30877 * @param {String|String[]} [options.passwords] - Passwords to decrypt the session key
30878 * @param {Date} [options.date] - Date to use for key verification instead of the current time
30879 * @param {Object} [options.config] - Custom configuration settings to overwrite those in [config]{@link module:config}
30880 * @returns {Promise<Object[]>} Array of decrypted session key, algorithm pairs in the form:
30881 * { data:Uint8Array, algorithm:String }
30882 * @throws if no session key could be found or decrypted
30883 * @async
30884 * @static
30885 */
30886async function decryptSessionKeys({ message, decryptionKeys, passwords, date = new Date(), config, ...rest }) {
30887 config = { ...defaultConfig, ...config }; checkConfig(config);
30888 checkMessage(message); decryptionKeys = toArray$1(decryptionKeys); passwords = toArray$1(passwords);
30889 if (rest.privateKeys) throw new Error('The `privateKeys` option has been removed from openpgp.decryptSessionKeys, pass `decryptionKeys` instead');
30890 const unknownOptions = Object.keys(rest); if (unknownOptions.length > 0) throw new Error(`Unknown option: ${unknownOptions.join(', ')}`);
30891
30892 try {
30893 const sessionKeys = await message.decryptSessionKeys(decryptionKeys, passwords, date, config);
30894 return sessionKeys;
30895 } catch (err) {
30896 throw util.wrapError('Error decrypting session keys', err);
30897 }
30898}
30899
30900
30901//////////////////////////
30902// //
30903// Helper functions //
30904// //
30905//////////////////////////
30906
30907
30908/**
30909 * Input validation
30910 * @private
30911 */
30912function checkString(data, name) {
30913 if (!util.isString(data)) {
30914 throw new Error('Parameter [' + (name || 'data') + '] must be of type String');
30915 }
30916}
30917function checkBinary(data, name) {
30918 if (!util.isUint8Array(data)) {
30919 throw new Error('Parameter [' + (name || 'data') + '] must be of type Uint8Array');
30920 }
30921}
30922function checkMessage(message) {
30923 if (!(message instanceof Message)) {
30924 throw new Error('Parameter [message] needs to be of type Message');
30925 }
30926}
30927function checkCleartextOrMessage(message) {
30928 if (!(message instanceof CleartextMessage) && !(message instanceof Message)) {
30929 throw new Error('Parameter [message] needs to be of type Message or CleartextMessage');
30930 }
30931}
30932function checkOutputMessageFormat(format) {
30933 if (format !== 'armored' && format !== 'binary' && format !== 'object') {
30934 throw new Error(`Unsupported format ${format}`);
30935 }
30936}
30937const defaultConfigPropsCount = Object.keys(defaultConfig).length;
30938function checkConfig(config) {
30939 const inputConfigProps = Object.keys(config);
30940 if (inputConfigProps.length !== defaultConfigPropsCount) {
30941 for (const inputProp of inputConfigProps) {
30942 if (defaultConfig[inputProp] === undefined) {
30943 throw new Error(`Unknown config property: ${inputProp}`);
30944 }
30945 }
30946 }
30947}
30948
30949/**
30950 * Normalize parameter to an array if it is not undefined.
30951 * @param {Object} param - the parameter to be normalized
30952 * @returns {Array<Object>|undefined} The resulting array or undefined.
30953 * @private
30954 */
30955function toArray$1(param) {
30956 if (param && !util.isArray(param)) {
30957 param = [param];
30958 }
30959 return param;
30960}
30961
30962/**
30963 * Convert data to or from Stream
30964 * @param {Object} data - the data to convert
30965 * @param {'web'|'ponyfill'|'node'|false} streaming - Whether to return a ReadableStream, and of what type
30966 * @param {'utf8'|'binary'} [encoding] - How to return data in Node Readable streams
30967 * @returns {Promise<Object>} The data in the respective format.
30968 * @async
30969 * @private
30970 */
30971async function convertStream(data, streaming, encoding = 'utf8') {
30972 const streamType = util.isStream(data);
30973 if (streamType === 'array') {
30974 return readToEnd(data);
30975 }
30976 if (streaming === 'node') {
30977 data = webToNode(data);
30978 if (encoding !== 'binary') data.setEncoding(encoding);
30979 return data;
30980 }
30981 if (streaming === 'web' && streamType === 'ponyfill') {
30982 return toNativeReadable(data);
30983 }
30984 return data;
30985}
30986
30987/**
30988 * Link result.data to the message stream for cancellation.
30989 * Also, forward errors in the message to result.data.
30990 * @param {Object} result - the data to convert
30991 * @param {Message} message - message object
30992 * @returns {Object}
30993 * @private
30994 */
30995function linkStreams(result, message) {
30996 result.data = transformPair(message.packets.stream, async (readable, writable) => {
30997 await pipe(result.data, writable, {
30998 preventClose: true
30999 });
31000 const writer = getWriter(writable);
31001 try {
31002 // Forward errors in the message stream to result.data.
31003 await readToEnd(readable, _ => _);
31004 await writer.close();
31005 } catch (e) {
31006 await writer.abort(e);
31007 }
31008 });
31009}
31010
31011/**
31012 * Convert the object to the given format
31013 * @param {Key|Message} object
31014 * @param {'armored'|'binary'|'object'} format
31015 * @param {Object} config - Full configuration
31016 * @returns {String|Uint8Array|Object}
31017 */
31018function formatObject(object, format, config) {
31019 switch (format) {
31020 case 'object':
31021 return object;
31022 case 'armored':
31023 return object.armor(config);
31024 case 'binary':
31025 return object.write();
31026 default:
31027 throw new Error(`Unsupported format ${format}`);
31028 }
31029}
31030
31031/**
31032 * web-streams-polyfill v3.0.3
31033 */
31034/// <reference lib="es2015.symbol" />
31035const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ?
31036 Symbol :
31037 description => `Symbol(${description})`;
31038
31039/// <reference lib="dom" />
31040function noop() {
31041 return undefined;
31042}
31043function getGlobals() {
31044 if (typeof self !== 'undefined') {
31045 return self;
31046 }
31047 else if (typeof window !== 'undefined') {
31048 return window;
31049 }
31050 else if (typeof global !== 'undefined') {
31051 return global;
31052 }
31053 return undefined;
31054}
31055const globals = getGlobals();
31056
31057function typeIsObject(x) {
31058 return (typeof x === 'object' && x !== null) || typeof x === 'function';
31059}
31060const rethrowAssertionErrorRejection = noop;
31061
31062const originalPromise = Promise;
31063const originalPromiseThen = Promise.prototype.then;
31064const originalPromiseResolve = Promise.resolve.bind(originalPromise);
31065const originalPromiseReject = Promise.reject.bind(originalPromise);
31066function newPromise(executor) {
31067 return new originalPromise(executor);
31068}
31069function promiseResolvedWith(value) {
31070 return originalPromiseResolve(value);
31071}
31072function promiseRejectedWith(reason) {
31073 return originalPromiseReject(reason);
31074}
31075function PerformPromiseThen(promise, onFulfilled, onRejected) {
31076 // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an
31077 // approximation.
31078 return originalPromiseThen.call(promise, onFulfilled, onRejected);
31079}
31080function uponPromise(promise, onFulfilled, onRejected) {
31081 PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection);
31082}
31083function uponFulfillment(promise, onFulfilled) {
31084 uponPromise(promise, onFulfilled);
31085}
31086function uponRejection(promise, onRejected) {
31087 uponPromise(promise, undefined, onRejected);
31088}
31089function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) {
31090 return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler);
31091}
31092function setPromiseIsHandledToTrue(promise) {
31093 PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection);
31094}
31095const queueMicrotask = (() => {
31096 const globalQueueMicrotask = globals && globals.queueMicrotask;
31097 if (typeof globalQueueMicrotask === 'function') {
31098 return globalQueueMicrotask;
31099 }
31100 const resolvedPromise = promiseResolvedWith(undefined);
31101 return (fn) => PerformPromiseThen(resolvedPromise, fn);
31102})();
31103function reflectCall(F, V, args) {
31104 if (typeof F !== 'function') {
31105 throw new TypeError('Argument is not a function');
31106 }
31107 return Function.prototype.apply.call(F, V, args);
31108}
31109function promiseCall(F, V, args) {
31110 try {
31111 return promiseResolvedWith(reflectCall(F, V, args));
31112 }
31113 catch (value) {
31114 return promiseRejectedWith(value);
31115 }
31116}
31117
31118// Original from Chromium
31119// https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js
31120const QUEUE_MAX_ARRAY_SIZE = 16384;
31121/**
31122 * Simple queue structure.
31123 *
31124 * Avoids scalability issues with using a packed array directly by using
31125 * multiple arrays in a linked list and keeping the array size bounded.
31126 */
31127class SimpleQueue {
31128 constructor() {
31129 this._cursor = 0;
31130 this._size = 0;
31131 // _front and _back are always defined.
31132 this._front = {
31133 _elements: [],
31134 _next: undefined
31135 };
31136 this._back = this._front;
31137 // The cursor is used to avoid calling Array.shift().
31138 // It contains the index of the front element of the array inside the
31139 // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE).
31140 this._cursor = 0;
31141 // When there is only one node, size === elements.length - cursor.
31142 this._size = 0;
31143 }
31144 get length() {
31145 return this._size;
31146 }
31147 // For exception safety, this method is structured in order:
31148 // 1. Read state
31149 // 2. Calculate required state mutations
31150 // 3. Perform state mutations
31151 push(element) {
31152 const oldBack = this._back;
31153 let newBack = oldBack;
31154 if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) {
31155 newBack = {
31156 _elements: [],
31157 _next: undefined
31158 };
31159 }
31160 // push() is the mutation most likely to throw an exception, so it
31161 // goes first.
31162 oldBack._elements.push(element);
31163 if (newBack !== oldBack) {
31164 this._back = newBack;
31165 oldBack._next = newBack;
31166 }
31167 ++this._size;
31168 }
31169 // Like push(), shift() follows the read -> calculate -> mutate pattern for
31170 // exception safety.
31171 shift() { // must not be called on an empty queue
31172 const oldFront = this._front;
31173 let newFront = oldFront;
31174 const oldCursor = this._cursor;
31175 let newCursor = oldCursor + 1;
31176 const elements = oldFront._elements;
31177 const element = elements[oldCursor];
31178 if (newCursor === QUEUE_MAX_ARRAY_SIZE) {
31179 newFront = oldFront._next;
31180 newCursor = 0;
31181 }
31182 // No mutations before this point.
31183 --this._size;
31184 this._cursor = newCursor;
31185 if (oldFront !== newFront) {
31186 this._front = newFront;
31187 }
31188 // Permit shifted element to be garbage collected.
31189 elements[oldCursor] = undefined;
31190 return element;
31191 }
31192 // The tricky thing about forEach() is that it can be called
31193 // re-entrantly. The queue may be mutated inside the callback. It is easy to
31194 // see that push() within the callback has no negative effects since the end
31195 // of the queue is checked for on every iteration. If shift() is called
31196 // repeatedly within the callback then the next iteration may return an
31197 // element that has been removed. In this case the callback will be called
31198 // with undefined values until we either "catch up" with elements that still
31199 // exist or reach the back of the queue.
31200 forEach(callback) {
31201 let i = this._cursor;
31202 let node = this._front;
31203 let elements = node._elements;
31204 while (i !== elements.length || node._next !== undefined) {
31205 if (i === elements.length) {
31206 node = node._next;
31207 elements = node._elements;
31208 i = 0;
31209 if (elements.length === 0) {
31210 break;
31211 }
31212 }
31213 callback(elements[i]);
31214 ++i;
31215 }
31216 }
31217 // Return the element that would be returned if shift() was called now,
31218 // without modifying the queue.
31219 peek() { // must not be called on an empty queue
31220 const front = this._front;
31221 const cursor = this._cursor;
31222 return front._elements[cursor];
31223 }
31224}
31225
31226function ReadableStreamReaderGenericInitialize(reader, stream) {
31227 reader._ownerReadableStream = stream;
31228 stream._reader = reader;
31229 if (stream._state === 'readable') {
31230 defaultReaderClosedPromiseInitialize(reader);
31231 }
31232 else if (stream._state === 'closed') {
31233 defaultReaderClosedPromiseInitializeAsResolved(reader);
31234 }
31235 else {
31236 defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError);
31237 }
31238}
31239// A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state
31240// check.
31241function ReadableStreamReaderGenericCancel(reader, reason) {
31242 const stream = reader._ownerReadableStream;
31243 return ReadableStreamCancel(stream, reason);
31244}
31245function ReadableStreamReaderGenericRelease(reader) {
31246 if (reader._ownerReadableStream._state === 'readable') {
31247 defaultReaderClosedPromiseReject(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
31248 }
31249 else {
31250 defaultReaderClosedPromiseResetToRejected(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`));
31251 }
31252 reader._ownerReadableStream._reader = undefined;
31253 reader._ownerReadableStream = undefined;
31254}
31255// Helper functions for the readers.
31256function readerLockException(name) {
31257 return new TypeError('Cannot ' + name + ' a stream using a released reader');
31258}
31259// Helper functions for the ReadableStreamDefaultReader.
31260function defaultReaderClosedPromiseInitialize(reader) {
31261 reader._closedPromise = newPromise((resolve, reject) => {
31262 reader._closedPromise_resolve = resolve;
31263 reader._closedPromise_reject = reject;
31264 });
31265}
31266function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) {
31267 defaultReaderClosedPromiseInitialize(reader);
31268 defaultReaderClosedPromiseReject(reader, reason);
31269}
31270function defaultReaderClosedPromiseInitializeAsResolved(reader) {
31271 defaultReaderClosedPromiseInitialize(reader);
31272 defaultReaderClosedPromiseResolve(reader);
31273}
31274function defaultReaderClosedPromiseReject(reader, reason) {
31275 if (reader._closedPromise_reject === undefined) {
31276 return;
31277 }
31278 setPromiseIsHandledToTrue(reader._closedPromise);
31279 reader._closedPromise_reject(reason);
31280 reader._closedPromise_resolve = undefined;
31281 reader._closedPromise_reject = undefined;
31282}
31283function defaultReaderClosedPromiseResetToRejected(reader, reason) {
31284 defaultReaderClosedPromiseInitializeAsRejected(reader, reason);
31285}
31286function defaultReaderClosedPromiseResolve(reader) {
31287 if (reader._closedPromise_resolve === undefined) {
31288 return;
31289 }
31290 reader._closedPromise_resolve(undefined);
31291 reader._closedPromise_resolve = undefined;
31292 reader._closedPromise_reject = undefined;
31293}
31294
31295const AbortSteps = SymbolPolyfill('[[AbortSteps]]');
31296const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]');
31297const CancelSteps = SymbolPolyfill('[[CancelSteps]]');
31298const PullSteps = SymbolPolyfill('[[PullSteps]]');
31299
31300/// <reference lib="es2015.core" />
31301// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill
31302const NumberIsFinite = Number.isFinite || function (x) {
31303 return typeof x === 'number' && isFinite(x);
31304};
31305
31306/// <reference lib="es2015.core" />
31307// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill
31308const MathTrunc = Math.trunc || function (v) {
31309 return v < 0 ? Math.ceil(v) : Math.floor(v);
31310};
31311
31312// https://heycam.github.io/webidl/#idl-dictionaries
31313function isDictionary(x) {
31314 return typeof x === 'object' || typeof x === 'function';
31315}
31316function assertDictionary(obj, context) {
31317 if (obj !== undefined && !isDictionary(obj)) {
31318 throw new TypeError(`${context} is not an object.`);
31319 }
31320}
31321// https://heycam.github.io/webidl/#idl-callback-functions
31322function assertFunction(x, context) {
31323 if (typeof x !== 'function') {
31324 throw new TypeError(`${context} is not a function.`);
31325 }
31326}
31327// https://heycam.github.io/webidl/#idl-object
31328function isObject(x) {
31329 return (typeof x === 'object' && x !== null) || typeof x === 'function';
31330}
31331function assertObject(x, context) {
31332 if (!isObject(x)) {
31333 throw new TypeError(`${context} is not an object.`);
31334 }
31335}
31336function assertRequiredArgument(x, position, context) {
31337 if (x === undefined) {
31338 throw new TypeError(`Parameter ${position} is required in '${context}'.`);
31339 }
31340}
31341function assertRequiredField(x, field, context) {
31342 if (x === undefined) {
31343 throw new TypeError(`${field} is required in '${context}'.`);
31344 }
31345}
31346// https://heycam.github.io/webidl/#idl-unrestricted-double
31347function convertUnrestrictedDouble(value) {
31348 return Number(value);
31349}
31350function censorNegativeZero(x) {
31351 return x === 0 ? 0 : x;
31352}
31353function integerPart(x) {
31354 return censorNegativeZero(MathTrunc(x));
31355}
31356// https://heycam.github.io/webidl/#idl-unsigned-long-long
31357function convertUnsignedLongLongWithEnforceRange(value, context) {
31358 const lowerBound = 0;
31359 const upperBound = Number.MAX_SAFE_INTEGER;
31360 let x = Number(value);
31361 x = censorNegativeZero(x);
31362 if (!NumberIsFinite(x)) {
31363 throw new TypeError(`${context} is not a finite number`);
31364 }
31365 x = integerPart(x);
31366 if (x < lowerBound || x > upperBound) {
31367 throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`);
31368 }
31369 if (!NumberIsFinite(x) || x === 0) {
31370 return 0;
31371 }
31372 // TODO Use BigInt if supported?
31373 // let xBigInt = BigInt(integerPart(x));
31374 // xBigInt = BigInt.asUintN(64, xBigInt);
31375 // return Number(xBigInt);
31376 return x;
31377}
31378
31379function assertReadableStream(x, context) {
31380 if (!IsReadableStream(x)) {
31381 throw new TypeError(`${context} is not a ReadableStream.`);
31382 }
31383}
31384
31385// Abstract operations for the ReadableStream.
31386function AcquireReadableStreamDefaultReader(stream) {
31387 return new ReadableStreamDefaultReader(stream);
31388}
31389// ReadableStream API exposed for controllers.
31390function ReadableStreamAddReadRequest(stream, readRequest) {
31391 stream._reader._readRequests.push(readRequest);
31392}
31393function ReadableStreamFulfillReadRequest(stream, chunk, done) {
31394 const reader = stream._reader;
31395 const readRequest = reader._readRequests.shift();
31396 if (done) {
31397 readRequest._closeSteps();
31398 }
31399 else {
31400 readRequest._chunkSteps(chunk);
31401 }
31402}
31403function ReadableStreamGetNumReadRequests(stream) {
31404 return stream._reader._readRequests.length;
31405}
31406function ReadableStreamHasDefaultReader(stream) {
31407 const reader = stream._reader;
31408 if (reader === undefined) {
31409 return false;
31410 }
31411 if (!IsReadableStreamDefaultReader(reader)) {
31412 return false;
31413 }
31414 return true;
31415}
31416/**
31417 * A default reader vended by a {@link ReadableStream}.
31418 *
31419 * @public
31420 */
31421class ReadableStreamDefaultReader {
31422 constructor(stream) {
31423 assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader');
31424 assertReadableStream(stream, 'First parameter');
31425 if (IsReadableStreamLocked(stream)) {
31426 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
31427 }
31428 ReadableStreamReaderGenericInitialize(this, stream);
31429 this._readRequests = new SimpleQueue();
31430 }
31431 /**
31432 * Returns a promise that will be fulfilled when the stream becomes closed,
31433 * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing.
31434 */
31435 get closed() {
31436 if (!IsReadableStreamDefaultReader(this)) {
31437 return promiseRejectedWith(defaultReaderBrandCheckException('closed'));
31438 }
31439 return this._closedPromise;
31440 }
31441 /**
31442 * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
31443 */
31444 cancel(reason = undefined) {
31445 if (!IsReadableStreamDefaultReader(this)) {
31446 return promiseRejectedWith(defaultReaderBrandCheckException('cancel'));
31447 }
31448 if (this._ownerReadableStream === undefined) {
31449 return promiseRejectedWith(readerLockException('cancel'));
31450 }
31451 return ReadableStreamReaderGenericCancel(this, reason);
31452 }
31453 /**
31454 * Returns a promise that allows access to the next chunk from the stream's internal queue, if available.
31455 *
31456 * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
31457 */
31458 read() {
31459 if (!IsReadableStreamDefaultReader(this)) {
31460 return promiseRejectedWith(defaultReaderBrandCheckException('read'));
31461 }
31462 if (this._ownerReadableStream === undefined) {
31463 return promiseRejectedWith(readerLockException('read from'));
31464 }
31465 let resolvePromise;
31466 let rejectPromise;
31467 const promise = newPromise((resolve, reject) => {
31468 resolvePromise = resolve;
31469 rejectPromise = reject;
31470 });
31471 const readRequest = {
31472 _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
31473 _closeSteps: () => resolvePromise({ value: undefined, done: true }),
31474 _errorSteps: e => rejectPromise(e)
31475 };
31476 ReadableStreamDefaultReaderRead(this, readRequest);
31477 return promise;
31478 }
31479 /**
31480 * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
31481 * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
31482 * from now on; otherwise, the reader will appear closed.
31483 *
31484 * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
31485 * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to
31486 * do so will throw a `TypeError` and leave the reader locked to the stream.
31487 */
31488 releaseLock() {
31489 if (!IsReadableStreamDefaultReader(this)) {
31490 throw defaultReaderBrandCheckException('releaseLock');
31491 }
31492 if (this._ownerReadableStream === undefined) {
31493 return;
31494 }
31495 if (this._readRequests.length > 0) {
31496 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
31497 }
31498 ReadableStreamReaderGenericRelease(this);
31499 }
31500}
31501Object.defineProperties(ReadableStreamDefaultReader.prototype, {
31502 cancel: { enumerable: true },
31503 read: { enumerable: true },
31504 releaseLock: { enumerable: true },
31505 closed: { enumerable: true }
31506});
31507if (typeof SymbolPolyfill.toStringTag === 'symbol') {
31508 Object.defineProperty(ReadableStreamDefaultReader.prototype, SymbolPolyfill.toStringTag, {
31509 value: 'ReadableStreamDefaultReader',
31510 configurable: true
31511 });
31512}
31513// Abstract operations for the readers.
31514function IsReadableStreamDefaultReader(x) {
31515 if (!typeIsObject(x)) {
31516 return false;
31517 }
31518 if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) {
31519 return false;
31520 }
31521 return true;
31522}
31523function ReadableStreamDefaultReaderRead(reader, readRequest) {
31524 const stream = reader._ownerReadableStream;
31525 stream._disturbed = true;
31526 if (stream._state === 'closed') {
31527 readRequest._closeSteps();
31528 }
31529 else if (stream._state === 'errored') {
31530 readRequest._errorSteps(stream._storedError);
31531 }
31532 else {
31533 stream._readableStreamController[PullSteps](readRequest);
31534 }
31535}
31536// Helper functions for the ReadableStreamDefaultReader.
31537function defaultReaderBrandCheckException(name) {
31538 return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`);
31539}
31540
31541/// <reference lib="es2018.asynciterable" />
31542let AsyncIteratorPrototype;
31543if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
31544 // We're running inside a ES2018+ environment, but we're compiling to an older syntax.
31545 // We cannot access %AsyncIteratorPrototype% without non-ES2018 syntax, but we can re-create it.
31546 AsyncIteratorPrototype = {
31547 // 25.1.3.1 %AsyncIteratorPrototype% [ @@asyncIterator ] ( )
31548 // https://tc39.github.io/ecma262/#sec-asynciteratorprototype-asynciterator
31549 [SymbolPolyfill.asyncIterator]() {
31550 return this;
31551 }
31552 };
31553 Object.defineProperty(AsyncIteratorPrototype, SymbolPolyfill.asyncIterator, { enumerable: false });
31554}
31555
31556/// <reference lib="es2018.asynciterable" />
31557class ReadableStreamAsyncIteratorImpl {
31558 constructor(reader, preventCancel) {
31559 this._ongoingPromise = undefined;
31560 this._isFinished = false;
31561 this._reader = reader;
31562 this._preventCancel = preventCancel;
31563 }
31564 next() {
31565 const nextSteps = () => this._nextSteps();
31566 this._ongoingPromise = this._ongoingPromise ?
31567 transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) :
31568 nextSteps();
31569 return this._ongoingPromise;
31570 }
31571 return(value) {
31572 const returnSteps = () => this._returnSteps(value);
31573 return this._ongoingPromise ?
31574 transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) :
31575 returnSteps();
31576 }
31577 _nextSteps() {
31578 if (this._isFinished) {
31579 return Promise.resolve({ value: undefined, done: true });
31580 }
31581 const reader = this._reader;
31582 if (reader._ownerReadableStream === undefined) {
31583 return promiseRejectedWith(readerLockException('iterate'));
31584 }
31585 let resolvePromise;
31586 let rejectPromise;
31587 const promise = newPromise((resolve, reject) => {
31588 resolvePromise = resolve;
31589 rejectPromise = reject;
31590 });
31591 const readRequest = {
31592 _chunkSteps: chunk => {
31593 this._ongoingPromise = undefined;
31594 // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test.
31595 // FIXME Is this a bug in the specification, or in the test?
31596 queueMicrotask(() => resolvePromise({ value: chunk, done: false }));
31597 },
31598 _closeSteps: () => {
31599 this._ongoingPromise = undefined;
31600 this._isFinished = true;
31601 ReadableStreamReaderGenericRelease(reader);
31602 resolvePromise({ value: undefined, done: true });
31603 },
31604 _errorSteps: reason => {
31605 this._ongoingPromise = undefined;
31606 this._isFinished = true;
31607 ReadableStreamReaderGenericRelease(reader);
31608 rejectPromise(reason);
31609 }
31610 };
31611 ReadableStreamDefaultReaderRead(reader, readRequest);
31612 return promise;
31613 }
31614 _returnSteps(value) {
31615 if (this._isFinished) {
31616 return Promise.resolve({ value, done: true });
31617 }
31618 this._isFinished = true;
31619 const reader = this._reader;
31620 if (reader._ownerReadableStream === undefined) {
31621 return promiseRejectedWith(readerLockException('finish iterating'));
31622 }
31623 if (!this._preventCancel) {
31624 const result = ReadableStreamReaderGenericCancel(reader, value);
31625 ReadableStreamReaderGenericRelease(reader);
31626 return transformPromiseWith(result, () => ({ value, done: true }));
31627 }
31628 ReadableStreamReaderGenericRelease(reader);
31629 return promiseResolvedWith({ value, done: true });
31630 }
31631}
31632const ReadableStreamAsyncIteratorPrototype = {
31633 next() {
31634 if (!IsReadableStreamAsyncIterator(this)) {
31635 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next'));
31636 }
31637 return this._asyncIteratorImpl.next();
31638 },
31639 return(value) {
31640 if (!IsReadableStreamAsyncIterator(this)) {
31641 return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return'));
31642 }
31643 return this._asyncIteratorImpl.return(value);
31644 }
31645};
31646if (AsyncIteratorPrototype !== undefined) {
31647 Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype);
31648}
31649// Abstract operations for the ReadableStream.
31650function AcquireReadableStreamAsyncIterator(stream, preventCancel) {
31651 const reader = AcquireReadableStreamDefaultReader(stream);
31652 const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel);
31653 const iterator = Object.create(ReadableStreamAsyncIteratorPrototype);
31654 iterator._asyncIteratorImpl = impl;
31655 return iterator;
31656}
31657function IsReadableStreamAsyncIterator(x) {
31658 if (!typeIsObject(x)) {
31659 return false;
31660 }
31661 if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) {
31662 return false;
31663 }
31664 return true;
31665}
31666// Helper functions for the ReadableStream.
31667function streamAsyncIteratorBrandCheckException(name) {
31668 return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`);
31669}
31670
31671/// <reference lib="es2015.core" />
31672// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill
31673const NumberIsNaN = Number.isNaN || function (x) {
31674 // eslint-disable-next-line no-self-compare
31675 return x !== x;
31676};
31677
31678function IsFiniteNonNegativeNumber(v) {
31679 if (!IsNonNegativeNumber(v)) {
31680 return false;
31681 }
31682 if (v === Infinity) {
31683 return false;
31684 }
31685 return true;
31686}
31687function IsNonNegativeNumber(v) {
31688 if (typeof v !== 'number') {
31689 return false;
31690 }
31691 if (NumberIsNaN(v)) {
31692 return false;
31693 }
31694 if (v < 0) {
31695 return false;
31696 }
31697 return true;
31698}
31699
31700function DequeueValue(container) {
31701 const pair = container._queue.shift();
31702 container._queueTotalSize -= pair.size;
31703 if (container._queueTotalSize < 0) {
31704 container._queueTotalSize = 0;
31705 }
31706 return pair.value;
31707}
31708function EnqueueValueWithSize(container, value, size) {
31709 size = Number(size);
31710 if (!IsFiniteNonNegativeNumber(size)) {
31711 throw new RangeError('Size must be a finite, non-NaN, non-negative number.');
31712 }
31713 container._queue.push({ value, size });
31714 container._queueTotalSize += size;
31715}
31716function PeekQueueValue(container) {
31717 const pair = container._queue.peek();
31718 return pair.value;
31719}
31720function ResetQueue(container) {
31721 container._queue = new SimpleQueue();
31722 container._queueTotalSize = 0;
31723}
31724
31725function CreateArrayFromList(elements) {
31726 // We use arrays to represent lists, so this is basically a no-op.
31727 // Do a slice though just in case we happen to depend on the unique-ness.
31728 return elements.slice();
31729}
31730function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) {
31731 new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset);
31732}
31733// Not implemented correctly
31734function TransferArrayBuffer(O) {
31735 return O;
31736}
31737// Not implemented correctly
31738function IsDetachedBuffer(O) {
31739 return false;
31740}
31741
31742/**
31743 * A pull-into request in a {@link ReadableByteStreamController}.
31744 *
31745 * @public
31746 */
31747class ReadableStreamBYOBRequest {
31748 constructor() {
31749 throw new TypeError('Illegal constructor');
31750 }
31751 /**
31752 * Returns the view for writing in to, or `null` if the BYOB request has already been responded to.
31753 */
31754 get view() {
31755 if (!IsReadableStreamBYOBRequest(this)) {
31756 throw byobRequestBrandCheckException('view');
31757 }
31758 return this._view;
31759 }
31760 respond(bytesWritten) {
31761 if (!IsReadableStreamBYOBRequest(this)) {
31762 throw byobRequestBrandCheckException('respond');
31763 }
31764 assertRequiredArgument(bytesWritten, 1, 'respond');
31765 bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter');
31766 if (this._associatedReadableByteStreamController === undefined) {
31767 throw new TypeError('This BYOB request has been invalidated');
31768 }
31769 if (IsDetachedBuffer(this._view.buffer)) ;
31770 ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten);
31771 }
31772 respondWithNewView(view) {
31773 if (!IsReadableStreamBYOBRequest(this)) {
31774 throw byobRequestBrandCheckException('respondWithNewView');
31775 }
31776 assertRequiredArgument(view, 1, 'respondWithNewView');
31777 if (!ArrayBuffer.isView(view)) {
31778 throw new TypeError('You can only respond with array buffer views');
31779 }
31780 if (view.byteLength === 0) {
31781 throw new TypeError('chunk must have non-zero byteLength');
31782 }
31783 if (view.buffer.byteLength === 0) {
31784 throw new TypeError(`chunk's buffer must have non-zero byteLength`);
31785 }
31786 if (this._associatedReadableByteStreamController === undefined) {
31787 throw new TypeError('This BYOB request has been invalidated');
31788 }
31789 ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view);
31790 }
31791}
31792Object.defineProperties(ReadableStreamBYOBRequest.prototype, {
31793 respond: { enumerable: true },
31794 respondWithNewView: { enumerable: true },
31795 view: { enumerable: true }
31796});
31797if (typeof SymbolPolyfill.toStringTag === 'symbol') {
31798 Object.defineProperty(ReadableStreamBYOBRequest.prototype, SymbolPolyfill.toStringTag, {
31799 value: 'ReadableStreamBYOBRequest',
31800 configurable: true
31801 });
31802}
31803/**
31804 * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue.
31805 *
31806 * @public
31807 */
31808class ReadableByteStreamController {
31809 constructor() {
31810 throw new TypeError('Illegal constructor');
31811 }
31812 /**
31813 * Returns the current BYOB pull request, or `null` if there isn't one.
31814 */
31815 get byobRequest() {
31816 if (!IsReadableByteStreamController(this)) {
31817 throw byteStreamControllerBrandCheckException('byobRequest');
31818 }
31819 if (this._byobRequest === null && this._pendingPullIntos.length > 0) {
31820 const firstDescriptor = this._pendingPullIntos.peek();
31821 const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled);
31822 const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype);
31823 SetUpReadableStreamBYOBRequest(byobRequest, this, view);
31824 this._byobRequest = byobRequest;
31825 }
31826 return this._byobRequest;
31827 }
31828 /**
31829 * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
31830 * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure.
31831 */
31832 get desiredSize() {
31833 if (!IsReadableByteStreamController(this)) {
31834 throw byteStreamControllerBrandCheckException('desiredSize');
31835 }
31836 return ReadableByteStreamControllerGetDesiredSize(this);
31837 }
31838 /**
31839 * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
31840 * the stream, but once those are read, the stream will become closed.
31841 */
31842 close() {
31843 if (!IsReadableByteStreamController(this)) {
31844 throw byteStreamControllerBrandCheckException('close');
31845 }
31846 if (this._closeRequested) {
31847 throw new TypeError('The stream has already been closed; do not close it again!');
31848 }
31849 const state = this._controlledReadableByteStream._state;
31850 if (state !== 'readable') {
31851 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`);
31852 }
31853 ReadableByteStreamControllerClose(this);
31854 }
31855 enqueue(chunk) {
31856 if (!IsReadableByteStreamController(this)) {
31857 throw byteStreamControllerBrandCheckException('enqueue');
31858 }
31859 assertRequiredArgument(chunk, 1, 'enqueue');
31860 if (!ArrayBuffer.isView(chunk)) {
31861 throw new TypeError('chunk must be an array buffer view');
31862 }
31863 if (chunk.byteLength === 0) {
31864 throw new TypeError('chunk must have non-zero byteLength');
31865 }
31866 if (chunk.buffer.byteLength === 0) {
31867 throw new TypeError(`chunk's buffer must have non-zero byteLength`);
31868 }
31869 if (this._closeRequested) {
31870 throw new TypeError('stream is closed or draining');
31871 }
31872 const state = this._controlledReadableByteStream._state;
31873 if (state !== 'readable') {
31874 throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`);
31875 }
31876 ReadableByteStreamControllerEnqueue(this, chunk);
31877 }
31878 /**
31879 * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
31880 */
31881 error(e = undefined) {
31882 if (!IsReadableByteStreamController(this)) {
31883 throw byteStreamControllerBrandCheckException('error');
31884 }
31885 ReadableByteStreamControllerError(this, e);
31886 }
31887 /** @internal */
31888 [CancelSteps](reason) {
31889 if (this._pendingPullIntos.length > 0) {
31890 const firstDescriptor = this._pendingPullIntos.peek();
31891 firstDescriptor.bytesFilled = 0;
31892 }
31893 ResetQueue(this);
31894 const result = this._cancelAlgorithm(reason);
31895 ReadableByteStreamControllerClearAlgorithms(this);
31896 return result;
31897 }
31898 /** @internal */
31899 [PullSteps](readRequest) {
31900 const stream = this._controlledReadableByteStream;
31901 if (this._queueTotalSize > 0) {
31902 const entry = this._queue.shift();
31903 this._queueTotalSize -= entry.byteLength;
31904 ReadableByteStreamControllerHandleQueueDrain(this);
31905 const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength);
31906 readRequest._chunkSteps(view);
31907 return;
31908 }
31909 const autoAllocateChunkSize = this._autoAllocateChunkSize;
31910 if (autoAllocateChunkSize !== undefined) {
31911 let buffer;
31912 try {
31913 buffer = new ArrayBuffer(autoAllocateChunkSize);
31914 }
31915 catch (bufferE) {
31916 readRequest._errorSteps(bufferE);
31917 return;
31918 }
31919 const pullIntoDescriptor = {
31920 buffer,
31921 byteOffset: 0,
31922 byteLength: autoAllocateChunkSize,
31923 bytesFilled: 0,
31924 elementSize: 1,
31925 viewConstructor: Uint8Array,
31926 readerType: 'default'
31927 };
31928 this._pendingPullIntos.push(pullIntoDescriptor);
31929 }
31930 ReadableStreamAddReadRequest(stream, readRequest);
31931 ReadableByteStreamControllerCallPullIfNeeded(this);
31932 }
31933}
31934Object.defineProperties(ReadableByteStreamController.prototype, {
31935 close: { enumerable: true },
31936 enqueue: { enumerable: true },
31937 error: { enumerable: true },
31938 byobRequest: { enumerable: true },
31939 desiredSize: { enumerable: true }
31940});
31941if (typeof SymbolPolyfill.toStringTag === 'symbol') {
31942 Object.defineProperty(ReadableByteStreamController.prototype, SymbolPolyfill.toStringTag, {
31943 value: 'ReadableByteStreamController',
31944 configurable: true
31945 });
31946}
31947// Abstract operations for the ReadableByteStreamController.
31948function IsReadableByteStreamController(x) {
31949 if (!typeIsObject(x)) {
31950 return false;
31951 }
31952 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) {
31953 return false;
31954 }
31955 return true;
31956}
31957function IsReadableStreamBYOBRequest(x) {
31958 if (!typeIsObject(x)) {
31959 return false;
31960 }
31961 if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) {
31962 return false;
31963 }
31964 return true;
31965}
31966function ReadableByteStreamControllerCallPullIfNeeded(controller) {
31967 const shouldPull = ReadableByteStreamControllerShouldCallPull(controller);
31968 if (!shouldPull) {
31969 return;
31970 }
31971 if (controller._pulling) {
31972 controller._pullAgain = true;
31973 return;
31974 }
31975 controller._pulling = true;
31976 // TODO: Test controller argument
31977 const pullPromise = controller._pullAlgorithm();
31978 uponPromise(pullPromise, () => {
31979 controller._pulling = false;
31980 if (controller._pullAgain) {
31981 controller._pullAgain = false;
31982 ReadableByteStreamControllerCallPullIfNeeded(controller);
31983 }
31984 }, e => {
31985 ReadableByteStreamControllerError(controller, e);
31986 });
31987}
31988function ReadableByteStreamControllerClearPendingPullIntos(controller) {
31989 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
31990 controller._pendingPullIntos = new SimpleQueue();
31991}
31992function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) {
31993 let done = false;
31994 if (stream._state === 'closed') {
31995 done = true;
31996 }
31997 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
31998 if (pullIntoDescriptor.readerType === 'default') {
31999 ReadableStreamFulfillReadRequest(stream, filledView, done);
32000 }
32001 else {
32002 ReadableStreamFulfillReadIntoRequest(stream, filledView, done);
32003 }
32004}
32005function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) {
32006 const bytesFilled = pullIntoDescriptor.bytesFilled;
32007 const elementSize = pullIntoDescriptor.elementSize;
32008 return new pullIntoDescriptor.viewConstructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize);
32009}
32010function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) {
32011 controller._queue.push({ buffer, byteOffset, byteLength });
32012 controller._queueTotalSize += byteLength;
32013}
32014function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) {
32015 const elementSize = pullIntoDescriptor.elementSize;
32016 const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize;
32017 const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled);
32018 const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy;
32019 const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize;
32020 let totalBytesToCopyRemaining = maxBytesToCopy;
32021 let ready = false;
32022 if (maxAlignedBytes > currentAlignedBytes) {
32023 totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled;
32024 ready = true;
32025 }
32026 const queue = controller._queue;
32027 while (totalBytesToCopyRemaining > 0) {
32028 const headOfQueue = queue.peek();
32029 const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength);
32030 const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
32031 CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy);
32032 if (headOfQueue.byteLength === bytesToCopy) {
32033 queue.shift();
32034 }
32035 else {
32036 headOfQueue.byteOffset += bytesToCopy;
32037 headOfQueue.byteLength -= bytesToCopy;
32038 }
32039 controller._queueTotalSize -= bytesToCopy;
32040 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor);
32041 totalBytesToCopyRemaining -= bytesToCopy;
32042 }
32043 return ready;
32044}
32045function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) {
32046 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
32047 pullIntoDescriptor.bytesFilled += size;
32048}
32049function ReadableByteStreamControllerHandleQueueDrain(controller) {
32050 if (controller._queueTotalSize === 0 && controller._closeRequested) {
32051 ReadableByteStreamControllerClearAlgorithms(controller);
32052 ReadableStreamClose(controller._controlledReadableByteStream);
32053 }
32054 else {
32055 ReadableByteStreamControllerCallPullIfNeeded(controller);
32056 }
32057}
32058function ReadableByteStreamControllerInvalidateBYOBRequest(controller) {
32059 if (controller._byobRequest === null) {
32060 return;
32061 }
32062 controller._byobRequest._associatedReadableByteStreamController = undefined;
32063 controller._byobRequest._view = null;
32064 controller._byobRequest = null;
32065}
32066function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) {
32067 while (controller._pendingPullIntos.length > 0) {
32068 if (controller._queueTotalSize === 0) {
32069 return;
32070 }
32071 const pullIntoDescriptor = controller._pendingPullIntos.peek();
32072 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
32073 ReadableByteStreamControllerShiftPendingPullInto(controller);
32074 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
32075 }
32076 }
32077}
32078function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest) {
32079 const stream = controller._controlledReadableByteStream;
32080 let elementSize = 1;
32081 if (view.constructor !== DataView) {
32082 elementSize = view.constructor.BYTES_PER_ELEMENT;
32083 }
32084 const ctor = view.constructor;
32085 const buffer = TransferArrayBuffer(view.buffer);
32086 const pullIntoDescriptor = {
32087 buffer,
32088 byteOffset: view.byteOffset,
32089 byteLength: view.byteLength,
32090 bytesFilled: 0,
32091 elementSize,
32092 viewConstructor: ctor,
32093 readerType: 'byob'
32094 };
32095 if (controller._pendingPullIntos.length > 0) {
32096 controller._pendingPullIntos.push(pullIntoDescriptor);
32097 // No ReadableByteStreamControllerCallPullIfNeeded() call since:
32098 // - No change happens on desiredSize
32099 // - The source has already been notified of that there's at least 1 pending read(view)
32100 ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
32101 return;
32102 }
32103 if (stream._state === 'closed') {
32104 const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0);
32105 readIntoRequest._closeSteps(emptyView);
32106 return;
32107 }
32108 if (controller._queueTotalSize > 0) {
32109 if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) {
32110 const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor);
32111 ReadableByteStreamControllerHandleQueueDrain(controller);
32112 readIntoRequest._chunkSteps(filledView);
32113 return;
32114 }
32115 if (controller._closeRequested) {
32116 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
32117 ReadableByteStreamControllerError(controller, e);
32118 readIntoRequest._errorSteps(e);
32119 return;
32120 }
32121 }
32122 controller._pendingPullIntos.push(pullIntoDescriptor);
32123 ReadableStreamAddReadIntoRequest(stream, readIntoRequest);
32124 ReadableByteStreamControllerCallPullIfNeeded(controller);
32125}
32126function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) {
32127 firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer);
32128 const stream = controller._controlledReadableByteStream;
32129 if (ReadableStreamHasBYOBReader(stream)) {
32130 while (ReadableStreamGetNumReadIntoRequests(stream) > 0) {
32131 const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller);
32132 ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor);
32133 }
32134 }
32135}
32136function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) {
32137 if (pullIntoDescriptor.bytesFilled + bytesWritten > pullIntoDescriptor.byteLength) {
32138 throw new RangeError('bytesWritten out of range');
32139 }
32140 ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor);
32141 if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) {
32142 // TODO: Figure out whether we should detach the buffer or not here.
32143 return;
32144 }
32145 ReadableByteStreamControllerShiftPendingPullInto(controller);
32146 const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize;
32147 if (remainderSize > 0) {
32148 const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled;
32149 const remainder = pullIntoDescriptor.buffer.slice(end - remainderSize, end);
32150 ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength);
32151 }
32152 pullIntoDescriptor.buffer = TransferArrayBuffer(pullIntoDescriptor.buffer);
32153 pullIntoDescriptor.bytesFilled -= remainderSize;
32154 ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor);
32155 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
32156}
32157function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) {
32158 const firstDescriptor = controller._pendingPullIntos.peek();
32159 const state = controller._controlledReadableByteStream._state;
32160 if (state === 'closed') {
32161 if (bytesWritten !== 0) {
32162 throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream');
32163 }
32164 ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor);
32165 }
32166 else {
32167 ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor);
32168 }
32169 ReadableByteStreamControllerCallPullIfNeeded(controller);
32170}
32171function ReadableByteStreamControllerShiftPendingPullInto(controller) {
32172 const descriptor = controller._pendingPullIntos.shift();
32173 ReadableByteStreamControllerInvalidateBYOBRequest(controller);
32174 return descriptor;
32175}
32176function ReadableByteStreamControllerShouldCallPull(controller) {
32177 const stream = controller._controlledReadableByteStream;
32178 if (stream._state !== 'readable') {
32179 return false;
32180 }
32181 if (controller._closeRequested) {
32182 return false;
32183 }
32184 if (!controller._started) {
32185 return false;
32186 }
32187 if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
32188 return true;
32189 }
32190 if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) {
32191 return true;
32192 }
32193 const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller);
32194 if (desiredSize > 0) {
32195 return true;
32196 }
32197 return false;
32198}
32199function ReadableByteStreamControllerClearAlgorithms(controller) {
32200 controller._pullAlgorithm = undefined;
32201 controller._cancelAlgorithm = undefined;
32202}
32203// A client of ReadableByteStreamController may use these functions directly to bypass state check.
32204function ReadableByteStreamControllerClose(controller) {
32205 const stream = controller._controlledReadableByteStream;
32206 if (controller._closeRequested || stream._state !== 'readable') {
32207 return;
32208 }
32209 if (controller._queueTotalSize > 0) {
32210 controller._closeRequested = true;
32211 return;
32212 }
32213 if (controller._pendingPullIntos.length > 0) {
32214 const firstPendingPullInto = controller._pendingPullIntos.peek();
32215 if (firstPendingPullInto.bytesFilled > 0) {
32216 const e = new TypeError('Insufficient bytes to fill elements in the given buffer');
32217 ReadableByteStreamControllerError(controller, e);
32218 throw e;
32219 }
32220 }
32221 ReadableByteStreamControllerClearAlgorithms(controller);
32222 ReadableStreamClose(stream);
32223}
32224function ReadableByteStreamControllerEnqueue(controller, chunk) {
32225 const stream = controller._controlledReadableByteStream;
32226 if (controller._closeRequested || stream._state !== 'readable') {
32227 return;
32228 }
32229 const buffer = chunk.buffer;
32230 const byteOffset = chunk.byteOffset;
32231 const byteLength = chunk.byteLength;
32232 const transferredBuffer = TransferArrayBuffer(buffer);
32233 if (ReadableStreamHasDefaultReader(stream)) {
32234 if (ReadableStreamGetNumReadRequests(stream) === 0) {
32235 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
32236 }
32237 else {
32238 const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
32239 ReadableStreamFulfillReadRequest(stream, transferredView, false);
32240 }
32241 }
32242 else if (ReadableStreamHasBYOBReader(stream)) {
32243 // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully.
32244 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
32245 ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller);
32246 }
32247 else {
32248 ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
32249 }
32250 ReadableByteStreamControllerCallPullIfNeeded(controller);
32251}
32252function ReadableByteStreamControllerError(controller, e) {
32253 const stream = controller._controlledReadableByteStream;
32254 if (stream._state !== 'readable') {
32255 return;
32256 }
32257 ReadableByteStreamControllerClearPendingPullIntos(controller);
32258 ResetQueue(controller);
32259 ReadableByteStreamControllerClearAlgorithms(controller);
32260 ReadableStreamError(stream, e);
32261}
32262function ReadableByteStreamControllerGetDesiredSize(controller) {
32263 const state = controller._controlledReadableByteStream._state;
32264 if (state === 'errored') {
32265 return null;
32266 }
32267 if (state === 'closed') {
32268 return 0;
32269 }
32270 return controller._strategyHWM - controller._queueTotalSize;
32271}
32272function ReadableByteStreamControllerRespond(controller, bytesWritten) {
32273 bytesWritten = Number(bytesWritten);
32274 if (!IsFiniteNonNegativeNumber(bytesWritten)) {
32275 throw new RangeError('bytesWritten must be a finite');
32276 }
32277 ReadableByteStreamControllerRespondInternal(controller, bytesWritten);
32278}
32279function ReadableByteStreamControllerRespondWithNewView(controller, view) {
32280 const firstDescriptor = controller._pendingPullIntos.peek();
32281 if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) {
32282 throw new RangeError('The region specified by view does not match byobRequest');
32283 }
32284 if (firstDescriptor.byteLength !== view.byteLength) {
32285 throw new RangeError('The buffer of view has different capacity than byobRequest');
32286 }
32287 firstDescriptor.buffer = view.buffer;
32288 ReadableByteStreamControllerRespondInternal(controller, view.byteLength);
32289}
32290function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) {
32291 controller._controlledReadableByteStream = stream;
32292 controller._pullAgain = false;
32293 controller._pulling = false;
32294 controller._byobRequest = null;
32295 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
32296 controller._queue = controller._queueTotalSize = undefined;
32297 ResetQueue(controller);
32298 controller._closeRequested = false;
32299 controller._started = false;
32300 controller._strategyHWM = highWaterMark;
32301 controller._pullAlgorithm = pullAlgorithm;
32302 controller._cancelAlgorithm = cancelAlgorithm;
32303 controller._autoAllocateChunkSize = autoAllocateChunkSize;
32304 controller._pendingPullIntos = new SimpleQueue();
32305 stream._readableStreamController = controller;
32306 const startResult = startAlgorithm();
32307 uponPromise(promiseResolvedWith(startResult), () => {
32308 controller._started = true;
32309 ReadableByteStreamControllerCallPullIfNeeded(controller);
32310 }, r => {
32311 ReadableByteStreamControllerError(controller, r);
32312 });
32313}
32314function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) {
32315 const controller = Object.create(ReadableByteStreamController.prototype);
32316 let startAlgorithm = () => undefined;
32317 let pullAlgorithm = () => promiseResolvedWith(undefined);
32318 let cancelAlgorithm = () => promiseResolvedWith(undefined);
32319 if (underlyingByteSource.start !== undefined) {
32320 startAlgorithm = () => underlyingByteSource.start(controller);
32321 }
32322 if (underlyingByteSource.pull !== undefined) {
32323 pullAlgorithm = () => underlyingByteSource.pull(controller);
32324 }
32325 if (underlyingByteSource.cancel !== undefined) {
32326 cancelAlgorithm = reason => underlyingByteSource.cancel(reason);
32327 }
32328 const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
32329 if (autoAllocateChunkSize === 0) {
32330 throw new TypeError('autoAllocateChunkSize must be greater than 0');
32331 }
32332 SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize);
32333}
32334function SetUpReadableStreamBYOBRequest(request, controller, view) {
32335 request._associatedReadableByteStreamController = controller;
32336 request._view = view;
32337}
32338// Helper functions for the ReadableStreamBYOBRequest.
32339function byobRequestBrandCheckException(name) {
32340 return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`);
32341}
32342// Helper functions for the ReadableByteStreamController.
32343function byteStreamControllerBrandCheckException(name) {
32344 return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`);
32345}
32346
32347// Abstract operations for the ReadableStream.
32348function AcquireReadableStreamBYOBReader(stream) {
32349 return new ReadableStreamBYOBReader(stream);
32350}
32351// ReadableStream API exposed for controllers.
32352function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) {
32353 stream._reader._readIntoRequests.push(readIntoRequest);
32354}
32355function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) {
32356 const reader = stream._reader;
32357 const readIntoRequest = reader._readIntoRequests.shift();
32358 if (done) {
32359 readIntoRequest._closeSteps(chunk);
32360 }
32361 else {
32362 readIntoRequest._chunkSteps(chunk);
32363 }
32364}
32365function ReadableStreamGetNumReadIntoRequests(stream) {
32366 return stream._reader._readIntoRequests.length;
32367}
32368function ReadableStreamHasBYOBReader(stream) {
32369 const reader = stream._reader;
32370 if (reader === undefined) {
32371 return false;
32372 }
32373 if (!IsReadableStreamBYOBReader(reader)) {
32374 return false;
32375 }
32376 return true;
32377}
32378/**
32379 * A BYOB reader vended by a {@link ReadableStream}.
32380 *
32381 * @public
32382 */
32383class ReadableStreamBYOBReader {
32384 constructor(stream) {
32385 assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader');
32386 assertReadableStream(stream, 'First parameter');
32387 if (IsReadableStreamLocked(stream)) {
32388 throw new TypeError('This stream has already been locked for exclusive reading by another reader');
32389 }
32390 if (!IsReadableByteStreamController(stream._readableStreamController)) {
32391 throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' +
32392 'source');
32393 }
32394 ReadableStreamReaderGenericInitialize(this, stream);
32395 this._readIntoRequests = new SimpleQueue();
32396 }
32397 /**
32398 * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
32399 * the reader's lock is released before the stream finishes closing.
32400 */
32401 get closed() {
32402 if (!IsReadableStreamBYOBReader(this)) {
32403 return promiseRejectedWith(byobReaderBrandCheckException('closed'));
32404 }
32405 return this._closedPromise;
32406 }
32407 /**
32408 * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}.
32409 */
32410 cancel(reason = undefined) {
32411 if (!IsReadableStreamBYOBReader(this)) {
32412 return promiseRejectedWith(byobReaderBrandCheckException('cancel'));
32413 }
32414 if (this._ownerReadableStream === undefined) {
32415 return promiseRejectedWith(readerLockException('cancel'));
32416 }
32417 return ReadableStreamReaderGenericCancel(this, reason);
32418 }
32419 /**
32420 * Attempts to reads bytes into view, and returns a promise resolved with the result.
32421 *
32422 * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source.
32423 */
32424 read(view) {
32425 if (!IsReadableStreamBYOBReader(this)) {
32426 return promiseRejectedWith(byobReaderBrandCheckException('read'));
32427 }
32428 if (!ArrayBuffer.isView(view)) {
32429 return promiseRejectedWith(new TypeError('view must be an array buffer view'));
32430 }
32431 if (view.byteLength === 0) {
32432 return promiseRejectedWith(new TypeError('view must have non-zero byteLength'));
32433 }
32434 if (view.buffer.byteLength === 0) {
32435 return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`));
32436 }
32437 if (this._ownerReadableStream === undefined) {
32438 return promiseRejectedWith(readerLockException('read from'));
32439 }
32440 let resolvePromise;
32441 let rejectPromise;
32442 const promise = newPromise((resolve, reject) => {
32443 resolvePromise = resolve;
32444 rejectPromise = reject;
32445 });
32446 const readIntoRequest = {
32447 _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }),
32448 _closeSteps: chunk => resolvePromise({ value: chunk, done: true }),
32449 _errorSteps: e => rejectPromise(e)
32450 };
32451 ReadableStreamBYOBReaderRead(this, view, readIntoRequest);
32452 return promise;
32453 }
32454 /**
32455 * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active.
32456 * If the associated stream is errored when the lock is released, the reader will appear errored in the same way
32457 * from now on; otherwise, the reader will appear closed.
32458 *
32459 * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by
32460 * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to
32461 * do so will throw a `TypeError` and leave the reader locked to the stream.
32462 */
32463 releaseLock() {
32464 if (!IsReadableStreamBYOBReader(this)) {
32465 throw byobReaderBrandCheckException('releaseLock');
32466 }
32467 if (this._ownerReadableStream === undefined) {
32468 return;
32469 }
32470 if (this._readIntoRequests.length > 0) {
32471 throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled');
32472 }
32473 ReadableStreamReaderGenericRelease(this);
32474 }
32475}
32476Object.defineProperties(ReadableStreamBYOBReader.prototype, {
32477 cancel: { enumerable: true },
32478 read: { enumerable: true },
32479 releaseLock: { enumerable: true },
32480 closed: { enumerable: true }
32481});
32482if (typeof SymbolPolyfill.toStringTag === 'symbol') {
32483 Object.defineProperty(ReadableStreamBYOBReader.prototype, SymbolPolyfill.toStringTag, {
32484 value: 'ReadableStreamBYOBReader',
32485 configurable: true
32486 });
32487}
32488// Abstract operations for the readers.
32489function IsReadableStreamBYOBReader(x) {
32490 if (!typeIsObject(x)) {
32491 return false;
32492 }
32493 if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) {
32494 return false;
32495 }
32496 return true;
32497}
32498function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) {
32499 const stream = reader._ownerReadableStream;
32500 stream._disturbed = true;
32501 if (stream._state === 'errored') {
32502 readIntoRequest._errorSteps(stream._storedError);
32503 }
32504 else {
32505 ReadableByteStreamControllerPullInto(stream._readableStreamController, view, readIntoRequest);
32506 }
32507}
32508// Helper functions for the ReadableStreamBYOBReader.
32509function byobReaderBrandCheckException(name) {
32510 return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`);
32511}
32512
32513function ExtractHighWaterMark(strategy, defaultHWM) {
32514 const { highWaterMark } = strategy;
32515 if (highWaterMark === undefined) {
32516 return defaultHWM;
32517 }
32518 if (NumberIsNaN(highWaterMark) || highWaterMark < 0) {
32519 throw new RangeError('Invalid highWaterMark');
32520 }
32521 return highWaterMark;
32522}
32523function ExtractSizeAlgorithm(strategy) {
32524 const { size } = strategy;
32525 if (!size) {
32526 return () => 1;
32527 }
32528 return size;
32529}
32530
32531function convertQueuingStrategy(init, context) {
32532 assertDictionary(init, context);
32533 const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
32534 const size = init === null || init === void 0 ? void 0 : init.size;
32535 return {
32536 highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark),
32537 size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`)
32538 };
32539}
32540function convertQueuingStrategySize(fn, context) {
32541 assertFunction(fn, context);
32542 return chunk => convertUnrestrictedDouble(fn(chunk));
32543}
32544
32545function convertUnderlyingSink(original, context) {
32546 assertDictionary(original, context);
32547 const abort = original === null || original === void 0 ? void 0 : original.abort;
32548 const close = original === null || original === void 0 ? void 0 : original.close;
32549 const start = original === null || original === void 0 ? void 0 : original.start;
32550 const type = original === null || original === void 0 ? void 0 : original.type;
32551 const write = original === null || original === void 0 ? void 0 : original.write;
32552 return {
32553 abort: abort === undefined ?
32554 undefined :
32555 convertUnderlyingSinkAbortCallback(abort, original, `${context} has member 'abort' that`),
32556 close: close === undefined ?
32557 undefined :
32558 convertUnderlyingSinkCloseCallback(close, original, `${context} has member 'close' that`),
32559 start: start === undefined ?
32560 undefined :
32561 convertUnderlyingSinkStartCallback(start, original, `${context} has member 'start' that`),
32562 write: write === undefined ?
32563 undefined :
32564 convertUnderlyingSinkWriteCallback(write, original, `${context} has member 'write' that`),
32565 type
32566 };
32567}
32568function convertUnderlyingSinkAbortCallback(fn, original, context) {
32569 assertFunction(fn, context);
32570 return (reason) => promiseCall(fn, original, [reason]);
32571}
32572function convertUnderlyingSinkCloseCallback(fn, original, context) {
32573 assertFunction(fn, context);
32574 return () => promiseCall(fn, original, []);
32575}
32576function convertUnderlyingSinkStartCallback(fn, original, context) {
32577 assertFunction(fn, context);
32578 return (controller) => reflectCall(fn, original, [controller]);
32579}
32580function convertUnderlyingSinkWriteCallback(fn, original, context) {
32581 assertFunction(fn, context);
32582 return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
32583}
32584
32585function assertWritableStream(x, context) {
32586 if (!IsWritableStream(x)) {
32587 throw new TypeError(`${context} is not a WritableStream.`);
32588 }
32589}
32590
32591/**
32592 * A writable stream represents a destination for data, into which you can write.
32593 *
32594 * @public
32595 */
32596class WritableStream$1 {
32597 constructor(rawUnderlyingSink = {}, rawStrategy = {}) {
32598 if (rawUnderlyingSink === undefined) {
32599 rawUnderlyingSink = null;
32600 }
32601 else {
32602 assertObject(rawUnderlyingSink, 'First parameter');
32603 }
32604 const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
32605 const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter');
32606 InitializeWritableStream(this);
32607 const type = underlyingSink.type;
32608 if (type !== undefined) {
32609 throw new RangeError('Invalid type is specified');
32610 }
32611 const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
32612 const highWaterMark = ExtractHighWaterMark(strategy, 1);
32613 SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm);
32614 }
32615 /**
32616 * Returns whether or not the writable stream is locked to a writer.
32617 */
32618 get locked() {
32619 if (!IsWritableStream(this)) {
32620 throw streamBrandCheckException$2('locked');
32621 }
32622 return IsWritableStreamLocked(this);
32623 }
32624 /**
32625 * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be
32626 * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort
32627 * mechanism of the underlying sink.
32628 *
32629 * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled
32630 * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel
32631 * the stream) if the stream is currently locked.
32632 */
32633 abort(reason = undefined) {
32634 if (!IsWritableStream(this)) {
32635 return promiseRejectedWith(streamBrandCheckException$2('abort'));
32636 }
32637 if (IsWritableStreamLocked(this)) {
32638 return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer'));
32639 }
32640 return WritableStreamAbort(this, reason);
32641 }
32642 /**
32643 * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its
32644 * close behavior. During this time any further attempts to write will fail (without erroring the stream).
32645 *
32646 * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream
32647 * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with
32648 * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked.
32649 */
32650 close() {
32651 if (!IsWritableStream(this)) {
32652 return promiseRejectedWith(streamBrandCheckException$2('close'));
32653 }
32654 if (IsWritableStreamLocked(this)) {
32655 return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer'));
32656 }
32657 if (WritableStreamCloseQueuedOrInFlight(this)) {
32658 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
32659 }
32660 return WritableStreamClose(this);
32661 }
32662 /**
32663 * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream
32664 * is locked, no other writer can be acquired until this one is released.
32665 *
32666 * This functionality is especially useful for creating abstractions that desire the ability to write to a stream
32667 * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at
32668 * the same time, which would cause the resulting written data to be unpredictable and probably useless.
32669 */
32670 getWriter() {
32671 if (!IsWritableStream(this)) {
32672 throw streamBrandCheckException$2('getWriter');
32673 }
32674 return AcquireWritableStreamDefaultWriter(this);
32675 }
32676}
32677Object.defineProperties(WritableStream$1.prototype, {
32678 abort: { enumerable: true },
32679 close: { enumerable: true },
32680 getWriter: { enumerable: true },
32681 locked: { enumerable: true }
32682});
32683if (typeof SymbolPolyfill.toStringTag === 'symbol') {
32684 Object.defineProperty(WritableStream$1.prototype, SymbolPolyfill.toStringTag, {
32685 value: 'WritableStream',
32686 configurable: true
32687 });
32688}
32689// Abstract operations for the WritableStream.
32690function AcquireWritableStreamDefaultWriter(stream) {
32691 return new WritableStreamDefaultWriter(stream);
32692}
32693// Throws if and only if startAlgorithm throws.
32694function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
32695 const stream = Object.create(WritableStream$1.prototype);
32696 InitializeWritableStream(stream);
32697 const controller = Object.create(WritableStreamDefaultController.prototype);
32698 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
32699 return stream;
32700}
32701function InitializeWritableStream(stream) {
32702 stream._state = 'writable';
32703 // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is
32704 // 'erroring' or 'errored'. May be set to an undefined value.
32705 stream._storedError = undefined;
32706 stream._writer = undefined;
32707 // Initialize to undefined first because the constructor of the controller checks this
32708 // variable to validate the caller.
32709 stream._writableStreamController = undefined;
32710 // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data
32711 // producer without waiting for the queued writes to finish.
32712 stream._writeRequests = new SimpleQueue();
32713 // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents
32714 // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here.
32715 stream._inFlightWriteRequest = undefined;
32716 // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer
32717 // has been detached.
32718 stream._closeRequest = undefined;
32719 // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it
32720 // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here.
32721 stream._inFlightCloseRequest = undefined;
32722 // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached.
32723 stream._pendingAbortRequest = undefined;
32724 // The backpressure signal set by the controller.
32725 stream._backpressure = false;
32726}
32727function IsWritableStream(x) {
32728 if (!typeIsObject(x)) {
32729 return false;
32730 }
32731 if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) {
32732 return false;
32733 }
32734 return true;
32735}
32736function IsWritableStreamLocked(stream) {
32737 if (stream._writer === undefined) {
32738 return false;
32739 }
32740 return true;
32741}
32742function WritableStreamAbort(stream, reason) {
32743 const state = stream._state;
32744 if (state === 'closed' || state === 'errored') {
32745 return promiseResolvedWith(undefined);
32746 }
32747 if (stream._pendingAbortRequest !== undefined) {
32748 return stream._pendingAbortRequest._promise;
32749 }
32750 let wasAlreadyErroring = false;
32751 if (state === 'erroring') {
32752 wasAlreadyErroring = true;
32753 // reason will not be used, so don't keep a reference to it.
32754 reason = undefined;
32755 }
32756 const promise = newPromise((resolve, reject) => {
32757 stream._pendingAbortRequest = {
32758 _promise: undefined,
32759 _resolve: resolve,
32760 _reject: reject,
32761 _reason: reason,
32762 _wasAlreadyErroring: wasAlreadyErroring
32763 };
32764 });
32765 stream._pendingAbortRequest._promise = promise;
32766 if (!wasAlreadyErroring) {
32767 WritableStreamStartErroring(stream, reason);
32768 }
32769 return promise;
32770}
32771function WritableStreamClose(stream) {
32772 const state = stream._state;
32773 if (state === 'closed' || state === 'errored') {
32774 return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`));
32775 }
32776 const promise = newPromise((resolve, reject) => {
32777 const closeRequest = {
32778 _resolve: resolve,
32779 _reject: reject
32780 };
32781 stream._closeRequest = closeRequest;
32782 });
32783 const writer = stream._writer;
32784 if (writer !== undefined && stream._backpressure && state === 'writable') {
32785 defaultWriterReadyPromiseResolve(writer);
32786 }
32787 WritableStreamDefaultControllerClose(stream._writableStreamController);
32788 return promise;
32789}
32790// WritableStream API exposed for controllers.
32791function WritableStreamAddWriteRequest(stream) {
32792 const promise = newPromise((resolve, reject) => {
32793 const writeRequest = {
32794 _resolve: resolve,
32795 _reject: reject
32796 };
32797 stream._writeRequests.push(writeRequest);
32798 });
32799 return promise;
32800}
32801function WritableStreamDealWithRejection(stream, error) {
32802 const state = stream._state;
32803 if (state === 'writable') {
32804 WritableStreamStartErroring(stream, error);
32805 return;
32806 }
32807 WritableStreamFinishErroring(stream);
32808}
32809function WritableStreamStartErroring(stream, reason) {
32810 const controller = stream._writableStreamController;
32811 stream._state = 'erroring';
32812 stream._storedError = reason;
32813 const writer = stream._writer;
32814 if (writer !== undefined) {
32815 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason);
32816 }
32817 if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) {
32818 WritableStreamFinishErroring(stream);
32819 }
32820}
32821function WritableStreamFinishErroring(stream) {
32822 stream._state = 'errored';
32823 stream._writableStreamController[ErrorSteps]();
32824 const storedError = stream._storedError;
32825 stream._writeRequests.forEach(writeRequest => {
32826 writeRequest._reject(storedError);
32827 });
32828 stream._writeRequests = new SimpleQueue();
32829 if (stream._pendingAbortRequest === undefined) {
32830 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
32831 return;
32832 }
32833 const abortRequest = stream._pendingAbortRequest;
32834 stream._pendingAbortRequest = undefined;
32835 if (abortRequest._wasAlreadyErroring) {
32836 abortRequest._reject(storedError);
32837 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
32838 return;
32839 }
32840 const promise = stream._writableStreamController[AbortSteps](abortRequest._reason);
32841 uponPromise(promise, () => {
32842 abortRequest._resolve();
32843 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
32844 }, (reason) => {
32845 abortRequest._reject(reason);
32846 WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
32847 });
32848}
32849function WritableStreamFinishInFlightWrite(stream) {
32850 stream._inFlightWriteRequest._resolve(undefined);
32851 stream._inFlightWriteRequest = undefined;
32852}
32853function WritableStreamFinishInFlightWriteWithError(stream, error) {
32854 stream._inFlightWriteRequest._reject(error);
32855 stream._inFlightWriteRequest = undefined;
32856 WritableStreamDealWithRejection(stream, error);
32857}
32858function WritableStreamFinishInFlightClose(stream) {
32859 stream._inFlightCloseRequest._resolve(undefined);
32860 stream._inFlightCloseRequest = undefined;
32861 const state = stream._state;
32862 if (state === 'erroring') {
32863 // The error was too late to do anything, so it is ignored.
32864 stream._storedError = undefined;
32865 if (stream._pendingAbortRequest !== undefined) {
32866 stream._pendingAbortRequest._resolve();
32867 stream._pendingAbortRequest = undefined;
32868 }
32869 }
32870 stream._state = 'closed';
32871 const writer = stream._writer;
32872 if (writer !== undefined) {
32873 defaultWriterClosedPromiseResolve(writer);
32874 }
32875}
32876function WritableStreamFinishInFlightCloseWithError(stream, error) {
32877 stream._inFlightCloseRequest._reject(error);
32878 stream._inFlightCloseRequest = undefined;
32879 // Never execute sink abort() after sink close().
32880 if (stream._pendingAbortRequest !== undefined) {
32881 stream._pendingAbortRequest._reject(error);
32882 stream._pendingAbortRequest = undefined;
32883 }
32884 WritableStreamDealWithRejection(stream, error);
32885}
32886// TODO(ricea): Fix alphabetical order.
32887function WritableStreamCloseQueuedOrInFlight(stream) {
32888 if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) {
32889 return false;
32890 }
32891 return true;
32892}
32893function WritableStreamHasOperationMarkedInFlight(stream) {
32894 if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) {
32895 return false;
32896 }
32897 return true;
32898}
32899function WritableStreamMarkCloseRequestInFlight(stream) {
32900 stream._inFlightCloseRequest = stream._closeRequest;
32901 stream._closeRequest = undefined;
32902}
32903function WritableStreamMarkFirstWriteRequestInFlight(stream) {
32904 stream._inFlightWriteRequest = stream._writeRequests.shift();
32905}
32906function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) {
32907 if (stream._closeRequest !== undefined) {
32908 stream._closeRequest._reject(stream._storedError);
32909 stream._closeRequest = undefined;
32910 }
32911 const writer = stream._writer;
32912 if (writer !== undefined) {
32913 defaultWriterClosedPromiseReject(writer, stream._storedError);
32914 }
32915}
32916function WritableStreamUpdateBackpressure(stream, backpressure) {
32917 const writer = stream._writer;
32918 if (writer !== undefined && backpressure !== stream._backpressure) {
32919 if (backpressure) {
32920 defaultWriterReadyPromiseReset(writer);
32921 }
32922 else {
32923 defaultWriterReadyPromiseResolve(writer);
32924 }
32925 }
32926 stream._backpressure = backpressure;
32927}
32928/**
32929 * A default writer vended by a {@link WritableStream}.
32930 *
32931 * @public
32932 */
32933class WritableStreamDefaultWriter {
32934 constructor(stream) {
32935 assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter');
32936 assertWritableStream(stream, 'First parameter');
32937 if (IsWritableStreamLocked(stream)) {
32938 throw new TypeError('This stream has already been locked for exclusive writing by another writer');
32939 }
32940 this._ownerWritableStream = stream;
32941 stream._writer = this;
32942 const state = stream._state;
32943 if (state === 'writable') {
32944 if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) {
32945 defaultWriterReadyPromiseInitialize(this);
32946 }
32947 else {
32948 defaultWriterReadyPromiseInitializeAsResolved(this);
32949 }
32950 defaultWriterClosedPromiseInitialize(this);
32951 }
32952 else if (state === 'erroring') {
32953 defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError);
32954 defaultWriterClosedPromiseInitialize(this);
32955 }
32956 else if (state === 'closed') {
32957 defaultWriterReadyPromiseInitializeAsResolved(this);
32958 defaultWriterClosedPromiseInitializeAsResolved(this);
32959 }
32960 else {
32961 const storedError = stream._storedError;
32962 defaultWriterReadyPromiseInitializeAsRejected(this, storedError);
32963 defaultWriterClosedPromiseInitializeAsRejected(this, storedError);
32964 }
32965 }
32966 /**
32967 * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or
32968 * the writer’s lock is released before the stream finishes closing.
32969 */
32970 get closed() {
32971 if (!IsWritableStreamDefaultWriter(this)) {
32972 return promiseRejectedWith(defaultWriterBrandCheckException('closed'));
32973 }
32974 return this._closedPromise;
32975 }
32976 /**
32977 * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full.
32978 * A producer can use this information to determine the right amount of data to write.
32979 *
32980 * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort
32981 * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when
32982 * the writer’s lock is released.
32983 */
32984 get desiredSize() {
32985 if (!IsWritableStreamDefaultWriter(this)) {
32986 throw defaultWriterBrandCheckException('desiredSize');
32987 }
32988 if (this._ownerWritableStream === undefined) {
32989 throw defaultWriterLockException('desiredSize');
32990 }
32991 return WritableStreamDefaultWriterGetDesiredSize(this);
32992 }
32993 /**
32994 * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions
32995 * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips
32996 * back to zero or below, the getter will return a new promise that stays pending until the next transition.
32997 *
32998 * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become
32999 * rejected.
33000 */
33001 get ready() {
33002 if (!IsWritableStreamDefaultWriter(this)) {
33003 return promiseRejectedWith(defaultWriterBrandCheckException('ready'));
33004 }
33005 return this._readyPromise;
33006 }
33007 /**
33008 * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}.
33009 */
33010 abort(reason = undefined) {
33011 if (!IsWritableStreamDefaultWriter(this)) {
33012 return promiseRejectedWith(defaultWriterBrandCheckException('abort'));
33013 }
33014 if (this._ownerWritableStream === undefined) {
33015 return promiseRejectedWith(defaultWriterLockException('abort'));
33016 }
33017 return WritableStreamDefaultWriterAbort(this, reason);
33018 }
33019 /**
33020 * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}.
33021 */
33022 close() {
33023 if (!IsWritableStreamDefaultWriter(this)) {
33024 return promiseRejectedWith(defaultWriterBrandCheckException('close'));
33025 }
33026 const stream = this._ownerWritableStream;
33027 if (stream === undefined) {
33028 return promiseRejectedWith(defaultWriterLockException('close'));
33029 }
33030 if (WritableStreamCloseQueuedOrInFlight(stream)) {
33031 return promiseRejectedWith(new TypeError('Cannot close an already-closing stream'));
33032 }
33033 return WritableStreamDefaultWriterClose(this);
33034 }
33035 /**
33036 * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active.
33037 * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from
33038 * now on; otherwise, the writer will appear closed.
33039 *
33040 * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the
33041 * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled).
33042 * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents
33043 * other producers from writing in an interleaved manner.
33044 */
33045 releaseLock() {
33046 if (!IsWritableStreamDefaultWriter(this)) {
33047 throw defaultWriterBrandCheckException('releaseLock');
33048 }
33049 const stream = this._ownerWritableStream;
33050 if (stream === undefined) {
33051 return;
33052 }
33053 WritableStreamDefaultWriterRelease(this);
33054 }
33055 write(chunk = undefined) {
33056 if (!IsWritableStreamDefaultWriter(this)) {
33057 return promiseRejectedWith(defaultWriterBrandCheckException('write'));
33058 }
33059 if (this._ownerWritableStream === undefined) {
33060 return promiseRejectedWith(defaultWriterLockException('write to'));
33061 }
33062 return WritableStreamDefaultWriterWrite(this, chunk);
33063 }
33064}
33065Object.defineProperties(WritableStreamDefaultWriter.prototype, {
33066 abort: { enumerable: true },
33067 close: { enumerable: true },
33068 releaseLock: { enumerable: true },
33069 write: { enumerable: true },
33070 closed: { enumerable: true },
33071 desiredSize: { enumerable: true },
33072 ready: { enumerable: true }
33073});
33074if (typeof SymbolPolyfill.toStringTag === 'symbol') {
33075 Object.defineProperty(WritableStreamDefaultWriter.prototype, SymbolPolyfill.toStringTag, {
33076 value: 'WritableStreamDefaultWriter',
33077 configurable: true
33078 });
33079}
33080// Abstract operations for the WritableStreamDefaultWriter.
33081function IsWritableStreamDefaultWriter(x) {
33082 if (!typeIsObject(x)) {
33083 return false;
33084 }
33085 if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) {
33086 return false;
33087 }
33088 return true;
33089}
33090// A client of WritableStreamDefaultWriter may use these functions directly to bypass state check.
33091function WritableStreamDefaultWriterAbort(writer, reason) {
33092 const stream = writer._ownerWritableStream;
33093 return WritableStreamAbort(stream, reason);
33094}
33095function WritableStreamDefaultWriterClose(writer) {
33096 const stream = writer._ownerWritableStream;
33097 return WritableStreamClose(stream);
33098}
33099function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) {
33100 const stream = writer._ownerWritableStream;
33101 const state = stream._state;
33102 if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
33103 return promiseResolvedWith(undefined);
33104 }
33105 if (state === 'errored') {
33106 return promiseRejectedWith(stream._storedError);
33107 }
33108 return WritableStreamDefaultWriterClose(writer);
33109}
33110function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) {
33111 if (writer._closedPromiseState === 'pending') {
33112 defaultWriterClosedPromiseReject(writer, error);
33113 }
33114 else {
33115 defaultWriterClosedPromiseResetToRejected(writer, error);
33116 }
33117}
33118function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) {
33119 if (writer._readyPromiseState === 'pending') {
33120 defaultWriterReadyPromiseReject(writer, error);
33121 }
33122 else {
33123 defaultWriterReadyPromiseResetToRejected(writer, error);
33124 }
33125}
33126function WritableStreamDefaultWriterGetDesiredSize(writer) {
33127 const stream = writer._ownerWritableStream;
33128 const state = stream._state;
33129 if (state === 'errored' || state === 'erroring') {
33130 return null;
33131 }
33132 if (state === 'closed') {
33133 return 0;
33134 }
33135 return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController);
33136}
33137function WritableStreamDefaultWriterRelease(writer) {
33138 const stream = writer._ownerWritableStream;
33139 const releasedError = new TypeError(`Writer was released and can no longer be used to monitor the stream's closedness`);
33140 WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError);
33141 // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not
33142 // rejected until afterwards. This means that simply testing state will not work.
33143 WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError);
33144 stream._writer = undefined;
33145 writer._ownerWritableStream = undefined;
33146}
33147function WritableStreamDefaultWriterWrite(writer, chunk) {
33148 const stream = writer._ownerWritableStream;
33149 const controller = stream._writableStreamController;
33150 const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk);
33151 if (stream !== writer._ownerWritableStream) {
33152 return promiseRejectedWith(defaultWriterLockException('write to'));
33153 }
33154 const state = stream._state;
33155 if (state === 'errored') {
33156 return promiseRejectedWith(stream._storedError);
33157 }
33158 if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') {
33159 return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to'));
33160 }
33161 if (state === 'erroring') {
33162 return promiseRejectedWith(stream._storedError);
33163 }
33164 const promise = WritableStreamAddWriteRequest(stream);
33165 WritableStreamDefaultControllerWrite(controller, chunk, chunkSize);
33166 return promise;
33167}
33168const closeSentinel = {};
33169/**
33170 * Allows control of a {@link WritableStream | writable stream}'s state and internal queue.
33171 *
33172 * @public
33173 */
33174class WritableStreamDefaultController {
33175 constructor() {
33176 throw new TypeError('Illegal constructor');
33177 }
33178 /**
33179 * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`.
33180 *
33181 * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying
33182 * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the
33183 * normal lifecycle of interactions with the underlying sink.
33184 */
33185 error(e = undefined) {
33186 if (!IsWritableStreamDefaultController(this)) {
33187 throw new TypeError('WritableStreamDefaultController.prototype.error can only be used on a WritableStreamDefaultController');
33188 }
33189 const state = this._controlledWritableStream._state;
33190 if (state !== 'writable') {
33191 // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so
33192 // just treat it as a no-op.
33193 return;
33194 }
33195 WritableStreamDefaultControllerError(this, e);
33196 }
33197 /** @internal */
33198 [AbortSteps](reason) {
33199 const result = this._abortAlgorithm(reason);
33200 WritableStreamDefaultControllerClearAlgorithms(this);
33201 return result;
33202 }
33203 /** @internal */
33204 [ErrorSteps]() {
33205 ResetQueue(this);
33206 }
33207}
33208Object.defineProperties(WritableStreamDefaultController.prototype, {
33209 error: { enumerable: true }
33210});
33211if (typeof SymbolPolyfill.toStringTag === 'symbol') {
33212 Object.defineProperty(WritableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
33213 value: 'WritableStreamDefaultController',
33214 configurable: true
33215 });
33216}
33217// Abstract operations implementing interface required by the WritableStream.
33218function IsWritableStreamDefaultController(x) {
33219 if (!typeIsObject(x)) {
33220 return false;
33221 }
33222 if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) {
33223 return false;
33224 }
33225 return true;
33226}
33227function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) {
33228 controller._controlledWritableStream = stream;
33229 stream._writableStreamController = controller;
33230 // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly.
33231 controller._queue = undefined;
33232 controller._queueTotalSize = undefined;
33233 ResetQueue(controller);
33234 controller._started = false;
33235 controller._strategySizeAlgorithm = sizeAlgorithm;
33236 controller._strategyHWM = highWaterMark;
33237 controller._writeAlgorithm = writeAlgorithm;
33238 controller._closeAlgorithm = closeAlgorithm;
33239 controller._abortAlgorithm = abortAlgorithm;
33240 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
33241 WritableStreamUpdateBackpressure(stream, backpressure);
33242 const startResult = startAlgorithm();
33243 const startPromise = promiseResolvedWith(startResult);
33244 uponPromise(startPromise, () => {
33245 controller._started = true;
33246 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
33247 }, r => {
33248 controller._started = true;
33249 WritableStreamDealWithRejection(stream, r);
33250 });
33251}
33252function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) {
33253 const controller = Object.create(WritableStreamDefaultController.prototype);
33254 let startAlgorithm = () => undefined;
33255 let writeAlgorithm = () => promiseResolvedWith(undefined);
33256 let closeAlgorithm = () => promiseResolvedWith(undefined);
33257 let abortAlgorithm = () => promiseResolvedWith(undefined);
33258 if (underlyingSink.start !== undefined) {
33259 startAlgorithm = () => underlyingSink.start(controller);
33260 }
33261 if (underlyingSink.write !== undefined) {
33262 writeAlgorithm = chunk => underlyingSink.write(chunk, controller);
33263 }
33264 if (underlyingSink.close !== undefined) {
33265 closeAlgorithm = () => underlyingSink.close();
33266 }
33267 if (underlyingSink.abort !== undefined) {
33268 abortAlgorithm = reason => underlyingSink.abort(reason);
33269 }
33270 SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm);
33271}
33272// ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls.
33273function WritableStreamDefaultControllerClearAlgorithms(controller) {
33274 controller._writeAlgorithm = undefined;
33275 controller._closeAlgorithm = undefined;
33276 controller._abortAlgorithm = undefined;
33277 controller._strategySizeAlgorithm = undefined;
33278}
33279function WritableStreamDefaultControllerClose(controller) {
33280 EnqueueValueWithSize(controller, closeSentinel, 0);
33281 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
33282}
33283function WritableStreamDefaultControllerGetChunkSize(controller, chunk) {
33284 try {
33285 return controller._strategySizeAlgorithm(chunk);
33286 }
33287 catch (chunkSizeE) {
33288 WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE);
33289 return 1;
33290 }
33291}
33292function WritableStreamDefaultControllerGetDesiredSize(controller) {
33293 return controller._strategyHWM - controller._queueTotalSize;
33294}
33295function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) {
33296 try {
33297 EnqueueValueWithSize(controller, chunk, chunkSize);
33298 }
33299 catch (enqueueE) {
33300 WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE);
33301 return;
33302 }
33303 const stream = controller._controlledWritableStream;
33304 if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable') {
33305 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
33306 WritableStreamUpdateBackpressure(stream, backpressure);
33307 }
33308 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
33309}
33310// Abstract operations for the WritableStreamDefaultController.
33311function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) {
33312 const stream = controller._controlledWritableStream;
33313 if (!controller._started) {
33314 return;
33315 }
33316 if (stream._inFlightWriteRequest !== undefined) {
33317 return;
33318 }
33319 const state = stream._state;
33320 if (state === 'erroring') {
33321 WritableStreamFinishErroring(stream);
33322 return;
33323 }
33324 if (controller._queue.length === 0) {
33325 return;
33326 }
33327 const value = PeekQueueValue(controller);
33328 if (value === closeSentinel) {
33329 WritableStreamDefaultControllerProcessClose(controller);
33330 }
33331 else {
33332 WritableStreamDefaultControllerProcessWrite(controller, value);
33333 }
33334}
33335function WritableStreamDefaultControllerErrorIfNeeded(controller, error) {
33336 if (controller._controlledWritableStream._state === 'writable') {
33337 WritableStreamDefaultControllerError(controller, error);
33338 }
33339}
33340function WritableStreamDefaultControllerProcessClose(controller) {
33341 const stream = controller._controlledWritableStream;
33342 WritableStreamMarkCloseRequestInFlight(stream);
33343 DequeueValue(controller);
33344 const sinkClosePromise = controller._closeAlgorithm();
33345 WritableStreamDefaultControllerClearAlgorithms(controller);
33346 uponPromise(sinkClosePromise, () => {
33347 WritableStreamFinishInFlightClose(stream);
33348 }, reason => {
33349 WritableStreamFinishInFlightCloseWithError(stream, reason);
33350 });
33351}
33352function WritableStreamDefaultControllerProcessWrite(controller, chunk) {
33353 const stream = controller._controlledWritableStream;
33354 WritableStreamMarkFirstWriteRequestInFlight(stream);
33355 const sinkWritePromise = controller._writeAlgorithm(chunk);
33356 uponPromise(sinkWritePromise, () => {
33357 WritableStreamFinishInFlightWrite(stream);
33358 const state = stream._state;
33359 DequeueValue(controller);
33360 if (!WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable') {
33361 const backpressure = WritableStreamDefaultControllerGetBackpressure(controller);
33362 WritableStreamUpdateBackpressure(stream, backpressure);
33363 }
33364 WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
33365 }, reason => {
33366 if (stream._state === 'writable') {
33367 WritableStreamDefaultControllerClearAlgorithms(controller);
33368 }
33369 WritableStreamFinishInFlightWriteWithError(stream, reason);
33370 });
33371}
33372function WritableStreamDefaultControllerGetBackpressure(controller) {
33373 const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller);
33374 return desiredSize <= 0;
33375}
33376// A client of WritableStreamDefaultController may use these functions directly to bypass state check.
33377function WritableStreamDefaultControllerError(controller, error) {
33378 const stream = controller._controlledWritableStream;
33379 WritableStreamDefaultControllerClearAlgorithms(controller);
33380 WritableStreamStartErroring(stream, error);
33381}
33382// Helper functions for the WritableStream.
33383function streamBrandCheckException$2(name) {
33384 return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`);
33385}
33386// Helper functions for the WritableStreamDefaultWriter.
33387function defaultWriterBrandCheckException(name) {
33388 return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`);
33389}
33390function defaultWriterLockException(name) {
33391 return new TypeError('Cannot ' + name + ' a stream using a released writer');
33392}
33393function defaultWriterClosedPromiseInitialize(writer) {
33394 writer._closedPromise = newPromise((resolve, reject) => {
33395 writer._closedPromise_resolve = resolve;
33396 writer._closedPromise_reject = reject;
33397 writer._closedPromiseState = 'pending';
33398 });
33399}
33400function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) {
33401 defaultWriterClosedPromiseInitialize(writer);
33402 defaultWriterClosedPromiseReject(writer, reason);
33403}
33404function defaultWriterClosedPromiseInitializeAsResolved(writer) {
33405 defaultWriterClosedPromiseInitialize(writer);
33406 defaultWriterClosedPromiseResolve(writer);
33407}
33408function defaultWriterClosedPromiseReject(writer, reason) {
33409 if (writer._closedPromise_reject === undefined) {
33410 return;
33411 }
33412 setPromiseIsHandledToTrue(writer._closedPromise);
33413 writer._closedPromise_reject(reason);
33414 writer._closedPromise_resolve = undefined;
33415 writer._closedPromise_reject = undefined;
33416 writer._closedPromiseState = 'rejected';
33417}
33418function defaultWriterClosedPromiseResetToRejected(writer, reason) {
33419 defaultWriterClosedPromiseInitializeAsRejected(writer, reason);
33420}
33421function defaultWriterClosedPromiseResolve(writer) {
33422 if (writer._closedPromise_resolve === undefined) {
33423 return;
33424 }
33425 writer._closedPromise_resolve(undefined);
33426 writer._closedPromise_resolve = undefined;
33427 writer._closedPromise_reject = undefined;
33428 writer._closedPromiseState = 'resolved';
33429}
33430function defaultWriterReadyPromiseInitialize(writer) {
33431 writer._readyPromise = newPromise((resolve, reject) => {
33432 writer._readyPromise_resolve = resolve;
33433 writer._readyPromise_reject = reject;
33434 });
33435 writer._readyPromiseState = 'pending';
33436}
33437function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) {
33438 defaultWriterReadyPromiseInitialize(writer);
33439 defaultWriterReadyPromiseReject(writer, reason);
33440}
33441function defaultWriterReadyPromiseInitializeAsResolved(writer) {
33442 defaultWriterReadyPromiseInitialize(writer);
33443 defaultWriterReadyPromiseResolve(writer);
33444}
33445function defaultWriterReadyPromiseReject(writer, reason) {
33446 if (writer._readyPromise_reject === undefined) {
33447 return;
33448 }
33449 setPromiseIsHandledToTrue(writer._readyPromise);
33450 writer._readyPromise_reject(reason);
33451 writer._readyPromise_resolve = undefined;
33452 writer._readyPromise_reject = undefined;
33453 writer._readyPromiseState = 'rejected';
33454}
33455function defaultWriterReadyPromiseReset(writer) {
33456 defaultWriterReadyPromiseInitialize(writer);
33457}
33458function defaultWriterReadyPromiseResetToRejected(writer, reason) {
33459 defaultWriterReadyPromiseInitializeAsRejected(writer, reason);
33460}
33461function defaultWriterReadyPromiseResolve(writer) {
33462 if (writer._readyPromise_resolve === undefined) {
33463 return;
33464 }
33465 writer._readyPromise_resolve(undefined);
33466 writer._readyPromise_resolve = undefined;
33467 writer._readyPromise_reject = undefined;
33468 writer._readyPromiseState = 'fulfilled';
33469}
33470
33471function isAbortSignal(value) {
33472 if (typeof value !== 'object' || value === null) {
33473 return false;
33474 }
33475 try {
33476 return typeof value.aborted === 'boolean';
33477 }
33478 catch (_a) {
33479 // AbortSignal.prototype.aborted throws if its brand check fails
33480 return false;
33481 }
33482}
33483
33484/// <reference lib="dom" />
33485const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined;
33486
33487/// <reference types="node" />
33488function isDOMExceptionConstructor(ctor) {
33489 if (!(typeof ctor === 'function' || typeof ctor === 'object')) {
33490 return false;
33491 }
33492 try {
33493 new ctor();
33494 return true;
33495 }
33496 catch (_a) {
33497 return false;
33498 }
33499}
33500function createDOMExceptionPolyfill() {
33501 // eslint-disable-next-line no-shadow
33502 const ctor = function DOMException(message, name) {
33503 this.message = message || '';
33504 this.name = name || 'Error';
33505 if (Error.captureStackTrace) {
33506 Error.captureStackTrace(this, this.constructor);
33507 }
33508 };
33509 ctor.prototype = Object.create(Error.prototype);
33510 Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true });
33511 return ctor;
33512}
33513// eslint-disable-next-line no-redeclare
33514const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill();
33515
33516function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) {
33517 const reader = AcquireReadableStreamDefaultReader(source);
33518 const writer = AcquireWritableStreamDefaultWriter(dest);
33519 source._disturbed = true;
33520 let shuttingDown = false;
33521 // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown.
33522 let currentWrite = promiseResolvedWith(undefined);
33523 return newPromise((resolve, reject) => {
33524 let abortAlgorithm;
33525 if (signal !== undefined) {
33526 abortAlgorithm = () => {
33527 const error = new DOMException$1('Aborted', 'AbortError');
33528 const actions = [];
33529 if (!preventAbort) {
33530 actions.push(() => {
33531 if (dest._state === 'writable') {
33532 return WritableStreamAbort(dest, error);
33533 }
33534 return promiseResolvedWith(undefined);
33535 });
33536 }
33537 if (!preventCancel) {
33538 actions.push(() => {
33539 if (source._state === 'readable') {
33540 return ReadableStreamCancel(source, error);
33541 }
33542 return promiseResolvedWith(undefined);
33543 });
33544 }
33545 shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error);
33546 };
33547 if (signal.aborted) {
33548 abortAlgorithm();
33549 return;
33550 }
33551 signal.addEventListener('abort', abortAlgorithm);
33552 }
33553 // Using reader and writer, read all chunks from this and write them to dest
33554 // - Backpressure must be enforced
33555 // - Shutdown must stop all activity
33556 function pipeLoop() {
33557 return newPromise((resolveLoop, rejectLoop) => {
33558 function next(done) {
33559 if (done) {
33560 resolveLoop();
33561 }
33562 else {
33563 // Use `PerformPromiseThen` instead of `uponPromise` to avoid
33564 // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers
33565 PerformPromiseThen(pipeStep(), next, rejectLoop);
33566 }
33567 }
33568 next(false);
33569 });
33570 }
33571 function pipeStep() {
33572 if (shuttingDown) {
33573 return promiseResolvedWith(true);
33574 }
33575 return PerformPromiseThen(writer._readyPromise, () => {
33576 return newPromise((resolveRead, rejectRead) => {
33577 ReadableStreamDefaultReaderRead(reader, {
33578 _chunkSteps: chunk => {
33579 currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop);
33580 resolveRead(false);
33581 },
33582 _closeSteps: () => resolveRead(true),
33583 _errorSteps: rejectRead
33584 });
33585 });
33586 });
33587 }
33588 // Errors must be propagated forward
33589 isOrBecomesErrored(source, reader._closedPromise, storedError => {
33590 if (!preventAbort) {
33591 shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError);
33592 }
33593 else {
33594 shutdown(true, storedError);
33595 }
33596 });
33597 // Errors must be propagated backward
33598 isOrBecomesErrored(dest, writer._closedPromise, storedError => {
33599 if (!preventCancel) {
33600 shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError);
33601 }
33602 else {
33603 shutdown(true, storedError);
33604 }
33605 });
33606 // Closing must be propagated forward
33607 isOrBecomesClosed(source, reader._closedPromise, () => {
33608 if (!preventClose) {
33609 shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer));
33610 }
33611 else {
33612 shutdown();
33613 }
33614 });
33615 // Closing must be propagated backward
33616 if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') {
33617 const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it');
33618 if (!preventCancel) {
33619 shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed);
33620 }
33621 else {
33622 shutdown(true, destClosed);
33623 }
33624 }
33625 setPromiseIsHandledToTrue(pipeLoop());
33626 function waitForWritesToFinish() {
33627 // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait
33628 // for that too.
33629 const oldCurrentWrite = currentWrite;
33630 return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined);
33631 }
33632 function isOrBecomesErrored(stream, promise, action) {
33633 if (stream._state === 'errored') {
33634 action(stream._storedError);
33635 }
33636 else {
33637 uponRejection(promise, action);
33638 }
33639 }
33640 function isOrBecomesClosed(stream, promise, action) {
33641 if (stream._state === 'closed') {
33642 action();
33643 }
33644 else {
33645 uponFulfillment(promise, action);
33646 }
33647 }
33648 function shutdownWithAction(action, originalIsError, originalError) {
33649 if (shuttingDown) {
33650 return;
33651 }
33652 shuttingDown = true;
33653 if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
33654 uponFulfillment(waitForWritesToFinish(), doTheRest);
33655 }
33656 else {
33657 doTheRest();
33658 }
33659 function doTheRest() {
33660 uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError));
33661 }
33662 }
33663 function shutdown(isError, error) {
33664 if (shuttingDown) {
33665 return;
33666 }
33667 shuttingDown = true;
33668 if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) {
33669 uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error));
33670 }
33671 else {
33672 finalize(isError, error);
33673 }
33674 }
33675 function finalize(isError, error) {
33676 WritableStreamDefaultWriterRelease(writer);
33677 ReadableStreamReaderGenericRelease(reader);
33678 if (signal !== undefined) {
33679 signal.removeEventListener('abort', abortAlgorithm);
33680 }
33681 if (isError) {
33682 reject(error);
33683 }
33684 else {
33685 resolve(undefined);
33686 }
33687 }
33688 });
33689}
33690
33691/**
33692 * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue.
33693 *
33694 * @public
33695 */
33696class ReadableStreamDefaultController {
33697 constructor() {
33698 throw new TypeError('Illegal constructor');
33699 }
33700 /**
33701 * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is
33702 * over-full. An underlying source ought to use this information to determine when and how to apply backpressure.
33703 */
33704 get desiredSize() {
33705 if (!IsReadableStreamDefaultController(this)) {
33706 throw defaultControllerBrandCheckException$1('desiredSize');
33707 }
33708 return ReadableStreamDefaultControllerGetDesiredSize(this);
33709 }
33710 /**
33711 * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from
33712 * the stream, but once those are read, the stream will become closed.
33713 */
33714 close() {
33715 if (!IsReadableStreamDefaultController(this)) {
33716 throw defaultControllerBrandCheckException$1('close');
33717 }
33718 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
33719 throw new TypeError('The stream is not in a state that permits close');
33720 }
33721 ReadableStreamDefaultControllerClose(this);
33722 }
33723 enqueue(chunk = undefined) {
33724 if (!IsReadableStreamDefaultController(this)) {
33725 throw defaultControllerBrandCheckException$1('enqueue');
33726 }
33727 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) {
33728 throw new TypeError('The stream is not in a state that permits enqueue');
33729 }
33730 return ReadableStreamDefaultControllerEnqueue(this, chunk);
33731 }
33732 /**
33733 * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`.
33734 */
33735 error(e = undefined) {
33736 if (!IsReadableStreamDefaultController(this)) {
33737 throw defaultControllerBrandCheckException$1('error');
33738 }
33739 ReadableStreamDefaultControllerError(this, e);
33740 }
33741 /** @internal */
33742 [CancelSteps](reason) {
33743 ResetQueue(this);
33744 const result = this._cancelAlgorithm(reason);
33745 ReadableStreamDefaultControllerClearAlgorithms(this);
33746 return result;
33747 }
33748 /** @internal */
33749 [PullSteps](readRequest) {
33750 const stream = this._controlledReadableStream;
33751 if (this._queue.length > 0) {
33752 const chunk = DequeueValue(this);
33753 if (this._closeRequested && this._queue.length === 0) {
33754 ReadableStreamDefaultControllerClearAlgorithms(this);
33755 ReadableStreamClose(stream);
33756 }
33757 else {
33758 ReadableStreamDefaultControllerCallPullIfNeeded(this);
33759 }
33760 readRequest._chunkSteps(chunk);
33761 }
33762 else {
33763 ReadableStreamAddReadRequest(stream, readRequest);
33764 ReadableStreamDefaultControllerCallPullIfNeeded(this);
33765 }
33766 }
33767}
33768Object.defineProperties(ReadableStreamDefaultController.prototype, {
33769 close: { enumerable: true },
33770 enqueue: { enumerable: true },
33771 error: { enumerable: true },
33772 desiredSize: { enumerable: true }
33773});
33774if (typeof SymbolPolyfill.toStringTag === 'symbol') {
33775 Object.defineProperty(ReadableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
33776 value: 'ReadableStreamDefaultController',
33777 configurable: true
33778 });
33779}
33780// Abstract operations for the ReadableStreamDefaultController.
33781function IsReadableStreamDefaultController(x) {
33782 if (!typeIsObject(x)) {
33783 return false;
33784 }
33785 if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) {
33786 return false;
33787 }
33788 return true;
33789}
33790function ReadableStreamDefaultControllerCallPullIfNeeded(controller) {
33791 const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller);
33792 if (!shouldPull) {
33793 return;
33794 }
33795 if (controller._pulling) {
33796 controller._pullAgain = true;
33797 return;
33798 }
33799 controller._pulling = true;
33800 const pullPromise = controller._pullAlgorithm();
33801 uponPromise(pullPromise, () => {
33802 controller._pulling = false;
33803 if (controller._pullAgain) {
33804 controller._pullAgain = false;
33805 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
33806 }
33807 }, e => {
33808 ReadableStreamDefaultControllerError(controller, e);
33809 });
33810}
33811function ReadableStreamDefaultControllerShouldCallPull(controller) {
33812 const stream = controller._controlledReadableStream;
33813 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
33814 return false;
33815 }
33816 if (!controller._started) {
33817 return false;
33818 }
33819 if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
33820 return true;
33821 }
33822 const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller);
33823 if (desiredSize > 0) {
33824 return true;
33825 }
33826 return false;
33827}
33828function ReadableStreamDefaultControllerClearAlgorithms(controller) {
33829 controller._pullAlgorithm = undefined;
33830 controller._cancelAlgorithm = undefined;
33831 controller._strategySizeAlgorithm = undefined;
33832}
33833// A client of ReadableStreamDefaultController may use these functions directly to bypass state check.
33834function ReadableStreamDefaultControllerClose(controller) {
33835 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
33836 return;
33837 }
33838 const stream = controller._controlledReadableStream;
33839 controller._closeRequested = true;
33840 if (controller._queue.length === 0) {
33841 ReadableStreamDefaultControllerClearAlgorithms(controller);
33842 ReadableStreamClose(stream);
33843 }
33844}
33845function ReadableStreamDefaultControllerEnqueue(controller, chunk) {
33846 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) {
33847 return;
33848 }
33849 const stream = controller._controlledReadableStream;
33850 if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) {
33851 ReadableStreamFulfillReadRequest(stream, chunk, false);
33852 }
33853 else {
33854 let chunkSize;
33855 try {
33856 chunkSize = controller._strategySizeAlgorithm(chunk);
33857 }
33858 catch (chunkSizeE) {
33859 ReadableStreamDefaultControllerError(controller, chunkSizeE);
33860 throw chunkSizeE;
33861 }
33862 try {
33863 EnqueueValueWithSize(controller, chunk, chunkSize);
33864 }
33865 catch (enqueueE) {
33866 ReadableStreamDefaultControllerError(controller, enqueueE);
33867 throw enqueueE;
33868 }
33869 }
33870 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
33871}
33872function ReadableStreamDefaultControllerError(controller, e) {
33873 const stream = controller._controlledReadableStream;
33874 if (stream._state !== 'readable') {
33875 return;
33876 }
33877 ResetQueue(controller);
33878 ReadableStreamDefaultControllerClearAlgorithms(controller);
33879 ReadableStreamError(stream, e);
33880}
33881function ReadableStreamDefaultControllerGetDesiredSize(controller) {
33882 const state = controller._controlledReadableStream._state;
33883 if (state === 'errored') {
33884 return null;
33885 }
33886 if (state === 'closed') {
33887 return 0;
33888 }
33889 return controller._strategyHWM - controller._queueTotalSize;
33890}
33891// This is used in the implementation of TransformStream.
33892function ReadableStreamDefaultControllerHasBackpressure(controller) {
33893 if (ReadableStreamDefaultControllerShouldCallPull(controller)) {
33894 return false;
33895 }
33896 return true;
33897}
33898function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) {
33899 const state = controller._controlledReadableStream._state;
33900 if (!controller._closeRequested && state === 'readable') {
33901 return true;
33902 }
33903 return false;
33904}
33905function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) {
33906 controller._controlledReadableStream = stream;
33907 controller._queue = undefined;
33908 controller._queueTotalSize = undefined;
33909 ResetQueue(controller);
33910 controller._started = false;
33911 controller._closeRequested = false;
33912 controller._pullAgain = false;
33913 controller._pulling = false;
33914 controller._strategySizeAlgorithm = sizeAlgorithm;
33915 controller._strategyHWM = highWaterMark;
33916 controller._pullAlgorithm = pullAlgorithm;
33917 controller._cancelAlgorithm = cancelAlgorithm;
33918 stream._readableStreamController = controller;
33919 const startResult = startAlgorithm();
33920 uponPromise(promiseResolvedWith(startResult), () => {
33921 controller._started = true;
33922 ReadableStreamDefaultControllerCallPullIfNeeded(controller);
33923 }, r => {
33924 ReadableStreamDefaultControllerError(controller, r);
33925 });
33926}
33927function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) {
33928 const controller = Object.create(ReadableStreamDefaultController.prototype);
33929 let startAlgorithm = () => undefined;
33930 let pullAlgorithm = () => promiseResolvedWith(undefined);
33931 let cancelAlgorithm = () => promiseResolvedWith(undefined);
33932 if (underlyingSource.start !== undefined) {
33933 startAlgorithm = () => underlyingSource.start(controller);
33934 }
33935 if (underlyingSource.pull !== undefined) {
33936 pullAlgorithm = () => underlyingSource.pull(controller);
33937 }
33938 if (underlyingSource.cancel !== undefined) {
33939 cancelAlgorithm = reason => underlyingSource.cancel(reason);
33940 }
33941 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
33942}
33943// Helper functions for the ReadableStreamDefaultController.
33944function defaultControllerBrandCheckException$1(name) {
33945 return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`);
33946}
33947
33948function ReadableStreamTee(stream, cloneForBranch2) {
33949 const reader = AcquireReadableStreamDefaultReader(stream);
33950 let reading = false;
33951 let canceled1 = false;
33952 let canceled2 = false;
33953 let reason1;
33954 let reason2;
33955 let branch1;
33956 let branch2;
33957 let resolveCancelPromise;
33958 const cancelPromise = newPromise(resolve => {
33959 resolveCancelPromise = resolve;
33960 });
33961 function pullAlgorithm() {
33962 if (reading) {
33963 return promiseResolvedWith(undefined);
33964 }
33965 reading = true;
33966 const readRequest = {
33967 _chunkSteps: value => {
33968 // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using
33969 // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
33970 // successful synchronously-available reads get ahead of asynchronously-available errors.
33971 queueMicrotask(() => {
33972 reading = false;
33973 const value1 = value;
33974 const value2 = value;
33975 // There is no way to access the cloning code right now in the reference implementation.
33976 // If we add one then we'll need an implementation for serializable objects.
33977 // if (!canceled2 && cloneForBranch2) {
33978 // value2 = StructuredDeserialize(StructuredSerialize(value2));
33979 // }
33980 if (!canceled1) {
33981 ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, value1);
33982 }
33983 if (!canceled2) {
33984 ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, value2);
33985 }
33986 });
33987 },
33988 _closeSteps: () => {
33989 reading = false;
33990 if (!canceled1) {
33991 ReadableStreamDefaultControllerClose(branch1._readableStreamController);
33992 }
33993 if (!canceled2) {
33994 ReadableStreamDefaultControllerClose(branch2._readableStreamController);
33995 }
33996 if (!canceled1 || !canceled2) {
33997 resolveCancelPromise(undefined);
33998 }
33999 },
34000 _errorSteps: () => {
34001 reading = false;
34002 }
34003 };
34004 ReadableStreamDefaultReaderRead(reader, readRequest);
34005 return promiseResolvedWith(undefined);
34006 }
34007 function cancel1Algorithm(reason) {
34008 canceled1 = true;
34009 reason1 = reason;
34010 if (canceled2) {
34011 const compositeReason = CreateArrayFromList([reason1, reason2]);
34012 const cancelResult = ReadableStreamCancel(stream, compositeReason);
34013 resolveCancelPromise(cancelResult);
34014 }
34015 return cancelPromise;
34016 }
34017 function cancel2Algorithm(reason) {
34018 canceled2 = true;
34019 reason2 = reason;
34020 if (canceled1) {
34021 const compositeReason = CreateArrayFromList([reason1, reason2]);
34022 const cancelResult = ReadableStreamCancel(stream, compositeReason);
34023 resolveCancelPromise(cancelResult);
34024 }
34025 return cancelPromise;
34026 }
34027 function startAlgorithm() {
34028 // do nothing
34029 }
34030 branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm);
34031 branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm);
34032 uponRejection(reader._closedPromise, (r) => {
34033 ReadableStreamDefaultControllerError(branch1._readableStreamController, r);
34034 ReadableStreamDefaultControllerError(branch2._readableStreamController, r);
34035 if (!canceled1 || !canceled2) {
34036 resolveCancelPromise(undefined);
34037 }
34038 });
34039 return [branch1, branch2];
34040}
34041
34042function convertUnderlyingDefaultOrByteSource(source, context) {
34043 assertDictionary(source, context);
34044 const original = source;
34045 const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize;
34046 const cancel = original === null || original === void 0 ? void 0 : original.cancel;
34047 const pull = original === null || original === void 0 ? void 0 : original.pull;
34048 const start = original === null || original === void 0 ? void 0 : original.start;
34049 const type = original === null || original === void 0 ? void 0 : original.type;
34050 return {
34051 autoAllocateChunkSize: autoAllocateChunkSize === undefined ?
34052 undefined :
34053 convertUnsignedLongLongWithEnforceRange(autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that`),
34054 cancel: cancel === undefined ?
34055 undefined :
34056 convertUnderlyingSourceCancelCallback(cancel, original, `${context} has member 'cancel' that`),
34057 pull: pull === undefined ?
34058 undefined :
34059 convertUnderlyingSourcePullCallback(pull, original, `${context} has member 'pull' that`),
34060 start: start === undefined ?
34061 undefined :
34062 convertUnderlyingSourceStartCallback(start, original, `${context} has member 'start' that`),
34063 type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`)
34064 };
34065}
34066function convertUnderlyingSourceCancelCallback(fn, original, context) {
34067 assertFunction(fn, context);
34068 return (reason) => promiseCall(fn, original, [reason]);
34069}
34070function convertUnderlyingSourcePullCallback(fn, original, context) {
34071 assertFunction(fn, context);
34072 return (controller) => promiseCall(fn, original, [controller]);
34073}
34074function convertUnderlyingSourceStartCallback(fn, original, context) {
34075 assertFunction(fn, context);
34076 return (controller) => reflectCall(fn, original, [controller]);
34077}
34078function convertReadableStreamType(type, context) {
34079 type = `${type}`;
34080 if (type !== 'bytes') {
34081 throw new TypeError(`${context} '${type}' is not a valid enumeration value for ReadableStreamType`);
34082 }
34083 return type;
34084}
34085
34086function convertReaderOptions(options, context) {
34087 assertDictionary(options, context);
34088 const mode = options === null || options === void 0 ? void 0 : options.mode;
34089 return {
34090 mode: mode === undefined ? undefined : convertReadableStreamReaderMode(mode, `${context} has member 'mode' that`)
34091 };
34092}
34093function convertReadableStreamReaderMode(mode, context) {
34094 mode = `${mode}`;
34095 if (mode !== 'byob') {
34096 throw new TypeError(`${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode`);
34097 }
34098 return mode;
34099}
34100
34101function convertIteratorOptions(options, context) {
34102 assertDictionary(options, context);
34103 const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
34104 return { preventCancel: Boolean(preventCancel) };
34105}
34106
34107function convertPipeOptions(options, context) {
34108 assertDictionary(options, context);
34109 const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort;
34110 const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel;
34111 const preventClose = options === null || options === void 0 ? void 0 : options.preventClose;
34112 const signal = options === null || options === void 0 ? void 0 : options.signal;
34113 if (signal !== undefined) {
34114 assertAbortSignal(signal, `${context} has member 'signal' that`);
34115 }
34116 return {
34117 preventAbort: Boolean(preventAbort),
34118 preventCancel: Boolean(preventCancel),
34119 preventClose: Boolean(preventClose),
34120 signal
34121 };
34122}
34123function assertAbortSignal(signal, context) {
34124 if (!isAbortSignal(signal)) {
34125 throw new TypeError(`${context} is not an AbortSignal.`);
34126 }
34127}
34128
34129function convertReadableWritablePair(pair, context) {
34130 assertDictionary(pair, context);
34131 const readable = pair === null || pair === void 0 ? void 0 : pair.readable;
34132 assertRequiredField(readable, 'readable', 'ReadableWritablePair');
34133 assertReadableStream(readable, `${context} has member 'readable' that`);
34134 const writable = pair === null || pair === void 0 ? void 0 : pair.writable;
34135 assertRequiredField(writable, 'writable', 'ReadableWritablePair');
34136 assertWritableStream(writable, `${context} has member 'writable' that`);
34137 return { readable, writable };
34138}
34139
34140/**
34141 * A readable stream represents a source of data, from which you can read.
34142 *
34143 * @public
34144 */
34145class ReadableStream$1 {
34146 constructor(rawUnderlyingSource = {}, rawStrategy = {}) {
34147 if (rawUnderlyingSource === undefined) {
34148 rawUnderlyingSource = null;
34149 }
34150 else {
34151 assertObject(rawUnderlyingSource, 'First parameter');
34152 }
34153 const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter');
34154 const underlyingSource = convertUnderlyingDefaultOrByteSource(rawUnderlyingSource, 'First parameter');
34155 InitializeReadableStream(this);
34156 if (underlyingSource.type === 'bytes') {
34157 if (strategy.size !== undefined) {
34158 throw new RangeError('The strategy for a byte stream cannot have a size function');
34159 }
34160 const highWaterMark = ExtractHighWaterMark(strategy, 0);
34161 SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark);
34162 }
34163 else {
34164 const sizeAlgorithm = ExtractSizeAlgorithm(strategy);
34165 const highWaterMark = ExtractHighWaterMark(strategy, 1);
34166 SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm);
34167 }
34168 }
34169 /**
34170 * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}.
34171 */
34172 get locked() {
34173 if (!IsReadableStream(this)) {
34174 throw streamBrandCheckException$1('locked');
34175 }
34176 return IsReadableStreamLocked(this);
34177 }
34178 /**
34179 * Cancels the stream, signaling a loss of interest in the stream by a consumer.
34180 *
34181 * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()}
34182 * method, which might or might not use it.
34183 */
34184 cancel(reason = undefined) {
34185 if (!IsReadableStream(this)) {
34186 return promiseRejectedWith(streamBrandCheckException$1('cancel'));
34187 }
34188 if (IsReadableStreamLocked(this)) {
34189 return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader'));
34190 }
34191 return ReadableStreamCancel(this, reason);
34192 }
34193 getReader(rawOptions = undefined) {
34194 if (!IsReadableStream(this)) {
34195 throw streamBrandCheckException$1('getReader');
34196 }
34197 const options = convertReaderOptions(rawOptions, 'First parameter');
34198 if (options.mode === undefined) {
34199 return AcquireReadableStreamDefaultReader(this);
34200 }
34201 return AcquireReadableStreamBYOBReader(this);
34202 }
34203 pipeThrough(rawTransform, rawOptions = {}) {
34204 if (!IsReadableStream(this)) {
34205 throw streamBrandCheckException$1('pipeThrough');
34206 }
34207 assertRequiredArgument(rawTransform, 1, 'pipeThrough');
34208 const transform = convertReadableWritablePair(rawTransform, 'First parameter');
34209 const options = convertPipeOptions(rawOptions, 'Second parameter');
34210 if (IsReadableStreamLocked(this)) {
34211 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream');
34212 }
34213 if (IsWritableStreamLocked(transform.writable)) {
34214 throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream');
34215 }
34216 const promise = ReadableStreamPipeTo(this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
34217 setPromiseIsHandledToTrue(promise);
34218 return transform.readable;
34219 }
34220 pipeTo(destination, rawOptions = {}) {
34221 if (!IsReadableStream(this)) {
34222 return promiseRejectedWith(streamBrandCheckException$1('pipeTo'));
34223 }
34224 if (destination === undefined) {
34225 return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`);
34226 }
34227 if (!IsWritableStream(destination)) {
34228 return promiseRejectedWith(new TypeError(`ReadableStream.prototype.pipeTo's first argument must be a WritableStream`));
34229 }
34230 let options;
34231 try {
34232 options = convertPipeOptions(rawOptions, 'Second parameter');
34233 }
34234 catch (e) {
34235 return promiseRejectedWith(e);
34236 }
34237 if (IsReadableStreamLocked(this)) {
34238 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream'));
34239 }
34240 if (IsWritableStreamLocked(destination)) {
34241 return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream'));
34242 }
34243 return ReadableStreamPipeTo(this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal);
34244 }
34245 /**
34246 * Tees this readable stream, returning a two-element array containing the two resulting branches as
34247 * new {@link ReadableStream} instances.
34248 *
34249 * Teeing a stream will lock it, preventing any other consumer from acquiring a reader.
34250 * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be
34251 * propagated to the stream's underlying source.
34252 *
34253 * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable,
34254 * this could allow interference between the two branches.
34255 */
34256 tee() {
34257 if (!IsReadableStream(this)) {
34258 throw streamBrandCheckException$1('tee');
34259 }
34260 const branches = ReadableStreamTee(this);
34261 return CreateArrayFromList(branches);
34262 }
34263 values(rawOptions = undefined) {
34264 if (!IsReadableStream(this)) {
34265 throw streamBrandCheckException$1('values');
34266 }
34267 const options = convertIteratorOptions(rawOptions, 'First parameter');
34268 return AcquireReadableStreamAsyncIterator(this, options.preventCancel);
34269 }
34270}
34271Object.defineProperties(ReadableStream$1.prototype, {
34272 cancel: { enumerable: true },
34273 getReader: { enumerable: true },
34274 pipeThrough: { enumerable: true },
34275 pipeTo: { enumerable: true },
34276 tee: { enumerable: true },
34277 values: { enumerable: true },
34278 locked: { enumerable: true }
34279});
34280if (typeof SymbolPolyfill.toStringTag === 'symbol') {
34281 Object.defineProperty(ReadableStream$1.prototype, SymbolPolyfill.toStringTag, {
34282 value: 'ReadableStream',
34283 configurable: true
34284 });
34285}
34286if (typeof SymbolPolyfill.asyncIterator === 'symbol') {
34287 Object.defineProperty(ReadableStream$1.prototype, SymbolPolyfill.asyncIterator, {
34288 value: ReadableStream$1.prototype.values,
34289 writable: true,
34290 configurable: true
34291 });
34292}
34293// Abstract operations for the ReadableStream.
34294// Throws if and only if startAlgorithm throws.
34295function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) {
34296 const stream = Object.create(ReadableStream$1.prototype);
34297 InitializeReadableStream(stream);
34298 const controller = Object.create(ReadableStreamDefaultController.prototype);
34299 SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm);
34300 return stream;
34301}
34302function InitializeReadableStream(stream) {
34303 stream._state = 'readable';
34304 stream._reader = undefined;
34305 stream._storedError = undefined;
34306 stream._disturbed = false;
34307}
34308function IsReadableStream(x) {
34309 if (!typeIsObject(x)) {
34310 return false;
34311 }
34312 if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) {
34313 return false;
34314 }
34315 return true;
34316}
34317function IsReadableStreamLocked(stream) {
34318 if (stream._reader === undefined) {
34319 return false;
34320 }
34321 return true;
34322}
34323// ReadableStream API exposed for controllers.
34324function ReadableStreamCancel(stream, reason) {
34325 stream._disturbed = true;
34326 if (stream._state === 'closed') {
34327 return promiseResolvedWith(undefined);
34328 }
34329 if (stream._state === 'errored') {
34330 return promiseRejectedWith(stream._storedError);
34331 }
34332 ReadableStreamClose(stream);
34333 const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason);
34334 return transformPromiseWith(sourceCancelPromise, noop);
34335}
34336function ReadableStreamClose(stream) {
34337 stream._state = 'closed';
34338 const reader = stream._reader;
34339 if (reader === undefined) {
34340 return;
34341 }
34342 defaultReaderClosedPromiseResolve(reader);
34343 if (IsReadableStreamDefaultReader(reader)) {
34344 reader._readRequests.forEach(readRequest => {
34345 readRequest._closeSteps();
34346 });
34347 reader._readRequests = new SimpleQueue();
34348 }
34349}
34350function ReadableStreamError(stream, e) {
34351 stream._state = 'errored';
34352 stream._storedError = e;
34353 const reader = stream._reader;
34354 if (reader === undefined) {
34355 return;
34356 }
34357 defaultReaderClosedPromiseReject(reader, e);
34358 if (IsReadableStreamDefaultReader(reader)) {
34359 reader._readRequests.forEach(readRequest => {
34360 readRequest._errorSteps(e);
34361 });
34362 reader._readRequests = new SimpleQueue();
34363 }
34364 else {
34365 reader._readIntoRequests.forEach(readIntoRequest => {
34366 readIntoRequest._errorSteps(e);
34367 });
34368 reader._readIntoRequests = new SimpleQueue();
34369 }
34370}
34371// Helper functions for the ReadableStream.
34372function streamBrandCheckException$1(name) {
34373 return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`);
34374}
34375
34376function convertQueuingStrategyInit(init, context) {
34377 assertDictionary(init, context);
34378 const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark;
34379 assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit');
34380 return {
34381 highWaterMark: convertUnrestrictedDouble(highWaterMark)
34382 };
34383}
34384
34385const byteLengthSizeFunction = function size(chunk) {
34386 return chunk.byteLength;
34387};
34388/**
34389 * A queuing strategy that counts the number of bytes in each chunk.
34390 *
34391 * @public
34392 */
34393class ByteLengthQueuingStrategy {
34394 constructor(options) {
34395 assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy');
34396 options = convertQueuingStrategyInit(options, 'First parameter');
34397 this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark;
34398 }
34399 /**
34400 * Returns the high water mark provided to the constructor.
34401 */
34402 get highWaterMark() {
34403 if (!IsByteLengthQueuingStrategy(this)) {
34404 throw byteLengthBrandCheckException('highWaterMark');
34405 }
34406 return this._byteLengthQueuingStrategyHighWaterMark;
34407 }
34408 /**
34409 * Measures the size of `chunk` by returning the value of its `byteLength` property.
34410 */
34411 get size() {
34412 if (!IsByteLengthQueuingStrategy(this)) {
34413 throw byteLengthBrandCheckException('size');
34414 }
34415 return byteLengthSizeFunction;
34416 }
34417}
34418Object.defineProperties(ByteLengthQueuingStrategy.prototype, {
34419 highWaterMark: { enumerable: true },
34420 size: { enumerable: true }
34421});
34422if (typeof SymbolPolyfill.toStringTag === 'symbol') {
34423 Object.defineProperty(ByteLengthQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
34424 value: 'ByteLengthQueuingStrategy',
34425 configurable: true
34426 });
34427}
34428// Helper functions for the ByteLengthQueuingStrategy.
34429function byteLengthBrandCheckException(name) {
34430 return new TypeError(`ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy`);
34431}
34432function IsByteLengthQueuingStrategy(x) {
34433 if (!typeIsObject(x)) {
34434 return false;
34435 }
34436 if (!Object.prototype.hasOwnProperty.call(x, '_byteLengthQueuingStrategyHighWaterMark')) {
34437 return false;
34438 }
34439 return true;
34440}
34441
34442const countSizeFunction = function size() {
34443 return 1;
34444};
34445/**
34446 * A queuing strategy that counts the number of chunks.
34447 *
34448 * @public
34449 */
34450class CountQueuingStrategy {
34451 constructor(options) {
34452 assertRequiredArgument(options, 1, 'CountQueuingStrategy');
34453 options = convertQueuingStrategyInit(options, 'First parameter');
34454 this._countQueuingStrategyHighWaterMark = options.highWaterMark;
34455 }
34456 /**
34457 * Returns the high water mark provided to the constructor.
34458 */
34459 get highWaterMark() {
34460 if (!IsCountQueuingStrategy(this)) {
34461 throw countBrandCheckException('highWaterMark');
34462 }
34463 return this._countQueuingStrategyHighWaterMark;
34464 }
34465 /**
34466 * Measures the size of `chunk` by always returning 1.
34467 * This ensures that the total queue size is a count of the number of chunks in the queue.
34468 */
34469 get size() {
34470 if (!IsCountQueuingStrategy(this)) {
34471 throw countBrandCheckException('size');
34472 }
34473 return countSizeFunction;
34474 }
34475}
34476Object.defineProperties(CountQueuingStrategy.prototype, {
34477 highWaterMark: { enumerable: true },
34478 size: { enumerable: true }
34479});
34480if (typeof SymbolPolyfill.toStringTag === 'symbol') {
34481 Object.defineProperty(CountQueuingStrategy.prototype, SymbolPolyfill.toStringTag, {
34482 value: 'CountQueuingStrategy',
34483 configurable: true
34484 });
34485}
34486// Helper functions for the CountQueuingStrategy.
34487function countBrandCheckException(name) {
34488 return new TypeError(`CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy`);
34489}
34490function IsCountQueuingStrategy(x) {
34491 if (!typeIsObject(x)) {
34492 return false;
34493 }
34494 if (!Object.prototype.hasOwnProperty.call(x, '_countQueuingStrategyHighWaterMark')) {
34495 return false;
34496 }
34497 return true;
34498}
34499
34500function convertTransformer(original, context) {
34501 assertDictionary(original, context);
34502 const flush = original === null || original === void 0 ? void 0 : original.flush;
34503 const readableType = original === null || original === void 0 ? void 0 : original.readableType;
34504 const start = original === null || original === void 0 ? void 0 : original.start;
34505 const transform = original === null || original === void 0 ? void 0 : original.transform;
34506 const writableType = original === null || original === void 0 ? void 0 : original.writableType;
34507 return {
34508 flush: flush === undefined ?
34509 undefined :
34510 convertTransformerFlushCallback(flush, original, `${context} has member 'flush' that`),
34511 readableType,
34512 start: start === undefined ?
34513 undefined :
34514 convertTransformerStartCallback(start, original, `${context} has member 'start' that`),
34515 transform: transform === undefined ?
34516 undefined :
34517 convertTransformerTransformCallback(transform, original, `${context} has member 'transform' that`),
34518 writableType
34519 };
34520}
34521function convertTransformerFlushCallback(fn, original, context) {
34522 assertFunction(fn, context);
34523 return (controller) => promiseCall(fn, original, [controller]);
34524}
34525function convertTransformerStartCallback(fn, original, context) {
34526 assertFunction(fn, context);
34527 return (controller) => reflectCall(fn, original, [controller]);
34528}
34529function convertTransformerTransformCallback(fn, original, context) {
34530 assertFunction(fn, context);
34531 return (chunk, controller) => promiseCall(fn, original, [chunk, controller]);
34532}
34533
34534// Class TransformStream
34535/**
34536 * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream},
34537 * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side.
34538 * In a manner specific to the transform stream in question, writes to the writable side result in new data being
34539 * made available for reading from the readable side.
34540 *
34541 * @public
34542 */
34543class TransformStream$1 {
34544 constructor(rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {}) {
34545 if (rawTransformer === undefined) {
34546 rawTransformer = null;
34547 }
34548 const writableStrategy = convertQueuingStrategy(rawWritableStrategy, 'Second parameter');
34549 const readableStrategy = convertQueuingStrategy(rawReadableStrategy, 'Third parameter');
34550 const transformer = convertTransformer(rawTransformer, 'First parameter');
34551 if (transformer.readableType !== undefined) {
34552 throw new RangeError('Invalid readableType specified');
34553 }
34554 if (transformer.writableType !== undefined) {
34555 throw new RangeError('Invalid writableType specified');
34556 }
34557 const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0);
34558 const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy);
34559 const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1);
34560 const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy);
34561 let startPromise_resolve;
34562 const startPromise = newPromise(resolve => {
34563 startPromise_resolve = resolve;
34564 });
34565 InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
34566 SetUpTransformStreamDefaultControllerFromTransformer(this, transformer);
34567 if (transformer.start !== undefined) {
34568 startPromise_resolve(transformer.start(this._transformStreamController));
34569 }
34570 else {
34571 startPromise_resolve(undefined);
34572 }
34573 }
34574 /**
34575 * The readable side of the transform stream.
34576 */
34577 get readable() {
34578 if (!IsTransformStream(this)) {
34579 throw streamBrandCheckException('readable');
34580 }
34581 return this._readable;
34582 }
34583 /**
34584 * The writable side of the transform stream.
34585 */
34586 get writable() {
34587 if (!IsTransformStream(this)) {
34588 throw streamBrandCheckException('writable');
34589 }
34590 return this._writable;
34591 }
34592}
34593Object.defineProperties(TransformStream$1.prototype, {
34594 readable: { enumerable: true },
34595 writable: { enumerable: true }
34596});
34597if (typeof SymbolPolyfill.toStringTag === 'symbol') {
34598 Object.defineProperty(TransformStream$1.prototype, SymbolPolyfill.toStringTag, {
34599 value: 'TransformStream',
34600 configurable: true
34601 });
34602}
34603function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) {
34604 function startAlgorithm() {
34605 return startPromise;
34606 }
34607 function writeAlgorithm(chunk) {
34608 return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk);
34609 }
34610 function abortAlgorithm(reason) {
34611 return TransformStreamDefaultSinkAbortAlgorithm(stream, reason);
34612 }
34613 function closeAlgorithm() {
34614 return TransformStreamDefaultSinkCloseAlgorithm(stream);
34615 }
34616 stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm);
34617 function pullAlgorithm() {
34618 return TransformStreamDefaultSourcePullAlgorithm(stream);
34619 }
34620 function cancelAlgorithm(reason) {
34621 TransformStreamErrorWritableAndUnblockWrite(stream, reason);
34622 return promiseResolvedWith(undefined);
34623 }
34624 stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm);
34625 // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure.
34626 stream._backpressure = undefined;
34627 stream._backpressureChangePromise = undefined;
34628 stream._backpressureChangePromise_resolve = undefined;
34629 TransformStreamSetBackpressure(stream, true);
34630 stream._transformStreamController = undefined;
34631}
34632function IsTransformStream(x) {
34633 if (!typeIsObject(x)) {
34634 return false;
34635 }
34636 if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) {
34637 return false;
34638 }
34639 return true;
34640}
34641// This is a no-op if both sides are already errored.
34642function TransformStreamError(stream, e) {
34643 ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e);
34644 TransformStreamErrorWritableAndUnblockWrite(stream, e);
34645}
34646function TransformStreamErrorWritableAndUnblockWrite(stream, e) {
34647 TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController);
34648 WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e);
34649 if (stream._backpressure) {
34650 // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure()
34651 // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time
34652 // _backpressure is set.
34653 TransformStreamSetBackpressure(stream, false);
34654 }
34655}
34656function TransformStreamSetBackpressure(stream, backpressure) {
34657 // Passes also when called during construction.
34658 if (stream._backpressureChangePromise !== undefined) {
34659 stream._backpressureChangePromise_resolve();
34660 }
34661 stream._backpressureChangePromise = newPromise(resolve => {
34662 stream._backpressureChangePromise_resolve = resolve;
34663 });
34664 stream._backpressure = backpressure;
34665}
34666// Class TransformStreamDefaultController
34667/**
34668 * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}.
34669 *
34670 * @public
34671 */
34672class TransformStreamDefaultController {
34673 constructor() {
34674 throw new TypeError('Illegal constructor');
34675 }
34676 /**
34677 * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full.
34678 */
34679 get desiredSize() {
34680 if (!IsTransformStreamDefaultController(this)) {
34681 throw defaultControllerBrandCheckException('desiredSize');
34682 }
34683 const readableController = this._controlledTransformStream._readable._readableStreamController;
34684 return ReadableStreamDefaultControllerGetDesiredSize(readableController);
34685 }
34686 enqueue(chunk = undefined) {
34687 if (!IsTransformStreamDefaultController(this)) {
34688 throw defaultControllerBrandCheckException('enqueue');
34689 }
34690 TransformStreamDefaultControllerEnqueue(this, chunk);
34691 }
34692 /**
34693 * Errors both the readable side and the writable side of the controlled transform stream, making all future
34694 * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded.
34695 */
34696 error(reason = undefined) {
34697 if (!IsTransformStreamDefaultController(this)) {
34698 throw defaultControllerBrandCheckException('error');
34699 }
34700 TransformStreamDefaultControllerError(this, reason);
34701 }
34702 /**
34703 * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the
34704 * transformer only needs to consume a portion of the chunks written to the writable side.
34705 */
34706 terminate() {
34707 if (!IsTransformStreamDefaultController(this)) {
34708 throw defaultControllerBrandCheckException('terminate');
34709 }
34710 TransformStreamDefaultControllerTerminate(this);
34711 }
34712}
34713Object.defineProperties(TransformStreamDefaultController.prototype, {
34714 enqueue: { enumerable: true },
34715 error: { enumerable: true },
34716 terminate: { enumerable: true },
34717 desiredSize: { enumerable: true }
34718});
34719if (typeof SymbolPolyfill.toStringTag === 'symbol') {
34720 Object.defineProperty(TransformStreamDefaultController.prototype, SymbolPolyfill.toStringTag, {
34721 value: 'TransformStreamDefaultController',
34722 configurable: true
34723 });
34724}
34725// Transform Stream Default Controller Abstract Operations
34726function IsTransformStreamDefaultController(x) {
34727 if (!typeIsObject(x)) {
34728 return false;
34729 }
34730 if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) {
34731 return false;
34732 }
34733 return true;
34734}
34735function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) {
34736 controller._controlledTransformStream = stream;
34737 stream._transformStreamController = controller;
34738 controller._transformAlgorithm = transformAlgorithm;
34739 controller._flushAlgorithm = flushAlgorithm;
34740}
34741function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) {
34742 const controller = Object.create(TransformStreamDefaultController.prototype);
34743 let transformAlgorithm = (chunk) => {
34744 try {
34745 TransformStreamDefaultControllerEnqueue(controller, chunk);
34746 return promiseResolvedWith(undefined);
34747 }
34748 catch (transformResultE) {
34749 return promiseRejectedWith(transformResultE);
34750 }
34751 };
34752 let flushAlgorithm = () => promiseResolvedWith(undefined);
34753 if (transformer.transform !== undefined) {
34754 transformAlgorithm = chunk => transformer.transform(chunk, controller);
34755 }
34756 if (transformer.flush !== undefined) {
34757 flushAlgorithm = () => transformer.flush(controller);
34758 }
34759 SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
34760}
34761function TransformStreamDefaultControllerClearAlgorithms(controller) {
34762 controller._transformAlgorithm = undefined;
34763 controller._flushAlgorithm = undefined;
34764}
34765function TransformStreamDefaultControllerEnqueue(controller, chunk) {
34766 const stream = controller._controlledTransformStream;
34767 const readableController = stream._readable._readableStreamController;
34768 if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) {
34769 throw new TypeError('Readable side is not in a state that permits enqueue');
34770 }
34771 // We throttle transform invocations based on the backpressure of the ReadableStream, but we still
34772 // accept TransformStreamDefaultControllerEnqueue() calls.
34773 try {
34774 ReadableStreamDefaultControllerEnqueue(readableController, chunk);
34775 }
34776 catch (e) {
34777 // This happens when readableStrategy.size() throws.
34778 TransformStreamErrorWritableAndUnblockWrite(stream, e);
34779 throw stream._readable._storedError;
34780 }
34781 const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController);
34782 if (backpressure !== stream._backpressure) {
34783 TransformStreamSetBackpressure(stream, true);
34784 }
34785}
34786function TransformStreamDefaultControllerError(controller, e) {
34787 TransformStreamError(controller._controlledTransformStream, e);
34788}
34789function TransformStreamDefaultControllerPerformTransform(controller, chunk) {
34790 const transformPromise = controller._transformAlgorithm(chunk);
34791 return transformPromiseWith(transformPromise, undefined, r => {
34792 TransformStreamError(controller._controlledTransformStream, r);
34793 throw r;
34794 });
34795}
34796function TransformStreamDefaultControllerTerminate(controller) {
34797 const stream = controller._controlledTransformStream;
34798 const readableController = stream._readable._readableStreamController;
34799 ReadableStreamDefaultControllerClose(readableController);
34800 const error = new TypeError('TransformStream terminated');
34801 TransformStreamErrorWritableAndUnblockWrite(stream, error);
34802}
34803// TransformStreamDefaultSink Algorithms
34804function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) {
34805 const controller = stream._transformStreamController;
34806 if (stream._backpressure) {
34807 const backpressureChangePromise = stream._backpressureChangePromise;
34808 return transformPromiseWith(backpressureChangePromise, () => {
34809 const writable = stream._writable;
34810 const state = writable._state;
34811 if (state === 'erroring') {
34812 throw writable._storedError;
34813 }
34814 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
34815 });
34816 }
34817 return TransformStreamDefaultControllerPerformTransform(controller, chunk);
34818}
34819function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) {
34820 // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already
34821 // errored.
34822 TransformStreamError(stream, reason);
34823 return promiseResolvedWith(undefined);
34824}
34825function TransformStreamDefaultSinkCloseAlgorithm(stream) {
34826 // stream._readable cannot change after construction, so caching it across a call to user code is safe.
34827 const readable = stream._readable;
34828 const controller = stream._transformStreamController;
34829 const flushPromise = controller._flushAlgorithm();
34830 TransformStreamDefaultControllerClearAlgorithms(controller);
34831 // Return a promise that is fulfilled with undefined on success.
34832 return transformPromiseWith(flushPromise, () => {
34833 if (readable._state === 'errored') {
34834 throw readable._storedError;
34835 }
34836 ReadableStreamDefaultControllerClose(readable._readableStreamController);
34837 }, r => {
34838 TransformStreamError(stream, r);
34839 throw readable._storedError;
34840 });
34841}
34842// TransformStreamDefaultSource Algorithms
34843function TransformStreamDefaultSourcePullAlgorithm(stream) {
34844 // Invariant. Enforced by the promises returned by start() and pull().
34845 TransformStreamSetBackpressure(stream, false);
34846 // Prevent the next pull() call until there is backpressure.
34847 return stream._backpressureChangePromise;
34848}
34849// Helper functions for the TransformStreamDefaultController.
34850function defaultControllerBrandCheckException(name) {
34851 return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`);
34852}
34853// Helper functions for the TransformStream.
34854function streamBrandCheckException(name) {
34855 return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`);
34856}
34857
34858var ponyfill_es6 = /*#__PURE__*/Object.freeze({
34859 __proto__: null,
34860 ByteLengthQueuingStrategy: ByteLengthQueuingStrategy,
34861 CountQueuingStrategy: CountQueuingStrategy,
34862 ReadableByteStreamController: ReadableByteStreamController,
34863 ReadableStream: ReadableStream$1,
34864 ReadableStreamBYOBReader: ReadableStreamBYOBReader,
34865 ReadableStreamBYOBRequest: ReadableStreamBYOBRequest,
34866 ReadableStreamDefaultController: ReadableStreamDefaultController,
34867 ReadableStreamDefaultReader: ReadableStreamDefaultReader,
34868 TransformStream: TransformStream$1,
34869 TransformStreamDefaultController: TransformStreamDefaultController,
34870 WritableStream: WritableStream$1,
34871 WritableStreamDefaultController: WritableStreamDefaultController,
34872 WritableStreamDefaultWriter: WritableStreamDefaultWriter
34873});
34874
34875/*! *****************************************************************************
34876Copyright (c) Microsoft Corporation.
34877
34878Permission to use, copy, modify, and/or distribute this software for any
34879purpose with or without fee is hereby granted.
34880
34881THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
34882REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
34883AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
34884INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
34885LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
34886OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
34887PERFORMANCE OF THIS SOFTWARE.
34888***************************************************************************** */
34889/* global Reflect, Promise */
34890
34891var extendStatics = function(d, b) {
34892 extendStatics = Object.setPrototypeOf ||
34893 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
34894 function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
34895 return extendStatics(d, b);
34896};
34897
34898function __extends(d, b) {
34899 if (typeof b !== "function" && b !== null)
34900 throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
34901 extendStatics(d, b);
34902 function __() { this.constructor = d; }
34903 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
34904}
34905
34906function assert$1(test) {
34907 if (!test) {
34908 throw new TypeError('Assertion failed');
34909 }
34910}
34911
34912function noop$1() {
34913 return;
34914}
34915function typeIsObject$1(x) {
34916 return (typeof x === 'object' && x !== null) || typeof x === 'function';
34917}
34918
34919function isStreamConstructor(ctor) {
34920 if (typeof ctor !== 'function') {
34921 return false;
34922 }
34923 var startCalled = false;
34924 try {
34925 new ctor({
34926 start: function () {
34927 startCalled = true;
34928 }
34929 });
34930 }
34931 catch (e) {
34932 // ignore
34933 }
34934 return startCalled;
34935}
34936function isReadableStream(readable) {
34937 if (!typeIsObject$1(readable)) {
34938 return false;
34939 }
34940 if (typeof readable.getReader !== 'function') {
34941 return false;
34942 }
34943 return true;
34944}
34945function isReadableStreamConstructor(ctor) {
34946 if (!isStreamConstructor(ctor)) {
34947 return false;
34948 }
34949 if (!isReadableStream(new ctor())) {
34950 return false;
34951 }
34952 return true;
34953}
34954function isWritableStream(writable) {
34955 if (!typeIsObject$1(writable)) {
34956 return false;
34957 }
34958 if (typeof writable.getWriter !== 'function') {
34959 return false;
34960 }
34961 return true;
34962}
34963function isWritableStreamConstructor(ctor) {
34964 if (!isStreamConstructor(ctor)) {
34965 return false;
34966 }
34967 if (!isWritableStream(new ctor())) {
34968 return false;
34969 }
34970 return true;
34971}
34972function isTransformStream(transform) {
34973 if (!typeIsObject$1(transform)) {
34974 return false;
34975 }
34976 if (!isReadableStream(transform.readable)) {
34977 return false;
34978 }
34979 if (!isWritableStream(transform.writable)) {
34980 return false;
34981 }
34982 return true;
34983}
34984function isTransformStreamConstructor(ctor) {
34985 if (!isStreamConstructor(ctor)) {
34986 return false;
34987 }
34988 if (!isTransformStream(new ctor())) {
34989 return false;
34990 }
34991 return true;
34992}
34993function supportsByobReader(readable) {
34994 try {
34995 var reader = readable.getReader({ mode: 'byob' });
34996 reader.releaseLock();
34997 return true;
34998 }
34999 catch (_a) {
35000 return false;
35001 }
35002}
35003function supportsByteSource(ctor) {
35004 try {
35005 new ctor({ type: 'bytes' });
35006 return true;
35007 }
35008 catch (_a) {
35009 return false;
35010 }
35011}
35012
35013function createReadableStreamWrapper(ctor) {
35014 assert$1(isReadableStreamConstructor(ctor));
35015 var byteSourceSupported = supportsByteSource(ctor);
35016 return function (readable, _a) {
35017 var _b = _a === void 0 ? {} : _a, type = _b.type;
35018 type = parseReadableType(type);
35019 if (type === 'bytes' && !byteSourceSupported) {
35020 type = undefined;
35021 }
35022 if (readable.constructor === ctor) {
35023 if (type !== 'bytes' || supportsByobReader(readable)) {
35024 return readable;
35025 }
35026 }
35027 if (type === 'bytes') {
35028 var source = createWrappingReadableSource(readable, { type: type });
35029 return new ctor(source);
35030 }
35031 else {
35032 var source = createWrappingReadableSource(readable);
35033 return new ctor(source);
35034 }
35035 };
35036}
35037function createWrappingReadableSource(readable, _a) {
35038 var _b = _a === void 0 ? {} : _a, type = _b.type;
35039 assert$1(isReadableStream(readable));
35040 assert$1(readable.locked === false);
35041 type = parseReadableType(type);
35042 var source;
35043 if (type === 'bytes') {
35044 source = new WrappingReadableByteStreamSource(readable);
35045 }
35046 else {
35047 source = new WrappingReadableStreamDefaultSource(readable);
35048 }
35049 return source;
35050}
35051function parseReadableType(type) {
35052 var typeString = String(type);
35053 if (typeString === 'bytes') {
35054 return typeString;
35055 }
35056 else if (type === undefined) {
35057 return type;
35058 }
35059 else {
35060 throw new RangeError('Invalid type is specified');
35061 }
35062}
35063var AbstractWrappingReadableStreamSource = /** @class */ (function () {
35064 function AbstractWrappingReadableStreamSource(underlyingStream) {
35065 this._underlyingReader = undefined;
35066 this._readerMode = undefined;
35067 this._readableStreamController = undefined;
35068 this._pendingRead = undefined;
35069 this._underlyingStream = underlyingStream;
35070 // always keep a reader attached to detect close/error
35071 this._attachDefaultReader();
35072 }
35073 AbstractWrappingReadableStreamSource.prototype.start = function (controller) {
35074 this._readableStreamController = controller;
35075 };
35076 AbstractWrappingReadableStreamSource.prototype.cancel = function (reason) {
35077 assert$1(this._underlyingReader !== undefined);
35078 return this._underlyingReader.cancel(reason);
35079 };
35080 AbstractWrappingReadableStreamSource.prototype._attachDefaultReader = function () {
35081 if (this._readerMode === "default" /* DEFAULT */) {
35082 return;
35083 }
35084 this._detachReader();
35085 var reader = this._underlyingStream.getReader();
35086 this._readerMode = "default" /* DEFAULT */;
35087 this._attachReader(reader);
35088 };
35089 AbstractWrappingReadableStreamSource.prototype._attachReader = function (reader) {
35090 var _this = this;
35091 assert$1(this._underlyingReader === undefined);
35092 this._underlyingReader = reader;
35093 var closed = this._underlyingReader.closed;
35094 if (!closed) {
35095 return;
35096 }
35097 closed
35098 .then(function () { return _this._finishPendingRead(); })
35099 .then(function () {
35100 if (reader === _this._underlyingReader) {
35101 _this._readableStreamController.close();
35102 }
35103 }, function (reason) {
35104 if (reader === _this._underlyingReader) {
35105 _this._readableStreamController.error(reason);
35106 }
35107 })
35108 .catch(noop$1);
35109 };
35110 AbstractWrappingReadableStreamSource.prototype._detachReader = function () {
35111 if (this._underlyingReader === undefined) {
35112 return;
35113 }
35114 this._underlyingReader.releaseLock();
35115 this._underlyingReader = undefined;
35116 this._readerMode = undefined;
35117 };
35118 AbstractWrappingReadableStreamSource.prototype._pullWithDefaultReader = function () {
35119 var _this = this;
35120 this._attachDefaultReader();
35121 // TODO Backpressure?
35122 var read = this._underlyingReader.read()
35123 .then(function (result) {
35124 var controller = _this._readableStreamController;
35125 if (result.done) {
35126 _this._tryClose();
35127 }
35128 else {
35129 controller.enqueue(result.value);
35130 }
35131 });
35132 this._setPendingRead(read);
35133 return read;
35134 };
35135 AbstractWrappingReadableStreamSource.prototype._tryClose = function () {
35136 try {
35137 this._readableStreamController.close();
35138 }
35139 catch (_a) {
35140 // already errored or closed
35141 }
35142 };
35143 AbstractWrappingReadableStreamSource.prototype._setPendingRead = function (readPromise) {
35144 var _this = this;
35145 var pendingRead;
35146 var finishRead = function () {
35147 if (_this._pendingRead === pendingRead) {
35148 _this._pendingRead = undefined;
35149 }
35150 };
35151 this._pendingRead = pendingRead = readPromise.then(finishRead, finishRead);
35152 };
35153 AbstractWrappingReadableStreamSource.prototype._finishPendingRead = function () {
35154 var _this = this;
35155 if (!this._pendingRead) {
35156 return undefined;
35157 }
35158 var afterRead = function () { return _this._finishPendingRead(); };
35159 return this._pendingRead.then(afterRead, afterRead);
35160 };
35161 return AbstractWrappingReadableStreamSource;
35162}());
35163var WrappingReadableStreamDefaultSource = /** @class */ (function (_super) {
35164 __extends(WrappingReadableStreamDefaultSource, _super);
35165 function WrappingReadableStreamDefaultSource() {
35166 return _super !== null && _super.apply(this, arguments) || this;
35167 }
35168 WrappingReadableStreamDefaultSource.prototype.pull = function () {
35169 return this._pullWithDefaultReader();
35170 };
35171 return WrappingReadableStreamDefaultSource;
35172}(AbstractWrappingReadableStreamSource));
35173function toUint8Array(view) {
35174 return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
35175}
35176function copyArrayBufferView(from, to) {
35177 var fromArray = toUint8Array(from);
35178 var toArray = toUint8Array(to);
35179 toArray.set(fromArray, 0);
35180}
35181var WrappingReadableByteStreamSource = /** @class */ (function (_super) {
35182 __extends(WrappingReadableByteStreamSource, _super);
35183 function WrappingReadableByteStreamSource(underlyingStream) {
35184 var _this = this;
35185 var supportsByob = supportsByobReader(underlyingStream);
35186 _this = _super.call(this, underlyingStream) || this;
35187 _this._supportsByob = supportsByob;
35188 return _this;
35189 }
35190 Object.defineProperty(WrappingReadableByteStreamSource.prototype, "type", {
35191 get: function () {
35192 return 'bytes';
35193 },
35194 enumerable: false,
35195 configurable: true
35196 });
35197 WrappingReadableByteStreamSource.prototype._attachByobReader = function () {
35198 if (this._readerMode === "byob" /* BYOB */) {
35199 return;
35200 }
35201 assert$1(this._supportsByob);
35202 this._detachReader();
35203 var reader = this._underlyingStream.getReader({ mode: 'byob' });
35204 this._readerMode = "byob" /* BYOB */;
35205 this._attachReader(reader);
35206 };
35207 WrappingReadableByteStreamSource.prototype.pull = function () {
35208 if (this._supportsByob) {
35209 var byobRequest = this._readableStreamController.byobRequest;
35210 if (byobRequest) {
35211 return this._pullWithByobRequest(byobRequest);
35212 }
35213 }
35214 return this._pullWithDefaultReader();
35215 };
35216 WrappingReadableByteStreamSource.prototype._pullWithByobRequest = function (byobRequest) {
35217 var _this = this;
35218 this._attachByobReader();
35219 // reader.read(view) detaches the input view, therefore we cannot pass byobRequest.view directly
35220 // create a separate buffer to read into, then copy that to byobRequest.view
35221 var buffer = new Uint8Array(byobRequest.view.byteLength);
35222 // TODO Backpressure?
35223 var read = this._underlyingReader.read(buffer)
35224 .then(function (result) {
35225 _this._readableStreamController;
35226 if (result.done) {
35227 _this._tryClose();
35228 byobRequest.respond(0);
35229 }
35230 else {
35231 copyArrayBufferView(result.value, byobRequest.view);
35232 byobRequest.respond(result.value.byteLength);
35233 }
35234 });
35235 this._setPendingRead(read);
35236 return read;
35237 };
35238 return WrappingReadableByteStreamSource;
35239}(AbstractWrappingReadableStreamSource));
35240
35241function createWritableStreamWrapper(ctor) {
35242 assert$1(isWritableStreamConstructor(ctor));
35243 return function (writable) {
35244 if (writable.constructor === ctor) {
35245 return writable;
35246 }
35247 var sink = createWrappingWritableSink(writable);
35248 return new ctor(sink);
35249 };
35250}
35251function createWrappingWritableSink(writable) {
35252 assert$1(isWritableStream(writable));
35253 assert$1(writable.locked === false);
35254 var writer = writable.getWriter();
35255 return new WrappingWritableStreamSink(writer);
35256}
35257var WrappingWritableStreamSink = /** @class */ (function () {
35258 function WrappingWritableStreamSink(underlyingWriter) {
35259 var _this = this;
35260 this._writableStreamController = undefined;
35261 this._pendingWrite = undefined;
35262 this._state = "writable" /* WRITABLE */;
35263 this._storedError = undefined;
35264 this._underlyingWriter = underlyingWriter;
35265 this._errorPromise = new Promise(function (resolve, reject) {
35266 _this._errorPromiseReject = reject;
35267 });
35268 this._errorPromise.catch(noop$1);
35269 }
35270 WrappingWritableStreamSink.prototype.start = function (controller) {
35271 var _this = this;
35272 this._writableStreamController = controller;
35273 this._underlyingWriter.closed
35274 .then(function () {
35275 _this._state = "closed" /* CLOSED */;
35276 })
35277 .catch(function (reason) { return _this._finishErroring(reason); });
35278 };
35279 WrappingWritableStreamSink.prototype.write = function (chunk) {
35280 var _this = this;
35281 var writer = this._underlyingWriter;
35282 // Detect past errors
35283 if (writer.desiredSize === null) {
35284 return writer.ready;
35285 }
35286 var writeRequest = writer.write(chunk);
35287 // Detect future errors
35288 writeRequest.catch(function (reason) { return _this._finishErroring(reason); });
35289 writer.ready.catch(function (reason) { return _this._startErroring(reason); });
35290 // Reject write when errored
35291 var write = Promise.race([writeRequest, this._errorPromise]);
35292 this._setPendingWrite(write);
35293 return write;
35294 };
35295 WrappingWritableStreamSink.prototype.close = function () {
35296 var _this = this;
35297 if (this._pendingWrite === undefined) {
35298 return this._underlyingWriter.close();
35299 }
35300 return this._finishPendingWrite().then(function () { return _this.close(); });
35301 };
35302 WrappingWritableStreamSink.prototype.abort = function (reason) {
35303 if (this._state === "errored" /* ERRORED */) {
35304 return undefined;
35305 }
35306 var writer = this._underlyingWriter;
35307 return writer.abort(reason);
35308 };
35309 WrappingWritableStreamSink.prototype._setPendingWrite = function (writePromise) {
35310 var _this = this;
35311 var pendingWrite;
35312 var finishWrite = function () {
35313 if (_this._pendingWrite === pendingWrite) {
35314 _this._pendingWrite = undefined;
35315 }
35316 };
35317 this._pendingWrite = pendingWrite = writePromise.then(finishWrite, finishWrite);
35318 };
35319 WrappingWritableStreamSink.prototype._finishPendingWrite = function () {
35320 var _this = this;
35321 if (this._pendingWrite === undefined) {
35322 return Promise.resolve();
35323 }
35324 var afterWrite = function () { return _this._finishPendingWrite(); };
35325 return this._pendingWrite.then(afterWrite, afterWrite);
35326 };
35327 WrappingWritableStreamSink.prototype._startErroring = function (reason) {
35328 var _this = this;
35329 if (this._state === "writable" /* WRITABLE */) {
35330 this._state = "erroring" /* ERRORING */;
35331 this._storedError = reason;
35332 var afterWrite = function () { return _this._finishErroring(reason); };
35333 if (this._pendingWrite === undefined) {
35334 afterWrite();
35335 }
35336 else {
35337 this._finishPendingWrite().then(afterWrite, afterWrite);
35338 }
35339 this._writableStreamController.error(reason);
35340 }
35341 };
35342 WrappingWritableStreamSink.prototype._finishErroring = function (reason) {
35343 if (this._state === "writable" /* WRITABLE */) {
35344 this._startErroring(reason);
35345 }
35346 if (this._state === "erroring" /* ERRORING */) {
35347 this._state = "errored" /* ERRORED */;
35348 this._errorPromiseReject(this._storedError);
35349 }
35350 };
35351 return WrappingWritableStreamSink;
35352}());
35353
35354function createTransformStreamWrapper(ctor) {
35355 assert$1(isTransformStreamConstructor(ctor));
35356 return function (transform) {
35357 if (transform.constructor === ctor) {
35358 return transform;
35359 }
35360 var transformer = createWrappingTransformer(transform);
35361 return new ctor(transformer);
35362 };
35363}
35364function createWrappingTransformer(transform) {
35365 assert$1(isTransformStream(transform));
35366 var readable = transform.readable, writable = transform.writable;
35367 assert$1(readable.locked === false);
35368 assert$1(writable.locked === false);
35369 var reader = readable.getReader();
35370 var writer;
35371 try {
35372 writer = writable.getWriter();
35373 }
35374 catch (e) {
35375 reader.releaseLock(); // do not leak reader
35376 throw e;
35377 }
35378 return new WrappingTransformStreamTransformer(reader, writer);
35379}
35380var WrappingTransformStreamTransformer = /** @class */ (function () {
35381 function WrappingTransformStreamTransformer(reader, writer) {
35382 var _this = this;
35383 this._transformStreamController = undefined;
35384 this._onRead = function (result) {
35385 if (result.done) {
35386 return;
35387 }
35388 _this._transformStreamController.enqueue(result.value);
35389 return _this._reader.read().then(_this._onRead);
35390 };
35391 this._onError = function (reason) {
35392 _this._flushReject(reason);
35393 _this._transformStreamController.error(reason);
35394 _this._reader.cancel(reason).catch(noop$1);
35395 _this._writer.abort(reason).catch(noop$1);
35396 };
35397 this._onTerminate = function () {
35398 _this._flushResolve();
35399 _this._transformStreamController.terminate();
35400 var error = new TypeError('TransformStream terminated');
35401 _this._writer.abort(error).catch(noop$1);
35402 };
35403 this._reader = reader;
35404 this._writer = writer;
35405 this._flushPromise = new Promise(function (resolve, reject) {
35406 _this._flushResolve = resolve;
35407 _this._flushReject = reject;
35408 });
35409 }
35410 WrappingTransformStreamTransformer.prototype.start = function (controller) {
35411 this._transformStreamController = controller;
35412 this._reader.read()
35413 .then(this._onRead)
35414 .then(this._onTerminate, this._onError);
35415 var readerClosed = this._reader.closed;
35416 if (readerClosed) {
35417 readerClosed
35418 .then(this._onTerminate, this._onError);
35419 }
35420 };
35421 WrappingTransformStreamTransformer.prototype.transform = function (chunk) {
35422 return this._writer.write(chunk);
35423 };
35424 WrappingTransformStreamTransformer.prototype.flush = function () {
35425 var _this = this;
35426 return this._writer.close()
35427 .then(function () { return _this._flushPromise; });
35428 };
35429 return WrappingTransformStreamTransformer;
35430}());
35431
35432var webStreamsAdapter = /*#__PURE__*/Object.freeze({
35433 __proto__: null,
35434 createReadableStreamWrapper: createReadableStreamWrapper,
35435 createTransformStreamWrapper: createTransformStreamWrapper,
35436 createWrappingReadableSource: createWrappingReadableSource,
35437 createWrappingTransformer: createWrappingTransformer,
35438 createWrappingWritableSink: createWrappingWritableSink,
35439 createWritableStreamWrapper: createWritableStreamWrapper
35440});
35441
35442var bn = createCommonjsModule(function (module) {
35443(function (module, exports) {
35444
35445 // Utils
35446 function assert (val, msg) {
35447 if (!val) throw new Error(msg || 'Assertion failed');
35448 }
35449
35450 // Could use `inherits` module, but don't want to move from single file
35451 // architecture yet.
35452 function inherits (ctor, superCtor) {
35453 ctor.super_ = superCtor;
35454 var TempCtor = function () {};
35455 TempCtor.prototype = superCtor.prototype;
35456 ctor.prototype = new TempCtor();
35457 ctor.prototype.constructor = ctor;
35458 }
35459
35460 // BN
35461
35462 function BN (number, base, endian) {
35463 if (BN.isBN(number)) {
35464 return number;
35465 }
35466
35467 this.negative = 0;
35468 this.words = null;
35469 this.length = 0;
35470
35471 // Reduction context
35472 this.red = null;
35473
35474 if (number !== null) {
35475 if (base === 'le' || base === 'be') {
35476 endian = base;
35477 base = 10;
35478 }
35479
35480 this._init(number || 0, base || 10, endian || 'be');
35481 }
35482 }
35483 if (typeof module === 'object') {
35484 module.exports = BN;
35485 } else {
35486 exports.BN = BN;
35487 }
35488
35489 BN.BN = BN;
35490 BN.wordSize = 26;
35491
35492 var Buffer;
35493 try {
35494 Buffer = buffer.Buffer;
35495 } catch (e) {
35496 }
35497
35498 BN.isBN = function isBN (num) {
35499 if (num instanceof BN) {
35500 return true;
35501 }
35502
35503 return num !== null && typeof num === 'object' &&
35504 num.constructor.wordSize === BN.wordSize && Array.isArray(num.words);
35505 };
35506
35507 BN.max = function max (left, right) {
35508 if (left.cmp(right) > 0) return left;
35509 return right;
35510 };
35511
35512 BN.min = function min (left, right) {
35513 if (left.cmp(right) < 0) return left;
35514 return right;
35515 };
35516
35517 BN.prototype._init = function init (number, base, endian) {
35518 if (typeof number === 'number') {
35519 return this._initNumber(number, base, endian);
35520 }
35521
35522 if (typeof number === 'object') {
35523 return this._initArray(number, base, endian);
35524 }
35525
35526 if (base === 'hex') {
35527 base = 16;
35528 }
35529 assert(base === (base | 0) && base >= 2 && base <= 36);
35530
35531 number = number.toString().replace(/\s+/g, '');
35532 var start = 0;
35533 if (number[0] === '-') {
35534 start++;
35535 }
35536
35537 if (base === 16) {
35538 this._parseHex(number, start);
35539 } else {
35540 this._parseBase(number, base, start);
35541 }
35542
35543 if (number[0] === '-') {
35544 this.negative = 1;
35545 }
35546
35547 this.strip();
35548
35549 if (endian !== 'le') return;
35550
35551 this._initArray(this.toArray(), base, endian);
35552 };
35553
35554 BN.prototype._initNumber = function _initNumber (number, base, endian) {
35555 if (number < 0) {
35556 this.negative = 1;
35557 number = -number;
35558 }
35559 if (number < 0x4000000) {
35560 this.words = [ number & 0x3ffffff ];
35561 this.length = 1;
35562 } else if (number < 0x10000000000000) {
35563 this.words = [
35564 number & 0x3ffffff,
35565 (number / 0x4000000) & 0x3ffffff
35566 ];
35567 this.length = 2;
35568 } else {
35569 assert(number < 0x20000000000000); // 2 ^ 53 (unsafe)
35570 this.words = [
35571 number & 0x3ffffff,
35572 (number / 0x4000000) & 0x3ffffff,
35573 1
35574 ];
35575 this.length = 3;
35576 }
35577
35578 if (endian !== 'le') return;
35579
35580 // Reverse the bytes
35581 this._initArray(this.toArray(), base, endian);
35582 };
35583
35584 BN.prototype._initArray = function _initArray (number, base, endian) {
35585 // Perhaps a Uint8Array
35586 assert(typeof number.length === 'number');
35587 if (number.length <= 0) {
35588 this.words = [ 0 ];
35589 this.length = 1;
35590 return this;
35591 }
35592
35593 this.length = Math.ceil(number.length / 3);
35594 this.words = new Array(this.length);
35595 for (var i = 0; i < this.length; i++) {
35596 this.words[i] = 0;
35597 }
35598
35599 var j, w;
35600 var off = 0;
35601 if (endian === 'be') {
35602 for (i = number.length - 1, j = 0; i >= 0; i -= 3) {
35603 w = number[i] | (number[i - 1] << 8) | (number[i - 2] << 16);
35604 this.words[j] |= (w << off) & 0x3ffffff;
35605 this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
35606 off += 24;
35607 if (off >= 26) {
35608 off -= 26;
35609 j++;
35610 }
35611 }
35612 } else if (endian === 'le') {
35613 for (i = 0, j = 0; i < number.length; i += 3) {
35614 w = number[i] | (number[i + 1] << 8) | (number[i + 2] << 16);
35615 this.words[j] |= (w << off) & 0x3ffffff;
35616 this.words[j + 1] = (w >>> (26 - off)) & 0x3ffffff;
35617 off += 24;
35618 if (off >= 26) {
35619 off -= 26;
35620 j++;
35621 }
35622 }
35623 }
35624 return this.strip();
35625 };
35626
35627 function parseHex (str, start, end) {
35628 var r = 0;
35629 var len = Math.min(str.length, end);
35630 for (var i = start; i < len; i++) {
35631 var c = str.charCodeAt(i) - 48;
35632
35633 r <<= 4;
35634
35635 // 'a' - 'f'
35636 if (c >= 49 && c <= 54) {
35637 r |= c - 49 + 0xa;
35638
35639 // 'A' - 'F'
35640 } else if (c >= 17 && c <= 22) {
35641 r |= c - 17 + 0xa;
35642
35643 // '0' - '9'
35644 } else {
35645 r |= c & 0xf;
35646 }
35647 }
35648 return r;
35649 }
35650
35651 BN.prototype._parseHex = function _parseHex (number, start) {
35652 // Create possibly bigger array to ensure that it fits the number
35653 this.length = Math.ceil((number.length - start) / 6);
35654 this.words = new Array(this.length);
35655 for (var i = 0; i < this.length; i++) {
35656 this.words[i] = 0;
35657 }
35658
35659 var j, w;
35660 // Scan 24-bit chunks and add them to the number
35661 var off = 0;
35662 for (i = number.length - 6, j = 0; i >= start; i -= 6) {
35663 w = parseHex(number, i, i + 6);
35664 this.words[j] |= (w << off) & 0x3ffffff;
35665 // NOTE: `0x3fffff` is intentional here, 26bits max shift + 24bit hex limb
35666 this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
35667 off += 24;
35668 if (off >= 26) {
35669 off -= 26;
35670 j++;
35671 }
35672 }
35673 if (i + 6 !== start) {
35674 w = parseHex(number, start, i + 6);
35675 this.words[j] |= (w << off) & 0x3ffffff;
35676 this.words[j + 1] |= w >>> (26 - off) & 0x3fffff;
35677 }
35678 this.strip();
35679 };
35680
35681 function parseBase (str, start, end, mul) {
35682 var r = 0;
35683 var len = Math.min(str.length, end);
35684 for (var i = start; i < len; i++) {
35685 var c = str.charCodeAt(i) - 48;
35686
35687 r *= mul;
35688
35689 // 'a'
35690 if (c >= 49) {
35691 r += c - 49 + 0xa;
35692
35693 // 'A'
35694 } else if (c >= 17) {
35695 r += c - 17 + 0xa;
35696
35697 // '0' - '9'
35698 } else {
35699 r += c;
35700 }
35701 }
35702 return r;
35703 }
35704
35705 BN.prototype._parseBase = function _parseBase (number, base, start) {
35706 // Initialize as zero
35707 this.words = [ 0 ];
35708 this.length = 1;
35709
35710 // Find length of limb in base
35711 for (var limbLen = 0, limbPow = 1; limbPow <= 0x3ffffff; limbPow *= base) {
35712 limbLen++;
35713 }
35714 limbLen--;
35715 limbPow = (limbPow / base) | 0;
35716
35717 var total = number.length - start;
35718 var mod = total % limbLen;
35719 var end = Math.min(total, total - mod) + start;
35720
35721 var word = 0;
35722 for (var i = start; i < end; i += limbLen) {
35723 word = parseBase(number, i, i + limbLen, base);
35724
35725 this.imuln(limbPow);
35726 if (this.words[0] + word < 0x4000000) {
35727 this.words[0] += word;
35728 } else {
35729 this._iaddn(word);
35730 }
35731 }
35732
35733 if (mod !== 0) {
35734 var pow = 1;
35735 word = parseBase(number, i, number.length, base);
35736
35737 for (i = 0; i < mod; i++) {
35738 pow *= base;
35739 }
35740
35741 this.imuln(pow);
35742 if (this.words[0] + word < 0x4000000) {
35743 this.words[0] += word;
35744 } else {
35745 this._iaddn(word);
35746 }
35747 }
35748 };
35749
35750 BN.prototype.copy = function copy (dest) {
35751 dest.words = new Array(this.length);
35752 for (var i = 0; i < this.length; i++) {
35753 dest.words[i] = this.words[i];
35754 }
35755 dest.length = this.length;
35756 dest.negative = this.negative;
35757 dest.red = this.red;
35758 };
35759
35760 BN.prototype.clone = function clone () {
35761 var r = new BN(null);
35762 this.copy(r);
35763 return r;
35764 };
35765
35766 BN.prototype._expand = function _expand (size) {
35767 while (this.length < size) {
35768 this.words[this.length++] = 0;
35769 }
35770 return this;
35771 };
35772
35773 // Remove leading `0` from `this`
35774 BN.prototype.strip = function strip () {
35775 while (this.length > 1 && this.words[this.length - 1] === 0) {
35776 this.length--;
35777 }
35778 return this._normSign();
35779 };
35780
35781 BN.prototype._normSign = function _normSign () {
35782 // -0 = 0
35783 if (this.length === 1 && this.words[0] === 0) {
35784 this.negative = 0;
35785 }
35786 return this;
35787 };
35788
35789 BN.prototype.inspect = function inspect () {
35790 return (this.red ? '<BN-R: ' : '<BN: ') + this.toString(16) + '>';
35791 };
35792
35793 /*
35794
35795 var zeros = [];
35796 var groupSizes = [];
35797 var groupBases = [];
35798
35799 var s = '';
35800 var i = -1;
35801 while (++i < BN.wordSize) {
35802 zeros[i] = s;
35803 s += '0';
35804 }
35805 groupSizes[0] = 0;
35806 groupSizes[1] = 0;
35807 groupBases[0] = 0;
35808 groupBases[1] = 0;
35809 var base = 2 - 1;
35810 while (++base < 36 + 1) {
35811 var groupSize = 0;
35812 var groupBase = 1;
35813 while (groupBase < (1 << BN.wordSize) / base) {
35814 groupBase *= base;
35815 groupSize += 1;
35816 }
35817 groupSizes[base] = groupSize;
35818 groupBases[base] = groupBase;
35819 }
35820
35821 */
35822
35823 var zeros = [
35824 '',
35825 '0',
35826 '00',
35827 '000',
35828 '0000',
35829 '00000',
35830 '000000',
35831 '0000000',
35832 '00000000',
35833 '000000000',
35834 '0000000000',
35835 '00000000000',
35836 '000000000000',
35837 '0000000000000',
35838 '00000000000000',
35839 '000000000000000',
35840 '0000000000000000',
35841 '00000000000000000',
35842 '000000000000000000',
35843 '0000000000000000000',
35844 '00000000000000000000',
35845 '000000000000000000000',
35846 '0000000000000000000000',
35847 '00000000000000000000000',
35848 '000000000000000000000000',
35849 '0000000000000000000000000'
35850 ];
35851
35852 var groupSizes = [
35853 0, 0,
35854 25, 16, 12, 11, 10, 9, 8,
35855 8, 7, 7, 7, 7, 6, 6,
35856 6, 6, 6, 6, 6, 5, 5,
35857 5, 5, 5, 5, 5, 5, 5,
35858 5, 5, 5, 5, 5, 5, 5
35859 ];
35860
35861 var groupBases = [
35862 0, 0,
35863 33554432, 43046721, 16777216, 48828125, 60466176, 40353607, 16777216,
35864 43046721, 10000000, 19487171, 35831808, 62748517, 7529536, 11390625,
35865 16777216, 24137569, 34012224, 47045881, 64000000, 4084101, 5153632,
35866 6436343, 7962624, 9765625, 11881376, 14348907, 17210368, 20511149,
35867 24300000, 28629151, 33554432, 39135393, 45435424, 52521875, 60466176
35868 ];
35869
35870 BN.prototype.toString = function toString (base, padding) {
35871 base = base || 10;
35872 padding = padding | 0 || 1;
35873
35874 var out;
35875 if (base === 16 || base === 'hex') {
35876 out = '';
35877 var off = 0;
35878 var carry = 0;
35879 for (var i = 0; i < this.length; i++) {
35880 var w = this.words[i];
35881 var word = (((w << off) | carry) & 0xffffff).toString(16);
35882 carry = (w >>> (24 - off)) & 0xffffff;
35883 if (carry !== 0 || i !== this.length - 1) {
35884 out = zeros[6 - word.length] + word + out;
35885 } else {
35886 out = word + out;
35887 }
35888 off += 2;
35889 if (off >= 26) {
35890 off -= 26;
35891 i--;
35892 }
35893 }
35894 if (carry !== 0) {
35895 out = carry.toString(16) + out;
35896 }
35897 while (out.length % padding !== 0) {
35898 out = '0' + out;
35899 }
35900 if (this.negative !== 0) {
35901 out = '-' + out;
35902 }
35903 return out;
35904 }
35905
35906 if (base === (base | 0) && base >= 2 && base <= 36) {
35907 // var groupSize = Math.floor(BN.wordSize * Math.LN2 / Math.log(base));
35908 var groupSize = groupSizes[base];
35909 // var groupBase = Math.pow(base, groupSize);
35910 var groupBase = groupBases[base];
35911 out = '';
35912 var c = this.clone();
35913 c.negative = 0;
35914 while (!c.isZero()) {
35915 var r = c.modn(groupBase).toString(base);
35916 c = c.idivn(groupBase);
35917
35918 if (!c.isZero()) {
35919 out = zeros[groupSize - r.length] + r + out;
35920 } else {
35921 out = r + out;
35922 }
35923 }
35924 if (this.isZero()) {
35925 out = '0' + out;
35926 }
35927 while (out.length % padding !== 0) {
35928 out = '0' + out;
35929 }
35930 if (this.negative !== 0) {
35931 out = '-' + out;
35932 }
35933 return out;
35934 }
35935
35936 assert(false, 'Base should be between 2 and 36');
35937 };
35938
35939 BN.prototype.toNumber = function toNumber () {
35940 var ret = this.words[0];
35941 if (this.length === 2) {
35942 ret += this.words[1] * 0x4000000;
35943 } else if (this.length === 3 && this.words[2] === 0x01) {
35944 // NOTE: at this stage it is known that the top bit is set
35945 ret += 0x10000000000000 + (this.words[1] * 0x4000000);
35946 } else if (this.length > 2) {
35947 assert(false, 'Number can only safely store up to 53 bits');
35948 }
35949 return (this.negative !== 0) ? -ret : ret;
35950 };
35951
35952 BN.prototype.toJSON = function toJSON () {
35953 return this.toString(16);
35954 };
35955
35956 BN.prototype.toBuffer = function toBuffer (endian, length) {
35957 assert(typeof Buffer !== 'undefined');
35958 return this.toArrayLike(Buffer, endian, length);
35959 };
35960
35961 BN.prototype.toArray = function toArray (endian, length) {
35962 return this.toArrayLike(Array, endian, length);
35963 };
35964
35965 BN.prototype.toArrayLike = function toArrayLike (ArrayType, endian, length) {
35966 var byteLength = this.byteLength();
35967 var reqLength = length || Math.max(1, byteLength);
35968 assert(byteLength <= reqLength, 'byte array longer than desired length');
35969 assert(reqLength > 0, 'Requested array length <= 0');
35970
35971 this.strip();
35972 var littleEndian = endian === 'le';
35973 var res = new ArrayType(reqLength);
35974
35975 var b, i;
35976 var q = this.clone();
35977 if (!littleEndian) {
35978 // Assume big-endian
35979 for (i = 0; i < reqLength - byteLength; i++) {
35980 res[i] = 0;
35981 }
35982
35983 for (i = 0; !q.isZero(); i++) {
35984 b = q.andln(0xff);
35985 q.iushrn(8);
35986
35987 res[reqLength - i - 1] = b;
35988 }
35989 } else {
35990 for (i = 0; !q.isZero(); i++) {
35991 b = q.andln(0xff);
35992 q.iushrn(8);
35993
35994 res[i] = b;
35995 }
35996
35997 for (; i < reqLength; i++) {
35998 res[i] = 0;
35999 }
36000 }
36001
36002 return res;
36003 };
36004
36005 if (Math.clz32) {
36006 BN.prototype._countBits = function _countBits (w) {
36007 return 32 - Math.clz32(w);
36008 };
36009 } else {
36010 BN.prototype._countBits = function _countBits (w) {
36011 var t = w;
36012 var r = 0;
36013 if (t >= 0x1000) {
36014 r += 13;
36015 t >>>= 13;
36016 }
36017 if (t >= 0x40) {
36018 r += 7;
36019 t >>>= 7;
36020 }
36021 if (t >= 0x8) {
36022 r += 4;
36023 t >>>= 4;
36024 }
36025 if (t >= 0x02) {
36026 r += 2;
36027 t >>>= 2;
36028 }
36029 return r + t;
36030 };
36031 }
36032
36033 BN.prototype._zeroBits = function _zeroBits (w) {
36034 // Short-cut
36035 if (w === 0) return 26;
36036
36037 var t = w;
36038 var r = 0;
36039 if ((t & 0x1fff) === 0) {
36040 r += 13;
36041 t >>>= 13;
36042 }
36043 if ((t & 0x7f) === 0) {
36044 r += 7;
36045 t >>>= 7;
36046 }
36047 if ((t & 0xf) === 0) {
36048 r += 4;
36049 t >>>= 4;
36050 }
36051 if ((t & 0x3) === 0) {
36052 r += 2;
36053 t >>>= 2;
36054 }
36055 if ((t & 0x1) === 0) {
36056 r++;
36057 }
36058 return r;
36059 };
36060
36061 // Return number of used bits in a BN
36062 BN.prototype.bitLength = function bitLength () {
36063 var w = this.words[this.length - 1];
36064 var hi = this._countBits(w);
36065 return (this.length - 1) * 26 + hi;
36066 };
36067
36068 function toBitArray (num) {
36069 var w = new Array(num.bitLength());
36070
36071 for (var bit = 0; bit < w.length; bit++) {
36072 var off = (bit / 26) | 0;
36073 var wbit = bit % 26;
36074
36075 w[bit] = (num.words[off] & (1 << wbit)) >>> wbit;
36076 }
36077
36078 return w;
36079 }
36080
36081 // Number of trailing zero bits
36082 BN.prototype.zeroBits = function zeroBits () {
36083 if (this.isZero()) return 0;
36084
36085 var r = 0;
36086 for (var i = 0; i < this.length; i++) {
36087 var b = this._zeroBits(this.words[i]);
36088 r += b;
36089 if (b !== 26) break;
36090 }
36091 return r;
36092 };
36093
36094 BN.prototype.byteLength = function byteLength () {
36095 return Math.ceil(this.bitLength() / 8);
36096 };
36097
36098 BN.prototype.toTwos = function toTwos (width) {
36099 if (this.negative !== 0) {
36100 return this.abs().inotn(width).iaddn(1);
36101 }
36102 return this.clone();
36103 };
36104
36105 BN.prototype.fromTwos = function fromTwos (width) {
36106 if (this.testn(width - 1)) {
36107 return this.notn(width).iaddn(1).ineg();
36108 }
36109 return this.clone();
36110 };
36111
36112 BN.prototype.isNeg = function isNeg () {
36113 return this.negative !== 0;
36114 };
36115
36116 // Return negative clone of `this`
36117 BN.prototype.neg = function neg () {
36118 return this.clone().ineg();
36119 };
36120
36121 BN.prototype.ineg = function ineg () {
36122 if (!this.isZero()) {
36123 this.negative ^= 1;
36124 }
36125
36126 return this;
36127 };
36128
36129 // Or `num` with `this` in-place
36130 BN.prototype.iuor = function iuor (num) {
36131 while (this.length < num.length) {
36132 this.words[this.length++] = 0;
36133 }
36134
36135 for (var i = 0; i < num.length; i++) {
36136 this.words[i] = this.words[i] | num.words[i];
36137 }
36138
36139 return this.strip();
36140 };
36141
36142 BN.prototype.ior = function ior (num) {
36143 assert((this.negative | num.negative) === 0);
36144 return this.iuor(num);
36145 };
36146
36147 // Or `num` with `this`
36148 BN.prototype.or = function or (num) {
36149 if (this.length > num.length) return this.clone().ior(num);
36150 return num.clone().ior(this);
36151 };
36152
36153 BN.prototype.uor = function uor (num) {
36154 if (this.length > num.length) return this.clone().iuor(num);
36155 return num.clone().iuor(this);
36156 };
36157
36158 // And `num` with `this` in-place
36159 BN.prototype.iuand = function iuand (num) {
36160 // b = min-length(num, this)
36161 var b;
36162 if (this.length > num.length) {
36163 b = num;
36164 } else {
36165 b = this;
36166 }
36167
36168 for (var i = 0; i < b.length; i++) {
36169 this.words[i] = this.words[i] & num.words[i];
36170 }
36171
36172 this.length = b.length;
36173
36174 return this.strip();
36175 };
36176
36177 BN.prototype.iand = function iand (num) {
36178 assert((this.negative | num.negative) === 0);
36179 return this.iuand(num);
36180 };
36181
36182 // And `num` with `this`
36183 BN.prototype.and = function and (num) {
36184 if (this.length > num.length) return this.clone().iand(num);
36185 return num.clone().iand(this);
36186 };
36187
36188 BN.prototype.uand = function uand (num) {
36189 if (this.length > num.length) return this.clone().iuand(num);
36190 return num.clone().iuand(this);
36191 };
36192
36193 // Xor `num` with `this` in-place
36194 BN.prototype.iuxor = function iuxor (num) {
36195 // a.length > b.length
36196 var a;
36197 var b;
36198 if (this.length > num.length) {
36199 a = this;
36200 b = num;
36201 } else {
36202 a = num;
36203 b = this;
36204 }
36205
36206 for (var i = 0; i < b.length; i++) {
36207 this.words[i] = a.words[i] ^ b.words[i];
36208 }
36209
36210 if (this !== a) {
36211 for (; i < a.length; i++) {
36212 this.words[i] = a.words[i];
36213 }
36214 }
36215
36216 this.length = a.length;
36217
36218 return this.strip();
36219 };
36220
36221 BN.prototype.ixor = function ixor (num) {
36222 assert((this.negative | num.negative) === 0);
36223 return this.iuxor(num);
36224 };
36225
36226 // Xor `num` with `this`
36227 BN.prototype.xor = function xor (num) {
36228 if (this.length > num.length) return this.clone().ixor(num);
36229 return num.clone().ixor(this);
36230 };
36231
36232 BN.prototype.uxor = function uxor (num) {
36233 if (this.length > num.length) return this.clone().iuxor(num);
36234 return num.clone().iuxor(this);
36235 };
36236
36237 // Not ``this`` with ``width`` bitwidth
36238 BN.prototype.inotn = function inotn (width) {
36239 assert(typeof width === 'number' && width >= 0);
36240
36241 var bytesNeeded = Math.ceil(width / 26) | 0;
36242 var bitsLeft = width % 26;
36243
36244 // Extend the buffer with leading zeroes
36245 this._expand(bytesNeeded);
36246
36247 if (bitsLeft > 0) {
36248 bytesNeeded--;
36249 }
36250
36251 // Handle complete words
36252 for (var i = 0; i < bytesNeeded; i++) {
36253 this.words[i] = ~this.words[i] & 0x3ffffff;
36254 }
36255
36256 // Handle the residue
36257 if (bitsLeft > 0) {
36258 this.words[i] = ~this.words[i] & (0x3ffffff >> (26 - bitsLeft));
36259 }
36260
36261 // And remove leading zeroes
36262 return this.strip();
36263 };
36264
36265 BN.prototype.notn = function notn (width) {
36266 return this.clone().inotn(width);
36267 };
36268
36269 // Set `bit` of `this`
36270 BN.prototype.setn = function setn (bit, val) {
36271 assert(typeof bit === 'number' && bit >= 0);
36272
36273 var off = (bit / 26) | 0;
36274 var wbit = bit % 26;
36275
36276 this._expand(off + 1);
36277
36278 if (val) {
36279 this.words[off] = this.words[off] | (1 << wbit);
36280 } else {
36281 this.words[off] = this.words[off] & ~(1 << wbit);
36282 }
36283
36284 return this.strip();
36285 };
36286
36287 // Add `num` to `this` in-place
36288 BN.prototype.iadd = function iadd (num) {
36289 var r;
36290
36291 // negative + positive
36292 if (this.negative !== 0 && num.negative === 0) {
36293 this.negative = 0;
36294 r = this.isub(num);
36295 this.negative ^= 1;
36296 return this._normSign();
36297
36298 // positive + negative
36299 } else if (this.negative === 0 && num.negative !== 0) {
36300 num.negative = 0;
36301 r = this.isub(num);
36302 num.negative = 1;
36303 return r._normSign();
36304 }
36305
36306 // a.length > b.length
36307 var a, b;
36308 if (this.length > num.length) {
36309 a = this;
36310 b = num;
36311 } else {
36312 a = num;
36313 b = this;
36314 }
36315
36316 var carry = 0;
36317 for (var i = 0; i < b.length; i++) {
36318 r = (a.words[i] | 0) + (b.words[i] | 0) + carry;
36319 this.words[i] = r & 0x3ffffff;
36320 carry = r >>> 26;
36321 }
36322 for (; carry !== 0 && i < a.length; i++) {
36323 r = (a.words[i] | 0) + carry;
36324 this.words[i] = r & 0x3ffffff;
36325 carry = r >>> 26;
36326 }
36327
36328 this.length = a.length;
36329 if (carry !== 0) {
36330 this.words[this.length] = carry;
36331 this.length++;
36332 // Copy the rest of the words
36333 } else if (a !== this) {
36334 for (; i < a.length; i++) {
36335 this.words[i] = a.words[i];
36336 }
36337 }
36338
36339 return this;
36340 };
36341
36342 // Add `num` to `this`
36343 BN.prototype.add = function add (num) {
36344 var res;
36345 if (num.negative !== 0 && this.negative === 0) {
36346 num.negative = 0;
36347 res = this.sub(num);
36348 num.negative ^= 1;
36349 return res;
36350 } else if (num.negative === 0 && this.negative !== 0) {
36351 this.negative = 0;
36352 res = num.sub(this);
36353 this.negative = 1;
36354 return res;
36355 }
36356
36357 if (this.length > num.length) return this.clone().iadd(num);
36358
36359 return num.clone().iadd(this);
36360 };
36361
36362 // Subtract `num` from `this` in-place
36363 BN.prototype.isub = function isub (num) {
36364 // this - (-num) = this + num
36365 if (num.negative !== 0) {
36366 num.negative = 0;
36367 var r = this.iadd(num);
36368 num.negative = 1;
36369 return r._normSign();
36370
36371 // -this - num = -(this + num)
36372 } else if (this.negative !== 0) {
36373 this.negative = 0;
36374 this.iadd(num);
36375 this.negative = 1;
36376 return this._normSign();
36377 }
36378
36379 // At this point both numbers are positive
36380 var cmp = this.cmp(num);
36381
36382 // Optimization - zeroify
36383 if (cmp === 0) {
36384 this.negative = 0;
36385 this.length = 1;
36386 this.words[0] = 0;
36387 return this;
36388 }
36389
36390 // a > b
36391 var a, b;
36392 if (cmp > 0) {
36393 a = this;
36394 b = num;
36395 } else {
36396 a = num;
36397 b = this;
36398 }
36399
36400 var carry = 0;
36401 for (var i = 0; i < b.length; i++) {
36402 r = (a.words[i] | 0) - (b.words[i] | 0) + carry;
36403 carry = r >> 26;
36404 this.words[i] = r & 0x3ffffff;
36405 }
36406 for (; carry !== 0 && i < a.length; i++) {
36407 r = (a.words[i] | 0) + carry;
36408 carry = r >> 26;
36409 this.words[i] = r & 0x3ffffff;
36410 }
36411
36412 // Copy rest of the words
36413 if (carry === 0 && i < a.length && a !== this) {
36414 for (; i < a.length; i++) {
36415 this.words[i] = a.words[i];
36416 }
36417 }
36418
36419 this.length = Math.max(this.length, i);
36420
36421 if (a !== this) {
36422 this.negative = 1;
36423 }
36424
36425 return this.strip();
36426 };
36427
36428 // Subtract `num` from `this`
36429 BN.prototype.sub = function sub (num) {
36430 return this.clone().isub(num);
36431 };
36432
36433 function smallMulTo (self, num, out) {
36434 out.negative = num.negative ^ self.negative;
36435 var len = (self.length + num.length) | 0;
36436 out.length = len;
36437 len = (len - 1) | 0;
36438
36439 // Peel one iteration (compiler can't do it, because of code complexity)
36440 var a = self.words[0] | 0;
36441 var b = num.words[0] | 0;
36442 var r = a * b;
36443
36444 var lo = r & 0x3ffffff;
36445 var carry = (r / 0x4000000) | 0;
36446 out.words[0] = lo;
36447
36448 for (var k = 1; k < len; k++) {
36449 // Sum all words with the same `i + j = k` and accumulate `ncarry`,
36450 // note that ncarry could be >= 0x3ffffff
36451 var ncarry = carry >>> 26;
36452 var rword = carry & 0x3ffffff;
36453 var maxJ = Math.min(k, num.length - 1);
36454 for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
36455 var i = (k - j) | 0;
36456 a = self.words[i] | 0;
36457 b = num.words[j] | 0;
36458 r = a * b + rword;
36459 ncarry += (r / 0x4000000) | 0;
36460 rword = r & 0x3ffffff;
36461 }
36462 out.words[k] = rword | 0;
36463 carry = ncarry | 0;
36464 }
36465 if (carry !== 0) {
36466 out.words[k] = carry | 0;
36467 } else {
36468 out.length--;
36469 }
36470
36471 return out.strip();
36472 }
36473
36474 // TODO(indutny): it may be reasonable to omit it for users who don't need
36475 // to work with 256-bit numbers, otherwise it gives 20% improvement for 256-bit
36476 // multiplication (like elliptic secp256k1).
36477 var comb10MulTo = function comb10MulTo (self, num, out) {
36478 var a = self.words;
36479 var b = num.words;
36480 var o = out.words;
36481 var c = 0;
36482 var lo;
36483 var mid;
36484 var hi;
36485 var a0 = a[0] | 0;
36486 var al0 = a0 & 0x1fff;
36487 var ah0 = a0 >>> 13;
36488 var a1 = a[1] | 0;
36489 var al1 = a1 & 0x1fff;
36490 var ah1 = a1 >>> 13;
36491 var a2 = a[2] | 0;
36492 var al2 = a2 & 0x1fff;
36493 var ah2 = a2 >>> 13;
36494 var a3 = a[3] | 0;
36495 var al3 = a3 & 0x1fff;
36496 var ah3 = a3 >>> 13;
36497 var a4 = a[4] | 0;
36498 var al4 = a4 & 0x1fff;
36499 var ah4 = a4 >>> 13;
36500 var a5 = a[5] | 0;
36501 var al5 = a5 & 0x1fff;
36502 var ah5 = a5 >>> 13;
36503 var a6 = a[6] | 0;
36504 var al6 = a6 & 0x1fff;
36505 var ah6 = a6 >>> 13;
36506 var a7 = a[7] | 0;
36507 var al7 = a7 & 0x1fff;
36508 var ah7 = a7 >>> 13;
36509 var a8 = a[8] | 0;
36510 var al8 = a8 & 0x1fff;
36511 var ah8 = a8 >>> 13;
36512 var a9 = a[9] | 0;
36513 var al9 = a9 & 0x1fff;
36514 var ah9 = a9 >>> 13;
36515 var b0 = b[0] | 0;
36516 var bl0 = b0 & 0x1fff;
36517 var bh0 = b0 >>> 13;
36518 var b1 = b[1] | 0;
36519 var bl1 = b1 & 0x1fff;
36520 var bh1 = b1 >>> 13;
36521 var b2 = b[2] | 0;
36522 var bl2 = b2 & 0x1fff;
36523 var bh2 = b2 >>> 13;
36524 var b3 = b[3] | 0;
36525 var bl3 = b3 & 0x1fff;
36526 var bh3 = b3 >>> 13;
36527 var b4 = b[4] | 0;
36528 var bl4 = b4 & 0x1fff;
36529 var bh4 = b4 >>> 13;
36530 var b5 = b[5] | 0;
36531 var bl5 = b5 & 0x1fff;
36532 var bh5 = b5 >>> 13;
36533 var b6 = b[6] | 0;
36534 var bl6 = b6 & 0x1fff;
36535 var bh6 = b6 >>> 13;
36536 var b7 = b[7] | 0;
36537 var bl7 = b7 & 0x1fff;
36538 var bh7 = b7 >>> 13;
36539 var b8 = b[8] | 0;
36540 var bl8 = b8 & 0x1fff;
36541 var bh8 = b8 >>> 13;
36542 var b9 = b[9] | 0;
36543 var bl9 = b9 & 0x1fff;
36544 var bh9 = b9 >>> 13;
36545
36546 out.negative = self.negative ^ num.negative;
36547 out.length = 19;
36548 /* k = 0 */
36549 lo = Math.imul(al0, bl0);
36550 mid = Math.imul(al0, bh0);
36551 mid = (mid + Math.imul(ah0, bl0)) | 0;
36552 hi = Math.imul(ah0, bh0);
36553 var w0 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36554 c = (((hi + (mid >>> 13)) | 0) + (w0 >>> 26)) | 0;
36555 w0 &= 0x3ffffff;
36556 /* k = 1 */
36557 lo = Math.imul(al1, bl0);
36558 mid = Math.imul(al1, bh0);
36559 mid = (mid + Math.imul(ah1, bl0)) | 0;
36560 hi = Math.imul(ah1, bh0);
36561 lo = (lo + Math.imul(al0, bl1)) | 0;
36562 mid = (mid + Math.imul(al0, bh1)) | 0;
36563 mid = (mid + Math.imul(ah0, bl1)) | 0;
36564 hi = (hi + Math.imul(ah0, bh1)) | 0;
36565 var w1 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36566 c = (((hi + (mid >>> 13)) | 0) + (w1 >>> 26)) | 0;
36567 w1 &= 0x3ffffff;
36568 /* k = 2 */
36569 lo = Math.imul(al2, bl0);
36570 mid = Math.imul(al2, bh0);
36571 mid = (mid + Math.imul(ah2, bl0)) | 0;
36572 hi = Math.imul(ah2, bh0);
36573 lo = (lo + Math.imul(al1, bl1)) | 0;
36574 mid = (mid + Math.imul(al1, bh1)) | 0;
36575 mid = (mid + Math.imul(ah1, bl1)) | 0;
36576 hi = (hi + Math.imul(ah1, bh1)) | 0;
36577 lo = (lo + Math.imul(al0, bl2)) | 0;
36578 mid = (mid + Math.imul(al0, bh2)) | 0;
36579 mid = (mid + Math.imul(ah0, bl2)) | 0;
36580 hi = (hi + Math.imul(ah0, bh2)) | 0;
36581 var w2 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36582 c = (((hi + (mid >>> 13)) | 0) + (w2 >>> 26)) | 0;
36583 w2 &= 0x3ffffff;
36584 /* k = 3 */
36585 lo = Math.imul(al3, bl0);
36586 mid = Math.imul(al3, bh0);
36587 mid = (mid + Math.imul(ah3, bl0)) | 0;
36588 hi = Math.imul(ah3, bh0);
36589 lo = (lo + Math.imul(al2, bl1)) | 0;
36590 mid = (mid + Math.imul(al2, bh1)) | 0;
36591 mid = (mid + Math.imul(ah2, bl1)) | 0;
36592 hi = (hi + Math.imul(ah2, bh1)) | 0;
36593 lo = (lo + Math.imul(al1, bl2)) | 0;
36594 mid = (mid + Math.imul(al1, bh2)) | 0;
36595 mid = (mid + Math.imul(ah1, bl2)) | 0;
36596 hi = (hi + Math.imul(ah1, bh2)) | 0;
36597 lo = (lo + Math.imul(al0, bl3)) | 0;
36598 mid = (mid + Math.imul(al0, bh3)) | 0;
36599 mid = (mid + Math.imul(ah0, bl3)) | 0;
36600 hi = (hi + Math.imul(ah0, bh3)) | 0;
36601 var w3 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36602 c = (((hi + (mid >>> 13)) | 0) + (w3 >>> 26)) | 0;
36603 w3 &= 0x3ffffff;
36604 /* k = 4 */
36605 lo = Math.imul(al4, bl0);
36606 mid = Math.imul(al4, bh0);
36607 mid = (mid + Math.imul(ah4, bl0)) | 0;
36608 hi = Math.imul(ah4, bh0);
36609 lo = (lo + Math.imul(al3, bl1)) | 0;
36610 mid = (mid + Math.imul(al3, bh1)) | 0;
36611 mid = (mid + Math.imul(ah3, bl1)) | 0;
36612 hi = (hi + Math.imul(ah3, bh1)) | 0;
36613 lo = (lo + Math.imul(al2, bl2)) | 0;
36614 mid = (mid + Math.imul(al2, bh2)) | 0;
36615 mid = (mid + Math.imul(ah2, bl2)) | 0;
36616 hi = (hi + Math.imul(ah2, bh2)) | 0;
36617 lo = (lo + Math.imul(al1, bl3)) | 0;
36618 mid = (mid + Math.imul(al1, bh3)) | 0;
36619 mid = (mid + Math.imul(ah1, bl3)) | 0;
36620 hi = (hi + Math.imul(ah1, bh3)) | 0;
36621 lo = (lo + Math.imul(al0, bl4)) | 0;
36622 mid = (mid + Math.imul(al0, bh4)) | 0;
36623 mid = (mid + Math.imul(ah0, bl4)) | 0;
36624 hi = (hi + Math.imul(ah0, bh4)) | 0;
36625 var w4 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36626 c = (((hi + (mid >>> 13)) | 0) + (w4 >>> 26)) | 0;
36627 w4 &= 0x3ffffff;
36628 /* k = 5 */
36629 lo = Math.imul(al5, bl0);
36630 mid = Math.imul(al5, bh0);
36631 mid = (mid + Math.imul(ah5, bl0)) | 0;
36632 hi = Math.imul(ah5, bh0);
36633 lo = (lo + Math.imul(al4, bl1)) | 0;
36634 mid = (mid + Math.imul(al4, bh1)) | 0;
36635 mid = (mid + Math.imul(ah4, bl1)) | 0;
36636 hi = (hi + Math.imul(ah4, bh1)) | 0;
36637 lo = (lo + Math.imul(al3, bl2)) | 0;
36638 mid = (mid + Math.imul(al3, bh2)) | 0;
36639 mid = (mid + Math.imul(ah3, bl2)) | 0;
36640 hi = (hi + Math.imul(ah3, bh2)) | 0;
36641 lo = (lo + Math.imul(al2, bl3)) | 0;
36642 mid = (mid + Math.imul(al2, bh3)) | 0;
36643 mid = (mid + Math.imul(ah2, bl3)) | 0;
36644 hi = (hi + Math.imul(ah2, bh3)) | 0;
36645 lo = (lo + Math.imul(al1, bl4)) | 0;
36646 mid = (mid + Math.imul(al1, bh4)) | 0;
36647 mid = (mid + Math.imul(ah1, bl4)) | 0;
36648 hi = (hi + Math.imul(ah1, bh4)) | 0;
36649 lo = (lo + Math.imul(al0, bl5)) | 0;
36650 mid = (mid + Math.imul(al0, bh5)) | 0;
36651 mid = (mid + Math.imul(ah0, bl5)) | 0;
36652 hi = (hi + Math.imul(ah0, bh5)) | 0;
36653 var w5 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36654 c = (((hi + (mid >>> 13)) | 0) + (w5 >>> 26)) | 0;
36655 w5 &= 0x3ffffff;
36656 /* k = 6 */
36657 lo = Math.imul(al6, bl0);
36658 mid = Math.imul(al6, bh0);
36659 mid = (mid + Math.imul(ah6, bl0)) | 0;
36660 hi = Math.imul(ah6, bh0);
36661 lo = (lo + Math.imul(al5, bl1)) | 0;
36662 mid = (mid + Math.imul(al5, bh1)) | 0;
36663 mid = (mid + Math.imul(ah5, bl1)) | 0;
36664 hi = (hi + Math.imul(ah5, bh1)) | 0;
36665 lo = (lo + Math.imul(al4, bl2)) | 0;
36666 mid = (mid + Math.imul(al4, bh2)) | 0;
36667 mid = (mid + Math.imul(ah4, bl2)) | 0;
36668 hi = (hi + Math.imul(ah4, bh2)) | 0;
36669 lo = (lo + Math.imul(al3, bl3)) | 0;
36670 mid = (mid + Math.imul(al3, bh3)) | 0;
36671 mid = (mid + Math.imul(ah3, bl3)) | 0;
36672 hi = (hi + Math.imul(ah3, bh3)) | 0;
36673 lo = (lo + Math.imul(al2, bl4)) | 0;
36674 mid = (mid + Math.imul(al2, bh4)) | 0;
36675 mid = (mid + Math.imul(ah2, bl4)) | 0;
36676 hi = (hi + Math.imul(ah2, bh4)) | 0;
36677 lo = (lo + Math.imul(al1, bl5)) | 0;
36678 mid = (mid + Math.imul(al1, bh5)) | 0;
36679 mid = (mid + Math.imul(ah1, bl5)) | 0;
36680 hi = (hi + Math.imul(ah1, bh5)) | 0;
36681 lo = (lo + Math.imul(al0, bl6)) | 0;
36682 mid = (mid + Math.imul(al0, bh6)) | 0;
36683 mid = (mid + Math.imul(ah0, bl6)) | 0;
36684 hi = (hi + Math.imul(ah0, bh6)) | 0;
36685 var w6 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36686 c = (((hi + (mid >>> 13)) | 0) + (w6 >>> 26)) | 0;
36687 w6 &= 0x3ffffff;
36688 /* k = 7 */
36689 lo = Math.imul(al7, bl0);
36690 mid = Math.imul(al7, bh0);
36691 mid = (mid + Math.imul(ah7, bl0)) | 0;
36692 hi = Math.imul(ah7, bh0);
36693 lo = (lo + Math.imul(al6, bl1)) | 0;
36694 mid = (mid + Math.imul(al6, bh1)) | 0;
36695 mid = (mid + Math.imul(ah6, bl1)) | 0;
36696 hi = (hi + Math.imul(ah6, bh1)) | 0;
36697 lo = (lo + Math.imul(al5, bl2)) | 0;
36698 mid = (mid + Math.imul(al5, bh2)) | 0;
36699 mid = (mid + Math.imul(ah5, bl2)) | 0;
36700 hi = (hi + Math.imul(ah5, bh2)) | 0;
36701 lo = (lo + Math.imul(al4, bl3)) | 0;
36702 mid = (mid + Math.imul(al4, bh3)) | 0;
36703 mid = (mid + Math.imul(ah4, bl3)) | 0;
36704 hi = (hi + Math.imul(ah4, bh3)) | 0;
36705 lo = (lo + Math.imul(al3, bl4)) | 0;
36706 mid = (mid + Math.imul(al3, bh4)) | 0;
36707 mid = (mid + Math.imul(ah3, bl4)) | 0;
36708 hi = (hi + Math.imul(ah3, bh4)) | 0;
36709 lo = (lo + Math.imul(al2, bl5)) | 0;
36710 mid = (mid + Math.imul(al2, bh5)) | 0;
36711 mid = (mid + Math.imul(ah2, bl5)) | 0;
36712 hi = (hi + Math.imul(ah2, bh5)) | 0;
36713 lo = (lo + Math.imul(al1, bl6)) | 0;
36714 mid = (mid + Math.imul(al1, bh6)) | 0;
36715 mid = (mid + Math.imul(ah1, bl6)) | 0;
36716 hi = (hi + Math.imul(ah1, bh6)) | 0;
36717 lo = (lo + Math.imul(al0, bl7)) | 0;
36718 mid = (mid + Math.imul(al0, bh7)) | 0;
36719 mid = (mid + Math.imul(ah0, bl7)) | 0;
36720 hi = (hi + Math.imul(ah0, bh7)) | 0;
36721 var w7 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36722 c = (((hi + (mid >>> 13)) | 0) + (w7 >>> 26)) | 0;
36723 w7 &= 0x3ffffff;
36724 /* k = 8 */
36725 lo = Math.imul(al8, bl0);
36726 mid = Math.imul(al8, bh0);
36727 mid = (mid + Math.imul(ah8, bl0)) | 0;
36728 hi = Math.imul(ah8, bh0);
36729 lo = (lo + Math.imul(al7, bl1)) | 0;
36730 mid = (mid + Math.imul(al7, bh1)) | 0;
36731 mid = (mid + Math.imul(ah7, bl1)) | 0;
36732 hi = (hi + Math.imul(ah7, bh1)) | 0;
36733 lo = (lo + Math.imul(al6, bl2)) | 0;
36734 mid = (mid + Math.imul(al6, bh2)) | 0;
36735 mid = (mid + Math.imul(ah6, bl2)) | 0;
36736 hi = (hi + Math.imul(ah6, bh2)) | 0;
36737 lo = (lo + Math.imul(al5, bl3)) | 0;
36738 mid = (mid + Math.imul(al5, bh3)) | 0;
36739 mid = (mid + Math.imul(ah5, bl3)) | 0;
36740 hi = (hi + Math.imul(ah5, bh3)) | 0;
36741 lo = (lo + Math.imul(al4, bl4)) | 0;
36742 mid = (mid + Math.imul(al4, bh4)) | 0;
36743 mid = (mid + Math.imul(ah4, bl4)) | 0;
36744 hi = (hi + Math.imul(ah4, bh4)) | 0;
36745 lo = (lo + Math.imul(al3, bl5)) | 0;
36746 mid = (mid + Math.imul(al3, bh5)) | 0;
36747 mid = (mid + Math.imul(ah3, bl5)) | 0;
36748 hi = (hi + Math.imul(ah3, bh5)) | 0;
36749 lo = (lo + Math.imul(al2, bl6)) | 0;
36750 mid = (mid + Math.imul(al2, bh6)) | 0;
36751 mid = (mid + Math.imul(ah2, bl6)) | 0;
36752 hi = (hi + Math.imul(ah2, bh6)) | 0;
36753 lo = (lo + Math.imul(al1, bl7)) | 0;
36754 mid = (mid + Math.imul(al1, bh7)) | 0;
36755 mid = (mid + Math.imul(ah1, bl7)) | 0;
36756 hi = (hi + Math.imul(ah1, bh7)) | 0;
36757 lo = (lo + Math.imul(al0, bl8)) | 0;
36758 mid = (mid + Math.imul(al0, bh8)) | 0;
36759 mid = (mid + Math.imul(ah0, bl8)) | 0;
36760 hi = (hi + Math.imul(ah0, bh8)) | 0;
36761 var w8 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36762 c = (((hi + (mid >>> 13)) | 0) + (w8 >>> 26)) | 0;
36763 w8 &= 0x3ffffff;
36764 /* k = 9 */
36765 lo = Math.imul(al9, bl0);
36766 mid = Math.imul(al9, bh0);
36767 mid = (mid + Math.imul(ah9, bl0)) | 0;
36768 hi = Math.imul(ah9, bh0);
36769 lo = (lo + Math.imul(al8, bl1)) | 0;
36770 mid = (mid + Math.imul(al8, bh1)) | 0;
36771 mid = (mid + Math.imul(ah8, bl1)) | 0;
36772 hi = (hi + Math.imul(ah8, bh1)) | 0;
36773 lo = (lo + Math.imul(al7, bl2)) | 0;
36774 mid = (mid + Math.imul(al7, bh2)) | 0;
36775 mid = (mid + Math.imul(ah7, bl2)) | 0;
36776 hi = (hi + Math.imul(ah7, bh2)) | 0;
36777 lo = (lo + Math.imul(al6, bl3)) | 0;
36778 mid = (mid + Math.imul(al6, bh3)) | 0;
36779 mid = (mid + Math.imul(ah6, bl3)) | 0;
36780 hi = (hi + Math.imul(ah6, bh3)) | 0;
36781 lo = (lo + Math.imul(al5, bl4)) | 0;
36782 mid = (mid + Math.imul(al5, bh4)) | 0;
36783 mid = (mid + Math.imul(ah5, bl4)) | 0;
36784 hi = (hi + Math.imul(ah5, bh4)) | 0;
36785 lo = (lo + Math.imul(al4, bl5)) | 0;
36786 mid = (mid + Math.imul(al4, bh5)) | 0;
36787 mid = (mid + Math.imul(ah4, bl5)) | 0;
36788 hi = (hi + Math.imul(ah4, bh5)) | 0;
36789 lo = (lo + Math.imul(al3, bl6)) | 0;
36790 mid = (mid + Math.imul(al3, bh6)) | 0;
36791 mid = (mid + Math.imul(ah3, bl6)) | 0;
36792 hi = (hi + Math.imul(ah3, bh6)) | 0;
36793 lo = (lo + Math.imul(al2, bl7)) | 0;
36794 mid = (mid + Math.imul(al2, bh7)) | 0;
36795 mid = (mid + Math.imul(ah2, bl7)) | 0;
36796 hi = (hi + Math.imul(ah2, bh7)) | 0;
36797 lo = (lo + Math.imul(al1, bl8)) | 0;
36798 mid = (mid + Math.imul(al1, bh8)) | 0;
36799 mid = (mid + Math.imul(ah1, bl8)) | 0;
36800 hi = (hi + Math.imul(ah1, bh8)) | 0;
36801 lo = (lo + Math.imul(al0, bl9)) | 0;
36802 mid = (mid + Math.imul(al0, bh9)) | 0;
36803 mid = (mid + Math.imul(ah0, bl9)) | 0;
36804 hi = (hi + Math.imul(ah0, bh9)) | 0;
36805 var w9 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36806 c = (((hi + (mid >>> 13)) | 0) + (w9 >>> 26)) | 0;
36807 w9 &= 0x3ffffff;
36808 /* k = 10 */
36809 lo = Math.imul(al9, bl1);
36810 mid = Math.imul(al9, bh1);
36811 mid = (mid + Math.imul(ah9, bl1)) | 0;
36812 hi = Math.imul(ah9, bh1);
36813 lo = (lo + Math.imul(al8, bl2)) | 0;
36814 mid = (mid + Math.imul(al8, bh2)) | 0;
36815 mid = (mid + Math.imul(ah8, bl2)) | 0;
36816 hi = (hi + Math.imul(ah8, bh2)) | 0;
36817 lo = (lo + Math.imul(al7, bl3)) | 0;
36818 mid = (mid + Math.imul(al7, bh3)) | 0;
36819 mid = (mid + Math.imul(ah7, bl3)) | 0;
36820 hi = (hi + Math.imul(ah7, bh3)) | 0;
36821 lo = (lo + Math.imul(al6, bl4)) | 0;
36822 mid = (mid + Math.imul(al6, bh4)) | 0;
36823 mid = (mid + Math.imul(ah6, bl4)) | 0;
36824 hi = (hi + Math.imul(ah6, bh4)) | 0;
36825 lo = (lo + Math.imul(al5, bl5)) | 0;
36826 mid = (mid + Math.imul(al5, bh5)) | 0;
36827 mid = (mid + Math.imul(ah5, bl5)) | 0;
36828 hi = (hi + Math.imul(ah5, bh5)) | 0;
36829 lo = (lo + Math.imul(al4, bl6)) | 0;
36830 mid = (mid + Math.imul(al4, bh6)) | 0;
36831 mid = (mid + Math.imul(ah4, bl6)) | 0;
36832 hi = (hi + Math.imul(ah4, bh6)) | 0;
36833 lo = (lo + Math.imul(al3, bl7)) | 0;
36834 mid = (mid + Math.imul(al3, bh7)) | 0;
36835 mid = (mid + Math.imul(ah3, bl7)) | 0;
36836 hi = (hi + Math.imul(ah3, bh7)) | 0;
36837 lo = (lo + Math.imul(al2, bl8)) | 0;
36838 mid = (mid + Math.imul(al2, bh8)) | 0;
36839 mid = (mid + Math.imul(ah2, bl8)) | 0;
36840 hi = (hi + Math.imul(ah2, bh8)) | 0;
36841 lo = (lo + Math.imul(al1, bl9)) | 0;
36842 mid = (mid + Math.imul(al1, bh9)) | 0;
36843 mid = (mid + Math.imul(ah1, bl9)) | 0;
36844 hi = (hi + Math.imul(ah1, bh9)) | 0;
36845 var w10 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36846 c = (((hi + (mid >>> 13)) | 0) + (w10 >>> 26)) | 0;
36847 w10 &= 0x3ffffff;
36848 /* k = 11 */
36849 lo = Math.imul(al9, bl2);
36850 mid = Math.imul(al9, bh2);
36851 mid = (mid + Math.imul(ah9, bl2)) | 0;
36852 hi = Math.imul(ah9, bh2);
36853 lo = (lo + Math.imul(al8, bl3)) | 0;
36854 mid = (mid + Math.imul(al8, bh3)) | 0;
36855 mid = (mid + Math.imul(ah8, bl3)) | 0;
36856 hi = (hi + Math.imul(ah8, bh3)) | 0;
36857 lo = (lo + Math.imul(al7, bl4)) | 0;
36858 mid = (mid + Math.imul(al7, bh4)) | 0;
36859 mid = (mid + Math.imul(ah7, bl4)) | 0;
36860 hi = (hi + Math.imul(ah7, bh4)) | 0;
36861 lo = (lo + Math.imul(al6, bl5)) | 0;
36862 mid = (mid + Math.imul(al6, bh5)) | 0;
36863 mid = (mid + Math.imul(ah6, bl5)) | 0;
36864 hi = (hi + Math.imul(ah6, bh5)) | 0;
36865 lo = (lo + Math.imul(al5, bl6)) | 0;
36866 mid = (mid + Math.imul(al5, bh6)) | 0;
36867 mid = (mid + Math.imul(ah5, bl6)) | 0;
36868 hi = (hi + Math.imul(ah5, bh6)) | 0;
36869 lo = (lo + Math.imul(al4, bl7)) | 0;
36870 mid = (mid + Math.imul(al4, bh7)) | 0;
36871 mid = (mid + Math.imul(ah4, bl7)) | 0;
36872 hi = (hi + Math.imul(ah4, bh7)) | 0;
36873 lo = (lo + Math.imul(al3, bl8)) | 0;
36874 mid = (mid + Math.imul(al3, bh8)) | 0;
36875 mid = (mid + Math.imul(ah3, bl8)) | 0;
36876 hi = (hi + Math.imul(ah3, bh8)) | 0;
36877 lo = (lo + Math.imul(al2, bl9)) | 0;
36878 mid = (mid + Math.imul(al2, bh9)) | 0;
36879 mid = (mid + Math.imul(ah2, bl9)) | 0;
36880 hi = (hi + Math.imul(ah2, bh9)) | 0;
36881 var w11 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36882 c = (((hi + (mid >>> 13)) | 0) + (w11 >>> 26)) | 0;
36883 w11 &= 0x3ffffff;
36884 /* k = 12 */
36885 lo = Math.imul(al9, bl3);
36886 mid = Math.imul(al9, bh3);
36887 mid = (mid + Math.imul(ah9, bl3)) | 0;
36888 hi = Math.imul(ah9, bh3);
36889 lo = (lo + Math.imul(al8, bl4)) | 0;
36890 mid = (mid + Math.imul(al8, bh4)) | 0;
36891 mid = (mid + Math.imul(ah8, bl4)) | 0;
36892 hi = (hi + Math.imul(ah8, bh4)) | 0;
36893 lo = (lo + Math.imul(al7, bl5)) | 0;
36894 mid = (mid + Math.imul(al7, bh5)) | 0;
36895 mid = (mid + Math.imul(ah7, bl5)) | 0;
36896 hi = (hi + Math.imul(ah7, bh5)) | 0;
36897 lo = (lo + Math.imul(al6, bl6)) | 0;
36898 mid = (mid + Math.imul(al6, bh6)) | 0;
36899 mid = (mid + Math.imul(ah6, bl6)) | 0;
36900 hi = (hi + Math.imul(ah6, bh6)) | 0;
36901 lo = (lo + Math.imul(al5, bl7)) | 0;
36902 mid = (mid + Math.imul(al5, bh7)) | 0;
36903 mid = (mid + Math.imul(ah5, bl7)) | 0;
36904 hi = (hi + Math.imul(ah5, bh7)) | 0;
36905 lo = (lo + Math.imul(al4, bl8)) | 0;
36906 mid = (mid + Math.imul(al4, bh8)) | 0;
36907 mid = (mid + Math.imul(ah4, bl8)) | 0;
36908 hi = (hi + Math.imul(ah4, bh8)) | 0;
36909 lo = (lo + Math.imul(al3, bl9)) | 0;
36910 mid = (mid + Math.imul(al3, bh9)) | 0;
36911 mid = (mid + Math.imul(ah3, bl9)) | 0;
36912 hi = (hi + Math.imul(ah3, bh9)) | 0;
36913 var w12 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36914 c = (((hi + (mid >>> 13)) | 0) + (w12 >>> 26)) | 0;
36915 w12 &= 0x3ffffff;
36916 /* k = 13 */
36917 lo = Math.imul(al9, bl4);
36918 mid = Math.imul(al9, bh4);
36919 mid = (mid + Math.imul(ah9, bl4)) | 0;
36920 hi = Math.imul(ah9, bh4);
36921 lo = (lo + Math.imul(al8, bl5)) | 0;
36922 mid = (mid + Math.imul(al8, bh5)) | 0;
36923 mid = (mid + Math.imul(ah8, bl5)) | 0;
36924 hi = (hi + Math.imul(ah8, bh5)) | 0;
36925 lo = (lo + Math.imul(al7, bl6)) | 0;
36926 mid = (mid + Math.imul(al7, bh6)) | 0;
36927 mid = (mid + Math.imul(ah7, bl6)) | 0;
36928 hi = (hi + Math.imul(ah7, bh6)) | 0;
36929 lo = (lo + Math.imul(al6, bl7)) | 0;
36930 mid = (mid + Math.imul(al6, bh7)) | 0;
36931 mid = (mid + Math.imul(ah6, bl7)) | 0;
36932 hi = (hi + Math.imul(ah6, bh7)) | 0;
36933 lo = (lo + Math.imul(al5, bl8)) | 0;
36934 mid = (mid + Math.imul(al5, bh8)) | 0;
36935 mid = (mid + Math.imul(ah5, bl8)) | 0;
36936 hi = (hi + Math.imul(ah5, bh8)) | 0;
36937 lo = (lo + Math.imul(al4, bl9)) | 0;
36938 mid = (mid + Math.imul(al4, bh9)) | 0;
36939 mid = (mid + Math.imul(ah4, bl9)) | 0;
36940 hi = (hi + Math.imul(ah4, bh9)) | 0;
36941 var w13 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36942 c = (((hi + (mid >>> 13)) | 0) + (w13 >>> 26)) | 0;
36943 w13 &= 0x3ffffff;
36944 /* k = 14 */
36945 lo = Math.imul(al9, bl5);
36946 mid = Math.imul(al9, bh5);
36947 mid = (mid + Math.imul(ah9, bl5)) | 0;
36948 hi = Math.imul(ah9, bh5);
36949 lo = (lo + Math.imul(al8, bl6)) | 0;
36950 mid = (mid + Math.imul(al8, bh6)) | 0;
36951 mid = (mid + Math.imul(ah8, bl6)) | 0;
36952 hi = (hi + Math.imul(ah8, bh6)) | 0;
36953 lo = (lo + Math.imul(al7, bl7)) | 0;
36954 mid = (mid + Math.imul(al7, bh7)) | 0;
36955 mid = (mid + Math.imul(ah7, bl7)) | 0;
36956 hi = (hi + Math.imul(ah7, bh7)) | 0;
36957 lo = (lo + Math.imul(al6, bl8)) | 0;
36958 mid = (mid + Math.imul(al6, bh8)) | 0;
36959 mid = (mid + Math.imul(ah6, bl8)) | 0;
36960 hi = (hi + Math.imul(ah6, bh8)) | 0;
36961 lo = (lo + Math.imul(al5, bl9)) | 0;
36962 mid = (mid + Math.imul(al5, bh9)) | 0;
36963 mid = (mid + Math.imul(ah5, bl9)) | 0;
36964 hi = (hi + Math.imul(ah5, bh9)) | 0;
36965 var w14 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36966 c = (((hi + (mid >>> 13)) | 0) + (w14 >>> 26)) | 0;
36967 w14 &= 0x3ffffff;
36968 /* k = 15 */
36969 lo = Math.imul(al9, bl6);
36970 mid = Math.imul(al9, bh6);
36971 mid = (mid + Math.imul(ah9, bl6)) | 0;
36972 hi = Math.imul(ah9, bh6);
36973 lo = (lo + Math.imul(al8, bl7)) | 0;
36974 mid = (mid + Math.imul(al8, bh7)) | 0;
36975 mid = (mid + Math.imul(ah8, bl7)) | 0;
36976 hi = (hi + Math.imul(ah8, bh7)) | 0;
36977 lo = (lo + Math.imul(al7, bl8)) | 0;
36978 mid = (mid + Math.imul(al7, bh8)) | 0;
36979 mid = (mid + Math.imul(ah7, bl8)) | 0;
36980 hi = (hi + Math.imul(ah7, bh8)) | 0;
36981 lo = (lo + Math.imul(al6, bl9)) | 0;
36982 mid = (mid + Math.imul(al6, bh9)) | 0;
36983 mid = (mid + Math.imul(ah6, bl9)) | 0;
36984 hi = (hi + Math.imul(ah6, bh9)) | 0;
36985 var w15 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
36986 c = (((hi + (mid >>> 13)) | 0) + (w15 >>> 26)) | 0;
36987 w15 &= 0x3ffffff;
36988 /* k = 16 */
36989 lo = Math.imul(al9, bl7);
36990 mid = Math.imul(al9, bh7);
36991 mid = (mid + Math.imul(ah9, bl7)) | 0;
36992 hi = Math.imul(ah9, bh7);
36993 lo = (lo + Math.imul(al8, bl8)) | 0;
36994 mid = (mid + Math.imul(al8, bh8)) | 0;
36995 mid = (mid + Math.imul(ah8, bl8)) | 0;
36996 hi = (hi + Math.imul(ah8, bh8)) | 0;
36997 lo = (lo + Math.imul(al7, bl9)) | 0;
36998 mid = (mid + Math.imul(al7, bh9)) | 0;
36999 mid = (mid + Math.imul(ah7, bl9)) | 0;
37000 hi = (hi + Math.imul(ah7, bh9)) | 0;
37001 var w16 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
37002 c = (((hi + (mid >>> 13)) | 0) + (w16 >>> 26)) | 0;
37003 w16 &= 0x3ffffff;
37004 /* k = 17 */
37005 lo = Math.imul(al9, bl8);
37006 mid = Math.imul(al9, bh8);
37007 mid = (mid + Math.imul(ah9, bl8)) | 0;
37008 hi = Math.imul(ah9, bh8);
37009 lo = (lo + Math.imul(al8, bl9)) | 0;
37010 mid = (mid + Math.imul(al8, bh9)) | 0;
37011 mid = (mid + Math.imul(ah8, bl9)) | 0;
37012 hi = (hi + Math.imul(ah8, bh9)) | 0;
37013 var w17 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
37014 c = (((hi + (mid >>> 13)) | 0) + (w17 >>> 26)) | 0;
37015 w17 &= 0x3ffffff;
37016 /* k = 18 */
37017 lo = Math.imul(al9, bl9);
37018 mid = Math.imul(al9, bh9);
37019 mid = (mid + Math.imul(ah9, bl9)) | 0;
37020 hi = Math.imul(ah9, bh9);
37021 var w18 = (((c + lo) | 0) + ((mid & 0x1fff) << 13)) | 0;
37022 c = (((hi + (mid >>> 13)) | 0) + (w18 >>> 26)) | 0;
37023 w18 &= 0x3ffffff;
37024 o[0] = w0;
37025 o[1] = w1;
37026 o[2] = w2;
37027 o[3] = w3;
37028 o[4] = w4;
37029 o[5] = w5;
37030 o[6] = w6;
37031 o[7] = w7;
37032 o[8] = w8;
37033 o[9] = w9;
37034 o[10] = w10;
37035 o[11] = w11;
37036 o[12] = w12;
37037 o[13] = w13;
37038 o[14] = w14;
37039 o[15] = w15;
37040 o[16] = w16;
37041 o[17] = w17;
37042 o[18] = w18;
37043 if (c !== 0) {
37044 o[19] = c;
37045 out.length++;
37046 }
37047 return out;
37048 };
37049
37050 // Polyfill comb
37051 if (!Math.imul) {
37052 comb10MulTo = smallMulTo;
37053 }
37054
37055 function bigMulTo (self, num, out) {
37056 out.negative = num.negative ^ self.negative;
37057 out.length = self.length + num.length;
37058
37059 var carry = 0;
37060 var hncarry = 0;
37061 for (var k = 0; k < out.length - 1; k++) {
37062 // Sum all words with the same `i + j = k` and accumulate `ncarry`,
37063 // note that ncarry could be >= 0x3ffffff
37064 var ncarry = hncarry;
37065 hncarry = 0;
37066 var rword = carry & 0x3ffffff;
37067 var maxJ = Math.min(k, num.length - 1);
37068 for (var j = Math.max(0, k - self.length + 1); j <= maxJ; j++) {
37069 var i = k - j;
37070 var a = self.words[i] | 0;
37071 var b = num.words[j] | 0;
37072 var r = a * b;
37073
37074 var lo = r & 0x3ffffff;
37075 ncarry = (ncarry + ((r / 0x4000000) | 0)) | 0;
37076 lo = (lo + rword) | 0;
37077 rword = lo & 0x3ffffff;
37078 ncarry = (ncarry + (lo >>> 26)) | 0;
37079
37080 hncarry += ncarry >>> 26;
37081 ncarry &= 0x3ffffff;
37082 }
37083 out.words[k] = rword;
37084 carry = ncarry;
37085 ncarry = hncarry;
37086 }
37087 if (carry !== 0) {
37088 out.words[k] = carry;
37089 } else {
37090 out.length--;
37091 }
37092
37093 return out.strip();
37094 }
37095
37096 function jumboMulTo (self, num, out) {
37097 var fftm = new FFTM();
37098 return fftm.mulp(self, num, out);
37099 }
37100
37101 BN.prototype.mulTo = function mulTo (num, out) {
37102 var res;
37103 var len = this.length + num.length;
37104 if (this.length === 10 && num.length === 10) {
37105 res = comb10MulTo(this, num, out);
37106 } else if (len < 63) {
37107 res = smallMulTo(this, num, out);
37108 } else if (len < 1024) {
37109 res = bigMulTo(this, num, out);
37110 } else {
37111 res = jumboMulTo(this, num, out);
37112 }
37113
37114 return res;
37115 };
37116
37117 // Cooley-Tukey algorithm for FFT
37118 // slightly revisited to rely on looping instead of recursion
37119
37120 function FFTM (x, y) {
37121 this.x = x;
37122 this.y = y;
37123 }
37124
37125 FFTM.prototype.makeRBT = function makeRBT (N) {
37126 var t = new Array(N);
37127 var l = BN.prototype._countBits(N) - 1;
37128 for (var i = 0; i < N; i++) {
37129 t[i] = this.revBin(i, l, N);
37130 }
37131
37132 return t;
37133 };
37134
37135 // Returns binary-reversed representation of `x`
37136 FFTM.prototype.revBin = function revBin (x, l, N) {
37137 if (x === 0 || x === N - 1) return x;
37138
37139 var rb = 0;
37140 for (var i = 0; i < l; i++) {
37141 rb |= (x & 1) << (l - i - 1);
37142 x >>= 1;
37143 }
37144
37145 return rb;
37146 };
37147
37148 // Performs "tweedling" phase, therefore 'emulating'
37149 // behaviour of the recursive algorithm
37150 FFTM.prototype.permute = function permute (rbt, rws, iws, rtws, itws, N) {
37151 for (var i = 0; i < N; i++) {
37152 rtws[i] = rws[rbt[i]];
37153 itws[i] = iws[rbt[i]];
37154 }
37155 };
37156
37157 FFTM.prototype.transform = function transform (rws, iws, rtws, itws, N, rbt) {
37158 this.permute(rbt, rws, iws, rtws, itws, N);
37159
37160 for (var s = 1; s < N; s <<= 1) {
37161 var l = s << 1;
37162
37163 var rtwdf = Math.cos(2 * Math.PI / l);
37164 var itwdf = Math.sin(2 * Math.PI / l);
37165
37166 for (var p = 0; p < N; p += l) {
37167 var rtwdf_ = rtwdf;
37168 var itwdf_ = itwdf;
37169
37170 for (var j = 0; j < s; j++) {
37171 var re = rtws[p + j];
37172 var ie = itws[p + j];
37173
37174 var ro = rtws[p + j + s];
37175 var io = itws[p + j + s];
37176
37177 var rx = rtwdf_ * ro - itwdf_ * io;
37178
37179 io = rtwdf_ * io + itwdf_ * ro;
37180 ro = rx;
37181
37182 rtws[p + j] = re + ro;
37183 itws[p + j] = ie + io;
37184
37185 rtws[p + j + s] = re - ro;
37186 itws[p + j + s] = ie - io;
37187
37188 /* jshint maxdepth : false */
37189 if (j !== l) {
37190 rx = rtwdf * rtwdf_ - itwdf * itwdf_;
37191
37192 itwdf_ = rtwdf * itwdf_ + itwdf * rtwdf_;
37193 rtwdf_ = rx;
37194 }
37195 }
37196 }
37197 }
37198 };
37199
37200 FFTM.prototype.guessLen13b = function guessLen13b (n, m) {
37201 var N = Math.max(m, n) | 1;
37202 var odd = N & 1;
37203 var i = 0;
37204 for (N = N / 2 | 0; N; N = N >>> 1) {
37205 i++;
37206 }
37207
37208 return 1 << i + 1 + odd;
37209 };
37210
37211 FFTM.prototype.conjugate = function conjugate (rws, iws, N) {
37212 if (N <= 1) return;
37213
37214 for (var i = 0; i < N / 2; i++) {
37215 var t = rws[i];
37216
37217 rws[i] = rws[N - i - 1];
37218 rws[N - i - 1] = t;
37219
37220 t = iws[i];
37221
37222 iws[i] = -iws[N - i - 1];
37223 iws[N - i - 1] = -t;
37224 }
37225 };
37226
37227 FFTM.prototype.normalize13b = function normalize13b (ws, N) {
37228 var carry = 0;
37229 for (var i = 0; i < N / 2; i++) {
37230 var w = Math.round(ws[2 * i + 1] / N) * 0x2000 +
37231 Math.round(ws[2 * i] / N) +
37232 carry;
37233
37234 ws[i] = w & 0x3ffffff;
37235
37236 if (w < 0x4000000) {
37237 carry = 0;
37238 } else {
37239 carry = w / 0x4000000 | 0;
37240 }
37241 }
37242
37243 return ws;
37244 };
37245
37246 FFTM.prototype.convert13b = function convert13b (ws, len, rws, N) {
37247 var carry = 0;
37248 for (var i = 0; i < len; i++) {
37249 carry = carry + (ws[i] | 0);
37250
37251 rws[2 * i] = carry & 0x1fff; carry = carry >>> 13;
37252 rws[2 * i + 1] = carry & 0x1fff; carry = carry >>> 13;
37253 }
37254
37255 // Pad with zeroes
37256 for (i = 2 * len; i < N; ++i) {
37257 rws[i] = 0;
37258 }
37259
37260 assert(carry === 0);
37261 assert((carry & ~0x1fff) === 0);
37262 };
37263
37264 FFTM.prototype.stub = function stub (N) {
37265 var ph = new Array(N);
37266 for (var i = 0; i < N; i++) {
37267 ph[i] = 0;
37268 }
37269
37270 return ph;
37271 };
37272
37273 FFTM.prototype.mulp = function mulp (x, y, out) {
37274 var N = 2 * this.guessLen13b(x.length, y.length);
37275
37276 var rbt = this.makeRBT(N);
37277
37278 var _ = this.stub(N);
37279
37280 var rws = new Array(N);
37281 var rwst = new Array(N);
37282 var iwst = new Array(N);
37283
37284 var nrws = new Array(N);
37285 var nrwst = new Array(N);
37286 var niwst = new Array(N);
37287
37288 var rmws = out.words;
37289 rmws.length = N;
37290
37291 this.convert13b(x.words, x.length, rws, N);
37292 this.convert13b(y.words, y.length, nrws, N);
37293
37294 this.transform(rws, _, rwst, iwst, N, rbt);
37295 this.transform(nrws, _, nrwst, niwst, N, rbt);
37296
37297 for (var i = 0; i < N; i++) {
37298 var rx = rwst[i] * nrwst[i] - iwst[i] * niwst[i];
37299 iwst[i] = rwst[i] * niwst[i] + iwst[i] * nrwst[i];
37300 rwst[i] = rx;
37301 }
37302
37303 this.conjugate(rwst, iwst, N);
37304 this.transform(rwst, iwst, rmws, _, N, rbt);
37305 this.conjugate(rmws, _, N);
37306 this.normalize13b(rmws, N);
37307
37308 out.negative = x.negative ^ y.negative;
37309 out.length = x.length + y.length;
37310 return out.strip();
37311 };
37312
37313 // Multiply `this` by `num`
37314 BN.prototype.mul = function mul (num) {
37315 var out = new BN(null);
37316 out.words = new Array(this.length + num.length);
37317 return this.mulTo(num, out);
37318 };
37319
37320 // Multiply employing FFT
37321 BN.prototype.mulf = function mulf (num) {
37322 var out = new BN(null);
37323 out.words = new Array(this.length + num.length);
37324 return jumboMulTo(this, num, out);
37325 };
37326
37327 // In-place Multiplication
37328 BN.prototype.imul = function imul (num) {
37329 return this.clone().mulTo(num, this);
37330 };
37331
37332 BN.prototype.imuln = function imuln (num) {
37333 assert(typeof num === 'number');
37334 assert(num < 0x4000000);
37335
37336 // Carry
37337 var carry = 0;
37338 for (var i = 0; i < this.length; i++) {
37339 var w = (this.words[i] | 0) * num;
37340 var lo = (w & 0x3ffffff) + (carry & 0x3ffffff);
37341 carry >>= 26;
37342 carry += (w / 0x4000000) | 0;
37343 // NOTE: lo is 27bit maximum
37344 carry += lo >>> 26;
37345 this.words[i] = lo & 0x3ffffff;
37346 }
37347
37348 if (carry !== 0) {
37349 this.words[i] = carry;
37350 this.length++;
37351 }
37352
37353 return this;
37354 };
37355
37356 BN.prototype.muln = function muln (num) {
37357 return this.clone().imuln(num);
37358 };
37359
37360 // `this` * `this`
37361 BN.prototype.sqr = function sqr () {
37362 return this.mul(this);
37363 };
37364
37365 // `this` * `this` in-place
37366 BN.prototype.isqr = function isqr () {
37367 return this.imul(this.clone());
37368 };
37369
37370 // Math.pow(`this`, `num`)
37371 BN.prototype.pow = function pow (num) {
37372 var w = toBitArray(num);
37373 if (w.length === 0) return new BN(1);
37374
37375 // Skip leading zeroes
37376 var res = this;
37377 for (var i = 0; i < w.length; i++, res = res.sqr()) {
37378 if (w[i] !== 0) break;
37379 }
37380
37381 if (++i < w.length) {
37382 for (var q = res.sqr(); i < w.length; i++, q = q.sqr()) {
37383 if (w[i] === 0) continue;
37384
37385 res = res.mul(q);
37386 }
37387 }
37388
37389 return res;
37390 };
37391
37392 // Shift-left in-place
37393 BN.prototype.iushln = function iushln (bits) {
37394 assert(typeof bits === 'number' && bits >= 0);
37395 var r = bits % 26;
37396 var s = (bits - r) / 26;
37397 var carryMask = (0x3ffffff >>> (26 - r)) << (26 - r);
37398 var i;
37399
37400 if (r !== 0) {
37401 var carry = 0;
37402
37403 for (i = 0; i < this.length; i++) {
37404 var newCarry = this.words[i] & carryMask;
37405 var c = ((this.words[i] | 0) - newCarry) << r;
37406 this.words[i] = c | carry;
37407 carry = newCarry >>> (26 - r);
37408 }
37409
37410 if (carry) {
37411 this.words[i] = carry;
37412 this.length++;
37413 }
37414 }
37415
37416 if (s !== 0) {
37417 for (i = this.length - 1; i >= 0; i--) {
37418 this.words[i + s] = this.words[i];
37419 }
37420
37421 for (i = 0; i < s; i++) {
37422 this.words[i] = 0;
37423 }
37424
37425 this.length += s;
37426 }
37427
37428 return this.strip();
37429 };
37430
37431 BN.prototype.ishln = function ishln (bits) {
37432 // TODO(indutny): implement me
37433 assert(this.negative === 0);
37434 return this.iushln(bits);
37435 };
37436
37437 // Shift-right in-place
37438 // NOTE: `hint` is a lowest bit before trailing zeroes
37439 // NOTE: if `extended` is present - it will be filled with destroyed bits
37440 BN.prototype.iushrn = function iushrn (bits, hint, extended) {
37441 assert(typeof bits === 'number' && bits >= 0);
37442 var h;
37443 if (hint) {
37444 h = (hint - (hint % 26)) / 26;
37445 } else {
37446 h = 0;
37447 }
37448
37449 var r = bits % 26;
37450 var s = Math.min((bits - r) / 26, this.length);
37451 var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
37452 var maskedWords = extended;
37453
37454 h -= s;
37455 h = Math.max(0, h);
37456
37457 // Extended mode, copy masked part
37458 if (maskedWords) {
37459 for (var i = 0; i < s; i++) {
37460 maskedWords.words[i] = this.words[i];
37461 }
37462 maskedWords.length = s;
37463 }
37464
37465 if (s === 0) ; else if (this.length > s) {
37466 this.length -= s;
37467 for (i = 0; i < this.length; i++) {
37468 this.words[i] = this.words[i + s];
37469 }
37470 } else {
37471 this.words[0] = 0;
37472 this.length = 1;
37473 }
37474
37475 var carry = 0;
37476 for (i = this.length - 1; i >= 0 && (carry !== 0 || i >= h); i--) {
37477 var word = this.words[i] | 0;
37478 this.words[i] = (carry << (26 - r)) | (word >>> r);
37479 carry = word & mask;
37480 }
37481
37482 // Push carried bits as a mask
37483 if (maskedWords && carry !== 0) {
37484 maskedWords.words[maskedWords.length++] = carry;
37485 }
37486
37487 if (this.length === 0) {
37488 this.words[0] = 0;
37489 this.length = 1;
37490 }
37491
37492 return this.strip();
37493 };
37494
37495 BN.prototype.ishrn = function ishrn (bits, hint, extended) {
37496 // TODO(indutny): implement me
37497 assert(this.negative === 0);
37498 return this.iushrn(bits, hint, extended);
37499 };
37500
37501 // Shift-left
37502 BN.prototype.shln = function shln (bits) {
37503 return this.clone().ishln(bits);
37504 };
37505
37506 BN.prototype.ushln = function ushln (bits) {
37507 return this.clone().iushln(bits);
37508 };
37509
37510 // Shift-right
37511 BN.prototype.shrn = function shrn (bits) {
37512 return this.clone().ishrn(bits);
37513 };
37514
37515 BN.prototype.ushrn = function ushrn (bits) {
37516 return this.clone().iushrn(bits);
37517 };
37518
37519 // Test if n bit is set
37520 BN.prototype.testn = function testn (bit) {
37521 assert(typeof bit === 'number' && bit >= 0);
37522 var r = bit % 26;
37523 var s = (bit - r) / 26;
37524 var q = 1 << r;
37525
37526 // Fast case: bit is much higher than all existing words
37527 if (this.length <= s) return false;
37528
37529 // Check bit and return
37530 var w = this.words[s];
37531
37532 return !!(w & q);
37533 };
37534
37535 // Return only lowers bits of number (in-place)
37536 BN.prototype.imaskn = function imaskn (bits) {
37537 assert(typeof bits === 'number' && bits >= 0);
37538 var r = bits % 26;
37539 var s = (bits - r) / 26;
37540
37541 assert(this.negative === 0, 'imaskn works only with positive numbers');
37542
37543 if (this.length <= s) {
37544 return this;
37545 }
37546
37547 if (r !== 0) {
37548 s++;
37549 }
37550 this.length = Math.min(s, this.length);
37551
37552 if (r !== 0) {
37553 var mask = 0x3ffffff ^ ((0x3ffffff >>> r) << r);
37554 this.words[this.length - 1] &= mask;
37555 }
37556
37557 return this.strip();
37558 };
37559
37560 // Return only lowers bits of number
37561 BN.prototype.maskn = function maskn (bits) {
37562 return this.clone().imaskn(bits);
37563 };
37564
37565 // Add plain number `num` to `this`
37566 BN.prototype.iaddn = function iaddn (num) {
37567 assert(typeof num === 'number');
37568 assert(num < 0x4000000);
37569 if (num < 0) return this.isubn(-num);
37570
37571 // Possible sign change
37572 if (this.negative !== 0) {
37573 if (this.length === 1 && (this.words[0] | 0) < num) {
37574 this.words[0] = num - (this.words[0] | 0);
37575 this.negative = 0;
37576 return this;
37577 }
37578
37579 this.negative = 0;
37580 this.isubn(num);
37581 this.negative = 1;
37582 return this;
37583 }
37584
37585 // Add without checks
37586 return this._iaddn(num);
37587 };
37588
37589 BN.prototype._iaddn = function _iaddn (num) {
37590 this.words[0] += num;
37591
37592 // Carry
37593 for (var i = 0; i < this.length && this.words[i] >= 0x4000000; i++) {
37594 this.words[i] -= 0x4000000;
37595 if (i === this.length - 1) {
37596 this.words[i + 1] = 1;
37597 } else {
37598 this.words[i + 1]++;
37599 }
37600 }
37601 this.length = Math.max(this.length, i + 1);
37602
37603 return this;
37604 };
37605
37606 // Subtract plain number `num` from `this`
37607 BN.prototype.isubn = function isubn (num) {
37608 assert(typeof num === 'number');
37609 assert(num < 0x4000000);
37610 if (num < 0) return this.iaddn(-num);
37611
37612 if (this.negative !== 0) {
37613 this.negative = 0;
37614 this.iaddn(num);
37615 this.negative = 1;
37616 return this;
37617 }
37618
37619 this.words[0] -= num;
37620
37621 if (this.length === 1 && this.words[0] < 0) {
37622 this.words[0] = -this.words[0];
37623 this.negative = 1;
37624 } else {
37625 // Carry
37626 for (var i = 0; i < this.length && this.words[i] < 0; i++) {
37627 this.words[i] += 0x4000000;
37628 this.words[i + 1] -= 1;
37629 }
37630 }
37631
37632 return this.strip();
37633 };
37634
37635 BN.prototype.addn = function addn (num) {
37636 return this.clone().iaddn(num);
37637 };
37638
37639 BN.prototype.subn = function subn (num) {
37640 return this.clone().isubn(num);
37641 };
37642
37643 BN.prototype.iabs = function iabs () {
37644 this.negative = 0;
37645
37646 return this;
37647 };
37648
37649 BN.prototype.abs = function abs () {
37650 return this.clone().iabs();
37651 };
37652
37653 BN.prototype._ishlnsubmul = function _ishlnsubmul (num, mul, shift) {
37654 var len = num.length + shift;
37655 var i;
37656
37657 this._expand(len);
37658
37659 var w;
37660 var carry = 0;
37661 for (i = 0; i < num.length; i++) {
37662 w = (this.words[i + shift] | 0) + carry;
37663 var right = (num.words[i] | 0) * mul;
37664 w -= right & 0x3ffffff;
37665 carry = (w >> 26) - ((right / 0x4000000) | 0);
37666 this.words[i + shift] = w & 0x3ffffff;
37667 }
37668 for (; i < this.length - shift; i++) {
37669 w = (this.words[i + shift] | 0) + carry;
37670 carry = w >> 26;
37671 this.words[i + shift] = w & 0x3ffffff;
37672 }
37673
37674 if (carry === 0) return this.strip();
37675
37676 // Subtraction overflow
37677 assert(carry === -1);
37678 carry = 0;
37679 for (i = 0; i < this.length; i++) {
37680 w = -(this.words[i] | 0) + carry;
37681 carry = w >> 26;
37682 this.words[i] = w & 0x3ffffff;
37683 }
37684 this.negative = 1;
37685
37686 return this.strip();
37687 };
37688
37689 BN.prototype._wordDiv = function _wordDiv (num, mode) {
37690 var shift = this.length - num.length;
37691
37692 var a = this.clone();
37693 var b = num;
37694
37695 // Normalize
37696 var bhi = b.words[b.length - 1] | 0;
37697 var bhiBits = this._countBits(bhi);
37698 shift = 26 - bhiBits;
37699 if (shift !== 0) {
37700 b = b.ushln(shift);
37701 a.iushln(shift);
37702 bhi = b.words[b.length - 1] | 0;
37703 }
37704
37705 // Initialize quotient
37706 var m = a.length - b.length;
37707 var q;
37708
37709 if (mode !== 'mod') {
37710 q = new BN(null);
37711 q.length = m + 1;
37712 q.words = new Array(q.length);
37713 for (var i = 0; i < q.length; i++) {
37714 q.words[i] = 0;
37715 }
37716 }
37717
37718 var diff = a.clone()._ishlnsubmul(b, 1, m);
37719 if (diff.negative === 0) {
37720 a = diff;
37721 if (q) {
37722 q.words[m] = 1;
37723 }
37724 }
37725
37726 for (var j = m - 1; j >= 0; j--) {
37727 var qj = (a.words[b.length + j] | 0) * 0x4000000 +
37728 (a.words[b.length + j - 1] | 0);
37729
37730 // NOTE: (qj / bhi) is (0x3ffffff * 0x4000000 + 0x3ffffff) / 0x2000000 max
37731 // (0x7ffffff)
37732 qj = Math.min((qj / bhi) | 0, 0x3ffffff);
37733
37734 a._ishlnsubmul(b, qj, j);
37735 while (a.negative !== 0) {
37736 qj--;
37737 a.negative = 0;
37738 a._ishlnsubmul(b, 1, j);
37739 if (!a.isZero()) {
37740 a.negative ^= 1;
37741 }
37742 }
37743 if (q) {
37744 q.words[j] = qj;
37745 }
37746 }
37747 if (q) {
37748 q.strip();
37749 }
37750 a.strip();
37751
37752 // Denormalize
37753 if (mode !== 'div' && shift !== 0) {
37754 a.iushrn(shift);
37755 }
37756
37757 return {
37758 div: q || null,
37759 mod: a
37760 };
37761 };
37762
37763 // NOTE: 1) `mode` can be set to `mod` to request mod only,
37764 // to `div` to request div only, or be absent to
37765 // request both div & mod
37766 // 2) `positive` is true if unsigned mod is requested
37767 BN.prototype.divmod = function divmod (num, mode, positive) {
37768 assert(!num.isZero());
37769
37770 if (this.isZero()) {
37771 return {
37772 div: new BN(0),
37773 mod: new BN(0)
37774 };
37775 }
37776
37777 var div, mod, res;
37778 if (this.negative !== 0 && num.negative === 0) {
37779 res = this.neg().divmod(num, mode);
37780
37781 if (mode !== 'mod') {
37782 div = res.div.neg();
37783 }
37784
37785 if (mode !== 'div') {
37786 mod = res.mod.neg();
37787 if (positive && mod.negative !== 0) {
37788 mod.iadd(num);
37789 }
37790 }
37791
37792 return {
37793 div: div,
37794 mod: mod
37795 };
37796 }
37797
37798 if (this.negative === 0 && num.negative !== 0) {
37799 res = this.divmod(num.neg(), mode);
37800
37801 if (mode !== 'mod') {
37802 div = res.div.neg();
37803 }
37804
37805 return {
37806 div: div,
37807 mod: res.mod
37808 };
37809 }
37810
37811 if ((this.negative & num.negative) !== 0) {
37812 res = this.neg().divmod(num.neg(), mode);
37813
37814 if (mode !== 'div') {
37815 mod = res.mod.neg();
37816 if (positive && mod.negative !== 0) {
37817 mod.isub(num);
37818 }
37819 }
37820
37821 return {
37822 div: res.div,
37823 mod: mod
37824 };
37825 }
37826
37827 // Both numbers are positive at this point
37828
37829 // Strip both numbers to approximate shift value
37830 if (num.length > this.length || this.cmp(num) < 0) {
37831 return {
37832 div: new BN(0),
37833 mod: this
37834 };
37835 }
37836
37837 // Very short reduction
37838 if (num.length === 1) {
37839 if (mode === 'div') {
37840 return {
37841 div: this.divn(num.words[0]),
37842 mod: null
37843 };
37844 }
37845
37846 if (mode === 'mod') {
37847 return {
37848 div: null,
37849 mod: new BN(this.modn(num.words[0]))
37850 };
37851 }
37852
37853 return {
37854 div: this.divn(num.words[0]),
37855 mod: new BN(this.modn(num.words[0]))
37856 };
37857 }
37858
37859 return this._wordDiv(num, mode);
37860 };
37861
37862 // Find `this` / `num`
37863 BN.prototype.div = function div (num) {
37864 return this.divmod(num, 'div', false).div;
37865 };
37866
37867 // Find `this` % `num`
37868 BN.prototype.mod = function mod (num) {
37869 return this.divmod(num, 'mod', false).mod;
37870 };
37871
37872 BN.prototype.umod = function umod (num) {
37873 return this.divmod(num, 'mod', true).mod;
37874 };
37875
37876 // Find Round(`this` / `num`)
37877 BN.prototype.divRound = function divRound (num) {
37878 var dm = this.divmod(num);
37879
37880 // Fast case - exact division
37881 if (dm.mod.isZero()) return dm.div;
37882
37883 var mod = dm.div.negative !== 0 ? dm.mod.isub(num) : dm.mod;
37884
37885 var half = num.ushrn(1);
37886 var r2 = num.andln(1);
37887 var cmp = mod.cmp(half);
37888
37889 // Round down
37890 if (cmp < 0 || r2 === 1 && cmp === 0) return dm.div;
37891
37892 // Round up
37893 return dm.div.negative !== 0 ? dm.div.isubn(1) : dm.div.iaddn(1);
37894 };
37895
37896 BN.prototype.modn = function modn (num) {
37897 assert(num <= 0x3ffffff);
37898 var p = (1 << 26) % num;
37899
37900 var acc = 0;
37901 for (var i = this.length - 1; i >= 0; i--) {
37902 acc = (p * acc + (this.words[i] | 0)) % num;
37903 }
37904
37905 return acc;
37906 };
37907
37908 // In-place division by number
37909 BN.prototype.idivn = function idivn (num) {
37910 assert(num <= 0x3ffffff);
37911
37912 var carry = 0;
37913 for (var i = this.length - 1; i >= 0; i--) {
37914 var w = (this.words[i] | 0) + carry * 0x4000000;
37915 this.words[i] = (w / num) | 0;
37916 carry = w % num;
37917 }
37918
37919 return this.strip();
37920 };
37921
37922 BN.prototype.divn = function divn (num) {
37923 return this.clone().idivn(num);
37924 };
37925
37926 BN.prototype.egcd = function egcd (p) {
37927 assert(p.negative === 0);
37928 assert(!p.isZero());
37929
37930 var x = this;
37931 var y = p.clone();
37932
37933 if (x.negative !== 0) {
37934 x = x.umod(p);
37935 } else {
37936 x = x.clone();
37937 }
37938
37939 // A * x + B * y = x
37940 var A = new BN(1);
37941 var B = new BN(0);
37942
37943 // C * x + D * y = y
37944 var C = new BN(0);
37945 var D = new BN(1);
37946
37947 var g = 0;
37948
37949 while (x.isEven() && y.isEven()) {
37950 x.iushrn(1);
37951 y.iushrn(1);
37952 ++g;
37953 }
37954
37955 var yp = y.clone();
37956 var xp = x.clone();
37957
37958 while (!x.isZero()) {
37959 for (var i = 0, im = 1; (x.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
37960 if (i > 0) {
37961 x.iushrn(i);
37962 while (i-- > 0) {
37963 if (A.isOdd() || B.isOdd()) {
37964 A.iadd(yp);
37965 B.isub(xp);
37966 }
37967
37968 A.iushrn(1);
37969 B.iushrn(1);
37970 }
37971 }
37972
37973 for (var j = 0, jm = 1; (y.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
37974 if (j > 0) {
37975 y.iushrn(j);
37976 while (j-- > 0) {
37977 if (C.isOdd() || D.isOdd()) {
37978 C.iadd(yp);
37979 D.isub(xp);
37980 }
37981
37982 C.iushrn(1);
37983 D.iushrn(1);
37984 }
37985 }
37986
37987 if (x.cmp(y) >= 0) {
37988 x.isub(y);
37989 A.isub(C);
37990 B.isub(D);
37991 } else {
37992 y.isub(x);
37993 C.isub(A);
37994 D.isub(B);
37995 }
37996 }
37997
37998 return {
37999 a: C,
38000 b: D,
38001 gcd: y.iushln(g)
38002 };
38003 };
38004
38005 // This is reduced incarnation of the binary EEA
38006 // above, designated to invert members of the
38007 // _prime_ fields F(p) at a maximal speed
38008 BN.prototype._invmp = function _invmp (p) {
38009 assert(p.negative === 0);
38010 assert(!p.isZero());
38011
38012 var a = this;
38013 var b = p.clone();
38014
38015 if (a.negative !== 0) {
38016 a = a.umod(p);
38017 } else {
38018 a = a.clone();
38019 }
38020
38021 var x1 = new BN(1);
38022 var x2 = new BN(0);
38023
38024 var delta = b.clone();
38025
38026 while (a.cmpn(1) > 0 && b.cmpn(1) > 0) {
38027 for (var i = 0, im = 1; (a.words[0] & im) === 0 && i < 26; ++i, im <<= 1);
38028 if (i > 0) {
38029 a.iushrn(i);
38030 while (i-- > 0) {
38031 if (x1.isOdd()) {
38032 x1.iadd(delta);
38033 }
38034
38035 x1.iushrn(1);
38036 }
38037 }
38038
38039 for (var j = 0, jm = 1; (b.words[0] & jm) === 0 && j < 26; ++j, jm <<= 1);
38040 if (j > 0) {
38041 b.iushrn(j);
38042 while (j-- > 0) {
38043 if (x2.isOdd()) {
38044 x2.iadd(delta);
38045 }
38046
38047 x2.iushrn(1);
38048 }
38049 }
38050
38051 if (a.cmp(b) >= 0) {
38052 a.isub(b);
38053 x1.isub(x2);
38054 } else {
38055 b.isub(a);
38056 x2.isub(x1);
38057 }
38058 }
38059
38060 var res;
38061 if (a.cmpn(1) === 0) {
38062 res = x1;
38063 } else {
38064 res = x2;
38065 }
38066
38067 if (res.cmpn(0) < 0) {
38068 res.iadd(p);
38069 }
38070
38071 return res;
38072 };
38073
38074 BN.prototype.gcd = function gcd (num) {
38075 if (this.isZero()) return num.abs();
38076 if (num.isZero()) return this.abs();
38077
38078 var a = this.clone();
38079 var b = num.clone();
38080 a.negative = 0;
38081 b.negative = 0;
38082
38083 // Remove common factor of two
38084 for (var shift = 0; a.isEven() && b.isEven(); shift++) {
38085 a.iushrn(1);
38086 b.iushrn(1);
38087 }
38088
38089 do {
38090 while (a.isEven()) {
38091 a.iushrn(1);
38092 }
38093 while (b.isEven()) {
38094 b.iushrn(1);
38095 }
38096
38097 var r = a.cmp(b);
38098 if (r < 0) {
38099 // Swap `a` and `b` to make `a` always bigger than `b`
38100 var t = a;
38101 a = b;
38102 b = t;
38103 } else if (r === 0 || b.cmpn(1) === 0) {
38104 break;
38105 }
38106
38107 a.isub(b);
38108 } while (true);
38109
38110 return b.iushln(shift);
38111 };
38112
38113 // Invert number in the field F(num)
38114 BN.prototype.invm = function invm (num) {
38115 return this.egcd(num).a.umod(num);
38116 };
38117
38118 BN.prototype.isEven = function isEven () {
38119 return (this.words[0] & 1) === 0;
38120 };
38121
38122 BN.prototype.isOdd = function isOdd () {
38123 return (this.words[0] & 1) === 1;
38124 };
38125
38126 // And first word and num
38127 BN.prototype.andln = function andln (num) {
38128 return this.words[0] & num;
38129 };
38130
38131 // Increment at the bit position in-line
38132 BN.prototype.bincn = function bincn (bit) {
38133 assert(typeof bit === 'number');
38134 var r = bit % 26;
38135 var s = (bit - r) / 26;
38136 var q = 1 << r;
38137
38138 // Fast case: bit is much higher than all existing words
38139 if (this.length <= s) {
38140 this._expand(s + 1);
38141 this.words[s] |= q;
38142 return this;
38143 }
38144
38145 // Add bit and propagate, if needed
38146 var carry = q;
38147 for (var i = s; carry !== 0 && i < this.length; i++) {
38148 var w = this.words[i] | 0;
38149 w += carry;
38150 carry = w >>> 26;
38151 w &= 0x3ffffff;
38152 this.words[i] = w;
38153 }
38154 if (carry !== 0) {
38155 this.words[i] = carry;
38156 this.length++;
38157 }
38158 return this;
38159 };
38160
38161 BN.prototype.isZero = function isZero () {
38162 return this.length === 1 && this.words[0] === 0;
38163 };
38164
38165 BN.prototype.cmpn = function cmpn (num) {
38166 var negative = num < 0;
38167
38168 if (this.negative !== 0 && !negative) return -1;
38169 if (this.negative === 0 && negative) return 1;
38170
38171 this.strip();
38172
38173 var res;
38174 if (this.length > 1) {
38175 res = 1;
38176 } else {
38177 if (negative) {
38178 num = -num;
38179 }
38180
38181 assert(num <= 0x3ffffff, 'Number is too big');
38182
38183 var w = this.words[0] | 0;
38184 res = w === num ? 0 : w < num ? -1 : 1;
38185 }
38186 if (this.negative !== 0) return -res | 0;
38187 return res;
38188 };
38189
38190 // Compare two numbers and return:
38191 // 1 - if `this` > `num`
38192 // 0 - if `this` == `num`
38193 // -1 - if `this` < `num`
38194 BN.prototype.cmp = function cmp (num) {
38195 if (this.negative !== 0 && num.negative === 0) return -1;
38196 if (this.negative === 0 && num.negative !== 0) return 1;
38197
38198 var res = this.ucmp(num);
38199 if (this.negative !== 0) return -res | 0;
38200 return res;
38201 };
38202
38203 // Unsigned comparison
38204 BN.prototype.ucmp = function ucmp (num) {
38205 // At this point both numbers have the same sign
38206 if (this.length > num.length) return 1;
38207 if (this.length < num.length) return -1;
38208
38209 var res = 0;
38210 for (var i = this.length - 1; i >= 0; i--) {
38211 var a = this.words[i] | 0;
38212 var b = num.words[i] | 0;
38213
38214 if (a === b) continue;
38215 if (a < b) {
38216 res = -1;
38217 } else if (a > b) {
38218 res = 1;
38219 }
38220 break;
38221 }
38222 return res;
38223 };
38224
38225 BN.prototype.gtn = function gtn (num) {
38226 return this.cmpn(num) === 1;
38227 };
38228
38229 BN.prototype.gt = function gt (num) {
38230 return this.cmp(num) === 1;
38231 };
38232
38233 BN.prototype.gten = function gten (num) {
38234 return this.cmpn(num) >= 0;
38235 };
38236
38237 BN.prototype.gte = function gte (num) {
38238 return this.cmp(num) >= 0;
38239 };
38240
38241 BN.prototype.ltn = function ltn (num) {
38242 return this.cmpn(num) === -1;
38243 };
38244
38245 BN.prototype.lt = function lt (num) {
38246 return this.cmp(num) === -1;
38247 };
38248
38249 BN.prototype.lten = function lten (num) {
38250 return this.cmpn(num) <= 0;
38251 };
38252
38253 BN.prototype.lte = function lte (num) {
38254 return this.cmp(num) <= 0;
38255 };
38256
38257 BN.prototype.eqn = function eqn (num) {
38258 return this.cmpn(num) === 0;
38259 };
38260
38261 BN.prototype.eq = function eq (num) {
38262 return this.cmp(num) === 0;
38263 };
38264
38265 //
38266 // A reduce context, could be using montgomery or something better, depending
38267 // on the `m` itself.
38268 //
38269 BN.red = function red (num) {
38270 return new Red(num);
38271 };
38272
38273 BN.prototype.toRed = function toRed (ctx) {
38274 assert(!this.red, 'Already a number in reduction context');
38275 assert(this.negative === 0, 'red works only with positives');
38276 return ctx.convertTo(this)._forceRed(ctx);
38277 };
38278
38279 BN.prototype.fromRed = function fromRed () {
38280 assert(this.red, 'fromRed works only with numbers in reduction context');
38281 return this.red.convertFrom(this);
38282 };
38283
38284 BN.prototype._forceRed = function _forceRed (ctx) {
38285 this.red = ctx;
38286 return this;
38287 };
38288
38289 BN.prototype.forceRed = function forceRed (ctx) {
38290 assert(!this.red, 'Already a number in reduction context');
38291 return this._forceRed(ctx);
38292 };
38293
38294 BN.prototype.redAdd = function redAdd (num) {
38295 assert(this.red, 'redAdd works only with red numbers');
38296 return this.red.add(this, num);
38297 };
38298
38299 BN.prototype.redIAdd = function redIAdd (num) {
38300 assert(this.red, 'redIAdd works only with red numbers');
38301 return this.red.iadd(this, num);
38302 };
38303
38304 BN.prototype.redSub = function redSub (num) {
38305 assert(this.red, 'redSub works only with red numbers');
38306 return this.red.sub(this, num);
38307 };
38308
38309 BN.prototype.redISub = function redISub (num) {
38310 assert(this.red, 'redISub works only with red numbers');
38311 return this.red.isub(this, num);
38312 };
38313
38314 BN.prototype.redShl = function redShl (num) {
38315 assert(this.red, 'redShl works only with red numbers');
38316 return this.red.shl(this, num);
38317 };
38318
38319 BN.prototype.redMul = function redMul (num) {
38320 assert(this.red, 'redMul works only with red numbers');
38321 this.red._verify2(this, num);
38322 return this.red.mul(this, num);
38323 };
38324
38325 BN.prototype.redIMul = function redIMul (num) {
38326 assert(this.red, 'redMul works only with red numbers');
38327 this.red._verify2(this, num);
38328 return this.red.imul(this, num);
38329 };
38330
38331 BN.prototype.redSqr = function redSqr () {
38332 assert(this.red, 'redSqr works only with red numbers');
38333 this.red._verify1(this);
38334 return this.red.sqr(this);
38335 };
38336
38337 BN.prototype.redISqr = function redISqr () {
38338 assert(this.red, 'redISqr works only with red numbers');
38339 this.red._verify1(this);
38340 return this.red.isqr(this);
38341 };
38342
38343 // Square root over p
38344 BN.prototype.redSqrt = function redSqrt () {
38345 assert(this.red, 'redSqrt works only with red numbers');
38346 this.red._verify1(this);
38347 return this.red.sqrt(this);
38348 };
38349
38350 BN.prototype.redInvm = function redInvm () {
38351 assert(this.red, 'redInvm works only with red numbers');
38352 this.red._verify1(this);
38353 return this.red.invm(this);
38354 };
38355
38356 // Return negative clone of `this` % `red modulo`
38357 BN.prototype.redNeg = function redNeg () {
38358 assert(this.red, 'redNeg works only with red numbers');
38359 this.red._verify1(this);
38360 return this.red.neg(this);
38361 };
38362
38363 BN.prototype.redPow = function redPow (num) {
38364 assert(this.red && !num.red, 'redPow(normalNum)');
38365 this.red._verify1(this);
38366 return this.red.pow(this, num);
38367 };
38368
38369 // Prime numbers with efficient reduction
38370 var primes = {
38371 k256: null,
38372 p224: null,
38373 p192: null,
38374 p25519: null
38375 };
38376
38377 // Pseudo-Mersenne prime
38378 function MPrime (name, p) {
38379 // P = 2 ^ N - K
38380 this.name = name;
38381 this.p = new BN(p, 16);
38382 this.n = this.p.bitLength();
38383 this.k = new BN(1).iushln(this.n).isub(this.p);
38384
38385 this.tmp = this._tmp();
38386 }
38387
38388 MPrime.prototype._tmp = function _tmp () {
38389 var tmp = new BN(null);
38390 tmp.words = new Array(Math.ceil(this.n / 13));
38391 return tmp;
38392 };
38393
38394 MPrime.prototype.ireduce = function ireduce (num) {
38395 // Assumes that `num` is less than `P^2`
38396 // num = HI * (2 ^ N - K) + HI * K + LO = HI * K + LO (mod P)
38397 var r = num;
38398 var rlen;
38399
38400 do {
38401 this.split(r, this.tmp);
38402 r = this.imulK(r);
38403 r = r.iadd(this.tmp);
38404 rlen = r.bitLength();
38405 } while (rlen > this.n);
38406
38407 var cmp = rlen < this.n ? -1 : r.ucmp(this.p);
38408 if (cmp === 0) {
38409 r.words[0] = 0;
38410 r.length = 1;
38411 } else if (cmp > 0) {
38412 r.isub(this.p);
38413 } else {
38414 r.strip();
38415 }
38416
38417 return r;
38418 };
38419
38420 MPrime.prototype.split = function split (input, out) {
38421 input.iushrn(this.n, 0, out);
38422 };
38423
38424 MPrime.prototype.imulK = function imulK (num) {
38425 return num.imul(this.k);
38426 };
38427
38428 function K256 () {
38429 MPrime.call(
38430 this,
38431 'k256',
38432 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f');
38433 }
38434 inherits(K256, MPrime);
38435
38436 K256.prototype.split = function split (input, output) {
38437 // 256 = 9 * 26 + 22
38438 var mask = 0x3fffff;
38439
38440 var outLen = Math.min(input.length, 9);
38441 for (var i = 0; i < outLen; i++) {
38442 output.words[i] = input.words[i];
38443 }
38444 output.length = outLen;
38445
38446 if (input.length <= 9) {
38447 input.words[0] = 0;
38448 input.length = 1;
38449 return;
38450 }
38451
38452 // Shift by 9 limbs
38453 var prev = input.words[9];
38454 output.words[output.length++] = prev & mask;
38455
38456 for (i = 10; i < input.length; i++) {
38457 var next = input.words[i] | 0;
38458 input.words[i - 10] = ((next & mask) << 4) | (prev >>> 22);
38459 prev = next;
38460 }
38461 prev >>>= 22;
38462 input.words[i - 10] = prev;
38463 if (prev === 0 && input.length > 10) {
38464 input.length -= 10;
38465 } else {
38466 input.length -= 9;
38467 }
38468 };
38469
38470 K256.prototype.imulK = function imulK (num) {
38471 // K = 0x1000003d1 = [ 0x40, 0x3d1 ]
38472 num.words[num.length] = 0;
38473 num.words[num.length + 1] = 0;
38474 num.length += 2;
38475
38476 // bounded at: 0x40 * 0x3ffffff + 0x3d0 = 0x100000390
38477 var lo = 0;
38478 for (var i = 0; i < num.length; i++) {
38479 var w = num.words[i] | 0;
38480 lo += w * 0x3d1;
38481 num.words[i] = lo & 0x3ffffff;
38482 lo = w * 0x40 + ((lo / 0x4000000) | 0);
38483 }
38484
38485 // Fast length reduction
38486 if (num.words[num.length - 1] === 0) {
38487 num.length--;
38488 if (num.words[num.length - 1] === 0) {
38489 num.length--;
38490 }
38491 }
38492 return num;
38493 };
38494
38495 function P224 () {
38496 MPrime.call(
38497 this,
38498 'p224',
38499 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001');
38500 }
38501 inherits(P224, MPrime);
38502
38503 function P192 () {
38504 MPrime.call(
38505 this,
38506 'p192',
38507 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff');
38508 }
38509 inherits(P192, MPrime);
38510
38511 function P25519 () {
38512 // 2 ^ 255 - 19
38513 MPrime.call(
38514 this,
38515 '25519',
38516 '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed');
38517 }
38518 inherits(P25519, MPrime);
38519
38520 P25519.prototype.imulK = function imulK (num) {
38521 // K = 0x13
38522 var carry = 0;
38523 for (var i = 0; i < num.length; i++) {
38524 var hi = (num.words[i] | 0) * 0x13 + carry;
38525 var lo = hi & 0x3ffffff;
38526 hi >>>= 26;
38527
38528 num.words[i] = lo;
38529 carry = hi;
38530 }
38531 if (carry !== 0) {
38532 num.words[num.length++] = carry;
38533 }
38534 return num;
38535 };
38536
38537 // Exported mostly for testing purposes, use plain name instead
38538 BN._prime = function prime (name) {
38539 // Cached version of prime
38540 if (primes[name]) return primes[name];
38541
38542 var prime;
38543 if (name === 'k256') {
38544 prime = new K256();
38545 } else if (name === 'p224') {
38546 prime = new P224();
38547 } else if (name === 'p192') {
38548 prime = new P192();
38549 } else if (name === 'p25519') {
38550 prime = new P25519();
38551 } else {
38552 throw new Error('Unknown prime ' + name);
38553 }
38554 primes[name] = prime;
38555
38556 return prime;
38557 };
38558
38559 //
38560 // Base reduction engine
38561 //
38562 function Red (m) {
38563 if (typeof m === 'string') {
38564 var prime = BN._prime(m);
38565 this.m = prime.p;
38566 this.prime = prime;
38567 } else {
38568 assert(m.gtn(1), 'modulus must be greater than 1');
38569 this.m = m;
38570 this.prime = null;
38571 }
38572 }
38573
38574 Red.prototype._verify1 = function _verify1 (a) {
38575 assert(a.negative === 0, 'red works only with positives');
38576 assert(a.red, 'red works only with red numbers');
38577 };
38578
38579 Red.prototype._verify2 = function _verify2 (a, b) {
38580 assert((a.negative | b.negative) === 0, 'red works only with positives');
38581 assert(a.red && a.red === b.red,
38582 'red works only with red numbers');
38583 };
38584
38585 Red.prototype.imod = function imod (a) {
38586 if (this.prime) return this.prime.ireduce(a)._forceRed(this);
38587 return a.umod(this.m)._forceRed(this);
38588 };
38589
38590 Red.prototype.neg = function neg (a) {
38591 if (a.isZero()) {
38592 return a.clone();
38593 }
38594
38595 return this.m.sub(a)._forceRed(this);
38596 };
38597
38598 Red.prototype.add = function add (a, b) {
38599 this._verify2(a, b);
38600
38601 var res = a.add(b);
38602 if (res.cmp(this.m) >= 0) {
38603 res.isub(this.m);
38604 }
38605 return res._forceRed(this);
38606 };
38607
38608 Red.prototype.iadd = function iadd (a, b) {
38609 this._verify2(a, b);
38610
38611 var res = a.iadd(b);
38612 if (res.cmp(this.m) >= 0) {
38613 res.isub(this.m);
38614 }
38615 return res;
38616 };
38617
38618 Red.prototype.sub = function sub (a, b) {
38619 this._verify2(a, b);
38620
38621 var res = a.sub(b);
38622 if (res.cmpn(0) < 0) {
38623 res.iadd(this.m);
38624 }
38625 return res._forceRed(this);
38626 };
38627
38628 Red.prototype.isub = function isub (a, b) {
38629 this._verify2(a, b);
38630
38631 var res = a.isub(b);
38632 if (res.cmpn(0) < 0) {
38633 res.iadd(this.m);
38634 }
38635 return res;
38636 };
38637
38638 Red.prototype.shl = function shl (a, num) {
38639 this._verify1(a);
38640 return this.imod(a.ushln(num));
38641 };
38642
38643 Red.prototype.imul = function imul (a, b) {
38644 this._verify2(a, b);
38645 return this.imod(a.imul(b));
38646 };
38647
38648 Red.prototype.mul = function mul (a, b) {
38649 this._verify2(a, b);
38650 return this.imod(a.mul(b));
38651 };
38652
38653 Red.prototype.isqr = function isqr (a) {
38654 return this.imul(a, a.clone());
38655 };
38656
38657 Red.prototype.sqr = function sqr (a) {
38658 return this.mul(a, a);
38659 };
38660
38661 Red.prototype.sqrt = function sqrt (a) {
38662 if (a.isZero()) return a.clone();
38663
38664 var mod3 = this.m.andln(3);
38665 assert(mod3 % 2 === 1);
38666
38667 // Fast case
38668 if (mod3 === 3) {
38669 var pow = this.m.add(new BN(1)).iushrn(2);
38670 return this.pow(a, pow);
38671 }
38672
38673 // Tonelli-Shanks algorithm (Totally unoptimized and slow)
38674 //
38675 // Find Q and S, that Q * 2 ^ S = (P - 1)
38676 var q = this.m.subn(1);
38677 var s = 0;
38678 while (!q.isZero() && q.andln(1) === 0) {
38679 s++;
38680 q.iushrn(1);
38681 }
38682 assert(!q.isZero());
38683
38684 var one = new BN(1).toRed(this);
38685 var nOne = one.redNeg();
38686
38687 // Find quadratic non-residue
38688 // NOTE: Max is such because of generalized Riemann hypothesis.
38689 var lpow = this.m.subn(1).iushrn(1);
38690 var z = this.m.bitLength();
38691 z = new BN(2 * z * z).toRed(this);
38692
38693 while (this.pow(z, lpow).cmp(nOne) !== 0) {
38694 z.redIAdd(nOne);
38695 }
38696
38697 var c = this.pow(z, q);
38698 var r = this.pow(a, q.addn(1).iushrn(1));
38699 var t = this.pow(a, q);
38700 var m = s;
38701 while (t.cmp(one) !== 0) {
38702 var tmp = t;
38703 for (var i = 0; tmp.cmp(one) !== 0; i++) {
38704 tmp = tmp.redSqr();
38705 }
38706 assert(i < m);
38707 var b = this.pow(c, new BN(1).iushln(m - i - 1));
38708
38709 r = r.redMul(b);
38710 c = b.redSqr();
38711 t = t.redMul(c);
38712 m = i;
38713 }
38714
38715 return r;
38716 };
38717
38718 Red.prototype.invm = function invm (a) {
38719 var inv = a._invmp(this.m);
38720 if (inv.negative !== 0) {
38721 inv.negative = 0;
38722 return this.imod(inv).redNeg();
38723 } else {
38724 return this.imod(inv);
38725 }
38726 };
38727
38728 Red.prototype.pow = function pow (a, num) {
38729 if (num.isZero()) return new BN(1).toRed(this);
38730 if (num.cmpn(1) === 0) return a.clone();
38731
38732 var windowSize = 4;
38733 var wnd = new Array(1 << windowSize);
38734 wnd[0] = new BN(1).toRed(this);
38735 wnd[1] = a;
38736 for (var i = 2; i < wnd.length; i++) {
38737 wnd[i] = this.mul(wnd[i - 1], a);
38738 }
38739
38740 var res = wnd[0];
38741 var current = 0;
38742 var currentLen = 0;
38743 var start = num.bitLength() % 26;
38744 if (start === 0) {
38745 start = 26;
38746 }
38747
38748 for (i = num.length - 1; i >= 0; i--) {
38749 var word = num.words[i];
38750 for (var j = start - 1; j >= 0; j--) {
38751 var bit = (word >> j) & 1;
38752 if (res !== wnd[0]) {
38753 res = this.sqr(res);
38754 }
38755
38756 if (bit === 0 && current === 0) {
38757 currentLen = 0;
38758 continue;
38759 }
38760
38761 current <<= 1;
38762 current |= bit;
38763 currentLen++;
38764 if (currentLen !== windowSize && (i !== 0 || j !== 0)) continue;
38765
38766 res = this.mul(res, wnd[current]);
38767 currentLen = 0;
38768 current = 0;
38769 }
38770 start = 26;
38771 }
38772
38773 return res;
38774 };
38775
38776 Red.prototype.convertTo = function convertTo (num) {
38777 var r = num.umod(this.m);
38778
38779 return r === num ? r.clone() : r;
38780 };
38781
38782 Red.prototype.convertFrom = function convertFrom (num) {
38783 var res = num.clone();
38784 res.red = null;
38785 return res;
38786 };
38787
38788 //
38789 // Montgomery method engine
38790 //
38791
38792 BN.mont = function mont (num) {
38793 return new Mont(num);
38794 };
38795
38796 function Mont (m) {
38797 Red.call(this, m);
38798
38799 this.shift = this.m.bitLength();
38800 if (this.shift % 26 !== 0) {
38801 this.shift += 26 - (this.shift % 26);
38802 }
38803
38804 this.r = new BN(1).iushln(this.shift);
38805 this.r2 = this.imod(this.r.sqr());
38806 this.rinv = this.r._invmp(this.m);
38807
38808 this.minv = this.rinv.mul(this.r).isubn(1).div(this.m);
38809 this.minv = this.minv.umod(this.r);
38810 this.minv = this.r.sub(this.minv);
38811 }
38812 inherits(Mont, Red);
38813
38814 Mont.prototype.convertTo = function convertTo (num) {
38815 return this.imod(num.ushln(this.shift));
38816 };
38817
38818 Mont.prototype.convertFrom = function convertFrom (num) {
38819 var r = this.imod(num.mul(this.rinv));
38820 r.red = null;
38821 return r;
38822 };
38823
38824 Mont.prototype.imul = function imul (a, b) {
38825 if (a.isZero() || b.isZero()) {
38826 a.words[0] = 0;
38827 a.length = 1;
38828 return a;
38829 }
38830
38831 var t = a.imul(b);
38832 var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
38833 var u = t.isub(c).iushrn(this.shift);
38834 var res = u;
38835
38836 if (u.cmp(this.m) >= 0) {
38837 res = u.isub(this.m);
38838 } else if (u.cmpn(0) < 0) {
38839 res = u.iadd(this.m);
38840 }
38841
38842 return res._forceRed(this);
38843 };
38844
38845 Mont.prototype.mul = function mul (a, b) {
38846 if (a.isZero() || b.isZero()) return new BN(0)._forceRed(this);
38847
38848 var t = a.mul(b);
38849 var c = t.maskn(this.shift).mul(this.minv).imaskn(this.shift).mul(this.m);
38850 var u = t.isub(c).iushrn(this.shift);
38851 var res = u;
38852 if (u.cmp(this.m) >= 0) {
38853 res = u.isub(this.m);
38854 } else if (u.cmpn(0) < 0) {
38855 res = u.iadd(this.m);
38856 }
38857
38858 return res._forceRed(this);
38859 };
38860
38861 Mont.prototype.invm = function invm (a) {
38862 // (AR)^-1 * R^2 = (A^-1 * R^-1) * R^2 = A^-1 * R
38863 var res = this.imod(a._invmp(this.m).mul(this.r2));
38864 return res._forceRed(this);
38865 };
38866})(module, commonjsGlobal);
38867});
38868
38869var bn$1 = /*#__PURE__*/Object.freeze({
38870 __proto__: null,
38871 'default': bn,
38872 __moduleExports: bn
38873});
38874
38875/**
38876 * @fileoverview
38877 * BigInteger implementation of basic operations
38878 * Wrapper of bn.js library (wwww.github.com/indutny/bn.js)
38879 * @module biginteger/bn
38880 * @private
38881 */
38882
38883/**
38884 * @private
38885 */
38886class BigInteger$1 {
38887 /**
38888 * Get a BigInteger (input must be big endian for strings and arrays)
38889 * @param {Number|String|Uint8Array} n - Value to convert
38890 * @throws {Error} on undefined input
38891 */
38892 constructor(n) {
38893 if (n === undefined) {
38894 throw new Error('Invalid BigInteger input');
38895 }
38896
38897 this.value = new bn(n);
38898 }
38899
38900 clone() {
38901 const clone = new BigInteger$1(null);
38902 this.value.copy(clone.value);
38903 return clone;
38904 }
38905
38906 /**
38907 * BigInteger increment in place
38908 */
38909 iinc() {
38910 this.value.iadd(new bn(1));
38911 return this;
38912 }
38913
38914 /**
38915 * BigInteger increment
38916 * @returns {BigInteger} this + 1.
38917 */
38918 inc() {
38919 return this.clone().iinc();
38920 }
38921
38922 /**
38923 * BigInteger decrement in place
38924 */
38925 idec() {
38926 this.value.isub(new bn(1));
38927 return this;
38928 }
38929
38930 /**
38931 * BigInteger decrement
38932 * @returns {BigInteger} this - 1.
38933 */
38934 dec() {
38935 return this.clone().idec();
38936 }
38937
38938
38939 /**
38940 * BigInteger addition in place
38941 * @param {BigInteger} x - Value to add
38942 */
38943 iadd(x) {
38944 this.value.iadd(x.value);
38945 return this;
38946 }
38947
38948 /**
38949 * BigInteger addition
38950 * @param {BigInteger} x - Value to add
38951 * @returns {BigInteger} this + x.
38952 */
38953 add(x) {
38954 return this.clone().iadd(x);
38955 }
38956
38957 /**
38958 * BigInteger subtraction in place
38959 * @param {BigInteger} x - Value to subtract
38960 */
38961 isub(x) {
38962 this.value.isub(x.value);
38963 return this;
38964 }
38965
38966 /**
38967 * BigInteger subtraction
38968 * @param {BigInteger} x - Value to subtract
38969 * @returns {BigInteger} this - x.
38970 */
38971 sub(x) {
38972 return this.clone().isub(x);
38973 }
38974
38975 /**
38976 * BigInteger multiplication in place
38977 * @param {BigInteger} x - Value to multiply
38978 */
38979 imul(x) {
38980 this.value.imul(x.value);
38981 return this;
38982 }
38983
38984 /**
38985 * BigInteger multiplication
38986 * @param {BigInteger} x - Value to multiply
38987 * @returns {BigInteger} this * x.
38988 */
38989 mul(x) {
38990 return this.clone().imul(x);
38991 }
38992
38993 /**
38994 * Compute value modulo m, in place
38995 * @param {BigInteger} m - Modulo
38996 */
38997 imod(m) {
38998 this.value = this.value.umod(m.value);
38999 return this;
39000 }
39001
39002 /**
39003 * Compute value modulo m
39004 * @param {BigInteger} m - Modulo
39005 * @returns {BigInteger} this mod m.
39006 */
39007 mod(m) {
39008 return this.clone().imod(m);
39009 }
39010
39011 /**
39012 * Compute modular exponentiation
39013 * Much faster than this.exp(e).mod(n)
39014 * @param {BigInteger} e - Exponent
39015 * @param {BigInteger} n - Modulo
39016 * @returns {BigInteger} this ** e mod n.
39017 */
39018 modExp(e, n) {
39019 // We use either Montgomery or normal reduction context
39020 // Montgomery requires coprime n and R (montogmery multiplier)
39021 // bn.js picks R as power of 2, so n must be odd
39022 const nred = n.isEven() ? bn.red(n.value) : bn.mont(n.value);
39023 const x = this.clone();
39024 x.value = x.value.toRed(nred).redPow(e.value).fromRed();
39025 return x;
39026 }
39027
39028 /**
39029 * Compute the inverse of this value modulo n
39030 * Note: this and and n must be relatively prime
39031 * @param {BigInteger} n - Modulo
39032 * @returns {BigInteger} x such that this*x = 1 mod n
39033 * @throws {Error} if the inverse does not exist
39034 */
39035 modInv(n) {
39036 // invm returns a wrong result if the inverse does not exist
39037 if (!this.gcd(n).isOne()) {
39038 throw new Error('Inverse does not exist');
39039 }
39040 return new BigInteger$1(this.value.invm(n.value));
39041 }
39042
39043 /**
39044 * Compute greatest common divisor between this and n
39045 * @param {BigInteger} n - Operand
39046 * @returns {BigInteger} gcd
39047 */
39048 gcd(n) {
39049 return new BigInteger$1(this.value.gcd(n.value));
39050 }
39051
39052 /**
39053 * Shift this to the left by x, in place
39054 * @param {BigInteger} x - Shift value
39055 */
39056 ileftShift(x) {
39057 this.value.ishln(x.value.toNumber());
39058 return this;
39059 }
39060
39061 /**
39062 * Shift this to the left by x
39063 * @param {BigInteger} x - Shift value
39064 * @returns {BigInteger} this << x.
39065 */
39066 leftShift(x) {
39067 return this.clone().ileftShift(x);
39068 }
39069
39070 /**
39071 * Shift this to the right by x, in place
39072 * @param {BigInteger} x - Shift value
39073 */
39074 irightShift(x) {
39075 this.value.ishrn(x.value.toNumber());
39076 return this;
39077 }
39078
39079 /**
39080 * Shift this to the right by x
39081 * @param {BigInteger} x - Shift value
39082 * @returns {BigInteger} this >> x.
39083 */
39084 rightShift(x) {
39085 return this.clone().irightShift(x);
39086 }
39087
39088 /**
39089 * Whether this value is equal to x
39090 * @param {BigInteger} x
39091 * @returns {Boolean}
39092 */
39093 equal(x) {
39094 return this.value.eq(x.value);
39095 }
39096
39097 /**
39098 * Whether this value is less than x
39099 * @param {BigInteger} x
39100 * @returns {Boolean}
39101 */
39102 lt(x) {
39103 return this.value.lt(x.value);
39104 }
39105
39106 /**
39107 * Whether this value is less than or equal to x
39108 * @param {BigInteger} x
39109 * @returns {Boolean}
39110 */
39111 lte(x) {
39112 return this.value.lte(x.value);
39113 }
39114
39115 /**
39116 * Whether this value is greater than x
39117 * @param {BigInteger} x
39118 * @returns {Boolean}
39119 */
39120 gt(x) {
39121 return this.value.gt(x.value);
39122 }
39123
39124 /**
39125 * Whether this value is greater than or equal to x
39126 * @param {BigInteger} x
39127 * @returns {Boolean}
39128 */
39129 gte(x) {
39130 return this.value.gte(x.value);
39131 }
39132
39133 isZero() {
39134 return this.value.isZero();
39135 }
39136
39137 isOne() {
39138 return this.value.eq(new bn(1));
39139 }
39140
39141 isNegative() {
39142 return this.value.isNeg();
39143 }
39144
39145 isEven() {
39146 return this.value.isEven();
39147 }
39148
39149 abs() {
39150 const res = this.clone();
39151 res.value = res.value.abs();
39152 return res;
39153 }
39154
39155 /**
39156 * Get this value as a string
39157 * @returns {String} this value.
39158 */
39159 toString() {
39160 return this.value.toString();
39161 }
39162
39163 /**
39164 * Get this value as an exact Number (max 53 bits)
39165 * Fails if this value is too large
39166 * @returns {Number}
39167 */
39168 toNumber() {
39169 return this.value.toNumber();
39170 }
39171
39172 /**
39173 * Get value of i-th bit
39174 * @param {Number} i - Bit index
39175 * @returns {Number} Bit value.
39176 */
39177 getBit(i) {
39178 return this.value.testn(i) ? 1 : 0;
39179 }
39180
39181 /**
39182 * Compute bit length
39183 * @returns {Number} Bit length.
39184 */
39185 bitLength() {
39186 return this.value.bitLength();
39187 }
39188
39189 /**
39190 * Compute byte length
39191 * @returns {Number} Byte length.
39192 */
39193 byteLength() {
39194 return this.value.byteLength();
39195 }
39196
39197 /**
39198 * Get Uint8Array representation of this number
39199 * @param {String} endian - Endianess of output array (defaults to 'be')
39200 * @param {Number} length - Of output array
39201 * @returns {Uint8Array}
39202 */
39203 toUint8Array(endian = 'be', length) {
39204 return this.value.toArrayLike(Uint8Array, endian, length);
39205 }
39206}
39207
39208var bn_interface = /*#__PURE__*/Object.freeze({
39209 __proto__: null,
39210 'default': BigInteger$1
39211});
39212
39213var utils_1 = createCommonjsModule(function (module, exports) {
39214
39215var utils = exports;
39216
39217function toArray(msg, enc) {
39218 if (Array.isArray(msg))
39219 return msg.slice();
39220 if (!msg)
39221 return [];
39222 var res = [];
39223 if (typeof msg !== 'string') {
39224 for (var i = 0; i < msg.length; i++)
39225 res[i] = msg[i] | 0;
39226 return res;
39227 }
39228 if (enc === 'hex') {
39229 msg = msg.replace(/[^a-z0-9]+/ig, '');
39230 if (msg.length % 2 !== 0)
39231 msg = '0' + msg;
39232 for (var i = 0; i < msg.length; i += 2)
39233 res.push(parseInt(msg[i] + msg[i + 1], 16));
39234 } else {
39235 for (var i = 0; i < msg.length; i++) {
39236 var c = msg.charCodeAt(i);
39237 var hi = c >> 8;
39238 var lo = c & 0xff;
39239 if (hi)
39240 res.push(hi, lo);
39241 else
39242 res.push(lo);
39243 }
39244 }
39245 return res;
39246}
39247utils.toArray = toArray;
39248
39249function zero2(word) {
39250 if (word.length === 1)
39251 return '0' + word;
39252 else
39253 return word;
39254}
39255utils.zero2 = zero2;
39256
39257function toHex(msg) {
39258 var res = '';
39259 for (var i = 0; i < msg.length; i++)
39260 res += zero2(msg[i].toString(16));
39261 return res;
39262}
39263utils.toHex = toHex;
39264
39265utils.encode = function encode(arr, enc) {
39266 if (enc === 'hex')
39267 return toHex(arr);
39268 else
39269 return arr;
39270};
39271});
39272
39273var utils_1$1 = createCommonjsModule(function (module, exports) {
39274
39275var utils = exports;
39276
39277
39278
39279
39280utils.assert = minimalisticAssert;
39281utils.toArray = utils_1.toArray;
39282utils.zero2 = utils_1.zero2;
39283utils.toHex = utils_1.toHex;
39284utils.encode = utils_1.encode;
39285
39286// Represent num in a w-NAF form
39287function getNAF(num, w) {
39288 var naf = [];
39289 var ws = 1 << (w + 1);
39290 var k = num.clone();
39291 while (k.cmpn(1) >= 0) {
39292 var z;
39293 if (k.isOdd()) {
39294 var mod = k.andln(ws - 1);
39295 if (mod > (ws >> 1) - 1)
39296 z = (ws >> 1) - mod;
39297 else
39298 z = mod;
39299 k.isubn(z);
39300 } else {
39301 z = 0;
39302 }
39303 naf.push(z);
39304
39305 // Optimization, shift by word if possible
39306 var shift = (k.cmpn(0) !== 0 && k.andln(ws - 1) === 0) ? (w + 1) : 1;
39307 for (var i = 1; i < shift; i++)
39308 naf.push(0);
39309 k.iushrn(shift);
39310 }
39311
39312 return naf;
39313}
39314utils.getNAF = getNAF;
39315
39316// Represent k1, k2 in a Joint Sparse Form
39317function getJSF(k1, k2) {
39318 var jsf = [
39319 [],
39320 []
39321 ];
39322
39323 k1 = k1.clone();
39324 k2 = k2.clone();
39325 var d1 = 0;
39326 var d2 = 0;
39327 while (k1.cmpn(-d1) > 0 || k2.cmpn(-d2) > 0) {
39328
39329 // First phase
39330 var m14 = (k1.andln(3) + d1) & 3;
39331 var m24 = (k2.andln(3) + d2) & 3;
39332 if (m14 === 3)
39333 m14 = -1;
39334 if (m24 === 3)
39335 m24 = -1;
39336 var u1;
39337 if ((m14 & 1) === 0) {
39338 u1 = 0;
39339 } else {
39340 var m8 = (k1.andln(7) + d1) & 7;
39341 if ((m8 === 3 || m8 === 5) && m24 === 2)
39342 u1 = -m14;
39343 else
39344 u1 = m14;
39345 }
39346 jsf[0].push(u1);
39347
39348 var u2;
39349 if ((m24 & 1) === 0) {
39350 u2 = 0;
39351 } else {
39352 var m8 = (k2.andln(7) + d2) & 7;
39353 if ((m8 === 3 || m8 === 5) && m14 === 2)
39354 u2 = -m24;
39355 else
39356 u2 = m24;
39357 }
39358 jsf[1].push(u2);
39359
39360 // Second phase
39361 if (2 * d1 === u1 + 1)
39362 d1 = 1 - d1;
39363 if (2 * d2 === u2 + 1)
39364 d2 = 1 - d2;
39365 k1.iushrn(1);
39366 k2.iushrn(1);
39367 }
39368
39369 return jsf;
39370}
39371utils.getJSF = getJSF;
39372
39373function cachedProperty(obj, name, computer) {
39374 var key = '_' + name;
39375 obj.prototype[name] = function cachedProperty() {
39376 return this[key] !== undefined ? this[key] :
39377 this[key] = computer.call(this);
39378 };
39379}
39380utils.cachedProperty = cachedProperty;
39381
39382function parseBytes(bytes) {
39383 return typeof bytes === 'string' ? utils.toArray(bytes, 'hex') :
39384 bytes;
39385}
39386utils.parseBytes = parseBytes;
39387
39388function intFromLE(bytes) {
39389 return new bn(bytes, 'hex', 'le');
39390}
39391utils.intFromLE = intFromLE;
39392});
39393
39394var r$1;
39395
39396var brorand = function rand(len) {
39397 if (!r$1)
39398 r$1 = new Rand(null);
39399
39400 return r$1.generate(len);
39401};
39402
39403function Rand(rand) {
39404 this.rand = rand;
39405}
39406var Rand_1 = Rand;
39407
39408Rand.prototype.generate = function generate(len) {
39409 return this._rand(len);
39410};
39411
39412// Emulate crypto API using randy
39413Rand.prototype._rand = function _rand(n) {
39414 if (this.rand.getBytes)
39415 return this.rand.getBytes(n);
39416
39417 var res = new Uint8Array(n);
39418 for (var i = 0; i < res.length; i++)
39419 res[i] = this.rand.getByte();
39420 return res;
39421};
39422
39423if (typeof self === 'object') {
39424 if (self.crypto && self.crypto.getRandomValues) {
39425 // Modern browsers
39426 Rand.prototype._rand = function _rand(n) {
39427 var arr = new Uint8Array(n);
39428 self.crypto.getRandomValues(arr);
39429 return arr;
39430 };
39431 } else if (self.msCrypto && self.msCrypto.getRandomValues) {
39432 // IE
39433 Rand.prototype._rand = function _rand(n) {
39434 var arr = new Uint8Array(n);
39435 self.msCrypto.getRandomValues(arr);
39436 return arr;
39437 };
39438
39439 // Safari's WebWorkers do not have `crypto`
39440 } else if (typeof window === 'object') {
39441 // Old junk
39442 Rand.prototype._rand = function() {
39443 throw new Error('Not implemented yet');
39444 };
39445 }
39446} else {
39447 // Node.js or Web worker with no crypto support
39448 try {
39449 var crypto$2 = crypto$3;
39450 if (typeof crypto$2.randomBytes !== 'function')
39451 throw new Error('Not supported');
39452
39453 Rand.prototype._rand = function _rand(n) {
39454 return crypto$2.randomBytes(n);
39455 };
39456 } catch (e) {
39457 }
39458}
39459brorand.Rand = Rand_1;
39460
39461var getNAF = utils_1$1.getNAF;
39462var getJSF = utils_1$1.getJSF;
39463var assert$2 = utils_1$1.assert;
39464
39465function BaseCurve(type, conf) {
39466 this.type = type;
39467 this.p = new bn(conf.p, 16);
39468
39469 // Use Montgomery, when there is no fast reduction for the prime
39470 this.red = conf.prime ? bn.red(conf.prime) : bn.mont(this.p);
39471
39472 // Useful for many curves
39473 this.zero = new bn(0).toRed(this.red);
39474 this.one = new bn(1).toRed(this.red);
39475 this.two = new bn(2).toRed(this.red);
39476
39477 // Curve configuration, optional
39478 this.n = conf.n && new bn(conf.n, 16);
39479 this.g = conf.g && this.pointFromJSON(conf.g, conf.gRed);
39480
39481 // Temporary arrays
39482 this._wnafT1 = new Array(4);
39483 this._wnafT2 = new Array(4);
39484 this._wnafT3 = new Array(4);
39485 this._wnafT4 = new Array(4);
39486
39487 // Generalized Greg Maxwell's trick
39488 var adjustCount = this.n && this.p.div(this.n);
39489 if (!adjustCount || adjustCount.cmpn(100) > 0) {
39490 this.redN = null;
39491 } else {
39492 this._maxwellTrick = true;
39493 this.redN = this.n.toRed(this.red);
39494 }
39495}
39496var base = BaseCurve;
39497
39498BaseCurve.prototype.point = function point() {
39499 throw new Error('Not implemented');
39500};
39501
39502BaseCurve.prototype.validate = function validate() {
39503 throw new Error('Not implemented');
39504};
39505
39506BaseCurve.prototype._fixedNafMul = function _fixedNafMul(p, k) {
39507 assert$2(p.precomputed);
39508 var doubles = p._getDoubles();
39509
39510 var naf = getNAF(k, 1);
39511 var I = (1 << (doubles.step + 1)) - (doubles.step % 2 === 0 ? 2 : 1);
39512 I /= 3;
39513
39514 // Translate into more windowed form
39515 var repr = [];
39516 for (var j = 0; j < naf.length; j += doubles.step) {
39517 var nafW = 0;
39518 for (var k = j + doubles.step - 1; k >= j; k--)
39519 nafW = (nafW << 1) + naf[k];
39520 repr.push(nafW);
39521 }
39522
39523 var a = this.jpoint(null, null, null);
39524 var b = this.jpoint(null, null, null);
39525 for (var i = I; i > 0; i--) {
39526 for (var j = 0; j < repr.length; j++) {
39527 var nafW = repr[j];
39528 if (nafW === i)
39529 b = b.mixedAdd(doubles.points[j]);
39530 else if (nafW === -i)
39531 b = b.mixedAdd(doubles.points[j].neg());
39532 }
39533 a = a.add(b);
39534 }
39535 return a.toP();
39536};
39537
39538BaseCurve.prototype._wnafMul = function _wnafMul(p, k) {
39539 var w = 4;
39540
39541 // Precompute window
39542 var nafPoints = p._getNAFPoints(w);
39543 w = nafPoints.wnd;
39544 var wnd = nafPoints.points;
39545
39546 // Get NAF form
39547 var naf = getNAF(k, w);
39548
39549 // Add `this`*(N+1) for every w-NAF index
39550 var acc = this.jpoint(null, null, null);
39551 for (var i = naf.length - 1; i >= 0; i--) {
39552 // Count zeroes
39553 for (var k = 0; i >= 0 && naf[i] === 0; i--)
39554 k++;
39555 if (i >= 0)
39556 k++;
39557 acc = acc.dblp(k);
39558
39559 if (i < 0)
39560 break;
39561 var z = naf[i];
39562 assert$2(z !== 0);
39563 if (p.type === 'affine') {
39564 // J +- P
39565 if (z > 0)
39566 acc = acc.mixedAdd(wnd[(z - 1) >> 1]);
39567 else
39568 acc = acc.mixedAdd(wnd[(-z - 1) >> 1].neg());
39569 } else {
39570 // J +- J
39571 if (z > 0)
39572 acc = acc.add(wnd[(z - 1) >> 1]);
39573 else
39574 acc = acc.add(wnd[(-z - 1) >> 1].neg());
39575 }
39576 }
39577 return p.type === 'affine' ? acc.toP() : acc;
39578};
39579
39580BaseCurve.prototype._wnafMulAdd = function _wnafMulAdd(defW,
39581 points,
39582 coeffs,
39583 len,
39584 jacobianResult) {
39585 var wndWidth = this._wnafT1;
39586 var wnd = this._wnafT2;
39587 var naf = this._wnafT3;
39588
39589 // Fill all arrays
39590 var max = 0;
39591 for (var i = 0; i < len; i++) {
39592 var p = points[i];
39593 var nafPoints = p._getNAFPoints(defW);
39594 wndWidth[i] = nafPoints.wnd;
39595 wnd[i] = nafPoints.points;
39596 }
39597
39598 // Comb small window NAFs
39599 for (var i = len - 1; i >= 1; i -= 2) {
39600 var a = i - 1;
39601 var b = i;
39602 if (wndWidth[a] !== 1 || wndWidth[b] !== 1) {
39603 naf[a] = getNAF(coeffs[a], wndWidth[a]);
39604 naf[b] = getNAF(coeffs[b], wndWidth[b]);
39605 max = Math.max(naf[a].length, max);
39606 max = Math.max(naf[b].length, max);
39607 continue;
39608 }
39609
39610 var comb = [
39611 points[a], /* 1 */
39612 null, /* 3 */
39613 null, /* 5 */
39614 points[b] /* 7 */
39615 ];
39616
39617 // Try to avoid Projective points, if possible
39618 if (points[a].y.cmp(points[b].y) === 0) {
39619 comb[1] = points[a].add(points[b]);
39620 comb[2] = points[a].toJ().mixedAdd(points[b].neg());
39621 } else if (points[a].y.cmp(points[b].y.redNeg()) === 0) {
39622 comb[1] = points[a].toJ().mixedAdd(points[b]);
39623 comb[2] = points[a].add(points[b].neg());
39624 } else {
39625 comb[1] = points[a].toJ().mixedAdd(points[b]);
39626 comb[2] = points[a].toJ().mixedAdd(points[b].neg());
39627 }
39628
39629 var index = [
39630 -3, /* -1 -1 */
39631 -1, /* -1 0 */
39632 -5, /* -1 1 */
39633 -7, /* 0 -1 */
39634 0, /* 0 0 */
39635 7, /* 0 1 */
39636 5, /* 1 -1 */
39637 1, /* 1 0 */
39638 3 /* 1 1 */
39639 ];
39640
39641 var jsf = getJSF(coeffs[a], coeffs[b]);
39642 max = Math.max(jsf[0].length, max);
39643 naf[a] = new Array(max);
39644 naf[b] = new Array(max);
39645 for (var j = 0; j < max; j++) {
39646 var ja = jsf[0][j] | 0;
39647 var jb = jsf[1][j] | 0;
39648
39649 naf[a][j] = index[(ja + 1) * 3 + (jb + 1)];
39650 naf[b][j] = 0;
39651 wnd[a] = comb;
39652 }
39653 }
39654
39655 var acc = this.jpoint(null, null, null);
39656 var tmp = this._wnafT4;
39657 for (var i = max; i >= 0; i--) {
39658 var k = 0;
39659
39660 while (i >= 0) {
39661 var zero = true;
39662 for (var j = 0; j < len; j++) {
39663 tmp[j] = naf[j][i] | 0;
39664 if (tmp[j] !== 0)
39665 zero = false;
39666 }
39667 if (!zero)
39668 break;
39669 k++;
39670 i--;
39671 }
39672 if (i >= 0)
39673 k++;
39674 acc = acc.dblp(k);
39675 if (i < 0)
39676 break;
39677
39678 for (var j = 0; j < len; j++) {
39679 var z = tmp[j];
39680 var p;
39681 if (z === 0)
39682 continue;
39683 else if (z > 0)
39684 p = wnd[j][(z - 1) >> 1];
39685 else if (z < 0)
39686 p = wnd[j][(-z - 1) >> 1].neg();
39687
39688 if (p.type === 'affine')
39689 acc = acc.mixedAdd(p);
39690 else
39691 acc = acc.add(p);
39692 }
39693 }
39694 // Zeroify references
39695 for (var i = 0; i < len; i++)
39696 wnd[i] = null;
39697
39698 if (jacobianResult)
39699 return acc;
39700 else
39701 return acc.toP();
39702};
39703
39704function BasePoint(curve, type) {
39705 this.curve = curve;
39706 this.type = type;
39707 this.precomputed = null;
39708}
39709BaseCurve.BasePoint = BasePoint;
39710
39711BasePoint.prototype.eq = function eq(/*other*/) {
39712 throw new Error('Not implemented');
39713};
39714
39715BasePoint.prototype.validate = function validate() {
39716 return this.curve.validate(this);
39717};
39718
39719BaseCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
39720 bytes = utils_1$1.toArray(bytes, enc);
39721
39722 var len = this.p.byteLength();
39723
39724 // uncompressed, hybrid-odd, hybrid-even
39725 if ((bytes[0] === 0x04 || bytes[0] === 0x06 || bytes[0] === 0x07) &&
39726 bytes.length - 1 === 2 * len) {
39727 if (bytes[0] === 0x06)
39728 assert$2(bytes[bytes.length - 1] % 2 === 0);
39729 else if (bytes[0] === 0x07)
39730 assert$2(bytes[bytes.length - 1] % 2 === 1);
39731
39732 var res = this.point(bytes.slice(1, 1 + len),
39733 bytes.slice(1 + len, 1 + 2 * len));
39734
39735 return res;
39736 } else if ((bytes[0] === 0x02 || bytes[0] === 0x03) &&
39737 bytes.length - 1 === len) {
39738 return this.pointFromX(bytes.slice(1, 1 + len), bytes[0] === 0x03);
39739 }
39740 throw new Error('Unknown point format');
39741};
39742
39743BasePoint.prototype.encodeCompressed = function encodeCompressed(enc) {
39744 return this.encode(enc, true);
39745};
39746
39747BasePoint.prototype._encode = function _encode(compact) {
39748 var len = this.curve.p.byteLength();
39749 var x = this.getX().toArray('be', len);
39750
39751 if (compact)
39752 return [ this.getY().isEven() ? 0x02 : 0x03 ].concat(x);
39753
39754 return [ 0x04 ].concat(x, this.getY().toArray('be', len)) ;
39755};
39756
39757BasePoint.prototype.encode = function encode(enc, compact) {
39758 return utils_1$1.encode(this._encode(compact), enc);
39759};
39760
39761BasePoint.prototype.precompute = function precompute(power) {
39762 if (this.precomputed)
39763 return this;
39764
39765 var precomputed = {
39766 doubles: null,
39767 naf: null,
39768 beta: null
39769 };
39770 precomputed.naf = this._getNAFPoints(8);
39771 precomputed.doubles = this._getDoubles(4, power);
39772 precomputed.beta = this._getBeta();
39773 this.precomputed = precomputed;
39774
39775 return this;
39776};
39777
39778BasePoint.prototype._hasDoubles = function _hasDoubles(k) {
39779 if (!this.precomputed)
39780 return false;
39781
39782 var doubles = this.precomputed.doubles;
39783 if (!doubles)
39784 return false;
39785
39786 return doubles.points.length >= Math.ceil((k.bitLength() + 1) / doubles.step);
39787};
39788
39789BasePoint.prototype._getDoubles = function _getDoubles(step, power) {
39790 if (this.precomputed && this.precomputed.doubles)
39791 return this.precomputed.doubles;
39792
39793 var doubles = [ this ];
39794 var acc = this;
39795 for (var i = 0; i < power; i += step) {
39796 for (var j = 0; j < step; j++)
39797 acc = acc.dbl();
39798 doubles.push(acc);
39799 }
39800 return {
39801 step: step,
39802 points: doubles
39803 };
39804};
39805
39806BasePoint.prototype._getNAFPoints = function _getNAFPoints(wnd) {
39807 if (this.precomputed && this.precomputed.naf)
39808 return this.precomputed.naf;
39809
39810 var res = [ this ];
39811 var max = (1 << wnd) - 1;
39812 var dbl = max === 1 ? null : this.dbl();
39813 for (var i = 1; i < max; i++)
39814 res[i] = res[i - 1].add(dbl);
39815 return {
39816 wnd: wnd,
39817 points: res
39818 };
39819};
39820
39821BasePoint.prototype._getBeta = function _getBeta() {
39822 return null;
39823};
39824
39825BasePoint.prototype.dblp = function dblp(k) {
39826 var r = this;
39827 for (var i = 0; i < k; i++)
39828 r = r.dbl();
39829 return r;
39830};
39831
39832var assert$3 = utils_1$1.assert;
39833
39834function ShortCurve(conf) {
39835 base.call(this, 'short', conf);
39836
39837 this.a = new bn(conf.a, 16).toRed(this.red);
39838 this.b = new bn(conf.b, 16).toRed(this.red);
39839 this.tinv = this.two.redInvm();
39840
39841 this.zeroA = this.a.fromRed().cmpn(0) === 0;
39842 this.threeA = this.a.fromRed().sub(this.p).cmpn(-3) === 0;
39843
39844 // If the curve is endomorphic, precalculate beta and lambda
39845 this.endo = this._getEndomorphism(conf);
39846 this._endoWnafT1 = new Array(4);
39847 this._endoWnafT2 = new Array(4);
39848}
39849inherits(ShortCurve, base);
39850var short_1 = ShortCurve;
39851
39852ShortCurve.prototype._getEndomorphism = function _getEndomorphism(conf) {
39853 // No efficient endomorphism
39854 if (!this.zeroA || !this.g || !this.n || this.p.modn(3) !== 1)
39855 return;
39856
39857 // Compute beta and lambda, that lambda * P = (beta * Px; Py)
39858 var beta;
39859 var lambda;
39860 if (conf.beta) {
39861 beta = new bn(conf.beta, 16).toRed(this.red);
39862 } else {
39863 var betas = this._getEndoRoots(this.p);
39864 // Choose the smallest beta
39865 beta = betas[0].cmp(betas[1]) < 0 ? betas[0] : betas[1];
39866 beta = beta.toRed(this.red);
39867 }
39868 if (conf.lambda) {
39869 lambda = new bn(conf.lambda, 16);
39870 } else {
39871 // Choose the lambda that is matching selected beta
39872 var lambdas = this._getEndoRoots(this.n);
39873 if (this.g.mul(lambdas[0]).x.cmp(this.g.x.redMul(beta)) === 0) {
39874 lambda = lambdas[0];
39875 } else {
39876 lambda = lambdas[1];
39877 assert$3(this.g.mul(lambda).x.cmp(this.g.x.redMul(beta)) === 0);
39878 }
39879 }
39880
39881 // Get basis vectors, used for balanced length-two representation
39882 var basis;
39883 if (conf.basis) {
39884 basis = conf.basis.map(function(vec) {
39885 return {
39886 a: new bn(vec.a, 16),
39887 b: new bn(vec.b, 16)
39888 };
39889 });
39890 } else {
39891 basis = this._getEndoBasis(lambda);
39892 }
39893
39894 return {
39895 beta: beta,
39896 lambda: lambda,
39897 basis: basis
39898 };
39899};
39900
39901ShortCurve.prototype._getEndoRoots = function _getEndoRoots(num) {
39902 // Find roots of for x^2 + x + 1 in F
39903 // Root = (-1 +- Sqrt(-3)) / 2
39904 //
39905 var red = num === this.p ? this.red : bn.mont(num);
39906 var tinv = new bn(2).toRed(red).redInvm();
39907 var ntinv = tinv.redNeg();
39908
39909 var s = new bn(3).toRed(red).redNeg().redSqrt().redMul(tinv);
39910
39911 var l1 = ntinv.redAdd(s).fromRed();
39912 var l2 = ntinv.redSub(s).fromRed();
39913 return [ l1, l2 ];
39914};
39915
39916ShortCurve.prototype._getEndoBasis = function _getEndoBasis(lambda) {
39917 // aprxSqrt >= sqrt(this.n)
39918 var aprxSqrt = this.n.ushrn(Math.floor(this.n.bitLength() / 2));
39919
39920 // 3.74
39921 // Run EGCD, until r(L + 1) < aprxSqrt
39922 var u = lambda;
39923 var v = this.n.clone();
39924 var x1 = new bn(1);
39925 var y1 = new bn(0);
39926 var x2 = new bn(0);
39927 var y2 = new bn(1);
39928
39929 // NOTE: all vectors are roots of: a + b * lambda = 0 (mod n)
39930 var a0;
39931 var b0;
39932 // First vector
39933 var a1;
39934 var b1;
39935 // Second vector
39936 var a2;
39937 var b2;
39938
39939 var prevR;
39940 var i = 0;
39941 var r;
39942 var x;
39943 while (u.cmpn(0) !== 0) {
39944 var q = v.div(u);
39945 r = v.sub(q.mul(u));
39946 x = x2.sub(q.mul(x1));
39947 var y = y2.sub(q.mul(y1));
39948
39949 if (!a1 && r.cmp(aprxSqrt) < 0) {
39950 a0 = prevR.neg();
39951 b0 = x1;
39952 a1 = r.neg();
39953 b1 = x;
39954 } else if (a1 && ++i === 2) {
39955 break;
39956 }
39957 prevR = r;
39958
39959 v = u;
39960 u = r;
39961 x2 = x1;
39962 x1 = x;
39963 y2 = y1;
39964 y1 = y;
39965 }
39966 a2 = r.neg();
39967 b2 = x;
39968
39969 var len1 = a1.sqr().add(b1.sqr());
39970 var len2 = a2.sqr().add(b2.sqr());
39971 if (len2.cmp(len1) >= 0) {
39972 a2 = a0;
39973 b2 = b0;
39974 }
39975
39976 // Normalize signs
39977 if (a1.negative) {
39978 a1 = a1.neg();
39979 b1 = b1.neg();
39980 }
39981 if (a2.negative) {
39982 a2 = a2.neg();
39983 b2 = b2.neg();
39984 }
39985
39986 return [
39987 { a: a1, b: b1 },
39988 { a: a2, b: b2 }
39989 ];
39990};
39991
39992ShortCurve.prototype._endoSplit = function _endoSplit(k) {
39993 var basis = this.endo.basis;
39994 var v1 = basis[0];
39995 var v2 = basis[1];
39996
39997 var c1 = v2.b.mul(k).divRound(this.n);
39998 var c2 = v1.b.neg().mul(k).divRound(this.n);
39999
40000 var p1 = c1.mul(v1.a);
40001 var p2 = c2.mul(v2.a);
40002 var q1 = c1.mul(v1.b);
40003 var q2 = c2.mul(v2.b);
40004
40005 // Calculate answer
40006 var k1 = k.sub(p1).sub(p2);
40007 var k2 = q1.add(q2).neg();
40008 return { k1: k1, k2: k2 };
40009};
40010
40011ShortCurve.prototype.pointFromX = function pointFromX(x, odd) {
40012 x = new bn(x, 16);
40013 if (!x.red)
40014 x = x.toRed(this.red);
40015
40016 var y2 = x.redSqr().redMul(x).redIAdd(x.redMul(this.a)).redIAdd(this.b);
40017 var y = y2.redSqrt();
40018 if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
40019 throw new Error('invalid point');
40020
40021 // XXX Is there any way to tell if the number is odd without converting it
40022 // to non-red form?
40023 var isOdd = y.fromRed().isOdd();
40024 if (odd && !isOdd || !odd && isOdd)
40025 y = y.redNeg();
40026
40027 return this.point(x, y);
40028};
40029
40030ShortCurve.prototype.validate = function validate(point) {
40031 if (point.inf)
40032 return true;
40033
40034 var x = point.x;
40035 var y = point.y;
40036
40037 var ax = this.a.redMul(x);
40038 var rhs = x.redSqr().redMul(x).redIAdd(ax).redIAdd(this.b);
40039 return y.redSqr().redISub(rhs).cmpn(0) === 0;
40040};
40041
40042ShortCurve.prototype._endoWnafMulAdd =
40043 function _endoWnafMulAdd(points, coeffs, jacobianResult) {
40044 var npoints = this._endoWnafT1;
40045 var ncoeffs = this._endoWnafT2;
40046 for (var i = 0; i < points.length; i++) {
40047 var split = this._endoSplit(coeffs[i]);
40048 var p = points[i];
40049 var beta = p._getBeta();
40050
40051 if (split.k1.negative) {
40052 split.k1.ineg();
40053 p = p.neg(true);
40054 }
40055 if (split.k2.negative) {
40056 split.k2.ineg();
40057 beta = beta.neg(true);
40058 }
40059
40060 npoints[i * 2] = p;
40061 npoints[i * 2 + 1] = beta;
40062 ncoeffs[i * 2] = split.k1;
40063 ncoeffs[i * 2 + 1] = split.k2;
40064 }
40065 var res = this._wnafMulAdd(1, npoints, ncoeffs, i * 2, jacobianResult);
40066
40067 // Clean-up references to points and coefficients
40068 for (var j = 0; j < i * 2; j++) {
40069 npoints[j] = null;
40070 ncoeffs[j] = null;
40071 }
40072 return res;
40073};
40074
40075function Point(curve, x, y, isRed) {
40076 base.BasePoint.call(this, curve, 'affine');
40077 if (x === null && y === null) {
40078 this.x = null;
40079 this.y = null;
40080 this.inf = true;
40081 } else {
40082 this.x = new bn(x, 16);
40083 this.y = new bn(y, 16);
40084 // Force redgomery representation when loading from JSON
40085 if (isRed) {
40086 this.x.forceRed(this.curve.red);
40087 this.y.forceRed(this.curve.red);
40088 }
40089 if (!this.x.red)
40090 this.x = this.x.toRed(this.curve.red);
40091 if (!this.y.red)
40092 this.y = this.y.toRed(this.curve.red);
40093 this.inf = false;
40094 }
40095}
40096inherits(Point, base.BasePoint);
40097
40098ShortCurve.prototype.point = function point(x, y, isRed) {
40099 return new Point(this, x, y, isRed);
40100};
40101
40102ShortCurve.prototype.pointFromJSON = function pointFromJSON(obj, red) {
40103 return Point.fromJSON(this, obj, red);
40104};
40105
40106Point.prototype._getBeta = function _getBeta() {
40107 if (!this.curve.endo)
40108 return;
40109
40110 var pre = this.precomputed;
40111 if (pre && pre.beta)
40112 return pre.beta;
40113
40114 var beta = this.curve.point(this.x.redMul(this.curve.endo.beta), this.y);
40115 if (pre) {
40116 var curve = this.curve;
40117 var endoMul = function(p) {
40118 return curve.point(p.x.redMul(curve.endo.beta), p.y);
40119 };
40120 pre.beta = beta;
40121 beta.precomputed = {
40122 beta: null,
40123 naf: pre.naf && {
40124 wnd: pre.naf.wnd,
40125 points: pre.naf.points.map(endoMul)
40126 },
40127 doubles: pre.doubles && {
40128 step: pre.doubles.step,
40129 points: pre.doubles.points.map(endoMul)
40130 }
40131 };
40132 }
40133 return beta;
40134};
40135
40136Point.prototype.toJSON = function toJSON() {
40137 if (!this.precomputed)
40138 return [ this.x, this.y ];
40139
40140 return [ this.x, this.y, this.precomputed && {
40141 doubles: this.precomputed.doubles && {
40142 step: this.precomputed.doubles.step,
40143 points: this.precomputed.doubles.points.slice(1)
40144 },
40145 naf: this.precomputed.naf && {
40146 wnd: this.precomputed.naf.wnd,
40147 points: this.precomputed.naf.points.slice(1)
40148 }
40149 } ];
40150};
40151
40152Point.fromJSON = function fromJSON(curve, obj, red) {
40153 if (typeof obj === 'string')
40154 obj = JSON.parse(obj);
40155 var res = curve.point(obj[0], obj[1], red);
40156 if (!obj[2])
40157 return res;
40158
40159 function obj2point(obj) {
40160 return curve.point(obj[0], obj[1], red);
40161 }
40162
40163 var pre = obj[2];
40164 res.precomputed = {
40165 beta: null,
40166 doubles: pre.doubles && {
40167 step: pre.doubles.step,
40168 points: [ res ].concat(pre.doubles.points.map(obj2point))
40169 },
40170 naf: pre.naf && {
40171 wnd: pre.naf.wnd,
40172 points: [ res ].concat(pre.naf.points.map(obj2point))
40173 }
40174 };
40175 return res;
40176};
40177
40178Point.prototype.inspect = function inspect() {
40179 if (this.isInfinity())
40180 return '<EC Point Infinity>';
40181 return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
40182 ' y: ' + this.y.fromRed().toString(16, 2) + '>';
40183};
40184
40185Point.prototype.isInfinity = function isInfinity() {
40186 return this.inf;
40187};
40188
40189Point.prototype.add = function add(p) {
40190 // O + P = P
40191 if (this.inf)
40192 return p;
40193
40194 // P + O = P
40195 if (p.inf)
40196 return this;
40197
40198 // P + P = 2P
40199 if (this.eq(p))
40200 return this.dbl();
40201
40202 // P + (-P) = O
40203 if (this.neg().eq(p))
40204 return this.curve.point(null, null);
40205
40206 // P + Q = O
40207 if (this.x.cmp(p.x) === 0)
40208 return this.curve.point(null, null);
40209
40210 var c = this.y.redSub(p.y);
40211 if (c.cmpn(0) !== 0)
40212 c = c.redMul(this.x.redSub(p.x).redInvm());
40213 var nx = c.redSqr().redISub(this.x).redISub(p.x);
40214 var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
40215 return this.curve.point(nx, ny);
40216};
40217
40218Point.prototype.dbl = function dbl() {
40219 if (this.inf)
40220 return this;
40221
40222 // 2P = O
40223 var ys1 = this.y.redAdd(this.y);
40224 if (ys1.cmpn(0) === 0)
40225 return this.curve.point(null, null);
40226
40227 var a = this.curve.a;
40228
40229 var x2 = this.x.redSqr();
40230 var dyinv = ys1.redInvm();
40231 var c = x2.redAdd(x2).redIAdd(x2).redIAdd(a).redMul(dyinv);
40232
40233 var nx = c.redSqr().redISub(this.x.redAdd(this.x));
40234 var ny = c.redMul(this.x.redSub(nx)).redISub(this.y);
40235 return this.curve.point(nx, ny);
40236};
40237
40238Point.prototype.getX = function getX() {
40239 return this.x.fromRed();
40240};
40241
40242Point.prototype.getY = function getY() {
40243 return this.y.fromRed();
40244};
40245
40246Point.prototype.mul = function mul(k) {
40247 k = new bn(k, 16);
40248 if (this.isInfinity())
40249 return this;
40250 else if (this._hasDoubles(k))
40251 return this.curve._fixedNafMul(this, k);
40252 else if (this.curve.endo)
40253 return this.curve._endoWnafMulAdd([ this ], [ k ]);
40254 else
40255 return this.curve._wnafMul(this, k);
40256};
40257
40258Point.prototype.mulAdd = function mulAdd(k1, p2, k2) {
40259 var points = [ this, p2 ];
40260 var coeffs = [ k1, k2 ];
40261 if (this.curve.endo)
40262 return this.curve._endoWnafMulAdd(points, coeffs);
40263 else
40264 return this.curve._wnafMulAdd(1, points, coeffs, 2);
40265};
40266
40267Point.prototype.jmulAdd = function jmulAdd(k1, p2, k2) {
40268 var points = [ this, p2 ];
40269 var coeffs = [ k1, k2 ];
40270 if (this.curve.endo)
40271 return this.curve._endoWnafMulAdd(points, coeffs, true);
40272 else
40273 return this.curve._wnafMulAdd(1, points, coeffs, 2, true);
40274};
40275
40276Point.prototype.eq = function eq(p) {
40277 return this === p ||
40278 this.inf === p.inf &&
40279 (this.inf || this.x.cmp(p.x) === 0 && this.y.cmp(p.y) === 0);
40280};
40281
40282Point.prototype.neg = function neg(_precompute) {
40283 if (this.inf)
40284 return this;
40285
40286 var res = this.curve.point(this.x, this.y.redNeg());
40287 if (_precompute && this.precomputed) {
40288 var pre = this.precomputed;
40289 var negate = function(p) {
40290 return p.neg();
40291 };
40292 res.precomputed = {
40293 naf: pre.naf && {
40294 wnd: pre.naf.wnd,
40295 points: pre.naf.points.map(negate)
40296 },
40297 doubles: pre.doubles && {
40298 step: pre.doubles.step,
40299 points: pre.doubles.points.map(negate)
40300 }
40301 };
40302 }
40303 return res;
40304};
40305
40306Point.prototype.toJ = function toJ() {
40307 if (this.inf)
40308 return this.curve.jpoint(null, null, null);
40309
40310 var res = this.curve.jpoint(this.x, this.y, this.curve.one);
40311 return res;
40312};
40313
40314function JPoint(curve, x, y, z) {
40315 base.BasePoint.call(this, curve, 'jacobian');
40316 if (x === null && y === null && z === null) {
40317 this.x = this.curve.one;
40318 this.y = this.curve.one;
40319 this.z = new bn(0);
40320 } else {
40321 this.x = new bn(x, 16);
40322 this.y = new bn(y, 16);
40323 this.z = new bn(z, 16);
40324 }
40325 if (!this.x.red)
40326 this.x = this.x.toRed(this.curve.red);
40327 if (!this.y.red)
40328 this.y = this.y.toRed(this.curve.red);
40329 if (!this.z.red)
40330 this.z = this.z.toRed(this.curve.red);
40331
40332 this.zOne = this.z === this.curve.one;
40333}
40334inherits(JPoint, base.BasePoint);
40335
40336ShortCurve.prototype.jpoint = function jpoint(x, y, z) {
40337 return new JPoint(this, x, y, z);
40338};
40339
40340JPoint.prototype.toP = function toP() {
40341 if (this.isInfinity())
40342 return this.curve.point(null, null);
40343
40344 var zinv = this.z.redInvm();
40345 var zinv2 = zinv.redSqr();
40346 var ax = this.x.redMul(zinv2);
40347 var ay = this.y.redMul(zinv2).redMul(zinv);
40348
40349 return this.curve.point(ax, ay);
40350};
40351
40352JPoint.prototype.neg = function neg() {
40353 return this.curve.jpoint(this.x, this.y.redNeg(), this.z);
40354};
40355
40356JPoint.prototype.add = function add(p) {
40357 // O + P = P
40358 if (this.isInfinity())
40359 return p;
40360
40361 // P + O = P
40362 if (p.isInfinity())
40363 return this;
40364
40365 // 12M + 4S + 7A
40366 var pz2 = p.z.redSqr();
40367 var z2 = this.z.redSqr();
40368 var u1 = this.x.redMul(pz2);
40369 var u2 = p.x.redMul(z2);
40370 var s1 = this.y.redMul(pz2.redMul(p.z));
40371 var s2 = p.y.redMul(z2.redMul(this.z));
40372
40373 var h = u1.redSub(u2);
40374 var r = s1.redSub(s2);
40375 if (h.cmpn(0) === 0) {
40376 if (r.cmpn(0) !== 0)
40377 return this.curve.jpoint(null, null, null);
40378 else
40379 return this.dbl();
40380 }
40381
40382 var h2 = h.redSqr();
40383 var h3 = h2.redMul(h);
40384 var v = u1.redMul(h2);
40385
40386 var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
40387 var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
40388 var nz = this.z.redMul(p.z).redMul(h);
40389
40390 return this.curve.jpoint(nx, ny, nz);
40391};
40392
40393JPoint.prototype.mixedAdd = function mixedAdd(p) {
40394 // O + P = P
40395 if (this.isInfinity())
40396 return p.toJ();
40397
40398 // P + O = P
40399 if (p.isInfinity())
40400 return this;
40401
40402 // 8M + 3S + 7A
40403 var z2 = this.z.redSqr();
40404 var u1 = this.x;
40405 var u2 = p.x.redMul(z2);
40406 var s1 = this.y;
40407 var s2 = p.y.redMul(z2).redMul(this.z);
40408
40409 var h = u1.redSub(u2);
40410 var r = s1.redSub(s2);
40411 if (h.cmpn(0) === 0) {
40412 if (r.cmpn(0) !== 0)
40413 return this.curve.jpoint(null, null, null);
40414 else
40415 return this.dbl();
40416 }
40417
40418 var h2 = h.redSqr();
40419 var h3 = h2.redMul(h);
40420 var v = u1.redMul(h2);
40421
40422 var nx = r.redSqr().redIAdd(h3).redISub(v).redISub(v);
40423 var ny = r.redMul(v.redISub(nx)).redISub(s1.redMul(h3));
40424 var nz = this.z.redMul(h);
40425
40426 return this.curve.jpoint(nx, ny, nz);
40427};
40428
40429JPoint.prototype.dblp = function dblp(pow) {
40430 if (pow === 0)
40431 return this;
40432 if (this.isInfinity())
40433 return this;
40434 if (!pow)
40435 return this.dbl();
40436
40437 if (this.curve.zeroA || this.curve.threeA) {
40438 var r = this;
40439 for (var i = 0; i < pow; i++)
40440 r = r.dbl();
40441 return r;
40442 }
40443
40444 // 1M + 2S + 1A + N * (4S + 5M + 8A)
40445 // N = 1 => 6M + 6S + 9A
40446 var a = this.curve.a;
40447 var tinv = this.curve.tinv;
40448
40449 var jx = this.x;
40450 var jy = this.y;
40451 var jz = this.z;
40452 var jz4 = jz.redSqr().redSqr();
40453
40454 // Reuse results
40455 var jyd = jy.redAdd(jy);
40456 for (var i = 0; i < pow; i++) {
40457 var jx2 = jx.redSqr();
40458 var jyd2 = jyd.redSqr();
40459 var jyd4 = jyd2.redSqr();
40460 var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
40461
40462 var t1 = jx.redMul(jyd2);
40463 var nx = c.redSqr().redISub(t1.redAdd(t1));
40464 var t2 = t1.redISub(nx);
40465 var dny = c.redMul(t2);
40466 dny = dny.redIAdd(dny).redISub(jyd4);
40467 var nz = jyd.redMul(jz);
40468 if (i + 1 < pow)
40469 jz4 = jz4.redMul(jyd4);
40470
40471 jx = nx;
40472 jz = nz;
40473 jyd = dny;
40474 }
40475
40476 return this.curve.jpoint(jx, jyd.redMul(tinv), jz);
40477};
40478
40479JPoint.prototype.dbl = function dbl() {
40480 if (this.isInfinity())
40481 return this;
40482
40483 if (this.curve.zeroA)
40484 return this._zeroDbl();
40485 else if (this.curve.threeA)
40486 return this._threeDbl();
40487 else
40488 return this._dbl();
40489};
40490
40491JPoint.prototype._zeroDbl = function _zeroDbl() {
40492 var nx;
40493 var ny;
40494 var nz;
40495 // Z = 1
40496 if (this.zOne) {
40497 // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
40498 // #doubling-mdbl-2007-bl
40499 // 1M + 5S + 14A
40500
40501 // XX = X1^2
40502 var xx = this.x.redSqr();
40503 // YY = Y1^2
40504 var yy = this.y.redSqr();
40505 // YYYY = YY^2
40506 var yyyy = yy.redSqr();
40507 // S = 2 * ((X1 + YY)^2 - XX - YYYY)
40508 var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
40509 s = s.redIAdd(s);
40510 // M = 3 * XX + a; a = 0
40511 var m = xx.redAdd(xx).redIAdd(xx);
40512 // T = M ^ 2 - 2*S
40513 var t = m.redSqr().redISub(s).redISub(s);
40514
40515 // 8 * YYYY
40516 var yyyy8 = yyyy.redIAdd(yyyy);
40517 yyyy8 = yyyy8.redIAdd(yyyy8);
40518 yyyy8 = yyyy8.redIAdd(yyyy8);
40519
40520 // X3 = T
40521 nx = t;
40522 // Y3 = M * (S - T) - 8 * YYYY
40523 ny = m.redMul(s.redISub(t)).redISub(yyyy8);
40524 // Z3 = 2*Y1
40525 nz = this.y.redAdd(this.y);
40526 } else {
40527 // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html
40528 // #doubling-dbl-2009-l
40529 // 2M + 5S + 13A
40530
40531 // A = X1^2
40532 var a = this.x.redSqr();
40533 // B = Y1^2
40534 var b = this.y.redSqr();
40535 // C = B^2
40536 var c = b.redSqr();
40537 // D = 2 * ((X1 + B)^2 - A - C)
40538 var d = this.x.redAdd(b).redSqr().redISub(a).redISub(c);
40539 d = d.redIAdd(d);
40540 // E = 3 * A
40541 var e = a.redAdd(a).redIAdd(a);
40542 // F = E^2
40543 var f = e.redSqr();
40544
40545 // 8 * C
40546 var c8 = c.redIAdd(c);
40547 c8 = c8.redIAdd(c8);
40548 c8 = c8.redIAdd(c8);
40549
40550 // X3 = F - 2 * D
40551 nx = f.redISub(d).redISub(d);
40552 // Y3 = E * (D - X3) - 8 * C
40553 ny = e.redMul(d.redISub(nx)).redISub(c8);
40554 // Z3 = 2 * Y1 * Z1
40555 nz = this.y.redMul(this.z);
40556 nz = nz.redIAdd(nz);
40557 }
40558
40559 return this.curve.jpoint(nx, ny, nz);
40560};
40561
40562JPoint.prototype._threeDbl = function _threeDbl() {
40563 var nx;
40564 var ny;
40565 var nz;
40566 // Z = 1
40567 if (this.zOne) {
40568 // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html
40569 // #doubling-mdbl-2007-bl
40570 // 1M + 5S + 15A
40571
40572 // XX = X1^2
40573 var xx = this.x.redSqr();
40574 // YY = Y1^2
40575 var yy = this.y.redSqr();
40576 // YYYY = YY^2
40577 var yyyy = yy.redSqr();
40578 // S = 2 * ((X1 + YY)^2 - XX - YYYY)
40579 var s = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
40580 s = s.redIAdd(s);
40581 // M = 3 * XX + a
40582 var m = xx.redAdd(xx).redIAdd(xx).redIAdd(this.curve.a);
40583 // T = M^2 - 2 * S
40584 var t = m.redSqr().redISub(s).redISub(s);
40585 // X3 = T
40586 nx = t;
40587 // Y3 = M * (S - T) - 8 * YYYY
40588 var yyyy8 = yyyy.redIAdd(yyyy);
40589 yyyy8 = yyyy8.redIAdd(yyyy8);
40590 yyyy8 = yyyy8.redIAdd(yyyy8);
40591 ny = m.redMul(s.redISub(t)).redISub(yyyy8);
40592 // Z3 = 2 * Y1
40593 nz = this.y.redAdd(this.y);
40594 } else {
40595 // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
40596 // 3M + 5S
40597
40598 // delta = Z1^2
40599 var delta = this.z.redSqr();
40600 // gamma = Y1^2
40601 var gamma = this.y.redSqr();
40602 // beta = X1 * gamma
40603 var beta = this.x.redMul(gamma);
40604 // alpha = 3 * (X1 - delta) * (X1 + delta)
40605 var alpha = this.x.redSub(delta).redMul(this.x.redAdd(delta));
40606 alpha = alpha.redAdd(alpha).redIAdd(alpha);
40607 // X3 = alpha^2 - 8 * beta
40608 var beta4 = beta.redIAdd(beta);
40609 beta4 = beta4.redIAdd(beta4);
40610 var beta8 = beta4.redAdd(beta4);
40611 nx = alpha.redSqr().redISub(beta8);
40612 // Z3 = (Y1 + Z1)^2 - gamma - delta
40613 nz = this.y.redAdd(this.z).redSqr().redISub(gamma).redISub(delta);
40614 // Y3 = alpha * (4 * beta - X3) - 8 * gamma^2
40615 var ggamma8 = gamma.redSqr();
40616 ggamma8 = ggamma8.redIAdd(ggamma8);
40617 ggamma8 = ggamma8.redIAdd(ggamma8);
40618 ggamma8 = ggamma8.redIAdd(ggamma8);
40619 ny = alpha.redMul(beta4.redISub(nx)).redISub(ggamma8);
40620 }
40621
40622 return this.curve.jpoint(nx, ny, nz);
40623};
40624
40625JPoint.prototype._dbl = function _dbl() {
40626 var a = this.curve.a;
40627
40628 // 4M + 6S + 10A
40629 var jx = this.x;
40630 var jy = this.y;
40631 var jz = this.z;
40632 var jz4 = jz.redSqr().redSqr();
40633
40634 var jx2 = jx.redSqr();
40635 var jy2 = jy.redSqr();
40636
40637 var c = jx2.redAdd(jx2).redIAdd(jx2).redIAdd(a.redMul(jz4));
40638
40639 var jxd4 = jx.redAdd(jx);
40640 jxd4 = jxd4.redIAdd(jxd4);
40641 var t1 = jxd4.redMul(jy2);
40642 var nx = c.redSqr().redISub(t1.redAdd(t1));
40643 var t2 = t1.redISub(nx);
40644
40645 var jyd8 = jy2.redSqr();
40646 jyd8 = jyd8.redIAdd(jyd8);
40647 jyd8 = jyd8.redIAdd(jyd8);
40648 jyd8 = jyd8.redIAdd(jyd8);
40649 var ny = c.redMul(t2).redISub(jyd8);
40650 var nz = jy.redAdd(jy).redMul(jz);
40651
40652 return this.curve.jpoint(nx, ny, nz);
40653};
40654
40655JPoint.prototype.trpl = function trpl() {
40656 if (!this.curve.zeroA)
40657 return this.dbl().add(this);
40658
40659 // hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#tripling-tpl-2007-bl
40660 // 5M + 10S + ...
40661
40662 // XX = X1^2
40663 var xx = this.x.redSqr();
40664 // YY = Y1^2
40665 var yy = this.y.redSqr();
40666 // ZZ = Z1^2
40667 var zz = this.z.redSqr();
40668 // YYYY = YY^2
40669 var yyyy = yy.redSqr();
40670 // M = 3 * XX + a * ZZ2; a = 0
40671 var m = xx.redAdd(xx).redIAdd(xx);
40672 // MM = M^2
40673 var mm = m.redSqr();
40674 // E = 6 * ((X1 + YY)^2 - XX - YYYY) - MM
40675 var e = this.x.redAdd(yy).redSqr().redISub(xx).redISub(yyyy);
40676 e = e.redIAdd(e);
40677 e = e.redAdd(e).redIAdd(e);
40678 e = e.redISub(mm);
40679 // EE = E^2
40680 var ee = e.redSqr();
40681 // T = 16*YYYY
40682 var t = yyyy.redIAdd(yyyy);
40683 t = t.redIAdd(t);
40684 t = t.redIAdd(t);
40685 t = t.redIAdd(t);
40686 // U = (M + E)^2 - MM - EE - T
40687 var u = m.redIAdd(e).redSqr().redISub(mm).redISub(ee).redISub(t);
40688 // X3 = 4 * (X1 * EE - 4 * YY * U)
40689 var yyu4 = yy.redMul(u);
40690 yyu4 = yyu4.redIAdd(yyu4);
40691 yyu4 = yyu4.redIAdd(yyu4);
40692 var nx = this.x.redMul(ee).redISub(yyu4);
40693 nx = nx.redIAdd(nx);
40694 nx = nx.redIAdd(nx);
40695 // Y3 = 8 * Y1 * (U * (T - U) - E * EE)
40696 var ny = this.y.redMul(u.redMul(t.redISub(u)).redISub(e.redMul(ee)));
40697 ny = ny.redIAdd(ny);
40698 ny = ny.redIAdd(ny);
40699 ny = ny.redIAdd(ny);
40700 // Z3 = (Z1 + E)^2 - ZZ - EE
40701 var nz = this.z.redAdd(e).redSqr().redISub(zz).redISub(ee);
40702
40703 return this.curve.jpoint(nx, ny, nz);
40704};
40705
40706JPoint.prototype.mul = function mul(k, kbase) {
40707 k = new bn(k, kbase);
40708
40709 return this.curve._wnafMul(this, k);
40710};
40711
40712JPoint.prototype.eq = function eq(p) {
40713 if (p.type === 'affine')
40714 return this.eq(p.toJ());
40715
40716 if (this === p)
40717 return true;
40718
40719 // x1 * z2^2 == x2 * z1^2
40720 var z2 = this.z.redSqr();
40721 var pz2 = p.z.redSqr();
40722 if (this.x.redMul(pz2).redISub(p.x.redMul(z2)).cmpn(0) !== 0)
40723 return false;
40724
40725 // y1 * z2^3 == y2 * z1^3
40726 var z3 = z2.redMul(this.z);
40727 var pz3 = pz2.redMul(p.z);
40728 return this.y.redMul(pz3).redISub(p.y.redMul(z3)).cmpn(0) === 0;
40729};
40730
40731JPoint.prototype.eqXToP = function eqXToP(x) {
40732 var zs = this.z.redSqr();
40733 var rx = x.toRed(this.curve.red).redMul(zs);
40734 if (this.x.cmp(rx) === 0)
40735 return true;
40736
40737 var xc = x.clone();
40738 var t = this.curve.redN.redMul(zs);
40739 for (;;) {
40740 xc.iadd(this.curve.n);
40741 if (xc.cmp(this.curve.p) >= 0)
40742 return false;
40743
40744 rx.redIAdd(t);
40745 if (this.x.cmp(rx) === 0)
40746 return true;
40747 }
40748};
40749
40750JPoint.prototype.inspect = function inspect() {
40751 if (this.isInfinity())
40752 return '<EC JPoint Infinity>';
40753 return '<EC JPoint x: ' + this.x.toString(16, 2) +
40754 ' y: ' + this.y.toString(16, 2) +
40755 ' z: ' + this.z.toString(16, 2) + '>';
40756};
40757
40758JPoint.prototype.isInfinity = function isInfinity() {
40759 // XXX This code assumes that zero is always zero in red
40760 return this.z.cmpn(0) === 0;
40761};
40762
40763function MontCurve(conf) {
40764 base.call(this, 'mont', conf);
40765
40766 this.a = new bn(conf.a, 16).toRed(this.red);
40767 this.b = new bn(conf.b, 16).toRed(this.red);
40768 this.i4 = new bn(4).toRed(this.red).redInvm();
40769 this.two = new bn(2).toRed(this.red);
40770 // Note: this implementation is according to the original paper
40771 // by P. Montgomery, NOT the one by D. J. Bernstein.
40772 this.a24 = this.i4.redMul(this.a.redAdd(this.two));
40773}
40774inherits(MontCurve, base);
40775var mont = MontCurve;
40776
40777MontCurve.prototype.validate = function validate(point) {
40778 var x = point.normalize().x;
40779 var x2 = x.redSqr();
40780 var rhs = x2.redMul(x).redAdd(x2.redMul(this.a)).redAdd(x);
40781 var y = rhs.redSqrt();
40782
40783 return y.redSqr().cmp(rhs) === 0;
40784};
40785
40786function Point$1(curve, x, z) {
40787 base.BasePoint.call(this, curve, 'projective');
40788 if (x === null && z === null) {
40789 this.x = this.curve.one;
40790 this.z = this.curve.zero;
40791 } else {
40792 this.x = new bn(x, 16);
40793 this.z = new bn(z, 16);
40794 if (!this.x.red)
40795 this.x = this.x.toRed(this.curve.red);
40796 if (!this.z.red)
40797 this.z = this.z.toRed(this.curve.red);
40798 }
40799}
40800inherits(Point$1, base.BasePoint);
40801
40802MontCurve.prototype.decodePoint = function decodePoint(bytes, enc) {
40803 var bytes = utils_1$1.toArray(bytes, enc);
40804
40805 // TODO Curve448
40806 // Montgomery curve points must be represented in the compressed format
40807 // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
40808 if (bytes.length === 33 && bytes[0] === 0x40)
40809 bytes = bytes.slice(1, 33).reverse(); // point must be little-endian
40810 if (bytes.length !== 32)
40811 throw new Error('Unknown point compression format');
40812 return this.point(bytes, 1);
40813};
40814
40815MontCurve.prototype.point = function point(x, z) {
40816 return new Point$1(this, x, z);
40817};
40818
40819MontCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
40820 return Point$1.fromJSON(this, obj);
40821};
40822
40823Point$1.prototype.precompute = function precompute() {
40824 // No-op
40825};
40826
40827Point$1.prototype._encode = function _encode(compact) {
40828 var len = this.curve.p.byteLength();
40829
40830 // Note: the output should always be little-endian
40831 // https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-02#appendix-B
40832 if (compact) {
40833 return [ 0x40 ].concat(this.getX().toArray('le', len));
40834 } else {
40835 return this.getX().toArray('be', len);
40836 }
40837};
40838
40839Point$1.fromJSON = function fromJSON(curve, obj) {
40840 return new Point$1(curve, obj[0], obj[1] || curve.one);
40841};
40842
40843Point$1.prototype.inspect = function inspect() {
40844 if (this.isInfinity())
40845 return '<EC Point Infinity>';
40846 return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
40847 ' z: ' + this.z.fromRed().toString(16, 2) + '>';
40848};
40849
40850Point$1.prototype.isInfinity = function isInfinity() {
40851 // XXX This code assumes that zero is always zero in red
40852 return this.z.cmpn(0) === 0;
40853};
40854
40855Point$1.prototype.dbl = function dbl() {
40856 // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#doubling-dbl-1987-m-3
40857 // 2M + 2S + 4A
40858
40859 // A = X1 + Z1
40860 var a = this.x.redAdd(this.z);
40861 // AA = A^2
40862 var aa = a.redSqr();
40863 // B = X1 - Z1
40864 var b = this.x.redSub(this.z);
40865 // BB = B^2
40866 var bb = b.redSqr();
40867 // C = AA - BB
40868 var c = aa.redSub(bb);
40869 // X3 = AA * BB
40870 var nx = aa.redMul(bb);
40871 // Z3 = C * (BB + A24 * C)
40872 var nz = c.redMul(bb.redAdd(this.curve.a24.redMul(c)));
40873 return this.curve.point(nx, nz);
40874};
40875
40876Point$1.prototype.add = function add() {
40877 throw new Error('Not supported on Montgomery curve');
40878};
40879
40880Point$1.prototype.diffAdd = function diffAdd(p, diff) {
40881 // http://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html#diffadd-dadd-1987-m-3
40882 // 4M + 2S + 6A
40883
40884 // A = X2 + Z2
40885 var a = this.x.redAdd(this.z);
40886 // B = X2 - Z2
40887 var b = this.x.redSub(this.z);
40888 // C = X3 + Z3
40889 var c = p.x.redAdd(p.z);
40890 // D = X3 - Z3
40891 var d = p.x.redSub(p.z);
40892 // DA = D * A
40893 var da = d.redMul(a);
40894 // CB = C * B
40895 var cb = c.redMul(b);
40896 // X5 = Z1 * (DA + CB)^2
40897 var nx = diff.z.redMul(da.redAdd(cb).redSqr());
40898 // Z5 = X1 * (DA - CB)^2
40899 var nz = diff.x.redMul(da.redISub(cb).redSqr());
40900 return this.curve.point(nx, nz);
40901};
40902
40903Point$1.prototype.mul = function mul(k) {
40904 k = new bn(k, 16);
40905
40906 var t = k.clone();
40907 var a = this; // (N / 2) * Q + Q
40908 var b = this.curve.point(null, null); // (N / 2) * Q
40909 var c = this; // Q
40910
40911 for (var bits = []; t.cmpn(0) !== 0; t.iushrn(1))
40912 bits.push(t.andln(1));
40913
40914 for (var i = bits.length - 1; i >= 0; i--) {
40915 if (bits[i] === 0) {
40916 // N * Q + Q = ((N / 2) * Q + Q)) + (N / 2) * Q
40917 a = a.diffAdd(b, c);
40918 // N * Q = 2 * ((N / 2) * Q + Q))
40919 b = b.dbl();
40920 } else {
40921 // N * Q = ((N / 2) * Q + Q) + ((N / 2) * Q)
40922 b = a.diffAdd(b, c);
40923 // N * Q + Q = 2 * ((N / 2) * Q + Q)
40924 a = a.dbl();
40925 }
40926 }
40927 return b;
40928};
40929
40930Point$1.prototype.mulAdd = function mulAdd() {
40931 throw new Error('Not supported on Montgomery curve');
40932};
40933
40934Point$1.prototype.jumlAdd = function jumlAdd() {
40935 throw new Error('Not supported on Montgomery curve');
40936};
40937
40938Point$1.prototype.eq = function eq(other) {
40939 return this.getX().cmp(other.getX()) === 0;
40940};
40941
40942Point$1.prototype.normalize = function normalize() {
40943 this.x = this.x.redMul(this.z.redInvm());
40944 this.z = this.curve.one;
40945 return this;
40946};
40947
40948Point$1.prototype.getX = function getX() {
40949 // Normalize coordinates
40950 this.normalize();
40951
40952 return this.x.fromRed();
40953};
40954
40955var assert$4 = utils_1$1.assert;
40956
40957function EdwardsCurve(conf) {
40958 // NOTE: Important as we are creating point in Base.call()
40959 this.twisted = (conf.a | 0) !== 1;
40960 this.mOneA = this.twisted && (conf.a | 0) === -1;
40961 this.extended = this.mOneA;
40962
40963 base.call(this, 'edwards', conf);
40964
40965 this.a = new bn(conf.a, 16).umod(this.red.m);
40966 this.a = this.a.toRed(this.red);
40967 this.c = new bn(conf.c, 16).toRed(this.red);
40968 this.c2 = this.c.redSqr();
40969 this.d = new bn(conf.d, 16).toRed(this.red);
40970 this.dd = this.d.redAdd(this.d);
40971
40972 assert$4(!this.twisted || this.c.fromRed().cmpn(1) === 0);
40973 this.oneC = (conf.c | 0) === 1;
40974}
40975inherits(EdwardsCurve, base);
40976var edwards = EdwardsCurve;
40977
40978EdwardsCurve.prototype._mulA = function _mulA(num) {
40979 if (this.mOneA)
40980 return num.redNeg();
40981 else
40982 return this.a.redMul(num);
40983};
40984
40985EdwardsCurve.prototype._mulC = function _mulC(num) {
40986 if (this.oneC)
40987 return num;
40988 else
40989 return this.c.redMul(num);
40990};
40991
40992// Just for compatibility with Short curve
40993EdwardsCurve.prototype.jpoint = function jpoint(x, y, z, t) {
40994 return this.point(x, y, z, t);
40995};
40996
40997EdwardsCurve.prototype.pointFromX = function pointFromX(x, odd) {
40998 x = new bn(x, 16);
40999 if (!x.red)
41000 x = x.toRed(this.red);
41001
41002 var x2 = x.redSqr();
41003 var rhs = this.c2.redSub(this.a.redMul(x2));
41004 var lhs = this.one.redSub(this.c2.redMul(this.d).redMul(x2));
41005
41006 var y2 = rhs.redMul(lhs.redInvm());
41007 var y = y2.redSqrt();
41008 if (y.redSqr().redSub(y2).cmp(this.zero) !== 0)
41009 throw new Error('invalid point');
41010
41011 var isOdd = y.fromRed().isOdd();
41012 if (odd && !isOdd || !odd && isOdd)
41013 y = y.redNeg();
41014
41015 return this.point(x, y);
41016};
41017
41018EdwardsCurve.prototype.pointFromY = function pointFromY(y, odd) {
41019 y = new bn(y, 16);
41020 if (!y.red)
41021 y = y.toRed(this.red);
41022
41023 // x^2 = (y^2 - c^2) / (c^2 d y^2 - a)
41024 var y2 = y.redSqr();
41025 var lhs = y2.redSub(this.c2);
41026 var rhs = y2.redMul(this.d).redMul(this.c2).redSub(this.a);
41027 var x2 = lhs.redMul(rhs.redInvm());
41028
41029 if (x2.cmp(this.zero) === 0) {
41030 if (odd)
41031 throw new Error('invalid point');
41032 else
41033 return this.point(this.zero, y);
41034 }
41035
41036 var x = x2.redSqrt();
41037 if (x.redSqr().redSub(x2).cmp(this.zero) !== 0)
41038 throw new Error('invalid point');
41039
41040 if (x.fromRed().isOdd() !== odd)
41041 x = x.redNeg();
41042
41043 return this.point(x, y);
41044};
41045
41046EdwardsCurve.prototype.validate = function validate(point) {
41047 if (point.isInfinity())
41048 return true;
41049
41050 // Curve: A * X^2 + Y^2 = C^2 * (1 + D * X^2 * Y^2)
41051 point.normalize();
41052
41053 var x2 = point.x.redSqr();
41054 var y2 = point.y.redSqr();
41055 var lhs = x2.redMul(this.a).redAdd(y2);
41056 var rhs = this.c2.redMul(this.one.redAdd(this.d.redMul(x2).redMul(y2)));
41057
41058 return lhs.cmp(rhs) === 0;
41059};
41060
41061function Point$2(curve, x, y, z, t) {
41062 base.BasePoint.call(this, curve, 'projective');
41063 if (x === null && y === null && z === null) {
41064 this.x = this.curve.zero;
41065 this.y = this.curve.one;
41066 this.z = this.curve.one;
41067 this.t = this.curve.zero;
41068 this.zOne = true;
41069 } else {
41070 this.x = new bn(x, 16);
41071 this.y = new bn(y, 16);
41072 this.z = z ? new bn(z, 16) : this.curve.one;
41073 this.t = t && new bn(t, 16);
41074 if (!this.x.red)
41075 this.x = this.x.toRed(this.curve.red);
41076 if (!this.y.red)
41077 this.y = this.y.toRed(this.curve.red);
41078 if (!this.z.red)
41079 this.z = this.z.toRed(this.curve.red);
41080 if (this.t && !this.t.red)
41081 this.t = this.t.toRed(this.curve.red);
41082 this.zOne = this.z === this.curve.one;
41083
41084 // Use extended coordinates
41085 if (this.curve.extended && !this.t) {
41086 this.t = this.x.redMul(this.y);
41087 if (!this.zOne)
41088 this.t = this.t.redMul(this.z.redInvm());
41089 }
41090 }
41091}
41092inherits(Point$2, base.BasePoint);
41093
41094EdwardsCurve.prototype.pointFromJSON = function pointFromJSON(obj) {
41095 return Point$2.fromJSON(this, obj);
41096};
41097
41098EdwardsCurve.prototype.point = function point(x, y, z, t) {
41099 return new Point$2(this, x, y, z, t);
41100};
41101
41102Point$2.fromJSON = function fromJSON(curve, obj) {
41103 return new Point$2(curve, obj[0], obj[1], obj[2]);
41104};
41105
41106Point$2.prototype.inspect = function inspect() {
41107 if (this.isInfinity())
41108 return '<EC Point Infinity>';
41109 return '<EC Point x: ' + this.x.fromRed().toString(16, 2) +
41110 ' y: ' + this.y.fromRed().toString(16, 2) +
41111 ' z: ' + this.z.fromRed().toString(16, 2) + '>';
41112};
41113
41114Point$2.prototype.isInfinity = function isInfinity() {
41115 // XXX This code assumes that zero is always zero in red
41116 return this.x.cmpn(0) === 0 &&
41117 (this.y.cmp(this.z) === 0 ||
41118 (this.zOne && this.y.cmp(this.curve.c) === 0));
41119};
41120
41121Point$2.prototype._extDbl = function _extDbl() {
41122 // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
41123 // #doubling-dbl-2008-hwcd
41124 // 4M + 4S
41125
41126 // A = X1^2
41127 var a = this.x.redSqr();
41128 // B = Y1^2
41129 var b = this.y.redSqr();
41130 // C = 2 * Z1^2
41131 var c = this.z.redSqr();
41132 c = c.redIAdd(c);
41133 // D = a * A
41134 var d = this.curve._mulA(a);
41135 // E = (X1 + Y1)^2 - A - B
41136 var e = this.x.redAdd(this.y).redSqr().redISub(a).redISub(b);
41137 // G = D + B
41138 var g = d.redAdd(b);
41139 // F = G - C
41140 var f = g.redSub(c);
41141 // H = D - B
41142 var h = d.redSub(b);
41143 // X3 = E * F
41144 var nx = e.redMul(f);
41145 // Y3 = G * H
41146 var ny = g.redMul(h);
41147 // T3 = E * H
41148 var nt = e.redMul(h);
41149 // Z3 = F * G
41150 var nz = f.redMul(g);
41151 return this.curve.point(nx, ny, nz, nt);
41152};
41153
41154Point$2.prototype._projDbl = function _projDbl() {
41155 // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
41156 // #doubling-dbl-2008-bbjlp
41157 // #doubling-dbl-2007-bl
41158 // and others
41159 // Generally 3M + 4S or 2M + 4S
41160
41161 // B = (X1 + Y1)^2
41162 var b = this.x.redAdd(this.y).redSqr();
41163 // C = X1^2
41164 var c = this.x.redSqr();
41165 // D = Y1^2
41166 var d = this.y.redSqr();
41167
41168 var nx;
41169 var ny;
41170 var nz;
41171 if (this.curve.twisted) {
41172 // E = a * C
41173 var e = this.curve._mulA(c);
41174 // F = E + D
41175 var f = e.redAdd(d);
41176 if (this.zOne) {
41177 // X3 = (B - C - D) * (F - 2)
41178 nx = b.redSub(c).redSub(d).redMul(f.redSub(this.curve.two));
41179 // Y3 = F * (E - D)
41180 ny = f.redMul(e.redSub(d));
41181 // Z3 = F^2 - 2 * F
41182 nz = f.redSqr().redSub(f).redSub(f);
41183 } else {
41184 // H = Z1^2
41185 var h = this.z.redSqr();
41186 // J = F - 2 * H
41187 var j = f.redSub(h).redISub(h);
41188 // X3 = (B-C-D)*J
41189 nx = b.redSub(c).redISub(d).redMul(j);
41190 // Y3 = F * (E - D)
41191 ny = f.redMul(e.redSub(d));
41192 // Z3 = F * J
41193 nz = f.redMul(j);
41194 }
41195 } else {
41196 // E = C + D
41197 var e = c.redAdd(d);
41198 // H = (c * Z1)^2
41199 var h = this.curve._mulC(this.z).redSqr();
41200 // J = E - 2 * H
41201 var j = e.redSub(h).redSub(h);
41202 // X3 = c * (B - E) * J
41203 nx = this.curve._mulC(b.redISub(e)).redMul(j);
41204 // Y3 = c * E * (C - D)
41205 ny = this.curve._mulC(e).redMul(c.redISub(d));
41206 // Z3 = E * J
41207 nz = e.redMul(j);
41208 }
41209 return this.curve.point(nx, ny, nz);
41210};
41211
41212Point$2.prototype.dbl = function dbl() {
41213 if (this.isInfinity())
41214 return this;
41215
41216 // Double in extended coordinates
41217 if (this.curve.extended)
41218 return this._extDbl();
41219 else
41220 return this._projDbl();
41221};
41222
41223Point$2.prototype._extAdd = function _extAdd(p) {
41224 // hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
41225 // #addition-add-2008-hwcd-3
41226 // 8M
41227
41228 // A = (Y1 - X1) * (Y2 - X2)
41229 var a = this.y.redSub(this.x).redMul(p.y.redSub(p.x));
41230 // B = (Y1 + X1) * (Y2 + X2)
41231 var b = this.y.redAdd(this.x).redMul(p.y.redAdd(p.x));
41232 // C = T1 * k * T2
41233 var c = this.t.redMul(this.curve.dd).redMul(p.t);
41234 // D = Z1 * 2 * Z2
41235 var d = this.z.redMul(p.z.redAdd(p.z));
41236 // E = B - A
41237 var e = b.redSub(a);
41238 // F = D - C
41239 var f = d.redSub(c);
41240 // G = D + C
41241 var g = d.redAdd(c);
41242 // H = B + A
41243 var h = b.redAdd(a);
41244 // X3 = E * F
41245 var nx = e.redMul(f);
41246 // Y3 = G * H
41247 var ny = g.redMul(h);
41248 // T3 = E * H
41249 var nt = e.redMul(h);
41250 // Z3 = F * G
41251 var nz = f.redMul(g);
41252 return this.curve.point(nx, ny, nz, nt);
41253};
41254
41255Point$2.prototype._projAdd = function _projAdd(p) {
41256 // hyperelliptic.org/EFD/g1p/auto-twisted-projective.html
41257 // #addition-add-2008-bbjlp
41258 // #addition-add-2007-bl
41259 // 10M + 1S
41260
41261 // A = Z1 * Z2
41262 var a = this.z.redMul(p.z);
41263 // B = A^2
41264 var b = a.redSqr();
41265 // C = X1 * X2
41266 var c = this.x.redMul(p.x);
41267 // D = Y1 * Y2
41268 var d = this.y.redMul(p.y);
41269 // E = d * C * D
41270 var e = this.curve.d.redMul(c).redMul(d);
41271 // F = B - E
41272 var f = b.redSub(e);
41273 // G = B + E
41274 var g = b.redAdd(e);
41275 // X3 = A * F * ((X1 + Y1) * (X2 + Y2) - C - D)
41276 var tmp = this.x.redAdd(this.y).redMul(p.x.redAdd(p.y)).redISub(c).redISub(d);
41277 var nx = a.redMul(f).redMul(tmp);
41278 var ny;
41279 var nz;
41280 if (this.curve.twisted) {
41281 // Y3 = A * G * (D - a * C)
41282 ny = a.redMul(g).redMul(d.redSub(this.curve._mulA(c)));
41283 // Z3 = F * G
41284 nz = f.redMul(g);
41285 } else {
41286 // Y3 = A * G * (D - C)
41287 ny = a.redMul(g).redMul(d.redSub(c));
41288 // Z3 = c * F * G
41289 nz = this.curve._mulC(f).redMul(g);
41290 }
41291 return this.curve.point(nx, ny, nz);
41292};
41293
41294Point$2.prototype.add = function add(p) {
41295 if (this.isInfinity())
41296 return p;
41297 if (p.isInfinity())
41298 return this;
41299
41300 if (this.curve.extended)
41301 return this._extAdd(p);
41302 else
41303 return this._projAdd(p);
41304};
41305
41306Point$2.prototype.mul = function mul(k) {
41307 if (this._hasDoubles(k))
41308 return this.curve._fixedNafMul(this, k);
41309 else
41310 return this.curve._wnafMul(this, k);
41311};
41312
41313Point$2.prototype.mulAdd = function mulAdd(k1, p, k2) {
41314 return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, false);
41315};
41316
41317Point$2.prototype.jmulAdd = function jmulAdd(k1, p, k2) {
41318 return this.curve._wnafMulAdd(1, [ this, p ], [ k1, k2 ], 2, true);
41319};
41320
41321Point$2.prototype.normalize = function normalize() {
41322 if (this.zOne)
41323 return this;
41324
41325 // Normalize coordinates
41326 var zi = this.z.redInvm();
41327 this.x = this.x.redMul(zi);
41328 this.y = this.y.redMul(zi);
41329 if (this.t)
41330 this.t = this.t.redMul(zi);
41331 this.z = this.curve.one;
41332 this.zOne = true;
41333 return this;
41334};
41335
41336Point$2.prototype.neg = function neg() {
41337 return this.curve.point(this.x.redNeg(),
41338 this.y,
41339 this.z,
41340 this.t && this.t.redNeg());
41341};
41342
41343Point$2.prototype.getX = function getX() {
41344 this.normalize();
41345 return this.x.fromRed();
41346};
41347
41348Point$2.prototype.getY = function getY() {
41349 this.normalize();
41350 return this.y.fromRed();
41351};
41352
41353Point$2.prototype.eq = function eq(other) {
41354 return this === other ||
41355 this.getX().cmp(other.getX()) === 0 &&
41356 this.getY().cmp(other.getY()) === 0;
41357};
41358
41359Point$2.prototype.eqXToP = function eqXToP(x) {
41360 var rx = x.toRed(this.curve.red).redMul(this.z);
41361 if (this.x.cmp(rx) === 0)
41362 return true;
41363
41364 var xc = x.clone();
41365 var t = this.curve.redN.redMul(this.z);
41366 for (;;) {
41367 xc.iadd(this.curve.n);
41368 if (xc.cmp(this.curve.p) >= 0)
41369 return false;
41370
41371 rx.redIAdd(t);
41372 if (this.x.cmp(rx) === 0)
41373 return true;
41374 }
41375};
41376
41377// Compatibility with BaseCurve
41378Point$2.prototype.toP = Point$2.prototype.normalize;
41379Point$2.prototype.mixedAdd = Point$2.prototype.add;
41380
41381var curve_1 = createCommonjsModule(function (module, exports) {
41382
41383var curve = exports;
41384
41385curve.base = base;
41386curve.short = short_1;
41387curve.mont = mont;
41388curve.edwards = edwards;
41389});
41390
41391var rotl32$2 = utils.rotl32;
41392var sum32$3 = utils.sum32;
41393var sum32_5$2 = utils.sum32_5;
41394var ft_1$1 = common$1.ft_1;
41395var BlockHash$4 = common.BlockHash;
41396
41397var sha1_K = [
41398 0x5A827999, 0x6ED9EBA1,
41399 0x8F1BBCDC, 0xCA62C1D6
41400];
41401
41402function SHA1() {
41403 if (!(this instanceof SHA1))
41404 return new SHA1();
41405
41406 BlockHash$4.call(this);
41407 this.h = [
41408 0x67452301, 0xefcdab89, 0x98badcfe,
41409 0x10325476, 0xc3d2e1f0 ];
41410 this.W = new Array(80);
41411}
41412
41413utils.inherits(SHA1, BlockHash$4);
41414var _1 = SHA1;
41415
41416SHA1.blockSize = 512;
41417SHA1.outSize = 160;
41418SHA1.hmacStrength = 80;
41419SHA1.padLength = 64;
41420
41421SHA1.prototype._update = function _update(msg, start) {
41422 var W = this.W;
41423
41424 for (var i = 0; i < 16; i++)
41425 W[i] = msg[start + i];
41426
41427 for(; i < W.length; i++)
41428 W[i] = rotl32$2(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
41429
41430 var a = this.h[0];
41431 var b = this.h[1];
41432 var c = this.h[2];
41433 var d = this.h[3];
41434 var e = this.h[4];
41435
41436 for (i = 0; i < W.length; i++) {
41437 var s = ~~(i / 20);
41438 var t = sum32_5$2(rotl32$2(a, 5), ft_1$1(s, b, c, d), e, W[i], sha1_K[s]);
41439 e = d;
41440 d = c;
41441 c = rotl32$2(b, 30);
41442 b = a;
41443 a = t;
41444 }
41445
41446 this.h[0] = sum32$3(this.h[0], a);
41447 this.h[1] = sum32$3(this.h[1], b);
41448 this.h[2] = sum32$3(this.h[2], c);
41449 this.h[3] = sum32$3(this.h[3], d);
41450 this.h[4] = sum32$3(this.h[4], e);
41451};
41452
41453SHA1.prototype._digest = function digest(enc) {
41454 if (enc === 'hex')
41455 return utils.toHex32(this.h, 'big');
41456 else
41457 return utils.split32(this.h, 'big');
41458};
41459
41460var sha1 = _1;
41461var sha224 = _224;
41462var sha256 = _256;
41463var sha384 = _384;
41464var sha512 = _512;
41465
41466var sha = {
41467 sha1: sha1,
41468 sha224: sha224,
41469 sha256: sha256,
41470 sha384: sha384,
41471 sha512: sha512
41472};
41473
41474function Hmac(hash, key, enc) {
41475 if (!(this instanceof Hmac))
41476 return new Hmac(hash, key, enc);
41477 this.Hash = hash;
41478 this.blockSize = hash.blockSize / 8;
41479 this.outSize = hash.outSize / 8;
41480 this.inner = null;
41481 this.outer = null;
41482
41483 this._init(utils.toArray(key, enc));
41484}
41485var hmac = Hmac;
41486
41487Hmac.prototype._init = function init(key) {
41488 // Shorten key, if needed
41489 if (key.length > this.blockSize)
41490 key = new this.Hash().update(key).digest();
41491 minimalisticAssert(key.length <= this.blockSize);
41492
41493 // Add padding to key
41494 for (var i = key.length; i < this.blockSize; i++)
41495 key.push(0);
41496
41497 for (i = 0; i < key.length; i++)
41498 key[i] ^= 0x36;
41499 this.inner = new this.Hash().update(key);
41500
41501 // 0x36 ^ 0x5c = 0x6a
41502 for (i = 0; i < key.length; i++)
41503 key[i] ^= 0x6a;
41504 this.outer = new this.Hash().update(key);
41505};
41506
41507Hmac.prototype.update = function update(msg, enc) {
41508 this.inner.update(msg, enc);
41509 return this;
41510};
41511
41512Hmac.prototype.digest = function digest(enc) {
41513 this.outer.update(this.inner.digest());
41514 return this.outer.digest(enc);
41515};
41516
41517var hash_1 = createCommonjsModule(function (module, exports) {
41518var hash = exports;
41519
41520hash.utils = utils;
41521hash.common = common;
41522hash.sha = sha;
41523hash.ripemd = ripemd;
41524hash.hmac = hmac;
41525
41526// Proxy hash functions to the main object
41527hash.sha1 = hash.sha.sha1;
41528hash.sha256 = hash.sha.sha256;
41529hash.sha224 = hash.sha.sha224;
41530hash.sha384 = hash.sha.sha384;
41531hash.sha512 = hash.sha.sha512;
41532hash.ripemd160 = hash.ripemd.ripemd160;
41533});
41534
41535var secp256k1 = {
41536 doubles: {
41537 step: 4,
41538 points: [
41539 [
41540 'e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a',
41541 'f7e3507399e595929db99f34f57937101296891e44d23f0be1f32cce69616821'
41542 ],
41543 [
41544 '8282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508',
41545 '11f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf'
41546 ],
41547 [
41548 '175e159f728b865a72f99cc6c6fc846de0b93833fd2222ed73fce5b551e5b739',
41549 'd3506e0d9e3c79eba4ef97a51ff71f5eacb5955add24345c6efa6ffee9fed695'
41550 ],
41551 [
41552 '363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640',
41553 '4e273adfc732221953b445397f3363145b9a89008199ecb62003c7f3bee9de9'
41554 ],
41555 [
41556 '8b4b5f165df3c2be8c6244b5b745638843e4a781a15bcd1b69f79a55dffdf80c',
41557 '4aad0a6f68d308b4b3fbd7813ab0da04f9e336546162ee56b3eff0c65fd4fd36'
41558 ],
41559 [
41560 '723cbaa6e5db996d6bf771c00bd548c7b700dbffa6c0e77bcb6115925232fcda',
41561 '96e867b5595cc498a921137488824d6e2660a0653779494801dc069d9eb39f5f'
41562 ],
41563 [
41564 'eebfa4d493bebf98ba5feec812c2d3b50947961237a919839a533eca0e7dd7fa',
41565 '5d9a8ca3970ef0f269ee7edaf178089d9ae4cdc3a711f712ddfd4fdae1de8999'
41566 ],
41567 [
41568 '100f44da696e71672791d0a09b7bde459f1215a29b3c03bfefd7835b39a48db0',
41569 'cdd9e13192a00b772ec8f3300c090666b7ff4a18ff5195ac0fbd5cd62bc65a09'
41570 ],
41571 [
41572 'e1031be262c7ed1b1dc9227a4a04c017a77f8d4464f3b3852c8acde6e534fd2d',
41573 '9d7061928940405e6bb6a4176597535af292dd419e1ced79a44f18f29456a00d'
41574 ],
41575 [
41576 'feea6cae46d55b530ac2839f143bd7ec5cf8b266a41d6af52d5e688d9094696d',
41577 'e57c6b6c97dce1bab06e4e12bf3ecd5c981c8957cc41442d3155debf18090088'
41578 ],
41579 [
41580 'da67a91d91049cdcb367be4be6ffca3cfeed657d808583de33fa978bc1ec6cb1',
41581 '9bacaa35481642bc41f463f7ec9780e5dec7adc508f740a17e9ea8e27a68be1d'
41582 ],
41583 [
41584 '53904faa0b334cdda6e000935ef22151ec08d0f7bb11069f57545ccc1a37b7c0',
41585 '5bc087d0bc80106d88c9eccac20d3c1c13999981e14434699dcb096b022771c8'
41586 ],
41587 [
41588 '8e7bcd0bd35983a7719cca7764ca906779b53a043a9b8bcaeff959f43ad86047',
41589 '10b7770b2a3da4b3940310420ca9514579e88e2e47fd68b3ea10047e8460372a'
41590 ],
41591 [
41592 '385eed34c1cdff21e6d0818689b81bde71a7f4f18397e6690a841e1599c43862',
41593 '283bebc3e8ea23f56701de19e9ebf4576b304eec2086dc8cc0458fe5542e5453'
41594 ],
41595 [
41596 '6f9d9b803ecf191637c73a4413dfa180fddf84a5947fbc9c606ed86c3fac3a7',
41597 '7c80c68e603059ba69b8e2a30e45c4d47ea4dd2f5c281002d86890603a842160'
41598 ],
41599 [
41600 '3322d401243c4e2582a2147c104d6ecbf774d163db0f5e5313b7e0e742d0e6bd',
41601 '56e70797e9664ef5bfb019bc4ddaf9b72805f63ea2873af624f3a2e96c28b2a0'
41602 ],
41603 [
41604 '85672c7d2de0b7da2bd1770d89665868741b3f9af7643397721d74d28134ab83',
41605 '7c481b9b5b43b2eb6374049bfa62c2e5e77f17fcc5298f44c8e3094f790313a6'
41606 ],
41607 [
41608 '948bf809b1988a46b06c9f1919413b10f9226c60f668832ffd959af60c82a0a',
41609 '53a562856dcb6646dc6b74c5d1c3418c6d4dff08c97cd2bed4cb7f88d8c8e589'
41610 ],
41611 [
41612 '6260ce7f461801c34f067ce0f02873a8f1b0e44dfc69752accecd819f38fd8e8',
41613 'bc2da82b6fa5b571a7f09049776a1ef7ecd292238051c198c1a84e95b2b4ae17'
41614 ],
41615 [
41616 'e5037de0afc1d8d43d8348414bbf4103043ec8f575bfdc432953cc8d2037fa2d',
41617 '4571534baa94d3b5f9f98d09fb990bddbd5f5b03ec481f10e0e5dc841d755bda'
41618 ],
41619 [
41620 'e06372b0f4a207adf5ea905e8f1771b4e7e8dbd1c6a6c5b725866a0ae4fce725',
41621 '7a908974bce18cfe12a27bb2ad5a488cd7484a7787104870b27034f94eee31dd'
41622 ],
41623 [
41624 '213c7a715cd5d45358d0bbf9dc0ce02204b10bdde2a3f58540ad6908d0559754',
41625 '4b6dad0b5ae462507013ad06245ba190bb4850f5f36a7eeddff2c27534b458f2'
41626 ],
41627 [
41628 '4e7c272a7af4b34e8dbb9352a5419a87e2838c70adc62cddf0cc3a3b08fbd53c',
41629 '17749c766c9d0b18e16fd09f6def681b530b9614bff7dd33e0b3941817dcaae6'
41630 ],
41631 [
41632 'fea74e3dbe778b1b10f238ad61686aa5c76e3db2be43057632427e2840fb27b6',
41633 '6e0568db9b0b13297cf674deccb6af93126b596b973f7b77701d3db7f23cb96f'
41634 ],
41635 [
41636 '76e64113f677cf0e10a2570d599968d31544e179b760432952c02a4417bdde39',
41637 'c90ddf8dee4e95cf577066d70681f0d35e2a33d2b56d2032b4b1752d1901ac01'
41638 ],
41639 [
41640 'c738c56b03b2abe1e8281baa743f8f9a8f7cc643df26cbee3ab150242bcbb891',
41641 '893fb578951ad2537f718f2eacbfbbbb82314eef7880cfe917e735d9699a84c3'
41642 ],
41643 [
41644 'd895626548b65b81e264c7637c972877d1d72e5f3a925014372e9f6588f6c14b',
41645 'febfaa38f2bc7eae728ec60818c340eb03428d632bb067e179363ed75d7d991f'
41646 ],
41647 [
41648 'b8da94032a957518eb0f6433571e8761ceffc73693e84edd49150a564f676e03',
41649 '2804dfa44805a1e4d7c99cc9762808b092cc584d95ff3b511488e4e74efdf6e7'
41650 ],
41651 [
41652 'e80fea14441fb33a7d8adab9475d7fab2019effb5156a792f1a11778e3c0df5d',
41653 'eed1de7f638e00771e89768ca3ca94472d155e80af322ea9fcb4291b6ac9ec78'
41654 ],
41655 [
41656 'a301697bdfcd704313ba48e51d567543f2a182031efd6915ddc07bbcc4e16070',
41657 '7370f91cfb67e4f5081809fa25d40f9b1735dbf7c0a11a130c0d1a041e177ea1'
41658 ],
41659 [
41660 '90ad85b389d6b936463f9d0512678de208cc330b11307fffab7ac63e3fb04ed4',
41661 'e507a3620a38261affdcbd9427222b839aefabe1582894d991d4d48cb6ef150'
41662 ],
41663 [
41664 '8f68b9d2f63b5f339239c1ad981f162ee88c5678723ea3351b7b444c9ec4c0da',
41665 '662a9f2dba063986de1d90c2b6be215dbbea2cfe95510bfdf23cbf79501fff82'
41666 ],
41667 [
41668 'e4f3fb0176af85d65ff99ff9198c36091f48e86503681e3e6686fd5053231e11',
41669 '1e63633ad0ef4f1c1661a6d0ea02b7286cc7e74ec951d1c9822c38576feb73bc'
41670 ],
41671 [
41672 '8c00fa9b18ebf331eb961537a45a4266c7034f2f0d4e1d0716fb6eae20eae29e',
41673 'efa47267fea521a1a9dc343a3736c974c2fadafa81e36c54e7d2a4c66702414b'
41674 ],
41675 [
41676 'e7a26ce69dd4829f3e10cec0a9e98ed3143d084f308b92c0997fddfc60cb3e41',
41677 '2a758e300fa7984b471b006a1aafbb18d0a6b2c0420e83e20e8a9421cf2cfd51'
41678 ],
41679 [
41680 'b6459e0ee3662ec8d23540c223bcbdc571cbcb967d79424f3cf29eb3de6b80ef',
41681 '67c876d06f3e06de1dadf16e5661db3c4b3ae6d48e35b2ff30bf0b61a71ba45'
41682 ],
41683 [
41684 'd68a80c8280bb840793234aa118f06231d6f1fc67e73c5a5deda0f5b496943e8',
41685 'db8ba9fff4b586d00c4b1f9177b0e28b5b0e7b8f7845295a294c84266b133120'
41686 ],
41687 [
41688 '324aed7df65c804252dc0270907a30b09612aeb973449cea4095980fc28d3d5d',
41689 '648a365774b61f2ff130c0c35aec1f4f19213b0c7e332843967224af96ab7c84'
41690 ],
41691 [
41692 '4df9c14919cde61f6d51dfdbe5fee5dceec4143ba8d1ca888e8bd373fd054c96',
41693 '35ec51092d8728050974c23a1d85d4b5d506cdc288490192ebac06cad10d5d'
41694 ],
41695 [
41696 '9c3919a84a474870faed8a9c1cc66021523489054d7f0308cbfc99c8ac1f98cd',
41697 'ddb84f0f4a4ddd57584f044bf260e641905326f76c64c8e6be7e5e03d4fc599d'
41698 ],
41699 [
41700 '6057170b1dd12fdf8de05f281d8e06bb91e1493a8b91d4cc5a21382120a959e5',
41701 '9a1af0b26a6a4807add9a2daf71df262465152bc3ee24c65e899be932385a2a8'
41702 ],
41703 [
41704 'a576df8e23a08411421439a4518da31880cef0fba7d4df12b1a6973eecb94266',
41705 '40a6bf20e76640b2c92b97afe58cd82c432e10a7f514d9f3ee8be11ae1b28ec8'
41706 ],
41707 [
41708 '7778a78c28dec3e30a05fe9629de8c38bb30d1f5cf9a3a208f763889be58ad71',
41709 '34626d9ab5a5b22ff7098e12f2ff580087b38411ff24ac563b513fc1fd9f43ac'
41710 ],
41711 [
41712 '928955ee637a84463729fd30e7afd2ed5f96274e5ad7e5cb09eda9c06d903ac',
41713 'c25621003d3f42a827b78a13093a95eeac3d26efa8a8d83fc5180e935bcd091f'
41714 ],
41715 [
41716 '85d0fef3ec6db109399064f3a0e3b2855645b4a907ad354527aae75163d82751',
41717 '1f03648413a38c0be29d496e582cf5663e8751e96877331582c237a24eb1f962'
41718 ],
41719 [
41720 'ff2b0dce97eece97c1c9b6041798b85dfdfb6d8882da20308f5404824526087e',
41721 '493d13fef524ba188af4c4dc54d07936c7b7ed6fb90e2ceb2c951e01f0c29907'
41722 ],
41723 [
41724 '827fbbe4b1e880ea9ed2b2e6301b212b57f1ee148cd6dd28780e5e2cf856e241',
41725 'c60f9c923c727b0b71bef2c67d1d12687ff7a63186903166d605b68baec293ec'
41726 ],
41727 [
41728 'eaa649f21f51bdbae7be4ae34ce6e5217a58fdce7f47f9aa7f3b58fa2120e2b3',
41729 'be3279ed5bbbb03ac69a80f89879aa5a01a6b965f13f7e59d47a5305ba5ad93d'
41730 ],
41731 [
41732 'e4a42d43c5cf169d9391df6decf42ee541b6d8f0c9a137401e23632dda34d24f',
41733 '4d9f92e716d1c73526fc99ccfb8ad34ce886eedfa8d8e4f13a7f7131deba9414'
41734 ],
41735 [
41736 '1ec80fef360cbdd954160fadab352b6b92b53576a88fea4947173b9d4300bf19',
41737 'aeefe93756b5340d2f3a4958a7abbf5e0146e77f6295a07b671cdc1cc107cefd'
41738 ],
41739 [
41740 '146a778c04670c2f91b00af4680dfa8bce3490717d58ba889ddb5928366642be',
41741 'b318e0ec3354028add669827f9d4b2870aaa971d2f7e5ed1d0b297483d83efd0'
41742 ],
41743 [
41744 'fa50c0f61d22e5f07e3acebb1aa07b128d0012209a28b9776d76a8793180eef9',
41745 '6b84c6922397eba9b72cd2872281a68a5e683293a57a213b38cd8d7d3f4f2811'
41746 ],
41747 [
41748 'da1d61d0ca721a11b1a5bf6b7d88e8421a288ab5d5bba5220e53d32b5f067ec2',
41749 '8157f55a7c99306c79c0766161c91e2966a73899d279b48a655fba0f1ad836f1'
41750 ],
41751 [
41752 'a8e282ff0c9706907215ff98e8fd416615311de0446f1e062a73b0610d064e13',
41753 '7f97355b8db81c09abfb7f3c5b2515888b679a3e50dd6bd6cef7c73111f4cc0c'
41754 ],
41755 [
41756 '174a53b9c9a285872d39e56e6913cab15d59b1fa512508c022f382de8319497c',
41757 'ccc9dc37abfc9c1657b4155f2c47f9e6646b3a1d8cb9854383da13ac079afa73'
41758 ],
41759 [
41760 '959396981943785c3d3e57edf5018cdbe039e730e4918b3d884fdff09475b7ba',
41761 '2e7e552888c331dd8ba0386a4b9cd6849c653f64c8709385e9b8abf87524f2fd'
41762 ],
41763 [
41764 'd2a63a50ae401e56d645a1153b109a8fcca0a43d561fba2dbb51340c9d82b151',
41765 'e82d86fb6443fcb7565aee58b2948220a70f750af484ca52d4142174dcf89405'
41766 ],
41767 [
41768 '64587e2335471eb890ee7896d7cfdc866bacbdbd3839317b3436f9b45617e073',
41769 'd99fcdd5bf6902e2ae96dd6447c299a185b90a39133aeab358299e5e9faf6589'
41770 ],
41771 [
41772 '8481bde0e4e4d885b3a546d3e549de042f0aa6cea250e7fd358d6c86dd45e458',
41773 '38ee7b8cba5404dd84a25bf39cecb2ca900a79c42b262e556d64b1b59779057e'
41774 ],
41775 [
41776 '13464a57a78102aa62b6979ae817f4637ffcfed3c4b1ce30bcd6303f6caf666b',
41777 '69be159004614580ef7e433453ccb0ca48f300a81d0942e13f495a907f6ecc27'
41778 ],
41779 [
41780 'bc4a9df5b713fe2e9aef430bcc1dc97a0cd9ccede2f28588cada3a0d2d83f366',
41781 'd3a81ca6e785c06383937adf4b798caa6e8a9fbfa547b16d758d666581f33c1'
41782 ],
41783 [
41784 '8c28a97bf8298bc0d23d8c749452a32e694b65e30a9472a3954ab30fe5324caa',
41785 '40a30463a3305193378fedf31f7cc0eb7ae784f0451cb9459e71dc73cbef9482'
41786 ],
41787 [
41788 '8ea9666139527a8c1dd94ce4f071fd23c8b350c5a4bb33748c4ba111faccae0',
41789 '620efabbc8ee2782e24e7c0cfb95c5d735b783be9cf0f8e955af34a30e62b945'
41790 ],
41791 [
41792 'dd3625faef5ba06074669716bbd3788d89bdde815959968092f76cc4eb9a9787',
41793 '7a188fa3520e30d461da2501045731ca941461982883395937f68d00c644a573'
41794 ],
41795 [
41796 'f710d79d9eb962297e4f6232b40e8f7feb2bc63814614d692c12de752408221e',
41797 'ea98e67232d3b3295d3b535532115ccac8612c721851617526ae47a9c77bfc82'
41798 ]
41799 ]
41800 },
41801 naf: {
41802 wnd: 7,
41803 points: [
41804 [
41805 'f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9',
41806 '388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672'
41807 ],
41808 [
41809 '2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4',
41810 'd8ac222636e5e3d6d4dba9dda6c9c426f788271bab0d6840dca87d3aa6ac62d6'
41811 ],
41812 [
41813 '5cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc',
41814 '6aebca40ba255960a3178d6d861a54dba813d0b813fde7b5a5082628087264da'
41815 ],
41816 [
41817 'acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe',
41818 'cc338921b0a7d9fd64380971763b61e9add888a4375f8e0f05cc262ac64f9c37'
41819 ],
41820 [
41821 '774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb',
41822 'd984a032eb6b5e190243dd56d7b7b365372db1e2dff9d6a8301d74c9c953c61b'
41823 ],
41824 [
41825 'f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8',
41826 'ab0902e8d880a89758212eb65cdaf473a1a06da521fa91f29b5cb52db03ed81'
41827 ],
41828 [
41829 'd7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e',
41830 '581e2872a86c72a683842ec228cc6defea40af2bd896d3a5c504dc9ff6a26b58'
41831 ],
41832 [
41833 'defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34',
41834 '4211ab0694635168e997b0ead2a93daeced1f4a04a95c0f6cfb199f69e56eb77'
41835 ],
41836 [
41837 '2b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c',
41838 '85e89bc037945d93b343083b5a1c86131a01f60c50269763b570c854e5c09b7a'
41839 ],
41840 [
41841 '352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5',
41842 '321eb4075348f534d59c18259dda3e1f4a1b3b2e71b1039c67bd3d8bcf81998c'
41843 ],
41844 [
41845 '2fa2104d6b38d11b0230010559879124e42ab8dfeff5ff29dc9cdadd4ecacc3f',
41846 '2de1068295dd865b64569335bd5dd80181d70ecfc882648423ba76b532b7d67'
41847 ],
41848 [
41849 '9248279b09b4d68dab21a9b066edda83263c3d84e09572e269ca0cd7f5453714',
41850 '73016f7bf234aade5d1aa71bdea2b1ff3fc0de2a887912ffe54a32ce97cb3402'
41851 ],
41852 [
41853 'daed4f2be3a8bf278e70132fb0beb7522f570e144bf615c07e996d443dee8729',
41854 'a69dce4a7d6c98e8d4a1aca87ef8d7003f83c230f3afa726ab40e52290be1c55'
41855 ],
41856 [
41857 'c44d12c7065d812e8acf28d7cbb19f9011ecd9e9fdf281b0e6a3b5e87d22e7db',
41858 '2119a460ce326cdc76c45926c982fdac0e106e861edf61c5a039063f0e0e6482'
41859 ],
41860 [
41861 '6a245bf6dc698504c89a20cfded60853152b695336c28063b61c65cbd269e6b4',
41862 'e022cf42c2bd4a708b3f5126f16a24ad8b33ba48d0423b6efd5e6348100d8a82'
41863 ],
41864 [
41865 '1697ffa6fd9de627c077e3d2fe541084ce13300b0bec1146f95ae57f0d0bd6a5',
41866 'b9c398f186806f5d27561506e4557433a2cf15009e498ae7adee9d63d01b2396'
41867 ],
41868 [
41869 '605bdb019981718b986d0f07e834cb0d9deb8360ffb7f61df982345ef27a7479',
41870 '2972d2de4f8d20681a78d93ec96fe23c26bfae84fb14db43b01e1e9056b8c49'
41871 ],
41872 [
41873 '62d14dab4150bf497402fdc45a215e10dcb01c354959b10cfe31c7e9d87ff33d',
41874 '80fc06bd8cc5b01098088a1950eed0db01aa132967ab472235f5642483b25eaf'
41875 ],
41876 [
41877 '80c60ad0040f27dade5b4b06c408e56b2c50e9f56b9b8b425e555c2f86308b6f',
41878 '1c38303f1cc5c30f26e66bad7fe72f70a65eed4cbe7024eb1aa01f56430bd57a'
41879 ],
41880 [
41881 '7a9375ad6167ad54aa74c6348cc54d344cc5dc9487d847049d5eabb0fa03c8fb',
41882 'd0e3fa9eca8726909559e0d79269046bdc59ea10c70ce2b02d499ec224dc7f7'
41883 ],
41884 [
41885 'd528ecd9b696b54c907a9ed045447a79bb408ec39b68df504bb51f459bc3ffc9',
41886 'eecf41253136e5f99966f21881fd656ebc4345405c520dbc063465b521409933'
41887 ],
41888 [
41889 '49370a4b5f43412ea25f514e8ecdad05266115e4a7ecb1387231808f8b45963',
41890 '758f3f41afd6ed428b3081b0512fd62a54c3f3afbb5b6764b653052a12949c9a'
41891 ],
41892 [
41893 '77f230936ee88cbbd73df930d64702ef881d811e0e1498e2f1c13eb1fc345d74',
41894 '958ef42a7886b6400a08266e9ba1b37896c95330d97077cbbe8eb3c7671c60d6'
41895 ],
41896 [
41897 'f2dac991cc4ce4b9ea44887e5c7c0bce58c80074ab9d4dbaeb28531b7739f530',
41898 'e0dedc9b3b2f8dad4da1f32dec2531df9eb5fbeb0598e4fd1a117dba703a3c37'
41899 ],
41900 [
41901 '463b3d9f662621fb1b4be8fbbe2520125a216cdfc9dae3debcba4850c690d45b',
41902 '5ed430d78c296c3543114306dd8622d7c622e27c970a1de31cb377b01af7307e'
41903 ],
41904 [
41905 'f16f804244e46e2a09232d4aff3b59976b98fac14328a2d1a32496b49998f247',
41906 'cedabd9b82203f7e13d206fcdf4e33d92a6c53c26e5cce26d6579962c4e31df6'
41907 ],
41908 [
41909 'caf754272dc84563b0352b7a14311af55d245315ace27c65369e15f7151d41d1',
41910 'cb474660ef35f5f2a41b643fa5e460575f4fa9b7962232a5c32f908318a04476'
41911 ],
41912 [
41913 '2600ca4b282cb986f85d0f1709979d8b44a09c07cb86d7c124497bc86f082120',
41914 '4119b88753c15bd6a693b03fcddbb45d5ac6be74ab5f0ef44b0be9475a7e4b40'
41915 ],
41916 [
41917 '7635ca72d7e8432c338ec53cd12220bc01c48685e24f7dc8c602a7746998e435',
41918 '91b649609489d613d1d5e590f78e6d74ecfc061d57048bad9e76f302c5b9c61'
41919 ],
41920 [
41921 '754e3239f325570cdbbf4a87deee8a66b7f2b33479d468fbc1a50743bf56cc18',
41922 '673fb86e5bda30fb3cd0ed304ea49a023ee33d0197a695d0c5d98093c536683'
41923 ],
41924 [
41925 'e3e6bd1071a1e96aff57859c82d570f0330800661d1c952f9fe2694691d9b9e8',
41926 '59c9e0bba394e76f40c0aa58379a3cb6a5a2283993e90c4167002af4920e37f5'
41927 ],
41928 [
41929 '186b483d056a033826ae73d88f732985c4ccb1f32ba35f4b4cc47fdcf04aa6eb',
41930 '3b952d32c67cf77e2e17446e204180ab21fb8090895138b4a4a797f86e80888b'
41931 ],
41932 [
41933 'df9d70a6b9876ce544c98561f4be4f725442e6d2b737d9c91a8321724ce0963f',
41934 '55eb2dafd84d6ccd5f862b785dc39d4ab157222720ef9da217b8c45cf2ba2417'
41935 ],
41936 [
41937 '5edd5cc23c51e87a497ca815d5dce0f8ab52554f849ed8995de64c5f34ce7143',
41938 'efae9c8dbc14130661e8cec030c89ad0c13c66c0d17a2905cdc706ab7399a868'
41939 ],
41940 [
41941 '290798c2b6476830da12fe02287e9e777aa3fba1c355b17a722d362f84614fba',
41942 'e38da76dcd440621988d00bcf79af25d5b29c094db2a23146d003afd41943e7a'
41943 ],
41944 [
41945 'af3c423a95d9f5b3054754efa150ac39cd29552fe360257362dfdecef4053b45',
41946 'f98a3fd831eb2b749a93b0e6f35cfb40c8cd5aa667a15581bc2feded498fd9c6'
41947 ],
41948 [
41949 '766dbb24d134e745cccaa28c99bf274906bb66b26dcf98df8d2fed50d884249a',
41950 '744b1152eacbe5e38dcc887980da38b897584a65fa06cedd2c924f97cbac5996'
41951 ],
41952 [
41953 '59dbf46f8c94759ba21277c33784f41645f7b44f6c596a58ce92e666191abe3e',
41954 'c534ad44175fbc300f4ea6ce648309a042ce739a7919798cd85e216c4a307f6e'
41955 ],
41956 [
41957 'f13ada95103c4537305e691e74e9a4a8dd647e711a95e73cb62dc6018cfd87b8',
41958 'e13817b44ee14de663bf4bc808341f326949e21a6a75c2570778419bdaf5733d'
41959 ],
41960 [
41961 '7754b4fa0e8aced06d4167a2c59cca4cda1869c06ebadfb6488550015a88522c',
41962 '30e93e864e669d82224b967c3020b8fa8d1e4e350b6cbcc537a48b57841163a2'
41963 ],
41964 [
41965 '948dcadf5990e048aa3874d46abef9d701858f95de8041d2a6828c99e2262519',
41966 'e491a42537f6e597d5d28a3224b1bc25df9154efbd2ef1d2cbba2cae5347d57e'
41967 ],
41968 [
41969 '7962414450c76c1689c7b48f8202ec37fb224cf5ac0bfa1570328a8a3d7c77ab',
41970 '100b610ec4ffb4760d5c1fc133ef6f6b12507a051f04ac5760afa5b29db83437'
41971 ],
41972 [
41973 '3514087834964b54b15b160644d915485a16977225b8847bb0dd085137ec47ca',
41974 'ef0afbb2056205448e1652c48e8127fc6039e77c15c2378b7e7d15a0de293311'
41975 ],
41976 [
41977 'd3cc30ad6b483e4bc79ce2c9dd8bc54993e947eb8df787b442943d3f7b527eaf',
41978 '8b378a22d827278d89c5e9be8f9508ae3c2ad46290358630afb34db04eede0a4'
41979 ],
41980 [
41981 '1624d84780732860ce1c78fcbfefe08b2b29823db913f6493975ba0ff4847610',
41982 '68651cf9b6da903e0914448c6cd9d4ca896878f5282be4c8cc06e2a404078575'
41983 ],
41984 [
41985 '733ce80da955a8a26902c95633e62a985192474b5af207da6df7b4fd5fc61cd4',
41986 'f5435a2bd2badf7d485a4d8b8db9fcce3e1ef8e0201e4578c54673bc1dc5ea1d'
41987 ],
41988 [
41989 '15d9441254945064cf1a1c33bbd3b49f8966c5092171e699ef258dfab81c045c',
41990 'd56eb30b69463e7234f5137b73b84177434800bacebfc685fc37bbe9efe4070d'
41991 ],
41992 [
41993 'a1d0fcf2ec9de675b612136e5ce70d271c21417c9d2b8aaaac138599d0717940',
41994 'edd77f50bcb5a3cab2e90737309667f2641462a54070f3d519212d39c197a629'
41995 ],
41996 [
41997 'e22fbe15c0af8ccc5780c0735f84dbe9a790badee8245c06c7ca37331cb36980',
41998 'a855babad5cd60c88b430a69f53a1a7a38289154964799be43d06d77d31da06'
41999 ],
42000 [
42001 '311091dd9860e8e20ee13473c1155f5f69635e394704eaa74009452246cfa9b3',
42002 '66db656f87d1f04fffd1f04788c06830871ec5a64feee685bd80f0b1286d8374'
42003 ],
42004 [
42005 '34c1fd04d301be89b31c0442d3e6ac24883928b45a9340781867d4232ec2dbdf',
42006 '9414685e97b1b5954bd46f730174136d57f1ceeb487443dc5321857ba73abee'
42007 ],
42008 [
42009 'f219ea5d6b54701c1c14de5b557eb42a8d13f3abbcd08affcc2a5e6b049b8d63',
42010 '4cb95957e83d40b0f73af4544cccf6b1f4b08d3c07b27fb8d8c2962a400766d1'
42011 ],
42012 [
42013 'd7b8740f74a8fbaab1f683db8f45de26543a5490bca627087236912469a0b448',
42014 'fa77968128d9c92ee1010f337ad4717eff15db5ed3c049b3411e0315eaa4593b'
42015 ],
42016 [
42017 '32d31c222f8f6f0ef86f7c98d3a3335ead5bcd32abdd94289fe4d3091aa824bf',
42018 '5f3032f5892156e39ccd3d7915b9e1da2e6dac9e6f26e961118d14b8462e1661'
42019 ],
42020 [
42021 '7461f371914ab32671045a155d9831ea8793d77cd59592c4340f86cbc18347b5',
42022 '8ec0ba238b96bec0cbdddcae0aa442542eee1ff50c986ea6b39847b3cc092ff6'
42023 ],
42024 [
42025 'ee079adb1df1860074356a25aa38206a6d716b2c3e67453d287698bad7b2b2d6',
42026 '8dc2412aafe3be5c4c5f37e0ecc5f9f6a446989af04c4e25ebaac479ec1c8c1e'
42027 ],
42028 [
42029 '16ec93e447ec83f0467b18302ee620f7e65de331874c9dc72bfd8616ba9da6b5',
42030 '5e4631150e62fb40d0e8c2a7ca5804a39d58186a50e497139626778e25b0674d'
42031 ],
42032 [
42033 'eaa5f980c245f6f038978290afa70b6bd8855897f98b6aa485b96065d537bd99',
42034 'f65f5d3e292c2e0819a528391c994624d784869d7e6ea67fb18041024edc07dc'
42035 ],
42036 [
42037 '78c9407544ac132692ee1910a02439958ae04877151342ea96c4b6b35a49f51',
42038 'f3e0319169eb9b85d5404795539a5e68fa1fbd583c064d2462b675f194a3ddb4'
42039 ],
42040 [
42041 '494f4be219a1a77016dcd838431aea0001cdc8ae7a6fc688726578d9702857a5',
42042 '42242a969283a5f339ba7f075e36ba2af925ce30d767ed6e55f4b031880d562c'
42043 ],
42044 [
42045 'a598a8030da6d86c6bc7f2f5144ea549d28211ea58faa70ebf4c1e665c1fe9b5',
42046 '204b5d6f84822c307e4b4a7140737aec23fc63b65b35f86a10026dbd2d864e6b'
42047 ],
42048 [
42049 'c41916365abb2b5d09192f5f2dbeafec208f020f12570a184dbadc3e58595997',
42050 '4f14351d0087efa49d245b328984989d5caf9450f34bfc0ed16e96b58fa9913'
42051 ],
42052 [
42053 '841d6063a586fa475a724604da03bc5b92a2e0d2e0a36acfe4c73a5514742881',
42054 '73867f59c0659e81904f9a1c7543698e62562d6744c169ce7a36de01a8d6154'
42055 ],
42056 [
42057 '5e95bb399a6971d376026947f89bde2f282b33810928be4ded112ac4d70e20d5',
42058 '39f23f366809085beebfc71181313775a99c9aed7d8ba38b161384c746012865'
42059 ],
42060 [
42061 '36e4641a53948fd476c39f8a99fd974e5ec07564b5315d8bf99471bca0ef2f66',
42062 'd2424b1b1abe4eb8164227b085c9aa9456ea13493fd563e06fd51cf5694c78fc'
42063 ],
42064 [
42065 '336581ea7bfbbb290c191a2f507a41cf5643842170e914faeab27c2c579f726',
42066 'ead12168595fe1be99252129b6e56b3391f7ab1410cd1e0ef3dcdcabd2fda224'
42067 ],
42068 [
42069 '8ab89816dadfd6b6a1f2634fcf00ec8403781025ed6890c4849742706bd43ede',
42070 '6fdcef09f2f6d0a044e654aef624136f503d459c3e89845858a47a9129cdd24e'
42071 ],
42072 [
42073 '1e33f1a746c9c5778133344d9299fcaa20b0938e8acff2544bb40284b8c5fb94',
42074 '60660257dd11b3aa9c8ed618d24edff2306d320f1d03010e33a7d2057f3b3b6'
42075 ],
42076 [
42077 '85b7c1dcb3cec1b7ee7f30ded79dd20a0ed1f4cc18cbcfcfa410361fd8f08f31',
42078 '3d98a9cdd026dd43f39048f25a8847f4fcafad1895d7a633c6fed3c35e999511'
42079 ],
42080 [
42081 '29df9fbd8d9e46509275f4b125d6d45d7fbe9a3b878a7af872a2800661ac5f51',
42082 'b4c4fe99c775a606e2d8862179139ffda61dc861c019e55cd2876eb2a27d84b'
42083 ],
42084 [
42085 'a0b1cae06b0a847a3fea6e671aaf8adfdfe58ca2f768105c8082b2e449fce252',
42086 'ae434102edde0958ec4b19d917a6a28e6b72da1834aff0e650f049503a296cf2'
42087 ],
42088 [
42089 '4e8ceafb9b3e9a136dc7ff67e840295b499dfb3b2133e4ba113f2e4c0e121e5',
42090 'cf2174118c8b6d7a4b48f6d534ce5c79422c086a63460502b827ce62a326683c'
42091 ],
42092 [
42093 'd24a44e047e19b6f5afb81c7ca2f69080a5076689a010919f42725c2b789a33b',
42094 '6fb8d5591b466f8fc63db50f1c0f1c69013f996887b8244d2cdec417afea8fa3'
42095 ],
42096 [
42097 'ea01606a7a6c9cdd249fdfcfacb99584001edd28abbab77b5104e98e8e3b35d4',
42098 '322af4908c7312b0cfbfe369f7a7b3cdb7d4494bc2823700cfd652188a3ea98d'
42099 ],
42100 [
42101 'af8addbf2b661c8a6c6328655eb96651252007d8c5ea31be4ad196de8ce2131f',
42102 '6749e67c029b85f52a034eafd096836b2520818680e26ac8f3dfbcdb71749700'
42103 ],
42104 [
42105 'e3ae1974566ca06cc516d47e0fb165a674a3dabcfca15e722f0e3450f45889',
42106 '2aeabe7e4531510116217f07bf4d07300de97e4874f81f533420a72eeb0bd6a4'
42107 ],
42108 [
42109 '591ee355313d99721cf6993ffed1e3e301993ff3ed258802075ea8ced397e246',
42110 'b0ea558a113c30bea60fc4775460c7901ff0b053d25ca2bdeee98f1a4be5d196'
42111 ],
42112 [
42113 '11396d55fda54c49f19aa97318d8da61fa8584e47b084945077cf03255b52984',
42114 '998c74a8cd45ac01289d5833a7beb4744ff536b01b257be4c5767bea93ea57a4'
42115 ],
42116 [
42117 '3c5d2a1ba39c5a1790000738c9e0c40b8dcdfd5468754b6405540157e017aa7a',
42118 'b2284279995a34e2f9d4de7396fc18b80f9b8b9fdd270f6661f79ca4c81bd257'
42119 ],
42120 [
42121 'cc8704b8a60a0defa3a99a7299f2e9c3fbc395afb04ac078425ef8a1793cc030',
42122 'bdd46039feed17881d1e0862db347f8cf395b74fc4bcdc4e940b74e3ac1f1b13'
42123 ],
42124 [
42125 'c533e4f7ea8555aacd9777ac5cad29b97dd4defccc53ee7ea204119b2889b197',
42126 '6f0a256bc5efdf429a2fb6242f1a43a2d9b925bb4a4b3a26bb8e0f45eb596096'
42127 ],
42128 [
42129 'c14f8f2ccb27d6f109f6d08d03cc96a69ba8c34eec07bbcf566d48e33da6593',
42130 'c359d6923bb398f7fd4473e16fe1c28475b740dd098075e6c0e8649113dc3a38'
42131 ],
42132 [
42133 'a6cbc3046bc6a450bac24789fa17115a4c9739ed75f8f21ce441f72e0b90e6ef',
42134 '21ae7f4680e889bb130619e2c0f95a360ceb573c70603139862afd617fa9b9f'
42135 ],
42136 [
42137 '347d6d9a02c48927ebfb86c1359b1caf130a3c0267d11ce6344b39f99d43cc38',
42138 '60ea7f61a353524d1c987f6ecec92f086d565ab687870cb12689ff1e31c74448'
42139 ],
42140 [
42141 'da6545d2181db8d983f7dcb375ef5866d47c67b1bf31c8cf855ef7437b72656a',
42142 '49b96715ab6878a79e78f07ce5680c5d6673051b4935bd897fea824b77dc208a'
42143 ],
42144 [
42145 'c40747cc9d012cb1a13b8148309c6de7ec25d6945d657146b9d5994b8feb1111',
42146 '5ca560753be2a12fc6de6caf2cb489565db936156b9514e1bb5e83037e0fa2d4'
42147 ],
42148 [
42149 '4e42c8ec82c99798ccf3a610be870e78338c7f713348bd34c8203ef4037f3502',
42150 '7571d74ee5e0fb92a7a8b33a07783341a5492144cc54bcc40a94473693606437'
42151 ],
42152 [
42153 '3775ab7089bc6af823aba2e1af70b236d251cadb0c86743287522a1b3b0dedea',
42154 'be52d107bcfa09d8bcb9736a828cfa7fac8db17bf7a76a2c42ad961409018cf7'
42155 ],
42156 [
42157 'cee31cbf7e34ec379d94fb814d3d775ad954595d1314ba8846959e3e82f74e26',
42158 '8fd64a14c06b589c26b947ae2bcf6bfa0149ef0be14ed4d80f448a01c43b1c6d'
42159 ],
42160 [
42161 'b4f9eaea09b6917619f6ea6a4eb5464efddb58fd45b1ebefcdc1a01d08b47986',
42162 '39e5c9925b5a54b07433a4f18c61726f8bb131c012ca542eb24a8ac07200682a'
42163 ],
42164 [
42165 'd4263dfc3d2df923a0179a48966d30ce84e2515afc3dccc1b77907792ebcc60e',
42166 '62dfaf07a0f78feb30e30d6295853ce189e127760ad6cf7fae164e122a208d54'
42167 ],
42168 [
42169 '48457524820fa65a4f8d35eb6930857c0032acc0a4a2de422233eeda897612c4',
42170 '25a748ab367979d98733c38a1fa1c2e7dc6cc07db2d60a9ae7a76aaa49bd0f77'
42171 ],
42172 [
42173 'dfeeef1881101f2cb11644f3a2afdfc2045e19919152923f367a1767c11cceda',
42174 'ecfb7056cf1de042f9420bab396793c0c390bde74b4bbdff16a83ae09a9a7517'
42175 ],
42176 [
42177 '6d7ef6b17543f8373c573f44e1f389835d89bcbc6062ced36c82df83b8fae859',
42178 'cd450ec335438986dfefa10c57fea9bcc521a0959b2d80bbf74b190dca712d10'
42179 ],
42180 [
42181 'e75605d59102a5a2684500d3b991f2e3f3c88b93225547035af25af66e04541f',
42182 'f5c54754a8f71ee540b9b48728473e314f729ac5308b06938360990e2bfad125'
42183 ],
42184 [
42185 'eb98660f4c4dfaa06a2be453d5020bc99a0c2e60abe388457dd43fefb1ed620c',
42186 '6cb9a8876d9cb8520609af3add26cd20a0a7cd8a9411131ce85f44100099223e'
42187 ],
42188 [
42189 '13e87b027d8514d35939f2e6892b19922154596941888336dc3563e3b8dba942',
42190 'fef5a3c68059a6dec5d624114bf1e91aac2b9da568d6abeb2570d55646b8adf1'
42191 ],
42192 [
42193 'ee163026e9fd6fe017c38f06a5be6fc125424b371ce2708e7bf4491691e5764a',
42194 '1acb250f255dd61c43d94ccc670d0f58f49ae3fa15b96623e5430da0ad6c62b2'
42195 ],
42196 [
42197 'b268f5ef9ad51e4d78de3a750c2dc89b1e626d43505867999932e5db33af3d80',
42198 '5f310d4b3c99b9ebb19f77d41c1dee018cf0d34fd4191614003e945a1216e423'
42199 ],
42200 [
42201 'ff07f3118a9df035e9fad85eb6c7bfe42b02f01ca99ceea3bf7ffdba93c4750d',
42202 '438136d603e858a3a5c440c38eccbaddc1d2942114e2eddd4740d098ced1f0d8'
42203 ],
42204 [
42205 '8d8b9855c7c052a34146fd20ffb658bea4b9f69e0d825ebec16e8c3ce2b526a1',
42206 'cdb559eedc2d79f926baf44fb84ea4d44bcf50fee51d7ceb30e2e7f463036758'
42207 ],
42208 [
42209 '52db0b5384dfbf05bfa9d472d7ae26dfe4b851ceca91b1eba54263180da32b63',
42210 'c3b997d050ee5d423ebaf66a6db9f57b3180c902875679de924b69d84a7b375'
42211 ],
42212 [
42213 'e62f9490d3d51da6395efd24e80919cc7d0f29c3f3fa48c6fff543becbd43352',
42214 '6d89ad7ba4876b0b22c2ca280c682862f342c8591f1daf5170e07bfd9ccafa7d'
42215 ],
42216 [
42217 '7f30ea2476b399b4957509c88f77d0191afa2ff5cb7b14fd6d8e7d65aaab1193',
42218 'ca5ef7d4b231c94c3b15389a5f6311e9daff7bb67b103e9880ef4bff637acaec'
42219 ],
42220 [
42221 '5098ff1e1d9f14fb46a210fada6c903fef0fb7b4a1dd1d9ac60a0361800b7a00',
42222 '9731141d81fc8f8084d37c6e7542006b3ee1b40d60dfe5362a5b132fd17ddc0'
42223 ],
42224 [
42225 '32b78c7de9ee512a72895be6b9cbefa6e2f3c4ccce445c96b9f2c81e2778ad58',
42226 'ee1849f513df71e32efc3896ee28260c73bb80547ae2275ba497237794c8753c'
42227 ],
42228 [
42229 'e2cb74fddc8e9fbcd076eef2a7c72b0ce37d50f08269dfc074b581550547a4f7',
42230 'd3aa2ed71c9dd2247a62df062736eb0baddea9e36122d2be8641abcb005cc4a4'
42231 ],
42232 [
42233 '8438447566d4d7bedadc299496ab357426009a35f235cb141be0d99cd10ae3a8',
42234 'c4e1020916980a4da5d01ac5e6ad330734ef0d7906631c4f2390426b2edd791f'
42235 ],
42236 [
42237 '4162d488b89402039b584c6fc6c308870587d9c46f660b878ab65c82c711d67e',
42238 '67163e903236289f776f22c25fb8a3afc1732f2b84b4e95dbda47ae5a0852649'
42239 ],
42240 [
42241 '3fad3fa84caf0f34f0f89bfd2dcf54fc175d767aec3e50684f3ba4a4bf5f683d',
42242 'cd1bc7cb6cc407bb2f0ca647c718a730cf71872e7d0d2a53fa20efcdfe61826'
42243 ],
42244 [
42245 '674f2600a3007a00568c1a7ce05d0816c1fb84bf1370798f1c69532faeb1a86b',
42246 '299d21f9413f33b3edf43b257004580b70db57da0b182259e09eecc69e0d38a5'
42247 ],
42248 [
42249 'd32f4da54ade74abb81b815ad1fb3b263d82d6c692714bcff87d29bd5ee9f08f',
42250 'f9429e738b8e53b968e99016c059707782e14f4535359d582fc416910b3eea87'
42251 ],
42252 [
42253 '30e4e670435385556e593657135845d36fbb6931f72b08cb1ed954f1e3ce3ff6',
42254 '462f9bce619898638499350113bbc9b10a878d35da70740dc695a559eb88db7b'
42255 ],
42256 [
42257 'be2062003c51cc3004682904330e4dee7f3dcd10b01e580bf1971b04d4cad297',
42258 '62188bc49d61e5428573d48a74e1c655b1c61090905682a0d5558ed72dccb9bc'
42259 ],
42260 [
42261 '93144423ace3451ed29e0fb9ac2af211cb6e84a601df5993c419859fff5df04a',
42262 '7c10dfb164c3425f5c71a3f9d7992038f1065224f72bb9d1d902a6d13037b47c'
42263 ],
42264 [
42265 'b015f8044f5fcbdcf21ca26d6c34fb8197829205c7b7d2a7cb66418c157b112c',
42266 'ab8c1e086d04e813744a655b2df8d5f83b3cdc6faa3088c1d3aea1454e3a1d5f'
42267 ],
42268 [
42269 'd5e9e1da649d97d89e4868117a465a3a4f8a18de57a140d36b3f2af341a21b52',
42270 '4cb04437f391ed73111a13cc1d4dd0db1693465c2240480d8955e8592f27447a'
42271 ],
42272 [
42273 'd3ae41047dd7ca065dbf8ed77b992439983005cd72e16d6f996a5316d36966bb',
42274 'bd1aeb21ad22ebb22a10f0303417c6d964f8cdd7df0aca614b10dc14d125ac46'
42275 ],
42276 [
42277 '463e2763d885f958fc66cdd22800f0a487197d0a82e377b49f80af87c897b065',
42278 'bfefacdb0e5d0fd7df3a311a94de062b26b80c61fbc97508b79992671ef7ca7f'
42279 ],
42280 [
42281 '7985fdfd127c0567c6f53ec1bb63ec3158e597c40bfe747c83cddfc910641917',
42282 '603c12daf3d9862ef2b25fe1de289aed24ed291e0ec6708703a5bd567f32ed03'
42283 ],
42284 [
42285 '74a1ad6b5f76e39db2dd249410eac7f99e74c59cb83d2d0ed5ff1543da7703e9',
42286 'cc6157ef18c9c63cd6193d83631bbea0093e0968942e8c33d5737fd790e0db08'
42287 ],
42288 [
42289 '30682a50703375f602d416664ba19b7fc9bab42c72747463a71d0896b22f6da3',
42290 '553e04f6b018b4fa6c8f39e7f311d3176290d0e0f19ca73f17714d9977a22ff8'
42291 ],
42292 [
42293 '9e2158f0d7c0d5f26c3791efefa79597654e7a2b2464f52b1ee6c1347769ef57',
42294 '712fcdd1b9053f09003a3481fa7762e9ffd7c8ef35a38509e2fbf2629008373'
42295 ],
42296 [
42297 '176e26989a43c9cfeba4029c202538c28172e566e3c4fce7322857f3be327d66',
42298 'ed8cc9d04b29eb877d270b4878dc43c19aefd31f4eee09ee7b47834c1fa4b1c3'
42299 ],
42300 [
42301 '75d46efea3771e6e68abb89a13ad747ecf1892393dfc4f1b7004788c50374da8',
42302 '9852390a99507679fd0b86fd2b39a868d7efc22151346e1a3ca4726586a6bed8'
42303 ],
42304 [
42305 '809a20c67d64900ffb698c4c825f6d5f2310fb0451c869345b7319f645605721',
42306 '9e994980d9917e22b76b061927fa04143d096ccc54963e6a5ebfa5f3f8e286c1'
42307 ],
42308 [
42309 '1b38903a43f7f114ed4500b4eac7083fdefece1cf29c63528d563446f972c180',
42310 '4036edc931a60ae889353f77fd53de4a2708b26b6f5da72ad3394119daf408f9'
42311 ]
42312 ]
42313 }
42314};
42315
42316var curves_1 = createCommonjsModule(function (module, exports) {
42317
42318var curves = exports;
42319
42320
42321
42322
42323
42324var assert = utils_1$1.assert;
42325
42326function PresetCurve(options) {
42327 if (options.type === 'short')
42328 this.curve = new curve_1.short(options);
42329 else if (options.type === 'edwards')
42330 this.curve = new curve_1.edwards(options);
42331 else if (options.type === 'mont')
42332 this.curve = new curve_1.mont(options);
42333 else throw new Error('Unknown curve type.');
42334 this.g = this.curve.g;
42335 this.n = this.curve.n;
42336 this.hash = options.hash;
42337
42338 assert(this.g.validate(), 'Invalid curve');
42339 assert(this.g.mul(this.n).isInfinity(), 'Invalid curve, n*G != O');
42340}
42341curves.PresetCurve = PresetCurve;
42342
42343function defineCurve(name, options) {
42344 Object.defineProperty(curves, name, {
42345 configurable: true,
42346 enumerable: true,
42347 get: function() {
42348 var curve = new PresetCurve(options);
42349 Object.defineProperty(curves, name, {
42350 configurable: true,
42351 enumerable: true,
42352 value: curve
42353 });
42354 return curve;
42355 }
42356 });
42357}
42358
42359defineCurve('p192', {
42360 type: 'short',
42361 prime: 'p192',
42362 p: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff',
42363 a: 'ffffffff ffffffff ffffffff fffffffe ffffffff fffffffc',
42364 b: '64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1',
42365 n: 'ffffffff ffffffff ffffffff 99def836 146bc9b1 b4d22831',
42366 hash: hash_1.sha256,
42367 gRed: false,
42368 g: [
42369 '188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012',
42370 '07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811'
42371 ]
42372});
42373
42374defineCurve('p224', {
42375 type: 'short',
42376 prime: 'p224',
42377 p: 'ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000001',
42378 a: 'ffffffff ffffffff ffffffff fffffffe ffffffff ffffffff fffffffe',
42379 b: 'b4050a85 0c04b3ab f5413256 5044b0b7 d7bfd8ba 270b3943 2355ffb4',
42380 n: 'ffffffff ffffffff ffffffff ffff16a2 e0b8f03e 13dd2945 5c5c2a3d',
42381 hash: hash_1.sha256,
42382 gRed: false,
42383 g: [
42384 'b70e0cbd 6bb4bf7f 321390b9 4a03c1d3 56c21122 343280d6 115c1d21',
42385 'bd376388 b5f723fb 4c22dfe6 cd4375a0 5a074764 44d58199 85007e34'
42386 ]
42387});
42388
42389defineCurve('p256', {
42390 type: 'short',
42391 prime: null,
42392 p: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff ffffffff',
42393 a: 'ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff fffffffc',
42394 b: '5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6 3bce3c3e 27d2604b',
42395 n: 'ffffffff 00000000 ffffffff ffffffff bce6faad a7179e84 f3b9cac2 fc632551',
42396 hash: hash_1.sha256,
42397 gRed: false,
42398 g: [
42399 '6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0 f4a13945 d898c296',
42400 '4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece cbb64068 37bf51f5'
42401 ]
42402});
42403
42404defineCurve('p384', {
42405 type: 'short',
42406 prime: null,
42407 p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42408 'fffffffe ffffffff 00000000 00000000 ffffffff',
42409 a: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42410 'fffffffe ffffffff 00000000 00000000 fffffffc',
42411 b: 'b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112 0314088f ' +
42412 '5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef',
42413 n: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff c7634d81 ' +
42414 'f4372ddf 581a0db2 48b0a77a ecec196a ccc52973',
42415 hash: hash_1.sha384,
42416 gRed: false,
42417 g: [
42418 'aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98 59f741e0 82542a38 ' +
42419 '5502f25d bf55296c 3a545e38 72760ab7',
42420 '3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c e9da3113 b5f0b8c0 ' +
42421 '0a60b1ce 1d7e819d 7a431d7c 90ea0e5f'
42422 ]
42423});
42424
42425defineCurve('p521', {
42426 type: 'short',
42427 prime: null,
42428 p: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42429 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42430 'ffffffff ffffffff ffffffff ffffffff ffffffff',
42431 a: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42432 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42433 'ffffffff ffffffff ffffffff ffffffff fffffffc',
42434 b: '00000051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b ' +
42435 '99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd ' +
42436 '3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00',
42437 n: '000001ff ffffffff ffffffff ffffffff ffffffff ffffffff ' +
42438 'ffffffff ffffffff fffffffa 51868783 bf2f966b 7fcc0148 ' +
42439 'f709a5d0 3bb5c9b8 899c47ae bb6fb71e 91386409',
42440 hash: hash_1.sha512,
42441 gRed: false,
42442 g: [
42443 '000000c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139 ' +
42444 '053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127 ' +
42445 'a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66',
42446 '00000118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449 ' +
42447 '579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901 ' +
42448 '3fad0761 353c7086 a272c240 88be9476 9fd16650'
42449 ]
42450});
42451
42452// https://tools.ietf.org/html/rfc7748#section-4.1
42453defineCurve('curve25519', {
42454 type: 'mont',
42455 prime: 'p25519',
42456 p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
42457 a: '76d06',
42458 b: '1',
42459 n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
42460 cofactor: '8',
42461 hash: hash_1.sha256,
42462 gRed: false,
42463 g: [
42464 '9'
42465 ]
42466});
42467
42468defineCurve('ed25519', {
42469 type: 'edwards',
42470 prime: 'p25519',
42471 p: '7fffffffffffffff ffffffffffffffff ffffffffffffffff ffffffffffffffed',
42472 a: '-1',
42473 c: '1',
42474 // -121665 * (121666^(-1)) (mod P)
42475 d: '52036cee2b6ffe73 8cc740797779e898 00700a4d4141d8ab 75eb4dca135978a3',
42476 n: '1000000000000000 0000000000000000 14def9dea2f79cd6 5812631a5cf5d3ed',
42477 cofactor: '8',
42478 hash: hash_1.sha256,
42479 gRed: false,
42480 g: [
42481 '216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a',
42482 // 4/5
42483 '6666666666666666666666666666666666666666666666666666666666666658'
42484 ]
42485});
42486
42487// https://tools.ietf.org/html/rfc5639#section-3.4
42488defineCurve('brainpoolP256r1', {
42489 type: 'short',
42490 prime: null,
42491 p: 'A9FB57DB A1EEA9BC 3E660A90 9D838D72 6E3BF623 D5262028 2013481D 1F6E5377',
42492 a: '7D5A0975 FC2C3057 EEF67530 417AFFE7 FB8055C1 26DC5C6C E94A4B44 F330B5D9',
42493 b: '26DC5C6C E94A4B44 F330B5D9 BBD77CBF 95841629 5CF7E1CE 6BCCDC18 FF8C07B6',
42494 n: 'A9FB57DB A1EEA9BC 3E660A90 9D838D71 8C397AA3 B561A6F7 901E0E82 974856A7',
42495 hash: hash_1.sha256, // or 384, or 512
42496 gRed: false,
42497 g: [
42498 '8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262',
42499 '547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997'
42500 ]
42501});
42502
42503// https://tools.ietf.org/html/rfc5639#section-3.6
42504defineCurve('brainpoolP384r1', {
42505 type: 'short',
42506 prime: null,
42507 p: '8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B4 12B1DA19 7FB71123' +
42508 'ACD3A729 901D1A71 87470013 3107EC53',
42509 a: '7BC382C6 3D8C150C 3C72080A CE05AFA0 C2BEA28E 4FB22787 139165EF BA91F90F' +
42510 '8AA5814A 503AD4EB 04A8C7DD 22CE2826',
42511 b: '04A8C7DD 22CE2826 8B39B554 16F0447C 2FB77DE1 07DCD2A6 2E880EA5 3EEB62D5' +
42512 '7CB43902 95DBC994 3AB78696 FA504C11',
42513 n: '8CB91E82 A3386D28 0F5D6F7E 50E641DF 152F7109 ED5456B3 1F166E6C AC0425A7' +
42514 'CF3AB6AF 6B7FC310 3B883202 E9046565',
42515 hash: hash_1.sha384, // or 512
42516 gRed: false,
42517 g: [
42518 '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10' +
42519 'E8E826E03436D646AAEF87B2E247D4AF1E',
42520 '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129' +
42521 '280E4646217791811142820341263C5315'
42522 ]
42523});
42524
42525// https://tools.ietf.org/html/rfc5639#section-3.7
42526defineCurve('brainpoolP512r1', {
42527 type: 'short',
42528 prime: null,
42529 p: 'AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E D6639CCA 70330871' +
42530 '7D4D9B00 9BC66842 AECDA12A E6A380E6 2881FF2F 2D82C685 28AA6056 583A48F3',
42531 a: '7830A331 8B603B89 E2327145 AC234CC5 94CBDD8D 3DF91610 A83441CA EA9863BC' +
42532 '2DED5D5A A8253AA1 0A2EF1C9 8B9AC8B5 7F1117A7 2BF2C7B9 E7C1AC4D 77FC94CA',
42533 b: '3DF91610 A83441CA EA9863BC 2DED5D5A A8253AA1 0A2EF1C9 8B9AC8B5 7F1117A7' +
42534 '2BF2C7B9 E7C1AC4D 77FC94CA DC083E67 984050B7 5EBAE5DD 2809BD63 8016F723',
42535 n: 'AADD9DB8 DBE9C48B 3FD4E6AE 33C9FC07 CB308DB3 B3C9D20E D6639CCA 70330870' +
42536 '553E5C41 4CA92619 41866119 7FAC1047 1DB1D381 085DDADD B5879682 9CA90069',
42537 hash: hash_1.sha512,
42538 gRed: false,
42539 g: [
42540 '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D009' +
42541 '8EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822',
42542 '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F81' +
42543 '11B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892'
42544 ]
42545});
42546
42547// https://en.bitcoin.it/wiki/Secp256k1
42548var pre;
42549try {
42550 pre = secp256k1;
42551} catch (e) {
42552 pre = undefined;
42553}
42554
42555defineCurve('secp256k1', {
42556 type: 'short',
42557 prime: 'k256',
42558 p: 'ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f',
42559 a: '0',
42560 b: '7',
42561 n: 'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141',
42562 h: '1',
42563 hash: hash_1.sha256,
42564
42565 // Precomputed endomorphism
42566 beta: '7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee',
42567 lambda: '5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72',
42568 basis: [
42569 {
42570 a: '3086d221a7d46bcde86c90e49284eb15',
42571 b: '-e4437ed6010e88286f547fa90abfe4c3'
42572 },
42573 {
42574 a: '114ca50f7a8e2f3f657c1108d9d44cfd8',
42575 b: '3086d221a7d46bcde86c90e49284eb15'
42576 }
42577 ],
42578
42579 gRed: false,
42580 g: [
42581 '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
42582 '483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8',
42583 pre
42584 ]
42585});
42586});
42587
42588function HmacDRBG(options) {
42589 if (!(this instanceof HmacDRBG))
42590 return new HmacDRBG(options);
42591 this.hash = options.hash;
42592 this.predResist = !!options.predResist;
42593
42594 this.outLen = this.hash.outSize;
42595 this.minEntropy = options.minEntropy || this.hash.hmacStrength;
42596
42597 this._reseed = null;
42598 this.reseedInterval = null;
42599 this.K = null;
42600 this.V = null;
42601
42602 var entropy = utils_1.toArray(options.entropy, options.entropyEnc || 'hex');
42603 var nonce = utils_1.toArray(options.nonce, options.nonceEnc || 'hex');
42604 var pers = utils_1.toArray(options.pers, options.persEnc || 'hex');
42605 minimalisticAssert(entropy.length >= (this.minEntropy / 8),
42606 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
42607 this._init(entropy, nonce, pers);
42608}
42609var hmacDrbg = HmacDRBG;
42610
42611HmacDRBG.prototype._init = function init(entropy, nonce, pers) {
42612 var seed = entropy.concat(nonce).concat(pers);
42613
42614 this.K = new Array(this.outLen / 8);
42615 this.V = new Array(this.outLen / 8);
42616 for (var i = 0; i < this.V.length; i++) {
42617 this.K[i] = 0x00;
42618 this.V[i] = 0x01;
42619 }
42620
42621 this._update(seed);
42622 this._reseed = 1;
42623 this.reseedInterval = 0x1000000000000; // 2^48
42624};
42625
42626HmacDRBG.prototype._hmac = function hmac() {
42627 return new hash_1.hmac(this.hash, this.K);
42628};
42629
42630HmacDRBG.prototype._update = function update(seed) {
42631 var kmac = this._hmac()
42632 .update(this.V)
42633 .update([ 0x00 ]);
42634 if (seed)
42635 kmac = kmac.update(seed);
42636 this.K = kmac.digest();
42637 this.V = this._hmac().update(this.V).digest();
42638 if (!seed)
42639 return;
42640
42641 this.K = this._hmac()
42642 .update(this.V)
42643 .update([ 0x01 ])
42644 .update(seed)
42645 .digest();
42646 this.V = this._hmac().update(this.V).digest();
42647};
42648
42649HmacDRBG.prototype.reseed = function reseed(entropy, entropyEnc, add, addEnc) {
42650 // Optional entropy enc
42651 if (typeof entropyEnc !== 'string') {
42652 addEnc = add;
42653 add = entropyEnc;
42654 entropyEnc = null;
42655 }
42656
42657 entropy = utils_1.toArray(entropy, entropyEnc);
42658 add = utils_1.toArray(add, addEnc);
42659
42660 minimalisticAssert(entropy.length >= (this.minEntropy / 8),
42661 'Not enough entropy. Minimum is: ' + this.minEntropy + ' bits');
42662
42663 this._update(entropy.concat(add || []));
42664 this._reseed = 1;
42665};
42666
42667HmacDRBG.prototype.generate = function generate(len, enc, add, addEnc) {
42668 if (this._reseed > this.reseedInterval)
42669 throw new Error('Reseed is required');
42670
42671 // Optional encoding
42672 if (typeof enc !== 'string') {
42673 addEnc = add;
42674 add = enc;
42675 enc = null;
42676 }
42677
42678 // Optional additional data
42679 if (add) {
42680 add = utils_1.toArray(add, addEnc || 'hex');
42681 this._update(add);
42682 }
42683
42684 var temp = [];
42685 while (temp.length < len) {
42686 this.V = this._hmac().update(this.V).digest();
42687 temp = temp.concat(this.V);
42688 }
42689
42690 var res = temp.slice(0, len);
42691 this._update(add);
42692 this._reseed++;
42693 return utils_1.encode(res, enc);
42694};
42695
42696var assert$5 = utils_1$1.assert;
42697
42698function KeyPair(ec, options) {
42699 this.ec = ec;
42700 this.priv = null;
42701 this.pub = null;
42702
42703 // KeyPair(ec, { priv: ..., pub: ... })
42704 if (options.priv)
42705 this._importPrivate(options.priv, options.privEnc);
42706 if (options.pub)
42707 this._importPublic(options.pub, options.pubEnc);
42708}
42709var key = KeyPair;
42710
42711KeyPair.fromPublic = function fromPublic(ec, pub, enc) {
42712 if (pub instanceof KeyPair)
42713 return pub;
42714
42715 return new KeyPair(ec, {
42716 pub: pub,
42717 pubEnc: enc
42718 });
42719};
42720
42721KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) {
42722 if (priv instanceof KeyPair)
42723 return priv;
42724
42725 return new KeyPair(ec, {
42726 priv: priv,
42727 privEnc: enc
42728 });
42729};
42730
42731// TODO: should not validate for X25519
42732KeyPair.prototype.validate = function validate() {
42733 var pub = this.getPublic();
42734
42735 if (pub.isInfinity())
42736 return { result: false, reason: 'Invalid public key' };
42737 if (!pub.validate())
42738 return { result: false, reason: 'Public key is not a point' };
42739 if (!pub.mul(this.ec.curve.n).isInfinity())
42740 return { result: false, reason: 'Public key * N != O' };
42741
42742 return { result: true, reason: null };
42743};
42744
42745KeyPair.prototype.getPublic = function getPublic(enc, compact) {
42746 if (!this.pub)
42747 this.pub = this.ec.g.mul(this.priv);
42748
42749 if (!enc)
42750 return this.pub;
42751
42752 return this.pub.encode(enc, compact);
42753};
42754
42755KeyPair.prototype.getPrivate = function getPrivate(enc) {
42756 if (enc === 'hex')
42757 return this.priv.toString(16, 2);
42758 else
42759 return this.priv;
42760};
42761
42762KeyPair.prototype._importPrivate = function _importPrivate(key, enc) {
42763 this.priv = new bn(key, enc || 16);
42764
42765 // For Curve25519/Curve448 we have a specific procedure.
42766 // TODO Curve448
42767 if (this.ec.curve.type === 'mont') {
42768 var one = this.ec.curve.one;
42769 var mask = one.ushln(255 - 3).sub(one).ushln(3);
42770 this.priv = this.priv.or(one.ushln(255 - 1));
42771 this.priv = this.priv.and(mask);
42772 } else
42773 // Ensure that the priv won't be bigger than n, otherwise we may fail
42774 // in fixed multiplication method
42775 this.priv = this.priv.umod(this.ec.curve.n);
42776};
42777
42778KeyPair.prototype._importPublic = function _importPublic(key, enc) {
42779 if (key.x || key.y) {
42780 // Montgomery points only have an `x` coordinate.
42781 // Weierstrass/Edwards points on the other hand have both `x` and
42782 // `y` coordinates.
42783 if (this.ec.curve.type === 'mont') {
42784 assert$5(key.x, 'Need x coordinate');
42785 } else if (this.ec.curve.type === 'short' ||
42786 this.ec.curve.type === 'edwards') {
42787 assert$5(key.x && key.y, 'Need both x and y coordinate');
42788 }
42789 this.pub = this.ec.curve.point(key.x, key.y);
42790 return;
42791 }
42792 this.pub = this.ec.curve.decodePoint(key, enc);
42793};
42794
42795// ECDH
42796KeyPair.prototype.derive = function derive(pub) {
42797 return pub.mul(this.priv).getX();
42798};
42799
42800// ECDSA
42801KeyPair.prototype.sign = function sign(msg, enc, options) {
42802 return this.ec.sign(msg, this, enc, options);
42803};
42804
42805KeyPair.prototype.verify = function verify(msg, signature) {
42806 return this.ec.verify(msg, signature, this);
42807};
42808
42809KeyPair.prototype.inspect = function inspect() {
42810 return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
42811 ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
42812};
42813
42814var assert$6 = utils_1$1.assert;
42815
42816function Signature$1(options, enc) {
42817 if (options instanceof Signature$1)
42818 return options;
42819
42820 if (this._importDER(options, enc))
42821 return;
42822
42823 assert$6(options.r && options.s, 'Signature without r or s');
42824 this.r = new bn(options.r, 16);
42825 this.s = new bn(options.s, 16);
42826 if (options.recoveryParam === undefined)
42827 this.recoveryParam = null;
42828 else
42829 this.recoveryParam = options.recoveryParam;
42830}
42831var signature$1 = Signature$1;
42832
42833function Position() {
42834 this.place = 0;
42835}
42836
42837function getLength(buf, p) {
42838 var initial = buf[p.place++];
42839 if (!(initial & 0x80)) {
42840 return initial;
42841 }
42842 var octetLen = initial & 0xf;
42843 var val = 0;
42844 for (var i = 0, off = p.place; i < octetLen; i++, off++) {
42845 val <<= 8;
42846 val |= buf[off];
42847 }
42848 p.place = off;
42849 return val;
42850}
42851
42852function rmPadding(buf) {
42853 var i = 0;
42854 var len = buf.length - 1;
42855 while (!buf[i] && !(buf[i + 1] & 0x80) && i < len) {
42856 i++;
42857 }
42858 if (i === 0) {
42859 return buf;
42860 }
42861 return buf.slice(i);
42862}
42863
42864Signature$1.prototype._importDER = function _importDER(data, enc) {
42865 data = utils_1$1.toArray(data, enc);
42866 var p = new Position();
42867 if (data[p.place++] !== 0x30) {
42868 return false;
42869 }
42870 var len = getLength(data, p);
42871 if ((len + p.place) !== data.length) {
42872 return false;
42873 }
42874 if (data[p.place++] !== 0x02) {
42875 return false;
42876 }
42877 var rlen = getLength(data, p);
42878 var r = data.slice(p.place, rlen + p.place);
42879 p.place += rlen;
42880 if (data[p.place++] !== 0x02) {
42881 return false;
42882 }
42883 var slen = getLength(data, p);
42884 if (data.length !== slen + p.place) {
42885 return false;
42886 }
42887 var s = data.slice(p.place, slen + p.place);
42888 if (r[0] === 0 && (r[1] & 0x80)) {
42889 r = r.slice(1);
42890 }
42891 if (s[0] === 0 && (s[1] & 0x80)) {
42892 s = s.slice(1);
42893 }
42894
42895 this.r = new bn(r);
42896 this.s = new bn(s);
42897 this.recoveryParam = null;
42898
42899 return true;
42900};
42901
42902function constructLength(arr, len) {
42903 if (len < 0x80) {
42904 arr.push(len);
42905 return;
42906 }
42907 var octets = 1 + (Math.log(len) / Math.LN2 >>> 3);
42908 arr.push(octets | 0x80);
42909 while (--octets) {
42910 arr.push((len >>> (octets << 3)) & 0xff);
42911 }
42912 arr.push(len);
42913}
42914
42915Signature$1.prototype.toDER = function toDER(enc) {
42916 var r = this.r.toArray();
42917 var s = this.s.toArray();
42918
42919 // Pad values
42920 if (r[0] & 0x80)
42921 r = [ 0 ].concat(r);
42922 // Pad values
42923 if (s[0] & 0x80)
42924 s = [ 0 ].concat(s);
42925
42926 r = rmPadding(r);
42927 s = rmPadding(s);
42928
42929 while (!s[0] && !(s[1] & 0x80)) {
42930 s = s.slice(1);
42931 }
42932 var arr = [ 0x02 ];
42933 constructLength(arr, r.length);
42934 arr = arr.concat(r);
42935 arr.push(0x02);
42936 constructLength(arr, s.length);
42937 var backHalf = arr.concat(s);
42938 var res = [ 0x30 ];
42939 constructLength(res, backHalf.length);
42940 res = res.concat(backHalf);
42941 return utils_1$1.encode(res, enc);
42942};
42943
42944var assert$7 = utils_1$1.assert;
42945
42946
42947
42948
42949function EC(options) {
42950 if (!(this instanceof EC))
42951 return new EC(options);
42952
42953 // Shortcut `elliptic.ec(curve-name)`
42954 if (typeof options === 'string') {
42955 assert$7(curves_1.hasOwnProperty(options), 'Unknown curve ' + options);
42956
42957 options = curves_1[options];
42958 }
42959
42960 // Shortcut for `elliptic.ec(elliptic.curves.curveName)`
42961 if (options instanceof curves_1.PresetCurve)
42962 options = { curve: options };
42963
42964 this.curve = options.curve.curve;
42965 this.n = this.curve.n;
42966 this.nh = this.n.ushrn(1);
42967 this.g = this.curve.g;
42968
42969 // Point on curve
42970 this.g = options.curve.g;
42971 this.g.precompute(options.curve.n.bitLength() + 1);
42972
42973 // Hash function for DRBG
42974 this.hash = options.hash || options.curve.hash;
42975}
42976var ec = EC;
42977
42978EC.prototype.keyPair = function keyPair(options) {
42979 return new key(this, options);
42980};
42981
42982EC.prototype.keyFromPrivate = function keyFromPrivate(priv, enc) {
42983 return key.fromPrivate(this, priv, enc);
42984};
42985
42986EC.prototype.keyFromPublic = function keyFromPublic(pub, enc) {
42987 return key.fromPublic(this, pub, enc);
42988};
42989
42990EC.prototype.genKeyPair = function genKeyPair(options) {
42991 if (!options)
42992 options = {};
42993
42994 // Instantiate Hmac_DRBG
42995 var drbg = new hmacDrbg({
42996 hash: this.hash,
42997 pers: options.pers,
42998 persEnc: options.persEnc || 'utf8',
42999 entropy: options.entropy || brorand(this.hash.hmacStrength),
43000 entropyEnc: options.entropy && options.entropyEnc || 'utf8',
43001 nonce: this.n.toArray()
43002 });
43003
43004 // Key generation for curve25519 is simpler
43005 if (this.curve.type === 'mont') {
43006 var priv = new bn(drbg.generate(32));
43007 return this.keyFromPrivate(priv);
43008 }
43009
43010 var bytes = this.n.byteLength();
43011 var ns2 = this.n.sub(new bn(2));
43012 do {
43013 var priv = new bn(drbg.generate(bytes));
43014 if (priv.cmp(ns2) > 0)
43015 continue;
43016
43017 priv.iaddn(1);
43018 return this.keyFromPrivate(priv);
43019 } while (true);
43020};
43021
43022EC.prototype._truncateToN = function truncateToN(msg, truncOnly, bitSize) {
43023 bitSize = bitSize || msg.byteLength() * 8;
43024 var delta = bitSize - this.n.bitLength();
43025 if (delta > 0)
43026 msg = msg.ushrn(delta);
43027 if (!truncOnly && msg.cmp(this.n) >= 0)
43028 return msg.sub(this.n);
43029 else
43030 return msg;
43031};
43032
43033EC.prototype.truncateMsg = function truncateMSG(msg) {
43034 // Bit size is only determined correctly for Uint8Arrays and hex strings
43035 var bitSize;
43036 if (msg instanceof Uint8Array) {
43037 bitSize = msg.byteLength * 8;
43038 msg = this._truncateToN(new bn(msg, 16), false, bitSize);
43039 } else if (typeof msg === 'string') {
43040 bitSize = msg.length * 4;
43041 msg = this._truncateToN(new bn(msg, 16), false, bitSize);
43042 } else {
43043 msg = this._truncateToN(new bn(msg, 16));
43044 }
43045 return msg;
43046};
43047
43048EC.prototype.sign = function sign(msg, key, enc, options) {
43049 if (typeof enc === 'object') {
43050 options = enc;
43051 enc = null;
43052 }
43053 if (!options)
43054 options = {};
43055
43056 key = this.keyFromPrivate(key, enc);
43057 msg = this.truncateMsg(msg);
43058
43059 // Zero-extend key to provide enough entropy
43060 var bytes = this.n.byteLength();
43061 var bkey = key.getPrivate().toArray('be', bytes);
43062
43063 // Zero-extend nonce to have the same byte size as N
43064 var nonce = msg.toArray('be', bytes);
43065
43066 // Instantiate Hmac_DRBG
43067 var drbg = new hmacDrbg({
43068 hash: this.hash,
43069 entropy: bkey,
43070 nonce: nonce,
43071 pers: options.pers,
43072 persEnc: options.persEnc || 'utf8'
43073 });
43074
43075 // Number of bytes to generate
43076 var ns1 = this.n.sub(new bn(1));
43077
43078 for (var iter = 0; true; iter++) {
43079 var k = options.k ?
43080 options.k(iter) :
43081 new bn(drbg.generate(this.n.byteLength()));
43082 k = this._truncateToN(k, true);
43083 if (k.cmpn(1) <= 0 || k.cmp(ns1) >= 0)
43084 continue;
43085
43086 var kp = this.g.mul(k);
43087 if (kp.isInfinity())
43088 continue;
43089
43090 var kpX = kp.getX();
43091 var r = kpX.umod(this.n);
43092 if (r.cmpn(0) === 0)
43093 continue;
43094
43095 var s = k.invm(this.n).mul(r.mul(key.getPrivate()).iadd(msg));
43096 s = s.umod(this.n);
43097 if (s.cmpn(0) === 0)
43098 continue;
43099
43100 var recoveryParam = (kp.getY().isOdd() ? 1 : 0) |
43101 (kpX.cmp(r) !== 0 ? 2 : 0);
43102
43103 // Use complement of `s`, if it is > `n / 2`
43104 if (options.canonical && s.cmp(this.nh) > 0) {
43105 s = this.n.sub(s);
43106 recoveryParam ^= 1;
43107 }
43108
43109 return new signature$1({ r: r, s: s, recoveryParam: recoveryParam });
43110 }
43111};
43112
43113EC.prototype.verify = function verify(msg, signature, key, enc) {
43114 key = this.keyFromPublic(key, enc);
43115 signature = new signature$1(signature, 'hex');
43116 // Fallback to the old code
43117 var ret = this._verify(this.truncateMsg(msg), signature, key) ||
43118 this._verify(this._truncateToN(new bn(msg, 16)), signature, key);
43119 return ret;
43120};
43121
43122EC.prototype._verify = function _verify(msg, signature, key) {
43123 // Perform primitive values validation
43124 var r = signature.r;
43125 var s = signature.s;
43126 if (r.cmpn(1) < 0 || r.cmp(this.n) >= 0)
43127 return false;
43128 if (s.cmpn(1) < 0 || s.cmp(this.n) >= 0)
43129 return false;
43130
43131 // Validate signature
43132 var sinv = s.invm(this.n);
43133 var u1 = sinv.mul(msg).umod(this.n);
43134 var u2 = sinv.mul(r).umod(this.n);
43135
43136 if (!this.curve._maxwellTrick) {
43137 var p = this.g.mulAdd(u1, key.getPublic(), u2);
43138 if (p.isInfinity())
43139 return false;
43140
43141 return p.getX().umod(this.n).cmp(r) === 0;
43142 }
43143
43144 // NOTE: Greg Maxwell's trick, inspired by:
43145 // https://git.io/vad3K
43146
43147 var p = this.g.jmulAdd(u1, key.getPublic(), u2);
43148 if (p.isInfinity())
43149 return false;
43150
43151 // Compare `p.x` of Jacobian point with `r`,
43152 // this will do `p.x == r * p.z^2` instead of multiplying `p.x` by the
43153 // inverse of `p.z^2`
43154 return p.eqXToP(r);
43155};
43156
43157EC.prototype.recoverPubKey = function(msg, signature, j, enc) {
43158 assert$7((3 & j) === j, 'The recovery param is more than two bits');
43159 signature = new signature$1(signature, enc);
43160
43161 var n = this.n;
43162 var e = new bn(msg);
43163 var r = signature.r;
43164 var s = signature.s;
43165
43166 // A set LSB signifies that the y-coordinate is odd
43167 var isYOdd = j & 1;
43168 var isSecondKey = j >> 1;
43169 if (r.cmp(this.curve.p.umod(this.curve.n)) >= 0 && isSecondKey)
43170 throw new Error('Unable to find sencond key candinate');
43171
43172 // 1.1. Let x = r + jn.
43173 if (isSecondKey)
43174 r = this.curve.pointFromX(r.add(this.curve.n), isYOdd);
43175 else
43176 r = this.curve.pointFromX(r, isYOdd);
43177
43178 var rInv = signature.r.invm(n);
43179 var s1 = n.sub(e).mul(rInv).umod(n);
43180 var s2 = s.mul(rInv).umod(n);
43181
43182 // 1.6.1 Compute Q = r^-1 (sR - eG)
43183 // Q = r^-1 (sR + -eG)
43184 return this.g.mulAdd(s1, r, s2);
43185};
43186
43187EC.prototype.getKeyRecoveryParam = function(e, signature, Q, enc) {
43188 signature = new signature$1(signature, enc);
43189 if (signature.recoveryParam !== null)
43190 return signature.recoveryParam;
43191
43192 for (var i = 0; i < 4; i++) {
43193 var Qprime;
43194 try {
43195 Qprime = this.recoverPubKey(e, signature, i);
43196 } catch (e) {
43197 continue;
43198 }
43199
43200 if (Qprime.eq(Q))
43201 return i;
43202 }
43203 throw new Error('Unable to find valid recovery factor');
43204};
43205
43206var assert$8 = utils_1$1.assert;
43207var parseBytes = utils_1$1.parseBytes;
43208var cachedProperty = utils_1$1.cachedProperty;
43209
43210/**
43211* @param {EDDSA} eddsa - instance
43212* @param {Object} params - public/private key parameters
43213*
43214* @param {Array<Byte>} [params.secret] - secret seed bytes
43215* @param {Point} [params.pub] - public key point (aka `A` in eddsa terms)
43216* @param {Array<Byte>} [params.pub] - public key point encoded as bytes
43217*
43218*/
43219function KeyPair$1(eddsa, params) {
43220 this.eddsa = eddsa;
43221 if (params.hasOwnProperty('secret'))
43222 this._secret = parseBytes(params.secret);
43223 if (eddsa.isPoint(params.pub))
43224 this._pub = params.pub;
43225 else {
43226 this._pubBytes = parseBytes(params.pub);
43227 if (this._pubBytes && this._pubBytes.length === 33 &&
43228 this._pubBytes[0] === 0x40)
43229 this._pubBytes = this._pubBytes.slice(1, 33);
43230 if (this._pubBytes && this._pubBytes.length !== 32)
43231 throw new Error('Unknown point compression format');
43232 }
43233}
43234
43235KeyPair$1.fromPublic = function fromPublic(eddsa, pub) {
43236 if (pub instanceof KeyPair$1)
43237 return pub;
43238 return new KeyPair$1(eddsa, { pub: pub });
43239};
43240
43241KeyPair$1.fromSecret = function fromSecret(eddsa, secret) {
43242 if (secret instanceof KeyPair$1)
43243 return secret;
43244 return new KeyPair$1(eddsa, { secret: secret });
43245};
43246
43247KeyPair$1.prototype.secret = function secret() {
43248 return this._secret;
43249};
43250
43251cachedProperty(KeyPair$1, 'pubBytes', function pubBytes() {
43252 return this.eddsa.encodePoint(this.pub());
43253});
43254
43255cachedProperty(KeyPair$1, 'pub', function pub() {
43256 if (this._pubBytes)
43257 return this.eddsa.decodePoint(this._pubBytes);
43258 return this.eddsa.g.mul(this.priv());
43259});
43260
43261cachedProperty(KeyPair$1, 'privBytes', function privBytes() {
43262 var eddsa = this.eddsa;
43263 var hash = this.hash();
43264 var lastIx = eddsa.encodingLength - 1;
43265
43266 // https://tools.ietf.org/html/rfc8032#section-5.1.5
43267 var a = hash.slice(0, eddsa.encodingLength);
43268 a[0] &= 248;
43269 a[lastIx] &= 127;
43270 a[lastIx] |= 64;
43271
43272 return a;
43273});
43274
43275cachedProperty(KeyPair$1, 'priv', function priv() {
43276 return this.eddsa.decodeInt(this.privBytes());
43277});
43278
43279cachedProperty(KeyPair$1, 'hash', function hash() {
43280 return this.eddsa.hash().update(this.secret()).digest();
43281});
43282
43283cachedProperty(KeyPair$1, 'messagePrefix', function messagePrefix() {
43284 return this.hash().slice(this.eddsa.encodingLength);
43285});
43286
43287KeyPair$1.prototype.sign = function sign(message) {
43288 assert$8(this._secret, 'KeyPair can only verify');
43289 return this.eddsa.sign(message, this);
43290};
43291
43292KeyPair$1.prototype.verify = function verify(message, sig) {
43293 return this.eddsa.verify(message, sig, this);
43294};
43295
43296KeyPair$1.prototype.getSecret = function getSecret(enc) {
43297 assert$8(this._secret, 'KeyPair is public only');
43298 return utils_1$1.encode(this.secret(), enc);
43299};
43300
43301KeyPair$1.prototype.getPublic = function getPublic(enc, compact) {
43302 return utils_1$1.encode((compact ? [ 0x40 ] : []).concat(this.pubBytes()), enc);
43303};
43304
43305var key$1 = KeyPair$1;
43306
43307var assert$9 = utils_1$1.assert;
43308var cachedProperty$1 = utils_1$1.cachedProperty;
43309var parseBytes$1 = utils_1$1.parseBytes;
43310
43311/**
43312* @param {EDDSA} eddsa - eddsa instance
43313* @param {Array<Bytes>|Object} sig -
43314* @param {Array<Bytes>|Point} [sig.R] - R point as Point or bytes
43315* @param {Array<Bytes>|bn} [sig.S] - S scalar as bn or bytes
43316* @param {Array<Bytes>} [sig.Rencoded] - R point encoded
43317* @param {Array<Bytes>} [sig.Sencoded] - S scalar encoded
43318*/
43319function Signature$2(eddsa, sig) {
43320 this.eddsa = eddsa;
43321
43322 if (typeof sig !== 'object')
43323 sig = parseBytes$1(sig);
43324
43325 if (Array.isArray(sig)) {
43326 sig = {
43327 R: sig.slice(0, eddsa.encodingLength),
43328 S: sig.slice(eddsa.encodingLength)
43329 };
43330 }
43331
43332 assert$9(sig.R && sig.S, 'Signature without R or S');
43333
43334 if (eddsa.isPoint(sig.R))
43335 this._R = sig.R;
43336 if (sig.S instanceof bn)
43337 this._S = sig.S;
43338
43339 this._Rencoded = Array.isArray(sig.R) ? sig.R : sig.Rencoded;
43340 this._Sencoded = Array.isArray(sig.S) ? sig.S : sig.Sencoded;
43341}
43342
43343cachedProperty$1(Signature$2, 'S', function S() {
43344 return this.eddsa.decodeInt(this.Sencoded());
43345});
43346
43347cachedProperty$1(Signature$2, 'R', function R() {
43348 return this.eddsa.decodePoint(this.Rencoded());
43349});
43350
43351cachedProperty$1(Signature$2, 'Rencoded', function Rencoded() {
43352 return this.eddsa.encodePoint(this.R());
43353});
43354
43355cachedProperty$1(Signature$2, 'Sencoded', function Sencoded() {
43356 return this.eddsa.encodeInt(this.S());
43357});
43358
43359Signature$2.prototype.toBytes = function toBytes() {
43360 return this.Rencoded().concat(this.Sencoded());
43361};
43362
43363Signature$2.prototype.toHex = function toHex() {
43364 return utils_1$1.encode(this.toBytes(), 'hex').toUpperCase();
43365};
43366
43367var signature$2 = Signature$2;
43368
43369var assert$a = utils_1$1.assert;
43370var parseBytes$2 = utils_1$1.parseBytes;
43371
43372
43373
43374function EDDSA(curve) {
43375 assert$a(curve === 'ed25519', 'only tested with ed25519 so far');
43376
43377 if (!(this instanceof EDDSA))
43378 return new EDDSA(curve);
43379
43380 var curve = curves_1[curve].curve;
43381 this.curve = curve;
43382 this.g = curve.g;
43383 this.g.precompute(curve.n.bitLength() + 1);
43384
43385 this.pointClass = curve.point().constructor;
43386 this.encodingLength = Math.ceil(curve.n.bitLength() / 8);
43387 this.hash = hash_1.sha512;
43388}
43389
43390var eddsa$1 = EDDSA;
43391
43392/**
43393* @param {Array|String} message - message bytes
43394* @param {Array|String|KeyPair} secret - secret bytes or a keypair
43395* @returns {Signature} - signature
43396*/
43397EDDSA.prototype.sign = function sign(message, secret) {
43398 message = parseBytes$2(message);
43399 var key = this.keyFromSecret(secret);
43400 var r = this.hashInt(key.messagePrefix(), message);
43401 var R = this.g.mul(r);
43402 var Rencoded = this.encodePoint(R);
43403 var s_ = this.hashInt(Rencoded, key.pubBytes(), message)
43404 .mul(key.priv());
43405 var S = r.add(s_).umod(this.curve.n);
43406 return this.makeSignature({ R: R, S: S, Rencoded: Rencoded });
43407};
43408
43409/**
43410* @param {Array} message - message bytes
43411* @param {Array|String|Signature} sig - sig bytes
43412* @param {Array|String|Point|KeyPair} pub - public key
43413* @returns {Boolean} - true if public key matches sig of message
43414*/
43415EDDSA.prototype.verify = function verify(message, sig, pub) {
43416 message = parseBytes$2(message);
43417 sig = this.makeSignature(sig);
43418 var key = this.keyFromPublic(pub);
43419 var h = this.hashInt(sig.Rencoded(), key.pubBytes(), message);
43420 var SG = this.g.mul(sig.S());
43421 var RplusAh = sig.R().add(key.pub().mul(h));
43422 return RplusAh.eq(SG);
43423};
43424
43425EDDSA.prototype.hashInt = function hashInt() {
43426 var hash = this.hash();
43427 for (var i = 0; i < arguments.length; i++)
43428 hash.update(arguments[i]);
43429 return utils_1$1.intFromLE(hash.digest()).umod(this.curve.n);
43430};
43431
43432EDDSA.prototype.keyPair = function keyPair(options) {
43433 return new key$1(this, options);
43434};
43435
43436EDDSA.prototype.keyFromPublic = function keyFromPublic(pub) {
43437 return key$1.fromPublic(this, pub);
43438};
43439
43440EDDSA.prototype.keyFromSecret = function keyFromSecret(secret) {
43441 return key$1.fromSecret(this, secret);
43442};
43443
43444EDDSA.prototype.genKeyPair = function genKeyPair(options) {
43445 if (!options)
43446 options = {};
43447
43448 // Instantiate Hmac_DRBG
43449 var drbg = new hmacDrbg({
43450 hash: this.hash,
43451 pers: options.pers,
43452 persEnc: options.persEnc || 'utf8',
43453 entropy: options.entropy || brorand(this.hash.hmacStrength),
43454 entropyEnc: options.entropy && options.entropyEnc || 'utf8',
43455 nonce: this.curve.n.toArray()
43456 });
43457
43458 return this.keyFromSecret(drbg.generate(32));
43459};
43460
43461EDDSA.prototype.makeSignature = function makeSignature(sig) {
43462 if (sig instanceof signature$2)
43463 return sig;
43464 return new signature$2(this, sig);
43465};
43466
43467/**
43468* * https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-5.2
43469*
43470* EDDSA defines methods for encoding and decoding points and integers. These are
43471* helper convenience methods, that pass along to utility functions implied
43472* parameters.
43473*
43474*/
43475EDDSA.prototype.encodePoint = function encodePoint(point) {
43476 var enc = point.getY().toArray('le', this.encodingLength);
43477 enc[this.encodingLength - 1] |= point.getX().isOdd() ? 0x80 : 0;
43478 return enc;
43479};
43480
43481EDDSA.prototype.decodePoint = function decodePoint(bytes) {
43482 bytes = utils_1$1.parseBytes(bytes);
43483
43484 var lastIx = bytes.length - 1;
43485 var normed = bytes.slice(0, lastIx).concat(bytes[lastIx] & ~0x80);
43486 var xIsOdd = (bytes[lastIx] & 0x80) !== 0;
43487
43488 var y = utils_1$1.intFromLE(normed);
43489 return this.curve.pointFromY(y, xIsOdd);
43490};
43491
43492EDDSA.prototype.encodeInt = function encodeInt(num) {
43493 return num.toArray('le', this.encodingLength);
43494};
43495
43496EDDSA.prototype.decodeInt = function decodeInt(bytes) {
43497 return utils_1$1.intFromLE(bytes);
43498};
43499
43500EDDSA.prototype.isPoint = function isPoint(val) {
43501 return val instanceof this.pointClass;
43502};
43503
43504var elliptic_1 = createCommonjsModule(function (module, exports) {
43505
43506var elliptic = exports;
43507
43508elliptic.utils = utils_1$1;
43509elliptic.rand = brorand;
43510elliptic.curve = curve_1;
43511elliptic.curves = curves_1;
43512
43513// Protocols
43514elliptic.ec = ec;
43515elliptic.eddsa = eddsa$1;
43516});
43517
43518var elliptic$1 = /*#__PURE__*/Object.freeze({
43519 __proto__: null,
43520 'default': elliptic_1,
43521 __moduleExports: elliptic_1
43522});
43523
43524export { AEADEncryptedDataPacket, CleartextMessage, CompressedDataPacket, LiteralDataPacket, MarkerPacket, Message, OnePassSignaturePacket, PacketList, PrivateKey, PublicKey, PublicKeyEncryptedSessionKeyPacket, PublicKeyPacket, PublicSubkeyPacket, SecretKeyPacket, SecretSubkeyPacket, Signature, SignaturePacket, Subkey, SymEncryptedIntegrityProtectedDataPacket, SymEncryptedSessionKeyPacket, SymmetricallyEncryptedDataPacket, TrustPacket, UnparseablePacket, UserAttributePacket, UserIDPacket, armor, defaultConfig as config, createCleartextMessage, createMessage, decrypt$4 as decrypt, decryptKey, decryptSessionKeys, encrypt$4 as encrypt, encryptKey, encryptSessionKey, enums, generateKey, generateSessionKey$1 as generateSessionKey, readCleartextMessage, readKey, readKeys, readMessage, readPrivateKey, readPrivateKeys, readSignature, reformatKey, revokeKey, sign$5 as sign, unarmor, verify$5 as verify };